mirror of
https://github.com/All-Of-Us-Mods/MiraAPI.git
synced 2026-10-28 19:43:55 +00:00
Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a72fefe235 |
No files matched your search
+2
-2
@@ -2,10 +2,10 @@
|
|||||||
<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.697" Private="false" ExcludeAssets="runtime;native" />
|
<PackageReference Include="BepInEx.Unity.IL2CPP" Version="6.0.0-be.697" Private="false" ExcludeAssets="runtime;native" />
|
||||||
<PackageReference Include="AmongUs.GameLibs.Android" Version="2025.3.28" PrivateAssets="all" />
|
<PackageReference Include="AmongUs.GameLibs.Steam" Version="2024.10.29" 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.0.1" PrivateAssets="all" ExcludeAssets="runtime" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<Target Name="Copy" AfterTargets="Build" Condition="'$(AmongUs)' != ''">
|
<Target Name="Copy" AfterTargets="Build" Condition="'$(AmongUs)' != ''">
|
||||||
|
|||||||
@@ -34,7 +34,7 @@
|
|||||||
<PackageReference Include="StyleCop.Analyzers" Version="1.2.0-beta.556" PrivateAssets="all" />
|
<PackageReference Include="StyleCop.Analyzers" Version="1.2.0-beta.556" PrivateAssets="all" />
|
||||||
<AdditionalFiles Include="$(MSBuildThisFileDirectory)\stylecop.json" Link="stylecop.json" Visible="false" />
|
<AdditionalFiles Include="$(MSBuildThisFileDirectory)\stylecop.json" Link="stylecop.json" Visible="false" />
|
||||||
|
|
||||||
<PackageReference Include="SonarAnalyzer.CSharp" Version="10.7.0.110445">
|
<PackageReference Include="SonarAnalyzer.CSharp" Version="9.32.0.97167">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
using AmongUs.GameOptions;
|
using AmongUs.GameOptions;
|
||||||
using MiraAPI.Roles;
|
using MiraAPI.Roles;
|
||||||
using Reactor.Utilities;
|
using MiraAPI.Utilities;
|
||||||
using TMPro;
|
using TMPro;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
@@ -20,12 +20,6 @@ public class ChameloenRole : CrewmateRole, ICustomRole
|
|||||||
IntroSound = CustomRoleUtils.GetIntroSound(RoleTypes.Shapeshifter),
|
IntroSound = CustomRoleUtils.GetIntroSound(RoleTypes.Shapeshifter),
|
||||||
};
|
};
|
||||||
|
|
||||||
public override void Initialize(PlayerControl player)
|
|
||||||
{
|
|
||||||
Player = player;
|
|
||||||
Logger<ExamplePlugin>.Error("Initializing ChamelonRole for player: " + player.PlayerId);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void PlayerControlFixedUpdate(PlayerControl playerControl)
|
public void PlayerControlFixedUpdate(PlayerControl playerControl)
|
||||||
{
|
{
|
||||||
if (playerControl.MyPhysics.Velocity.magnitude > 0)
|
if (playerControl.MyPhysics.Velocity.magnitude > 0)
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ public static class MiraEventManager
|
|||||||
public static bool InvokeEvent<T>(T eventInstance) where T : MiraEvent
|
public static bool InvokeEvent<T>(T eventInstance) where T : MiraEvent
|
||||||
{
|
{
|
||||||
EventWrappers.TryGetValue(typeof(T), out var handlers);
|
EventWrappers.TryGetValue(typeof(T), out var handlers);
|
||||||
if (handlers == null || handlers.Count == 0)
|
if (handlers == null)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -43,7 +43,7 @@ public static class MiraEventManager
|
|||||||
public static bool InvokeEvent(MiraEvent eventInstance, Type type)
|
public static bool InvokeEvent(MiraEvent eventInstance, Type type)
|
||||||
{
|
{
|
||||||
EventWrappers.TryGetValue(type, out var handlers);
|
EventWrappers.TryGetValue(type, out var handlers);
|
||||||
if (handlers == null || handlers.Count == 0)
|
if (handlers == null)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -61,51 +61,47 @@ public static class MiraEventManager
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="type">The type of event.</param>
|
/// <param name="type">The type of event.</param>
|
||||||
/// <param name="methodInfo">The MethodInfo of the event handler.</param>
|
/// <param name="methodInfo">The MethodInfo of the event handler.</param>
|
||||||
/// <param name="priority">The priority of the event handler. Lower values are called first.</param>
|
/// <param name="priority">The priority of the event handler. Higher values are called first.</param>
|
||||||
public static void RegisterEventHandler(Type type, MethodInfo methodInfo, int priority = 0)
|
public static void RegisterEventHandler(Type type, MethodInfo methodInfo, int priority = 0)
|
||||||
{
|
{
|
||||||
if (!type.IsSubclassOf(typeof(MiraEvent)))
|
if (!type.IsSubclassOf(typeof(MiraEvent)))
|
||||||
{
|
{
|
||||||
Logger<MiraApiPlugin>.Error($"Type must be a subclass of MiraEvent: {type.FullName}");
|
Logger<MiraApiPlugin>.Error($"Type must be a subclass of MiraEvent: {nameof(type)}");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
EventWrappers.TryAdd(type, []);
|
if (!EventWrappers.TryGetValue(type, out var handlers))
|
||||||
var handlers = EventWrappers[type];
|
|
||||||
|
|
||||||
var @delegate = Delegate.CreateDelegate(typeof(Action<>).MakeGenericType(type), methodInfo);
|
|
||||||
var eventWrapper = new MiraEventWrapper(@delegate, priority);
|
|
||||||
|
|
||||||
var index = handlers.BinarySearch(eventWrapper, Comparer<MiraEventWrapper>.Create((a, b) => a.Priority.CompareTo(b.Priority)));
|
|
||||||
|
|
||||||
if (index < 0)
|
|
||||||
{
|
{
|
||||||
index = ~index;
|
handlers = [];
|
||||||
|
EventWrappers.Add(type, handlers);
|
||||||
}
|
}
|
||||||
|
|
||||||
handlers.Insert(index, eventWrapper);
|
var @delegate = Delegate.CreateDelegate(typeof(Action<>).MakeGenericType(type), methodInfo);
|
||||||
|
handlers.Add(new MiraEventWrapper(@delegate, priority));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Register an event.
|
/// Register an event.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="handler">The callback method/handler for the event.</param>
|
/// <param name="handler">The callback method/handler for the event.</param>
|
||||||
/// <param name="priority">The priority of the event handler. Lower values are called first.</param>
|
/// <param name="priority">The priority of the event handler. Higher values are called first.</param>
|
||||||
/// <typeparam name="T">Type of event.</typeparam>
|
/// <typeparam name="T">Type of event.</typeparam>
|
||||||
public static void RegisterEventHandler<T>(Action<T> handler, int priority = 0) where T : MiraEvent
|
public static void RegisterEventHandler<T>(Action<T> handler, int priority = 0) where T : MiraEvent
|
||||||
{
|
{
|
||||||
EventWrappers.TryAdd(typeof(T), []);
|
if (!EventWrappers.ContainsKey(typeof(T)))
|
||||||
|
|
||||||
var handlers = EventWrappers[typeof(T)];
|
|
||||||
var eventWrapper = new MiraEventWrapper(handler, priority);
|
|
||||||
|
|
||||||
var index = handlers.BinarySearch(eventWrapper, Comparer<MiraEventWrapper>.Create((a, b) => a.Priority.CompareTo(b.Priority)));
|
|
||||||
|
|
||||||
if (index < 0)
|
|
||||||
{
|
{
|
||||||
index = ~index;
|
EventWrappers.Add(typeof(T), []);
|
||||||
}
|
}
|
||||||
|
|
||||||
handlers.Insert(index, eventWrapper);
|
var handlers = EventWrappers[typeof(T)];
|
||||||
|
handlers.Add(new MiraEventWrapper(handler, priority));
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static void SortAllHandlers()
|
||||||
|
{
|
||||||
|
foreach (var handlers in EventWrappers.Values)
|
||||||
|
{
|
||||||
|
handlers.Sort((a, b) => a.Priority.CompareTo(b.Priority));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -13,7 +13,7 @@ public class MiraEventWrapper
|
|||||||
public Delegate EventHandler { get; }
|
public Delegate EventHandler { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the priority of the handler. Lower values are called first.
|
/// Gets the priority of the handler. Higher values are called first.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int Priority { get; }
|
public int Priority { get; }
|
||||||
|
|
||||||
|
|||||||
@@ -9,14 +9,14 @@ namespace MiraAPI.Events;
|
|||||||
public class RegisterEventAttribute : Attribute
|
public class RegisterEventAttribute : Attribute
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the priority of the event. Lower values are called first.
|
/// Gets the priority of the event.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int Priority { get; }
|
public int Priority { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="RegisterEventAttribute"/> class.
|
/// Initializes a new instance of the <see cref="RegisterEventAttribute"/> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="priority">The priority of the event. Lower values are called first.</param>
|
/// <param name="priority">The priority of the event.</param>
|
||||||
public RegisterEventAttribute(int priority = 0)
|
public RegisterEventAttribute(int priority = 0)
|
||||||
{
|
{
|
||||||
Priority = priority;
|
Priority = priority;
|
||||||
|
|||||||
@@ -1,12 +0,0 @@
|
|||||||
namespace MiraAPI.Events.Vanilla.Gameplay;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The event that is invoked when the intro cutscene has finished playing.
|
|
||||||
/// </summary>
|
|
||||||
public class IntroEndEvent(IntroCutscene introCutscene) : MiraEvent
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the instance of the IntroCutscene.
|
|
||||||
/// </summary>
|
|
||||||
public IntroCutscene IntroCutscene { get; } = introCutscene;
|
|
||||||
}
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
namespace MiraAPI.Events.Vanilla.Gameplay;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Start Round event, invoked on IntroCutscene.OnDestroy and ExileController.WrapUp.
|
|
||||||
/// </summary>
|
|
||||||
public class RoundStartEvent : MiraEvent
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Gets a value indicating whether the event was triggered by the IntroCutscene or ExileController.
|
|
||||||
/// </summary>
|
|
||||||
public bool TriggeredByIntro { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Initializes a new instance of the <see cref="RoundStartEvent"/> class.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="triggeredByIntro">Whether the event was triggered by the intro or not.</param>
|
|
||||||
public RoundStartEvent(bool triggeredByIntro)
|
|
||||||
{
|
|
||||||
TriggeredByIntro = triggeredByIntro;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
namespace MiraAPI.Events.Vanilla.Meeting;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The event that is invoked when the meeting has ended.
|
|
||||||
/// </summary>
|
|
||||||
public class EndMeetingEvent(MeetingHud meetingHud) : MiraEvent
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the MeetingHud instance.
|
|
||||||
/// </summary>
|
|
||||||
public MeetingHud MeetingHud { get; } = meetingHud;
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
namespace MiraAPI.Events.Vanilla.Meeting.Voting;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The event that is invoked when the voting phase of a meeting is complete.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="meetingHud">The MeetingHud instance.</param>
|
|
||||||
public class VotingCompleteEvent(MeetingHud meetingHud) : MiraEvent
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the MeetingHud instance.
|
|
||||||
/// </summary>
|
|
||||||
public MeetingHud MeetingHud { get; } = meetingHud;
|
|
||||||
}
|
|
||||||
@@ -417,12 +417,9 @@ public abstract class CustomActionButton
|
|||||||
/// <param name="playerControl">The local PlayerControl.</param>
|
/// <param name="playerControl">The local PlayerControl.</param>
|
||||||
public virtual void FixedUpdateHandler(PlayerControl playerControl)
|
public virtual void FixedUpdateHandler(PlayerControl playerControl)
|
||||||
{
|
{
|
||||||
if (Timer >= 0)
|
if (Timer >= 0 && !TimerPaused)
|
||||||
{
|
{
|
||||||
if (!TimerPaused)
|
Timer -= Time.deltaTime;
|
||||||
{
|
|
||||||
Timer -= Time.deltaTime;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (HasEffect && EffectActive)
|
else if (HasEffect && EffectActive)
|
||||||
{
|
{
|
||||||
@@ -431,28 +428,25 @@ public abstract class CustomActionButton
|
|||||||
OnEffectEnd();
|
OnEffectEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Button)
|
if (CanUse())
|
||||||
{
|
{
|
||||||
if (CanUse())
|
Button?.SetEnabled();
|
||||||
{
|
}
|
||||||
Button.SetEnabled();
|
else
|
||||||
}
|
{
|
||||||
else
|
Button?.SetDisabled();
|
||||||
{
|
}
|
||||||
Button.SetDisabled();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (EffectActive)
|
if (EffectActive)
|
||||||
{
|
{
|
||||||
Button.SetFillUp(Timer, EffectDuration);
|
Button?.SetFillUp(Timer, EffectDuration);
|
||||||
|
|
||||||
Button.cooldownTimerText.text = Mathf.CeilToInt(Timer).ToString(NumberFormatInfo.InvariantInfo);
|
Button!.cooldownTimerText.text = Mathf.CeilToInt(Timer).ToString(NumberFormatInfo.InvariantInfo);
|
||||||
Button.cooldownTimerText.gameObject.SetActive(true);
|
Button!.cooldownTimerText.gameObject.SetActive(true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Button.SetCoolDown(Timer, Cooldown);
|
Button?.SetCoolDown(Timer, Cooldown);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FixedUpdate(playerControl);
|
FixedUpdate(playerControl);
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics.CodeAnalysis;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using AmongUs.GameOptions;
|
using AmongUs.GameOptions;
|
||||||
using Il2CppInterop.Runtime.Attributes;
|
using Il2CppInterop.Runtime.Attributes;
|
||||||
@@ -9,8 +8,6 @@ using Reactor.Utilities.Attributes;
|
|||||||
using Reactor.Utilities.Extensions;
|
using Reactor.Utilities.Extensions;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.Events;
|
using UnityEngine.Events;
|
||||||
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
|
|
||||||
#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring as nullable.
|
|
||||||
|
|
||||||
namespace MiraAPI.Hud;
|
namespace MiraAPI.Hud;
|
||||||
|
|
||||||
@@ -19,18 +16,22 @@ namespace MiraAPI.Hud;
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="il2CppPtr">Used by Il2Cpp. Do not use constructor, this is a MonoBehaviour.</param>
|
/// <param name="il2CppPtr">Used by Il2Cpp. Do not use constructor, this is a MonoBehaviour.</param>
|
||||||
[RegisterInIl2Cpp]
|
[RegisterInIl2Cpp]
|
||||||
[SuppressMessage("Design", "CA1051:Do not declare visible instance fields", Justification = "Unity Convention")]
|
|
||||||
[SuppressMessage("StyleCop.CSharp.NamingRules", "SA1307:Accessible fields should begin with upper-case letter", Justification = "Unity Convention")]
|
|
||||||
[SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1401:Fields should be private", Justification = "Unity Convention")]
|
|
||||||
public class CustomPlayerMenu(IntPtr il2CppPtr) : Minigame(il2CppPtr)
|
public class CustomPlayerMenu(IntPtr il2CppPtr) : Minigame(il2CppPtr)
|
||||||
{
|
{
|
||||||
public ShapeshifterPanel panelPrefab;
|
public ShapeshifterPanel PanelPrefab;
|
||||||
public float xStart = -0.8f;
|
|
||||||
public float yStart = 2.15f;
|
public float XStart = -0.8f;
|
||||||
public float xOffset = 1.95f;
|
|
||||||
public float yOffset = -0.65f;
|
public float YStart = 2.15f;
|
||||||
public UiElement backButton;
|
|
||||||
public UiElement defaultButtonSelected;
|
public float XOffset = 1.95f;
|
||||||
|
|
||||||
|
public float YOffset = -0.65f;
|
||||||
|
|
||||||
|
public UiElement BackButton;
|
||||||
|
|
||||||
|
public UiElement DefaultButtonSelected;
|
||||||
|
|
||||||
public List<ShapeshifterPanel> potentialVictims;
|
public List<ShapeshifterPanel> potentialVictims;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -41,17 +42,17 @@ public class CustomPlayerMenu(IntPtr il2CppPtr) : Minigame(il2CppPtr)
|
|||||||
{
|
{
|
||||||
var shapeShifterRole = RoleManager.Instance.GetRole(RoleTypes.Shapeshifter);
|
var shapeShifterRole = RoleManager.Instance.GetRole(RoleTypes.Shapeshifter);
|
||||||
|
|
||||||
var ogMenu = shapeShifterRole.TryCast<ShapeshifterRole>()!.ShapeshifterMenu;
|
var ogMenu = shapeShifterRole.TryCast<ShapeshifterRole>().ShapeshifterMenu;
|
||||||
var newMenu = Instantiate(ogMenu);
|
var newMenu = Instantiate(ogMenu);
|
||||||
var customMenu = newMenu.gameObject.AddComponent<CustomPlayerMenu>();
|
var customMenu = newMenu.gameObject.AddComponent<CustomPlayerMenu>();
|
||||||
|
|
||||||
customMenu.panelPrefab = newMenu.PanelPrefab;
|
customMenu.PanelPrefab = newMenu.PanelPrefab;
|
||||||
customMenu.xStart = newMenu.XStart;
|
customMenu.XStart = newMenu.XStart;
|
||||||
customMenu.yStart = newMenu.YStart;
|
customMenu.YStart = newMenu.YStart;
|
||||||
customMenu.xOffset = newMenu.XOffset;
|
customMenu.XOffset = newMenu.XOffset;
|
||||||
customMenu.yOffset = newMenu.YOffset;
|
customMenu.YOffset = newMenu.YOffset;
|
||||||
customMenu.backButton = newMenu.BackButton;
|
customMenu.BackButton = newMenu.BackButton;
|
||||||
var back = customMenu.backButton.GetComponent<PassiveButton>();
|
var back = customMenu.BackButton.GetComponent<PassiveButton>();
|
||||||
back.OnClick.RemoveAllListeners();
|
back.OnClick.RemoveAllListeners();
|
||||||
back.OnClick.AddListener((UnityAction)(() =>
|
back.OnClick.AddListener((UnityAction)(() =>
|
||||||
{
|
{
|
||||||
@@ -64,7 +65,7 @@ public class CustomPlayerMenu(IntPtr il2CppPtr) : Minigame(il2CppPtr)
|
|||||||
|
|
||||||
newMenu.DestroyImmediate();
|
newMenu.DestroyImmediate();
|
||||||
|
|
||||||
customMenu.transform.SetParent(Camera.main!.transform, false);
|
customMenu.transform.SetParent(Camera.main.transform, false);
|
||||||
customMenu.transform.localPosition = new Vector3(0f, 0f, -50f);
|
customMenu.transform.localPosition = new Vector3(0f, 0f, -50f);
|
||||||
return customMenu;
|
return customMenu;
|
||||||
}
|
}
|
||||||
@@ -74,7 +75,6 @@ public class CustomPlayerMenu(IntPtr il2CppPtr) : Minigame(il2CppPtr)
|
|||||||
ControllerManager.Instance.CloseOverlayMenu(name);
|
ControllerManager.Instance.CloseOverlayMenu(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public override void Begin(PlayerTask task)
|
public override void Begin(PlayerTask task)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException("Use the other Begin method.");
|
throw new NotImplementedException("Use the other Begin method.");
|
||||||
@@ -90,7 +90,7 @@ public class CustomPlayerMenu(IntPtr il2CppPtr) : Minigame(il2CppPtr)
|
|||||||
{
|
{
|
||||||
MinigameStubs.Begin(this, null);
|
MinigameStubs.Begin(this, null);
|
||||||
|
|
||||||
var back = backButton.GetComponent<PassiveButton>();
|
var back = BackButton.GetComponent<PassiveButton>();
|
||||||
back.OnClick.AddListener((UnityAction)(() =>
|
back.OnClick.AddListener((UnityAction)(() =>
|
||||||
{
|
{
|
||||||
onClick(null);
|
onClick(null);
|
||||||
@@ -107,13 +107,13 @@ public class CustomPlayerMenu(IntPtr il2CppPtr) : Minigame(il2CppPtr)
|
|||||||
var num = i % 3;
|
var num = i % 3;
|
||||||
var num2 = i / 3;
|
var num2 = i / 3;
|
||||||
var flag = PlayerControl.LocalPlayer.Data.Role.NameColor == player.Data.Role.NameColor;
|
var flag = PlayerControl.LocalPlayer.Data.Role.NameColor == player.Data.Role.NameColor;
|
||||||
var shapeshifterPanel = Instantiate(panelPrefab, transform);
|
var shapeshifterPanel = Instantiate(PanelPrefab, transform);
|
||||||
shapeshifterPanel.transform.localPosition = new Vector3(xStart + num * xOffset, yStart + num2 * yOffset, -1f);
|
shapeshifterPanel.transform.localPosition = new Vector3(XStart + num * XOffset, YStart + num2 * YOffset, -1f);
|
||||||
shapeshifterPanel.SetPlayer(i, player.Data, (Il2CppSystem.Action)(() => { onClick(player); }));
|
shapeshifterPanel.SetPlayer(i, player.Data, (Il2CppSystem.Action)(() => { onClick(player); }));
|
||||||
shapeshifterPanel.NameText.color = flag ? player.Data.Role.NameColor : Color.white;
|
shapeshifterPanel.NameText.color = flag ? player.Data.Role.NameColor : Color.white;
|
||||||
potentialVictims.Add(shapeshifterPanel);
|
potentialVictims.Add(shapeshifterPanel);
|
||||||
list2.Add(shapeshifterPanel.Button);
|
list2.Add(shapeshifterPanel.Button);
|
||||||
}
|
}
|
||||||
ControllerManager.Instance.OpenOverlayMenu(name, backButton, defaultButtonSelected, list2);
|
ControllerManager.Instance.OpenOverlayMenu(name, BackButton, DefaultButtonSelected, list2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,12 +1,19 @@
|
|||||||
using BepInEx;
|
using System;
|
||||||
|
using BepInEx;
|
||||||
using BepInEx.Unity.IL2CPP;
|
using BepInEx.Unity.IL2CPP;
|
||||||
using HarmonyLib;
|
using HarmonyLib;
|
||||||
|
using Il2CppInterop.Runtime;
|
||||||
using MiraAPI.PluginLoading;
|
using MiraAPI.PluginLoading;
|
||||||
|
using MiraAPI.Roles;
|
||||||
|
using MonoMod.Utils;
|
||||||
using Reactor;
|
using Reactor;
|
||||||
using Reactor.Networking;
|
using Reactor.Networking;
|
||||||
using Reactor.Networking.Attributes;
|
using Reactor.Networking.Attributes;
|
||||||
using Reactor.Utilities;
|
using Reactor.Utilities;
|
||||||
|
using TMPro;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
using UnityEngine.ProBuilder;
|
||||||
|
using Delegate = Il2CppSystem.Delegate;
|
||||||
|
|
||||||
namespace MiraAPI;
|
namespace MiraAPI;
|
||||||
|
|
||||||
@@ -16,20 +23,11 @@ namespace MiraAPI;
|
|||||||
[BepInAutoPlugin("mira.api", "MiraAPI")]
|
[BepInAutoPlugin("mira.api", "MiraAPI")]
|
||||||
[BepInProcess("Among Us.exe")]
|
[BepInProcess("Among Us.exe")]
|
||||||
[BepInDependency(ReactorPlugin.Id)]
|
[BepInDependency(ReactorPlugin.Id)]
|
||||||
[BepInDependency(ModCompatibility.SubmergedId, BepInDependency.DependencyFlags.SoftDependency)]
|
|
||||||
[ReactorModFlags(ModFlags.RequireOnAllClients)]
|
[ReactorModFlags(ModFlags.RequireOnAllClients)]
|
||||||
public partial class MiraApiPlugin : BasePlugin
|
public partial class MiraApiPlugin : BasePlugin
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// Gets the branding Mira API color.
|
|
||||||
/// </summary>
|
|
||||||
public static Color MiraColor { get; } = new Color32(238, 154, 112, 255);
|
public static Color MiraColor { get; } = new Color32(238, 154, 112, 255);
|
||||||
|
public static Color DefaultHeaderColor = new Color32(77, 77, 77, 255);
|
||||||
/// <summary>
|
|
||||||
/// Gets the default color for headers in the options menu.
|
|
||||||
/// </summary>
|
|
||||||
public static Color DefaultHeaderColor { get; } = new Color32(77, 77, 77, 255);
|
|
||||||
|
|
||||||
private static MiraPluginManager? PluginManager { get; set; }
|
private static MiraPluginManager? PluginManager { get; set; }
|
||||||
internal Harmony Harmony { get; } = new(Id);
|
internal Harmony Harmony { get; } = new(Id);
|
||||||
|
|
||||||
|
|||||||
@@ -1,28 +0,0 @@
|
|||||||
using System.Diagnostics.CodeAnalysis;
|
|
||||||
using System.Reflection;
|
|
||||||
using BepInEx.Unity.IL2CPP;
|
|
||||||
|
|
||||||
namespace MiraAPI;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Mod compatibility tools.
|
|
||||||
/// </summary>
|
|
||||||
public static class ModCompatibility
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// The ID for the Submerged mod.
|
|
||||||
/// </summary>
|
|
||||||
public const string SubmergedId = "Submerged";
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Checks if the Submerged mod is loaded.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="submergedAssembly">Submerged mod assembly if loaded, null otherwise.</param>
|
|
||||||
/// <returns>True if the Submerged mod is loaded, false otherwise.</returns>
|
|
||||||
public static bool SubmergedLoaded([NotNullWhen(true)] out Assembly? submergedAssembly)
|
|
||||||
{
|
|
||||||
var result = IL2CPPChainloader.Instance.Plugins.TryGetValue(SubmergedId, out var plugin);
|
|
||||||
submergedAssembly = result ? plugin?.Instance.GetType().Assembly : null;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -104,13 +104,6 @@ public abstract class BaseModifier : IOptionable
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Called when a meeting starts.
|
|
||||||
/// </summary>
|
|
||||||
public virtual void OnMeetingStart()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Determines whether the player can vent.
|
/// Determines whether the player can vent.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -29,9 +29,9 @@ public class ModifierComponent(IntPtr cppPtr) : MonoBehaviour(cppPtr)
|
|||||||
[HideFromIl2Cpp]
|
[HideFromIl2Cpp]
|
||||||
private List<BaseModifier> Modifiers { get; set; } = [];
|
private List<BaseModifier> Modifiers { get; set; } = [];
|
||||||
|
|
||||||
private PlayerControl _player = null!;
|
private PlayerControl? _player;
|
||||||
|
|
||||||
private TextMeshPro _modifierText = null!;
|
private TextMeshPro? _modifierText;
|
||||||
|
|
||||||
private readonly List<BaseModifier> _toRemove = [];
|
private readonly List<BaseModifier> _toRemove = [];
|
||||||
|
|
||||||
@@ -42,18 +42,9 @@ public class ModifierComponent(IntPtr cppPtr) : MonoBehaviour(cppPtr)
|
|||||||
_toRemove.AddRange(Modifiers);
|
_toRemove.AddRange(Modifiers);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Awake()
|
private void Start()
|
||||||
{
|
{
|
||||||
_player = GetComponent<PlayerControl>();
|
_player = GetComponent<PlayerControl>();
|
||||||
if (_player == null)
|
|
||||||
{
|
|
||||||
Logger<MiraApiPlugin>.Error("ModifierComponent could not find PlayerControl on the same GameObject.");
|
|
||||||
Destroy(this);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ModifierExtensions.ModifierComponents.Add(_player, this);
|
|
||||||
|
|
||||||
Modifiers = [];
|
Modifiers = [];
|
||||||
|
|
||||||
if (!_player.AmOwner)
|
if (!_player.AmOwner)
|
||||||
@@ -67,18 +58,14 @@ public class ModifierComponent(IntPtr cppPtr) : MonoBehaviour(cppPtr)
|
|||||||
|
|
||||||
private void FixedUpdate()
|
private void FixedUpdate()
|
||||||
{
|
{
|
||||||
var removed = _toRemove.Count > 0;
|
|
||||||
foreach (var modifier in _toRemove.ToArray())
|
foreach (var modifier in _toRemove.ToArray())
|
||||||
{
|
{
|
||||||
_toRemove.Remove(modifier);
|
|
||||||
modifier.OnDeactivate();
|
modifier.OnDeactivate();
|
||||||
Modifiers.Remove(modifier);
|
Modifiers.Remove(modifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
var added = _toAdd.Count > 0;
|
|
||||||
foreach (var modifier in _toAdd.ToArray())
|
foreach (var modifier in _toAdd.ToArray())
|
||||||
{
|
{
|
||||||
_toAdd.Remove(modifier);
|
|
||||||
Modifiers.Add(modifier);
|
Modifiers.Add(modifier);
|
||||||
modifier.Initialized = true;
|
modifier.Initialized = true;
|
||||||
modifier.OnActivate();
|
modifier.OnActivate();
|
||||||
@@ -89,12 +76,14 @@ public class ModifierComponent(IntPtr cppPtr) : MonoBehaviour(cppPtr)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (removed || added)
|
if (_toAdd.Count > 0 || _toRemove.Count > 0)
|
||||||
{
|
{
|
||||||
if (_player.AmOwner && HudManager.InstanceExists)
|
if (_player?.AmOwner == true)
|
||||||
{
|
{
|
||||||
HudManager.Instance.SetHudActive(_player, _player.Data.Role, HudManager.Instance.TaskPanel.isActiveAndEnabled);
|
HudManager.Instance?.SetHudActive(_player, _player.Data.Role, HudManager.Instance.TaskPanel.isActiveAndEnabled);
|
||||||
}
|
}
|
||||||
|
_toAdd.Clear();
|
||||||
|
_toRemove.Clear();
|
||||||
|
|
||||||
ActiveModifiers = Modifiers.ToImmutableList();
|
ActiveModifiers = Modifiers.ToImmutableList();
|
||||||
}
|
}
|
||||||
@@ -112,7 +101,7 @@ public class ModifierComponent(IntPtr cppPtr) : MonoBehaviour(cppPtr)
|
|||||||
modifier.Update();
|
modifier.Update();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_modifierText || !_player.AmOwner)
|
if (!_modifierText || _player?.AmOwner == false)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -136,13 +125,7 @@ public class ModifierComponent(IntPtr cppPtr) : MonoBehaviour(cppPtr)
|
|||||||
builder.AppendLine(modifier.GetHudString());
|
builder.AppendLine(modifier.GetHudString());
|
||||||
}
|
}
|
||||||
|
|
||||||
_modifierText.text = showText ? builder.ToString() : string.Empty;
|
_modifierText!.text = showText ? builder.ToString() : string.Empty;
|
||||||
}
|
|
||||||
|
|
||||||
private void OnDestroy()
|
|
||||||
{
|
|
||||||
// Remove this component from the global list when destroyed
|
|
||||||
ModifierExtensions.ModifierComponents.Remove(_player);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -509,61 +492,4 @@ public class ModifierComponent(IntPtr cppPtr) : MonoBehaviour(cppPtr)
|
|||||||
{
|
{
|
||||||
return ActiveModifiers.Exists(x => x.UniqueId == id);
|
return ActiveModifiers.Exists(x => x.UniqueId == id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Checks if a player has an active modifier by its type.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="checkInactive">Whether to check inactive modifiers (those pending to be added).</param>
|
|
||||||
/// <param name="predicate">The predicate to check the modifier.</param>
|
|
||||||
/// <typeparam name="T">The Type of the Modifier.</typeparam>
|
|
||||||
/// <returns>True if the Modifier is present, false otherwise.</returns>
|
|
||||||
[HideFromIl2Cpp]
|
|
||||||
public bool HasModifier<T>(bool checkInactive, Func<T, bool>? predicate=null) where T : BaseModifier
|
|
||||||
{
|
|
||||||
return ActiveModifiers.Exists(MatchExpr) || (checkInactive && _toAdd.Exists(MatchExpr));
|
|
||||||
bool MatchExpr(BaseModifier bm) => bm is T modifier && (predicate == null || predicate(modifier));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Checks if a player has an active modifier by its type.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="type">The modifier type.</param>
|
|
||||||
/// <param name="checkInactive">Whether to check inactive modifiers (those pending to be added).</param>
|
|
||||||
/// <param name="predicate">The predicate to check the modifier.</param>
|
|
||||||
/// <returns>True if the Modifier is present, false otherwise.</returns>
|
|
||||||
[HideFromIl2Cpp]
|
|
||||||
public bool HasModifier(Type type, bool checkInactive, Func<BaseModifier, bool>? predicate=null)
|
|
||||||
{
|
|
||||||
return ActiveModifiers.Exists(MatchExpr) || (checkInactive && _toAdd.Exists(MatchExpr));
|
|
||||||
bool MatchExpr(BaseModifier bm) => bm.GetType() == type && (predicate == null || predicate(bm));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Checks if a player has an active modifier by its type ID.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="id">The modifier's type ID.</param>
|
|
||||||
/// <param name="checkInactive">Whether to check inactive modifiers (those pending to be added).</param>
|
|
||||||
/// <param name="predicate">The predicate to check the modifier.</param>
|
|
||||||
/// <returns>True if the modifier is present, false otherwise.</returns>
|
|
||||||
[HideFromIl2Cpp]
|
|
||||||
public bool HasModifier(uint id, bool checkInactive, Func<BaseModifier, bool>? predicate=null)
|
|
||||||
{
|
|
||||||
var type = ModifierManager.GetModifierType(id) ?? throw new InvalidOperationException(
|
|
||||||
$"Cannot get modifier with id {id} because it is not registered.");
|
|
||||||
|
|
||||||
return HasModifier(type, checkInactive, predicate);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Checks if a player has an active modifier by its unique ID.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="id">The modifier's guid.</param>
|
|
||||||
/// <param name="checkInactive">Whether to check inactive modifiers (those pending to be added).</param>
|
|
||||||
/// <returns>True if the modifier is present, false otherwise.</returns>
|
|
||||||
[HideFromIl2Cpp]
|
|
||||||
public bool HasModifier(Guid id, bool checkInactive)
|
|
||||||
{
|
|
||||||
return ActiveModifiers.Exists(MatchExpr) || (checkInactive && _toAdd.Exists(MatchExpr));
|
|
||||||
bool MatchExpr(BaseModifier bm) => bm.UniqueId == id;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -180,17 +180,6 @@ public static class ModifierExtensions
|
|||||||
return player.GetModifierComponent().HasModifier(typeId, predicate);
|
return player.GetModifierComponent().HasModifier(typeId, predicate);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Checks if the player has a specific modifier by its GUID.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="player">The PlayerControl instance.</param>
|
|
||||||
/// <param name="uniqueId">The unique ID of the modifier.</param>
|
|
||||||
/// <returns>True if the player has the modifier, false otherwise.</returns>
|
|
||||||
public static bool HasModifier(this PlayerControl player, Guid uniqueId)
|
|
||||||
{
|
|
||||||
return player.GetModifierComponent().HasModifier(uniqueId);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Clears all modifiers from a player.
|
/// Clears all modifiers from a player.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -215,6 +204,17 @@ public static class ModifierExtensions
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Checks if the player has a specific modifier by its GUID.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="player">The PlayerControl instance.</param>
|
||||||
|
/// <param name="uniqueId">The unique ID of the modifier.</param>
|
||||||
|
/// <returns>True if the player has the modifier, false otherwise.</returns>
|
||||||
|
public static bool HasModifier(this PlayerControl player, Guid uniqueId)
|
||||||
|
{
|
||||||
|
return player.GetModifierComponent().HasModifier(uniqueId);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Tries to get a modifier by its type.
|
/// Tries to get a modifier by its type.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -103,57 +103,68 @@ public static class ModifierManager
|
|||||||
{
|
{
|
||||||
var rand = new Random();
|
var rand = new Random();
|
||||||
|
|
||||||
// Filter and sort modifiers by descending priority.
|
foreach (var priority in PrioritiesToIdsMap.Keys.OrderByDescending(x => x))
|
||||||
var modifiers = IdToTypeModifierMap
|
|
||||||
.Where(x=>x.Value.IsAssignableTo(typeof(GameModifier)))
|
|
||||||
.Select(x => Activator.CreateInstance(x.Value) as GameModifier)
|
|
||||||
.OfType<GameModifier>()
|
|
||||||
.Where(x => x.GetAmountPerGame() > 0 && x.GetAssignmentChance() > 0)
|
|
||||||
.OrderByDescending(x => x.Priority())
|
|
||||||
.ToArray();
|
|
||||||
|
|
||||||
foreach (var modifier in modifiers)
|
|
||||||
{
|
{
|
||||||
var assignments = modifier.GetAmountPerGame();
|
var filteredModifiers = new List<uint>();
|
||||||
|
|
||||||
var validPlayers = plrs.Where(x => IsGameModifierValid(x, modifier, modifier.TypeId)).ToList();
|
foreach (var id in PrioritiesToIdsMap[priority])
|
||||||
if (validPlayers.Count == 0)
|
|
||||||
{
|
{
|
||||||
Logger<MiraApiPlugin>.Warning($"No valid players for modifier {modifier.ModifierName}");
|
var mod = Activator.CreateInstance(IdToTypeModifierMap[id]) as GameModifier;
|
||||||
|
var chance = Math.Clamp(mod!.GetAssignmentChance(), 0, 100);
|
||||||
|
var count = mod.GetAmountPerGame();
|
||||||
|
|
||||||
|
if (chance == 0 || count == 0)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var maxCount = plrs.Count(x => IsGameModifierValid(x, mod, id));
|
||||||
|
|
||||||
|
if (maxCount == 0)
|
||||||
|
{
|
||||||
|
Logger<MiraApiPlugin>.Warning($"No players are valid for {mod.ModifierName}");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var num = Math.Clamp(count, 0, maxCount);
|
||||||
|
|
||||||
|
for (var i = 0; i < num; i++)
|
||||||
|
{
|
||||||
|
var randomNum = rand.Next(100);
|
||||||
|
|
||||||
|
if (randomNum < chance)
|
||||||
|
{
|
||||||
|
filteredModifiers.Add(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filteredModifiers.Count == 0)
|
||||||
|
{
|
||||||
|
Logger<MiraApiPlugin>.Warning($"No filtered modifiers for priority {priority}");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
assignments = Math.Min(assignments, validPlayers.Count);
|
var shuffledList = filteredModifiers.Randomize();
|
||||||
var availablePlayers = new List<PlayerControl>(validPlayers);
|
|
||||||
|
|
||||||
for (var i = 0; i < assignments; i++)
|
if (shuffledList.Count > plrs.Count)
|
||||||
{
|
{
|
||||||
var chance = Math.Clamp(modifier.GetAssignmentChance(), 0, 100);
|
shuffledList = shuffledList.GetRange(0, plrs.Count);
|
||||||
if (rand.Next(100) >= chance)
|
}
|
||||||
|
|
||||||
|
foreach (var id in shuffledList)
|
||||||
|
{
|
||||||
|
var mod = Activator.CreateInstance(IdToTypeModifierMap[id]) as GameModifier;
|
||||||
|
var plr = plrs.Where(x => IsGameModifierValid(x, mod!, id)).Random();
|
||||||
|
|
||||||
|
if (!plr || plr == null)
|
||||||
{
|
{
|
||||||
continue;
|
Logger<MiraApiPlugin>.Warning($"Somehow valid players for modifier {mod!.ModifierName} disappeared");
|
||||||
}
|
}
|
||||||
|
else
|
||||||
var candidates = availablePlayers
|
|
||||||
.Where(x => IsGameModifierValid(x, modifier, modifier.TypeId))
|
|
||||||
.ToList();
|
|
||||||
|
|
||||||
if (candidates.Count == 0)
|
|
||||||
{
|
{
|
||||||
Logger<MiraApiPlugin>.Warning(
|
plr.RpcAddModifier(id);
|
||||||
$"No available players for modifier {modifier.ModifierName} at assignment {i + 1}");
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var plr = candidates.Random();
|
|
||||||
if (plr == null)
|
|
||||||
{
|
|
||||||
Logger<MiraApiPlugin>.Warning($"Valid player for modifier {modifier.ModifierName} disappeared");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
plr.RpcAddModifier(modifier.TypeId);
|
|
||||||
availablePlayers.Remove(plr);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using AmongUs.Data;
|
|
||||||
using AmongUs.GameOptions;
|
using AmongUs.GameOptions;
|
||||||
using Assets.CoreScripts;
|
using Assets.CoreScripts;
|
||||||
using BepInEx.Unity.IL2CPP.Utils;
|
using BepInEx.Unity.IL2CPP.Utils;
|
||||||
@@ -97,7 +96,7 @@ public static class CustomMurderRpc
|
|||||||
var flag = PlayerControl.LocalPlayer.Data.Role.Role == RoleTypes.GuardianAngel;
|
var flag = PlayerControl.LocalPlayer.Data.Role.Role == RoleTypes.GuardianAngel;
|
||||||
if (flag && PlayerControl.LocalPlayer.Data.PlayerId == target.protectedByGuardianId)
|
if (flag && PlayerControl.LocalPlayer.Data.PlayerId == target.protectedByGuardianId)
|
||||||
{
|
{
|
||||||
DataManager.Player.Stats.IncrementStat(StatID.Role_GuardianAngel_CrewmatesProtected);
|
StatsManager.Instance.IncrementStat(StringNames.StatsGuardianAngelCrewmatesProtected);
|
||||||
AchievementManager.Instance.OnProtectACrewmate();
|
AchievementManager.Instance.OnProtectACrewmate();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -128,14 +127,14 @@ public static class CustomMurderRpc
|
|||||||
DebugAnalytics.Instance.Analytics.Kill(target.Data, source.Data);
|
DebugAnalytics.Instance.Analytics.Kill(target.Data, source.Data);
|
||||||
if (source.AmOwner)
|
if (source.AmOwner)
|
||||||
{
|
{
|
||||||
DataManager.Player.Stats.IncrementStat(
|
StatsManager.Instance.IncrementStat(
|
||||||
GameManager.Instance.IsHideAndSeek()
|
GameManager.Instance.IsHideAndSeek()
|
||||||
? StatID.HideAndSeek_ImpostorKills
|
? StringNames.StatsImpostorKills_HideAndSeek
|
||||||
: StatID.ImpostorKills);
|
: StringNames.StatsImpostorKills);
|
||||||
|
|
||||||
if (source.CurrentOutfitType == PlayerOutfitType.Shapeshifted)
|
if (source.CurrentOutfitType == PlayerOutfitType.Shapeshifted)
|
||||||
{
|
{
|
||||||
DataManager.Player.Stats.IncrementStat(StatID.Role_Shapeshifter_ShiftedKills);
|
StatsManager.Instance.IncrementStat(StringNames.StatsShapeshifterShiftedKills);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Constants.ShouldPlaySfx() && playKillSound)
|
if (Constants.ShouldPlaySfx() && playKillSound)
|
||||||
@@ -153,7 +152,7 @@ public static class CustomMurderRpc
|
|||||||
target.gameObject.layer = LayerMask.NameToLayer("Ghost");
|
target.gameObject.layer = LayerMask.NameToLayer("Ghost");
|
||||||
if (target.AmOwner)
|
if (target.AmOwner)
|
||||||
{
|
{
|
||||||
DataManager.Player.Stats.IncrementStat(StatID.TimesMurdered);
|
StatsManager.Instance.IncrementStat(StringNames.StatsTimesMurdered);
|
||||||
if (Minigame.Instance)
|
if (Minigame.Instance)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
|||||||
@@ -1,15 +0,0 @@
|
|||||||
using HarmonyLib;
|
|
||||||
using MiraAPI.Events;
|
|
||||||
using MiraAPI.Events.Vanilla.Gameplay;
|
|
||||||
|
|
||||||
namespace MiraAPI.Patches.Events;
|
|
||||||
|
|
||||||
[HarmonyPatch(typeof(SpawnInMinigame), nameof(SpawnInMinigame.Close))]
|
|
||||||
internal static class SpawnInMinigamePatch
|
|
||||||
{
|
|
||||||
public static void Postfix()
|
|
||||||
{
|
|
||||||
var @event = new RoundStartEvent(false);
|
|
||||||
MiraEventManager.InvokeEvent(@event);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using System.Reflection;
|
|
||||||
using HarmonyLib;
|
|
||||||
using MiraAPI.Events;
|
|
||||||
using MiraAPI.Events.Vanilla.Gameplay;
|
|
||||||
|
|
||||||
namespace MiraAPI.Patches.Events;
|
|
||||||
|
|
||||||
[HarmonyPatch]
|
|
||||||
internal static class SubmergedSpawnGamePatch
|
|
||||||
{
|
|
||||||
public static bool Prepare()
|
|
||||||
{
|
|
||||||
return ModCompatibility.SubmergedLoaded(out _);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static IEnumerable<MethodBase> TargetMethods()
|
|
||||||
{
|
|
||||||
if (ModCompatibility.SubmergedLoaded(out var subAss) &&
|
|
||||||
subAss.GetType("Submerged.SpawnIn.SubmarineSelectSpawn") is { } selectSpawn)
|
|
||||||
{
|
|
||||||
yield return AccessTools.Method(selectSpawn, "OnDestroy");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void Postfix()
|
|
||||||
{
|
|
||||||
var @event = new RoundStartEvent(false);
|
|
||||||
MiraEventManager.InvokeEvent(@event);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -18,7 +18,7 @@ namespace MiraAPI.Patches.Freeplay;
|
|||||||
[HarmonyPatch(typeof(TaskAdderGame))]
|
[HarmonyPatch(typeof(TaskAdderGame))]
|
||||||
internal static class TaskAdderPatches
|
internal static class TaskAdderPatches
|
||||||
{
|
{
|
||||||
private static Scroller _scroller = null!;
|
private static Scroller? _scroller;
|
||||||
|
|
||||||
[HarmonyPostfix]
|
[HarmonyPostfix]
|
||||||
[HarmonyPatch(nameof(TaskAdderGame.Begin))]
|
[HarmonyPatch(nameof(TaskAdderGame.Begin))]
|
||||||
@@ -293,9 +293,9 @@ internal static class TaskAdderPatches
|
|||||||
chip.GetComponent<SpriteRenderer>().maskInteraction = SpriteMaskInteraction.VisibleInsideMask;
|
chip.GetComponent<SpriteRenderer>().maskInteraction = SpriteMaskInteraction.VisibleInsideMask;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_scroller)
|
if (_scroller && _scroller != null)
|
||||||
{
|
{
|
||||||
_scroller.CalculateAndSetYBounds(__instance.ActiveItems.Count, 6, 5, 1.4f);
|
_scroller.CalculateAndSetYBounds(__instance.ActiveItems.Count, 6, 3, 1f);
|
||||||
_scroller.SetYBoundsMin(0.0f);
|
_scroller.SetYBoundsMin(0.0f);
|
||||||
_scroller.ScrollToTop();
|
_scroller.ScrollToTop();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
using HarmonyLib;
|
using HarmonyLib;
|
||||||
using MiraAPI.Hud;
|
using MiraAPI.Hud;
|
||||||
using Reactor.Utilities;
|
|
||||||
|
|
||||||
namespace MiraAPI.Patches.Hud;
|
namespace MiraAPI.Patches.Hud;
|
||||||
|
|
||||||
@@ -27,8 +26,7 @@ public static class ButtonResetPatches
|
|||||||
/// Resets the cooldown and effect of all custom buttons after the exile screen is closed.
|
/// Resets the cooldown and effect of all custom buttons after the exile screen is closed.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[HarmonyPostfix]
|
[HarmonyPostfix]
|
||||||
[HarmonyPatch(typeof(ExileController), nameof(ExileController.WrapUp))]
|
[HarmonyPatch(typeof(ExileController), nameof(ExileController.ReEnableGameplay))]
|
||||||
[HarmonyPatch(typeof(AirshipExileController), nameof(AirshipExileController.WrapUpAndSpawn))]
|
|
||||||
public static void ExileControllerReEnableGameplayPostfix()
|
public static void ExileControllerReEnableGameplayPostfix()
|
||||||
{
|
{
|
||||||
foreach (var customActionButton in CustomButtonManager.CustomButtons)
|
foreach (var customActionButton in CustomButtonManager.CustomButtons)
|
||||||
|
|||||||
@@ -56,16 +56,11 @@ public static class IntroCutscenePatches
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
[HarmonyPostfix]
|
[HarmonyPostfix]
|
||||||
[HarmonyPatch(typeof(IntroCutscene._CoBegin_d__34), nameof(IntroCutscene._CoBegin_d__34.MoveNext))]
|
[HarmonyPatch(nameof(IntroCutscene.OnDestroy))]
|
||||||
public static void GameBeginPatch(IntroCutscene._CoBegin_d__34 __instance)
|
public static void GameBeginPatch()
|
||||||
{
|
{
|
||||||
if (__instance.__1__state != -1)
|
CustomGameModeManager.ActiveMode?.Initialize();
|
||||||
{
|
}*/
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
MiraEventManager.InvokeEvent(new IntroEndEvent(__instance.__4__this));
|
|
||||||
MiraEventManager.InvokeEvent(new RoundStartEvent(true));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
using HarmonyLib;
|
|
||||||
|
|
||||||
namespace MiraAPI.Patches;
|
|
||||||
|
|
||||||
[HarmonyPatch(typeof(Minigame), nameof(Minigame.Begin))]
|
|
||||||
internal static class MinigameBeginErrorPatch
|
|
||||||
{
|
|
||||||
public static void Prefix(Minigame __instance)
|
|
||||||
{
|
|
||||||
__instance.logger ??= new Logger(Logger.Category.Gameplay, "Minigame");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -2,15 +2,13 @@
|
|||||||
using HarmonyLib;
|
using HarmonyLib;
|
||||||
using MiraAPI.Modifiers;
|
using MiraAPI.Modifiers;
|
||||||
using MiraAPI.Modifiers.Types;
|
using MiraAPI.Modifiers.Types;
|
||||||
using MiraAPI.Utilities;
|
|
||||||
using Reactor.Utilities;
|
|
||||||
|
|
||||||
namespace MiraAPI.Patches.Modifiers;
|
namespace MiraAPI.Patches.Modifiers;
|
||||||
|
|
||||||
[HarmonyPatch(typeof(AmongUsClient), nameof(AmongUsClient.OnGameEnd))]
|
[HarmonyPatch(typeof(AmongUsClient), nameof(AmongUsClient.CoEndGame))]
|
||||||
public static class EndGameDidWinPatch
|
public static class EndGameDidWinPatch
|
||||||
{
|
{
|
||||||
public static void Postfix()
|
public static void Prefix()
|
||||||
{
|
{
|
||||||
var gameOverReason = EndGameResult.CachedGameOverReason;
|
var gameOverReason = EndGameResult.CachedGameOverReason;
|
||||||
EndGameResult.CachedWinners.Clear();
|
EndGameResult.CachedWinners.Clear();
|
||||||
@@ -19,26 +17,18 @@ public static class EndGameDidWinPatch
|
|||||||
for (var i = 0; i < GameData.Instance.PlayerCount; i++)
|
for (var i = 0; i < GameData.Instance.PlayerCount; i++)
|
||||||
{
|
{
|
||||||
var networkedPlayerInfo = players[i];
|
var networkedPlayerInfo = players[i];
|
||||||
if (!networkedPlayerInfo)
|
if (networkedPlayerInfo == null)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
var didWin = networkedPlayerInfo.Role.DidWin(gameOverReason);
|
var didWin = networkedPlayerInfo.Role.DidWin(gameOverReason);
|
||||||
|
|
||||||
bool? modifierDidWin = null;
|
var modifierWin = networkedPlayerInfo.Object?.GetModifierComponent().GetModifiers<GameModifier>()
|
||||||
foreach (var modifier in networkedPlayerInfo.Object.GetModifiers<GameModifier>().OrderByDescending(x => x.Priority()))
|
.FirstOrDefault(x => x.DidWin(gameOverReason) != null)?.DidWin(gameOverReason);
|
||||||
|
if (modifierWin != null)
|
||||||
{
|
{
|
||||||
var result = modifier.DidWin(gameOverReason);
|
didWin = modifierWin.Value;
|
||||||
if (!result.HasValue) continue;
|
|
||||||
|
|
||||||
modifierDidWin = result.Value;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (modifierDidWin.HasValue)
|
|
||||||
{
|
|
||||||
didWin = modifierDidWin.Value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (didWin)
|
if (didWin)
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ using HarmonyLib;
|
|||||||
using MiraAPI.Modifiers;
|
using MiraAPI.Modifiers;
|
||||||
using MiraAPI.PluginLoading;
|
using MiraAPI.PluginLoading;
|
||||||
using MiraAPI.Utilities.Assets;
|
using MiraAPI.Utilities.Assets;
|
||||||
|
using Reactor.Utilities;
|
||||||
using Reactor.Utilities.Extensions;
|
using Reactor.Utilities.Extensions;
|
||||||
using TMPro;
|
using TMPro;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|||||||
@@ -260,7 +260,7 @@ public static class LobbyViewPanePatches
|
|||||||
|
|
||||||
foreach (var grouping in sortedRoleGroups)
|
foreach (var grouping in sortedRoleGroups)
|
||||||
{
|
{
|
||||||
if (!grouping.Any() || grouping.All(x => x.Configuration.HideSettings))
|
if (!grouping.Any())
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -335,7 +335,7 @@ public static class LobbyViewPanePatches
|
|||||||
viewSettingsInfoPanelRoleVariant.chanceTitle.color =
|
viewSettingsInfoPanelRoleVariant.chanceTitle.color =
|
||||||
viewSettingsInfoPanelRoleVariant.chanceBackground.color =
|
viewSettingsInfoPanelRoleVariant.chanceBackground.color =
|
||||||
viewSettingsInfoPanelRoleVariant.background.color =
|
viewSettingsInfoPanelRoleVariant.background.color =
|
||||||
customRole.RoleColor.FindAlternateColor();
|
customRole.RoleColor.GetAlternateColor();
|
||||||
instance.settingsInfo.Add(viewSettingsInfoPanelRoleVariant.gameObject);
|
instance.settingsInfo.Add(viewSettingsInfoPanelRoleVariant.gameObject);
|
||||||
num -= 0.664f;
|
num -= 0.664f;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -83,9 +83,10 @@ public static class RoleSettingMenuPatches
|
|||||||
var quotaThing = __instance.categoryHeaderEditRoleOrigin.transform.FindChild("QuotaHeader");
|
var quotaThing = __instance.categoryHeaderEditRoleOrigin.transform.FindChild("QuotaHeader");
|
||||||
var template = __instance.transform.parent.parent.GetComponent<GameSettingMenu>().GameSettingsTab.categoryHeaderOrigin;
|
var template = __instance.transform.parent.parent.GetComponent<GameSettingMenu>().GameSettingsTab.categoryHeaderOrigin;
|
||||||
|
|
||||||
|
|
||||||
foreach (var grouping in sortedRoleGroups)
|
foreach (var grouping in sortedRoleGroups)
|
||||||
{
|
{
|
||||||
if (!grouping.Any() || grouping.All(x=>x.Configuration.HideSettings))
|
if (!grouping.Any())
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,11 +15,14 @@ namespace MiraAPI.Patches;
|
|||||||
/// General patches for the PlayerControl class.
|
/// General patches for the PlayerControl class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[HarmonyPatch(typeof(PlayerControl))]
|
[HarmonyPatch(typeof(PlayerControl))]
|
||||||
internal static class PlayerControlPatches
|
public static class PlayerControlPatches
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Adds the modifier component to the player on start.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="__instance">PlayerControl instance.</param>
|
||||||
[HarmonyPostfix]
|
[HarmonyPostfix]
|
||||||
[HarmonyPatch(nameof(PlayerControl.Start))]
|
[HarmonyPatch(nameof(PlayerControl.Start))]
|
||||||
// ReSharper disable once InconsistentNaming
|
|
||||||
public static void PlayerControlStartPostfix(PlayerControl __instance)
|
public static void PlayerControlStartPostfix(PlayerControl __instance)
|
||||||
{
|
{
|
||||||
if (__instance.gameObject.TryGetComponent<ModifierComponent>(out var modifierComp))
|
if (__instance.gameObject.TryGetComponent<ModifierComponent>(out var modifierComp))
|
||||||
@@ -36,9 +39,12 @@ internal static class PlayerControlPatches
|
|||||||
__instance.gameObject.AddComponent<PlayerVoteData>();
|
__instance.gameObject.AddComponent<PlayerVoteData>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Calls the OnDeath method for all active modifiers.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="__instance">PlayerControl instance.</param>
|
||||||
[HarmonyPostfix]
|
[HarmonyPostfix]
|
||||||
[HarmonyPatch(nameof(PlayerControl.Die))]
|
[HarmonyPatch(nameof(PlayerControl.Die))]
|
||||||
// ReSharper disable once InconsistentNaming
|
|
||||||
public static void PlayerControlDiePostfix(PlayerControl __instance, DeathReason reason)
|
public static void PlayerControlDiePostfix(PlayerControl __instance, DeathReason reason)
|
||||||
{
|
{
|
||||||
var deathEvent = new PlayerDeathEvent(__instance, reason);
|
var deathEvent = new PlayerDeathEvent(__instance, reason);
|
||||||
@@ -52,9 +58,13 @@ internal static class PlayerControlPatches
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Used to trigger the <see cref="CompleteTaskEvent"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="__instance">PlayerControl instance.</param>
|
||||||
|
/// <param name="idx">The task id.</param>
|
||||||
[HarmonyPostfix]
|
[HarmonyPostfix]
|
||||||
[HarmonyPatch(nameof(PlayerControl.CompleteTask))]
|
[HarmonyPatch(nameof(PlayerControl.CompleteTask))]
|
||||||
// ReSharper disable once InconsistentNaming
|
|
||||||
public static void PlayerCompleteTaskPostfix(PlayerControl __instance, uint idx)
|
public static void PlayerCompleteTaskPostfix(PlayerControl __instance, uint idx)
|
||||||
{
|
{
|
||||||
var playerTask = __instance.myTasks.ToArray().First(playerTask => playerTask.Id == idx);
|
var playerTask = __instance.myTasks.ToArray().First(playerTask => playerTask.Id == idx);
|
||||||
@@ -65,9 +75,14 @@ internal static class PlayerControlPatches
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Used to trigger the <see cref="BeforeMurderEvent"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="__instance">The source player.</param>
|
||||||
|
/// <param name="target">The target.</param>
|
||||||
|
/// <param name="didSucceed">Whether the kill succeeded.</param>
|
||||||
[HarmonyPrefix]
|
[HarmonyPrefix]
|
||||||
[HarmonyPatch(nameof(PlayerControl.RpcMurderPlayer))]
|
[HarmonyPatch(nameof(PlayerControl.RpcMurderPlayer))]
|
||||||
// ReSharper disable once InconsistentNaming
|
|
||||||
public static void PlayerControlMurderPrefix(PlayerControl __instance, PlayerControl target, ref bool didSucceed)
|
public static void PlayerControlMurderPrefix(PlayerControl __instance, PlayerControl target, ref bool didSucceed)
|
||||||
{
|
{
|
||||||
var beforeMurderEvent = new BeforeMurderEvent(__instance, target);
|
var beforeMurderEvent = new BeforeMurderEvent(__instance, target);
|
||||||
@@ -76,16 +91,14 @@ internal static class PlayerControlPatches
|
|||||||
didSucceed = beforeMurderEvent.IsCancelled;
|
didSucceed = beforeMurderEvent.IsCancelled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// FixedUpdate handler for custom roles and custom buttons.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="__instance">PlayerControl instance.</param>
|
||||||
[HarmonyPostfix]
|
[HarmonyPostfix]
|
||||||
[HarmonyPatch(nameof(PlayerControl.FixedUpdate))]
|
[HarmonyPatch(nameof(PlayerControl.FixedUpdate))]
|
||||||
// ReSharper disable once InconsistentNaming
|
|
||||||
public static void PlayerControlFixedUpdatePostfix(PlayerControl __instance)
|
public static void PlayerControlFixedUpdatePostfix(PlayerControl __instance)
|
||||||
{
|
{
|
||||||
if (__instance.Data?.Role is ICustomRole customRole)
|
|
||||||
{
|
|
||||||
customRole.PlayerControlFixedUpdate(__instance);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!__instance.AmOwner)
|
if (!__instance.AmOwner)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
@@ -106,4 +119,15 @@ internal static class PlayerControlPatches
|
|||||||
button.FixedUpdateHandler(__instance);
|
button.FixedUpdateHandler(__instance);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Clear from modifier component cache.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="__instance">PlayerControl instance.</param>
|
||||||
|
[HarmonyPrefix]
|
||||||
|
[HarmonyPatch(nameof(PlayerControl.OnDestroy))]
|
||||||
|
public static void PlayerControlOnDestroyPrefix(PlayerControl __instance)
|
||||||
|
{
|
||||||
|
ModifierExtensions.ModifierComponents.Remove(__instance);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,8 +1,5 @@
|
|||||||
using System.Collections.Generic;
|
using HarmonyLib;
|
||||||
using System.Reflection;
|
|
||||||
using HarmonyLib;
|
|
||||||
using MiraAPI.Events;
|
using MiraAPI.Events;
|
||||||
using MiraAPI.Events.Vanilla.Gameplay;
|
|
||||||
using MiraAPI.Events.Vanilla.Meeting;
|
using MiraAPI.Events.Vanilla.Meeting;
|
||||||
using MiraAPI.Roles;
|
using MiraAPI.Roles;
|
||||||
|
|
||||||
@@ -12,7 +9,7 @@ namespace MiraAPI.Patches.Roles;
|
|||||||
/// Patches for custom ejection messages.
|
/// Patches for custom ejection messages.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[HarmonyPatch(typeof(ExileController))]
|
[HarmonyPatch(typeof(ExileController))]
|
||||||
internal static class EjectionPatches
|
public static class EjectionPatches
|
||||||
{
|
{
|
||||||
[HarmonyPostfix]
|
[HarmonyPostfix]
|
||||||
[HarmonyPatch(nameof(ExileController.Begin))]
|
[HarmonyPatch(nameof(ExileController.Begin))]
|
||||||
@@ -34,14 +31,4 @@ internal static class EjectionPatches
|
|||||||
|
|
||||||
__instance.completeString = role.GetCustomEjectionMessage(__instance.initData.networkedPlayer);
|
__instance.completeString = role.GetCustomEjectionMessage(__instance.initData.networkedPlayer);
|
||||||
}
|
}
|
||||||
|
|
||||||
[HarmonyPatch(typeof(ExileController), nameof(ExileController.WrapUp))]
|
|
||||||
public static class WrapUpPatch
|
|
||||||
{
|
|
||||||
public static void Postfix()
|
|
||||||
{
|
|
||||||
var @event = new RoundStartEvent(false);
|
|
||||||
MiraEventManager.InvokeEvent(@event);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -5,29 +5,15 @@ using Reactor.Utilities.Extensions;
|
|||||||
|
|
||||||
namespace MiraAPI.Patches.Roles;
|
namespace MiraAPI.Patches.Roles;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// HudManager patches for roles.
|
|
||||||
/// </summary>
|
|
||||||
[HarmonyPatch(typeof(HudManager))]
|
[HarmonyPatch(typeof(HudManager))]
|
||||||
public static class HudManagerPatches
|
internal static class HudManagerPatches
|
||||||
{
|
{
|
||||||
// Custom role tab.
|
|
||||||
private static TaskPanelBehaviour? _roleTab;
|
private static TaskPanelBehaviour? _roleTab;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Fixes Kill Button not showing for Neutral killing role.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="__instance">HudManager instance.</param>
|
|
||||||
/// <param name="localPlayer">The local PlayerControl.</param>
|
|
||||||
/// <param name="role">The player's RoleBehaviour.</param>
|
|
||||||
/// <param name="isActive">Whether the Hud should be set active or not.</param>
|
|
||||||
[HarmonyPostfix]
|
[HarmonyPostfix]
|
||||||
[HarmonyPatch(nameof(HudManager.SetHudActive), typeof(PlayerControl), typeof(RoleBehaviour), typeof(bool))]
|
[HarmonyPatch(nameof(HudManager.SetHudActive), typeof(PlayerControl), typeof(RoleBehaviour), typeof(bool))]
|
||||||
public static void SetHudActivePostfix(
|
// ReSharper disable once InconsistentNaming
|
||||||
HudManager __instance,
|
public static void SetHudActivePostfix(HudManager __instance, PlayerControl localPlayer, RoleBehaviour role, bool isActive)
|
||||||
PlayerControl localPlayer,
|
|
||||||
RoleBehaviour role,
|
|
||||||
bool isActive)
|
|
||||||
{
|
{
|
||||||
var flag = localPlayer.Data != null && localPlayer.Data.IsDead;
|
var flag = localPlayer.Data != null && localPlayer.Data.IsDead;
|
||||||
|
|
||||||
@@ -44,11 +30,9 @@ public static class HudManagerPatches
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Update custom role tab and custom role hud elements.
|
|
||||||
/// </summary>
|
|
||||||
[HarmonyPostfix]
|
[HarmonyPostfix]
|
||||||
[HarmonyPatch(nameof(HudManager.Update))]
|
[HarmonyPatch(nameof(HudManager.Update))]
|
||||||
|
// ReSharper disable once InconsistentNaming
|
||||||
public static void UpdatePostfix(HudManager __instance)
|
public static void UpdatePostfix(HudManager __instance)
|
||||||
{
|
{
|
||||||
var local = PlayerControl.LocalPlayer;
|
var local = PlayerControl.LocalPlayer;
|
||||||
@@ -62,8 +46,6 @@ public static class HudManagerPatches
|
|||||||
|
|
||||||
if (role is ICustomRole { Configuration.RoleHintType: RoleHintType.RoleTab } customRole)
|
if (role is ICustomRole { Configuration.RoleHintType: RoleHintType.RoleTab } customRole)
|
||||||
{
|
{
|
||||||
customRole.HudUpdate(__instance);
|
|
||||||
|
|
||||||
if (_roleTab == null)
|
if (_roleTab == null)
|
||||||
{
|
{
|
||||||
_roleTab = CustomRoleManager.CreateRoleTab(customRole);
|
_roleTab = CustomRoleManager.CreateRoleTab(customRole);
|
||||||
@@ -71,9 +53,9 @@ public static class HudManagerPatches
|
|||||||
|
|
||||||
CustomRoleManager.UpdateRoleTab(_roleTab, customRole);
|
CustomRoleManager.UpdateRoleTab(_roleTab, customRole);
|
||||||
}
|
}
|
||||||
else if (_roleTab)
|
else if (_roleTab != null)
|
||||||
{
|
{
|
||||||
_roleTab?.gameObject.Destroy();
|
_roleTab.gameObject.Destroy();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5,58 +5,18 @@ using MiraAPI.Events;
|
|||||||
using MiraAPI.Events.Vanilla.Gameplay;
|
using MiraAPI.Events.Vanilla.Gameplay;
|
||||||
using MiraAPI.Modifiers;
|
using MiraAPI.Modifiers;
|
||||||
using MiraAPI.Roles;
|
using MiraAPI.Roles;
|
||||||
using UnityEngine;
|
|
||||||
|
|
||||||
namespace MiraAPI.Patches.Roles;
|
namespace MiraAPI.Patches.Roles;
|
||||||
|
|
||||||
[HarmonyPatch(typeof(RoleManager))]
|
[HarmonyPatch(typeof(RoleManager))]
|
||||||
public static class RoleManagerPatches
|
public static class RoleManagerPatches
|
||||||
{
|
{
|
||||||
[HarmonyPrefix]
|
[HarmonyPostfix]
|
||||||
[HarmonyPatch(nameof(RoleManager.SetRole))]
|
[HarmonyPatch(nameof(RoleManager.SetRole))]
|
||||||
public static bool SetRolePatch(RoleManager __instance, PlayerControl targetPlayer, RoleTypes roleType)
|
public static void SetRolePatch(RoleManager __instance, PlayerControl targetPlayer, RoleTypes roleType)
|
||||||
{
|
{
|
||||||
if (!targetPlayer)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
var data = targetPlayer.Data;
|
|
||||||
if (data == null)
|
|
||||||
{
|
|
||||||
Debug.LogError("It shouldn't be possible, but " + targetPlayer.name + " still doesn't have PlayerData during role selection.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (data.Role)
|
|
||||||
{
|
|
||||||
data.Role.Deinitialize(targetPlayer);
|
|
||||||
Object.Destroy(data.Role.gameObject);
|
|
||||||
}
|
|
||||||
var roleBehaviour = Object.Instantiate<RoleBehaviour>(__instance.AllRoles.First(r => r.Role == roleType), data.gameObject.transform);
|
|
||||||
roleBehaviour.Initialize(targetPlayer);
|
|
||||||
targetPlayer.Data.Role = roleBehaviour;
|
|
||||||
targetPlayer.Data.RoleType = roleType;
|
|
||||||
|
|
||||||
// basically everything is the same except this one if statement
|
|
||||||
// innersloth decided to check the roleType manually instead of the role behaviour.
|
|
||||||
if (!roleBehaviour.IsDead)
|
|
||||||
{
|
|
||||||
targetPlayer.Data.RoleWhenAlive = new Il2CppSystem.Nullable<RoleTypes>(roleType);
|
|
||||||
}
|
|
||||||
roleBehaviour.AdjustTasks(targetPlayer);
|
|
||||||
switch (roleBehaviour.IsDead)
|
|
||||||
{
|
|
||||||
case true when !targetPlayer.Data.IsDead:
|
|
||||||
targetPlayer.Die(DeathReason.Kill, false);
|
|
||||||
return false;
|
|
||||||
case false when targetPlayer.Data.IsDead:
|
|
||||||
targetPlayer.Revive();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
var @event = new SetRoleEvent(targetPlayer, roleType);
|
var @event = new SetRoleEvent(targetPlayer, roleType);
|
||||||
MiraEventManager.InvokeEvent(@event);
|
MiraEventManager.InvokeEvent(@event);
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[HarmonyPostfix]
|
[HarmonyPostfix]
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ namespace MiraAPI.Patches.Roles;
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Patches to return the correct role counts.
|
/// Patches to return the correct role counts.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[HarmonyPatch(typeof(RoleOptionsCollectionV09))]
|
[HarmonyPatch(typeof(RoleOptionsCollectionV08))]
|
||||||
public static class RoleOptionsCollectionPatch
|
public static class RoleOptionsCollectionPatch
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -16,7 +16,7 @@ public static class RoleOptionsCollectionPatch
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>Return false to skip original method, true to not.</returns>
|
/// <returns>Return false to skip original method, true to not.</returns>
|
||||||
[HarmonyPrefix]
|
[HarmonyPrefix]
|
||||||
[HarmonyPatch(nameof(RoleOptionsCollectionV09.GetChancePerGame))]
|
[HarmonyPatch(nameof(RoleOptionsCollectionV08.GetChancePerGame))]
|
||||||
public static bool GetChancePrefix(RoleTypes role, ref int __result)
|
public static bool GetChancePrefix(RoleTypes role, ref int __result)
|
||||||
{
|
{
|
||||||
if (!CustomRoleManager.GetCustomRoleBehaviour(role, out var customRole) || customRole == null)
|
if (!CustomRoleManager.GetCustomRoleBehaviour(role, out var customRole) || customRole == null)
|
||||||
@@ -46,7 +46,7 @@ public static class RoleOptionsCollectionPatch
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>Return false to skip original method, true to not.</returns>
|
/// <returns>Return false to skip original method, true to not.</returns>
|
||||||
[HarmonyPrefix]
|
[HarmonyPrefix]
|
||||||
[HarmonyPatch(nameof(RoleOptionsCollectionV09.GetNumPerGame))]
|
[HarmonyPatch(nameof(RoleOptionsCollectionV08.GetNumPerGame))]
|
||||||
public static bool GetNumPrefix(RoleTypes role, ref int __result)
|
public static bool GetNumPrefix(RoleTypes role, ref int __result)
|
||||||
{
|
{
|
||||||
if (!CustomRoleManager.GetCustomRoleBehaviour(role, out var customRole) || customRole == null)
|
if (!CustomRoleManager.GetCustomRoleBehaviour(role, out var customRole) || customRole == null)
|
||||||
|
|||||||
@@ -33,4 +33,15 @@ public static class MinigameStubs
|
|||||||
{
|
{
|
||||||
// nothing needed
|
// nothing needed
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Fixes the error when creating custom minigames. Credit to Submerged for discovering this fix.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="__instance">The Minigame instance.</param>
|
||||||
|
[HarmonyPrefix]
|
||||||
|
[HarmonyPatch(typeof(Minigame), nameof(Minigame.Begin))]
|
||||||
|
public static void MinigameErrorFixPatch(Minigame __instance)
|
||||||
|
{
|
||||||
|
__instance.logger ??= new Logger("Minigame", Logger.Level.Info, Logger.Category.Gameplay);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -4,9 +4,6 @@ using Il2CppSystem.Text;
|
|||||||
|
|
||||||
namespace MiraAPI.Patches.Stubs;
|
namespace MiraAPI.Patches.Stubs;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Stub methods for the RoleBehaviour class. Needed because of Il2Cpp limitations on injected classes.
|
|
||||||
/// </summary>
|
|
||||||
[HarmonyPatch]
|
[HarmonyPatch]
|
||||||
public static class RoleBehaviourStubs
|
public static class RoleBehaviourStubs
|
||||||
{
|
{
|
||||||
@@ -60,7 +57,7 @@ public static class RoleBehaviourStubs
|
|||||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||||
public static bool CanUse(RoleBehaviour instance, IUsable console)
|
public static bool CanUse(RoleBehaviour instance, IUsable console)
|
||||||
{
|
{
|
||||||
return false;
|
return default;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -87,7 +84,7 @@ public static class RoleBehaviourStubs
|
|||||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||||
public static bool DidWin(RoleBehaviour instance, GameOverReason gameOverReason)
|
public static bool DidWin(RoleBehaviour instance, GameOverReason gameOverReason)
|
||||||
{
|
{
|
||||||
return false;
|
return default;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -100,7 +97,7 @@ public static class RoleBehaviourStubs
|
|||||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||||
public static PlayerControl FindClosestTarget(RoleBehaviour instance)
|
public static PlayerControl FindClosestTarget(RoleBehaviour instance)
|
||||||
{
|
{
|
||||||
return null!;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -113,7 +110,7 @@ public static class RoleBehaviourStubs
|
|||||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||||
public static float GetAbilityDistance(RoleBehaviour instance)
|
public static float GetAbilityDistance(RoleBehaviour instance)
|
||||||
{
|
{
|
||||||
return 0;
|
return default;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -127,7 +124,7 @@ public static class RoleBehaviourStubs
|
|||||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||||
public static bool IsValidTarget(RoleBehaviour instance, NetworkedPlayerInfo target)
|
public static bool IsValidTarget(RoleBehaviour instance, NetworkedPlayerInfo target)
|
||||||
{
|
{
|
||||||
return false;
|
return default;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -8,13 +8,17 @@ using UnityEngine;
|
|||||||
namespace MiraAPI.Patches;
|
namespace MiraAPI.Patches;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Used to change vent behaviour for the event system, custom roles, and modifiers.
|
/// Vent patches to make sure the player is able to use the vent.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[HarmonyPatch(typeof(Vent), nameof(Vent.CanUse))]
|
[HarmonyPatch(typeof(Vent))]
|
||||||
internal static class VentCanUsePatch
|
public static class VentPatches
|
||||||
{
|
{
|
||||||
// ReSharper disable InconsistentNaming
|
/// <summary>
|
||||||
public static void Postfix(Vent __instance, ref float __result, [HarmonyArgument(0)] NetworkedPlayerInfo pc, [HarmonyArgument(1)] ref bool canUse, [HarmonyArgument(2)] ref bool couldUse)
|
/// CanUse patch.
|
||||||
|
/// </summary>
|
||||||
|
[HarmonyPostfix]
|
||||||
|
[HarmonyPatch(nameof(Vent.CanUse))]
|
||||||
|
public static void VentCanUsePostfix(Vent __instance, ref float __result, [HarmonyArgument(0)] NetworkedPlayerInfo pc, [HarmonyArgument(1)] ref bool canUse, [HarmonyArgument(2)] ref bool couldUse)
|
||||||
{
|
{
|
||||||
var @event = new PlayerCanUseEvent(__instance.Cast<IUsable>());
|
var @event = new PlayerCanUseEvent(__instance.Cast<IUsable>());
|
||||||
MiraEventManager.InvokeEvent(@event);
|
MiraEventManager.InvokeEvent(@event);
|
||||||
@@ -1,18 +1,15 @@
|
|||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Linq;
|
||||||
using System.Linq;
|
|
||||||
using HarmonyLib;
|
using HarmonyLib;
|
||||||
using Il2CppInterop.Runtime.InteropTypes.Arrays;
|
using Il2CppInterop.Runtime.InteropTypes.Arrays;
|
||||||
using MiraAPI.Events;
|
using MiraAPI.Events;
|
||||||
using MiraAPI.Events.Vanilla.Meeting;
|
using MiraAPI.Events.Vanilla.Meeting;
|
||||||
using MiraAPI.Events.Vanilla.Meeting.Voting;
|
using MiraAPI.Events.Vanilla.Meeting.Voting;
|
||||||
using MiraAPI.Modifiers;
|
|
||||||
using MiraAPI.Utilities;
|
using MiraAPI.Utilities;
|
||||||
using MiraAPI.Voting;
|
using MiraAPI.Voting;
|
||||||
|
|
||||||
namespace MiraAPI.Patches.Voting;
|
namespace MiraAPI.Patches.Voting;
|
||||||
|
|
||||||
[HarmonyPatch(typeof(MeetingHud))]
|
[HarmonyPatch(typeof(MeetingHud))]
|
||||||
[SuppressMessage("ReSharper", "InconsistentNaming", Justification = "Harmony Convention")]
|
|
||||||
internal static class MeetingHudPatches
|
internal static class MeetingHudPatches
|
||||||
{
|
{
|
||||||
[HarmonyPostfix]
|
[HarmonyPostfix]
|
||||||
@@ -29,62 +26,11 @@ internal static class MeetingHudPatches
|
|||||||
{
|
{
|
||||||
voteData.SetRemainingVotes(0);
|
voteData.SetRemainingVotes(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var modifier in plr.GetModifierComponent().ActiveModifiers)
|
|
||||||
{
|
|
||||||
modifier.OnMeetingStart();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var @event = new StartMeetingEvent(__instance);
|
var @event = new StartMeetingEvent(__instance);
|
||||||
MiraEventManager.InvokeEvent(@event);
|
MiraEventManager.InvokeEvent(@event);
|
||||||
}
|
}
|
||||||
|
|
||||||
[HarmonyPostfix]
|
|
||||||
[HarmonyPatch(nameof(MeetingHud.OnDestroy))]
|
|
||||||
public static void OnDestroyPatch(MeetingHud __instance)
|
|
||||||
{
|
|
||||||
MiraEventManager.InvokeEvent(new EndMeetingEvent(__instance));
|
|
||||||
}
|
|
||||||
|
|
||||||
[HarmonyPostfix]
|
|
||||||
[HarmonyPatch(nameof(MeetingHud.VotingComplete))]
|
|
||||||
public static void VotingCompletePatch(MeetingHud __instance)
|
|
||||||
{
|
|
||||||
MiraEventManager.InvokeEvent(new VotingCompleteEvent(__instance));
|
|
||||||
}
|
|
||||||
|
|
||||||
// this is necessary because the actual ForceSkipAll method is inlined.
|
|
||||||
[HarmonyPrefix]
|
|
||||||
[HarmonyPatch(nameof(MeetingHud.Update))]
|
|
||||||
public static void ForceSkipPatch(MeetingHud __instance)
|
|
||||||
{
|
|
||||||
if (__instance.state is not (MeetingHud.VoteStates.NotVoted or MeetingHud.VoteStates.Voted))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var logicOptionsNormal = GameManager.Instance.LogicOptions.Cast<LogicOptionsNormal>();
|
|
||||||
var votingTime = logicOptionsNormal.GetVotingTime();
|
|
||||||
if (votingTime <= 0)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var num2 = __instance.discussionTimer - logicOptionsNormal.GetDiscussionTime();
|
|
||||||
|
|
||||||
if (!AmongUsClient.Instance.AmHost || num2 < votingTime)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var plr in PlayerControl.AllPlayerControls)
|
|
||||||
{
|
|
||||||
var voteData = plr.GetVoteData();
|
|
||||||
voteData.SetRemainingVotes(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[HarmonyPrefix]
|
[HarmonyPrefix]
|
||||||
[HarmonyPatch(nameof(MeetingHud.Select))]
|
[HarmonyPatch(nameof(MeetingHud.Select))]
|
||||||
public static bool SelectPatch(MeetingHud __instance, int suspectStateIdx)
|
public static bool SelectPatch(MeetingHud __instance, int suspectStateIdx)
|
||||||
|
|||||||
@@ -43,9 +43,6 @@ public sealed class MiraPluginManager
|
|||||||
var info = new MiraPluginInfo(miraPlugin, pluginInfo);
|
var info = new MiraPluginInfo(miraPlugin, pluginInfo);
|
||||||
var roles = new List<Type>();
|
var roles = new List<Type>();
|
||||||
|
|
||||||
var oldConfigSetting = info.PluginConfig.SaveOnConfigSet;
|
|
||||||
info.PluginConfig.SaveOnConfigSet = false;
|
|
||||||
|
|
||||||
foreach (var type in assembly.GetTypes())
|
foreach (var type in assembly.GetTypes())
|
||||||
{
|
{
|
||||||
if (type.GetCustomAttribute<MiraIgnoreAttribute>() != null)
|
if (type.GetCustomAttribute<MiraIgnoreAttribute>() != null)
|
||||||
@@ -99,9 +96,6 @@ public sealed class MiraPluginManager
|
|||||||
RegisterColorClasses(type);
|
RegisterColorClasses(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
info.PluginConfig.Save();
|
|
||||||
info.PluginConfig.SaveOnConfigSet = oldConfigSetting;
|
|
||||||
|
|
||||||
info.OptionGroups.Sort((x, y) => x.GroupPriority.CompareTo(y.GroupPriority));
|
info.OptionGroups.Sort((x, y) => x.GroupPriority.CompareTo(y.GroupPriority));
|
||||||
QueuedRoleRegistrations.Add(info, roles);
|
QueuedRoleRegistrations.Add(info, roles);
|
||||||
|
|
||||||
@@ -109,6 +103,7 @@ public sealed class MiraPluginManager
|
|||||||
Logger<MiraApiPlugin>.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 += MiraEventManager.SortAllHandlers;
|
||||||
IL2CPPChainloader.Instance.Finished += () =>
|
IL2CPPChainloader.Instance.Finished += () =>
|
||||||
{
|
{
|
||||||
CustomButtonManager.Buttons = new ReadOnlyCollection<CustomActionButton>(CustomButtonManager.CustomButtons);
|
CustomButtonManager.Buttons = new ReadOnlyCollection<CustomActionButton>(CustomButtonManager.CustomButtons);
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
using AmongUs.GameOptions;
|
using AmongUs.GameOptions;
|
||||||
|
using Il2CppSystem.Web.Util;
|
||||||
using MiraAPI.Utilities.Assets;
|
using MiraAPI.Utilities.Assets;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
using Helpers = MiraAPI.Utilities.Helpers;
|
||||||
|
|
||||||
namespace MiraAPI.Roles;
|
namespace MiraAPI.Roles;
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ using Reactor.Utilities;
|
|||||||
using Reactor.Utilities.Extensions;
|
using Reactor.Utilities.Extensions;
|
||||||
using TMPro;
|
using TMPro;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
using UnityEngine.TextCore;
|
||||||
using Object = UnityEngine.Object;
|
using Object = UnityEngine.Object;
|
||||||
|
|
||||||
namespace MiraAPI.Roles;
|
namespace MiraAPI.Roles;
|
||||||
@@ -59,9 +60,6 @@ public static class CustomRoleManager
|
|||||||
{
|
{
|
||||||
roles.ForEach(x => RoleIds.Add(x, GetNextRoleId()));
|
roles.ForEach(x => RoleIds.Add(x, GetNextRoleId()));
|
||||||
|
|
||||||
var oldConfigSetting = pluginInfo.PluginConfig.SaveOnConfigSet;
|
|
||||||
pluginInfo.PluginConfig.SaveOnConfigSet = false;
|
|
||||||
|
|
||||||
foreach (var roleType in roles)
|
foreach (var roleType in roles)
|
||||||
{
|
{
|
||||||
ClassInjector.RegisterTypeInIl2Cpp(roleType);
|
ClassInjector.RegisterTypeInIl2Cpp(roleType);
|
||||||
@@ -74,9 +72,6 @@ public static class CustomRoleManager
|
|||||||
|
|
||||||
pluginInfo.CustomRoles.Add((ushort)role.Role, role);
|
pluginInfo.CustomRoles.Add((ushort)role.Role, role);
|
||||||
}
|
}
|
||||||
|
|
||||||
pluginInfo.PluginConfig.Save();
|
|
||||||
pluginInfo.PluginConfig.SaveOnConfigSet = oldConfigSetting;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static RoleBehaviour? RegisterRole(Type roleType, MiraPluginInfo parentMod)
|
private static RoleBehaviour? RegisterRole(Type roleType, MiraPluginInfo parentMod)
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ using BepInEx.Configuration;
|
|||||||
using MiraAPI.GameOptions;
|
using MiraAPI.GameOptions;
|
||||||
using MiraAPI.Modifiers;
|
using MiraAPI.Modifiers;
|
||||||
using MiraAPI.PluginLoading;
|
using MiraAPI.PluginLoading;
|
||||||
|
using MiraAPI.Utilities;
|
||||||
using Reactor.Utilities;
|
using Reactor.Utilities;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
@@ -73,14 +74,6 @@ public interface ICustomRole : IOptionable
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
MiraPluginInfo ParentMod => CustomRoleManager.FindParentMod(this);
|
MiraPluginInfo ParentMod => CustomRoleManager.FindParentMod(this);
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// This method runs on the PlayerControl.FixedUpdate method for ALL players with this role.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="playerControl">The PlayerControl that has this role.</param>
|
|
||||||
void PlayerControlFixedUpdate(PlayerControl playerControl)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
internal ConfigDefinition NumConfigDefinition => new("Roles", $"Num {GetType().FullName}");
|
internal ConfigDefinition NumConfigDefinition => new("Roles", $"Num {GetType().FullName}");
|
||||||
internal ConfigDefinition ChanceConfigDefinition => new("Roles", $"Chance {GetType().FullName}");
|
internal ConfigDefinition ChanceConfigDefinition => new("Roles", $"Chance {GetType().FullName}");
|
||||||
|
|
||||||
@@ -183,14 +176,6 @@ public interface ICustomRole : IOptionable
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// This method runs on the HudManager.Update method ONLY when the LOCAL player has this role.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="hudManager">Reference to HudManager instance.</param>
|
|
||||||
void HudUpdate(HudManager hudManager)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a custom ejection message for the role. Return null to use the default message.
|
/// Gets a custom ejection message for the role. Return null to use the default message.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.IO;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using Reactor.Utilities.Extensions;
|
using Reactor.Utilities.Extensions;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|||||||
@@ -8,10 +8,10 @@ namespace MiraAPI.Utilities;
|
|||||||
public static class ColorExtensions
|
public static class ColorExtensions
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the relative luminance of a color (WCAG 2.1 specification). 0 is black, 1 is white.
|
/// Gets the relative luminance of a color (WCAG 2.1 specification).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="color">Color to calculate luminance for.</param>
|
/// <param name="color">Color to calculate luminance for.</param>
|
||||||
/// <returns>Luminance value between 0 and 1.</returns>
|
/// <returns>Relative luminance value.</returns>
|
||||||
public static float GetRelativeLuminance(this Color color)
|
public static float GetRelativeLuminance(this Color color)
|
||||||
{
|
{
|
||||||
var r = color.r <= 0.03928f ? color.r / 12.92f : Mathf.Pow((color.r + 0.055f) / 1.055f, 2.4f);
|
var r = color.r <= 0.03928f ? color.r / 12.92f : Mathf.Pow((color.r + 0.055f) / 1.055f, 2.4f);
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ public static class Helpers
|
|||||||
/// <returns>A list of alive players.</returns>
|
/// <returns>A list of alive players.</returns>
|
||||||
public static List<PlayerControl> GetAlivePlayers()
|
public static List<PlayerControl> GetAlivePlayers()
|
||||||
{
|
{
|
||||||
return [.. GameData.Instance.AllPlayers.ToArray().Where(x => !x.IsDead && !x.Disconnected && x.Object).Select(x=>x.Object)];
|
return PlayerControl.AllPlayerControls.ToArray().Where(x => !x.Data.IsDead).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Il2CppInterop.Runtime.Attributes;
|
|
||||||
using Reactor.Utilities.Attributes;
|
using Reactor.Utilities.Attributes;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
@@ -20,7 +19,6 @@ public class PlayerVoteData(nint cppPtr) : MonoBehaviour(cppPtr)
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the list of votes the owner has.
|
/// Gets the list of votes the owner has.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[HideFromIl2Cpp]
|
|
||||||
public List<CustomVote> Votes { get; private set; } = [];
|
public List<CustomVote> Votes { get; private set; } = [];
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -6,6 +6,5 @@
|
|||||||
<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="nuget.local/" />
|
|
||||||
</packageSources>
|
</packageSources>
|
||||||
</configuration>
|
</configuration>
|
||||||
Binary file not shown.
Reference in new issue
Block a user