diff --git a/MiraAPI.Example/Roles/CustomRole.cs b/MiraAPI.Example/Roles/CustomRole.cs index 44dfbe8..9226020 100644 --- a/MiraAPI.Example/Roles/CustomRole.cs +++ b/MiraAPI.Example/Roles/CustomRole.cs @@ -10,8 +10,8 @@ public class CustomRole : ImpostorRole, ICustomRole public string RoleName => "fortnite killer"; public string RoleLongDescription => "ok so your objective is to eliminate everyone with your fortnite tactical shotgun, good luck"; public string RoleDescription => RoleLongDescription; - public Color RoleColor => Palette.Orange; + public Color RoleColor => Palette.Black; public ModdedRoleTeams Team => ModdedRoleTeams.Impostor; public LoadableAsset OptionsScreenshot => MiraAssets.Banner; - + } \ No newline at end of file diff --git a/MiraAPI/GameOptions/OptionTypes/ModdedToggleOption.cs b/MiraAPI/GameOptions/OptionTypes/ModdedToggleOption.cs index a29e648..15b920e 100644 --- a/MiraAPI/GameOptions/OptionTypes/ModdedToggleOption.cs +++ b/MiraAPI/GameOptions/OptionTypes/ModdedToggleOption.cs @@ -1,5 +1,5 @@ -using System; -using MiraAPI.Networking; +using MiraAPI.Networking; +using System; using UnityEngine; using Object = UnityEngine.Object; @@ -7,7 +7,7 @@ namespace MiraAPI.GameOptions.OptionTypes; public class ModdedToggleOption : ModdedOption { - public ModdedToggleOption(string title, bool defaultValue, Type roleType=null) : base(title, defaultValue, roleType) + public ModdedToggleOption(string title, bool defaultValue, Type roleType = null) : base(title, defaultValue, roleType) { Data = ScriptableObject.CreateInstance(); diff --git a/MiraAPI/Patches/Options/GameOptionsMenuPatch.cs b/MiraAPI/Patches/Options/GameOptionsMenuPatch.cs index 06b46e1..d446f8e 100644 --- a/MiraAPI/Patches/Options/GameOptionsMenuPatch.cs +++ b/MiraAPI/Patches/Options/GameOptionsMenuPatch.cs @@ -41,7 +41,7 @@ public static class GameOptionsMenuPatch if (group.GroupColor != Color.clear) { categoryHeaderMasked.Background.color = group.GroupColor; - categoryHeaderMasked.Title.color = group.GroupColor.DarkenColor(); + categoryHeaderMasked.Title.color = group.GroupColor.GetAlternateColor(); } categoryHeaderMasked.transform.localScale = Vector3.one * 0.63f; categoryHeaderMasked.transform.localPosition = new Vector3(-0.903f, num, -2f); @@ -58,7 +58,12 @@ public static class GameOptionsMenuPatch { if (group.GroupColor != Color.clear) { - componentsInChildren[i].color = group.GroupColor; + componentsInChildren[i].color = group.GroupColor.GetAlternateColor(); + if (componentsInChildren[i].transform.parent.TryGetComponent(out var btn)) + { + btn.interactableColor = group.GroupColor.GetAlternateColor(); + btn.interactableHoveredColor = Color.white; + } } componentsInChildren[i].material.SetInt(PlayerMaterial.MaskLayer, 20); @@ -68,7 +73,7 @@ public static class GameOptionsMenuPatch { if (group.GroupColor != Color.clear) { - textMeshPro.color = group.GroupColor.DarkenColor(); + textMeshPro.color = group.GroupColor; } textMeshPro.fontMaterial.SetFloat(ShaderID.StencilComp, 3f); diff --git a/MiraAPI/Patches/Options/RoleSettingMenuPatches.cs b/MiraAPI/Patches/Options/RoleSettingMenuPatches.cs index cd25881..81c9522 100644 --- a/MiraAPI/Patches/Options/RoleSettingMenuPatches.cs +++ b/MiraAPI/Patches/Options/RoleSettingMenuPatches.cs @@ -131,7 +131,7 @@ public static class RoleSettingMenuPatches return false; } - + [HarmonyPostfix] [HarmonyPatch(nameof(RolesSettingsMenu.OpenChancesTab))] public static void OpenChancesTabPostfix(RolesSettingsMenu __instance) @@ -139,7 +139,7 @@ public static class RoleSettingMenuPatches __instance.scrollBar.CalculateAndSetYBounds(__instance.roleChances.Count + 5, 1f, 6f, 0.43f); __instance.scrollBar.ScrollToTop(); } - + private static void ValueChanged(OptionBehaviour obj) { var roleSetting = obj.Cast(); @@ -225,7 +225,7 @@ public static class RoleSettingMenuPatches __instance.roleScreenshot.sprite = Sprite.Create(customRole.OptionsScreenshot.LoadAsset().texture, new Rect(0, 0, 370, 230), Vector2.one / 2, 100); __instance.roleScreenshot.drawMode = SpriteDrawMode.Sliced; __instance.roleHeaderSprite.color = customRole.RoleColor; - __instance.roleHeaderText.color = customRole.RoleColor.DarkenColor(); + __instance.roleHeaderText.color = customRole.RoleColor.GetAlternateColor(); CreateAdvancedSettings(__instance, role); @@ -249,12 +249,14 @@ public static class RoleSettingMenuPatches roleOptionSetting.transform.localPosition = new Vector3(-0.15f, yPos, -2f); roleOptionSetting.SetRole(GameOptionsManager.Instance.CurrentGameOptions.RoleOptions, role, 20); roleOptionSetting.labelSprite.color = customRole.RoleColor; - roleOptionSetting.titleText.color = customRole.RoleColor.DarkenColor(); roleOptionSetting.OnValueChanged = new Action(ValueChanged); - roleOptionSetting.titleText.horizontalAlignment = HorizontalAlignmentOptions.Left; roleOptionSetting.SetClickMask(__instance.ButtonClickMask); __instance.roleChances.Add(roleOptionSetting); + roleOptionSetting.titleText.transform.localPosition = new Vector3(-0.5376f, -0.2923f, 0f); + roleOptionSetting.titleText.color = customRole.RoleColor.GetAlternateColor(); + roleOptionSetting.titleText.horizontalAlignment = HorizontalAlignmentOptions.Left; + PassiveButton newButton = Object.Instantiate(roleOptionSetting.buttons[0], roleOptionSetting.transform); newButton.name = "ConfigButton"; newButton.transform.localPosition = new Vector3(0.4473f, -0.3f, -2f); @@ -263,12 +265,11 @@ public static class RoleSettingMenuPatches SpriteRenderer btnRend = newButton.transform.FindChild("ButtonSprite").GetComponent(); btnRend.sprite = MiraAssets.Cog.LoadAsset(); - btnRend.color = customRole.RoleColor.DarkenColor(); - PassiveButton passiveButton = newButton.GetComponent(); + GameOptionButton passiveButton = newButton.GetComponent(); passiveButton.OnClick = new ButtonClickedEvent(); - passiveButton.disabledTextColor = customRole.RoleColor.DarkenColor(); - passiveButton.selectedTextColor = customRole.RoleColor.DarkenColor().DarkenColor(); + passiveButton.interactableColor = btnRend.color = customRole.RoleColor.GetAlternateColor(); + passiveButton.interactableHoveredColor = Color.white; passiveButton.OnClick.AddListener((UnityAction)(() => { diff --git a/MiraAPI/Patches/Roles/EjectionPatches.cs b/MiraAPI/Patches/Roles/EjectionPatches.cs index 60c0dfe..bbea1e8 100644 --- a/MiraAPI/Patches/Roles/EjectionPatches.cs +++ b/MiraAPI/Patches/Roles/EjectionPatches.cs @@ -6,12 +6,12 @@ namespace MiraAPI.Patches.Roles; [HarmonyPatch(typeof(ExileController))] public static class EjectionPatches { - + [HarmonyPostfix] [HarmonyPatch(nameof(ExileController.Begin))] public static void Begin(ExileController __instance) { - if (!__instance.initData.networkedPlayer.Role || __instance.initData.networkedPlayer.Role is not ICustomRole role) + if (!__instance.initData.networkedPlayer || !__instance.initData.networkedPlayer.Role || __instance.initData.networkedPlayer.Role is not ICustomRole role) { return; } @@ -20,7 +20,7 @@ public static class EjectionPatches { return; } - + __instance.completeString = role.GetCustomEjectionMessage(__instance.initData.networkedPlayer); } } \ No newline at end of file diff --git a/MiraAPI/PluginLoading/MiraPluginManager.cs b/MiraAPI/PluginLoading/MiraPluginManager.cs index 1124be9..f4075e8 100644 --- a/MiraAPI/PluginLoading/MiraPluginManager.cs +++ b/MiraAPI/PluginLoading/MiraPluginManager.cs @@ -3,25 +3,27 @@ using BepInEx.Unity.IL2CPP; using Il2CppInterop.Runtime.Injection; using MiraAPI.GameOptions; using MiraAPI.GameOptions.Attributes; +using MiraAPI.Hud; using MiraAPI.Roles; +using MiraAPI.Utilities.Colors; using Reactor.Utilities; using System; using System.Collections.Generic; using System.Linq; using System.Reflection; -using MiraAPI.Hud; namespace MiraAPI.PluginLoading; internal class MiraPluginManager { public readonly Dictionary RegisteredPlugins = []; - + private static MiraPluginManager _instance; - - public static MiraPluginManager Instance { + + public static MiraPluginManager Instance + { get => _instance ??= new MiraPluginManager(); - private set => _instance = value; + private set => _instance = value; } internal void Initialize() @@ -38,10 +40,12 @@ internal class MiraPluginManager var info = new MiraPluginInfo(id, plugin as IMiraPlugin, IL2CPPChainloader.Instance.Plugins[id]); RegisterAllOptions(assembly, info); - + RegisterRoleAttribute(assembly, info); RegisterButtonAttribute(assembly); + RegisterAllColors(assembly); + RegisteredPlugins.Add(assembly, info); Logger.Info($"Registering mod {id} with Mira API."); @@ -56,14 +60,14 @@ internal class MiraPluginManager private static void RegisterAllOptions(Assembly assembly, MiraPluginInfo pluginInfo) { var filteredTypes = assembly.GetTypes().Where(type => type.IsAssignableTo(typeof(AbstractOptionGroup))); - + foreach (var type in filteredTypes) { if (!ModdedOptionsManager.RegisterGroup(type, pluginInfo)) { continue; } - + foreach (var property in type.GetProperties()) { if (property.PropertyType.IsAssignableTo(typeof(IModdedOption))) @@ -71,7 +75,7 @@ internal class MiraPluginManager ModdedOptionsManager.RegisterPropertyOption(type, property, pluginInfo); continue; } - + var attribute = property.GetCustomAttribute(); if (attribute == null) { @@ -109,12 +113,31 @@ internal class MiraPluginManager { Logger.Error($"{k}: {v}"); } - + Logger.Error(e); } } } + private static void RegisterAllColors(Assembly assembly) + { + foreach (var type in assembly.GetTypes()) + { + foreach (FieldInfo field in type.GetFields()) + { + foreach (var attribute in field.GetCustomAttributes()) + { + if (attribute.GetType().BaseType == typeof(RegisterColorAttribute)) + { + /* Palette.PlayerColors = Palette.PlayerColors.ToArray().AddToArray(); + Palette.ShadowColors = Palette.ShadowColors.ToArray().AddToArray(); + Palette.ColorNames = Palette.ColorNames.ToArray().AddToArray();*/ + } + } + } + } + } + private static void RegisterButtonAttribute(Assembly assembly) { foreach (var type in assembly.GetTypes()) diff --git a/MiraAPI/Utilities/Colors/CustomColor.cs b/MiraAPI/Utilities/Colors/CustomColor.cs new file mode 100644 index 0000000..99ebbdb --- /dev/null +++ b/MiraAPI/Utilities/Colors/CustomColor.cs @@ -0,0 +1,30 @@ +using UnityEngine; + +namespace MiraAPI.Utilities; +public class CustomColor +{ + public CustomColor(Color32 mainColor, StringNames name) + { + MainColor = mainColor; + ShadowColor = GetShadowColor(mainColor, 60); + Name = name; + } + + public CustomColor(Color32 mainColor, Color32 shadowColor, StringNames name) + { + MainColor = mainColor; + ShadowColor = shadowColor; + Name = name; + } + + public Color32 MainColor { get; } + public Color32 ShadowColor { get; } + public StringNames Name { get; } + + public static Color32 GetShadowColor(Color32 c, byte darknessAmount) + { + return + new Color32((byte)Mathf.Clamp(c.r - darknessAmount, 0, 255), (byte)Mathf.Clamp(c.g - darknessAmount, 0, 255), + (byte)Mathf.Clamp(c.b - darknessAmount, 0, 255), byte.MaxValue); + } +} \ No newline at end of file diff --git a/MiraAPI/Utilities/Colors/RegisterColorAttribute.cs b/MiraAPI/Utilities/Colors/RegisterColorAttribute.cs new file mode 100644 index 0000000..f80a7f2 --- /dev/null +++ b/MiraAPI/Utilities/Colors/RegisterColorAttribute.cs @@ -0,0 +1,6 @@ +using System; + +namespace MiraAPI.Utilities.Colors; + +[AttributeUsage(AttributeTargets.Field)] +public class RegisterColorAttribute : Attribute; \ No newline at end of file diff --git a/MiraAPI/Utilities/Extensions.cs b/MiraAPI/Utilities/Extensions.cs index e80e0b2..3ee4b85 100644 --- a/MiraAPI/Utilities/Extensions.cs +++ b/MiraAPI/Utilities/Extensions.cs @@ -17,6 +17,21 @@ public static class Extensions { return new Color(color.r - 0.3f, color.g - 0.3f, color.b - 0.3f); } + public static Color GetAlternateColor(this Color color) + { + return color.IsColorDark() ? LightenColor(color) : DarkenColor(color); + } + + public static Color LightenColor(this Color color) + { + return new Color(color.r + 0.3f, color.g + 0.3f, color.b + 0.3f); + } + + public static bool IsColorDark(this Color color) + { + return color.r < 0.5f && color.g < 0.5f && color.b < 0.5f; + } + public static void UpdateBodies(this PlayerControl playerControl, Color outlineColor, ref DeadBody target) { foreach (var body in Object.FindObjectsOfType())