mirror of
https://github.com/Gurge44/EndlessHostRoles.git
synced 2026-10-20 01:46:25 +00:00
changelog
This commit is contained in:
1 parent
6f9b77fc01
commit
778c8efbc1
7 files changed
+26
-76
No files matched your search
+12
-62
@@ -1,67 +1,17 @@
|
||||
# Thank you so much for finding and using EHR!
|
||||
|
||||
> [!INFO]
|
||||
> Updated to Among Us v2026.3.31 (v17.3)
|
||||
> [!CAUTION]
|
||||
> **Due to an issue on InnerSloth's servers, players (even unmodded ones) get banned after completing a visual task. Please disable Visual Tasks to avoid this issue.** We've talked to InnerSloth about this, and they've said they're working on the fix.
|
||||
|
||||
> [!WARNING]
|
||||
> **Use commands with a `/cmd ` prefix, otherwise your message gets leaked.** So if you were to type `/bt 4 snitch`, you would now type `/cmd bt 4 snitch`. The system will NOT spam the chat after command usage even if it would be required.
|
||||
|
||||
## Bug Fixes
|
||||
- Fixed Custom Hide And Seek errors when the host uses /setrole with an unavailable role
|
||||
- Fixed Mingle ending during killing process
|
||||
- Fixed disasters spawning while some players still see the ejection screen in Natural Disasters
|
||||
- Fixed sinkholes not being despawned properly in Natural Disasters when the disaster limit specified in settings is reached
|
||||
- Fixed players getting stuck inside collapsed buildings in Natural Disasters
|
||||
- Fixed Sprayer, Catcher CNOs not disappearing after meetings
|
||||
- Fixed Skeld/Dleks Electrical bounds overlapping Storage's colliders
|
||||
- Fixed after-death actions not being triggered after guesses if the game instantly ends due to it
|
||||
- Fixed shapeshift-related issues (by TommyXL)
|
||||
- Fixed april fools stuff (by TommyXL)
|
||||
- Fixed host's messages not being logged (for chat spam & chat during game notifies)
|
||||
- GM and Specators cannot be summoned by Summoner
|
||||
- Fixed Hacker consuming ability uses when looking at physical admin map
|
||||
- Fixed memory leak
|
||||
- Medic's tasks don't reset if it uses the pet button as the kill button (by Hyper)
|
||||
- Time Master & Stasis now reset player speeds to their original values instead of the global value
|
||||
- Bloodmoon now always gives Loss Of Blood as the death reason
|
||||
|
||||
## Changes
|
||||
- **More compatibility with Starlight** (should be stable at this point)
|
||||
- Player points are counted individually in King Of The Zones (by Zypherus)
|
||||
- Optimized Natural Disasters: Suffix cache & saved about 3/4 of all RPCs sent
|
||||
- Reduced Snowdown vanish cooldown from 2s to 1s
|
||||
- Reduced network pressure in Solo PVP
|
||||
- Missing 'Notification' template no longer sends an error message
|
||||
- Snowdown auto enables pet use, just like Bed Wars
|
||||
- Many more small improvements
|
||||
|
||||
### Template System Overhaul (by Zypherus)
|
||||
|
||||
- `/t` with no args → lists all tags
|
||||
- Supports real/visual line breaks (`\n` still works)
|
||||
- Variables (`@Name = value`) usable anywhere
|
||||
- Lines starting with `#` = comment (ignored)
|
||||
|
||||
#### Properties
|
||||
Syntax: `tag[property=value]:` (chain with `|`)
|
||||
|
||||
- `weight=N` → weighted random (1–10)
|
||||
- `delay=N` → send after N sec (1–30, always fires; others are weighted)
|
||||
- `map=X|Y` → specific maps
|
||||
- `role=X|Y` / `!X` → role filter / exclude
|
||||
- `rank=X|Y` → Host/Admin/Mod/VIP only
|
||||
- `players><>=<=!=N` → player count condition
|
||||
- `preset=X|Y` → specific presets
|
||||
- `hidden` → hides from `/t` list
|
||||
|
||||
#### New Placeholders
|
||||
`{{HostName}} {{Players}} {{AlivePlayers}} {{DeadPlayers}} {{PlayerCount}} {{AlivePlayerCount}} {{DeadPlayerCount}} {{GameDuration}} {{MeetingCount}} {{PresetName}}`
|
||||
|
||||
## Additions
|
||||
- Client Control GUI (by Zypherus)
|
||||
- New setting for Capture The Flag: `Spawn Protection Time` (by Zypherus)
|
||||
- New setting for Natural Disasters: `Disaster Spawn Mode` (`All On Players`/`All On Random Places`/`On Players & Random Places`)
|
||||
- Death messages for others in Natural Disasters
|
||||
- New client option: `Classic Mode` (by TommyXL)
|
||||
- **Fixed HUGE (~ 400 MB) memory leak when opening the settings UI**
|
||||
- Custom Net Objects should spawn more reliably, and not delayed/flickering for non-host modded clients
|
||||
- Fixed Coven roles not getting the Necronomicon
|
||||
- Drafting in Custom Hide And Seek now doesn't give disabled roles as choices and forcefully assigns 1 seeker if everyone drafted a non-seeker role
|
||||
- Fixed King Of The Zones sometimes not registering zone domination
|
||||
- Fixed Asthmatic not working after the host dies
|
||||
- New client option: `Show Client Control GUI` (Enabled by default)
|
||||
- Improved Client Control GUI (by Zypherus)
|
||||
- Fixed Dleks button (by TommyXL)
|
||||
- Other internal fixes and optimizations
|
||||
|
||||
---
|
||||
@@ -900,7 +900,7 @@ public static class KingOfTheZones
|
||||
if (team != KOTZTeam.None)
|
||||
{
|
||||
Points[team]++;
|
||||
zoneInfo[zone].Players.FindAll(x => x.Team == (int)team).ForEach(x => PlayerPoints[x.Id]++);
|
||||
zoneInfo[zone].Players.DoIf(x => x.Team == (int)team, x => PlayerPoints[x.Id]++);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -288,7 +288,7 @@ public static class NaturalDisasters
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
Disaster remove = PreferRemovingThunderstorm.GetBool() ? ActiveDisasters.Find(x => x is Thunderstorm) : ActiveDisasters.RandomElement();
|
||||
Disaster remove = PreferRemovingThunderstorm.GetBool() && ActiveDisasters.FindFirst(x => x is Thunderstorm, out Disaster thunderstorm) ? thunderstorm : ActiveDisasters.RandomElement();
|
||||
if (remove != null) remove.Duration = 0;
|
||||
remove?.RemoveIfExpired();
|
||||
break;
|
||||
|
||||
@@ -41,8 +41,8 @@ public class Main : BasePlugin
|
||||
private const string DebugKeyHash = "c0fd562955ba56af3ae20d7ec9e64c664f0facecef4b3e366e109306adeae29d";
|
||||
private const string DebugKeySalt = "59687b";
|
||||
public const string PluginGuid = "com.gurge44.endlesshostroles";
|
||||
public const string PluginVersion = "7.4.0";
|
||||
public const string PluginDisplayVersion = "7.4.0";
|
||||
public const string PluginVersion = "7.4.1";
|
||||
public const string PluginDisplayVersion = "7.4.1";
|
||||
public const bool TestBuild = false;
|
||||
|
||||
public const string NeutralColor = "#ffab1b";
|
||||
|
||||
@@ -404,7 +404,7 @@ namespace EHR
|
||||
{
|
||||
SpawnTimeStamp = Utils.TimeStamp;
|
||||
CreateNetObject("<size=100%><font=\"VCR SDF\"><line-height=67%><alpha=#00>\u2588<alpha=#00>\u2588<#bababa>\u2588<#bababa>\u2588<#bababa>\u2588<#bababa>\u2588<alpha=#00>\u2588<alpha=#00>\u2588<br><alpha=#00>\u2588<#bababa>\u2588<#bababa>\u2588<#8c8c8c>\u2588<#8c8c8c>\u2588<#bababa>\u2588<#bababa>\u2588<alpha=#00>\u2588<br><#bababa>\u2588<#bababa>\u2588<#8c8c8c>\u2588<#8c8c8c>\u2588<#8c8c8c>\u2588<#8c8c8c>\u2588<#bababa>\u2588<#bababa>\u2588<br><#bababa>\u2588<#8c8c8c>\u2588<#8c8c8c>\u2588<#636363>\u2588<#636363>\u2588<#8c8c8c>\u2588<#8c8c8c>\u2588<#bababa>\u2588<br><#bababa>\u2588<#8c8c8c>\u2588<#8c8c8c>\u2588<#636363>\u2588<#636363>\u2588<#8c8c8c>\u2588<#8c8c8c>\u2588<#bababa>\u2588<br><#bababa>\u2588<#bababa>\u2588<#8c8c8c>\u2588<#8c8c8c>\u2588<#8c8c8c>\u2588<#8c8c8c>\u2588<#bababa>\u2588<#bababa>\u2588<br><alpha=#00>\u2588<#bababa>\u2588<#bababa>\u2588<#8c8c8c>\u2588<#8c8c8c>\u2588<#bababa>\u2588<#bababa>\u2588<alpha=#00>\u2588<br><alpha=#00>\u2588<alpha=#00>\u2588<#bababa>\u2588<#bababa>\u2588<#bababa>\u2588<#bababa>\u2588<alpha=#00>\u2588<alpha=#00>\u2588<br></color></line-height></font></size>", position);
|
||||
LateTask.New(() => Main.EnumerateAlivePlayerControls().ExceptBy(visibleList, x => x.PlayerId).Do(Hide), 0.7f);
|
||||
LateTask.New(() => Main.EnumerateAlivePlayerControls().ExceptBy(visibleList, x => x.PlayerId).Do(Hide), 0.4f);
|
||||
}
|
||||
|
||||
protected override void OnFixedUpdate()
|
||||
@@ -439,7 +439,7 @@ namespace EHR
|
||||
public PlayerDetector(Vector2 position, List<byte> visibleList, out int id)
|
||||
{
|
||||
CreateNetObject("<size=100%><font=\"VCR SDF\"><line-height=67%><alpha=#00>\u2588<alpha=#00>\u2588<#33e6b0>\u2588<alpha=#00>\u2588<alpha=#00>\u2588<#33e6b0>\u2588<alpha=#00>\u2588<alpha=#00>\u2588<br><alpha=#00>\u2588<#33e6b0>\u2588<alpha=#00>\u2588<alpha=#00>\u2588<alpha=#00>\u2588<alpha=#00>\u2588<#33e6b0>\u2588<alpha=#00>\u2588<br><#33e6b0>\u2588<alpha=#00>\u2588<alpha=#00>\u2588<#33e6b0>\u2588<#33e6b0>\u2588<alpha=#00>\u2588<alpha=#00>\u2588<#33e6b0>\u2588<br><#33e6b0>\u2588<alpha=#00>\u2588<#33e6b0>\u2588<#000000>\u2588<#000000>\u2588<#33e6b0>\u2588<alpha=#00>\u2588<#33e6b0>\u2588<br><#33e6b0>\u2588<alpha=#00>\u2588<#33e6b0>\u2588<#000000>\u2588<#000000>\u2588<#33e6b0>\u2588<alpha=#00>\u2588<#33e6b0>\u2588<br><#33e6b0>\u2588<alpha=#00>\u2588<alpha=#00>\u2588<#33e6b0>\u2588<#33e6b0>\u2588<alpha=#00>\u2588<alpha=#00>\u2588<#33e6b0>\u2588<br><alpha=#00>\u2588<#33e6b0>\u2588<alpha=#00>\u2588<alpha=#00>\u2588<alpha=#00>\u2588<alpha=#00>\u2588<#33e6b0>\u2588<alpha=#00>\u2588<br><alpha=#00>\u2588<alpha=#00>\u2588<#33e6b0>\u2588<alpha=#00>\u2588<alpha=#00>\u2588<#33e6b0>\u2588<alpha=#00>\u2588<alpha=#00>\u2588<br></color></line-height></font></size>", position);
|
||||
LateTask.New(() => Main.EnumerateAlivePlayerControls().ExceptBy(visibleList, x => x.PlayerId).Do(Hide), 0.7f);
|
||||
LateTask.New(() => Main.EnumerateAlivePlayerControls().ExceptBy(visibleList, x => x.PlayerId).Do(Hide), 0.4f);
|
||||
id = Id;
|
||||
}
|
||||
}
|
||||
@@ -453,7 +453,7 @@ namespace EHR
|
||||
Resource = resource;
|
||||
(char Icon, Color Color) data = Adventurer.ResourceDisplayData[resource];
|
||||
CreateNetObject($"<size=300%><font=\"VCR SDF\"><line-height=67%>{Utils.ColorString(data.Color, data.Icon.ToString())}</line-height></font></size>", position);
|
||||
LateTask.New(() => Main.EnumerateAlivePlayerControls().ExceptBy(visibleList, x => x.PlayerId).Do(Hide), 0.7f);
|
||||
LateTask.New(() => Main.EnumerateAlivePlayerControls().ExceptBy(visibleList, x => x.PlayerId).Do(Hide), 0.4f);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -462,7 +462,7 @@ namespace EHR
|
||||
internal Toilet(Vector2 position, IEnumerable<PlayerControl> hideList)
|
||||
{
|
||||
CreateNetObject("<size=100%><font=\"VCR SDF\"><line-height=67%><alpha=#00>\u2588<#e6e6e6>\u2588<#e6e6e6>\u2588<#e6e6e6>\u2588<#e6e6e6>\u2588<#e6e6e6>\u2588<#e6e6e6>\u2588<#e6e6e6>\u2588<#e6e6e6>\u2588<alpha=#00>\u2588<br><#e6e6e6>\u2588<#d3d4ce>\u2588<#d3d4ce>\u2588<#d3d4ce>\u2588<#d3d4ce>\u2588<#d3d4ce>\u2588<#d3d4ce>\u2588<#d3d4ce>\u2588<#d3d4ce>\u2588<#e6e6e6>\u2588<br><#e6e6e6>\u2588<#d3d4ce>\u2588<#d3d4ce>\u2588<#d3d4ce>\u2588<#d3d4ce>\u2588<#d3d4ce>\u2588<#d3d4ce>\u2588<#d3d4ce>\u2588<#d3d4ce>\u2588<#e6e6e6>\u2588<br><alpha=#00>\u2588<#e6e6e6>\u2588<#d3d4ce>\u2588<#d3d4ce>\u2588<#d3d4ce>\u2588<#d3d4ce>\u2588<#d3d4ce>\u2588<#d3d4ce>\u2588<#e6e6e6>\u2588<alpha=#00>\u2588<br><alpha=#00>\u2588<#e6e6e6>\u2588<#e6e6e6>\u2588<#d3d4ce>\u2588<#dedede>\u2588<#dedede>\u2588<#d3d4ce>\u2588<#e6e6e6>\u2588<#e6e6e6>\u2588<alpha=#00>\u2588<br><alpha=#00>\u2588<#bfbfbf>\u2588<#454545>\u2588<#333333>\u2588<#333333>\u2588<#333333>\u2588<#333333>\u2588<#333333>\u2588<#333333>\u2588<#bfbfbf>\u2588<br><alpha=#00>\u2588<#bfbfbf>\u2588<#bfbfbf>\u2588<#454545>\u2588<#454545>\u2588<#454545>\u2588<#454545>\u2588<#454545>\u2588<#454545>\u2588<#bfbfbf>\u2588<br><alpha=#00>\u2588<alpha=#00>\u2588<#bfbfbf>\u2588<#bfbfbf>\u2588<#bfbfbf>\u2588<#bfbfbf>\u2588<#bfbfbf>\u2588<#bfbfbf>\u2588<#bfbfbf>\u2588<#bfbfbf>\u2588<br><alpha=#00>\u2588<alpha=#00>\u2588<alpha=#00>\u2588<#dedede>\u2588<#dedede>\u2588<#dedede>\u2588<#dedede>\u2588<alpha=#00>\u2588<alpha=#00>\u2588<alpha=#00>\u2588<br><alpha=#00>\u2588<alpha=#00>\u2588<alpha=#00>\u2588<alpha=#00>\u2588<#dedede>\u2588<#dedede>\u2588<alpha=#00>\u2588<alpha=#00>\u2588<alpha=#00>\u2588<alpha=#00>\u2588<br></color></line-height></font></size>", position);
|
||||
LateTask.New(() => hideList.Do(Hide), 0.7f);
|
||||
LateTask.New(() => hideList.Do(Hide), 0.4f);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -485,7 +485,7 @@ namespace EHR
|
||||
public SprayedArea(Vector2 position, IEnumerable<byte> visibleList)
|
||||
{
|
||||
CreateNetObject("<size=100%><font=\"VCR SDF\"><line-height=67%><alpha=#00>\u2588<alpha=#00>\u2588<#ffd000>\u2588<#ffd000>\u2588<alpha=#00>\u2588<alpha=#00>\u2588<br><alpha=#00>\u2588<#ffd000>\u2588<#ffd000>\u2588<#ffd000>\u2588<#ffd000>\u2588<alpha=#00>\u2588<br><#ffd000>\u2588<#ffd000>\u2588<#ffd000>\u2588<#ffd000>\u2588<#ffd000>\u2588<#ffd000>\u2588<br><#ffd000>\u2588<#ffd000>\u2588<#ffd000>\u2588<#ffd000>\u2588<#ffd000>\u2588<#ffd000>\u2588<br><alpha=#00>\u2588<#ffd000>\u2588<#ffd000>\u2588<#ffd000>\u2588<#ffd000>\u2588<alpha=#00>\u2588<br><alpha=#00>\u2588<alpha=#00>\u2588<#ffd000>\u2588<#ffd000>\u2588<alpha=#00>\u2588<alpha=#00>\u2588<br></line-height></size>", position);
|
||||
LateTask.New(() => Main.EnumerateAlivePlayerControls().ExceptBy(visibleList, x => x.PlayerId).Do(Hide), 0.7f);
|
||||
LateTask.New(() => Main.EnumerateAlivePlayerControls().ExceptBy(visibleList, x => x.PlayerId).Do(Hide), 0.4f);
|
||||
}
|
||||
|
||||
public override void OnMeeting()
|
||||
@@ -499,7 +499,7 @@ namespace EHR
|
||||
public CatcherTrap(Vector2 position, PlayerControl catcher)
|
||||
{
|
||||
CreateNetObject("<size=100%><font=\"VCR SDF\"><line-height=67%><alpha=#00>\u2588<alpha=#00>\u2588<#ccffda>\u2588<#ccffda>\u2588<alpha=#00>\u2588<alpha=#00>\u2588<br><alpha=#00>\u2588<#ccffda>\u2588<#ccffda>\u2588<#ccffda>\u2588<#ccffda>\u2588<alpha=#00>\u2588<br><#ccffda>\u2588<#ccffda>\u2588<#ccffda>\u2588<#ccffda>\u2588<#ccffda>\u2588<#ccffda>\u2588<br><#ccffda>\u2588<#ccffda>\u2588<#ccffda>\u2588<#ccffda>\u2588<#ccffda>\u2588<#ccffda>\u2588<br><alpha=#00>\u2588<#ccffda>\u2588<#ccffda>\u2588<#ccffda>\u2588<#ccffda>\u2588<alpha=#00>\u2588<br><alpha=#00>\u2588<alpha=#00>\u2588<#ccffda>\u2588<#ccffda>\u2588<alpha=#00>\u2588<alpha=#00>\u2588<br></line-height></size>", position);
|
||||
LateTask.New(() => Main.EnumerateAlivePlayerControls().Without(catcher).Do(Hide), 0.7f);
|
||||
LateTask.New(() => Main.EnumerateAlivePlayerControls().Without(catcher).Do(Hide), 0.4f);
|
||||
}
|
||||
|
||||
public override void OnMeeting()
|
||||
@@ -529,7 +529,7 @@ namespace EHR
|
||||
public SoulObject(Vector2 position, PlayerControl whisperer)
|
||||
{
|
||||
CreateNetObject("<size=80%><font=\"VCR SDF\"><line-height=67%><alpha=#00>\u2588<alpha=#00>\u2588<#fcfcfc>\u2588<#fcfcfc>\u2588<#fcfcfc>\u2588<alpha=#00>\u2588<br><alpha=#00>\u2588<#fcfcfc>\u2588<#fcfcfc>\u2588<#fcfcfc>\u2588<#fcfcfc>\u2588<#fcfcfc>\u2588<br><#fcfcfc>\u2588<#fcfcfc>\u2588<#fcfcfc>\u2588<#fcfcfc>\u2588<#cfcfcf>\u2588<#cfcfcf>\u2588<br><#fcfcfc>\u2588<#fcfcfc>\u2588<#fcfcfc>\u2588<#fcfcfc>\u2588<#fcfcfc>\u2588<#fcfcfc>\u2588<br><alpha=#00>\u2588<#fcfcfc>\u2588<#fcfcfc>\u2588<#fcfcfc>\u2588<#fcfcfc>\u2588<#fcfcfc>\u2588<br><alpha=#00>\u2588<#fcfcfc>\u2588<#fcfcfc>\u2588<#fcfcfc>\u2588<alpha=#00>\u2588<#fcfcfc>\u2588<br></line-height></size>", position);
|
||||
LateTask.New(() => Main.EnumerateAlivePlayerControls().Without(whisperer).Do(Hide), 0.7f);
|
||||
LateTask.New(() => Main.EnumerateAlivePlayerControls().Without(whisperer).Do(Hide), 0.4f);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -752,7 +752,7 @@ namespace EHR
|
||||
public ShapeshiftMenuElement(byte visibleTo)
|
||||
{
|
||||
CreateNetObject(string.Empty, new Vector2(0f, 0f));
|
||||
LateTask.New(() => Main.EnumeratePlayerControls().DoIf(x => x.PlayerId != visibleTo, Hide), 0.7f);
|
||||
LateTask.New(() => Main.EnumeratePlayerControls().DoIf(x => x.PlayerId != visibleTo, Hide), 0.4f);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -947,7 +947,7 @@ internal static class StartGameHostPatch
|
||||
foreach (PlayerState state in Main.PlayerStates.Values)
|
||||
{
|
||||
if (Main.NeverSpawnTogetherCombos.TryGetValue(OptionItem.CurrentPreset, out Dictionary<CustomRoles, List<CustomRoles>> neverList) && neverList.TryGetValue(state.MainRole, out List<CustomRoles> bannedAddonList))
|
||||
bannedAddonList.ForEach(x => state.RemoveSubRole(x));
|
||||
bannedAddonList.ForEach(state.RemoveSubRole);
|
||||
|
||||
if (Main.AlwaysSpawnTogetherCombos.TryGetValue(OptionItem.CurrentPreset, out Dictionary<CustomRoles, List<CustomRoles>> alwaysList) && alwaysList.TryGetValue(state.MainRole, out List<CustomRoles> addonList))
|
||||
addonList.ForEach(x => state.SetSubRole(x));
|
||||
|
||||
@@ -1684,7 +1684,7 @@ internal static class FixedUpdatePatch
|
||||
var state = Main.PlayerStates[playerId];
|
||||
state.SubRoles
|
||||
.FindAll(x => x is CustomRoles.Fragile or CustomRoles.Unbound or CustomRoles.Diseased or CustomRoles.Antidote or CustomRoles.Beartrap or CustomRoles.Youtuber or CustomRoles.Lucky or CustomRoles.Onbound or CustomRoles.Allergic or CustomRoles.Asthmatic or CustomRoles.Bewilder or CustomRoles.Compelled or CustomRoles.Unlucky or CustomRoles.Bait)
|
||||
.ForEach(x => state.RemoveSubRole(x));
|
||||
.ForEach(state.RemoveSubRole);
|
||||
|
||||
if (!PlagueBearer.PestilenceList.Contains(playerId))
|
||||
PlagueBearer.PestilenceList.Add(playerId);
|
||||
|
||||
Reference in new issue
Block a user