diff --git a/MiraAPI/Modifiers/BaseModifier.cs b/MiraAPI/Modifiers/BaseModifier.cs
index cf108b3..3daeb56 100644
--- a/MiraAPI/Modifiers/BaseModifier.cs
+++ b/MiraAPI/Modifiers/BaseModifier.cs
@@ -107,17 +107,20 @@ public abstract class BaseModifier : IOptionable
///
/// The guide object.
/// The title text object.
+ /// The title's icon.
/// The scroller parent.
/// The of the wiki.
- public virtual GameObject GetAdvancedWiki(MatchInfoGuide guide, TextMeshPro titleText, Scroller parent)
+ public virtual GameObject GetAdvancedWiki(MatchInfoGuide guide, TextMeshPro titleText, SpriteRenderer titleIcon, Scroller parent)
{
var abilities = WikiAbilities;
return Helpers.CreateAdvancedWikiPage(
guide,
titleText,
+ titleIcon,
parent,
ModifierNameLocale,
- $"{this.GetTmpIcon()} {ModifierName} ({ModifierCategoryTitle})".TrimStart(),
+ $"{ModifierName} ({ModifierCategoryTitle})".TrimStart(),
+ ModifierIcon ?? MiraAssets.IconNeutral.LoadAsset(),
ModifierWikiDescription,
abilities);
}
diff --git a/MiraAPI/Patches/RoleGuidePatches.cs b/MiraAPI/Patches/RoleGuidePatches.cs
index 77f9cf4..92080e8 100644
--- a/MiraAPI/Patches/RoleGuidePatches.cs
+++ b/MiraAPI/Patches/RoleGuidePatches.cs
@@ -55,6 +55,7 @@ public static class RoleGuidePatches
private static TextBoxTMP _searchBoxTmp;
private static GameObject _currentAdvancedTabObject;
private static TextMeshPro _titleText;
+ private static SpriteRenderer _titleIcon;
private static bool _suppressSearchRefresh;
private static IEnumerator? _searchDebounce;
private static string _appliedSearch = string.Empty;
@@ -145,6 +146,7 @@ public static class RoleGuidePatches
_appliedSearch = string.Empty;
_suppressSearchRefresh = false;
_titleText = null!;
+ _titleIcon = null!;
_searchBoxTmp = null!;
_rolesScroller = null!;
_modifiersScroller = null!;
@@ -254,9 +256,18 @@ public static class RoleGuidePatches
_titleText = __instance.transitionOpen.transform.FindChild("Text_Title")?.GetComponent()!;
if (_titleText)
{
+ _titleText.transform.localPosition += new Vector3(0.5f, 0);
_titleText.transform.GetComponent().Destroy();
}
}
+ if (!_titleIcon)
+ {
+ var titleIconObj = new GameObject("TitleIcon");
+ _titleIcon = titleIconObj.AddComponent();
+ _titleIcon.transform.SetParent(_titleText.transform.parent);
+ _titleIcon.transform.localPosition = new Vector3(-2.75f, 1.4f, 0);
+ titleIconObj.layer = _titleText.gameObject.layer;
+ }
if (_titleText)
{
@@ -1247,26 +1258,33 @@ public static class RoleGuidePatches
[HarmonyPatch(typeof(MatchInfoGuide), nameof(MatchInfoGuide.SetActiveTab))]
private static void SetActiveTab(int tabIndex)
{
- if (_titleText)
+ if (_titleText && _titleIcon)
{
switch (tabIndex)
{
case 0:
_titleText.text = MiraLocaleManager.Get("MiraApi.Wiki.PlayersTab");
+ _titleIcon.sprite = MiraAssets.IconPlayerList.LoadAsset();
break;
case 1:
_titleText.text = MiraLocaleManager.Get("MiraApi.Wiki.SettingsTab");
+ _titleIcon.sprite = MiraAssets.IconSettings.LoadAsset();
break;
case RolesTabIndex:
_titleText.text = MiraLocaleManager.Get("Roles");
+ _titleIcon.sprite = GetRandomRoleIcon();
break;
case ModifiersTabIndex:
_titleText.text = MiraLocaleManager.Get("Modifiers");
+ _titleIcon.sprite = GetRandomModifierIcon();
break;
default:
_titleText.text = TranslationController.Instance.GetString(StringNames.MatchInfoGuideTitle);
+ _titleIcon.sprite = MiraAssets.IconPlayerList.LoadAsset();
break;
}
+
+ _titleIcon.SetSizeLimit(0.55f);
}
_advancedInfoTabScroller?.gameObject.SetActive(false);
@@ -1274,6 +1292,45 @@ public static class RoleGuidePatches
UpdateSpinner();
}
+ public static Sprite GetRandomModifierIcon()
+ {
+ var activeMods = PlayerControl.LocalPlayer.GetModifiers()
+ .Where(x => !x.HideOnUi && x.ModifierIcon != null).ToList();
+ if (activeMods.Count > 0)
+ {
+ return activeMods.Random()!.ModifierIcon!.LoadAsset();
+ }
+
+ return GetRandomFactionIcon();
+ }
+
+ public static Sprite GetRandomRoleIcon()
+ {
+ var aliveRole = PlayerControl.LocalPlayer.Data?.Role;
+ if (aliveRole != null && aliveRole.RoleIconSolid != null)
+ {
+ return aliveRole.RoleIconSolid;
+ }
+
+ return GetRandomFactionIcon();
+ }
+
+ public static Sprite GetRandomFactionIcon()
+ {
+ var random = UnityEngine.Random.Range(1, 4);
+ if (random == 1)
+ {
+ return MiraAssets.IconCrewmate.LoadAsset();
+ }
+
+ if (random == 2)
+ {
+ return MiraAssets.IconImpostor.LoadAsset();
+ }
+
+ return MiraAssets.IconNeutral.LoadAsset();
+ }
+
private static bool TryPrepareAdvancedWiki(MatchInfoGuide instance)
{
instance.settingsTabs[RolesTabIndex].SetActive(false);
@@ -1325,7 +1382,7 @@ public static class RoleGuidePatches
return;
}
- _currentAdvancedTabObject = modifier.GetAdvancedWiki(instance, _titleText, _advancedInfoTabScroller);
+ _currentAdvancedTabObject = modifier.GetAdvancedWiki(instance, _titleText, _titleIcon, _advancedInfoTabScroller);
}
public static void DisplayAdvancedWiki(MatchInfoGuide instance, RoleBehaviour role)
@@ -1345,11 +1402,11 @@ public static class RoleGuidePatches
if (role is ICustomRole custom)
{
- _currentAdvancedTabObject = custom.GetAdvancedWiki(instance, _titleText, _advancedInfoTabScroller);
+ _currentAdvancedTabObject = custom.GetAdvancedWiki(instance, _titleText, _titleIcon, _advancedInfoTabScroller);
}
else
{
- var titleTxt = $"{role.GetTmpIcon()} {role.GetRoleName()}" +
+ var titleTxt = $"{role.GetRoleName()}" +
$" ({TranslationController.Instance.GetString(role.TeamType is RoleTeamTypes.Crewmate ? StringNames.Crewmate : StringNames.Impostor)})";
var description = TranslationController.Instance.GetString(role.BlurbNameLong);
if (description.Contains("STRMISS"))
@@ -1364,9 +1421,11 @@ public static class RoleGuidePatches
_currentAdvancedTabObject = Helpers.CreateAdvancedWikiPage(
instance,
_titleText,
+ _titleIcon,
_advancedInfoTabScroller,
role.Role.ToString(),
titleTxt,
+ role.RoleIconColor,
description,
[]);
}
diff --git a/MiraAPI/Resources/Wiki/IconCrewmate.png b/MiraAPI/Resources/Wiki/IconCrewmate.png
new file mode 100644
index 0000000..61f706f
Binary files /dev/null and b/MiraAPI/Resources/Wiki/IconCrewmate.png differ
diff --git a/MiraAPI/Resources/Wiki/IconImpostor.png b/MiraAPI/Resources/Wiki/IconImpostor.png
new file mode 100644
index 0000000..6100cd1
Binary files /dev/null and b/MiraAPI/Resources/Wiki/IconImpostor.png differ
diff --git a/MiraAPI/Resources/Wiki/IconNeutral.png b/MiraAPI/Resources/Wiki/IconNeutral.png
new file mode 100644
index 0000000..984041c
Binary files /dev/null and b/MiraAPI/Resources/Wiki/IconNeutral.png differ
diff --git a/MiraAPI/Resources/Wiki/IconPlayerList.png b/MiraAPI/Resources/Wiki/IconPlayerList.png
new file mode 100644
index 0000000..234baa0
Binary files /dev/null and b/MiraAPI/Resources/Wiki/IconPlayerList.png differ
diff --git a/MiraAPI/Resources/Wiki/IconSettings.png b/MiraAPI/Resources/Wiki/IconSettings.png
new file mode 100644
index 0000000..50452dc
Binary files /dev/null and b/MiraAPI/Resources/Wiki/IconSettings.png differ
diff --git a/MiraAPI/Resources/Wiki/IconTerminology.png b/MiraAPI/Resources/Wiki/IconTerminology.png
new file mode 100644
index 0000000..8b95d62
Binary files /dev/null and b/MiraAPI/Resources/Wiki/IconTerminology.png differ
diff --git a/MiraAPI/Roles/ICustomRole.cs b/MiraAPI/Roles/ICustomRole.cs
index 307b6ca..4d5e247 100644
--- a/MiraAPI/Roles/ICustomRole.cs
+++ b/MiraAPI/Roles/ICustomRole.cs
@@ -318,17 +318,20 @@ public interface ICustomRole : IOptionable
///
/// The guide object.
/// The title text object.
+ /// The title's icon.
/// The scroller parent.
/// The of the wiki.
- GameObject GetAdvancedWiki(MatchInfoGuide guide, TextMeshPro titleText, Scroller parent)
+ GameObject GetAdvancedWiki(MatchInfoGuide guide, TextMeshPro titleText, SpriteRenderer titleIcon, Scroller parent)
{
var abilities = WikiAbilities;
return Helpers.CreateAdvancedWikiPage(
guide,
titleText,
+ titleIcon,
parent,
RoleNameLocale,
- $"{this.GetTmpIcon()} {RoleName} ({RoleFactionTitle})",
+ $"{RoleName} ({RoleFactionTitle})",
+ Configuration.Icon ?? MiraAssets.IconNeutral.LoadAsset(),
RoleWikiDescription,
abilities);
}
diff --git a/MiraAPI/Utilities/Assets/MiraAssets.cs b/MiraAPI/Utilities/Assets/MiraAssets.cs
index a57332b..0feb75c 100644
--- a/MiraAPI/Utilities/Assets/MiraAssets.cs
+++ b/MiraAPI/Utilities/Assets/MiraAssets.cs
@@ -305,5 +305,35 @@ public static class MiraAssets
///
public static LoadableResourceAsset VisibleOnIdleSprite { get; } = new("MiraAPI.Resources.Wiki.VisibleOnIdle.png");
+ ///
+ /// Gets the sprite used for crewmates.
+ ///
+ public static LoadableResourceAsset IconCrewmate { get; } = new("MiraAPI.Resources.Wiki.IconCrewmate.png");
+
+ ///
+ /// Gets the sprite used for impostors.
+ ///
+ public static LoadableResourceAsset IconImpostor { get; } = new("MiraAPI.Resources.Wiki.IconImpostor.png");
+
+ ///
+ /// Gets the sprite used for neutrals.
+ ///
+ public static LoadableResourceAsset IconNeutral { get; } = new("MiraAPI.Resources.Wiki.IconNeutral.png");
+
+ ///
+ /// Gets the sprite used for the player list.
+ ///
+ public static LoadableResourceAsset IconPlayerList { get; } = new("MiraAPI.Resources.Wiki.IconPlayerList.png");
+
+ ///
+ /// Gets the sprite used for settings.
+ ///
+ public static LoadableResourceAsset IconSettings { get; } = new("MiraAPI.Resources.Wiki.IconSettings.png");
+
+ ///
+ /// Gets the sprite used for terminology.
+ ///
+ public static LoadableResourceAsset IconTerminology { get; } = new("MiraAPI.Resources.Wiki.IconTerminology.png");
+
internal static LoadableResourceAsset BlankSprite { get; } = new("MiraAPI.Resources.BlankSprite.png");
}
diff --git a/MiraAPI/Utilities/Helpers.cs b/MiraAPI/Utilities/Helpers.cs
index 4587f36..773a4ae 100644
--- a/MiraAPI/Utilities/Helpers.cs
+++ b/MiraAPI/Utilities/Helpers.cs
@@ -741,15 +741,19 @@ public static class Helpers
/// The guide panel to attach the tab to.
/// The name of the tab.
/// The title of the tab.
+ /// The icon of the page.
/// The description of the tab.
/// The instance of the title.
+ /// The instance for the title.
/// The instance of the description.
/// The of the tab.
- public static GameObject CreateAdvancedWikiTab(MatchInfoGuide guide, string objName, string title, string description, TextMeshPro titleTmp, out TextMeshPro descriptionTmp)
+ public static GameObject CreateAdvancedWikiTab(MatchInfoGuide guide, string objName, string title, Sprite icon, string description, TextMeshPro titleTmp, SpriteRenderer titleIcon, out TextMeshPro descriptionTmp)
{
var obj = new GameObject(objName);
titleTmp.richText = true;
titleTmp.text = title;
+ titleIcon.sprite = icon;
+ titleIcon.SetSizeLimit(0.55f);
descriptionTmp = Object.Instantiate(guide.MatchInfoRolePanelPrefab.roleCount, obj.transform);
descriptionTmp.fontSizeMin = descriptionTmp.fontSizeMax = descriptionTmp.fontSize = 2f;
var sourceTmp = HudManager.Instance.TaskPanel.taskText;
@@ -769,9 +773,11 @@ public static class Helpers
///
/// The guide object.
/// The instance of the title.
+ /// The instance for the title.
/// The the page should be parented to.
/// The name of the page object.
/// The title of the page.
+ /// The icon of the page.
/// The description of the page.
/// The abilities to display in a grid below the description.
/// Whether to use variable text sizing for ability descriptions (allows different heights).
@@ -779,9 +785,11 @@ public static class Helpers
public static GameObject CreateAdvancedWikiPage(
MatchInfoGuide guide,
TextMeshPro titleTmp,
+ SpriteRenderer titleIcon,
Scroller parent,
string objName,
string title,
+ Sprite icon,
string description,
IReadOnlyCollection abilities,
bool variableTextSizing = false)
@@ -791,8 +799,10 @@ public static class Helpers
guide,
objName,
title,
+ icon,
description,
titleTmp,
+ titleIcon,
out var desc);
var num = 0;
var maxTextSize = 0f;