mirror of
https://github.com/All-Of-Us-Mods/MiraAPI.git
synced 2026-10-22 07:35:55 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ac2201b3ef | ||
|
|
992df67e18 | ||
|
|
67611471b8 | ||
|
|
5ddf48883c | ||
|
|
df8598db4d | ||
|
|
134e229523 | ||
|
|
cc1e89fd32 | ||
|
|
8bec9efa5c | ||
|
|
41c2a2b118 | ||
|
|
7919b32023 | ||
|
|
95bf1e1448 | ||
|
|
e4adaf7ab4 | ||
|
|
4027257b55 | ||
|
|
6c32c8bed9 | ||
|
|
905cc9e335 | ||
|
|
157aa65c2d | ||
|
|
3693ee754a | ||
|
|
85431d3685 | ||
|
|
2ac6c55cf8 | ||
|
|
db69446352 |
No files matched your search
+2
-2
@@ -2,12 +2,12 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Reactor" Version="2.3.1" />
|
<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="BepInEx.Unity.IL2CPP" Version="6.0.0-be.735" Private="false" ExcludeAssets="runtime;native" />
|
||||||
<PackageReference Include="AmongUs.GameLibs.Steam" Version="2025.10.14" PrivateAssets="all" />
|
<PackageReference Include="AmongUs.GameLibs.Android" Version="2025.9.9" PrivateAssets="all" />
|
||||||
|
|
||||||
<PackageReference Include="BepInEx.AutoPlugin" Version="1.1.0" 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" />
|
<PackageReference Include="BepInEx.IL2CPP.MSBuild" Version="2.1.0-rc.1" PrivateAssets="all" ExcludeAssets="runtime" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<Target Name="Copy" AfterTargets="Build" Condition="'$(AmongUs)' != ''">
|
<Target Name="Copy" AfterTargets="Build" Condition="'$(AmongUs)' != ''">
|
||||||
<Copy SourceFiles="$(TargetPath)" DestinationFolder="$(AmongUs)/BepInEx/plugins/" UseSymboliclinksIfPossible="true" />
|
<Copy SourceFiles="$(TargetPath)" DestinationFolder="$(AmongUs)/BepInEx/plugins/" UseSymboliclinksIfPossible="true" />
|
||||||
</Target>
|
</Target>
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
<RestorePackagesWithLockFile>true</RestorePackagesWithLockFile>
|
<RestorePackagesWithLockFile>true</RestorePackagesWithLockFile>
|
||||||
|
|
||||||
<VersionPrefix>0.3.4</VersionPrefix>
|
<VersionPrefix>0.3.1</VersionPrefix>
|
||||||
<VersionSuffix>dev</VersionSuffix>
|
<VersionSuffix>dev</VersionSuffix>
|
||||||
|
|
||||||
<Authors>All Of Us, XtraCube, Angxl</Authors>
|
<Authors>All Of Us, XtraCube, Angxl</Authors>
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ public static class MiraEventManager
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Error($"Error invoking event handler for {typeof(T).Name}: {ex.ToString()}");
|
Logger<MiraApiPlugin>.Error($"Error invoking event handler for {typeof(T).Name}: {ex.ToString()}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -63,7 +63,7 @@ public static class MiraEventManager
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Error($"Error invoking event handler for {type.Name}: {ex.ToString()}");
|
Logger<MiraApiPlugin>.Error($"Error invoking event handler for {type.Name}: {ex.ToString()}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,35 +0,0 @@
|
|||||||
namespace MiraAPI.Events.Vanilla.Player;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The event that is invoked when a player completes a task within Hide and Seek. Non-cancelable.
|
|
||||||
/// </summary>
|
|
||||||
public class CompleteHnsTaskEvent : MiraEvent
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the instance of the <see cref="PlayerControl"/>.
|
|
||||||
/// </summary>
|
|
||||||
public PlayerControl Player { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the instance of the <see cref="PlayerTask"/> that the player completed.
|
|
||||||
/// </summary>
|
|
||||||
public PlayerTask Task { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the instance of the <see cref="HnsManager"/> attached to the game.
|
|
||||||
/// </summary>
|
|
||||||
public HideAndSeekManager HnsManager { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Initializes a new instance of the <see cref="CompleteHnsTaskEvent"/> class.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="hnsManager">The Hide and Seek Manager currently active.</param>
|
|
||||||
/// <param name="player">The player who completed the task.</param>
|
|
||||||
/// <param name="task">The task that the player completed.</param>
|
|
||||||
public CompleteHnsTaskEvent(HideAndSeekManager hnsManager, PlayerControl player, PlayerTask task)
|
|
||||||
{
|
|
||||||
HnsManager = hnsManager;
|
|
||||||
Player = player;
|
|
||||||
Task = task;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -30,13 +30,13 @@ public static class GameOverManager
|
|||||||
|
|
||||||
if (gameOverType.IsAbstract)
|
if (gameOverType.IsAbstract)
|
||||||
{
|
{
|
||||||
Error("The type must not be abstract.");
|
Logger<MiraApiPlugin>.Error("The type must not be abstract.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gameOverType.GetConstructor(Type.EmptyTypes) == null)
|
if (gameOverType.GetConstructor(Type.EmptyTypes) == null)
|
||||||
{
|
{
|
||||||
Error("The type must have a parameterless constructor.");
|
Logger<MiraApiPlugin>.Error("The type must have a parameterless constructor.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ public static class CustomGameModeManager
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Error($"No gamemode with id {id} found!");
|
Logger<MiraApiPlugin>.Error($"No gamemode with id {id} found!");
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -48,7 +48,7 @@ public static class CustomGameModeManager
|
|||||||
{
|
{
|
||||||
if (!typeof(CustomGameMode).IsAssignableFrom(gameModeType))
|
if (!typeof(CustomGameMode).IsAssignableFrom(gameModeType))
|
||||||
{
|
{
|
||||||
Warning($"{gameModeType.Name} does not inherit CustomGameMode!");
|
Logger<MiraApiPlugin>.Warning($"{gameModeType.Name} does not inherit CustomGameMode!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -56,13 +56,13 @@ public static class CustomGameModeManager
|
|||||||
|
|
||||||
if (modeObj is not CustomGameMode gameMode)
|
if (modeObj is not CustomGameMode gameMode)
|
||||||
{
|
{
|
||||||
Error($"Failed to create instance of {gameModeType.Name}");
|
Logger<MiraApiPlugin>.Error($"Failed to create instance of {gameModeType.Name}");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GameModes.Any(x => x.Key == gameMode.Id))
|
if (GameModes.Any(x => x.Key == gameMode.Id))
|
||||||
{
|
{
|
||||||
Error($"ID for gamemode {gameMode.Name} already exists!");
|
Logger<MiraApiPlugin>.Error($"ID for gamemode {gameMode.Name} already exists!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
using MiraAPI.Modifiers;
|
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace MiraAPI.GameOptions;
|
namespace MiraAPI.GameOptions;
|
||||||
@@ -29,16 +28,11 @@ public abstract class AbstractOptionGroup
|
|||||||
public virtual Type? OptionableType => null;
|
public virtual Type? OptionableType => null;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a value indicating whether the group should be shown in the modifiers menu. This is deprecated, please use ParentMenu!
|
/// Gets a value indicating whether the group should be shown in the modifiers menu.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
// TODO: make this not a boolean
|
// TODO: make this not a boolean
|
||||||
public virtual bool ShowInModifiersMenu => false;
|
public virtual bool ShowInModifiersMenu => false;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets a value indicating which menu the group is in.
|
|
||||||
/// </summary>
|
|
||||||
public virtual MenuCategory ParentMenu => MenuCategory.Roles;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the function that determines whether the group should be visible or not.
|
/// Gets the function that determines whether the group should be visible or not.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -68,33 +62,4 @@ public abstract class AbstractOptionGroup<T> : AbstractOptionGroup where T : IOp
|
|||||||
{
|
{
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override Type OptionableType => typeof(T);
|
public override Type OptionableType => typeof(T);
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets a value indicating which menu the group is in.
|
|
||||||
/// </summary>
|
|
||||||
public override MenuCategory ParentMenu
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
var type = typeof(T);
|
|
||||||
if (type == typeof(BaseModifier))
|
|
||||||
{
|
|
||||||
return MenuCategory.Modifiers;
|
|
||||||
}
|
|
||||||
else if (type == typeof(RoleBehaviour))
|
|
||||||
{
|
|
||||||
return MenuCategory.Roles;
|
|
||||||
}
|
|
||||||
return MenuCategory.Game;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum MenuCategory
|
|
||||||
{
|
|
||||||
Game,
|
|
||||||
Roles,
|
|
||||||
Modifiers,
|
|
||||||
CustomOne,
|
|
||||||
CustomTwo
|
|
||||||
}
|
}
|
||||||
@@ -21,15 +21,7 @@ public class ModdedNumberOptionAttribute(
|
|||||||
{
|
{
|
||||||
internal override IModdedOption CreateOption(object? value, PropertyInfo property)
|
internal override IModdedOption CreateOption(object? value, PropertyInfo property)
|
||||||
{
|
{
|
||||||
return new ModdedNumberOption(
|
return new ModdedNumberOption(Title, (float)(value ?? min+increment), min, max, increment, suffixType, formatString, zeroInfinity);
|
||||||
Title,
|
|
||||||
(float)(value ?? min + increment),
|
|
||||||
min,
|
|
||||||
max,
|
|
||||||
increment,
|
|
||||||
suffixType,
|
|
||||||
formatString,
|
|
||||||
zeroInfinity);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
|
|||||||
@@ -17,9 +17,9 @@ public interface IModdedOption
|
|||||||
uint Id { get; }
|
uint Id { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the title of the option.
|
/// Gets the title of the option.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
string Title { get; set; }
|
string Title { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the StringName for the option, used for localization.
|
/// Gets the StringName for the option, used for localization.
|
||||||
|
|||||||
@@ -1,40 +0,0 @@
|
|||||||
using System;
|
|
||||||
using Il2CppInterop.Runtime.Attributes;
|
|
||||||
using MiraAPI.GameOptions.OptionTypes;
|
|
||||||
using Reactor.Utilities.Attributes;
|
|
||||||
using UnityEngine;
|
|
||||||
|
|
||||||
namespace MiraAPI.GameOptions;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Component added onto options generated via MiraAPI. This allows developers to hook patches onto options in general, without using a list.
|
|
||||||
/// </summary>
|
|
||||||
[RegisterInIl2Cpp]
|
|
||||||
public class MiraNumberOptionComponent(IntPtr cppPtr) : MonoBehaviour(cppPtr)
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the modded option associated with the object.
|
|
||||||
/// </summary>
|
|
||||||
[HideFromIl2Cpp]
|
|
||||||
public ModdedNumberOption NumberOption { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the default increment.
|
|
||||||
/// </summary>
|
|
||||||
public float DefaultIncrement { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets a value indicating whether holding shift will split the increment in half.
|
|
||||||
/// </summary>
|
|
||||||
public bool ShiftIncrementToggle { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets a value indicating what Zero displays.
|
|
||||||
/// </summary>
|
|
||||||
public string ZeroValue { get; set; } = "#";
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets a value indicating what Negative One displays.
|
|
||||||
/// </summary>
|
|
||||||
public string NegativeValue { get; set; } = "#";
|
|
||||||
}
|
|
||||||
@@ -39,7 +39,7 @@ public static class ModdedOptionsManager
|
|||||||
|
|
||||||
if (TypeToGroup.ContainsKey(type))
|
if (TypeToGroup.ContainsKey(type))
|
||||||
{
|
{
|
||||||
Error($"Group {type.Name} already exists.");
|
Logger<MiraApiPlugin>.Error($"Group {type.Name} already exists.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -60,13 +60,13 @@ public static class ModdedOptionsManager
|
|||||||
{
|
{
|
||||||
if (!TypeToGroup.TryGetValue(type, out var group))
|
if (!TypeToGroup.TryGetValue(type, out var group))
|
||||||
{
|
{
|
||||||
Error($"Failed to get group for {type.Name}");
|
Logger<MiraApiPlugin>.Error($"Failed to get group for {type.Name}");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (property.GetValue(group) is not IModdedOption option)
|
if (property.GetValue(group) is not IModdedOption option)
|
||||||
{
|
{
|
||||||
Error($"Failed to get option for {property.Name}");
|
Logger<MiraApiPlugin>.Error($"Failed to get option for {property.Name}");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -81,13 +81,13 @@ public static class ModdedOptionsManager
|
|||||||
{
|
{
|
||||||
if (OptionAttributes.ContainsKey(property))
|
if (OptionAttributes.ContainsKey(property))
|
||||||
{
|
{
|
||||||
Error($"Property {property.Name} already has an attribute registered.");
|
Logger<MiraApiPlugin>.Error($"Property {property.Name} already has an attribute registered.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!TypeToGroup.TryGetValue(type, out var group))
|
if (!TypeToGroup.TryGetValue(type, out var group))
|
||||||
{
|
{
|
||||||
Error($"Failed to get group for {type.Name}");
|
Logger<MiraApiPlugin>.Error($"Failed to get group for {type.Name}");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -95,7 +95,7 @@ public static class ModdedOptionsManager
|
|||||||
|
|
||||||
if (option == null)
|
if (option == null)
|
||||||
{
|
{
|
||||||
Error($"Failed to get option for {property.Name}");
|
Logger<MiraApiPlugin>.Error($"Failed to get option for {property.Name}");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -47,8 +47,6 @@ public class ModdedEnumOption : ModdedOption<int>
|
|||||||
public override OptionBehaviour CreateOption(ToggleOption toggleOpt, NumberOption numberOpt, StringOption stringOpt, PlayerOption playerOpt, Transform container)
|
public override OptionBehaviour CreateOption(ToggleOption toggleOpt, NumberOption numberOpt, StringOption stringOpt, PlayerOption playerOpt, Transform container)
|
||||||
{
|
{
|
||||||
var stringOption = Object.Instantiate(stringOpt, container);
|
var stringOption = Object.Instantiate(stringOpt, container);
|
||||||
stringOption.name =
|
|
||||||
$"{ParentMod!.OptionsTitleText}.EnumOption.{TranslationController.Instance.GetString(StringName)}";
|
|
||||||
|
|
||||||
stringOption.SetUpFromData(Data, 20);
|
stringOption.SetUpFromData(Data, 20);
|
||||||
stringOption.OnValueChanged = (Il2CppSystem.Action<OptionBehaviour>)ValueChanged;
|
stringOption.OnValueChanged = (Il2CppSystem.Action<OptionBehaviour>)ValueChanged;
|
||||||
@@ -140,8 +138,6 @@ public class ModdedEnumOption<T> : ModdedOption<T> where T : Enum
|
|||||||
public override OptionBehaviour CreateOption(ToggleOption toggleOpt, NumberOption numberOpt, StringOption stringOpt, PlayerOption playerOpt, Transform container)
|
public override OptionBehaviour CreateOption(ToggleOption toggleOpt, NumberOption numberOpt, StringOption stringOpt, PlayerOption playerOpt, Transform container)
|
||||||
{
|
{
|
||||||
var stringOption = Object.Instantiate(stringOpt, container);
|
var stringOption = Object.Instantiate(stringOpt, container);
|
||||||
stringOption.name =
|
|
||||||
$"{ParentMod!.OptionsTitleText}.EnumOption.{TranslationController.Instance.GetString(StringName)}";
|
|
||||||
|
|
||||||
stringOption.SetUpFromData(Data, 20);
|
stringOption.SetUpFromData(Data, 20);
|
||||||
stringOption.OnValueChanged = (Il2CppSystem.Action<OptionBehaviour>)ValueChanged;
|
stringOption.OnValueChanged = (Il2CppSystem.Action<OptionBehaviour>)ValueChanged;
|
||||||
|
|||||||
@@ -32,82 +32,10 @@ public class ModdedNumberOption : ModdedOption<float>
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public MiraNumberSuffixes SuffixType { get; }
|
public MiraNumberSuffixes SuffixType { get; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets a value indicating what zero appears as.
|
|
||||||
/// </summary>
|
|
||||||
public string ZeroWordValue { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets a value indicating what a negative one appears as.
|
|
||||||
/// </summary>
|
|
||||||
public string NegativeWordValue { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a value indicating whether zero is infinity.
|
/// Gets a value indicating whether zero is infinity.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool ZeroInfinity => ZeroWordValue == "∞";
|
public bool ZeroInfinity { get; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets a value indicating whether holding shift will divide the increment.
|
|
||||||
/// </summary>
|
|
||||||
public bool ShiftIncrement { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Initializes a new instance of the <see cref="ModdedNumberOption"/> class.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="title">The title of the option.</param>
|
|
||||||
/// <param name="defaultValue">The default value as a float.</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="formatString">Optional format string for the option screen.</param>
|
|
||||||
/// <param name="zeroBehavior">Determines what is shown for zero. Options: ∞, #, or a word value (such as Off).</param>
|
|
||||||
/// <param name="negativeBehavior">Determines what is shown for negative 1. Options: ∞, #, or a word value (such as Off).</param>
|
|
||||||
/// <param name="halfIncrements">Whether increments can be split in half.</param>
|
|
||||||
/// <param name="includeInPreset">Whether to include this option in the preset or not.</param>
|
|
||||||
public ModdedNumberOption(
|
|
||||||
string title,
|
|
||||||
float defaultValue,
|
|
||||||
float min,
|
|
||||||
float max,
|
|
||||||
float increment,
|
|
||||||
string zeroBehavior,
|
|
||||||
string negativeBehavior,
|
|
||||||
MiraNumberSuffixes suffixType,
|
|
||||||
string? formatString = null,
|
|
||||||
bool halfIncrements = false,
|
|
||||||
bool includeInPreset = true) : base(title, defaultValue, includeInPreset)
|
|
||||||
{
|
|
||||||
Min = min;
|
|
||||||
Max = max;
|
|
||||||
Increment = increment;
|
|
||||||
SuffixType = suffixType;
|
|
||||||
ZeroWordValue = zeroBehavior;
|
|
||||||
NegativeWordValue = negativeBehavior;
|
|
||||||
ShiftIncrement = halfIncrements;
|
|
||||||
|
|
||||||
Value = Mathf.Clamp(defaultValue, min, max);
|
|
||||||
|
|
||||||
Data = ScriptableObject.CreateInstance<FloatGameSetting>();
|
|
||||||
|
|
||||||
var data = (FloatGameSetting)Data;
|
|
||||||
data.Type = global::OptionTypes.Float;
|
|
||||||
data.Title = StringName;
|
|
||||||
data.Value = Value;
|
|
||||||
data.Increment = Increment;
|
|
||||||
data.ValidRange = new FloatRange(Min, Max);
|
|
||||||
data.FormatString = formatString ??
|
|
||||||
(defaultValue.IsInteger() &&
|
|
||||||
Increment.IsInteger() &&
|
|
||||||
Value.IsInteger() &&
|
|
||||||
Min.IsInteger() &&
|
|
||||||
Max.IsInteger() ? "0" : "0.0");
|
|
||||||
|
|
||||||
data.ZeroIsInfinity = ZeroInfinity;
|
|
||||||
data.SuffixType = (NumberSuffixes)SuffixType;
|
|
||||||
data.OptionName = FloatOptionNames.Invalid;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="ModdedNumberOption"/> class.
|
/// Initializes a new instance of the <see cref="ModdedNumberOption"/> class.
|
||||||
@@ -136,9 +64,7 @@ public class ModdedNumberOption : ModdedOption<float>
|
|||||||
Max = max;
|
Max = max;
|
||||||
Increment = increment;
|
Increment = increment;
|
||||||
SuffixType = suffixType;
|
SuffixType = suffixType;
|
||||||
ZeroWordValue = zeroInfinity ? "∞" : "#";
|
ZeroInfinity = zeroInfinity;
|
||||||
NegativeWordValue = "#";
|
|
||||||
ShiftIncrement = increment != 1f;
|
|
||||||
|
|
||||||
Value = Mathf.Clamp(defaultValue, min, max);
|
Value = Mathf.Clamp(defaultValue, min, max);
|
||||||
|
|
||||||
@@ -171,14 +97,6 @@ public class ModdedNumberOption : ModdedOption<float>
|
|||||||
Transform container)
|
Transform container)
|
||||||
{
|
{
|
||||||
var numberOption = Object.Instantiate(numberOpt, Vector3.zero, Quaternion.identity, container);
|
var numberOption = Object.Instantiate(numberOpt, Vector3.zero, Quaternion.identity, container);
|
||||||
numberOption.name =
|
|
||||||
$"{ParentMod!.OptionsTitleText}.NumberOption.{TranslationController.Instance.GetString(StringName)}";
|
|
||||||
var optionComponent = numberOption.gameObject.AddComponent<MiraNumberOptionComponent>();
|
|
||||||
optionComponent.NumberOption = this;
|
|
||||||
optionComponent.DefaultIncrement = Increment;
|
|
||||||
optionComponent.ShiftIncrementToggle = ShiftIncrement;
|
|
||||||
optionComponent.NegativeValue = NegativeWordValue;
|
|
||||||
optionComponent.ZeroValue = ZeroWordValue;
|
|
||||||
|
|
||||||
numberOption.SetUpFromData(Data, 20);
|
numberOption.SetUpFromData(Data, 20);
|
||||||
numberOption.OnValueChanged = (Il2CppSystem.Action<OptionBehaviour>)ValueChanged;
|
numberOption.OnValueChanged = (Il2CppSystem.Action<OptionBehaviour>)ValueChanged;
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ public abstract class ModdedOption<T> : IModdedOption
|
|||||||
public uint Id { get; }
|
public uint Id { get; }
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public string Title { get; set; }
|
public string Title { get; }
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public StringNames StringName { get; }
|
public StringNames StringName { get; }
|
||||||
@@ -125,7 +125,7 @@ public abstract class ModdedOption<T> : IModdedOption
|
|||||||
{
|
{
|
||||||
if (ConfigDefinition is null)
|
if (ConfigDefinition is null)
|
||||||
{
|
{
|
||||||
Error($"Attempted to save {Title} to preset, but ConfigDefinition is null.");
|
Logger<MiraApiPlugin>.Error($"Attempted to save {Title} to preset, but ConfigDefinition is null.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Bind(presetConfig);
|
Bind(presetConfig);
|
||||||
@@ -147,7 +147,7 @@ public abstract class ModdedOption<T> : IModdedOption
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Error($"Attempted to load {Title} from preset, but ConfigDefinition is not found in preset.");
|
Logger<MiraApiPlugin>.Error($"Attempted to load {Title} from preset, but ConfigDefinition is not found in preset.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -55,8 +55,6 @@ public class ModdedPlayerOption : ModdedOption<int>
|
|||||||
Transform container)
|
Transform container)
|
||||||
{
|
{
|
||||||
var playerOption = Object.Instantiate(playerOpt, container);
|
var playerOption = Object.Instantiate(playerOpt, container);
|
||||||
playerOption.name =
|
|
||||||
$"{ParentMod!.OptionsTitleText}.PlayerOption.{TranslationController.Instance.GetString(StringName)}";
|
|
||||||
|
|
||||||
var filteredList = GetFilteredPlayers();
|
var filteredList = GetFilteredPlayers();
|
||||||
Values = filteredList.ToIl2CppList();
|
Values = filteredList.ToIl2CppList();
|
||||||
|
|||||||
@@ -29,8 +29,6 @@ public class ModdedToggleOption : ModdedOption<bool>
|
|||||||
public override OptionBehaviour CreateOption(ToggleOption toggleOpt, NumberOption numberOpt, StringOption stringOpt, PlayerOption playerOpt, Transform container)
|
public override OptionBehaviour CreateOption(ToggleOption toggleOpt, NumberOption numberOpt, StringOption stringOpt, PlayerOption playerOpt, Transform container)
|
||||||
{
|
{
|
||||||
var toggleOption = Object.Instantiate(toggleOpt, Vector3.zero, Quaternion.identity, container);
|
var toggleOption = Object.Instantiate(toggleOpt, Vector3.zero, Quaternion.identity, container);
|
||||||
toggleOption.name =
|
|
||||||
$"{ParentMod!.OptionsTitleText}.ToggleOption.{TranslationController.Instance.GetString(StringName)}";
|
|
||||||
|
|
||||||
toggleOption.SetUpFromData(Data, 20);
|
toggleOption.SetUpFromData(Data, 20);
|
||||||
|
|
||||||
|
|||||||
@@ -64,14 +64,9 @@ public abstract class CustomActionButton
|
|||||||
public virtual float EffectDuration => 0;
|
public virtual float EffectDuration => 0;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a value indicating whether the button has limited uses.
|
/// Gets the maximum amount of uses the button has. If the button has infinite uses, set to 0.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool LimitedUses => ZeroIsInfinite ? MaxUses > 0 : MaxUses >= 0;
|
public virtual int MaxUses => 0;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the maximum number of uses the button has. If the button has infinite uses, set to 0 or -1 based on what value that ZeroIsInfinite is set to.
|
|
||||||
/// </summary>
|
|
||||||
public virtual int MaxUses => ZeroIsInfinite ? 0 : -1;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the value indicating uses mode.
|
/// Gets the value indicating uses mode.
|
||||||
@@ -94,9 +89,9 @@ public abstract class CustomActionButton
|
|||||||
public virtual ButtonLocation Location { get; set; } = ButtonLocation.BottomLeft;
|
public virtual ButtonLocation Location { get; set; } = ButtonLocation.BottomLeft;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets a value indicating whether limited uses are determined via zero or a negative number of uses.
|
/// Gets a value indicating whether the button has limited uses.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public virtual bool ZeroIsInfinite { get; set; } = true;
|
public bool LimitedUses => MaxUses > 0;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets a value indicating whether the effect is currently active, if there is one.
|
/// Gets or sets a value indicating whether the effect is currently active, if there is one.
|
||||||
@@ -211,39 +206,7 @@ public abstract class CustomActionButton
|
|||||||
{
|
{
|
||||||
if (Enabled(PlayerControl.LocalPlayer.Data.Role))
|
if (Enabled(PlayerControl.LocalPlayer.Data.Role))
|
||||||
{
|
{
|
||||||
// Invoke the generic button click event.
|
ClickHandler();
|
||||||
var genericEvent = new MiraButtonClickEvent(this);
|
|
||||||
MiraEventManager.InvokeEvent(genericEvent);
|
|
||||||
if (genericEvent.IsCancelled)
|
|
||||||
{
|
|
||||||
MiraEventManager.InvokeEvent(new MiraButtonCancelledEvent(this));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Invoke the button click event for specific button.
|
|
||||||
var eventType = CustomButtonManager.ButtonEventTypes[GetType()];
|
|
||||||
var @event = (MiraCancelableEvent)Activator.CreateInstance(eventType, this, genericEvent)!;
|
|
||||||
var specificInvoked = MiraEventManager.InvokeEvent(@event, eventType);
|
|
||||||
if (@event.IsCancelled)
|
|
||||||
{
|
|
||||||
var cancelEventType = CustomButtonManager.ButtonCancelledEventTypes[GetType()];
|
|
||||||
var cancelEvent = (MiraEvent)Activator.CreateInstance(cancelEventType, this)!;
|
|
||||||
MiraEventManager.InvokeEvent(cancelEvent, cancelEventType);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (specificInvoked)
|
|
||||||
{
|
|
||||||
if (!@event.IsCancelled)
|
|
||||||
{
|
|
||||||
ClickHandler();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!genericEvent.IsCancelled)
|
|
||||||
{
|
|
||||||
ClickHandler();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -251,10 +214,9 @@ public abstract class CustomActionButton
|
|||||||
Helpers.CreateKeybindIcon(
|
Helpers.CreateKeybindIcon(
|
||||||
Button.gameObject,
|
Button.gameObject,
|
||||||
Keybind.CurrentKey,
|
Keybind.CurrentKey,
|
||||||
new Vector3(0.4f, 0.45f, -9f)
|
new Vector3(MaxUses <= 0 ? -0.4f : 0.4f, 0.45f, -9f)
|
||||||
);
|
);
|
||||||
KeybindText = KeybindIcon.transform.GetChild(0).GetComponent<TextMeshPro>();
|
KeybindText = KeybindIcon.transform.GetChild(0).GetComponent<TextMeshPro>();
|
||||||
HudManagerPatches.ModdedKeybindIcons.Add(KeybindText);
|
|
||||||
Button.usesRemainingSprite.transform.localPosition = new(-0.341f, 0.45f, -0.1f);
|
Button.usesRemainingSprite.transform.localPosition = new(-0.341f, 0.45f, -0.1f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -271,7 +233,7 @@ public abstract class CustomActionButton
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Location = location;
|
this.Location = location;
|
||||||
|
|
||||||
if (!moveButton)
|
if (!moveButton)
|
||||||
{
|
{
|
||||||
@@ -532,7 +494,7 @@ public abstract class CustomActionButton
|
|||||||
if (Keybind != null && KeybindText != null)
|
if (Keybind != null && KeybindText != null)
|
||||||
{
|
{
|
||||||
KeybindText.text = Keybind.CurrentKey.ToString();
|
KeybindText.text = Keybind.CurrentKey.ToString();
|
||||||
KeybindIcon?.SetActive(ActiveInputManager.currentControlType is ActiveInputManager.InputType.Keyboard &&
|
KeybindIcon?.SetActive(ActiveInputManager.currentControlType == ActiveInputManager.InputType.Keyboard &&
|
||||||
LocalSettingsTabSingleton<MiraApiSettings>.Instance.ShowKeybinds.Value &&
|
LocalSettingsTabSingleton<MiraApiSettings>.Instance.ShowKeybinds.Value &&
|
||||||
Keybind.CurrentKey != KeyboardKeyCode.None);
|
Keybind.CurrentKey != KeyboardKeyCode.None);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,11 +26,11 @@ public static class KeybindManager
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
var instance = KeybindUtils.RewiredInputManager!;
|
var instance = KeybindUtils.RewiredInputManager!;
|
||||||
foreach (var keybind in Keybinds)
|
foreach (var keybind in KeybindManager.Keybinds)
|
||||||
{
|
{
|
||||||
if (instance.userData.actions.ToArray().Any(x => x.name == keybind.Id))
|
if (instance.userData.actions.ToArray().Any(x => x.name == keybind.Id))
|
||||||
{
|
{
|
||||||
Warning($"Keybind of id {keybind.Id} already exists. Skipping it");
|
Logger<MiraApiPlugin>.Warning($"Keybind of id {keybind.Id} already exists. Skipping it");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,7 +44,7 @@ public static class KeybindManager
|
|||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Error($"Error while registering keybinds in Rewired: {e}");
|
Logger<MiraApiPlugin>.Error($"Error while registering keybinds in Rewired: {e}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,6 @@ public class VanillaKeybind : BaseKeybind
|
|||||||
public VanillaKeybind(int id)
|
public VanillaKeybind(int id)
|
||||||
{
|
{
|
||||||
RewiredInputAction = KeybindUtils.GetInputActionById(id);
|
RewiredInputAction = KeybindUtils.GetInputActionById(id);
|
||||||
Id = RewiredInputAction != null ? RewiredInputAction.name : id.ToString();
|
Id = RewiredInputAction?.name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -24,7 +24,7 @@ public static class LocalSettingsManager
|
|||||||
|
|
||||||
if (TypeToTab.ContainsKey(type))
|
if (TypeToTab.ContainsKey(type))
|
||||||
{
|
{
|
||||||
Error($"Local settings tab {type.Name} already exists.");
|
Logger<MiraApiPlugin>.Error($"Local settings tab {type.Name} already exists.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
global using static Reactor.Utilities.Logger<MiraAPI.MiraApiPlugin>;
|
using BepInEx;
|
||||||
using BepInEx;
|
|
||||||
using BepInEx.Unity.IL2CPP;
|
using BepInEx.Unity.IL2CPP;
|
||||||
using HarmonyLib;
|
using HarmonyLib;
|
||||||
using MiraAPI.PluginLoading;
|
using MiraAPI.PluginLoading;
|
||||||
|
|||||||
@@ -28,11 +28,9 @@ public class MiraApiSettings(ConfigFile config) : LocalSettingsTab(config)
|
|||||||
public ConfigEntry<bool> ModifiersHudLeftSide { get; private set; } = config.Bind("Displays", "Show Modifiers HUD on Left Side", false);
|
public ConfigEntry<bool> ModifiersHudLeftSide { get; private set; } = config.Bind("Displays", "Show Modifiers HUD on Left Side", false);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets whether to show keybinds on buttons.
|
/// Gets whether to show keybinds in the control mapper.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[LocalToggleSetting]
|
public ConfigEntry<bool> ShowKeybinds { get; private set; } = config.Bind("Keybinds", "Show Keybinds in Control Mapper", true);
|
||||||
public ConfigEntry<bool> ShowKeybinds { get; private set; } = config.Bind("Keybinds", "Show Keybinds on Buttons", true);
|
|
||||||
// This would be placed in the keybinds menu, but it crashes for Epic Games users. - Atony
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets whether to apply cosmetic changes to the TaskAdder.
|
/// Gets whether to apply cosmetic changes to the TaskAdder.
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ public class ModifierComponent(IntPtr cppPtr) : MonoBehaviour(cppPtr)
|
|||||||
_player = GetComponent<PlayerControl>();
|
_player = GetComponent<PlayerControl>();
|
||||||
if (_player == null)
|
if (_player == null)
|
||||||
{
|
{
|
||||||
Error("ModifierComponent could not find PlayerControl on the same GameObject.");
|
Logger<MiraApiPlugin>.Error("ModifierComponent could not find PlayerControl on the same GameObject.");
|
||||||
Destroy(this);
|
Destroy(this);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -77,7 +77,7 @@ public class ModifierComponent(IntPtr cppPtr) : MonoBehaviour(cppPtr)
|
|||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Error($"Error while deactivating modifier {modifier.ModifierName}: {e.ToString()}");
|
Logger<MiraApiPlugin>.Error($"Error while deactivating modifier {modifier.ModifierName}: {e.ToString()}");
|
||||||
}
|
}
|
||||||
|
|
||||||
Modifiers.Remove(modifier);
|
Modifiers.Remove(modifier);
|
||||||
@@ -95,7 +95,7 @@ public class ModifierComponent(IntPtr cppPtr) : MonoBehaviour(cppPtr)
|
|||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Error($"Error while activating modifier {modifier.ModifierName}: {e.ToString()}");
|
Logger<MiraApiPlugin>.Error($"Error while activating modifier {modifier.ModifierName}: {e.ToString()}");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (modifier is TimedModifier { AutoStart: true } timer)
|
if (modifier is TimedModifier { AutoStart: true } timer)
|
||||||
@@ -122,7 +122,7 @@ public class ModifierComponent(IntPtr cppPtr) : MonoBehaviour(cppPtr)
|
|||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Error($"Error while (fixed) updating modifier {modifier.ModifierName}: {e.ToString()}");
|
Logger<MiraApiPlugin>.Error($"Error while (fixed) updating modifier {modifier.ModifierName}: {e.ToString()}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -153,7 +153,7 @@ public class ModifierComponent(IntPtr cppPtr) : MonoBehaviour(cppPtr)
|
|||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Error($"Error while updating modifier {modifier.ModifierName}: {e.ToString()}");
|
Logger<MiraApiPlugin>.Error($"Error while updating modifier {modifier.ModifierName}: {e.ToString()}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -336,7 +336,7 @@ public class ModifierComponent(IntPtr cppPtr) : MonoBehaviour(cppPtr)
|
|||||||
var modifier = modifiers.FirstOrDefault();
|
var modifier = modifiers.FirstOrDefault();
|
||||||
if (modifier is null)
|
if (modifier is null)
|
||||||
{
|
{
|
||||||
Error($"Cannot remove modifier {type.Name} because it is not active.");
|
Logger<MiraApiPlugin>.Error($"Cannot remove modifier {type.Name} because it is not active.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -352,7 +352,7 @@ public class ModifierComponent(IntPtr cppPtr) : MonoBehaviour(cppPtr)
|
|||||||
{
|
{
|
||||||
if (!ActiveModifiers.Contains(modifier))
|
if (!ActiveModifiers.Contains(modifier))
|
||||||
{
|
{
|
||||||
Error($"Cannot remove modifier {modifier.ModifierName} because it is not active on this player.");
|
Logger<MiraApiPlugin>.Error($"Cannot remove modifier {modifier.ModifierName} because it is not active on this player.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -382,7 +382,7 @@ public class ModifierComponent(IntPtr cppPtr) : MonoBehaviour(cppPtr)
|
|||||||
var modifier = GetModifier(uniqueId);
|
var modifier = GetModifier(uniqueId);
|
||||||
if (modifier == null)
|
if (modifier == null)
|
||||||
{
|
{
|
||||||
Error($"Cannot remove modifier with unique id {uniqueId} because it is not active.");
|
Logger<MiraApiPlugin>.Error($"Cannot remove modifier with unique id {uniqueId} because it is not active.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -412,19 +412,19 @@ public class ModifierComponent(IntPtr cppPtr) : MonoBehaviour(cppPtr)
|
|||||||
// TODO: Make a proper synchronization system.
|
// TODO: Make a proper synchronization system.
|
||||||
if (LobbyBehaviour.Instance)
|
if (LobbyBehaviour.Instance)
|
||||||
{
|
{
|
||||||
Warning($"Modifiers added in the lobby won't sync to new players!");
|
Logger<MiraApiPlugin>.Warning($"Modifiers added in the lobby won't sync to new players!");
|
||||||
}
|
}
|
||||||
|
|
||||||
var id = modifier.TypeId;
|
var id = modifier.TypeId;
|
||||||
if (modifier.Unique && ActiveModifiers.Find(x => x.TypeId == id) != null)
|
if (modifier.Unique && ActiveModifiers.Find(x => x.TypeId == id) != null)
|
||||||
{
|
{
|
||||||
Error($"Player already has modifier with id {id}!");
|
Logger<MiraApiPlugin>.Error($"Player already has modifier with id {id}!");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ActiveModifiers.Contains(modifier))
|
if (ActiveModifiers.Contains(modifier))
|
||||||
{
|
{
|
||||||
Error($"Player already has this modifier!");
|
Logger<MiraApiPlugin>.Error($"Player already has this modifier!");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ public static class ModifierExtensions
|
|||||||
var modifier = target.GetModifier(typeId, predicate);
|
var modifier = target.GetModifier(typeId, predicate);
|
||||||
if (modifier is null)
|
if (modifier is null)
|
||||||
{
|
{
|
||||||
Error($"Player {target.PlayerId} does not have modifier with type ID {typeId}.");
|
Logger<MiraApiPlugin>.Error($"Player {target.PlayerId} does not have modifier with type ID {typeId}.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -97,7 +97,7 @@ public static class ModifierManager
|
|||||||
|
|
||||||
if (modifierType.GetConstructor(Type.EmptyTypes) == null)
|
if (modifierType.GetConstructor(Type.EmptyTypes) == null)
|
||||||
{
|
{
|
||||||
Error($"Game Modifier {modifierType.FullName} does not have a parameterless constructor!");
|
Logger<MiraApiPlugin>.Error($"Game Modifier {modifierType.FullName} does not have a parameterless constructor!");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -137,7 +137,7 @@ public static class ModifierManager
|
|||||||
var validPlayers = plrs.Where(x => IsGameModifierValid(x, modifier, modifier.TypeId)).ToList();
|
var validPlayers = plrs.Where(x => IsGameModifierValid(x, modifier, modifier.TypeId)).ToList();
|
||||||
if (validPlayers.Count == 0)
|
if (validPlayers.Count == 0)
|
||||||
{
|
{
|
||||||
Warning($"No valid players for modifier {modifier.ModifierName}");
|
Logger<MiraApiPlugin>.Warning($"No valid players for modifier {modifier.ModifierName}");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -158,7 +158,7 @@ public static class ModifierManager
|
|||||||
|
|
||||||
if (candidates.Count == 0)
|
if (candidates.Count == 0)
|
||||||
{
|
{
|
||||||
Warning(
|
Logger<MiraApiPlugin>.Warning(
|
||||||
$"No available players for modifier {modifier.ModifierName} at assignment {i + 1}");
|
$"No available players for modifier {modifier.ModifierName} at assignment {i + 1}");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -166,7 +166,7 @@ public static class ModifierManager
|
|||||||
var plr = candidates.Random();
|
var plr = candidates.Random();
|
||||||
if (plr == null)
|
if (plr == null)
|
||||||
{
|
{
|
||||||
Warning($"Valid player for modifier {modifier.ModifierName} disappeared");
|
Logger<MiraApiPlugin>.Warning($"Valid player for modifier {modifier.ModifierName} disappeared");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -179,7 +179,6 @@ public static class ModifierManager
|
|||||||
private static bool IsGameModifierValid(PlayerControl player, GameModifier modifier, uint modifierId)
|
private static bool IsGameModifierValid(PlayerControl player, GameModifier modifier, uint modifierId)
|
||||||
{
|
{
|
||||||
return (player.Data.Role is not ICustomRole role || role.IsModifierApplicable(modifier)) &&
|
return (player.Data.Role is not ICustomRole role || role.IsModifierApplicable(modifier)) &&
|
||||||
modifier.IsModifierValidOn(player.Data.Role) && !player.HasModifier(modifierId) &&
|
modifier.IsModifierValidOn(player.Data.Role) && !player.HasModifier(modifierId);
|
||||||
modifier.CanSpawnOnCurrentMode();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -39,10 +39,4 @@ public abstract class GameModifier : BaseModifier
|
|||||||
/// <param name="reason">The reason why the game ended.</param>
|
/// <param name="reason">The reason why the game ended.</param>
|
||||||
/// <returns>True if the player won, false if they lost. Return null to use the player's default win condition.</returns>
|
/// <returns>True if the player won, false if they lost. Return null to use the player's default win condition.</returns>
|
||||||
public virtual bool? DidWin(GameOverReason reason) => null;
|
public virtual bool? DidWin(GameOverReason reason) => null;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Determines whether the modifier can spawn in general, accounting for gamemodes and everything else.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>True if the modifier is able to spawn, otherwise false.</returns>
|
|
||||||
public virtual bool CanSpawnOnCurrentMode() => !GameManager.Instance.IsHideAndSeek();
|
|
||||||
}
|
}
|
||||||
@@ -80,7 +80,7 @@ public abstract class TimedModifier : BaseModifier
|
|||||||
{
|
{
|
||||||
if (TimerActive)
|
if (TimerActive)
|
||||||
{
|
{
|
||||||
Error("Can't start a timer that has already been started.");
|
Logger<MiraApiPlugin>.Error("Can't start a timer that has already been started.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ public class CustomGameOverRpc(MiraApiPlugin plugin, uint id) : PlayerCustomRpc<
|
|||||||
{
|
{
|
||||||
if (!gameOver.VerifyCondition(innerNetObject, [.. data.Winners]))
|
if (!gameOver.VerifyCondition(innerNetObject, [.. data.Winners]))
|
||||||
{
|
{
|
||||||
Info($"Game over condition not met for {gameOver.GetType().Name}");
|
Logger<MiraApiPlugin>.Info($"Game over condition not met for {gameOver.GetType().Name}");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,7 +64,7 @@ public class CustomGameOverRpc(MiraApiPlugin plugin, uint id) : PlayerCustomRpc<
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
CustomGameOver.Instance = null;
|
CustomGameOver.Instance = null;
|
||||||
Error($"Unknown game over reason: {data.Reason}");
|
Logger<MiraApiPlugin>.Error($"Unknown game over reason: {data.Reason}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
using System;
|
using System.Collections;
|
||||||
using System.Collections;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using AmongUs.Data;
|
using AmongUs.Data;
|
||||||
using AmongUs.GameOptions;
|
using AmongUs.GameOptions;
|
||||||
@@ -9,10 +8,8 @@ using MiraAPI.Events;
|
|||||||
using MiraAPI.Events.Vanilla.Gameplay;
|
using MiraAPI.Events.Vanilla.Gameplay;
|
||||||
using Reactor.Networking.Attributes;
|
using Reactor.Networking.Attributes;
|
||||||
using Reactor.Networking.Rpc;
|
using Reactor.Networking.Rpc;
|
||||||
using Reactor.Utilities;
|
|
||||||
using Reactor.Utilities.Extensions;
|
using Reactor.Utilities.Extensions;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using Object = UnityEngine.Object;
|
|
||||||
|
|
||||||
namespace MiraAPI.Networking;
|
namespace MiraAPI.Networking;
|
||||||
|
|
||||||
@@ -87,11 +84,11 @@ public static class CustomMurderRpc
|
|||||||
bool playKillSound = true)
|
bool playKillSound = true)
|
||||||
{
|
{
|
||||||
source.isKilling = false;
|
source.isKilling = false;
|
||||||
|
var data = target.Data;
|
||||||
if (resultFlags.HasFlag(MurderResultFlags.FailedError))
|
if (resultFlags.HasFlag(MurderResultFlags.FailedError))
|
||||||
{
|
{
|
||||||
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))
|
||||||
@@ -172,14 +169,7 @@ public static class CustomMurderRpc
|
|||||||
|
|
||||||
if (showKillAnim)
|
if (showKillAnim)
|
||||||
{
|
{
|
||||||
try
|
HudManager.Instance.KillOverlay.ShowKillAnimation(source.Data, data);
|
||||||
{
|
|
||||||
HudManager.Instance.KillOverlay.ShowKillAnimation(source.Data, data);
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
Error($"Error with kill animation: {e.ToString()}");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
target.cosmetics.SetNameMask(false);
|
target.cosmetics.SetNameMask(false);
|
||||||
@@ -212,7 +202,7 @@ public static class CustomMurderRpc
|
|||||||
bool teleportMurderer = true)
|
bool teleportMurderer = true)
|
||||||
{
|
{
|
||||||
var cam = Camera.main?.GetComponent<FollowerCamera>();
|
var cam = Camera.main?.GetComponent<FollowerCamera>();
|
||||||
var isParticipant = source.AmOwner || target.AmOwner;
|
var isParticipant = PlayerControl.LocalPlayer == source || PlayerControl.LocalPlayer == target;
|
||||||
var sourcePhys = source.MyPhysics;
|
var sourcePhys = source.MyPhysics;
|
||||||
|
|
||||||
if (teleportMurderer)
|
if (teleportMurderer)
|
||||||
@@ -232,7 +222,7 @@ public static class CustomMurderRpc
|
|||||||
|
|
||||||
if (createDeadBody)
|
if (createDeadBody)
|
||||||
{
|
{
|
||||||
deadBody = Object.Instantiate(GameManager.Instance.GetDeadBody(source.Data.Role));
|
deadBody = Object.Instantiate(GameManager.Instance.deadBodyPrefab[0]);
|
||||||
deadBody.enabled = false;
|
deadBody.enabled = false;
|
||||||
deadBody.ParentId = target.PlayerId;
|
deadBody.ParentId = target.PlayerId;
|
||||||
deadBody.bodyRenderers.ToList().ForEach(target.SetPlayerMaterialColors);
|
deadBody.bodyRenderers.ToList().ForEach(target.SetPlayerMaterialColors);
|
||||||
@@ -243,13 +233,6 @@ public static class CustomMurderRpc
|
|||||||
deadBody.transform.position = vector;
|
deadBody.transform.position = vector;
|
||||||
}
|
}
|
||||||
|
|
||||||
source.Data.Role.KillAnimSpecialSetup(deadBody, source, target);
|
|
||||||
target.Data.Role.KillAnimSpecialSetup(deadBody, source, target);
|
|
||||||
|
|
||||||
// no idea if this causes bugs, but innersloth is brain-dead
|
|
||||||
// I HATE INNERSCUFF I HATE INNERSCUFF I HATE INNERSCUFF I HATE INNERSCUFF I HATE INNERSCUFF I HATE INNERSCUFF
|
|
||||||
PlayerControl.LocalPlayer.Data.Role.KillAnimSpecialSetup(deadBody, source, target);
|
|
||||||
|
|
||||||
if (isParticipant)
|
if (isParticipant)
|
||||||
{
|
{
|
||||||
if (cam != null)
|
if (cam != null)
|
||||||
|
|||||||
@@ -7,12 +7,12 @@ using UnityEngine;
|
|||||||
|
|
||||||
namespace MiraAPI.Patches;
|
namespace MiraAPI.Patches;
|
||||||
|
|
||||||
[HarmonyPatch(typeof(DetectiveNotesMinigame), nameof(DetectiveNotesMinigame.SetImpostorPopup))]
|
[HarmonyPatch(typeof(DetectiveNotesMinigame), nameof(DetectiveNotesMinigame.OpenBodyPopup))]
|
||||||
public static class DetectiveNotesMinigamePatch
|
public static class DetectiveNotesMinigamePatch
|
||||||
{
|
{
|
||||||
public static void Prefix(DetectiveNotesMinigame __instance, bool active)
|
public static void Prefix(DetectiveNotesMinigame __instance, bool active)
|
||||||
{
|
{
|
||||||
__instance.impostorTypePopup.gameObject.SetActive(active);
|
__instance.impostorTypePopup.SetActive(active);
|
||||||
if (!active)
|
if (!active)
|
||||||
{
|
{
|
||||||
ControllerManager.Instance.CloseOverlayMenu(__instance.ImpostorOverlay);
|
ControllerManager.Instance.CloseOverlayMenu(__instance.ImpostorOverlay);
|
||||||
@@ -22,21 +22,23 @@ public static class DetectiveNotesMinigamePatch
|
|||||||
}
|
}
|
||||||
if (__instance.impostorButton != null)
|
if (__instance.impostorButton != null)
|
||||||
{
|
{
|
||||||
ControllerManager.Instance.OpenOverlayMenu(__instance.ImpostorOverlay, __instance.impostorTypePopup, __instance.ImpostorIconControllerSelectables[0], __instance.ImpostorIconControllerSelectables, false);
|
ControllerManager.Instance.OpenOverlayMenu(__instance.ImpostorOverlay, null, __instance.ImpostorIconControllerSelectables[0], __instance.ImpostorIconControllerSelectables, false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
__instance.impostorButton = new List<GameObject>();
|
__instance.impostorButton = new List<GameObject>();
|
||||||
|
int num = 0;
|
||||||
var allRoles = DestroyableSingleton<RoleManager>.Instance.AllRoles;
|
var allRoles = DestroyableSingleton<RoleManager>.Instance.AllRoles;
|
||||||
var customRoles = CustomRoleManager.CustomRoleBehaviours;
|
var customRoles = CustomRoleManager.CustomRoleBehaviours;
|
||||||
foreach (var role in allRoles)
|
foreach (var role in allRoles)
|
||||||
{
|
{
|
||||||
if (role.TeamType != RoleTeamTypes.Impostor || role.Role == RoleTypes.ImpostorGhost || customRoles.Contains(role) )
|
if (role.TeamType != RoleTeamTypes.Impostor || role.Role == RoleTypes.ImpostorGhost || customRoles.Contains(role) )
|
||||||
continue;
|
continue;
|
||||||
var gameObject = Object.Instantiate(__instance.impostorTypePrefab, __instance.impostorTypeParent);
|
GameObject gameObject = Object.Instantiate<GameObject>(__instance.impostorTypePrefab, __instance.impostorTypeParent);
|
||||||
__instance.impostorButton.Add(gameObject);
|
__instance.impostorButton.Add(gameObject);
|
||||||
gameObject.GetComponent<DetectiveImpostorType>().Initialize(__instance, role);
|
gameObject.GetComponent<DetectiveImpostorType>().Initialize(__instance, role);
|
||||||
|
num++;
|
||||||
__instance.ImpostorIconControllerSelectables.Add(gameObject.GetComponent<PassiveButton>());
|
__instance.ImpostorIconControllerSelectables.Add(gameObject.GetComponent<PassiveButton>());
|
||||||
}
|
}
|
||||||
ControllerManager.Instance.OpenOverlayMenu(__instance.ImpostorOverlay, __instance.impostorTypePopup, __instance.ImpostorIconControllerSelectables[0], __instance.ImpostorIconControllerSelectables, false);
|
ControllerManager.Instance.OpenOverlayMenu(__instance.ImpostorOverlay, null, __instance.ImpostorIconControllerSelectables[0], __instance.ImpostorIconControllerSelectables, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -7,6 +7,15 @@ namespace MiraAPI.Patches.Events;
|
|||||||
|
|
||||||
internal static class EndGamePatches
|
internal static class EndGamePatches
|
||||||
{
|
{
|
||||||
|
[HarmonyPatch(typeof(GameManager), nameof(GameManager.Awake))]
|
||||||
|
public static class GameManagerAwakePatch
|
||||||
|
{
|
||||||
|
public static void Postfix(GameManager __instance)
|
||||||
|
{
|
||||||
|
__instance.enabled = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[HarmonyPatch(typeof(GameManager), nameof(GameManager.RpcEndGame))]
|
[HarmonyPatch(typeof(GameManager), nameof(GameManager.RpcEndGame))]
|
||||||
public static class GameManagerRpcEndGamePatch
|
public static class GameManagerRpcEndGamePatch
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,20 +1,13 @@
|
|||||||
using System.Reflection;
|
using HarmonyLib;
|
||||||
using HarmonyLib;
|
|
||||||
using MiraAPI.Events;
|
using MiraAPI.Events;
|
||||||
using MiraAPI.Events.Vanilla.Gameplay;
|
using MiraAPI.Events.Vanilla.Gameplay;
|
||||||
using MiraAPI.Utilities;
|
|
||||||
|
|
||||||
namespace MiraAPI.Patches.Events;
|
namespace MiraAPI.Patches.Events;
|
||||||
|
|
||||||
[HarmonyPatch]
|
[HarmonyPatch(typeof(TutorialManager._RunTutorial_d__3), nameof(TutorialManager._RunTutorial_d__3.MoveNext))]
|
||||||
public static class FreeplayRoundStartPatch
|
public static class FreeplayRoundStartPatch
|
||||||
{
|
{
|
||||||
public static MethodBase TargetMethod()
|
public static void Postfix(TutorialManager._RunTutorial_d__3 __instance, ref bool __result)
|
||||||
{
|
|
||||||
return Helpers.GetStateMachineMoveNext<TutorialManager>(nameof(TutorialManager.RunTutorial))!;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void Postfix(ref bool __result)
|
|
||||||
{
|
{
|
||||||
if (!__result)
|
if (!__result)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,17 +0,0 @@
|
|||||||
using HarmonyLib;
|
|
||||||
using MiraAPI.Events;
|
|
||||||
using MiraAPI.Events.Vanilla.Player;
|
|
||||||
|
|
||||||
namespace MiraAPI.Patches.Events;
|
|
||||||
|
|
||||||
[HarmonyPatch(typeof(HideAndSeekManager))]
|
|
||||||
public static class HnsFinishTaskPatch
|
|
||||||
{
|
|
||||||
[HarmonyPostfix]
|
|
||||||
[HarmonyPatch(nameof(HideAndSeekManager.FinishTask))]
|
|
||||||
public static void FinishTaskPostfix(HideAndSeekManager __instance, PlayerTask task)
|
|
||||||
{
|
|
||||||
var completeTaskEvent = new CompleteHnsTaskEvent(__instance, task.Owner, task);
|
|
||||||
MiraEventManager.InvokeEvent(completeTaskEvent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
using System.Reflection;
|
|
||||||
using HarmonyLib;
|
|
||||||
using Il2CppInterop.Runtime.InteropTypes;
|
|
||||||
using MiraAPI.Events;
|
|
||||||
using MiraAPI.Events.Vanilla.Gameplay;
|
|
||||||
using MiraAPI.Utilities;
|
|
||||||
|
|
||||||
namespace MiraAPI.Patches.Events;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Patch to invoke AfterMurderEvent after a kill animation is performed.
|
|
||||||
/// </summary>
|
|
||||||
[HarmonyPatch]
|
|
||||||
public static class KillAnimationMurderEventPatch
|
|
||||||
{
|
|
||||||
public static MethodBase TargetMethod()
|
|
||||||
{
|
|
||||||
return Helpers.GetStateMachineMoveNext<KillAnimation>(nameof(KillAnimation.CoPerformKill))!;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void Postfix(Il2CppObjectBase __instance)
|
|
||||||
{
|
|
||||||
var wrapper = new StateMachineWrapper<KillAnimation>(__instance);
|
|
||||||
if (wrapper.GetState() != 1)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var source = wrapper.GetParameter<PlayerControl>("source");
|
|
||||||
var target = wrapper.GetParameter<PlayerControl>("target");
|
|
||||||
|
|
||||||
var afterMurderEvent = new AfterMurderEvent(source, target, Helpers.GetBodyById(target.PlayerId));
|
|
||||||
MiraEventManager.InvokeEvent(afterMurderEvent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
using HarmonyLib;
|
||||||
|
using MiraAPI.Events;
|
||||||
|
using MiraAPI.Events.Vanilla.Gameplay;
|
||||||
|
using MiraAPI.Utilities;
|
||||||
|
|
||||||
|
namespace MiraAPI.Patches.Events;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// General patches for the KillAnimation class.
|
||||||
|
/// </summary>
|
||||||
|
[HarmonyPatch]
|
||||||
|
public static class KillAnimationPatches
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Used to trigger the <see cref="AfterMurderEvent"/>.
|
||||||
|
/// </summary>
|
||||||
|
[HarmonyPostfix]
|
||||||
|
[HarmonyPatch(typeof(KillAnimation._CoPerformKill_d__2), nameof(KillAnimation._CoPerformKill_d__2.MoveNext))]
|
||||||
|
public static void KillAnimPostfix(KillAnimation._CoPerformKill_d__2 __instance)
|
||||||
|
{
|
||||||
|
// Checking if state is -1 to wait for the end of coroutine.
|
||||||
|
if (__instance.__1__state != -1)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var afterMurderEvent = new AfterMurderEvent(__instance.source, __instance.target, Helpers.GetBodyById(__instance.target.PlayerId));
|
||||||
|
MiraEventManager.InvokeEvent(afterMurderEvent);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -41,7 +41,7 @@ public static class ReportBodyEventPatch
|
|||||||
var source = AmongUsClient.Instance.FindObjectByNetId<PlayerControl>(reportBodyMessage.rpcObjectNetId);
|
var source = AmongUsClient.Instance.FindObjectByNetId<PlayerControl>(reportBodyMessage.rpcObjectNetId);
|
||||||
if (source == null)
|
if (source == null)
|
||||||
{
|
{
|
||||||
Error("Failed to find source player for RpcReportDeadBodyMessage with NetId: " + reportBodyMessage.rpcObjectNetId);
|
Logger<MiraApiPlugin>.Error("Failed to find source player for RpcReportDeadBodyMessage with NetId: " + reportBodyMessage.rpcObjectNetId);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
/*
|
using HarmonyLib;
|
||||||
using HarmonyLib;
|
|
||||||
using MiraAPI.Events;
|
using MiraAPI.Events;
|
||||||
using MiraAPI.Events.Vanilla.Gameplay;
|
using MiraAPI.Events.Vanilla.Gameplay;
|
||||||
|
|
||||||
@@ -19,4 +18,3 @@ internal static class SpawnInMinigamePatch
|
|||||||
MiraEventManager.InvokeEvent(@event2);
|
MiraEventManager.InvokeEvent(@event2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
/*
|
using System.Collections.Generic;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using HarmonyLib;
|
using HarmonyLib;
|
||||||
using MiraAPI.Events;
|
using MiraAPI.Events;
|
||||||
@@ -35,4 +34,3 @@ internal static class SubmergedSpawnGamePatch
|
|||||||
MiraEventManager.InvokeEvent(@event2);
|
MiraEventManager.InvokeEvent(@event2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
@@ -21,14 +21,10 @@ using Object = UnityEngine.Object;
|
|||||||
namespace MiraAPI.Patches.Freeplay;
|
namespace MiraAPI.Patches.Freeplay;
|
||||||
|
|
||||||
[HarmonyPatch(typeof(TaskAdderGame))]
|
[HarmonyPatch(typeof(TaskAdderGame))]
|
||||||
public static class TaskAdderPatches
|
internal static class TaskAdderPatches
|
||||||
{
|
{
|
||||||
private static Scroller _scroller = null!;
|
private static Scroller _scroller = null!;
|
||||||
private static Dictionary<string, TaskFolder> folders = new();
|
private static Dictionary<string, TaskFolder> folders = new();
|
||||||
public static string CrewmateName => TranslationController.Instance.GetString(StringNames.Crewmate);
|
|
||||||
public static string ImpostorName => TranslationController.Instance.GetString(StringNames.Impostor);
|
|
||||||
public static string NeutralName => "Neutral";
|
|
||||||
public static string ModifiersName => "Modifiers";
|
|
||||||
|
|
||||||
[HarmonyPostfix]
|
[HarmonyPostfix]
|
||||||
[HarmonyPatch(nameof(TaskAdderGame.Begin))]
|
[HarmonyPatch(nameof(TaskAdderGame.Begin))]
|
||||||
@@ -70,16 +66,19 @@ public static class TaskAdderPatches
|
|||||||
__instance.RootFolderPrefab.GetComponent<PassiveButton>().ClickMask = collider;
|
__instance.RootFolderPrefab.GetComponent<PassiveButton>().ClickMask = collider;
|
||||||
__instance.RootFolderPrefab.gameObject.SetActive(false);
|
__instance.RootFolderPrefab.gameObject.SetActive(false);
|
||||||
__instance.TaskParent = inner.transform;
|
__instance.TaskParent = inner.transform;
|
||||||
var crewmateFolder = __instance.Root.SubFolders.ToArray().FirstOrDefault(x => x.FolderName == CrewmateName)!;
|
var crewLocale = TranslationController.Instance.GetString(StringNames.Crewmate);
|
||||||
var impostorFolder = __instance.Root.SubFolders.ToArray().FirstOrDefault(x => x.FolderName == ImpostorName)!;
|
var impLocale = TranslationController.Instance.GetString(StringNames.Impostor);
|
||||||
|
|
||||||
|
var crewmateFolder = __instance.Root.SubFolders.ToArray().FirstOrDefault(x => x.FolderName == crewLocale)!;
|
||||||
|
var impostorFolder = __instance.Root.SubFolders.ToArray().FirstOrDefault(x => x.FolderName == impLocale)!;
|
||||||
//var neutralFolder = __instance.CreateFolder("Neutral", __instance.Root, 2, Color.gray);
|
//var neutralFolder = __instance.CreateFolder("Neutral", __instance.Root, 2, Color.gray);
|
||||||
var modifiersFolder = __instance.CreateFolder(ModifiersName, __instance.Root, 0, Color.blue);
|
var modifiersFolder = __instance.CreateFolder("Modifiers", __instance.Root, 0, Color.blue);
|
||||||
|
|
||||||
folders.Clear();
|
folders.Clear();
|
||||||
folders.Add(crewmateFolder.FolderName, crewmateFolder);
|
folders.Add(crewmateFolder.FolderName, crewmateFolder);
|
||||||
folders.Add(impostorFolder.FolderName, impostorFolder);
|
folders.Add(impostorFolder.FolderName, impostorFolder);
|
||||||
//folders.Add("Neutrals", neutralFolder);
|
//folders.Add("Neutrals", neutralFolder);
|
||||||
folders.Add(ModifiersName, modifiersFolder);
|
folders.Add("Modifiers", modifiersFolder);
|
||||||
|
|
||||||
int folderIdx = 2;
|
int folderIdx = 2;
|
||||||
foreach (var plugin in MiraPluginManager.Instance.RegisteredPlugins)
|
foreach (var plugin in MiraPluginManager.Instance.RegisteredPlugins)
|
||||||
@@ -138,8 +137,8 @@ public static class TaskAdderPatches
|
|||||||
Object.Instantiate(__instance.RootFolderPrefab, __instance.transform);
|
Object.Instantiate(__instance.RootFolderPrefab, __instance.transform);
|
||||||
impFolder.gameObject.SetActive(false);
|
impFolder.gameObject.SetActive(false);
|
||||||
impFolder.SetFolderColor(TaskFolder.FolderColor.Red);
|
impFolder.SetFolderColor(TaskFolder.FolderColor.Red);
|
||||||
crewFolder.FolderName = CrewmateName;
|
crewFolder.FolderName = TranslationController.Instance.GetString(StringNames.Crewmate);
|
||||||
impFolder.FolderName = ImpostorName;
|
impFolder.FolderName = TranslationController.Instance.GetString(StringNames.Impostor);
|
||||||
rootFolder.SubFolders.Insert(0, crewFolder);
|
rootFolder.SubFolders.Insert(0, crewFolder);
|
||||||
rootFolder.SubFolders.Insert(0, impFolder);
|
rootFolder.SubFolders.Insert(0, impFolder);
|
||||||
Il2CppSystem.Collections.Generic.List<RoleBehaviour> impRoles = new();
|
Il2CppSystem.Collections.Generic.List<RoleBehaviour> impRoles = new();
|
||||||
@@ -441,7 +440,7 @@ public static class TaskAdderPatches
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (folders.TryGetValue(ModifiersName, out var modifiersFolder) && taskFolder.IsChildOf(modifiersFolder))
|
if (folders.TryGetValue("Modifiers", out var modifiersFolder) && taskFolder.IsChildOf(modifiersFolder))
|
||||||
{
|
{
|
||||||
var plugin = MiraPluginManager.GetPluginByGuid(taskFolder.name.Replace("(Clone)", string.Empty));
|
var plugin = MiraPluginManager.GetPluginByGuid(taskFolder.name.Replace("(Clone)", string.Empty));
|
||||||
if (plugin != null)
|
if (plugin != null)
|
||||||
|
|||||||
@@ -9,11 +9,6 @@ namespace MiraAPI.Patches.Hud;
|
|||||||
public static class ButtonResetPatches
|
public static class ButtonResetPatches
|
||||||
{
|
{
|
||||||
public static void Postfix()
|
public static void Postfix()
|
||||||
{
|
|
||||||
ResetCooldowns();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void ResetCooldowns()
|
|
||||||
{
|
{
|
||||||
foreach (var customActionButton in CustomButtonManager.CustomButtons)
|
foreach (var customActionButton in CustomButtonManager.CustomButtons)
|
||||||
{
|
{
|
||||||
@@ -23,7 +18,7 @@ public static class ButtonResetPatches
|
|||||||
}
|
}
|
||||||
catch (System.Exception ex)
|
catch (System.Exception ex)
|
||||||
{
|
{
|
||||||
Error($"Error resetting cooldown and effect for button {customActionButton.GetType().Name}: {ex}");
|
Logger<MiraApiPlugin>.Error($"Error resetting cooldown and effect for button {customActionButton.GetType().Name}: {ex}");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (customActionButton.UsesMode == ButtonUsesMode.PerRound)
|
if (customActionButton.UsesMode == ButtonUsesMode.PerRound)
|
||||||
|
|||||||
@@ -27,8 +27,6 @@ public static class HudManagerPatches
|
|||||||
|
|
||||||
private static Dictionary<TextMeshPro, int> vanillaKeybindIcons = new();
|
private static Dictionary<TextMeshPro, int> vanillaKeybindIcons = new();
|
||||||
|
|
||||||
internal static List<TextMeshPro> ModdedKeybindIcons = new();
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Trigger hudstart on current custom gamemode
|
/// Trigger hudstart on current custom gamemode
|
||||||
@@ -75,22 +73,17 @@ public static class HudManagerPatches
|
|||||||
gridArrange.Alignment = GridArrange.StartAlign.Right;
|
gridArrange.Alignment = GridArrange.StartAlign.Right;
|
||||||
aspectPosition.Alignment = AspectPosition.EdgeAlignments.LeftBottom;
|
aspectPosition.Alignment = AspectPosition.EdgeAlignments.LeftBottom;
|
||||||
|
|
||||||
if (Constants.GetPlatformType() is Platforms.Android or Platforms.IPhone)
|
var fakeButton = Object.Instantiate(__instance.AbilityButton, BottomLeft.transform);
|
||||||
|
foreach (var renderer in fakeButton.GetComponentsInChildren<Renderer>())
|
||||||
{
|
{
|
||||||
var fakeButton = Object.Instantiate(__instance.AbilityButton, BottomLeft.transform);
|
renderer.enabled = false;
|
||||||
foreach (var renderer in fakeButton.GetComponentsInChildren<Renderer>())
|
|
||||||
{
|
|
||||||
renderer.enabled = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
fakeButton.buttonLabelText.Destroy();
|
|
||||||
fakeButton.cooldownTimerText.Destroy();
|
|
||||||
fakeButton.usesRemainingText.Destroy();
|
|
||||||
fakeButton.GetComponent<PassiveButton>().Destroy();
|
|
||||||
fakeButton.ToggleVisible(true);
|
|
||||||
fakeButton.Destroy();
|
|
||||||
}
|
}
|
||||||
ModdedKeybindIcons = [];
|
fakeButton.buttonLabelText.Destroy();
|
||||||
|
fakeButton.cooldownTimerText.Destroy();
|
||||||
|
fakeButton.usesRemainingText.Destroy();
|
||||||
|
fakeButton.GetComponent<PassiveButton>().Destroy();
|
||||||
|
fakeButton.ToggleVisible(true);
|
||||||
|
fakeButton.Destroy();
|
||||||
|
|
||||||
foreach (var button in CustomButtonManager.CustomButtons)
|
foreach (var button in CustomButtonManager.CustomButtons)
|
||||||
{
|
{
|
||||||
@@ -112,18 +105,16 @@ public static class HudManagerPatches
|
|||||||
}
|
}
|
||||||
catch (System.Exception e)
|
catch (System.Exception e)
|
||||||
{
|
{
|
||||||
Error($"Failed to create custom button {button.GetType().Name}: {e}");
|
Logger<MiraApiPlugin>.Error($"Failed to create custom button {button.GetType().Name}: {e}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
__instance.ImpostorVentButton.transform.SetParent(null);
|
|
||||||
__instance.ImpostorVentButton.transform.SetParent(BottomRight.transform);
|
|
||||||
|
|
||||||
gridArrange.Start();
|
gridArrange.Start();
|
||||||
gridArrange.ArrangeChilds();
|
gridArrange.ArrangeChilds();
|
||||||
aspectPosition.AdjustPosition();
|
aspectPosition.AdjustPosition();
|
||||||
|
|
||||||
vanillaKeybindIcons = [];
|
vanillaKeybindIcons = [];
|
||||||
var keybindIconPos = new Vector3(0.4f, 0.4f, -9.5f);
|
var keybindIconPos = new Vector3(-0.4f, 0.4f, -9.5f);
|
||||||
var vanillaButtons = new Dictionary<GameObject, int>
|
var vanillaButtons = new Dictionary<GameObject, int>
|
||||||
{
|
{
|
||||||
{ __instance.KillButton.gameObject, 8 },
|
{ __instance.KillButton.gameObject, 8 },
|
||||||
@@ -176,7 +167,7 @@ public static class HudManagerPatches
|
|||||||
}
|
}
|
||||||
catch (System.Exception e)
|
catch (System.Exception e)
|
||||||
{
|
{
|
||||||
Error($"Failed to set custom button {button.GetType().Name} active: {e}");
|
Logger<MiraApiPlugin>.Error($"Failed to set custom button {button.GetType().Name} active: {e}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -185,16 +176,11 @@ public static class HudManagerPatches
|
|||||||
[HarmonyPostfix]
|
[HarmonyPostfix]
|
||||||
public static void UpdatePostfix()
|
public static void UpdatePostfix()
|
||||||
{
|
{
|
||||||
var canSeeBinds = ActiveInputManager.currentControlType == ActiveInputManager.InputType.Keyboard &&
|
|
||||||
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(ActiveInputManager.currentControlType == ActiveInputManager.InputType.Keyboard &&
|
||||||
}
|
LocalSettingsTabSingleton<MiraApiSettings>.Instance.ShowKeybinds.Value);
|
||||||
foreach (var btnIcon in ModdedKeybindIcons)
|
|
||||||
{
|
|
||||||
btnIcon.transform.parent.gameObject.SetActive(canSeeBinds);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var player = ReInput.players.GetPlayer(0);
|
var player = ReInput.players.GetPlayer(0);
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ public static class IntroCutscenePatches
|
|||||||
{
|
{
|
||||||
public static MethodBase TargetMethod()
|
public static MethodBase TargetMethod()
|
||||||
{
|
{
|
||||||
return Helpers.GetStateMachineMoveNext<IntroCutscene>(nameof(IntroCutscene.ShowRole))!;
|
return Helpers.GetStateMachineMoveNext<IntroCutscene>("ShowRole")!;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Postfix(Il2CppObjectBase __instance)
|
public static void Postfix(Il2CppObjectBase __instance)
|
||||||
@@ -52,7 +52,7 @@ public static class IntroCutscenePatches
|
|||||||
|
|
||||||
var introCutscene = wrapper.Instance;
|
var introCutscene = wrapper.Instance;
|
||||||
|
|
||||||
Info("IntroCutscene ShowRole reached");
|
Logger<MiraApiPlugin>.Info("IntroCutscene ShowRole reached");
|
||||||
var @event = new IntroRoleRevealEvent(introCutscene);
|
var @event = new IntroRoleRevealEvent(introCutscene);
|
||||||
MiraEventManager.InvokeEvent(@event);
|
MiraEventManager.InvokeEvent(@event);
|
||||||
}
|
}
|
||||||
@@ -96,12 +96,12 @@ public static class IntroCutscenePatches
|
|||||||
if (onDestroy != null)
|
if (onDestroy != null)
|
||||||
{
|
{
|
||||||
_usedFallback = false;
|
_usedFallback = false;
|
||||||
Info("Using OnDestroy for IntroCutsceneDestroyPatch");
|
Logger<MiraApiPlugin>.Info("Using OnDestroy for IntroCutsceneDestroyPatch");
|
||||||
return onDestroy;
|
return onDestroy;
|
||||||
}
|
}
|
||||||
|
|
||||||
_usedFallback = true;
|
_usedFallback = true;
|
||||||
return Helpers.GetStateMachineMoveNext<IntroCutscene>(nameof(IntroCutscene.CoBegin))!;
|
return Helpers.GetStateMachineMoveNext<IntroCutscene>("CoBegin")!;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Postfix(Il2CppObjectBase __instance)
|
public static void Postfix(Il2CppObjectBase __instance)
|
||||||
@@ -124,7 +124,7 @@ public static class IntroCutscenePatches
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Info("IntroCutscene ended");
|
Logger<MiraApiPlugin>.Info("IntroCutscene ended");
|
||||||
|
|
||||||
MiraEventManager.InvokeEvent(new IntroEndEvent(introCutscene));
|
MiraEventManager.InvokeEvent(new IntroEndEvent(introCutscene));
|
||||||
|
|
||||||
|
|||||||
@@ -15,8 +15,7 @@ namespace MiraAPI.Patches.Keybinds;
|
|||||||
[HarmonyPatch(typeof(ControlMapper))]
|
[HarmonyPatch(typeof(ControlMapper))]
|
||||||
public static class ControlMapperPatches
|
public static class ControlMapperPatches
|
||||||
{
|
{
|
||||||
// Patching this crashes for Epic Games users
|
[HarmonyPrefix]
|
||||||
/*[HarmonyPrefix]
|
|
||||||
[HarmonyPatch(nameof(ControlMapper.Start))]
|
[HarmonyPatch(nameof(ControlMapper.Start))]
|
||||||
private static void StartPrefix(ControlMapper __instance)
|
private static void StartPrefix(ControlMapper __instance)
|
||||||
{
|
{
|
||||||
@@ -38,7 +37,7 @@ public static class ControlMapperPatches
|
|||||||
entry.Value = !entry.Value;
|
entry.Value = !entry.Value;
|
||||||
text.text = $"Show Keybinds: {(entry.Value ? "On" : "Off")}";
|
text.text = $"Show Keybinds: {(entry.Value ? "On" : "Off")}";
|
||||||
}));
|
}));
|
||||||
}*/
|
}
|
||||||
|
|
||||||
[HarmonyPrefix]
|
[HarmonyPrefix]
|
||||||
[HarmonyPatch(nameof(ControlMapper.Update))]
|
[HarmonyPatch(nameof(ControlMapper.Update))]
|
||||||
|
|||||||
@@ -32,20 +32,11 @@ internal static class GameOptionsMenuPatch
|
|||||||
{
|
{
|
||||||
ModifiersUpdate(ref num);
|
ModifiersUpdate(ref num);
|
||||||
}
|
}
|
||||||
else if (__instance.name == "CUSTOM TAB 1")
|
|
||||||
{
|
|
||||||
CustomMenuOneUpdate(ref num);
|
|
||||||
}
|
|
||||||
else if (__instance.name == "CUSTOM TAB 2")
|
|
||||||
{
|
|
||||||
CustomMenuTwoUpdate(ref num);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var filteredGroups =
|
var filteredGroups =
|
||||||
GameSettingMenuPatches.SelectedMod?.InternalOptionGroups
|
GameSettingMenuPatches.SelectedMod?.InternalOptionGroups
|
||||||
.Where(x => x.OptionableType == null &&
|
.Where(x => x.OptionableType == null && !x.ShowInModifiersMenu) ?? [];
|
||||||
!x.ShowInModifiersMenu && x.ParentMenu == MenuCategory.Roles) ?? [];
|
|
||||||
|
|
||||||
foreach (var group in filteredGroups)
|
foreach (var group in filteredGroups)
|
||||||
{
|
{
|
||||||
@@ -108,48 +99,6 @@ internal static class GameOptionsMenuPatch
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void CustomMenuOneUpdate(ref float num)
|
|
||||||
{
|
|
||||||
var groups = GameSettingMenuPatches.SelectedMod?.InternalOptionGroups
|
|
||||||
.Where(x => x.ParentMenu == MenuCategory.CustomOne) ?? [];
|
|
||||||
|
|
||||||
foreach (var modGroup in groups)
|
|
||||||
{
|
|
||||||
UpdateGroup(modGroup, ref num);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void CustomMenuOneCreate(GameOptionsMenu menu)
|
|
||||||
{
|
|
||||||
var groups = GameSettingMenuPatches.SelectedMod?.InternalOptionGroups
|
|
||||||
.Where(x => x.ParentMenu == MenuCategory.CustomOne) ?? [];
|
|
||||||
foreach (var group in groups)
|
|
||||||
{
|
|
||||||
CreateGroup(menu, group);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void CustomMenuTwoUpdate(ref float num)
|
|
||||||
{
|
|
||||||
var groups = GameSettingMenuPatches.SelectedMod?.InternalOptionGroups
|
|
||||||
.Where(x => x.ParentMenu == MenuCategory.CustomTwo) ?? [];
|
|
||||||
|
|
||||||
foreach (var modGroup in groups)
|
|
||||||
{
|
|
||||||
UpdateGroup(modGroup, ref num);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void CustomMenuTwoCreate(GameOptionsMenu menu)
|
|
||||||
{
|
|
||||||
var groups = GameSettingMenuPatches.SelectedMod?.InternalOptionGroups
|
|
||||||
.Where(x => x.ParentMenu == MenuCategory.CustomTwo) ?? [];
|
|
||||||
foreach (var group in groups)
|
|
||||||
{
|
|
||||||
CreateGroup(menu, group);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void ModifiersUpdate(ref float num)
|
private static void ModifiersUpdate(ref float num)
|
||||||
{
|
{
|
||||||
var groups = GameSettingMenuPatches.SelectedMod?.InternalOptionGroups
|
var groups = GameSettingMenuPatches.SelectedMod?.InternalOptionGroups
|
||||||
@@ -188,19 +137,9 @@ internal static class GameOptionsMenuPatch
|
|||||||
ModifiersCreate(__instance);
|
ModifiersCreate(__instance);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else if (__instance.name == "CUSTOM TAB 1")
|
|
||||||
{
|
|
||||||
CustomMenuOneCreate(__instance);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else if (__instance.name == "CUSTOM TAB 2")
|
|
||||||
{
|
|
||||||
CustomMenuTwoCreate(__instance);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
var filteredGroups = GameSettingMenuPatches.SelectedMod?.InternalOptionGroups
|
var filteredGroups = GameSettingMenuPatches.SelectedMod?.InternalOptionGroups
|
||||||
.Where(x => x.OptionableType == null && !x.ShowInModifiersMenu && x.ParentMenu == MenuCategory.Roles) ?? [];
|
.Where(x => x.OptionableType == null && !x.ShowInModifiersMenu) ?? [];
|
||||||
|
|
||||||
foreach (var group in filteredGroups)
|
foreach (var group in filteredGroups)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -117,7 +117,7 @@ internal static class GamePresetsTabPatches
|
|||||||
// ReSharper disable once InconsistentNaming
|
// ReSharper disable once InconsistentNaming
|
||||||
public static void Postfix()
|
public static void Postfix()
|
||||||
{
|
{
|
||||||
Error("OnDisable called");
|
Logger<MiraApiPlugin>.Error("OnDisable called");
|
||||||
|
|
||||||
if (_saveButton)
|
if (_saveButton)
|
||||||
{
|
{
|
||||||
@@ -155,7 +155,7 @@ internal static class GamePresetsTabPatches
|
|||||||
var prefab = GameSettingMenu.Instance.GameSettingsButton;
|
var prefab = GameSettingMenu.Instance.GameSettingsButton;
|
||||||
if (prefab == null)
|
if (prefab == null)
|
||||||
{
|
{
|
||||||
Error("GameSettingsButton prefab is null");
|
Logger<MiraApiPlugin>.Error("GameSettingsButton prefab is null");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -318,10 +318,10 @@ internal static class GamePresetsTabPatches
|
|||||||
|
|
||||||
private static void Refresh()
|
private static void Refresh()
|
||||||
{
|
{
|
||||||
Error("Refreshing presets");
|
Logger<MiraApiPlugin>.Error("Refreshing presets");
|
||||||
if (GameSettingMenuPatches.SelectedMod == null)
|
if (GameSettingMenuPatches.SelectedMod == null)
|
||||||
{
|
{
|
||||||
Error("Selected mod is null, cannot refresh presets");
|
Logger<MiraApiPlugin>.Error("Selected mod is null, cannot refresh presets");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
lock (Lock)
|
lock (Lock)
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using HarmonyLib;
|
using HarmonyLib;
|
||||||
using MiraAPI.GameOptions;
|
|
||||||
using MiraAPI.Modifiers;
|
using MiraAPI.Modifiers;
|
||||||
using MiraAPI.PluginLoading;
|
using MiraAPI.PluginLoading;
|
||||||
using MiraAPI.Presets;
|
using MiraAPI.Presets;
|
||||||
@@ -28,23 +27,13 @@ internal static class GameSettingMenuPatches
|
|||||||
private static Vector3 _roleBtnOgPos;
|
private static Vector3 _roleBtnOgPos;
|
||||||
private static Vector3 _smallRoleBtnOgPos;
|
private static Vector3 _smallRoleBtnOgPos;
|
||||||
private static Vector3 _modifierBtnOgPos;
|
private static Vector3 _modifierBtnOgPos;
|
||||||
private static Vector3 _customOneBtnOgPos;
|
|
||||||
private static Vector3 _customTwoBtnOgPos;
|
|
||||||
|
|
||||||
private static GameOptionsMenu? _modifiersTab;
|
private static GameOptionsMenu? _modifiersTab;
|
||||||
private static PassiveButton? _modifiersButton;
|
private static PassiveButton? _modifiersButton;
|
||||||
private static PassiveButton? _smallRolesButton;
|
private static PassiveButton? _smallRolesButton;
|
||||||
private static GameOptionsMenu? _customOneTab;
|
|
||||||
private static PassiveButton? _customOneButton;
|
|
||||||
private static GameOptionsMenu? _customTwoTab;
|
|
||||||
private static PassiveButton? _customTwoButton;
|
|
||||||
private static GameObject? _nextModButton;
|
|
||||||
private static GameObject? _previousModButton;
|
|
||||||
|
|
||||||
private static Dictionary<int, Vector3> OptionsPositions { get; } = [];
|
private static Dictionary<int, Vector3> OptionsPositions { get; } = [];
|
||||||
private static Dictionary<int, Vector3> ModifiersPositions { get; } = [];
|
private static Dictionary<int, Vector3> ModifiersPositions { get; } = [];
|
||||||
private static Dictionary<int, Vector3> CustomOnePositions { get; } = [];
|
|
||||||
private static Dictionary<int, Vector3> CustomTwoPositions { get; } = [];
|
|
||||||
|
|
||||||
private static void SaveScrollPositions(GameSettingMenu gameSettingMenu)
|
private static void SaveScrollPositions(GameSettingMenu gameSettingMenu)
|
||||||
{
|
{
|
||||||
@@ -52,14 +41,6 @@ internal static class GameSettingMenuPatches
|
|||||||
{
|
{
|
||||||
ModifiersPositions[SelectedModIdx] = _modifiersTab!.scrollBar.Inner.localPosition;
|
ModifiersPositions[SelectedModIdx] = _modifiersTab!.scrollBar.Inner.localPosition;
|
||||||
}
|
}
|
||||||
else if (_customOneTab)
|
|
||||||
{
|
|
||||||
CustomOnePositions[SelectedModIdx] = _customOneTab!.scrollBar.Inner.localPosition;
|
|
||||||
}
|
|
||||||
else if (_customTwoTab)
|
|
||||||
{
|
|
||||||
CustomTwoPositions[SelectedModIdx] = _customTwoTab!.scrollBar.Inner.localPosition;
|
|
||||||
}
|
|
||||||
|
|
||||||
RoleSettingMenuPatches.RolePositions[SelectedModIdx] = gameSettingMenu.RoleSettingsTab.scrollBar.Inner.localPosition;
|
RoleSettingMenuPatches.RolePositions[SelectedModIdx] = gameSettingMenu.RoleSettingsTab.scrollBar.Inner.localPosition;
|
||||||
OptionsPositions[SelectedModIdx] = gameSettingMenu.GameSettingsTab.scrollBar.Inner.localPosition;
|
OptionsPositions[SelectedModIdx] = gameSettingMenu.GameSettingsTab.scrollBar.Inner.localPosition;
|
||||||
@@ -84,21 +65,9 @@ internal static class GameSettingMenuPatches
|
|||||||
_modifiersTab!.gameObject.SetActive(tabNum == 3);
|
_modifiersTab!.gameObject.SetActive(tabNum == 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_customOneTab)
|
|
||||||
{
|
|
||||||
_customOneTab!.gameObject.SetActive(tabNum == 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_customTwoTab)
|
|
||||||
{
|
|
||||||
_customTwoTab!.gameObject.SetActive(tabNum == 5);
|
|
||||||
}
|
|
||||||
|
|
||||||
_modifiersButton?.SelectButton(tabNum == 3);
|
_modifiersButton?.SelectButton(tabNum == 3);
|
||||||
_smallRolesButton?.SelectButton(tabNum == 2);
|
_smallRolesButton?.SelectButton(tabNum == 2);
|
||||||
_customOneButton?.SelectButton(tabNum == 4);
|
if (tabNum == 3)
|
||||||
_customTwoButton?.SelectButton(tabNum == 5);
|
|
||||||
if (tabNum >= 3 && tabNum <= 5)
|
|
||||||
{
|
{
|
||||||
if (__instance.RoleSettingsButton.gameObject.active)
|
if (__instance.RoleSettingsButton.gameObject.active)
|
||||||
{
|
{
|
||||||
@@ -106,21 +75,7 @@ internal static class GameSettingMenuPatches
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
switch (tabNum)
|
_modifiersButton?.SelectButton(true);
|
||||||
{
|
|
||||||
case 3:
|
|
||||||
_modifiersButton?.SelectButton(true);
|
|
||||||
__instance.MenuDescriptionText.text = SelectedMod != null ? SelectedMod.MiraPlugin.ModifierMenuDescription : "Configure modifiers and their settings here!";
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
_customOneButton?.SelectButton(true);
|
|
||||||
__instance.MenuDescriptionText.text = SelectedMod != null ? SelectedMod.MiraPlugin.CustomOptionMenuOneDescription : "Apply game settings for this mod!";
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
_customTwoButton?.SelectButton(true);
|
|
||||||
__instance.MenuDescriptionText.text = SelectedMod != null ? SelectedMod.MiraPlugin.CustomOptionMenuTwoDescription : "Apply game settings for this mod!";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -132,30 +87,19 @@ internal static class GameSettingMenuPatches
|
|||||||
|
|
||||||
_modifiersButton?.SelectButton(tabNum == 3);
|
_modifiersButton?.SelectButton(tabNum == 3);
|
||||||
_smallRolesButton?.SelectButton(tabNum == 2);
|
_smallRolesButton?.SelectButton(tabNum == 2);
|
||||||
_customOneButton?.SelectButton(tabNum == 4);
|
|
||||||
_customTwoButton?.SelectButton(tabNum == 5);
|
|
||||||
|
|
||||||
if (tabNum >= 3 && tabNum <= 5)
|
if (tabNum != 3)
|
||||||
{
|
{
|
||||||
if (__instance.RoleSettingsButton.gameObject.active)
|
return;
|
||||||
{
|
}
|
||||||
__instance.RoleSettingsButton.SelectButton(true);
|
|
||||||
}
|
if (__instance.RoleSettingsButton.gameObject.active)
|
||||||
else
|
{
|
||||||
{
|
__instance.RoleSettingsButton.SelectButton(true);
|
||||||
switch (tabNum)
|
}
|
||||||
{
|
else
|
||||||
case 3:
|
{
|
||||||
_modifiersButton?.SelectButton(true);
|
_modifiersButton?.SelectButton(true);
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
_customOneButton?.SelectButton(true);
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
_customTwoButton?.SelectButton(true);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -183,16 +127,16 @@ internal static class GameSettingMenuPatches
|
|||||||
|
|
||||||
_text.alignment = TextAlignmentOptions.Center;
|
_text.alignment = TextAlignmentOptions.Center;
|
||||||
|
|
||||||
_nextModButton = Object.Instantiate(__instance.BackButton, __instance.BackButton.transform.parent).gameObject;
|
var nextButton = Object.Instantiate(__instance.BackButton, __instance.BackButton.transform.parent).gameObject;
|
||||||
_nextModButton.transform.localPosition = new Vector3(-2.2663f, 1.5272f, -25f);
|
nextButton.transform.localPosition = new Vector3(-2.2663f, 1.5272f, -25f);
|
||||||
_nextModButton.name = "RightArrowButton";
|
nextButton.name = "RightArrowButton";
|
||||||
_nextModButton.transform.FindChild("Inactive").gameObject.GetComponent<SpriteRenderer>().sprite =
|
nextButton.transform.FindChild("Inactive").gameObject.GetComponent<SpriteRenderer>().sprite =
|
||||||
MiraAssets.NextButton.LoadAsset();
|
MiraAssets.NextButton.LoadAsset();
|
||||||
_nextModButton.transform.FindChild("Active").gameObject.GetComponent<SpriteRenderer>().sprite =
|
nextButton.transform.FindChild("Active").gameObject.GetComponent<SpriteRenderer>().sprite =
|
||||||
MiraAssets.NextButtonActive.LoadAsset();
|
MiraAssets.NextButtonActive.LoadAsset();
|
||||||
_nextModButton.gameObject.GetComponent<CloseButtonConsoleBehaviour>().DestroyImmediate();
|
nextButton.gameObject.GetComponent<CloseButtonConsoleBehaviour>().DestroyImmediate();
|
||||||
|
|
||||||
var passiveButton = _nextModButton.gameObject.GetComponent<PassiveButton>();
|
var passiveButton = nextButton.gameObject.GetComponent<PassiveButton>();
|
||||||
passiveButton.OnClick = new ButtonClickedEvent();
|
passiveButton.OnClick = new ButtonClickedEvent();
|
||||||
passiveButton.OnClick.AddListener(
|
passiveButton.OnClick.AddListener(
|
||||||
(UnityAction)(() =>
|
(UnityAction)(() =>
|
||||||
@@ -207,13 +151,13 @@ internal static class GameSettingMenuPatches
|
|||||||
UpdateText(__instance, __instance.GameSettingsTab, __instance.RoleSettingsTab);
|
UpdateText(__instance, __instance.GameSettingsTab, __instance.RoleSettingsTab);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
_previousModButton = Object.Instantiate(_nextModButton, __instance.BackButton.transform.parent).gameObject;
|
var backButton = Object.Instantiate(nextButton, __instance.BackButton.transform.parent).gameObject;
|
||||||
_previousModButton.transform.localPosition = new Vector3(-4.4209f, 1.5272f, -25f);
|
backButton.transform.localPosition = new Vector3(-4.4209f, 1.5272f, -25f);
|
||||||
_previousModButton.name = "LeftArrowButton";
|
backButton.name = "LeftArrowButton";
|
||||||
_previousModButton.gameObject.GetComponent<CloseButtonConsoleBehaviour>().Destroy();
|
backButton.gameObject.GetComponent<CloseButtonConsoleBehaviour>().Destroy();
|
||||||
_previousModButton.transform.FindChild("Active").gameObject.GetComponent<SpriteRenderer>().flipX =
|
backButton.transform.FindChild("Active").gameObject.GetComponent<SpriteRenderer>().flipX =
|
||||||
_previousModButton.transform.FindChild("Inactive").gameObject.GetComponent<SpriteRenderer>().flipX = true;
|
backButton.transform.FindChild("Inactive").gameObject.GetComponent<SpriteRenderer>().flipX = true;
|
||||||
_previousModButton.gameObject.GetComponent<PassiveButton>().OnClick.AddListener(
|
backButton.gameObject.GetComponent<PassiveButton>().OnClick.AddListener(
|
||||||
(UnityAction)(() =>
|
(UnityAction)(() =>
|
||||||
{
|
{
|
||||||
SaveScrollPositions(__instance);
|
SaveScrollPositions(__instance);
|
||||||
@@ -230,61 +174,6 @@ internal static class GameSettingMenuPatches
|
|||||||
_modifiersTab = Object.Instantiate(__instance.GameSettingsTab, __instance.GameSettingsTab.transform.parent);
|
_modifiersTab = Object.Instantiate(__instance.GameSettingsTab, __instance.GameSettingsTab.transform.parent);
|
||||||
_modifiersTab.name = "MODIFIERS TAB";
|
_modifiersTab.name = "MODIFIERS TAB";
|
||||||
|
|
||||||
// clone game settings tab for both custom tabs
|
|
||||||
_customOneTab = Object.Instantiate(__instance.GameSettingsTab, __instance.GameSettingsTab.transform.parent);
|
|
||||||
_customOneTab.name = "CUSTOM TAB 1";
|
|
||||||
_customTwoTab = Object.Instantiate(__instance.GameSettingsTab, __instance.GameSettingsTab.transform.parent);
|
|
||||||
_customTwoTab.name = "CUSTOM TAB 2";
|
|
||||||
|
|
||||||
// create button for the first custom category
|
|
||||||
var customPos = new Vector3(
|
|
||||||
__instance.RoleSettingsButton.transform.localPosition.x,
|
|
||||||
__instance.RoleSettingsButton.transform.localPosition.y,
|
|
||||||
__instance.RoleSettingsButton.transform.localPosition.z);
|
|
||||||
_customOneButton = Object.Instantiate(__instance.RoleSettingsButton, __instance.RoleSettingsButton.transform.parent);
|
|
||||||
_customOneButton.buttonText.gameObject.GetComponent<TextTranslatorTMP>().Destroy();
|
|
||||||
_customOneButton.OnClick = new ButtonClickedEvent();
|
|
||||||
_customOneButton.OnClick.AddListener(
|
|
||||||
(UnityAction)(() =>
|
|
||||||
{
|
|
||||||
__instance.ChangeTab(4, false);
|
|
||||||
}));
|
|
||||||
_customOneButton.OnMouseOver = new UnityEvent();
|
|
||||||
_customOneButton.OnMouseOver.AddListener(
|
|
||||||
(UnityAction)(() =>
|
|
||||||
{
|
|
||||||
__instance.ChangeTab(4, true);
|
|
||||||
}));
|
|
||||||
|
|
||||||
_customOneButton.buttonText.text = SelectedMod != null ? SelectedMod.MiraPlugin.CustomOptionMenuNameOne : "Custom Category 1";
|
|
||||||
customPos.y -= 0.637f;
|
|
||||||
_customOneButton.transform.localPosition = customPos;
|
|
||||||
_customOneButton.name = "CustomOneButton";
|
|
||||||
|
|
||||||
_customOneBtnOgPos = _customOneButton.transform.localPosition;
|
|
||||||
|
|
||||||
// create button for the first custom category
|
|
||||||
_customTwoButton = Object.Instantiate(_customOneButton, _customOneButton.transform.parent);
|
|
||||||
_customTwoButton.OnClick = new ButtonClickedEvent();
|
|
||||||
_customTwoButton.OnClick.AddListener(
|
|
||||||
(UnityAction)(() =>
|
|
||||||
{
|
|
||||||
__instance.ChangeTab(5, false);
|
|
||||||
}));
|
|
||||||
_customTwoButton.OnMouseOver = new UnityEvent();
|
|
||||||
_customTwoButton.OnMouseOver.AddListener(
|
|
||||||
(UnityAction)(() =>
|
|
||||||
{
|
|
||||||
__instance.ChangeTab(5, true);
|
|
||||||
}));
|
|
||||||
|
|
||||||
_customTwoButton.buttonText.text = SelectedMod != null ? SelectedMod.MiraPlugin.CustomOptionMenuNameTwo : "Custom Category 2";
|
|
||||||
customPos.y -= 0.637f;
|
|
||||||
_customTwoButton.transform.localPosition = customPos;
|
|
||||||
_customTwoButton.name = "CustomTwoButton";
|
|
||||||
|
|
||||||
_customTwoBtnOgPos = _customTwoButton.transform.localPosition;
|
|
||||||
|
|
||||||
// create button for modifiers
|
// create button for modifiers
|
||||||
__instance.RoleSettingsButton.buttonText.gameObject.GetComponent<TextTranslatorTMP>().Destroy();
|
__instance.RoleSettingsButton.buttonText.gameObject.GetComponent<TextTranslatorTMP>().Destroy();
|
||||||
__instance.RoleSettingsButton.gameObject.SetActive(false);
|
__instance.RoleSettingsButton.gameObject.SetActive(false);
|
||||||
@@ -415,32 +304,20 @@ internal static class GameSettingMenuPatches
|
|||||||
bool replaceWithModifiers = true;
|
bool replaceWithModifiers = true;
|
||||||
_smallRolesButton!.transform.localPosition = _smallRoleBtnOgPos;
|
_smallRolesButton!.transform.localPosition = _smallRoleBtnOgPos;
|
||||||
_modifiersButton!.transform.localPosition = _modifierBtnOgPos;
|
_modifiersButton!.transform.localPosition = _modifierBtnOgPos;
|
||||||
_customOneButton!.transform.localPosition = _customOneBtnOgPos;
|
|
||||||
_customTwoButton!.transform.localPosition = _customTwoBtnOgPos;
|
|
||||||
menu.RoleSettingsButton.transform.localPosition = _roleBtnOgPos;
|
menu.RoleSettingsButton.transform.localPosition = _roleBtnOgPos;
|
||||||
|
|
||||||
if (SelectedModIdx != 0)
|
if (SelectedModIdx != 0)
|
||||||
{
|
{
|
||||||
_customOneButton.buttonText.text = SelectedMod!.MiraPlugin.CustomOptionMenuNameOne;
|
|
||||||
_customTwoButton.buttonText.text = SelectedMod!.MiraPlugin.CustomOptionMenuNameTwo;
|
|
||||||
var modHasRoles = SelectedMod!.InternalRoles.Count != 0;
|
var modHasRoles = SelectedMod!.InternalRoles.Count != 0;
|
||||||
var modHasCustomOne = SelectedMod.InternalOptionGroups.Exists(
|
|
||||||
x => x.ParentMenu == MenuCategory.CustomOne);
|
|
||||||
var modHasCustomTwo = SelectedMod.InternalOptionGroups.Exists(
|
|
||||||
x => x.ParentMenu == MenuCategory.CustomTwo);
|
|
||||||
var modHasModifiers = SelectedMod.InternalOptionGroups.Exists(
|
var modHasModifiers = SelectedMod.InternalOptionGroups.Exists(
|
||||||
x => x.ShowInModifiersMenu || x.ParentMenu == MenuCategory.Modifiers || x.OptionableType?.IsAssignableTo(typeof(BaseModifier)) == true);
|
x => x.ShowInModifiersMenu || x.OptionableType?.IsAssignableTo(typeof(BaseModifier)) == true);
|
||||||
var modHasOptions =
|
var modHasOptions =
|
||||||
SelectedMod.InternalOptionGroups.Exists(x => x.OptionableType == null && (!x.ShowInModifiersMenu ||
|
SelectedMod.InternalOptionGroups.Exists(x => x.OptionableType == null && !x.ShowInModifiersMenu);
|
||||||
(x.ParentMenu != MenuCategory.Modifiers && x.ParentMenu != MenuCategory.Roles)));
|
|
||||||
|
|
||||||
_modifiersButton.gameObject.SetActive(true);
|
_modifiersButton.gameObject.SetActive(true);
|
||||||
_smallRolesButton.gameObject.SetActive(true);
|
_smallRolesButton.gameObject.SetActive(true);
|
||||||
_customOneButton.gameObject.SetActive(true);
|
|
||||||
_customTwoButton.gameObject.SetActive(true);
|
|
||||||
menu.GameSettingsButton.gameObject.SetActive(true);
|
menu.GameSettingsButton.gameObject.SetActive(true);
|
||||||
menu.RoleSettingsButton.gameObject.SetActive(false);
|
menu.RoleSettingsButton.gameObject.SetActive(false);
|
||||||
var defaultButton = menu.RoleSettingsButton;
|
|
||||||
|
|
||||||
// If there are no registered custom roles in the selected mod, hide the button.
|
// If there are no registered custom roles in the selected mod, hide the button.
|
||||||
if (!modHasRoles)
|
if (!modHasRoles)
|
||||||
@@ -457,7 +334,6 @@ internal static class GameSettingMenuPatches
|
|||||||
{
|
{
|
||||||
_modifiersButton.gameObject.SetActive(false);
|
_modifiersButton.gameObject.SetActive(false);
|
||||||
menu.RoleSettingsButton.gameObject.SetActive(true);
|
menu.RoleSettingsButton.gameObject.SetActive(true);
|
||||||
defaultButton = _modifiersButton;
|
|
||||||
|
|
||||||
if (_modifiersTab!.gameObject.active)
|
if (_modifiersTab!.gameObject.active)
|
||||||
{
|
{
|
||||||
@@ -480,7 +356,6 @@ internal static class GameSettingMenuPatches
|
|||||||
// If the mod has roles, we can enable the bigger role button and disable the small one.
|
// If the mod has roles, we can enable the bigger role button and disable the small one.
|
||||||
if (modHasRoles)
|
if (modHasRoles)
|
||||||
{
|
{
|
||||||
defaultButton = menu.RoleSettingsButton;
|
|
||||||
menu.RoleSettingsButton.gameObject.SetActive(true);
|
menu.RoleSettingsButton.gameObject.SetActive(true);
|
||||||
_smallRolesButton.gameObject.SetActive(false);
|
_smallRolesButton.gameObject.SetActive(false);
|
||||||
}
|
}
|
||||||
@@ -495,7 +370,6 @@ internal static class GameSettingMenuPatches
|
|||||||
{
|
{
|
||||||
menu.ChangeTab(0, false);
|
menu.ChangeTab(0, false);
|
||||||
}
|
}
|
||||||
defaultButton = menu.RoleSettingsButton;
|
|
||||||
|
|
||||||
// If the mod has roles and modifiers, we can move their buttons to the game settings button position, since nothing is there.
|
// If the mod has roles and modifiers, we can move their buttons to the game settings button position, since nothing is there.
|
||||||
if (menu.RoleSettingsButton.gameObject.active)
|
if (menu.RoleSettingsButton.gameObject.active)
|
||||||
@@ -515,37 +389,16 @@ internal static class GameSettingMenuPatches
|
|||||||
_smallRolesButton.transform.localPosition.z);
|
_smallRolesButton.transform.localPosition.z);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the mod has no primary custom tab, we can go ahead and hide the button.
|
|
||||||
if (!modHasCustomOne)
|
|
||||||
{
|
|
||||||
_customOneButton.gameObject.SetActive(false);
|
|
||||||
if (_customOneTab!.gameObject.active)
|
|
||||||
{
|
|
||||||
defaultButton.SelectButton(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// If the mod has no secondary custom tab, we can go ahead and hide the button.
|
|
||||||
if (!modHasCustomTwo)
|
|
||||||
{
|
|
||||||
_customTwoButton.gameObject.SetActive(false);
|
|
||||||
if (_customTwoTab!.gameObject.active)
|
|
||||||
{
|
|
||||||
defaultButton.SelectButton(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_modifiersButton.gameObject.SetActive(false);
|
_modifiersButton.gameObject.SetActive(false);
|
||||||
_smallRolesButton.gameObject.SetActive(false);
|
_smallRolesButton.gameObject.SetActive(false);
|
||||||
_customOneButton.gameObject.SetActive(false);
|
|
||||||
_customTwoButton.gameObject.SetActive(false);
|
|
||||||
menu.RoleSettingsButton.gameObject.SetActive(true);
|
menu.RoleSettingsButton.gameObject.SetActive(true);
|
||||||
menu.GameSettingsButton.gameObject.SetActive(true);
|
menu.GameSettingsButton.gameObject.SetActive(true);
|
||||||
replaceWithModifiers = false;
|
replaceWithModifiers = false;
|
||||||
|
|
||||||
if (_modifiersTab!.gameObject.active || _customOneTab!.gameObject.active || _customTwoTab!.gameObject.active)
|
if (_modifiersTab!.gameObject.active)
|
||||||
{
|
{
|
||||||
menu.ChangeTab(0, false);
|
menu.ChangeTab(0, false);
|
||||||
}
|
}
|
||||||
@@ -593,17 +446,7 @@ internal static class GameSettingMenuPatches
|
|||||||
|
|
||||||
if (_modifiersTab?.Children?.Count > 0)
|
if (_modifiersTab?.Children?.Count > 0)
|
||||||
{
|
{
|
||||||
CleanupSettings(_modifiersTab, MenuCategory.Modifiers);
|
CleanupSettings(_modifiersTab, true);
|
||||||
}
|
|
||||||
|
|
||||||
if (_customOneTab?.Children?.Count > 0)
|
|
||||||
{
|
|
||||||
CleanupSettings(_customOneTab, MenuCategory.CustomOne);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_customTwoTab?.Children?.Count > 0)
|
|
||||||
{
|
|
||||||
CleanupSettings(_customTwoTab, MenuCategory.CustomTwo);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CleanupRoleSettings(RolesSettingsMenu rolesMenu)
|
void CleanupRoleSettings(RolesSettingsMenu rolesMenu)
|
||||||
@@ -641,7 +484,7 @@ internal static class GameSettingMenuPatches
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CleanupSettings(GameOptionsMenu gameOptMenu, MenuCategory menuCategory = MenuCategory.Roles)
|
void CleanupSettings(GameOptionsMenu gameOptMenu, bool modifiers = false)
|
||||||
{
|
{
|
||||||
ClearOptions(gameOptMenu.Children);
|
ClearOptions(gameOptMenu.Children);
|
||||||
gameOptMenu.Children = null;
|
gameOptMenu.Children = null;
|
||||||
@@ -652,19 +495,7 @@ internal static class GameSettingMenuPatches
|
|||||||
.ForEach(header => header.gameObject.DestroyImmediate());
|
.ForEach(header => header.gameObject.DestroyImmediate());
|
||||||
|
|
||||||
gameOptMenu.Initialize();
|
gameOptMenu.Initialize();
|
||||||
var positions = OptionsPositions;
|
var positions = modifiers ? ModifiersPositions : OptionsPositions;
|
||||||
switch (menuCategory)
|
|
||||||
{
|
|
||||||
case MenuCategory.Modifiers:
|
|
||||||
positions = ModifiersPositions;
|
|
||||||
break;
|
|
||||||
case MenuCategory.CustomOne:
|
|
||||||
positions = CustomOnePositions;
|
|
||||||
break;
|
|
||||||
case MenuCategory.CustomTwo:
|
|
||||||
positions = CustomTwoPositions;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (positions.TryGetValue(SelectedModIdx, out var pos))
|
if (positions.TryGetValue(SelectedModIdx, out var pos))
|
||||||
{
|
{
|
||||||
gameOptMenu.scrollBar.Inner.localPosition = pos;
|
gameOptMenu.scrollBar.Inner.localPosition = pos;
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using AmongUs.GameOptions;
|
|
||||||
using HarmonyLib;
|
using HarmonyLib;
|
||||||
using MiraAPI.GameOptions;
|
using MiraAPI.GameOptions;
|
||||||
using MiraAPI.Modifiers;
|
using MiraAPI.Modifiers;
|
||||||
@@ -164,110 +163,7 @@ public static class LobbyViewPanePatches
|
|||||||
{
|
{
|
||||||
if (SelectedModIdx == 0)
|
if (SelectedModIdx == 0)
|
||||||
{
|
{
|
||||||
float num = 0.95f;
|
return true;
|
||||||
float num2 = -6.53f;
|
|
||||||
CategoryHeaderMasked categoryHeaderMasked =
|
|
||||||
Object.Instantiate(__instance.categoryHeaderOrigin, __instance.settingsContainer);
|
|
||||||
categoryHeaderMasked.SetHeader(StringNames.RoleQuotaLabel, 61);
|
|
||||||
categoryHeaderMasked.transform.localScale = Vector3.one;
|
|
||||||
categoryHeaderMasked.transform.localPosition = new Vector3(-9.77f, 1.26f, -2f);
|
|
||||||
__instance.settingsInfo.Add(categoryHeaderMasked.gameObject);
|
|
||||||
var list = new List<RoleBehaviour>();
|
|
||||||
for (int i = 0; i < 2; i++)
|
|
||||||
{
|
|
||||||
var categoryHeaderRoleVariant =
|
|
||||||
Object.Instantiate(__instance.categoryHeaderRoleOrigin, __instance.settingsContainer);
|
|
||||||
categoryHeaderRoleVariant.SetHeader(
|
|
||||||
(i == 0) ? StringNames.CrewmateRolesHeader : StringNames.ImpostorRolesHeader,
|
|
||||||
61);
|
|
||||||
categoryHeaderRoleVariant.transform.localScale = Vector3.one;
|
|
||||||
categoryHeaderRoleVariant.transform.localPosition = new Vector3(0.09f, num, -2f);
|
|
||||||
__instance.settingsInfo.Add(categoryHeaderRoleVariant.gameObject);
|
|
||||||
num -= 0.696f;
|
|
||||||
var roles = RoleManager.Instance.AllRoles.ToArray().Where(x =>
|
|
||||||
x is not ICustomRole && !x.IsRoleBlacklisted() && x.Role != RoleTypes.Crewmate &&
|
|
||||||
x.Role != RoleTypes.Impostor && ((i == 0 && x.TeamType is RoleTeamTypes.Crewmate) ||
|
|
||||||
(i == 1 && x.TeamType is RoleTeamTypes.Impostor)) &&
|
|
||||||
x.Role != RoleTypes.CrewmateGhost && x.Role != RoleTypes.ImpostorGhost).ToList();
|
|
||||||
for (int j = 0; j < roles.Count; j++)
|
|
||||||
{
|
|
||||||
var roleBehaviour = roles[j];
|
|
||||||
int chancePerGame =
|
|
||||||
GameOptionsManager.Instance.CurrentGameOptions.RoleOptions.GetChancePerGame(
|
|
||||||
roleBehaviour.Role);
|
|
||||||
int numPerGame =
|
|
||||||
GameOptionsManager.Instance.CurrentGameOptions.RoleOptions
|
|
||||||
.GetNumPerGame(roleBehaviour.Role);
|
|
||||||
bool flag = numPerGame == 0;
|
|
||||||
var viewSettingsInfoPanelRoleVariant =
|
|
||||||
Object.Instantiate(
|
|
||||||
__instance.infoPanelRoleOrigin,
|
|
||||||
__instance.settingsContainer);
|
|
||||||
viewSettingsInfoPanelRoleVariant.transform.localScale = Vector3.one;
|
|
||||||
viewSettingsInfoPanelRoleVariant.transform.localPosition = new Vector3(num2, num, -2f);
|
|
||||||
if (!flag)
|
|
||||||
{
|
|
||||||
list.Add(roleBehaviour);
|
|
||||||
}
|
|
||||||
|
|
||||||
viewSettingsInfoPanelRoleVariant.SetInfo(
|
|
||||||
roleBehaviour.NiceName,
|
|
||||||
numPerGame,
|
|
||||||
chancePerGame,
|
|
||||||
61,
|
|
||||||
(i == 0) ? Palette.CrewmateRoleBlue : Palette.ImpostorRoleRed,
|
|
||||||
roleBehaviour.RoleIconSolid,
|
|
||||||
i == 0,
|
|
||||||
flag);
|
|
||||||
__instance.settingsInfo.Add(viewSettingsInfoPanelRoleVariant.gameObject);
|
|
||||||
num -= 0.664f;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (list.Count > 0)
|
|
||||||
{
|
|
||||||
var categoryHeaderMasked2 =
|
|
||||||
Object.Instantiate(__instance.categoryHeaderOrigin, __instance.settingsContainer);
|
|
||||||
categoryHeaderMasked2.SetHeader(StringNames.RoleSettingsLabel, 61);
|
|
||||||
categoryHeaderMasked2.transform.localScale = Vector3.one;
|
|
||||||
categoryHeaderMasked2.transform.localPosition = new Vector3(-9.77f, num, -2f);
|
|
||||||
__instance.settingsInfo.Add(categoryHeaderMasked2.gameObject);
|
|
||||||
num -= 2.1f;
|
|
||||||
float num3 = 0f;
|
|
||||||
for (int k = 0; k < list.Count; k++)
|
|
||||||
{
|
|
||||||
float num4;
|
|
||||||
if (k % 2 == 0)
|
|
||||||
{
|
|
||||||
num4 = -5.8f;
|
|
||||||
if (k > 0)
|
|
||||||
{
|
|
||||||
num -= num3 + 0.85f;
|
|
||||||
num3 = 0f;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
num4 = 0.14999962f;
|
|
||||||
}
|
|
||||||
|
|
||||||
var advancedRoleViewPanel =
|
|
||||||
Object.Instantiate(__instance.advancedRolePanelOrigin, __instance.settingsContainer);
|
|
||||||
advancedRoleViewPanel.transform.localScale = Vector3.one;
|
|
||||||
advancedRoleViewPanel.transform.localPosition = new Vector3(num4, num, -2f);
|
|
||||||
float num5 = advancedRoleViewPanel.SetUp(list[k], 0.85f, 61);
|
|
||||||
if (num5 > num3)
|
|
||||||
{
|
|
||||||
num3 = num5;
|
|
||||||
}
|
|
||||||
|
|
||||||
__instance.settingsInfo.Add(advancedRoleViewPanel.gameObject);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
__instance.scrollBar.SetYBoundsMax(-num);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (__instance.currentTab == ModifiersTabName)
|
if (__instance.currentTab == ModifiersTabName)
|
||||||
@@ -382,7 +278,7 @@ public static class LobbyViewPanePatches
|
|||||||
|
|
||||||
foreach (var grouping in sortedRoleGroups)
|
foreach (var grouping in sortedRoleGroups)
|
||||||
{
|
{
|
||||||
if (!grouping.Any() || grouping.All(x => x.Configuration.HideSettings || !x.VisibleInSettings()))
|
if (!grouping.Any() || grouping.All(x => x.Configuration.HideSettings))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -413,7 +309,7 @@ public static class LobbyViewPanePatches
|
|||||||
|
|
||||||
foreach (var customRole in grouping)
|
foreach (var customRole in grouping)
|
||||||
{
|
{
|
||||||
if (customRole.Configuration.HideSettings || !customRole.VisibleInSettings())
|
if (customRole.Configuration.HideSettings)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -448,7 +344,7 @@ public static class LobbyViewPanePatches
|
|||||||
}
|
}
|
||||||
|
|
||||||
viewSettingsInfoPanelRoleVariant.SetInfo(
|
viewSettingsInfoPanelRoleVariant.SetInfo(
|
||||||
roleBehaviour.GetRoleName(),
|
roleBehaviour.NiceName,
|
||||||
numPerGame,
|
numPerGame,
|
||||||
chancePerGame,
|
chancePerGame,
|
||||||
61,
|
61,
|
||||||
|
|||||||
@@ -216,16 +216,7 @@ public static class OptionsPatches
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
var increment = __instance.Increment;
|
__instance.Value += __instance.Increment;
|
||||||
|
|
||||||
if (Input.GetKey(KeyCode.LeftShift) &&
|
|
||||||
__instance.TryGetComponent<MiraNumberOptionComponent>(out var miraNumber) &&
|
|
||||||
miraNumber.ShiftIncrementToggle)
|
|
||||||
{
|
|
||||||
increment /= 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
__instance.Value += increment;
|
|
||||||
if (__instance.Value > __instance.ValidRange.max)
|
if (__instance.Value > __instance.ValidRange.max)
|
||||||
{
|
{
|
||||||
__instance.Value = __instance.ValidRange.min;
|
__instance.Value = __instance.ValidRange.min;
|
||||||
@@ -244,16 +235,7 @@ public static class OptionsPatches
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
var increment = __instance.Increment;
|
__instance.Value -= __instance.Increment;
|
||||||
|
|
||||||
if (Input.GetKey(KeyCode.LeftShift) &&
|
|
||||||
__instance.TryGetComponent<MiraNumberOptionComponent>(out var miraNumber) &&
|
|
||||||
miraNumber.ShiftIncrementToggle)
|
|
||||||
{
|
|
||||||
increment /= 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
__instance.Value -= increment;
|
|
||||||
if (__instance.Value < __instance.ValidRange.min)
|
if (__instance.Value < __instance.ValidRange.min)
|
||||||
{
|
{
|
||||||
__instance.Value = __instance.ValidRange.max;
|
__instance.Value = __instance.ValidRange.max;
|
||||||
|
|||||||
@@ -74,10 +74,10 @@ public static class RoleSettingMenuPatches
|
|||||||
var num = 0.662f;
|
var num = 0.662f;
|
||||||
|
|
||||||
var list = CustomRoleManager.AllRoles.Where(
|
var list = CustomRoleManager.AllRoles.Where(
|
||||||
r => !r.IsCustomRole() && !r.IsRoleBlacklisted() && r.TeamType == RoleTeamTypes.Crewmate && r.Role != RoleTypes.Crewmate &&
|
r => !r.IsCustomRole() && r.TeamType == RoleTeamTypes.Crewmate && r.Role != RoleTypes.Crewmate &&
|
||||||
r.Role != RoleTypes.CrewmateGhost).ToList();
|
r.Role != RoleTypes.CrewmateGhost).ToList();
|
||||||
var list2 = CustomRoleManager.AllRoles.Where(
|
var list2 = CustomRoleManager.AllRoles.Where(
|
||||||
r => !r.IsCustomRole() && !r.IsRoleBlacklisted() && r.TeamType == RoleTeamTypes.Impostor && r.Role != RoleTypes.Impostor &&
|
r => !r.IsCustomRole() && r.TeamType == RoleTeamTypes.Impostor && r.Role != RoleTypes.Impostor &&
|
||||||
r.Role != RoleTypes.ImpostorGhost).ToList();
|
r.Role != RoleTypes.ImpostorGhost).ToList();
|
||||||
|
|
||||||
if (__instance.roleTabs == null || __instance.roleTabs.Count == 0)
|
if (__instance.roleTabs == null || __instance.roleTabs.Count == 0)
|
||||||
@@ -160,7 +160,7 @@ public static class RoleSettingMenuPatches
|
|||||||
|
|
||||||
foreach (var grouping in sortedRoleGroups)
|
foreach (var grouping in sortedRoleGroups)
|
||||||
{
|
{
|
||||||
if (!grouping.Any() || grouping.All(x=> x.Configuration.HideSettings || !x.VisibleInSettings()))
|
if (!grouping.Any() || grouping.All(x=>x.Configuration.HideSettings))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -392,7 +392,7 @@ public static class RoleSettingMenuPatches
|
|||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Warning(e);
|
Logger<MiraApiPlugin>.Warning(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
roleSetting.UpdateValuesAndText(GameOptionsManager.Instance.CurrentGameOptions.RoleOptions);
|
roleSetting.UpdateValuesAndText(GameOptionsManager.Instance.CurrentGameOptions.RoleOptions);
|
||||||
@@ -466,14 +466,16 @@ public static class RoleSettingMenuPatches
|
|||||||
{
|
{
|
||||||
if (role is not ICustomRole customRole)
|
if (role is not ICustomRole customRole)
|
||||||
{
|
{
|
||||||
Error($"Role {role.NiceName} is not a custom role.");
|
Logger<MiraApiPlugin>.Error($"Role {role.NiceName} is not a custom role.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
RolePositions[GameSettingMenuPatches.SelectedModIdx] = __instance.scrollBar.Inner.localPosition;
|
RolePositions[GameSettingMenuPatches.SelectedModIdx] = __instance.scrollBar.Inner.localPosition;
|
||||||
|
|
||||||
__instance.roleDescriptionText.text = customRole.RoleLongDescription;
|
__instance.roleDescriptionText.text = customRole.RoleLongDescription;
|
||||||
__instance.roleTitleText.text = role.GetRoleName();
|
__instance.roleTitleText.text = TranslationController.Instance.GetString(
|
||||||
|
role.StringName,
|
||||||
|
new Il2CppReferenceArray<Il2CppSystem.Object>(0));
|
||||||
|
|
||||||
var imgBg = __instance.AdvancedRolesSettings.transform.FindChild("Imagebackground");
|
var imgBg = __instance.AdvancedRolesSettings.transform.FindChild("Imagebackground");
|
||||||
var labelBg = __instance.AdvancedRolesSettings.transform.FindChild("InfoLabelBackground");
|
var labelBg = __instance.AdvancedRolesSettings.transform.FindChild("InfoLabelBackground");
|
||||||
@@ -560,7 +562,7 @@ public static class RoleSettingMenuPatches
|
|||||||
{
|
{
|
||||||
if (role is not ICustomRole customRole)
|
if (role is not ICustomRole customRole)
|
||||||
{
|
{
|
||||||
Error($"Role {role.NiceName} is not a custom role.");
|
Logger<MiraApiPlugin>.Error($"Role {role.NiceName} is not a custom role.");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -577,7 +579,6 @@ public static class RoleSettingMenuPatches
|
|||||||
roleOptionSetting.transform.localPosition = new Vector3(-0.1f, ScrollerNum, -2f);
|
roleOptionSetting.transform.localPosition = new Vector3(-0.1f, ScrollerNum, -2f);
|
||||||
|
|
||||||
roleOptionSetting.SetRole(GameOptionsManager.Instance.CurrentGameOptions.RoleOptions, role, 20);
|
roleOptionSetting.SetRole(GameOptionsManager.Instance.CurrentGameOptions.RoleOptions, role, 20);
|
||||||
roleOptionSetting.titleText.text = role.GetRoleName();
|
|
||||||
roleOptionSetting.labelSprite.color = customRole.OptionsMenuColor;
|
roleOptionSetting.labelSprite.color = customRole.OptionsMenuColor;
|
||||||
roleOptionSetting.OnValueChanged = new Action<OptionBehaviour>(ValueChanged);
|
roleOptionSetting.OnValueChanged = new Action<OptionBehaviour>(ValueChanged);
|
||||||
roleOptionSetting.SetClickMask(__instance.ButtonClickMask);
|
roleOptionSetting.SetClickMask(__instance.ButtonClickMask);
|
||||||
|
|||||||
@@ -1,8 +1,5 @@
|
|||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Linq;
|
|
||||||
using HarmonyLib;
|
using HarmonyLib;
|
||||||
using MiraAPI.GameOptions;
|
|
||||||
using MiraAPI.GameOptions.OptionTypes;
|
|
||||||
using MiraAPI.Utilities;
|
using MiraAPI.Utilities;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
@@ -31,33 +28,7 @@ public static class SettingPatches
|
|||||||
string result;
|
string result;
|
||||||
var suffix = (MiraNumberSuffixes)__instance.SuffixType;
|
var suffix = (MiraNumberSuffixes)__instance.SuffixType;
|
||||||
|
|
||||||
var custom =
|
if (__instance.ZeroIsInfinity && Mathf.Abs(value) < 0.0001f)
|
||||||
ModdedOptionsManager.ModdedOptions.Values.FirstOrDefault(opt =>
|
|
||||||
opt.OptionBehaviour != null && opt.OptionBehaviour.Data == __instance);
|
|
||||||
if (custom is ModdedNumberOption moddedNumberOption)
|
|
||||||
{
|
|
||||||
if (moddedNumberOption.NegativeWordValue != "#" && (int)value == -1)
|
|
||||||
{
|
|
||||||
result = $"<b>{moddedNumberOption.NegativeWordValue}</b>";
|
|
||||||
}
|
|
||||||
else if (moddedNumberOption.ZeroWordValue != "#" && Mathf.Abs(value) < 0.0001f)
|
|
||||||
{
|
|
||||||
result = $"<b>{moddedNumberOption.ZeroWordValue}</b>";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
result = suffix switch
|
|
||||||
{
|
|
||||||
MiraNumberSuffixes.None => value.ToString(__instance.FormatString, NumberFormatInfo.InvariantInfo),
|
|
||||||
MiraNumberSuffixes.Multiplier => value.ToString(__instance.FormatString, NumberFormatInfo.InvariantInfo) + "x",
|
|
||||||
MiraNumberSuffixes.Percent => value.ToString(__instance.FormatString, NumberFormatInfo.InvariantInfo) + "%",
|
|
||||||
_ => TranslationController.Instance.GetString(
|
|
||||||
StringNames.GameSecondsAbbrev,
|
|
||||||
(Il2CppSystem.Object[])[value.ToString(__instance.FormatString, CultureInfo.InvariantCulture)]),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (__instance.ZeroIsInfinity && Mathf.Abs(value) < 0.0001f)
|
|
||||||
{
|
{
|
||||||
result = "<b>∞</b>";
|
result = "<b>∞</b>";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -127,19 +127,17 @@ internal static class PlayerControlPatches
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var role = __instance.Data?.Role;
|
|
||||||
foreach (var button in CustomButtonManager.CustomButtons)
|
foreach (var button in CustomButtonManager.CustomButtons)
|
||||||
{
|
{
|
||||||
if (role == null)
|
if (__instance.Data?.Role == null)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (!button.Enabled(role))
|
if (!button.Enabled(__instance.Data?.Role))
|
||||||
{
|
{
|
||||||
button.SetActive(false, role);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -147,7 +145,7 @@ internal static class PlayerControlPatches
|
|||||||
}
|
}
|
||||||
catch (System.Exception e)
|
catch (System.Exception e)
|
||||||
{
|
{
|
||||||
Error($"Failed to update custom button {button.GetType().Name}: {e}");
|
Logger<MiraApiPlugin>.Error($"Failed to update custom button {button.GetType().Name}: {e}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,11 @@
|
|||||||
using HarmonyLib;
|
using HarmonyLib;
|
||||||
using MiraAPI.Roles;
|
using MiraAPI.Roles;
|
||||||
using MiraAPI.Utilities;
|
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace MiraAPI.Patches.Roles;
|
namespace MiraAPI.Patches.Roles;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Patches the haunt menu to show the actual role name rather than team.
|
/// Patches the haunt menu to show the actual role name rather then team.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[HarmonyPatch(typeof(HauntMenuMinigame), nameof(HauntMenuMinigame.SetHauntTarget))]
|
[HarmonyPatch(typeof(HauntMenuMinigame), nameof(HauntMenuMinigame.SetHauntTarget))]
|
||||||
// SetFilterText was INLINED
|
// SetFilterText was INLINED
|
||||||
@@ -23,7 +22,7 @@ public static class HauntMenuMinigamePatch
|
|||||||
var role = __instance.HauntTarget.Data.Role;
|
var role = __instance.HauntTarget.Data.Role;
|
||||||
var color = role is ICustomRole custom ? custom.RoleColor : role.TeamColor;
|
var color = role is ICustomRole custom ? custom.RoleColor : role.TeamColor;
|
||||||
|
|
||||||
__instance.FilterText.text = role.GetRoleName();
|
__instance.FilterText.text = role.NiceName;
|
||||||
__instance.FilterText.color = color;
|
__instance.FilterText.color = color;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -46,7 +46,7 @@ public static class KillButtonPatches
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Use Custom Murder instead of Murder Player from vanilla.
|
/// Use Custom Murder if player is custom role.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[HarmonyPrefix]
|
[HarmonyPrefix]
|
||||||
[HarmonyPatch(nameof(KillButton.DoClick))]
|
[HarmonyPatch(nameof(KillButton.DoClick))]
|
||||||
@@ -58,6 +58,11 @@ public static class KillButtonPatches
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (PlayerControl.LocalPlayer.Data.Role is not ICustomRole)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
PlayerControl.LocalPlayer.RpcCustomMurder(__instance.currentTarget);
|
PlayerControl.LocalPlayer.RpcCustomMurder(__instance.currentTarget);
|
||||||
__instance.SetTarget(null);
|
__instance.SetTarget(null);
|
||||||
|
|
||||||
|
|||||||
@@ -1,183 +0,0 @@
|
|||||||
using AmongUs.GameOptions;
|
|
||||||
using HarmonyLib;
|
|
||||||
using Il2CppSystem.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using MiraAPI.Roles;
|
|
||||||
|
|
||||||
namespace MiraAPI.Patches.Roles;
|
|
||||||
|
|
||||||
[HarmonyPatch(typeof(LogicRoleSelectionHnS))]
|
|
||||||
public static class LogicRoleSelectionHnsPatch
|
|
||||||
{
|
|
||||||
[HarmonyPrefix]
|
|
||||||
[HarmonyPatch(nameof(LogicRoleSelectionHnS.AssignRolesForTeam))]
|
|
||||||
public static bool AssignRolesForTeam(
|
|
||||||
LogicRoleSelectionHnS __instance,
|
|
||||||
List<NetworkedPlayerInfo> players,
|
|
||||||
IGameOptions opts,
|
|
||||||
RoleTeamTypes team,
|
|
||||||
int teamMax,
|
|
||||||
Il2CppSystem.Nullable<RoleTypes> defaultRole)
|
|
||||||
{
|
|
||||||
Error($"MiraAPI.Patches.Roles.LogicRoleSelectionHnsPatch - AssignRolesForTeam: Team: {team}, Max: {teamMax}, Players: {players.Count}, DefaultRole: {defaultRole}");
|
|
||||||
int num = 0;
|
|
||||||
IRoleOptionsCollection roleOptions = opts.RoleOptions;
|
|
||||||
var source = RoleManager.Instance.AllRoles.ToArray()
|
|
||||||
.Where(role => role.TeamType == team && !RoleManager.IsGhostRole(role.Role) &&
|
|
||||||
CustomRoleUtils.CanSpawnOnCurrentMode(role));
|
|
||||||
var assignmentData = source.Where(x => !x.IsDead).Select(role =>
|
|
||||||
new RoleManager.RoleAssignmentData(
|
|
||||||
role,
|
|
||||||
roleOptions.GetNumPerGame(role.Role),
|
|
||||||
roleOptions.GetChancePerGame(role.Role))).ToList();
|
|
||||||
var source2 = CustomRoleUtils.GetPossibleRoles(assignmentData, x => x.Chance == 100);
|
|
||||||
var guaranteedRoles = source.Where(x => source2.Contains(((ushort)x.Role, 100)));
|
|
||||||
List<RoleTypes> list = new List<RoleTypes>();
|
|
||||||
if (team == RoleTeamTypes.Crewmate)
|
|
||||||
{
|
|
||||||
Error($"MiraAPI.Patches.Roles.LogicRoleSelectionHnsPatch - AssignRolesForTeam: Before Guaranteed Assignment");
|
|
||||||
foreach (RoleManager.RoleAssignmentData roleAssignmentData in guaranteedRoles.Select((x) =>
|
|
||||||
new RoleManager.RoleAssignmentData(x, roleOptions.GetNumPerGame(x.Role), 100)))
|
|
||||||
{
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
RoleManager.RoleAssignmentData roleAssignmentData2 = roleAssignmentData;
|
|
||||||
int count = roleAssignmentData2.Count;
|
|
||||||
roleAssignmentData2.Count = count - 1;
|
|
||||||
if (count <= 0)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
list.Add(roleAssignmentData.Role.Role);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Error($"MiraAPI.Patches.Roles.LogicRoleSelectionHnsPatch - AssignRolesForTeam: After Guaranteed Assignment");
|
|
||||||
AssignRolesFromList(players, teamMax, list, ref num);
|
|
||||||
|
|
||||||
var list2 = source.Where(x => !x.IsDead).Select(role =>
|
|
||||||
new RoleManager.RoleAssignmentData(
|
|
||||||
role,
|
|
||||||
roleOptions.GetNumPerGame(role.Role),
|
|
||||||
roleOptions.GetChancePerGame(role.Role))).ToList();
|
|
||||||
|
|
||||||
list.Clear();
|
|
||||||
foreach (RoleManager.RoleAssignmentData roleAssignmentData3 in list2)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < roleAssignmentData3.Count; i++)
|
|
||||||
{
|
|
||||||
if (HashRandom.Next(101) < roleAssignmentData3.Chance)
|
|
||||||
{
|
|
||||||
list.Add(roleAssignmentData3.Role.Role);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Error($"MiraAPI.Patches.Roles.LogicRoleSelectionHnsPatch - AssignRolesForTeam: After Potential Assignment");
|
|
||||||
|
|
||||||
AssignRolesFromList(players, teamMax, list, ref num);
|
|
||||||
var basicRole = RoleTypes.Engineer;
|
|
||||||
while (list.Count < players.Count && list.Count + num < teamMax)
|
|
||||||
{
|
|
||||||
list.Add(basicRole);
|
|
||||||
}
|
|
||||||
|
|
||||||
AssignRolesFromList(players, teamMax, list, ref num);
|
|
||||||
Error($"MiraAPI.Patches.Roles.LogicRoleSelectionHnsPatch - AssignRolesForTeam: After Fallback Assignment");
|
|
||||||
}
|
|
||||||
else if (team == RoleTeamTypes.Impostor)
|
|
||||||
{
|
|
||||||
Error($"MiraAPI.Patches.Roles.LogicRoleSelectionHnsPatch - AssignRolesForTeam: Before Guaranteed Assignment");
|
|
||||||
var newImpostors = new List<NetworkedPlayerInfo>();
|
|
||||||
// Specified Seeker
|
|
||||||
if (__instance.hnsManager.LogicOptionsHnS.HasImpostorPlayerID() &&
|
|
||||||
__instance.hnsManager.LogicOptionsHnS.ValidateImpostorPlayerID(players) &&
|
|
||||||
!AmongUsClient.Instance.IsGamePublic)
|
|
||||||
{
|
|
||||||
NetworkedPlayerInfo networkedPlayerInfo = players.ToArray()
|
|
||||||
.First(p => p.PlayerId == __instance.hnsManager.LogicOptionsHnS.ImpostorPlayerID());
|
|
||||||
players.Remove(networkedPlayerInfo);
|
|
||||||
newImpostors.Add(networkedPlayerInfo);
|
|
||||||
Error($"MiraAPI.Patches.Roles.LogicRoleSelectionHnsPatch - AssignRolesForTeam: Seeker is {networkedPlayerInfo.PlayerName}, ID: {networkedPlayerInfo.PlayerId}");
|
|
||||||
}
|
|
||||||
// Random Seeker
|
|
||||||
else
|
|
||||||
{
|
|
||||||
int num2 = 0;
|
|
||||||
while (num2 < teamMax && players.Count > 0)
|
|
||||||
{
|
|
||||||
PseudoRandomList<NetworkedPlayerInfo> pseudoRandomList = new PseudoRandomList<NetworkedPlayerInfo>(AmongUsClient.Instance.GameId);
|
|
||||||
players._items.Do(x => pseudoRandomList.Add(x));
|
|
||||||
for (int i = 0; i < GameData.RoundsPlayedInSession; i++)
|
|
||||||
{
|
|
||||||
pseudoRandomList.PickRandom();
|
|
||||||
}
|
|
||||||
NetworkedPlayerInfo networkedPlayerInfo = pseudoRandomList.PickRandom();
|
|
||||||
players.Remove(networkedPlayerInfo);
|
|
||||||
newImpostors.Add(networkedPlayerInfo);
|
|
||||||
num2++;
|
|
||||||
Error($"MiraAPI.Patches.Roles.LogicRoleSelectionHnsPatch - AssignRolesForTeam: Seeker is {networkedPlayerInfo.PlayerName}, ID: {networkedPlayerInfo.PlayerId}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Error($"MiraAPI.Patches.Roles.LogicRoleSelectionHnsPatch - AssignRolesForTeam: After Guaranteed Assignment");
|
|
||||||
foreach (RoleManager.RoleAssignmentData roleAssignmentData in guaranteedRoles.Select((x) =>
|
|
||||||
new RoleManager.RoleAssignmentData(x, roleOptions.GetNumPerGame(x.Role), 100)))
|
|
||||||
{
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
RoleManager.RoleAssignmentData roleAssignmentData2 = roleAssignmentData;
|
|
||||||
int count = roleAssignmentData2.Count;
|
|
||||||
roleAssignmentData2.Count = count - 1;
|
|
||||||
if (count <= 0)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
list.Add(roleAssignmentData.Role.Role);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
AssignRolesFromList(newImpostors, teamMax, list, ref num);
|
|
||||||
|
|
||||||
var list2 = source.Where(x => !x.IsDead).Select(role =>
|
|
||||||
new RoleManager.RoleAssignmentData(
|
|
||||||
role,
|
|
||||||
roleOptions.GetNumPerGame(role.Role),
|
|
||||||
roleOptions.GetChancePerGame(role.Role))).ToList();
|
|
||||||
|
|
||||||
list.Clear();
|
|
||||||
foreach (RoleManager.RoleAssignmentData roleAssignmentData3 in list2)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < roleAssignmentData3.Count; i++)
|
|
||||||
{
|
|
||||||
if (HashRandom.Next(101) < roleAssignmentData3.Chance)
|
|
||||||
{
|
|
||||||
list.Add(roleAssignmentData3.Role.Role);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
AssignRolesFromList(newImpostors, teamMax, list, ref num);
|
|
||||||
var basicRole = RoleTypes.Impostor;
|
|
||||||
while (list.Count < newImpostors.Count && list.Count + num < teamMax)
|
|
||||||
{
|
|
||||||
list.Add(basicRole);
|
|
||||||
}
|
|
||||||
|
|
||||||
AssignRolesFromList(newImpostors, teamMax, list, ref num);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void AssignRolesFromList(List<NetworkedPlayerInfo> players, int teamMax, List<RoleTypes> roleList, ref int rolesAssigned)
|
|
||||||
{
|
|
||||||
while (roleList.Count > 0 && players.Count > 0 && rolesAssigned < teamMax)
|
|
||||||
{
|
|
||||||
int index = HashRandom.FastNext(roleList.Count);
|
|
||||||
RoleTypes roleType = roleList[index];
|
|
||||||
roleList.RemoveAt(index);
|
|
||||||
int index2 = HashRandom.FastNext(players.Count);
|
|
||||||
players[index2].Object.RpcSetRole(roleType, false);
|
|
||||||
players.RemoveAt(index2);
|
|
||||||
rolesAssigned++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,93 +0,0 @@
|
|||||||
using AmongUs.GameOptions;
|
|
||||||
using HarmonyLib;
|
|
||||||
using Il2CppSystem.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using MiraAPI.Roles;
|
|
||||||
|
|
||||||
namespace MiraAPI.Patches.Roles;
|
|
||||||
|
|
||||||
[HarmonyPatch(typeof(LogicRoleSelectionNormal))]
|
|
||||||
public static class LogicRoleSelectionNormalPatch
|
|
||||||
{
|
|
||||||
[HarmonyPrefix]
|
|
||||||
[HarmonyPatch(nameof(LogicRoleSelectionNormal.AssignRolesForTeam))]
|
|
||||||
public static bool AssignRolesForTeam(
|
|
||||||
LogicRoleSelectionNormal __instance,
|
|
||||||
List<NetworkedPlayerInfo> players,
|
|
||||||
IGameOptions opts,
|
|
||||||
RoleTeamTypes team,
|
|
||||||
int teamMax,
|
|
||||||
Il2CppSystem.Nullable<RoleTypes> defaultRole)
|
|
||||||
{
|
|
||||||
int num = 0;
|
|
||||||
var source = RoleManager.Instance.AllRoles.ToArray()
|
|
||||||
.Where(role => role.TeamType == team && !RoleManager.IsGhostRole(role.Role) &&
|
|
||||||
CustomRoleUtils.CanSpawnOnCurrentMode(role));
|
|
||||||
List<RoleTypes> list = new List<RoleTypes>();
|
|
||||||
IRoleOptionsCollection roleOptions = opts.RoleOptions;
|
|
||||||
|
|
||||||
var assignmentData = source.Where(x => !x.IsDead).Select(role =>
|
|
||||||
new RoleManager.RoleAssignmentData(
|
|
||||||
role,
|
|
||||||
roleOptions.GetNumPerGame(role.Role),
|
|
||||||
roleOptions.GetChancePerGame(role.Role))).ToList();
|
|
||||||
var source2 = CustomRoleUtils.GetPossibleRoles(assignmentData, x => x.Chance == 100);
|
|
||||||
var guaranteedRoles = source.Where(x => source2.Contains(((ushort)x.Role, 100)));
|
|
||||||
foreach (RoleManager.RoleAssignmentData roleAssignmentData in guaranteedRoles.Select((x) =>
|
|
||||||
new RoleManager.RoleAssignmentData(x, roleOptions.GetNumPerGame(x.Role), 100)))
|
|
||||||
{
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
RoleManager.RoleAssignmentData roleAssignmentData2 = roleAssignmentData;
|
|
||||||
int count = roleAssignmentData2.Count;
|
|
||||||
roleAssignmentData2.Count = count - 1;
|
|
||||||
if (count <= 0)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
list.Add(roleAssignmentData.Role.Role);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
__instance.AssignRolesFromList(players, teamMax, list, ref num);
|
|
||||||
|
|
||||||
var list2 = source.Where(x => !x.IsDead).Select(role =>
|
|
||||||
new RoleManager.RoleAssignmentData(
|
|
||||||
role,
|
|
||||||
roleOptions.GetNumPerGame(role.Role),
|
|
||||||
roleOptions.GetChancePerGame(role.Role))).ToList();
|
|
||||||
|
|
||||||
list.Clear();
|
|
||||||
foreach (RoleManager.RoleAssignmentData roleAssignmentData3 in list2)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < roleAssignmentData3.Count; i++)
|
|
||||||
{
|
|
||||||
if (HashRandom.Next(101) < roleAssignmentData3.Chance)
|
|
||||||
{
|
|
||||||
list.Add(roleAssignmentData3.Role.Role);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
__instance.AssignRolesFromList(players, teamMax, list, ref num);
|
|
||||||
var defaultRole2 = team is RoleTeamTypes.Crewmate ? RoleTypes.Crewmate : RoleTypes.Impostor;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
defaultRole2 = defaultRole.Value;
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
// Ignored
|
|
||||||
}
|
|
||||||
|
|
||||||
while (list.Count < players.Count && list.Count + num < teamMax)
|
|
||||||
{
|
|
||||||
list.Add(defaultRole2);
|
|
||||||
}
|
|
||||||
|
|
||||||
__instance.AssignRolesFromList(players, teamMax, list, ref num);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -20,7 +20,7 @@ public static class NameTagPatch
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (PlayerControl.LocalPlayer.Data?.Role?.IsImpostor == true && otherPlayerRole.IsImpostor)
|
if (PlayerControl.LocalPlayer.Data.Role.IsImpostor && otherPlayerRole.IsImpostor)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -30,7 +30,7 @@ public static class NameTagPatch
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!PlayerControl.LocalPlayer || !PlayerControl.LocalPlayer.Data || !PlayerControl.LocalPlayer.Data?.Role || !otherPlayerRole)
|
if (!PlayerControl.LocalPlayer || !PlayerControl.LocalPlayer.Data || !PlayerControl.LocalPlayer.Data.Role || !otherPlayerRole)
|
||||||
{
|
{
|
||||||
__result = Color.white;
|
__result = Color.white;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using AmongUs.GameOptions;
|
using AmongUs.GameOptions;
|
||||||
using HarmonyLib;
|
using HarmonyLib;
|
||||||
using InnerNet;
|
|
||||||
using MiraAPI.Events;
|
using MiraAPI.Events;
|
||||||
using MiraAPI.Events.Vanilla.Gameplay;
|
using MiraAPI.Events.Vanilla.Gameplay;
|
||||||
using MiraAPI.Modifiers;
|
using MiraAPI.Modifiers;
|
||||||
@@ -26,7 +25,7 @@ public static class RoleManagerPatches
|
|||||||
var data = targetPlayer.Data;
|
var data = targetPlayer.Data;
|
||||||
if (data == null)
|
if (data == null)
|
||||||
{
|
{
|
||||||
Error("It shouldn't be possible, but " + targetPlayer.name + " still doesn't have PlayerData during role selection.");
|
Debug.LogError("It shouldn't be possible, but " + targetPlayer.name + " still doesn't have PlayerData during role selection.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (data.Role)
|
if (data.Role)
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ public static class RoleOptionsCollectionPatch
|
|||||||
var chance = customRole.GetChance();
|
var chance = customRole.GetChance();
|
||||||
if (chance == null)
|
if (chance == null)
|
||||||
{
|
{
|
||||||
Error($"Chance is null, defaulting to zero.");
|
Logger<MiraApiPlugin>.Error($"Chance is null, defaulting to zero.");
|
||||||
chance = 0;
|
chance = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -81,7 +81,7 @@ public static class RoleOptionsCollectionPatch
|
|||||||
var count = customRole.GetCount();
|
var count = customRole.GetCount();
|
||||||
if (count == null)
|
if (count == null)
|
||||||
{
|
{
|
||||||
Error($"Count is null, defaulting to zero.");
|
Logger<MiraApiPlugin>.Error($"Count is null, defaulting to zero.");
|
||||||
count = 0;
|
count = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,31 +12,6 @@ public interface IMiraPlugin
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
string OptionsTitleText { get; }
|
string OptionsTitleText { get; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the name for the first custom category in the game options menu, if any.
|
|
||||||
/// </summary>
|
|
||||||
public virtual string CustomOptionMenuNameOne => "Custom Category 1";
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the name for the second custom category in the game options menu, if any.
|
|
||||||
/// </summary>
|
|
||||||
public virtual string CustomOptionMenuNameTwo => "Custom Category 2";
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the description for the second custom category in the game options menu, if any.
|
|
||||||
/// </summary>
|
|
||||||
public virtual string ModifierMenuDescription => "Configure modifiers and their settings here!";
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the description for the first custom category in the game options menu, if any.
|
|
||||||
/// </summary>
|
|
||||||
public virtual string CustomOptionMenuOneDescription => "Apply game settings for this mod!";
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the description for the second custom category in the game options menu, if any.
|
|
||||||
/// </summary>
|
|
||||||
public virtual string CustomOptionMenuTwoDescription => "Apply game settings for this mod!";
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the BepInEx configuration file for the plugin.
|
/// Gets the BepInEx configuration file for the plugin.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ public class MiraPluginInfo
|
|||||||
public IReadOnlyCollection<CustomActionButton> Buttons { get; private set; } = null!;
|
public IReadOnlyCollection<CustomActionButton> Buttons { get; private set; } = null!;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a read only dictionary of this plugin's custom presets.
|
/// Gets a read only dictionary of this plugin's custom game modes.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public IReadOnlyCollection<OptionPreset> Presets { get; internal set; } = null!;
|
public IReadOnlyCollection<OptionPreset> Presets { get; internal set; } = null!;
|
||||||
|
|
||||||
|
|||||||
@@ -70,14 +70,14 @@ public sealed class MiraPluginManager
|
|||||||
|
|
||||||
if (!method.IsStatic)
|
if (!method.IsStatic)
|
||||||
{
|
{
|
||||||
Error($"Event method {method.Name} in {type.Name} must be static.");
|
Logger<MiraApiPlugin>.Error($"Event method {method.Name} in {type.Name} must be static.");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
var parameters = method.GetParameters();
|
var parameters = method.GetParameters();
|
||||||
if (parameters.Length != 1 || !parameters[0].ParameterType.IsSubclassOf(typeof(MiraEvent)))
|
if (parameters.Length != 1 || !parameters[0].ParameterType.IsSubclassOf(typeof(MiraEvent)))
|
||||||
{
|
{
|
||||||
Error($"Invalid event registration method {method.Name} in {type.Name}");
|
Logger<MiraApiPlugin>.Error($"Invalid event registration method {method.Name} in {type.Name}");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -131,7 +131,7 @@ public sealed class MiraPluginManager
|
|||||||
info.SavePublicCollections();
|
info.SavePublicCollections();
|
||||||
PresetManager.CreateDefaultPreset(info);
|
PresetManager.CreateDefaultPreset(info);
|
||||||
PresetManager.LoadPresets(info);
|
PresetManager.LoadPresets(info);
|
||||||
Info($"Registering mod {pluginInfo.Metadata.GUID} with Mira API.");
|
Logger<MiraApiPlugin>.Info($"Registering mod {pluginInfo.Metadata.GUID} with Mira API.");
|
||||||
};
|
};
|
||||||
IL2CPPChainloader.Instance.Finished += PaletteManager.RegisterAllColors;
|
IL2CPPChainloader.Instance.Finished += PaletteManager.RegisterAllColors;
|
||||||
IL2CPPChainloader.Instance.Finished += () =>
|
IL2CPPChainloader.Instance.Finished += () =>
|
||||||
@@ -167,7 +167,7 @@ public sealed class MiraPluginManager
|
|||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Error($"Failed to register game over {type.Name}: {e}");
|
Logger<MiraApiPlugin>.Error($"Failed to register game over {type.Name}: {e}");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -190,7 +190,7 @@ public sealed class MiraPluginManager
|
|||||||
{
|
{
|
||||||
if (property.GetMethod?.IsStatic == true)
|
if (property.GetMethod?.IsStatic == true)
|
||||||
{
|
{
|
||||||
Error($"Option property {property.Name} in {type.Name} must not be static.");
|
Logger<MiraApiPlugin>.Error($"Option property {property.Name} in {type.Name} must not be static.");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -211,14 +211,14 @@ public sealed class MiraPluginManager
|
|||||||
|
|
||||||
foreach (var field in type.GetFields().Where(f => f.FieldType.IsAssignableTo(typeof(IModdedOption))))
|
foreach (var field in type.GetFields().Where(f => f.FieldType.IsAssignableTo(typeof(IModdedOption))))
|
||||||
{
|
{
|
||||||
Error($"{field.Name} is a field, not a property. Use properties for options.");
|
Logger<MiraApiPlugin>.Error($"{field.Name} is a field, not a property. Use properties for options.");
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Error($"Failed to register options for {type.Name}: {e.ToString()}");
|
Logger<MiraApiPlugin>.Error($"Failed to register options for {type.Name}: {e.ToString()}");
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -235,7 +235,7 @@ public sealed class MiraPluginManager
|
|||||||
|
|
||||||
if (!ModList.GetById(pluginInfo.PluginId).IsRequiredOnAllClients)
|
if (!ModList.GetById(pluginInfo.PluginId).IsRequiredOnAllClients)
|
||||||
{
|
{
|
||||||
Error("Custom roles are only supported on all clients.");
|
Logger<MiraApiPlugin>.Error("Custom roles are only supported on all clients.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -244,7 +244,7 @@ public sealed class MiraPluginManager
|
|||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Error($"Failed to register role for {type.Name}: {e}");
|
Logger<MiraApiPlugin>.Error($"Failed to register role for {type.Name}: {e}");
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -260,7 +260,7 @@ public sealed class MiraPluginManager
|
|||||||
|
|
||||||
if (!type.IsStatic())
|
if (!type.IsStatic())
|
||||||
{
|
{
|
||||||
Error($"Color class {type.Name} must be static.");
|
Logger<MiraApiPlugin>.Error($"Color class {type.Name} must be static.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -273,7 +273,7 @@ public sealed class MiraPluginManager
|
|||||||
|
|
||||||
if (property.GetValue(null) is not CustomColor color)
|
if (property.GetValue(null) is not CustomColor color)
|
||||||
{
|
{
|
||||||
Error($"Color property {property.Name} in {type.Name} is not a CustomColor.");
|
Logger<MiraApiPlugin>.Error($"Color property {property.Name} in {type.Name} is not a CustomColor.");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -282,12 +282,12 @@ public sealed class MiraPluginManager
|
|||||||
|
|
||||||
foreach (var field in type.GetFields().Where(f => f.FieldType.IsAssignableTo(typeof(CustomColor))))
|
foreach (var field in type.GetFields().Where(f => f.FieldType.IsAssignableTo(typeof(CustomColor))))
|
||||||
{
|
{
|
||||||
Error($"{field.Name} is a field, not a property. Use properties for colors.");
|
Logger<MiraApiPlugin>.Error($"{field.Name} is a field, not a property. Use properties for colors.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Error($"Failed to register color class {type.Name}: {e}");
|
Logger<MiraApiPlugin>.Error($"Failed to register color class {type.Name}: {e}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -299,7 +299,7 @@ public sealed class MiraPluginManager
|
|||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Error($"Failed to register modifier {type.Name}: {e}");
|
Logger<MiraApiPlugin>.Error($"Failed to register modifier {type.Name}: {e}");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -312,7 +312,7 @@ public sealed class MiraPluginManager
|
|||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Error($"Failed to register button {type.Name}: {e}");
|
Logger<MiraApiPlugin>.Error($"Failed to register button {type.Name}: {e}");
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@@ -355,13 +355,13 @@ public sealed class MiraPluginManager
|
|||||||
|
|
||||||
if (property.GetMethod?.IsStatic == true)
|
if (property.GetMethod?.IsStatic == true)
|
||||||
{
|
{
|
||||||
Error($"Option property {property.Name} in {type.Name} must not be static.");
|
Logger<MiraApiPlugin>.Error($"Option property {property.Name} in {type.Name} must not be static.");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (property.GetValue(tabInstance) is not ConfigEntryBase configEntry)
|
if (property.GetValue(tabInstance) is not ConfigEntryBase configEntry)
|
||||||
{
|
{
|
||||||
Error($"Option property {property.Name} in {type.Name} has to be a config entry.");
|
Logger<MiraApiPlugin>.Error($"Option property {property.Name} in {type.Name} has to be a config entry.");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -376,14 +376,14 @@ public sealed class MiraPluginManager
|
|||||||
|
|
||||||
foreach (var field in type.GetFields().Where(f => f.FieldType.IsAssignableTo(typeof(ConfigEntryBase)) && f.GetCustomAttribute<LocalSettingAttribute>() != null))
|
foreach (var field in type.GetFields().Where(f => f.FieldType.IsAssignableTo(typeof(ConfigEntryBase)) && f.GetCustomAttribute<LocalSettingAttribute>() != null))
|
||||||
{
|
{
|
||||||
Error($"{field.Name} is a field, not a property. Use properties for local settings.");
|
Logger<MiraApiPlugin>.Error($"{field.Name} is a field, not a property. Use properties for local settings.");
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Error($"Failed to register options for {type.Name}: {e.ToString()}");
|
Logger<MiraApiPlugin>.Error($"Failed to register options for {type.Name}: {e.ToString()}");
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@@ -400,7 +400,7 @@ public sealed class MiraPluginManager
|
|||||||
|
|
||||||
if (!type.IsStatic())
|
if (!type.IsStatic())
|
||||||
{
|
{
|
||||||
Error($"Keybinds class {type.Name} must be static.");
|
Logger<MiraApiPlugin>.Error($"Keybinds class {type.Name} must be static.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -413,7 +413,7 @@ public sealed class MiraPluginManager
|
|||||||
|
|
||||||
if (property.GetValue(null) is not MiraKeybind keybind)
|
if (property.GetValue(null) is not MiraKeybind keybind)
|
||||||
{
|
{
|
||||||
Error($"Keybind property {property.Name} in {type.Name} is not a MiraKeybind.");
|
Logger<MiraApiPlugin>.Error($"Keybind property {property.Name} in {type.Name} is not a MiraKeybind.");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -430,12 +430,12 @@ public sealed class MiraPluginManager
|
|||||||
|
|
||||||
foreach (var field in type.GetFields().Where(f => f.FieldType.IsAssignableTo(typeof(MiraKeybind))))
|
foreach (var field in type.GetFields().Where(f => f.FieldType.IsAssignableTo(typeof(MiraKeybind))))
|
||||||
{
|
{
|
||||||
Error($"{field.Name} is a field, not a property. Use properties for keybinds.");
|
Logger<MiraApiPlugin>.Error($"{field.Name} is a field, not a property. Use properties for keybinds.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Error($"Failed to register keybind class {type.Name}: {e}");
|
Logger<MiraApiPlugin>.Error($"Failed to register keybind class {type.Name}: {e}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
using System.Collections.Generic;
|
using System.IO;
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using BepInEx.Configuration;
|
using BepInEx.Configuration;
|
||||||
using MiraAPI.PluginLoading;
|
using MiraAPI.PluginLoading;
|
||||||
@@ -19,13 +18,6 @@ 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 List<OptionPreset> InternalMasterPresets { get; } = [];
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets a read only dictionary of this plugin's custom presets.
|
|
||||||
/// </summary>
|
|
||||||
public static IReadOnlyCollection<OptionPreset> MasterPresets { get; internal set; } = null!;
|
|
||||||
|
|
||||||
internal static void CreateDefaultPreset(MiraPluginInfo plugin)
|
internal static void CreateDefaultPreset(MiraPluginInfo plugin)
|
||||||
{
|
{
|
||||||
var presetPath = Path.Combine(PresetDirectory, plugin.PluginId);
|
var presetPath = Path.Combine(PresetDirectory, plugin.PluginId);
|
||||||
@@ -78,7 +70,7 @@ public static class PresetManager
|
|||||||
foreach (var file in Directory.GetFiles(pluginPresetPath, "*.cfg"))
|
foreach (var file in Directory.GetFiles(pluginPresetPath, "*.cfg"))
|
||||||
{
|
{
|
||||||
var fileName = Path.GetFileName(file);
|
var fileName = Path.GetFileName(file);
|
||||||
Info($"Loading preset file {fileName}");
|
Logger<MiraApiPlugin>.Info($"Loading preset file {fileName}");
|
||||||
var presetName = Path.GetFileNameWithoutExtension(file);
|
var presetName = Path.GetFileNameWithoutExtension(file);
|
||||||
var presetConfig = new ConfigFile(file, false)
|
var presetConfig = new ConfigFile(file, false)
|
||||||
{
|
{
|
||||||
@@ -101,58 +93,4 @@ public static class PresetManager
|
|||||||
}
|
}
|
||||||
plugin.Presets = [..plugin.InternalPresets];
|
plugin.Presets = [..plugin.InternalPresets];
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Loads the master presets by reading the configuration files from the preset directory.
|
|
||||||
/// </summary>
|
|
||||||
public static void LoadMasterPreset()
|
|
||||||
{
|
|
||||||
/*foreach (var btn in plugin.InternalPresets.Select(x=>x.PresetButton))
|
|
||||||
{
|
|
||||||
if (btn != null)
|
|
||||||
{
|
|
||||||
Object.DestroyImmediate(btn);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
plugin.InternalPresets.Clear();*/
|
|
||||||
if (!Directory.Exists(PresetDirectory))
|
|
||||||
{
|
|
||||||
Directory.CreateDirectory(PresetDirectory);
|
|
||||||
}
|
|
||||||
|
|
||||||
var pluginPresetPath = Path.Combine(PresetDirectory, "MasterPresets");
|
|
||||||
if (!Directory.Exists(pluginPresetPath))
|
|
||||||
{
|
|
||||||
Directory.CreateDirectory(pluginPresetPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var file in Directory.GetFiles(pluginPresetPath, "*.cfg"))
|
|
||||||
{
|
|
||||||
var fileName = Path.GetFileName(file);
|
|
||||||
Info($"Loading preset file {fileName}");
|
|
||||||
var presetName = Path.GetFileNameWithoutExtension(file);
|
|
||||||
var presetConfig = new ConfigFile(file, false)
|
|
||||||
{
|
|
||||||
SaveOnConfigSet = false,
|
|
||||||
};
|
|
||||||
foreach (var plugin in MiraPluginManager.Instance.RegisteredPlugins)
|
|
||||||
{
|
|
||||||
foreach (var option in plugin.InternalOptions.Where(x=>x.IncludeInPreset))
|
|
||||||
{
|
|
||||||
option.Bind(presetConfig);
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var role in plugin.InternalRoles.Values.OfType<ICustomRole>().Where(x=>!x.Configuration.HideSettings))
|
|
||||||
{
|
|
||||||
role.BindConfig(presetConfig);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
presetConfig.Save();
|
|
||||||
|
|
||||||
// InternalMasterPresets.Add(new OptionPreset(presetName, plugin, presetConfig));
|
|
||||||
}
|
|
||||||
MasterPresets = [..InternalMasterPresets];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -1,8 +1,7 @@
|
|||||||
using AmongUs.GameOptions;
|
using AmongUs.GameOptions;
|
||||||
using System;
|
|
||||||
using MiraAPI.Patches.Freeplay;
|
|
||||||
using MiraAPI.Utilities.Assets;
|
using MiraAPI.Utilities.Assets;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace MiraAPI.Roles;
|
namespace MiraAPI.Roles;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -10,16 +9,6 @@ namespace MiraAPI.Roles;
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public record struct CustomRoleConfiguration
|
public record struct CustomRoleConfiguration
|
||||||
{
|
{
|
||||||
#pragma warning disable S1133
|
|
||||||
[Obsolete("Default constructor is not supported. Please use the constructor that takes an ICustomRole parameter.")]
|
|
||||||
#pragma warning restore S1133
|
|
||||||
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
|
|
||||||
public CustomRoleConfiguration()
|
|
||||||
#pragma warning restore CS1591 // Missing XML comment for publicly visible type or member
|
|
||||||
{
|
|
||||||
throw new NotImplementedException("Default constructor is not supported. Please use the constructor that takes an ICustomRole parameter.");
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="CustomRoleConfiguration"/> struct.
|
/// Initializes a new instance of the <see cref="CustomRoleConfiguration"/> struct.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -47,7 +36,7 @@ public record struct CustomRoleConfiguration
|
|||||||
{
|
{
|
||||||
ModdedRoleTeams.Crewmate => TranslationController.Instance.GetString(StringNames.Crewmate),
|
ModdedRoleTeams.Crewmate => TranslationController.Instance.GetString(StringNames.Crewmate),
|
||||||
ModdedRoleTeams.Impostor => TranslationController.Instance.GetString(StringNames.Impostor),
|
ModdedRoleTeams.Impostor => TranslationController.Instance.GetString(StringNames.Impostor),
|
||||||
_ => TaskAdderPatches.NeutralName,
|
_ => "Neutral",
|
||||||
};
|
};
|
||||||
IntroSound = role.Team is ModdedRoleTeams.Crewmate
|
IntroSound = role.Team is ModdedRoleTeams.Crewmate
|
||||||
? CustomRoleManager.CrewmateIntroSound
|
? CustomRoleManager.CrewmateIntroSound
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ using System.Linq;
|
|||||||
using AmongUs.GameOptions;
|
using AmongUs.GameOptions;
|
||||||
using Il2CppInterop.Runtime;
|
using Il2CppInterop.Runtime;
|
||||||
using Il2CppInterop.Runtime.Injection;
|
using Il2CppInterop.Runtime.Injection;
|
||||||
using Il2CppInterop.Runtime.InteropTypes.Arrays;
|
|
||||||
using MiraAPI.Networking;
|
using MiraAPI.Networking;
|
||||||
using MiraAPI.PluginLoading;
|
using MiraAPI.PluginLoading;
|
||||||
using MiraAPI.Utilities;
|
using MiraAPI.Utilities;
|
||||||
@@ -54,9 +53,6 @@ public static class CustomRoleManager
|
|||||||
internal static readonly Dictionary<ushort, RoleBehaviour> CustomRoles = [];
|
internal static readonly Dictionary<ushort, RoleBehaviour> CustomRoles = [];
|
||||||
internal static readonly Dictionary<Type, ushort> RoleIds = [];
|
internal static readonly Dictionary<Type, ushort> RoleIds = [];
|
||||||
|
|
||||||
private static Il2CppSystem.Collections.Generic.List<BaseGameSetting>? _emptySettings;
|
|
||||||
private static Il2CppReferenceArray<OverlayKillAnimation>? _emptyKillAnimations;
|
|
||||||
|
|
||||||
private static ushort _roleId = 100;
|
private static ushort _roleId = 100;
|
||||||
|
|
||||||
private static ushort GetNextRoleId()
|
private static ushort GetNextRoleId()
|
||||||
@@ -108,7 +104,7 @@ public static class CustomRoleManager
|
|||||||
{
|
{
|
||||||
if (!(typeof(RoleBehaviour).IsAssignableFrom(roleType) && typeof(ICustomRole).IsAssignableFrom(roleType)))
|
if (!(typeof(RoleBehaviour).IsAssignableFrom(roleType) && typeof(ICustomRole).IsAssignableFrom(roleType)))
|
||||||
{
|
{
|
||||||
Error($"{roleType.Name} does not inherit from RoleBehaviour or ICustomRole.");
|
Logger<MiraApiPlugin>.Error($"{roleType.Name} does not inherit from RoleBehaviour or ICustomRole.");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -137,12 +133,6 @@ public static class CustomRoleManager
|
|||||||
roleBehaviour.MaxCount = customRole.Configuration.MaxRoleCount;
|
roleBehaviour.MaxCount = customRole.Configuration.MaxRoleCount;
|
||||||
roleBehaviour.RoleScreenshot = customRole.Configuration.OptionsScreenshot?.LoadAsset();
|
roleBehaviour.RoleScreenshot = customRole.Configuration.OptionsScreenshot?.LoadAsset();
|
||||||
|
|
||||||
_emptySettings ??= new(0);
|
|
||||||
_emptyKillAnimations ??= new(0);
|
|
||||||
|
|
||||||
roleBehaviour.AllGameSettings = _emptySettings;
|
|
||||||
roleBehaviour.CustomKillAnimations = _emptyKillAnimations;
|
|
||||||
|
|
||||||
if (customRole.Configuration.Icon != null)
|
if (customRole.Configuration.Icon != null)
|
||||||
{
|
{
|
||||||
var asset = customRole.Configuration.Icon.LoadAsset();
|
var asset = customRole.Configuration.Icon.LoadAsset();
|
||||||
@@ -168,7 +158,7 @@ public static class CustomRoleManager
|
|||||||
|
|
||||||
if (useTaskHint && !overridesTaskText)
|
if (useTaskHint && !overridesTaskText)
|
||||||
{
|
{
|
||||||
Error($"Role {customRole.RoleName} is using RoleHintType.TaskHint but does not override SpawnTaskHeader!");
|
Logger<MiraApiPlugin>.Error($"Role {customRole.RoleName} is using RoleHintType.TaskHint but does not override SpawnTaskHeader!");
|
||||||
}
|
}
|
||||||
|
|
||||||
CustomRoles.Add(roleId, roleBehaviour);
|
CustomRoles.Add(roleId, roleBehaviour);
|
||||||
@@ -298,7 +288,7 @@ public static class CustomRoleManager
|
|||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Error(e);
|
Logger<MiraApiPlugin>.Error(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using System;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
@@ -14,62 +13,6 @@ namespace MiraAPI.Roles;
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static class CustomRoleUtils
|
public static class CustomRoleUtils
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// Determines whether the specified role can spawn in general, accounting for gamemodes and everything else.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="role">The role you would like to check for.</param>
|
|
||||||
/// <returns>True if the role is able to spawn, otherwise false.</returns>
|
|
||||||
public static bool CanSpawnOnCurrentMode(RoleBehaviour role)
|
|
||||||
{
|
|
||||||
if (role is ICustomRole custom)
|
|
||||||
{
|
|
||||||
return custom.CanSpawnOnCurrentMode();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (GameManager.Instance.IsHideAndSeek())
|
|
||||||
{
|
|
||||||
return role.Role is RoleTypes.Engineer || role.Role is RoleTypes.Impostor;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static List<(ushort RoleType, int Chance)> GetPossibleRoles(
|
|
||||||
List<RoleManager.RoleAssignmentData> assignmentData,
|
|
||||||
Func<RoleManager.RoleAssignmentData, bool>? predicate = null)
|
|
||||||
{
|
|
||||||
var roles = new List<(ushort, int)>();
|
|
||||||
|
|
||||||
assignmentData.Where(x => predicate == null || predicate(x)).ToList().ForEach(x =>
|
|
||||||
{
|
|
||||||
for (var i = 0; i < x.Count; i++)
|
|
||||||
{
|
|
||||||
roles.Add(((ushort)x.Role.Role, x.Chance));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return roles;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static RoleManager.RoleAssignmentData GetAssignData(RoleTypes roleType)
|
|
||||||
{
|
|
||||||
var currentGameOptions = GameOptionsManager.Instance.CurrentGameOptions;
|
|
||||||
var roleOptions = currentGameOptions.RoleOptions;
|
|
||||||
|
|
||||||
var role = GetRegisteredRole(roleType);
|
|
||||||
var assignmentData = new RoleManager.RoleAssignmentData(role, roleOptions.GetNumPerGame(role!.Role),
|
|
||||||
roleOptions.GetChancePerGame(role.Role));
|
|
||||||
|
|
||||||
return assignmentData;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static RoleBehaviour? GetRegisteredRole(RoleTypes roleType)
|
|
||||||
{
|
|
||||||
// we want to prioritize the custom roles because the role has the right RoleColour/TeamColor
|
|
||||||
var role = CustomRoleManager.AllRoles.FirstOrDefault(x => x.Role == roleType);
|
|
||||||
|
|
||||||
return role;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets all active in-game roles.
|
/// Gets all active in-game roles.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using System;
|
using System.Text;
|
||||||
using System.Text;
|
|
||||||
using BepInEx.Configuration;
|
using BepInEx.Configuration;
|
||||||
using MiraAPI.GameOptions;
|
using MiraAPI.GameOptions;
|
||||||
using MiraAPI.Modifiers;
|
using MiraAPI.Modifiers;
|
||||||
@@ -157,7 +156,7 @@ public interface ICustomRole : IOptionable
|
|||||||
{
|
{
|
||||||
if (!Configuration.CanModifyChance)
|
if (!Configuration.CanModifyChance)
|
||||||
{
|
{
|
||||||
Error($"Cannot modify chance for role: {RoleName}");
|
Logger<MiraApiPlugin>.Error($"Cannot modify chance for role: {RoleName}");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -167,7 +166,7 @@ public interface ICustomRole : IOptionable
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Error($"Error getting chance configuration for role: {RoleName}");
|
Logger<MiraApiPlugin>.Error($"Error getting chance configuration for role: {RoleName}");
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -182,7 +181,7 @@ public interface ICustomRole : IOptionable
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Error($"Error getting count configuration for role: {RoleName}");
|
Logger<MiraApiPlugin>.Error($"Error getting count configuration for role: {RoleName}");
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -240,15 +239,4 @@ public interface ICustomRole : IOptionable
|
|||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Determines whether the role can spawn in general, accounting for gamemodes and everything else.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>True if the role is able to spawn, otherwise false.</returns>
|
|
||||||
public virtual bool CanSpawnOnCurrentMode() => !GameManager.Instance.IsHideAndSeek();
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the function that determines whether the role should be toggled on or off in the game settings.
|
|
||||||
/// </summary>
|
|
||||||
public virtual Func<bool> VisibleInSettings => () => true;
|
|
||||||
}
|
}
|
||||||
@@ -33,7 +33,7 @@ public static class AddressablesLoader
|
|||||||
{
|
{
|
||||||
if (_isInitialized)
|
if (_isInitialized)
|
||||||
{
|
{
|
||||||
Error("AddressablesLoader has already been initialized, cannot register more catalogs.");
|
Logger<MiraApiPlugin>.Error("AddressablesLoader has already been initialized, cannot register more catalogs.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -48,7 +48,7 @@ public static class AddressablesLoader
|
|||||||
{
|
{
|
||||||
if (_isInitialized)
|
if (_isInitialized)
|
||||||
{
|
{
|
||||||
Error("AddressablesLoader has already been initialized, cannot register more keys for hats.");
|
Logger<MiraApiPlugin>.Error("AddressablesLoader has already been initialized, cannot register more keys for hats.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -63,7 +63,7 @@ public static class AddressablesLoader
|
|||||||
{
|
{
|
||||||
if (_isInitialized)
|
if (_isInitialized)
|
||||||
{
|
{
|
||||||
Error("AddressablesLoader has already been initialized, cannot register more keys for skins.");
|
Logger<MiraApiPlugin>.Error("AddressablesLoader has already been initialized, cannot register more keys for skins.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -79,7 +79,7 @@ public static class AddressablesLoader
|
|||||||
{
|
{
|
||||||
if (_isInitialized)
|
if (_isInitialized)
|
||||||
{
|
{
|
||||||
Error("AddressablesLoader has already been initialized, cannot register more keys for nameplates.");
|
Logger<MiraApiPlugin>.Error("AddressablesLoader has already been initialized, cannot register more keys for nameplates.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -95,7 +95,7 @@ public static class AddressablesLoader
|
|||||||
{
|
{
|
||||||
if (_isInitialized)
|
if (_isInitialized)
|
||||||
{
|
{
|
||||||
Error("AddressablesLoader has already been initialized, cannot register more keys for visors.");
|
Logger<MiraApiPlugin>.Error("AddressablesLoader has already been initialized, cannot register more keys for visors.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -106,7 +106,7 @@ public static class AddressablesLoader
|
|||||||
{
|
{
|
||||||
if (_isInitialized)
|
if (_isInitialized)
|
||||||
{
|
{
|
||||||
Error("AddressablesLoader has already been initialized.");
|
Logger<MiraApiPlugin>.Error("AddressablesLoader has already been initialized.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -129,10 +129,10 @@ public static class AddressablesLoader
|
|||||||
// Check for errors
|
// Check for errors
|
||||||
if (catalogOperation.Status != AsyncOperationStatus.Succeeded)
|
if (catalogOperation.Status != AsyncOperationStatus.Succeeded)
|
||||||
{
|
{
|
||||||
Error($"Failed to load catalog {location}.");
|
Logger<MiraApiPlugin>.Error($"Failed to load catalog {location}.");
|
||||||
}
|
}
|
||||||
|
|
||||||
Info($"Loaded addressables {location}.");
|
Logger<MiraApiPlugin>.Info($"Loaded addressables {location}.");
|
||||||
LoadedLocations.Add(location);
|
LoadedLocations.Add(location);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -193,7 +193,7 @@ public static class AddressablesLoader
|
|||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
Error($"Failed to find tag {tag}");
|
Logger<MiraApiPlugin>.Error($"Failed to find tag {tag}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return behaviours;
|
return behaviours;
|
||||||
@@ -214,7 +214,7 @@ public static class AddressablesLoader
|
|||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
Error($"Failed to find tag {tag}");
|
Logger<MiraApiPlugin>.Error($"Failed to find tag {tag}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return behaviours;
|
return behaviours;
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ public class LoadableAddressableAsset<T>(string uid) : LoadableAsset<T> where T
|
|||||||
|
|
||||||
var remoteReference = new AssetReference(uid);
|
var remoteReference = new AssetReference(uid);
|
||||||
|
|
||||||
if (!GC.TryStartNoGCRegion(4096, true)) Error("Could not start NoGCRegion of size 4kb, there is the possibility of injected unmanaged classes being garbage collected as per BepInEx/Il2CppInterop/issues/40");
|
if (!GC.TryStartNoGCRegion(4096, true)) Logger<MiraApiPlugin>.Error("Could not start NoGCRegion of size 4kb, there is the possibility of injected unmanaged classes being garbage collected as per BepInEx/Il2CppInterop/issues/40");
|
||||||
|
|
||||||
LoadedAsset = remoteReference.LoadAssetAsync<T>().WaitForCompletion();
|
LoadedAsset = remoteReference.LoadAssetAsync<T>().WaitForCompletion();
|
||||||
if (LoadedAsset == null)
|
if (LoadedAsset == null)
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ public class LoadableAddressableAssets<T>(string key) where T : UnityEngine.Obje
|
|||||||
|
|
||||||
var locations = Addressables.LoadResourceLocationsAsync(key).WaitForCompletion();
|
var locations = Addressables.LoadResourceLocationsAsync(key).WaitForCompletion();
|
||||||
|
|
||||||
if (!GC.TryStartNoGCRegion(4096, true)) Error("Could not start NoGCRegion of size 4kb, there is the possibility of injected unmanaged classes being garbage collected as per BepInEx/Il2CppInterop/issues/40");
|
if (!GC.TryStartNoGCRegion(4096, true)) Logger<MiraApiPlugin>.Error("Could not start NoGCRegion of size 4kb, there is the possibility of injected unmanaged classes being garbage collected as per BepInEx/Il2CppInterop/issues/40");
|
||||||
|
|
||||||
var assetsIList = Addressables.LoadAssetsAsync<T>(locations, null, false).WaitForCompletion();
|
var assetsIList = Addressables.LoadAssetsAsync<T>(locations, null, false).WaitForCompletion();
|
||||||
if (assetsIList == null)
|
if (assetsIList == null)
|
||||||
|
|||||||
@@ -19,10 +19,7 @@ public static class SpriteTools
|
|||||||
/// <exception cref="ArgumentException">Thrown when the resource cannot be found in the specified assembly.</exception>
|
/// <exception cref="ArgumentException">Thrown when the resource cannot be found in the specified assembly.</exception>
|
||||||
public static Texture2D LoadTextureFromResourcePath(string resourcePath, Assembly assembly)
|
public static Texture2D LoadTextureFromResourcePath(string resourcePath, Assembly assembly)
|
||||||
{
|
{
|
||||||
var tex = new Texture2D(1, 1, TextureFormat.ARGB32, false)
|
var tex = new Texture2D(1, 1, TextureFormat.ARGB32, false);
|
||||||
{
|
|
||||||
wrapMode = TextureWrapMode.Clamp,
|
|
||||||
};
|
|
||||||
var myStream = assembly.GetManifestResourceStream(resourcePath);
|
var myStream = assembly.GetManifestResourceStream(resourcePath);
|
||||||
if (myStream != null)
|
if (myStream != null)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -29,13 +29,13 @@ public static class Extensions
|
|||||||
|
|
||||||
if (count == null)
|
if (count == null)
|
||||||
{
|
{
|
||||||
Error("Couldn't get role count for NetData, defaulting to zero.");
|
Logger<MiraApiPlugin>.Error("Couldn't get role count for NetData, defaulting to zero.");
|
||||||
count = 0;
|
count = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (chance == null)
|
if (chance == null)
|
||||||
{
|
{
|
||||||
Error("Couldn't get role chance for NetData, defaulting to zero.");
|
Logger<MiraApiPlugin>.Error("Couldn't get role chance for NetData, defaulting to zero.");
|
||||||
chance = 0;
|
chance = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -398,7 +398,7 @@ public static class Extensions
|
|||||||
|
|
||||||
if (length > chunkSize)
|
if (length > chunkSize)
|
||||||
{
|
{
|
||||||
Info($"NetData length is greater than chunk size: {length} > {chunkSize}");
|
Logger<MiraApiPlugin>.Info($"NetData length is greater than chunk size: {length} > {chunkSize}");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using AmongUs.GameOptions;
|
|
||||||
using HarmonyLib;
|
using HarmonyLib;
|
||||||
using Il2CppInterop.Runtime.InteropTypes.Arrays;
|
using Il2CppInterop.Runtime.InteropTypes.Arrays;
|
||||||
using MiraAPI.Roles;
|
using MiraAPI.Roles;
|
||||||
@@ -50,18 +49,18 @@ public static class Helpers
|
|||||||
|
|
||||||
if (showRoleStateMachine == null)
|
if (showRoleStateMachine == null)
|
||||||
{
|
{
|
||||||
Error($"Failed to find {methodName} state machine for {typeName}");
|
Logger<MiraApiPlugin>.Error($"Failed to find {methodName} state machine for {typeName}");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
var moveNext = AccessTools.Method(showRoleStateMachine, "MoveNext");
|
var moveNext = AccessTools.Method(showRoleStateMachine, "MoveNext");
|
||||||
if (moveNext == null)
|
if (moveNext == null)
|
||||||
{
|
{
|
||||||
Error($"Failed to find MoveNext method for {typeName}.{methodName}");
|
Logger<MiraApiPlugin>.Error($"Failed to find MoveNext method for {typeName}.{methodName}");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
Info($"Found {methodName}.MoveNext");
|
Logger<MiraApiPlugin>.Info($"Found {methodName}.MoveNext");
|
||||||
return moveNext;
|
return moveNext;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -140,7 +139,7 @@ public static class Helpers
|
|||||||
return true;
|
return true;
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
var num = Random.RandomRangeInt(1, 101);
|
var num = UnityEngine.Random.RandomRangeInt(1, 101);
|
||||||
return num <= probability;
|
return num <= probability;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -501,7 +500,7 @@ public static class Helpers
|
|||||||
public static string RandomString(int length, string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")
|
public static string RandomString(int length, string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")
|
||||||
{
|
{
|
||||||
return new string(Enumerable.Repeat(chars, length)
|
return new string(Enumerable.Repeat(chars, length)
|
||||||
.Select(s => s[Random.RandomRangeInt(0, s.Length)]).ToArray());
|
.Select(s => s[UnityEngine.Random.RandomRangeInt(0, s.Length)]).ToArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -537,19 +536,4 @@ public static class Helpers
|
|||||||
}
|
}
|
||||||
return role.NiceName;
|
return role.NiceName;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns whether the role is blacklisted from appearing and spawning. (Only applicable to vanilla roles)
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="role">The role to check.</param>
|
|
||||||
/// <returns>The role's blacklist status.</returns>
|
|
||||||
public static bool IsRoleBlacklisted(this RoleBehaviour role)
|
|
||||||
{
|
|
||||||
// This should be patchable by mods when a vanilla role is meant to be replaced by a custom role.
|
|
||||||
if (role.Role is RoleTypes.Engineer)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,4 @@
|
|||||||
using System;
|
using System.Reflection;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Reflection;
|
|
||||||
using HarmonyLib;
|
using HarmonyLib;
|
||||||
using Il2CppInterop.Runtime.InteropTypes;
|
using Il2CppInterop.Runtime.InteropTypes;
|
||||||
|
|
||||||
@@ -13,11 +11,8 @@ namespace MiraAPI.Utilities;
|
|||||||
public class StateMachineWrapper<T> where T : Il2CppObjectBase
|
public class StateMachineWrapper<T> where T : Il2CppObjectBase
|
||||||
{
|
{
|
||||||
private readonly Il2CppObjectBase _stateMachine;
|
private readonly Il2CppObjectBase _stateMachine;
|
||||||
|
|
||||||
// normally it is fields, but IL2CPP turns them into properties
|
|
||||||
private readonly PropertyInfo _thisProperty;
|
private readonly PropertyInfo _thisProperty;
|
||||||
private readonly PropertyInfo _stateProperty;
|
private readonly PropertyInfo _stateProperty;
|
||||||
private readonly Dictionary<string, PropertyInfo> _propertyCache;
|
|
||||||
|
|
||||||
private T? _parentInstance;
|
private T? _parentInstance;
|
||||||
|
|
||||||
@@ -37,13 +32,6 @@ public class StateMachineWrapper<T> where T : Il2CppObjectBase
|
|||||||
var type = _stateMachine.GetType();
|
var type = _stateMachine.GetType();
|
||||||
_thisProperty = AccessTools.Property(type, "__4__this");
|
_thisProperty = AccessTools.Property(type, "__4__this");
|
||||||
_stateProperty = AccessTools.Property(type, "__1__state");
|
_stateProperty = AccessTools.Property(type, "__1__state");
|
||||||
|
|
||||||
if (_thisProperty == null || _stateProperty == null)
|
|
||||||
{
|
|
||||||
throw new MissingMemberException($"Could not find required properties in type '{type}'.");
|
|
||||||
}
|
|
||||||
|
|
||||||
_propertyCache = [];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -51,25 +39,4 @@ public class StateMachineWrapper<T> where T : Il2CppObjectBase
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>The current state as an integer.</returns>
|
/// <returns>The current state as an integer.</returns>
|
||||||
public int GetState() => (int)_stateProperty.GetValue(_stateMachine)!;
|
public int GetState() => (int)_stateProperty.GetValue(_stateMachine)!;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets a parameter from the state machine by its name.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="parameterName">The name of the parameter to retrieve.</param>
|
|
||||||
/// <typeparam name="TField">The type of the parameter to retrieve.</typeparam>
|
|
||||||
/// <returns>>The value of the specified parameter.</returns>
|
|
||||||
/// <exception cref="MissingFieldException">Thrown if the specified parameter does not exist.</exception>
|
|
||||||
public TField GetParameter<TField>(string parameterName)
|
|
||||||
{
|
|
||||||
if (_propertyCache.TryGetValue(parameterName, out var property))
|
|
||||||
{
|
|
||||||
return (TField)property.GetValue(_stateMachine)!;
|
|
||||||
}
|
|
||||||
|
|
||||||
property = AccessTools.Property(_stateMachine.GetType(), parameterName)
|
|
||||||
?? throw new MissingFieldException($"Could not find parameter '{parameterName}' in state machine of type '{_stateMachine.GetType()}'.");
|
|
||||||
|
|
||||||
_propertyCache[parameterName] = property;
|
|
||||||
return (TField)property.GetValue(_stateMachine)!;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -224,7 +224,7 @@ public static class VotingUtils
|
|||||||
var playerById = GameData.Instance.GetPlayerById(vote.Voter);
|
var playerById = GameData.Instance.GetPlayerById(vote.Voter);
|
||||||
if (playerById == null)
|
if (playerById == null)
|
||||||
{
|
{
|
||||||
Error($"Couldn't find player info for voter: {vote.Voter}");
|
Logger<MiraApiPlugin>.Error($"Couldn't find player info for voter: {vote.Voter}");
|
||||||
}
|
}
|
||||||
else if (i == 0 && vote.Suspect == SkipVoteId)
|
else if (i == 0 && vote.Suspect == SkipVoteId)
|
||||||
{
|
{
|
||||||
|
|||||||
+1
-1
@@ -6,6 +6,6 @@
|
|||||||
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" protocolVersion="3" />
|
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" protocolVersion="3" />
|
||||||
<add key="Reactor" value="https://nuget.reactor.gg/v3/index.json" />
|
<add key="Reactor" value="https://nuget.reactor.gg/v3/index.json" />
|
||||||
<add key="Samboy063" value="https://nuget.samboy.dev/v3/index.json" />
|
<add key="Samboy063" value="https://nuget.samboy.dev/v3/index.json" />
|
||||||
<add key="local" value="./packages" />
|
<add key="Local" value="packages/" />
|
||||||
</packageSources>
|
</packageSources>
|
||||||
</configuration>
|
</configuration>
|
||||||
Binary file not shown.
Binary file not shown.
@@ -1,3 +0,0 @@
|
|||||||
here to ensure git doesn't delete empty folders
|
|
||||||
|
|
||||||
local packages are stored in this directory
|
|
||||||
Reference in new issue
Block a user