diff --git a/Images/TOR_colors.jpg b/Images/TOR_colors.jpg index 2a7134711..86e48f66c 100644 Binary files a/Images/TOR_colors.jpg and b/Images/TOR_colors.jpg differ diff --git a/README.md b/README.md index 4c02ef374..a14e50b9b 100644 --- a/README.md +++ b/README.md @@ -42,6 +42,7 @@ The [Role Assignment](#role-assignment) sections explains how the roles are bein # Releases | Among Us - Version| Mod Version | Link | |----------|-------------|-----------------| +| 2023.07.12s| v4.4.2| [Download](https://github.com/TheOtherRolesAU/TheOtherRoles/releases/download/v4.4.2/TheOtherRoles.zip) | 2023.07.12s| v4.4.1| [Download](https://github.com/TheOtherRolesAU/TheOtherRoles/releases/download/v4.4.1/TheOtherRoles.zip) | 2023.07.12s| v4.4.0| [Download](https://github.com/TheOtherRolesAU/TheOtherRoles/releases/download/v4.4.0/TheOtherRoles.zip) | 2023.07.12s| v4.3.4| [Download](https://github.com/Eisbison/TheOtherRoles/releases/download/v4.3.4/TheOtherRoles.zip) @@ -127,6 +128,10 @@ The [Role Assignment](#role-assignment) sections explains how the roles are bein
Click to show the Changelog +**Version 4.4.2** +- Added 10 new colors and adapted some existing ones (thanks to Avlona & Listoric for sorting our colors!) +- Added a message of the day feature in the main menu. Look out for interesting news and lame jokes! + **Version 4.4.1** - Fixed a bug where PropHunt buttons did not work for the Hunters after watching the intro cutscene. @@ -896,6 +901,8 @@ Here are a few instructions, on how to create a custom hat: # Colors Note: Lighter and Darker colors are no longer based on the players color. Instead they are assigned alternatingly, s.t. they are always balanced in a lobby. + +A big thank you goes to Avlona & Listoric for sorting the colors in the best possible order (which is surprisingly hard to do)! ![TOR Colors](./Images/TOR_colors.jpg) # Roles diff --git a/TheOtherRoles/Helpers.cs b/TheOtherRoles/Helpers.cs index 21a2d7536..f333bf3db 100644 --- a/TheOtherRoles/Helpers.cs +++ b/TheOtherRoles/Helpers.cs @@ -45,7 +45,7 @@ public static Sprite loadSpriteFromResources(string path, float pixelsPerUnit, b if (cache) sprite.hideFlags |= HideFlags.HideAndDontSave | HideFlags.DontSaveInEditor; if (!cache) return sprite; return CachedSprites[path + pixelsPerUnit] = sprite; - } catch (Exception e) { + } catch { System.Console.WriteLine("Error loading sprite from path: " + path); } return null; diff --git a/TheOtherRoles/Main.cs b/TheOtherRoles/Main.cs index f72a597f3..11a1b2f9e 100644 --- a/TheOtherRoles/Main.cs +++ b/TheOtherRoles/Main.cs @@ -31,7 +31,7 @@ namespace TheOtherRoles public class TheOtherRolesPlugin : BasePlugin { public const string Id = "me.eisbison.theotherroles"; - public const string VersionString = "4.4.1"; + public const string VersionString = "4.4.2"; public static uint betaDays = 0; // amount of days for the build to be usable (0 for infinite!) public static Version Version = Version.Parse(VersionString); @@ -92,6 +92,7 @@ public override void Load() { Instance = this; _ = Helpers.checkBeta(); // Exit if running an expired beta + _ = Patches.CredentialsPatch.MOTD.loadMOTDs(); DebugMode = Config.Bind("Custom", "Enable Debug Mode", "false"); GhostsSeeInformation = Config.Bind("Custom", "Ghosts See Remaining Tasks", true); @@ -125,7 +126,7 @@ public override void Load() { SubmergedCompatibility.Initialize(); AddComponent(); Modules.MainMenuPatch.addSceneChangeCallbacks(); - + _ = RoleInfo.loadReadme(); TheOtherRolesPlugin.Logger.LogInfo("Loading TOR completed!"); } public static Sprite GetModStamp() { diff --git a/TheOtherRoles/Modules/ChatCommands.cs b/TheOtherRoles/Modules/ChatCommands.cs index 2ede8ec2e..d33f863cf 100644 --- a/TheOtherRoles/Modules/ChatCommands.cs +++ b/TheOtherRoles/Modules/ChatCommands.cs @@ -64,6 +64,15 @@ static bool Prefix(ChatController __instance) { } } + if (text.ToLower().StartsWith("/role")) { + RoleInfo localRole = RoleInfo.getRoleInfoForPlayer(CachedPlayer.LocalPlayer.PlayerControl, false).FirstOrDefault(); + if (localRole != RoleInfo.impostor && localRole != RoleInfo.crewmate) { + string info = RoleInfo.GetRoleDescription(localRole); + __instance.AddChat(CachedPlayer.LocalPlayer.PlayerControl, info); + handled = true; + } + } + if (handled) { __instance.freeChatField.Clear(); __instance.quickChatMenu.Clear(); diff --git a/TheOtherRoles/Modules/CustomColors.cs b/TheOtherRoles/Modules/CustomColors.cs index 5dd1da2c3..9653b01e6 100644 --- a/TheOtherRoles/Modules/CustomColors.cs +++ b/TheOtherRoles/Modules/CustomColors.cs @@ -10,14 +10,13 @@ public class CustomColors { protected static Dictionary ColorStrings = new Dictionary(); public static List lighterColors = new List(){ 3, 4, 5, 7, 10, 11, 13, 14, 17 }; public static uint pickableColors = (uint)Palette.ColorNames.Length; - - private static readonly List ORDER = new List() { 7, 14, 5, 33, 4, - 30, 0, 19, 27, 3, - 17, 25, 18, 13, 23, - 8, 32, 1, 21, 31, - 10, 34, 15, 28, 22, - 29, 11, 2, 26, 16, - 20, 24, 9, 12, 6 }; + private static readonly List ORDER = new List() { 7, 37, 14, 5, 33, 41, 25, + 4, 30, 0, 35, 3, 27, 17, + 13, 23, 8, 32, 38, 1, 21, + 40, 31, 10, 34, 22, 28, 36, + 2, 11, 26, 29, 20, 19, 18, + 12, 9, 24, 16, 15, 6, 39, + }; public static void Load() { List longlist = Enumerable.ToList(Palette.ColorNames); List colorlist = Enumerable.ToList(Palette.PlayerColors); @@ -25,20 +24,23 @@ public static void Load() { List colors = new List(); - /* Custom Colors */ - colors.Add(new CustomColor { longname = "Salmon", - color = new Color32(239, 191, 192, byte.MaxValue), // color = new Color32(0xD8, 0x82, 0x83, byte.MaxValue), - shadow = new Color32(182, 119, 114, byte.MaxValue), // shadow = new Color32(0xA5, 0x63, 0x65, byte.MaxValue), - isLighterColor = true }); - colors.Add(new CustomColor { longname = "Bordeaux", - color = new Color32(109, 7, 26, byte.MaxValue), - shadow = new Color32(54, 2, 11, byte.MaxValue), - isLighterColor = false }); + /* Custom Colors, starting with id (for ORDER) 18 */ + colors.Add(new CustomColor { + longname = "Tamarind", //18 + color = new Color32(48, 28, 34, byte.MaxValue), + shadow = new Color32(30, 11, 16, byte.MaxValue), + isLighterColor = true }); + colors.Add(new CustomColor { + longname = "Army", // 19 + color = new Color32(39, 45, 31, byte.MaxValue), + shadow = new Color32(11, 30, 24, byte.MaxValue), + isLighterColor = false }); + // 20 colors.Add(new CustomColor { longname = "Olive", color = new Color32(154, 140, 61, byte.MaxValue), shadow = new Color32(104, 95, 40, byte.MaxValue), - isLighterColor = false }); - colors.Add(new CustomColor { longname = "Turqoise", + isLighterColor = true }); + colors.Add(new CustomColor { longname = "Turquoise", color = new Color32(22, 132, 176, byte.MaxValue), shadow = new Color32(15, 89, 117, byte.MaxValue), isLighterColor = false }); @@ -54,6 +56,7 @@ public static void Load() { color = new Color32(160, 101, 56, byte.MaxValue), shadow = new Color32(115, 15, 78, byte.MaxValue), isLighterColor = false }); + // 25 colors.Add(new CustomColor { longname = "Peach", color = new Color32(255, 164, 119, byte.MaxValue), shadow = new Color32(238, 128, 100, byte.MaxValue), @@ -74,44 +77,85 @@ public static void Load() { color = new Color32(0xDB, 0xFD, 0x2F, byte.MaxValue), shadow = new Color32(0x74, 0xE5, 0x10, byte.MaxValue), isLighterColor = true }); + // 30 colors.Add(new CustomColor { longname = "Signal\nOrange", color = new Color32(0xF7, 0x44, 0x17, byte.MaxValue), shadow = new Color32(0x9B, 0x2E, 0x0F, byte.MaxValue), isLighterColor = true }); - colors.Add(new CustomColor { longname = "Teal", color = new Color32(0x25, 0xB8, 0xBF, byte.MaxValue), shadow = new Color32(0x12, 0x89, 0x86, byte.MaxValue), - isLighterColor = false }); + isLighterColor = true }); colors.Add(new CustomColor { longname = "Blurple", - color = new Color32(0x59, 0x3C, 0xD6, byte.MaxValue), - shadow = new Color32(0x29, 0x17, 0x96, byte.MaxValue), + color = new Color32(61, 44, 142, byte.MaxValue), + shadow = new Color32(25, 14, 90, byte.MaxValue), isLighterColor = false }); colors.Add(new CustomColor { longname = "Sunrise", color = new Color32(0xFF, 0xCA, 0x19, byte.MaxValue), shadow = new Color32(0xDB, 0x44, 0x42, byte.MaxValue), isLighterColor = true }); - colors.Add(new CustomColor { longname = "Ice", color = new Color32(0xA8, 0xDF, 0xFF, byte.MaxValue), shadow = new Color32(0x59, 0x9F, 0xC8, byte.MaxValue), - isLighterColor = true }); - + isLighterColor = true }); + // 35 + colors.Add(new CustomColor { longname = "Fuchsia", //35 Color Credit: LaikosVK + color = new Color32(164, 17, 129, byte.MaxValue), + shadow = new Color32(104, 3, 79, byte.MaxValue), + isLighterColor = false + }); + colors.Add(new CustomColor { longname = "Royal\nGreen", //36 + color = new Color32(9, 82, 33, byte.MaxValue), + shadow = new Color32(0, 46, 8, byte.MaxValue), + isLighterColor = false + }); + colors.Add(new CustomColor { longname = "Slime", + color = new Color32(244, 255, 188, byte.MaxValue), + shadow = new Color32(167, 239, 112, byte.MaxValue), + isLighterColor = false + }); + colors.Add(new CustomColor { longname = "Navy", //38 + color = new Color32(9, 43, 119, byte.MaxValue), + shadow = new Color32(0, 13, 56, byte.MaxValue), + isLighterColor = false + }); + colors.Add(new CustomColor { longname = "Darkness", //39 + color = new Color32(36, 39, 40, byte.MaxValue), + shadow = new Color32(10, 10, 10, byte.MaxValue), + isLighterColor = false + }); + colors.Add(new CustomColor { + longname = "Ocean", //40 + color = new Color32(55, 159, 218, byte.MaxValue), + shadow = new Color32(62, 92, 158, byte.MaxValue), + isLighterColor = false + }); + colors.Add(new CustomColor { + longname = "Sundown", // 41 + color = new Color32(252, 194, 100, byte.MaxValue), + shadow = new Color32(197, 98, 54, byte.MaxValue), + isLighterColor = false + }); pickableColors += (uint)colors.Count; // Colors to show in Tab /** Hidden Colors **/ /** Add Colors **/ int id = 50000; + foreach (var c in Palette.PlayerColors) { + TheOtherRolesPlugin.Logger.LogMessage(c); + } foreach (CustomColor cc in colors) { longlist.Add((StringNames)id); CustomColors.ColorStrings[id++] = cc.longname; colorlist.Add(cc.color); + TheOtherRolesPlugin.Logger.LogMessage(cc.color); shadowlist.Add(cc.shadow); if (cc.isLighterColor) lighterColors.Add(colorlist.Count - 1); } + Palette.ColorNames = longlist.ToArray(); Palette.PlayerColors = colorlist.ToArray(); @@ -149,15 +193,15 @@ private static class PlayerTabEnablePatch { public static void Postfix(PlayerTab __instance) { // Replace instead Il2CppArrayBase chips = __instance.ColorChips.ToArray(); - int cols = 5; // TODO: Design an algorithm to dynamically position chips to optimally fill space + int cols = 7; // TODO: Design an algorithm to dynamically position chips to optimally fill space for (int i = 0; i < ORDER.Count; i++) { int pos = ORDER[i]; if (pos < 0 || pos > chips.Length) continue; ColorChip chip = chips[pos]; int row = i / cols, col = i % cols; // Dynamically do the positioning - chip.transform.localPosition = new Vector3(-0.975f + (col * 0.485f), 1.475f - (row * 0.49f), chip.transform.localPosition.z); - chip.transform.localScale *= 0.78f; + chip.transform.localPosition = new Vector3(-0.975f + (col * 0.5f), 1.475f - (row * 0.5f), chip.transform.localPosition.z); + chip.transform.localScale *= 0.76f; } for (int j = ORDER.Count; j < chips.Length; j++) { // If number isn't in order, hide it ColorChip chip = chips[j]; diff --git a/TheOtherRoles/Patches/CredentialsPatch.cs b/TheOtherRoles/Patches/CredentialsPatch.cs index a0566f6ea..28b13aeb9 100644 --- a/TheOtherRoles/Patches/CredentialsPatch.cs +++ b/TheOtherRoles/Patches/CredentialsPatch.cs @@ -1,5 +1,8 @@ using HarmonyLib; using System; +using System.Collections.Generic; +using System.Net.Http; +using System.Threading.Tasks; using TheOtherRoles; using TheOtherRoles.CustomGameModes; using TheOtherRoles.Players; @@ -76,6 +79,10 @@ public static class LogoPatch public static Sprite horseBannerSprite; public static Sprite banner2Sprite; private static PingTracker instance; + + public static GameObject motdObject; + public static TextMeshPro motdText; + static void Postfix(PingTracker __instance) { var torLogo = new GameObject("bannerLogo_TOR"); torLogo.transform.SetParent(GameObject.Find("RightPanel").transform, false); @@ -96,7 +103,23 @@ static void Postfix(PingTracker __instance) { credentials.fontSize *= 0.05f; credentials.transform.SetParent(torLogo.transform); - credentials.transform.localPosition = Vector3.down * 2; + credentials.transform.localPosition = Vector3.down * 1.25f; + motdObject = new GameObject("torMOTD"); + motdText = motdObject.AddComponent(); + motdText.alignment = TMPro.TextAlignmentOptions.Center; + motdText.fontSize *= 0.04f; + + motdText.transform.SetParent(torLogo.transform); + motdText.enableWordWrapping = true; + var rect = motdText.gameObject.GetComponent(); + rect.sizeDelta = new Vector2(5.2f, 0.25f); + + motdText.transform.localPosition = Vector3.down * 2.25f; + motdText.color = new Color(1, 53f / 255, 31f / 255); + Material mat = motdText.fontSharedMaterial; + mat.shaderKeywords = new string[] { "OUTLINE_ON" }; + motdText.SetOutlineColor(Color.white); + motdText.SetOutlineThickness(0.025f); } public static void loadSprites() { @@ -121,5 +144,43 @@ public static void updateSprite() { } } } + + [HarmonyPatch(typeof(MainMenuManager), nameof(MainMenuManager.LateUpdate))] + public static class MOTD { + public static List motds = new List(); + private static float timer = 0f; + private static float maxTimer = 5f; + private static int currentIndex = 0; + + public static void Postfix() { + if (motds.Count == 0) { + timer = maxTimer; + return; + } + if (motds.Count > currentIndex && LogoPatch.motdText != null) + LogoPatch.motdText.SetText(motds[currentIndex]); + else return; + + // fade in and out: + float alpha = Mathf.Clamp01(Mathf.Min(new float[] { timer, maxTimer - timer })); + if (motds.Count == 1) alpha = 1; + LogoPatch.motdText.color = LogoPatch.motdText.color.SetAlpha(alpha); + timer -= Time.deltaTime; + if (timer <= 0) { + timer = maxTimer; + currentIndex = (currentIndex + 1) % motds.Count; + } + } + + public static async Task loadMOTDs() { + HttpClient client = new HttpClient(); + HttpResponseMessage response = await client.GetAsync("https://raw.githubusercontent.com/TheOtherRolesAU/MOTD/main/motd.txt"); + response.EnsureSuccessStatusCode(); + string motds = await response.Content.ReadAsStringAsync(); + foreach(string line in motds.Split("\n", StringSplitOptions.RemoveEmptyEntries)) { + MOTD.motds.Add(line); + } + } + } } } diff --git a/TheOtherRoles/RoleInfo.cs b/TheOtherRoles/RoleInfo.cs index 29ba52e6a..53b0e3e0a 100644 --- a/TheOtherRoles/RoleInfo.cs +++ b/TheOtherRoles/RoleInfo.cs @@ -6,6 +6,8 @@ using UnityEngine; using TheOtherRoles.Utilities; using TheOtherRoles.CustomGameModes; +using System.Threading.Tasks; +using System.Net.Http; namespace TheOtherRoles { @@ -326,5 +328,26 @@ public static String GetRolesString(PlayerControl p, bool useColors, bool showMo } return roleName; } + + + static string ReadmePage = ""; + public static async Task loadReadme() { + if (ReadmePage == "") { + HttpClient client = new HttpClient(); + HttpResponseMessage response = await client.GetAsync("https://raw.githubusercontent.com/TheOtherRolesAU/TheOtherRoles/main/README.md"); + response.EnsureSuccessStatusCode(); + string httpres = await response.Content.ReadAsStringAsync(); + ReadmePage = httpres; + } + } + public static string GetRoleDescription(RoleInfo roleInfo) { + while (ReadmePage == "") { + } + + int index = ReadmePage.IndexOf($"## {roleInfo.name}"); + int endindex = ReadmePage.Substring(index).IndexOf("### Game Options"); + return ReadmePage.Substring(index, endindex); + + } } } diff --git a/TheOtherRoles/TheOtherRoles.csproj b/TheOtherRoles/TheOtherRoles.csproj index e7f79e132..5faf18aa3 100644 --- a/TheOtherRoles/TheOtherRoles.csproj +++ b/TheOtherRoles/TheOtherRoles.csproj @@ -1,7 +1,7 @@  net6.0 - 4.4.1 + 4.4.2 TheOtherRoles Eisbison latest