From 8a2ea406da34af2ca4e3ed73680745ecad06580d Mon Sep 17 00:00:00 2001 From: Gurge44 Date: Thu, 13 Aug 2026 14:18:00 +0200 Subject: [PATCH] Add Transfer --- CustomRoles.cs | 1 + Main.cs | 1 + Patches/OnGameStartedPatch.cs | 1 + Patches/PlayerControlPatch.cs | 7 ++++- Resources/Lang/en_US.json | 4 +++ Roles/Standard/Addons/Common/Transfer.cs | 38 ++++++++++++++++++++++++ 6 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 Roles/Standard/Addons/Common/Transfer.cs diff --git a/CustomRoles.cs b/CustomRoles.cs index e00ea4312..f6865fb56 100644 --- a/CustomRoles.cs +++ b/CustomRoles.cs @@ -632,6 +632,7 @@ public enum CustomRoles Tiebreaker, Tired, Torch, + Transfer, Truant, Unbound, Undead, diff --git a/Main.cs b/Main.cs index a6a33e981..b4259be91 100644 --- a/Main.cs +++ b/Main.cs @@ -762,6 +762,7 @@ public class Main : BasePlugin { CustomRoles.Listener, "#060270" }, { CustomRoles.Unbound, "#DFC57B" }, { CustomRoles.AntiTP, "#fcba03" }, + { CustomRoles.Transfer, "#737373" }, { CustomRoles.Focused, "#A10E49" }, { CustomRoles.Dizzy, "#de97a7" }, { CustomRoles.Entombed, "#8c71de" }, diff --git a/Patches/OnGameStartedPatch.cs b/Patches/OnGameStartedPatch.cs index ccee61536..e8407efbd 100644 --- a/Patches/OnGameStartedPatch.cs +++ b/Patches/OnGameStartedPatch.cs @@ -305,6 +305,7 @@ internal static class ChangeRoleSettings Circumvent.Init(); Committed.Init(); Reroll.Init(); + Transfer.Init(); } catch (Exception ex) { Logger.Exception(ex, "Init Roles"); } diff --git a/Patches/PlayerControlPatch.cs b/Patches/PlayerControlPatch.cs index 3b753d70a..b4c18efb1 100644 --- a/Patches/PlayerControlPatch.cs +++ b/Patches/PlayerControlPatch.cs @@ -1768,7 +1768,12 @@ internal static class FixedUpdatePatch } bool checkPos = inTask && !ExileController.Instance && !AntiBlackout.SkipTasks && alive && !Pelican.IsEaten(playerId) && Main.IntroDestroyed; - if (checkPos) Asthmatic.OnCheckPlayerPosition(player); + + if (checkPos) + { + Asthmatic.OnCheckPlayerPosition(player); + Transfer.OnCheckPlayerPosition(player); + } foreach (PlayerState state in Main.PlayerStates.Values) { diff --git a/Resources/Lang/en_US.json b/Resources/Lang/en_US.json index e9b5f7ca2..03ea76ecf 100644 --- a/Resources/Lang/en_US.json +++ b/Resources/Lang/en_US.json @@ -208,6 +208,7 @@ "Prefix.Tiebreaker": "Tiebreaker", "Prefix.Tired": "Tired", "Prefix.Torch": "Torch", + "Prefix.Transfer": "Transfer", "Prefix.Trainee": "Trainee", "Prefix.Truant": "Truant", "Prefix.Unbound": "Unbound", @@ -3981,6 +3982,9 @@ "TorchInfoLong": "(Add-ons):\\nOnly Crewmates will get Torch, who have increased vision and may not be affected by Lights Sabotage.", "TorchAffectedByLights": "Torch's vision is affected by Lights Sabotage", "TorchVision": "Torch Vision", + "Transfer": "Transfer", + "TransferInfo": "Transfer Between Vents", + "TransferInfoLong": "(Add-ons):\\nAs the Transfer, whenever you step on a vent, you teleport to a random vent.", "Trainee": "Trainee", "TraineeInfo": "You Can't Vent/Sabotage/SS/Pet/Vanish Round 1", "TraineeInfoLong": "(Add-ons):\\nYou can't vent, sabotage, shapeshift, or pet on the first round.", diff --git a/Roles/Standard/Addons/Common/Transfer.cs b/Roles/Standard/Addons/Common/Transfer.cs new file mode 100644 index 000000000..6d9185185 --- /dev/null +++ b/Roles/Standard/Addons/Common/Transfer.cs @@ -0,0 +1,38 @@ +using System.Collections.Generic; +using System.Linq; +using EHR.Modules; + +namespace EHR.Roles; + +public class Transfer : IAddon +{ + public AddonTypes Type => AddonTypes.Mixed; + + private static Dictionary LastTP; + private static Vector2[] VentLocations; + + public void SetupCustomOption() + { + Options.SetupAdtRoleOptions(659700, CustomRoles.Transfer, canSetNum: true, teamSpawnOptions: true); + } + + public static void Init() + { + LastTP = null; + LateTask.New(() => VentLocations = ShipStatus.Instance && CustomRoles.Transfer.RoleExist() ? ShipStatus.Instance.AllVents.Select(x => new Vector2(x.transform.position.x, x.transform.position.y + 0.3636f)).ToArray() : null, 25f); + } + + public static void OnCheckPlayerPosition(PlayerControl pc) + { + if (VentLocations == null || !PerSecondUpdateScheduler.ShouldRunUpdate(pc.PlayerId) || !pc.Is(CustomRoles.Transfer)) return; + + long now = Utils.TimeStamp; + LastTP ??= []; + + if (LastTP.TryGetValue(pc.PlayerId, out long ts) && ts + 3 >= now) return; + if (!FastVector2.TryGetClosestInRange(pc.Pos(), VentLocations, 0.8f, out _)) return; + + pc.TPToRandomVent(); + LastTP[pc.PlayerId] = now; + } +} \ No newline at end of file