Add WIP advanced role guide tab

This commit is contained in:
Atony committed 2026-09-23 01:34:06 -05:00
1 parent 8fa87c0b7d
commit b6881e4d77
2 files changed
+128 -4

No files matched your search

+107 -3
View File
@@ -7,7 +7,11 @@ using HarmonyLib;
using Innersloth.Assets; using Innersloth.Assets;
using MiraAPI.Roles; using MiraAPI.Roles;
using MiraAPI.Utilities; using MiraAPI.Utilities;
using Reactor.Utilities.Extensions;
using TMPro;
using UnityEngine; using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;
using Object = UnityEngine.Object; using Object = UnityEngine.Object;
namespace MiraAPI.Patches; namespace MiraAPI.Patches;
@@ -39,6 +43,8 @@ public static class RoleGuidePatches
__instance.MatchInfoRoleMaskArea.transform.parent.GetAllChildren() __instance.MatchInfoRoleMaskArea.transform.parent.GetAllChildren()
.First(x => x.name.Contains("BG_Gradient")).GetComponent<SpriteRenderer>() .First(x => x.name.Contains("BG_Gradient")).GetComponent<SpriteRenderer>()
.maskInteraction = SpriteMaskInteraction.VisibleInsideMask; .maskInteraction = SpriteMaskInteraction.VisibleInsideMask;
var wikiTab = Object.Instantiate(__instance.settingsTabs[2], __instance.settingsTabs[2].transform.parent);
AdvancedWikiTab = wikiTab.GetComponent<Scroller>();
} }
[HarmonyPrefix] [HarmonyPrefix]
@@ -75,13 +81,24 @@ public static class RoleGuidePatches
bool enabled = ActiveInputManager.currentControlType == ActiveInputManager.InputType.Joystick; bool enabled = ActiveInputManager.currentControlType == ActiveInputManager.InputType.Joystick;
__instance.glyphL.enabled = enabled; __instance.glyphL.enabled = enabled;
__instance.glyphR.enabled = enabled; __instance.glyphR.enabled = enabled;
if (!TitleText)
{
TitleText = __instance.transitionOpen.transform.FindChild("Text_Title")?.GetComponent<TextMeshPro>()!;
if (TitleText)
{
TitleText.transform.GetComponent<TextTranslatorTMP>().Destroy();
}
}
if (TitleText)
{
TitleText.text = TranslationController.Instance.GetString(StringNames.MatchInfoGuideTitle);
}
if (GameManager.Instance.TryCast<NormalGameManager>() != null) if (GameManager.Instance.TryCast<NormalGameManager>() != null)
{ {
if (__instance.NormalModeSettings.Count == 0) if (__instance.NormalModeSettings.Count == 0)
{ {
__instance.numOfTabs = 3; __instance.numOfTabs = 3;
__instance.TabButtons[0].SelectButton(true); __instance.TabButtons[0].SelectButton(true);
DisplayNormalRoleSettings(__instance, true);
__instance.MatchInfoRoleMaskArea.transform.localPosition = new Vector3(-0.0184f, 0.15f, -0.1f); __instance.MatchInfoRoleMaskArea.transform.localPosition = new Vector3(-0.0184f, 0.15f, -0.1f);
__instance.matchInfoPlayersMaskArea.transform.localPosition = __instance.matchInfoPlayersMaskArea.transform.localPosition =
@@ -100,6 +117,11 @@ public static class RoleGuidePatches
__instance.MatchInfoRoleMaskArea.transform.parent.GetAllChildren() __instance.MatchInfoRoleMaskArea.transform.parent.GetAllChildren()
.First(x => x.name.Contains("BG_Gradient")).GetComponent<SpriteRenderer>() .First(x => x.name.Contains("BG_Gradient")).GetComponent<SpriteRenderer>()
.maskInteraction = SpriteMaskInteraction.VisibleInsideMask; .maskInteraction = SpriteMaskInteraction.VisibleInsideMask;
__instance.MatchInfoRoleMaskArea.material.SetInt(PlayerMaterial.MaskLayer, 50);
__instance.matchInfoSettingsMaskArea.material.SetInt(PlayerMaterial.MaskLayer, 50);
var wikiTab = Object.Instantiate(__instance.settingsTabs[2], __instance.settingsTabs[2].transform.parent);
AdvancedWikiTab = wikiTab.GetComponent<Scroller>();
DisplayNormalRoleSettings(__instance, true);
} }
else else
{ {
@@ -126,6 +148,9 @@ public static class RoleGuidePatches
} }
private static Dictionary<RoleBehaviour, MatchInfoRolePanel> _rolePanels = []; private static Dictionary<RoleBehaviour, MatchInfoRolePanel> _rolePanels = [];
public static Scroller AdvancedWikiTab;
public static GameObject CurrentAdvancedTabObject;
public static TextMeshPro TitleText;
public static void DisplayNormalRoleSettings(MatchInfoGuide instance, bool reset) public static void DisplayNormalRoleSettings(MatchInfoGuide instance, bool reset)
{ {
@@ -156,6 +181,7 @@ public static class RoleGuidePatches
instance.CreateSettingsEntry( instance.CreateSettingsEntry(
StringNames.GameTaskBarMode, StringNames.GameTaskBarMode,
GameManager.Instance.LogicOptions.GetTaskBarMode().ToString()); GameManager.Instance.LogicOptions.GetTaskBarMode().ToString());
var hoverColor = new Color32(255, 255, 255, 150);
foreach (RoleBehaviour roleBehaviour in RoleManager.Instance.AllRoles) foreach (RoleBehaviour roleBehaviour in RoleManager.Instance.AllRoles)
{ {
if (roleBehaviour.Role != RoleTypes.Crewmate && roleBehaviour.Role != RoleTypes.Impostor && if (roleBehaviour.Role != RoleTypes.Crewmate && roleBehaviour.Role != RoleTypes.Impostor &&
@@ -165,10 +191,31 @@ public static class RoleGuidePatches
var panel = Object.Instantiate( var panel = Object.Instantiate(
instance.MatchInfoRolePanelPrefab, instance.MatchInfoRolePanelPrefab,
instance.settingsTabs[2].GetComponent<Scroller>().Inner); instance.settingsTabs[2].GetComponent<Scroller>().Inner);
var collider = panel.roleIcon.gameObject.AddComponent<BoxCollider2D>();
collider.size = new Vector2(0.13f, 0.13f);
collider.offset = new Vector2(0, 0);
var passiveButton = panel.roleIcon.gameObject.AddComponent<PassiveButton>();
passiveButton.OnMouseOver = new UnityEvent();
passiveButton.OnMouseOver.AddListener(
(UnityAction)(() =>
{
panel.roleIcon.color = hoverColor;
}));
passiveButton.OnMouseOut = new UnityEvent();
passiveButton.OnMouseOut.AddListener(
(UnityAction)(() =>
{
panel.roleIcon.color = Color.white;
}));
passiveButton.OnClick = new Button.ButtonClickedEvent();
passiveButton.OnClick.AddListener(
(UnityAction)(() => { DisplayAdvancedWiki(instance, roleBehaviour); }));
_rolePanels.Add(roleBehaviour, panel); _rolePanels.Add(roleBehaviour, panel);
} }
} }
} }
AdvancedWikiTab?.gameObject.SetActive(false);
int num = 0; int num = 0;
foreach (var pair in _rolePanels) foreach (var pair in _rolePanels)
@@ -200,8 +247,6 @@ public static class RoleGuidePatches
} }
instance.MatchInfoRoleScroller.SetYBoundsMax(Mathf.Clamp(Mathf.Ceil((float)num / 2f) * 1.3f - 1.5f, 0f, 999f)); instance.MatchInfoRoleScroller.SetYBoundsMax(Mathf.Clamp(Mathf.Ceil((float)num / 2f) * 1.3f - 1.5f, 0f, 999f));
instance.MatchInfoRoleMaskArea.material.SetInt(PlayerMaterial.MaskLayer, 50);
instance.matchInfoSettingsMaskArea.material.SetInt(PlayerMaterial.MaskLayer, 50);
if (reset) if (reset)
{ {
instance.CreatePlayerEntries(); instance.CreatePlayerEntries();
@@ -242,6 +287,65 @@ public static class RoleGuidePatches
return false; return false;
} }
[HarmonyPostfix]
[HarmonyPriority(Priority.First)]
[HarmonyPatch(typeof(MatchInfoGuide), nameof(MatchInfoGuide.SetActiveTab))]
private static void SetActiveTab(MatchInfoGuide __instance)
{
if (TitleText)
{
TitleText.text = TranslationController.Instance.GetString(StringNames.MatchInfoGuideTitle);
}
AdvancedWikiTab?.gameObject.SetActive(false);
}
public static void DisplayAdvancedWiki(MatchInfoGuide instance, RoleBehaviour role)
{
Warning($"Opening advanced tab for {role.GetRoleName()}.");
instance.settingsTabs[2].SetActive(false);
AdvancedWikiTab?.gameObject.SetActive(true);
if (CurrentAdvancedTabObject)
{
CurrentAdvancedTabObject.SetActive(false);
CurrentAdvancedTabObject.Destroy();
}
if (AdvancedWikiTab == null)
{
Warning($"Wiki tab is null.");
return;
}
if (role is ICustomRole custom)
{
CurrentAdvancedTabObject = custom.GetAdvancedWiki(instance, TitleText, AdvancedWikiTab);
CurrentAdvancedTabObject.transform.localPosition = new Vector3(0f, 0f, 0f);
}
else
{
AdvancedWikiTab.ScrollToTop();
CurrentAdvancedTabObject = new GameObject($"{role.Role}");
TitleText.text = role.GetRoleName() + $" ({TranslationController.Instance.GetString(role.TeamType is RoleTeamTypes.Crewmate ? StringNames.Crewmate : StringNames.Impostor)})";
var desc = Object.Instantiate(instance.MatchInfoRolePanelPrefab.roleCount, CurrentAdvancedTabObject.transform);
desc.fontSizeMin = desc.fontSizeMax = desc.fontSize = 2f;
var description = TranslationController.Instance.GetString(role.BlurbNameLong);
if (description.Contains("STRMISS"))
{
var baseName = ($"{role.StringName}").Replace("Role", "");
if (Enum.TryParse<StringNames>($"RolesHelp_{baseName}_01", out var helpName))
{
description = TranslationController.Instance.GetString(helpName);
}
}
desc.text = description;
desc.transform.localPosition = new Vector3(0, 0.925f, 0);
desc.rectTransform.sizeDelta = new Vector2(7.5f, 0.3f);
desc.alignment = TextAlignmentOptions.TopLeft;
CurrentAdvancedTabObject.transform.SetParent(AdvancedWikiTab.Inner.transform);
CurrentAdvancedTabObject.transform.localPosition = new Vector3(0f, 0f, 0f);
}
}
[HarmonyPrefix] [HarmonyPrefix]
[HarmonyPriority(Priority.First)] [HarmonyPriority(Priority.First)]
[HarmonyPatch(typeof(MatchInfoRolePanel), nameof(MatchInfoRolePanel.SetPanel))] [HarmonyPatch(typeof(MatchInfoRolePanel), nameof(MatchInfoRolePanel.SetPanel))]
+21 -1
View File
@@ -6,7 +6,9 @@ using MiraAPI.GameOptions;
using MiraAPI.Modifiers; using MiraAPI.Modifiers;
using MiraAPI.PluginLoading; using MiraAPI.PluginLoading;
using MiraAPI.Translation; using MiraAPI.Translation;
using TMPro;
using UnityEngine; using UnityEngine;
using Object = UnityEngine.Object;
namespace MiraAPI.Roles; namespace MiraAPI.Roles;
@@ -68,7 +70,7 @@ public interface ICustomRole : IOptionable
/// <summary> /// <summary>
/// Gets the wiki description of the role. Used in the wiki, but not currently required. /// Gets the wiki description of the role. Used in the wiki, but not currently required.
/// </summary> /// </summary>
string RoleWikiDescription => MiraLocaleManager.Get(RoleLongDescriptionLocale); string RoleWikiDescription => MiraLocaleManager.Get(RoleWikiDescriptionLocale, RoleLongDescription);
/// <summary> /// <summary>
/// Gets the role's wiki description id for localization. /// Gets the role's wiki description id for localization.
@@ -310,6 +312,24 @@ public interface ICustomRole : IOptionable
/// <returns><see langword="true"/> if the role is always displayed, otherwise <see langword="false"/> if it is never displayable, or <see langword="null"/> if it is dictated by amount and chance.</returns> /// <returns><see langword="true"/> if the role is always displayed, otherwise <see langword="false"/> if it is never displayable, or <see langword="null"/> if it is dictated by amount and chance.</returns>
public virtual bool? ForceShowRoleOnWiki => null; public virtual bool? ForceShowRoleOnWiki => null;
/// <summary>
/// Gets the information to display in the wiki.
/// </summary>
public virtual GameObject GetAdvancedWiki(MatchInfoGuide guide, TextMeshPro titleText, Scroller parent)
{
parent.ScrollToTop();
var obj = new GameObject(RoleNameLocale);
titleText.text = RoleName + $" ({RoleFactionTitle})";
var desc = Object.Instantiate(guide.MatchInfoRolePanelPrefab.roleCount, obj.transform);
desc.fontSizeMin = desc.fontSizeMax = desc.fontSize = 2f;
desc.text = RoleWikiDescription;
desc.transform.localPosition = new Vector3(0, 0.925f, 0);
desc.rectTransform.sizeDelta = new Vector2(7.5f, 0.3f);
desc.alignment = TextAlignmentOptions.TopLeft;
obj.transform.SetParent(parent.Inner.transform);
return obj;
}
/// <summary> /// <summary>
/// Gets the function that determines whether the role should be toggled on or off in the game settings. /// Gets the function that determines whether the role should be toggled on or off in the game settings.
/// </summary> /// </summary>