add alpha channel handling

This commit is contained in:
Gurge44 committed 2026-01-24 18:09:11 +01:00
1 parent e78141bb78
commit fc0ea73c7a
5 files changed
+14 -55

No files matched your search

+6 -31
View File
@@ -1,42 +1,17 @@
# Thank you so much for finding and using EHR!
> [!IMPORTANT]
> InnerSloth added a way to use chat commands without needing to spam the chat after it to hide who typed it. In the next few weeks, please adapt to using commands with a `/cmd ` prefix. So if you were to type `/bt 4 snitch`, you would now type `/cmd bt 4 snitch`. This is the last version of EHR that allows the old way of typing commands.
> [!NOTE]
> - Custom Net Objects work again! All game modes and roles can be used again on vanilla servers!
> - HTML tags are supported on vanilla regions again! Just make sure they don't contain many numbers. Color tags are automatically replaced to ones without digits. Some visual differences may occur.
> - See more info on [our Discord server](https://discord.gg/ehr).
> InnerSloth added a way to use chat commands without needing to spam the chat after it to hide who typed it. In the next few weeks, please adapt to using commands with a `/cmd ` prefix. So if you were to type `/bt 4 snitch`, you would now type `/cmd bt 4 snitch`. This is the last major version of EHR that allows the old way of typing commands. Starting v7.3.0, the mod will NOT spam the chat even if you don't use /cmd.
## Bug Fixes
- Fixed Comms Camouflage activating in non-standard game modes
- Fixed Room Rush sometimes not working
- Fixed chatting during game having weird notifications
- Deadlined and Alchemist info is now properly synced with non-host modded clients
- Fixed Imitator being able to imitate even after changing roles by other means
- Fixed Retributionist kill button availability not syncing with non-host modded clients
- Fixed Beacon sometimes not updating vision
- Fixed Chameleon being invisible infinitely
- Fixed Room Rusher showing incorrect rooms for non-host modded clients
- Fixed Starspawn ignoring ability cooldown and uses
- Fixed Mingle end summary for non-host modded clients
- Fixed `Chat During Game` causing black screen for vanilla clients in Mingle, Quiz and Natural Disasters
- Fixed color tags not being replaced to letter-only ones when they had an alpha channel
## Changes
- More compatibility with LevelImpostor
- Augur no longer dies due to misguessing, instead it just can't guess in that meeting again
- Doppelganger's ID is visually swapped with their victim on the meeting UI. Does not affect `/id` for critical scenarios.
- Kill log timestamps are now relative to when the game started (timestamps may be removed entirely in the future, because it's so many digits)
- Increased target selection range through pet button
- Optimized Mastermind code
-
## Additions
- New role: Accumulator (Neutral Killing)
- New role: Quarry (Neutral Killing)
- New settings for Portal Maker:
- - `Ability Cooldown`
- - `Can Pet To Remove Both Portals After Placing Them`
- New setting (Mod Settings > `Camouflage During Comms`):
- - `Don't Camouflage Round 1`
- New setting (Mod Settings):
- - `Take Role Spawn Chances Into Account When Picking Draft Choices`
-
---
+2 -2
View File
@@ -42,8 +42,8 @@ public class Main : BasePlugin
private const string DebugKeyHash = "c0fd562955ba56af3ae20d7ec9e64c664f0facecef4b3e366e109306adeae29d";
private const string DebugKeySalt = "59687b";
private const string PluginGuid = "com.gurge44.endlesshostroles";
public const string PluginVersion = "7.2.0";
public const string PluginDisplayVersion = "7.2.0";
public const string PluginVersion = "7.2.1";
public const string PluginDisplayVersion = "7.2.1";
public const bool TestBuild = false;
public const string NeutralColor = "#ffab1b";
-18
View File
@@ -48,8 +48,6 @@ public static class Translator
foreach (string jsonFileName in jsonFileNames)
{
Logger.Warn($"Loading lang file: {jsonFileName}", "Translator");
// Read the JSON file content
using Stream resourceStream = assembly.GetManifestResourceStream(jsonFileName);
@@ -58,8 +56,6 @@ public static class Translator
using StreamReader reader = new(resourceStream);
string jsonContent = reader.ReadToEnd();
File.WriteAllText($"{Main.DataPath}/{LanguageFolderName}/debug_{jsonFileName}.json", jsonContent);
// Deserialize the JSON into a dictionary
var jsonDictionary = JsonSerializer.Deserialize<Dictionary<string, string>>(jsonContent);
@@ -78,12 +74,6 @@ public static class Translator
}
}
}
// Convert the resulting translation map to JSON
File.WriteAllText($"{Main.DataPath}/{LanguageFolderName}/debug.json", JsonSerializer.Serialize(TranslateMaps, new JsonSerializerOptions
{
WriteIndented = true
}));
}
catch (Exception ex) { Logger.Error($"Error: {ex}", "Translator"); }
@@ -116,14 +106,6 @@ public static class Translator
{
// If the textString is not already in the translation map, add it
if (!translationMaps.ContainsKey(textString)) translationMaps[textString] = [];
if (translationMaps[textString].ContainsKey(languageId))
{
Logger.Warn(
$"Overwriting translation: {textString} ({languageId})",
"Translator"
);
}
// Add or update the translation for the current id and textString
translationMaps[textString][languageId] = translation.Replace("\\n", "\n").Replace("\\r", "\r");
+5 -2
View File
@@ -1813,7 +1813,7 @@ public static class Utils
private static Stopwatch TempReviveHostRevertStopwatch = new();
private static Stopwatch TempReviveHostTimeSinceRevivalStopwatch = new();
private static string[] CachedLetterOnlyHexColors = [];
private static readonly Regex ColorTagRegex = new(@"<\s*(?:color\s*=\s*)?#([0-9a-fA-F]{6})\s*>", RegexOptions.Compiled);
private static readonly Regex ColorTagRegex = new(@"<\s*(?:color\s*=\s*)?#([0-9a-fA-F]{6}(?:[0-9a-fA-F]{2})?)\s*>", RegexOptions.Compiled);
private static readonly Dictionary<(int R, int G, int B), string> CachedColorReplacements = [];
private static readonly char[] HexLetters = ['a', 'b', 'c', 'd', 'e', 'f'];
static readonly Dictionary<string, (int r, int g, int b)> NamedColors = new()
@@ -2238,6 +2238,9 @@ public static class Utils
{
string hex = match.Groups[1].Value.ToLowerInvariant();
string a = hex.Length == 8 ? hex[6..8] : string.Empty;
if (!string.IsNullOrEmpty(a)) hex = hex[..6];
if (hex.Length != 6 || !hex.Any(char.IsDigit)) return match.Value;
int r = Convert.ToInt32(hex[..2], 16);
@@ -2248,7 +2251,7 @@ public static class Utils
return NamedColors.ContainsKey(best)
? $"<color={best}>"
: $"<#{best}>";
: $"<#{best}{a}>";
});
static string FindClosestSafeColor(int r, int g, int b)
+1 -2
View File
@@ -1773,8 +1773,7 @@ internal static class ChatCommands
for (var i = 0; i < Math.Max(answers.Length, 2); i++)
{
var choiceLetter = (char)(i + 65);
var str = $"{char.ToUpper(choiceLetter)}) {answers[i]}\n";
msg += GameStates.CurrentServerType == GameStates.ServerType.Vanilla ? str : Utils.ColorString(gmPoll ? gmPollColors[i] : RandomColor(), str);
msg += Utils.ColorString(gmPoll ? gmPollColors[i] : RandomColor(), $"{char.ToUpper(choiceLetter)}) {answers[i]}\n");
PollVotes[choiceLetter] = 0;
PollAnswers[choiceLetter] = $"〖 {answers[i]} 〗";
}