mirror of
https://github.com/All-Of-Us-Mods/MiraAPI.git
synced 2026-10-20 01:46:15 +00:00
Compare commits
8
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9504862bea | ||
|
|
4b6ffc65df | ||
|
|
ccde63068b | ||
|
|
5e16429acf | ||
|
|
1e47500686 | ||
|
|
0b1cf998f8 | ||
|
|
14a3669031 | ||
|
|
ae79cd87d9 |
No files matched your search
@@ -16,7 +16,7 @@ public class ExampleOptions : AbstractOptionGroup
|
||||
[ModdedToggleOption("Toggle Opt 2")]
|
||||
public bool ToggleOpt2 { get; set; } = true;
|
||||
|
||||
[ModdedNumberOption("Number Opt", min: 0, max: 10, suffixType: MiraNumberSuffixes.Percent)]
|
||||
[ModdedNumberOption("Number Opt", min: 0, max: 10, increment: .25f, formatString: "0.00", suffixType: MiraNumberSuffixes.Percent)]
|
||||
public float NumberOpt { get; set; } = 4f;
|
||||
|
||||
[ModdedEnumOption("Best API", typeof(BestApi), ["Mira API", "Mitochondria", "Reactor"])]
|
||||
|
||||
@@ -15,13 +15,14 @@ public class ModdedNumberOptionAttribute(
|
||||
float max,
|
||||
float increment = 1,
|
||||
MiraNumberSuffixes suffixType = MiraNumberSuffixes.None,
|
||||
string? formatString = null,
|
||||
bool zeroInfinity = false,
|
||||
Type? roleType = null)
|
||||
: ModdedOptionAttribute(title, roleType)
|
||||
{
|
||||
internal override IModdedOption CreateOption(object? value, PropertyInfo property)
|
||||
{
|
||||
return new ModdedNumberOption(Title, (float)(value ?? min+increment), min, max, increment, suffixType, zeroInfinity, RoleType);
|
||||
return new ModdedNumberOption(Title, (float)(value ?? min+increment), min, max, increment, suffixType, formatString, zeroInfinity, RoleType);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
||||
@@ -46,6 +46,7 @@ public class ModdedNumberOption : ModdedOption<float>
|
||||
/// <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="zeroInfinity">Whether zero is infinity or not.</param>
|
||||
/// <param name="roleType">An optional role type.</param>
|
||||
public ModdedNumberOption(
|
||||
@@ -55,6 +56,7 @@ public class ModdedNumberOption : ModdedOption<float>
|
||||
float max,
|
||||
float increment,
|
||||
MiraNumberSuffixes suffixType,
|
||||
string? formatString = null,
|
||||
bool zeroInfinity = false,
|
||||
Type? roleType = null) : base(title, defaultValue, roleType)
|
||||
{
|
||||
@@ -74,7 +76,13 @@ public class ModdedNumberOption : ModdedOption<float>
|
||||
data.Value = Value;
|
||||
data.Increment = Increment;
|
||||
data.ValidRange = new FloatRange(Min, Max);
|
||||
data.FormatString = Increment % 1 == 0 && Value % 1 == 0 && Min % 1 == 0 && Max % 1 == 0 ? "0" : "0.0"; // not sure if the == checks will work since this is floats but we'll find out
|
||||
data.FormatString = formatString ??
|
||||
(!Mathf.Approximately(defaultValue, 0) ||
|
||||
!Mathf.Approximately(Increment % 1, 0) ||
|
||||
!Mathf.Approximately(Value % 1, 0) ||
|
||||
!Mathf.Approximately(Min % 1, 0) ||
|
||||
!Mathf.Approximately(Max % 1, 0) ? "0.0" : "0");
|
||||
|
||||
data.ZeroIsInfinity = ZeroInfinity;
|
||||
data.SuffixType = (NumberSuffixes)SuffixType;
|
||||
data.OptionName = FloatOptionNames.Invalid;
|
||||
|
||||
@@ -263,6 +263,9 @@ public static class CustomMurderRpc
|
||||
deadBody.enabled = true;
|
||||
}
|
||||
|
||||
var afterMurderEvent = new AfterMurderEvent(source, target);
|
||||
MiraEventManager.InvokeEvent(afterMurderEvent);
|
||||
|
||||
if (!isParticipant)
|
||||
{
|
||||
yield break;
|
||||
@@ -275,8 +278,5 @@ public static class CustomMurderRpc
|
||||
|
||||
PlayerControl.LocalPlayer.isKilling = false;
|
||||
source.isKilling = false;
|
||||
|
||||
var afterMurderEvent = new AfterMurderEvent(source, target);
|
||||
MiraEventManager.InvokeEvent(afterMurderEvent);
|
||||
}
|
||||
}
|
||||
@@ -4,17 +4,19 @@ using UnityEngine;
|
||||
|
||||
namespace MiraAPI.Patches.Colors;
|
||||
|
||||
[HarmonyPatch(typeof(PlayerTab))]
|
||||
/// <summary>
|
||||
/// This patch adds scrolling to the colors tab in the player customization menu.
|
||||
/// </summary>
|
||||
[HarmonyPatch(typeof(PlayerTab), nameof(PlayerTab.OnEnable))]
|
||||
public static class ScrollingColorsPatch
|
||||
{
|
||||
// Collider
|
||||
private static BoxCollider2D? _collider;
|
||||
|
||||
/// <summary>
|
||||
/// Add scrolling to the colors tab
|
||||
/// Add scrolling to the colors tab.
|
||||
/// </summary>
|
||||
[HarmonyPostfix, HarmonyPatch("OnEnable")]
|
||||
public static void AddScrollingToColorsTabPatch(PlayerTab __instance)
|
||||
public static void Postfix(PlayerTab __instance)
|
||||
{
|
||||
if (!PlayerCustomizationMenu.Instance)
|
||||
{
|
||||
|
||||
@@ -157,8 +157,6 @@ public static class GameSettingMenuPatches
|
||||
roles.AdvancedRolesSettings.gameObject.SetActive(false);
|
||||
roles.RoleChancesSettings.gameObject.SetActive(true);
|
||||
roles.SetQuotaTab();
|
||||
|
||||
roles.scrollBar.CalculateAndSetYBounds(roles.roleChances.Count + 5, 1f, 6f, 0.43f);
|
||||
roles.scrollBar.ScrollToTop();
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ using MiraAPI.Utilities.Assets;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Reactor.Localization.Utilities;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Events;
|
||||
using UnityEngine.UI;
|
||||
@@ -211,34 +212,43 @@ public static class LobbyViewPanePatches
|
||||
|
||||
var list = new List<Type>();
|
||||
|
||||
foreach (var team in Enum.GetValues<ModdedRoleTeams>())
|
||||
{
|
||||
var filteredRoles = SelectedMod.CustomRoles.Values
|
||||
.OfType<ICustomRole>()
|
||||
.Where(x => !x.Configuration.HideSettings && x.Team == team).ToList();
|
||||
var roleGroups = GameSettingMenuPatches.SelectedMod?.CustomRoles.Values.OfType<ICustomRole>()
|
||||
.ToLookup(x => x.RoleOptionsGroup);
|
||||
|
||||
if (filteredRoles.Count == 0)
|
||||
if (roleGroups is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// sort the groups by priority
|
||||
var sortedRoleGroups = roleGroups
|
||||
.OrderBy(x => x.Key.Priority)
|
||||
.ThenBy(x => x.Key.Name);
|
||||
|
||||
foreach (var grouping in sortedRoleGroups)
|
||||
{
|
||||
if (!grouping.Any())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var categoryHeaderRoleVariant =
|
||||
Object.Instantiate(instance.categoryHeaderRoleOrigin, instance.settingsContainer, true);
|
||||
var group = grouping.Key;
|
||||
|
||||
switch (team)
|
||||
var name = group.Name switch
|
||||
{
|
||||
case ModdedRoleTeams.Crewmate:
|
||||
categoryHeaderRoleVariant.SetHeader(StringNames.CrewmateRolesHeader, 61);
|
||||
break;
|
||||
case ModdedRoleTeams.Impostor:
|
||||
categoryHeaderRoleVariant.SetHeader(StringNames.ImpostorRolesHeader, 61);
|
||||
break;
|
||||
default:
|
||||
categoryHeaderRoleVariant.SetHeader(StringNames.CrewmateRolesHeader, 61);
|
||||
categoryHeaderRoleVariant.Title.text = team + " Roles";
|
||||
categoryHeaderRoleVariant.Background.color = Color.gray;
|
||||
categoryHeaderRoleVariant.Title.color = Color.white;
|
||||
break;
|
||||
"Crewmate" => StringNames.CrewmateRolesHeader,
|
||||
"Impostor" => StringNames.ImpostorRolesHeader,
|
||||
_ => CustomStringName.CreateAndRegister(group.Name),
|
||||
};
|
||||
|
||||
var categoryHeaderRoleVariant = Object.Instantiate(instance.categoryHeaderRoleOrigin, instance.settingsContainer, true);
|
||||
categoryHeaderRoleVariant.SetHeader(name, 61);
|
||||
|
||||
if (name is not (StringNames.CrewmateRolesHeader or StringNames.ImpostorRolesHeader))
|
||||
{
|
||||
var veryDarkColor = group.Color.DarkenColor(.35f);
|
||||
categoryHeaderRoleVariant.Title.color = veryDarkColor;
|
||||
categoryHeaderRoleVariant.Background.color = group.Color;
|
||||
}
|
||||
|
||||
categoryHeaderRoleVariant.transform.localScale = Vector3.one;
|
||||
@@ -246,7 +256,7 @@ public static class LobbyViewPanePatches
|
||||
instance.settingsInfo.Add(categoryHeaderRoleVariant.gameObject);
|
||||
num -= 0.696f;
|
||||
|
||||
foreach (var customRole in filteredRoles)
|
||||
foreach (var customRole in grouping)
|
||||
{
|
||||
var roleBehaviour = customRole as RoleBehaviour;
|
||||
if (roleBehaviour == null)
|
||||
@@ -259,8 +269,6 @@ public static class LobbyViewPanePatches
|
||||
var numPerGame =
|
||||
GameOptionsManager.Instance.CurrentGameOptions.RoleOptions.GetNumPerGame(roleBehaviour.Role);
|
||||
|
||||
var flag = numPerGame == 0;
|
||||
|
||||
var viewSettingsInfoPanelRoleVariant =
|
||||
Object.Instantiate(
|
||||
instance.infoPanelRoleOrigin,
|
||||
@@ -273,7 +281,7 @@ public static class LobbyViewPanePatches
|
||||
.Where(x => x.AdvancedRole == customRole.GetType())
|
||||
.ToList();
|
||||
|
||||
if (!flag && advancedRoleOptions.Count > 0)
|
||||
if (numPerGame > 0 && advancedRoleOptions.Count > 0)
|
||||
{
|
||||
list.Add(customRole.GetType());
|
||||
}
|
||||
@@ -286,6 +294,8 @@ public static class LobbyViewPanePatches
|
||||
customRole.RoleColor,
|
||||
customRole.Configuration.Icon.LoadAsset(),
|
||||
true);
|
||||
viewSettingsInfoPanelRoleVariant.iconSprite.transform.localScale = new Vector3(0.365f, 0.365f, 1f);
|
||||
viewSettingsInfoPanelRoleVariant.iconSprite.transform.localPosition = new Vector3(0.7144f, -0.028f, -2);
|
||||
|
||||
viewSettingsInfoPanelRoleVariant.titleText.color =
|
||||
viewSettingsInfoPanelRoleVariant.chanceTitle.color =
|
||||
@@ -370,6 +380,7 @@ public static class LobbyViewPanePatches
|
||||
maskLayer,
|
||||
role.TeamType == RoleTeamTypes.Crewmate,
|
||||
customRole.Configuration.Icon.LoadAsset());
|
||||
viewPanel.header.icon.transform.localScale = new Vector3(0.465f, 0.465f, 1f);
|
||||
viewPanel.divider.material.SetInt(PlayerMaterial.MaskLayer, maskLayer);
|
||||
|
||||
var num = viewPanel.yPosStart;
|
||||
|
||||
@@ -26,10 +26,16 @@ public static class RoleSettingMenuPatches
|
||||
private static List<CategoryHeaderEditRole> CategoryHeaderEditRoles { get; } = [];
|
||||
private static List<RoleOptionSetting> RoleOptionSettings { get; } = [];
|
||||
|
||||
private static float ScrollerNum { get; set; } = 0.522f;
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(nameof(RolesSettingsMenu.SetQuotaTab))]
|
||||
public static bool PatchStart(RolesSettingsMenu __instance)
|
||||
{
|
||||
CategoryHeaderEditRoles.ForEach(Object.Destroy);
|
||||
CategoryHeaderEditRoles.Clear();
|
||||
RoleOptionSettings.ForEach(Object.Destroy);
|
||||
RoleOptionSettings.Clear();
|
||||
__instance.roleChances = new Il2CppSystem.Collections.Generic.List<RoleOptionSetting>();
|
||||
__instance.advancedSettingChildren = new Il2CppSystem.Collections.Generic.List<OptionBehaviour>();
|
||||
|
||||
@@ -48,7 +54,7 @@ public static class RoleSettingMenuPatches
|
||||
return true;
|
||||
}
|
||||
|
||||
var num = 0.522f;
|
||||
ScrollerNum = 0.522f;
|
||||
|
||||
__instance.AllButton.transform.parent.gameObject.SetActive(false);
|
||||
__instance.AllButton.gameObject.SetActive(false);
|
||||
@@ -80,13 +86,15 @@ public static class RoleSettingMenuPatches
|
||||
continue;
|
||||
}
|
||||
|
||||
RoleGroupHidden.TryAdd(grouping.Key, false);
|
||||
var group = grouping.Key;
|
||||
|
||||
var name = grouping.Key.Name switch
|
||||
RoleGroupHidden.TryAdd(group, false);
|
||||
|
||||
var name = group.Name switch
|
||||
{
|
||||
"Crewmate" => StringNames.CrewmateRolesHeader,
|
||||
"Impostor" => StringNames.ImpostorRolesHeader,
|
||||
_ => CustomStringName.CreateAndRegister(grouping.Key.Name),
|
||||
_ => CustomStringName.CreateAndRegister(group.Name),
|
||||
};
|
||||
|
||||
var categoryHeaderEditRole = Object.Instantiate(
|
||||
@@ -95,15 +103,26 @@ public static class RoleSettingMenuPatches
|
||||
Quaternion.identity,
|
||||
__instance.RoleChancesSettings.transform);
|
||||
categoryHeaderEditRole.SetHeader(name, 20);
|
||||
categoryHeaderEditRole.transform.localPosition = new Vector3(4.986f, num, -2f);
|
||||
if (name is not (StringNames.CrewmateRolesHeader or StringNames.ImpostorRolesHeader))
|
||||
{
|
||||
var darkColor = group.Color.DarkenColor(.25f);
|
||||
var veryDarkColor = group.Color.DarkenColor(.35f);
|
||||
categoryHeaderEditRole.Title.color = veryDarkColor;
|
||||
categoryHeaderEditRole.blankLabel.color = veryDarkColor;
|
||||
categoryHeaderEditRole.Background.color = group.Color;
|
||||
categoryHeaderEditRole.chanceLabel.color = darkColor;
|
||||
categoryHeaderEditRole.countLabel.color = darkColor;
|
||||
}
|
||||
|
||||
categoryHeaderEditRole.transform.localPosition = new Vector3(4.986f, ScrollerNum, -2f);
|
||||
categoryHeaderEditRole.transform.Find("LabelSprite").transform.localScale = new Vector3(1.3f, 1, 0.5529f);
|
||||
categoryHeaderEditRole.transform.Find("QuotaHeader").gameObject.SetActive(!RoleGroupHidden[grouping.Key]);
|
||||
categoryHeaderEditRole.transform.Find("QuotaHeader").gameObject.SetActive(!RoleGroupHidden[group]);
|
||||
|
||||
CategoryHeaderEditRoles.Add(categoryHeaderEditRole);
|
||||
|
||||
num -= 0.522f;
|
||||
ScrollerNum -= 0.522f;
|
||||
|
||||
var label = RoleGroupHidden[grouping.Key]
|
||||
var label = RoleGroupHidden[group]
|
||||
? "(Click to open)"
|
||||
: "(Click to close)";
|
||||
var newText = Object.Instantiate(categoryHeaderEditRole.Title, categoryHeaderEditRole.transform);
|
||||
@@ -111,7 +130,7 @@ public static class RoleSettingMenuPatches
|
||||
newText.transform.localPosition = new Vector3(-3.3425f, -0.1706f, -1);
|
||||
newText.gameObject.GetComponent<TextTranslatorTMP>().Destroy();
|
||||
|
||||
if (!RoleGroupHidden[grouping.Key])
|
||||
if (!RoleGroupHidden[group])
|
||||
{
|
||||
foreach (var role in grouping)
|
||||
{
|
||||
@@ -120,7 +139,7 @@ public static class RoleSettingMenuPatches
|
||||
continue;
|
||||
}
|
||||
|
||||
var option = CreateQuotaOption(__instance, roleBehaviour, ref num, num3);
|
||||
var option = CreateQuotaOption(__instance, roleBehaviour, num3);
|
||||
if (option is not null)
|
||||
{
|
||||
RoleOptionSettings.Add(option);
|
||||
@@ -140,7 +159,10 @@ public static class RoleSettingMenuPatches
|
||||
headerBtn.OnClick.AddListener(
|
||||
(UnityAction)(() =>
|
||||
{
|
||||
RoleGroupHidden[grouping.Key] = !RoleGroupHidden[grouping.Key];
|
||||
if (RoleGroupHidden.TryGetValue(group, out var value))
|
||||
{
|
||||
RoleGroupHidden[group] = !value;
|
||||
}
|
||||
foreach (var header in CategoryHeaderEditRoles)
|
||||
{
|
||||
header.gameObject.Destroy();
|
||||
@@ -155,15 +177,20 @@ public static class RoleSettingMenuPatches
|
||||
}));
|
||||
headerBtn.SetButtonEnableState(true);
|
||||
|
||||
if (!RoleGroupHidden[grouping.Key])
|
||||
if (!RoleGroupHidden[group])
|
||||
{
|
||||
num -= 0.4f;
|
||||
ScrollerNum -= 0.4f;
|
||||
}
|
||||
}
|
||||
__instance.scrollBar.CalculateAndSetYBounds(__instance.roleChances.Count + 5, 1f, 6f, 0.43f);
|
||||
__instance.scrollBar.SetScrollBounds();
|
||||
return false;
|
||||
}
|
||||
|
||||
private static void SetScrollBounds(this Scroller scroller)
|
||||
{
|
||||
scroller.CalculateAndSetYBounds(1 + 1.5f * CategoryHeaderEditRoles.Count + RoleOptionSettings.Count, 1f, 6f, 0.43f);
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(nameof(RolesSettingsMenu.Update))]
|
||||
public static bool UpdatePatch()
|
||||
@@ -175,7 +202,12 @@ public static class RoleSettingMenuPatches
|
||||
[HarmonyPatch(nameof(RolesSettingsMenu.OpenChancesTab))]
|
||||
public static void OpenChancesTabPostfix(RolesSettingsMenu __instance)
|
||||
{
|
||||
__instance.scrollBar.CalculateAndSetYBounds(__instance.roleChances.Count + 5, 1f, 6f, 0.43f);
|
||||
if (GameSettingMenuPatches.SelectedModIdx == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
__instance.scrollBar.SetScrollBounds();
|
||||
__instance.scrollBar.ScrollToTop();
|
||||
}
|
||||
|
||||
@@ -319,7 +351,7 @@ public static class RoleSettingMenuPatches
|
||||
__instance.RefreshChildren();
|
||||
}
|
||||
|
||||
private static RoleOptionSetting? CreateQuotaOption(RolesSettingsMenu __instance, RoleBehaviour role, ref float yPos, int index)
|
||||
private static RoleOptionSetting? CreateQuotaOption(RolesSettingsMenu __instance, RoleBehaviour role, int index)
|
||||
{
|
||||
if (role is not ICustomRole customRole)
|
||||
{
|
||||
@@ -327,12 +359,17 @@ public static class RoleSettingMenuPatches
|
||||
return null;
|
||||
}
|
||||
|
||||
if (customRole.Configuration.HideSettings)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var roleOptionSetting = Object.Instantiate(
|
||||
__instance.roleOptionSettingOrigin,
|
||||
Vector3.zero,
|
||||
Quaternion.identity,
|
||||
__instance.RoleChancesSettings.transform);
|
||||
roleOptionSetting.transform.localPosition = new Vector3(-0.15f, yPos, -2f);
|
||||
roleOptionSetting.transform.localPosition = new Vector3(-0.15f, ScrollerNum, -2f);
|
||||
|
||||
roleOptionSetting.SetRole(GameOptionsManager.Instance.CurrentGameOptions.RoleOptions, role, 20);
|
||||
roleOptionSetting.labelSprite.color = customRole.RoleColor;
|
||||
@@ -379,7 +416,7 @@ public static class RoleSettingMenuPatches
|
||||
|
||||
if (index < GameSettingMenuPatches.SelectedMod?.CustomRoles.Count - 1)
|
||||
{
|
||||
yPos += -0.43f;
|
||||
ScrollerNum += -0.43f;
|
||||
}
|
||||
|
||||
return roleOptionSetting;
|
||||
|
||||
@@ -11,10 +11,11 @@ public static class RoleBehaviourStubs
|
||||
/// Stub method for RoleBehaviour.Initialize.
|
||||
/// </summary>
|
||||
/// <param name="instance">The RoleBehaviour object.</param>
|
||||
/// <param name="player">The PlayerControl to initialize.</param>
|
||||
[HarmonyReversePatch]
|
||||
[HarmonyPatch(typeof(RoleBehaviour), nameof(RoleBehaviour.Initialize))]
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
public static void Initialize(RoleBehaviour instance)
|
||||
public static void Initialize(RoleBehaviour instance, PlayerControl player)
|
||||
{
|
||||
// nothing needed
|
||||
}
|
||||
@@ -38,7 +39,7 @@ public static class RoleBehaviourStubs
|
||||
/// <param name="instance">The RoleBehaviour object.</param>
|
||||
/// <param name="taskStringBuilder">The StringBuilder to append the task hint to.</param>
|
||||
[HarmonyReversePatch]
|
||||
[HarmonyPatch(typeof(RoleBehaviour), nameof(RoleBehaviour.AppendTaskHint))]
|
||||
[HarmonyPatch(typeof(RoleBehaviour), nameof(RoleBehaviour.AppendTaskHint), typeof(StringBuilder))]
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
public static void AppendTaskHint(RoleBehaviour instance, StringBuilder taskStringBuilder)
|
||||
{
|
||||
|
||||
Reference in new issue
Block a user