Skip to content

Commit 512843c

Browse files
committed
auto watch switch gate
1 parent 48e6454 commit 512843c

File tree

9 files changed

+157
-4
lines changed

9 files changed

+157
-4
lines changed

Dialog/English.txt

+1
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,7 @@ TAS_HELPER_AUTO_WATCH_PUFFER= Puffer
301301
TAS_HELPER_AUTO_WATCH_REFILL= Refill
302302
TAS_HELPER_AUTO_WATCH_SEEKER= Seeker
303303
TAS_HELPER_AUTO_WATCH_SWAPBLOCK= Swap Block
304+
TAS_HELPER_AUTO_WATCH_SWITCHGATE= Switch Gate
304305
TAS_HELPER_AUTO_WATCH_THEOCRYSTAL= Theo Crystal
305306
TAS_HELPER_AUTO_WATCH_ZIPMOVER= Zip Mover
306307
TAS_HELPER_AUTO_WATCH_SHAKE= \S > Show Shake

Dialog/Simplified Chinese.txt

+1
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,7 @@ TAS_HELPER_AUTO_WATCH_PUFFER= Puffer
290290
TAS_HELPER_AUTO_WATCH_REFILL= Refill
291291
TAS_HELPER_AUTO_WATCH_SEEKER= Seeker
292292
TAS_HELPER_AUTO_WATCH_SWAPBLOCK= Swap Block
293+
TAS_HELPER_AUTO_WATCH_SWITCHGATE= Switch Gate
293294
TAS_HELPER_AUTO_WATCH_THEOCRYSTAL= Theo Crystal
294295
TAS_HELPER_AUTO_WATCH_ZIPMOVER= Zip Mover
295296
TAS_HELPER_AUTO_WATCH_SHAKE= \S > 显示摇摆

Source/Gameplay/AutoWatchEntity/Config.cs

+2
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ internal static class Config {
6060
public static Mode Seeker => TasHelperSettings.AutoWatch_Seeker;
6161
public static Mode SwapBlock => TasHelperSettings.AutoWatch_SwapBlock;
6262

63+
public static Mode SwitchGate => TasHelperSettings.AutoWatch_SwitchGate;
64+
6365
public static Mode TheoCrystal => TasHelperSettings.AutoWatch_TheoCrystal;
6466

6567
public static Mode Trigger => TasHelperSettings.AutoWatch_Trigger;

Source/Gameplay/AutoWatchEntity/CoreLogic.cs

+6-1
Original file line numberDiff line numberDiff line change
@@ -300,13 +300,18 @@ private static void PatchAfterUpdate(Scene self) {
300300
}
301301
}
302302

303-
internal static void WakeUpAllAutoWatchRenderer() {
303+
private static void WakeUpAllAutoWatchRenderer() {
304304
if (Engine.Scene is { } self) {
305305
foreach (AutoWatchRenderer renderer in self.Tracker.GetComponents<AutoWatchRenderer>()) {
306306
renderer.UpdateOn_ConfigChange_Or_StopUltraforwarding_Or_Clone();
307307
}
308308
}
309309
}
310+
311+
internal static void EverythingOnClone() {
312+
HiresLevelRenderer.RemoveRenderers<SwitchGateRenderer.SwitchLinker>();
313+
WakeUpAllAutoWatchRenderer();
314+
}
310315
}
311316

312317
internal interface IRendererFactory {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+

2+
using Celeste.Mod.TASHelper.Utils;
3+
using Microsoft.Xna.Framework;
4+
using Monocle;
5+
namespace Celeste.Mod.TASHelper.Gameplay.AutoWatchEntity;
6+
7+
internal class SwitchGateRenderer : AutoWatchRenderer {
8+
9+
public SwitchGate gate;
10+
11+
public bool Initialized = false;
12+
13+
public List<SwitchLinker> SwitchLinkers;
14+
15+
private static readonly List<SwitchLinker> toRemove = new();
16+
public class SwitchLinker : THRenderer {
17+
public Switch sw;
18+
19+
public SwitchGateRenderer holder;
20+
21+
public Vector2 from;
22+
23+
public SwitchLinker(Switch sw, SwitchGateRenderer holder) {
24+
this.sw = sw;
25+
this.holder = holder;
26+
from = holder.gate.Center;
27+
}
28+
29+
public void OnRemove() {
30+
HiresLevelRenderer.Remove(this);
31+
}
32+
33+
public override void Render() {
34+
if (DebugRendered && holder.Visible) {
35+
Monocle.Draw.Line(from * 6f, sw.Entity.Position * 6f, LineColor, Thickness);
36+
}
37+
}
38+
39+
public static Color LineColor = Color.Lime;
40+
41+
public static float Thickness = 2f;
42+
}
43+
public SwitchGateRenderer(RenderMode mode) : base(mode, hasUpdate: true, hasPreUpdate: false) { }
44+
45+
public override void Added(Entity entity) {
46+
base.Added(entity);
47+
gate = entity as SwitchGate;
48+
if (gate.icon?.Color == gate.finishColor || InPosition(gate)) {
49+
RemoveSelf();
50+
}
51+
Initialized = false;
52+
}
53+
54+
private void Initialize() {
55+
// we must wait until switches in last room get unloaded
56+
// so this cannot be in Added (or say, LoadLevel)
57+
SwitchLinkers = gate.Scene.Tracker.GetComponents<Switch>().Cast<Switch>().Where(x => !x.Activated).Select(x => new SwitchLinker(x, this)).ToList();
58+
foreach (SwitchLinker link in SwitchLinkers) {
59+
HiresLevelRenderer.AddIfNotPresent(link);
60+
}
61+
Initialized = true;
62+
}
63+
64+
private static bool InPosition(SwitchGate b) {
65+
return (b.Position + b.movementCounter) == b.node;
66+
}
67+
68+
public override void UpdateImpl() {
69+
if (!Initialized) {
70+
Initialize();
71+
}
72+
foreach (SwitchLinker link in SwitchLinkers) {
73+
if (link.sw.Activated) {
74+
toRemove.Add(link);
75+
}
76+
}
77+
foreach (SwitchLinker link in toRemove) {
78+
SwitchLinkers.Remove(link);
79+
link.OnRemove();
80+
}
81+
toRemove.Clear();
82+
if (SwitchLinkers.IsNullOrEmpty()) {
83+
RemoveSelf();
84+
return;
85+
}
86+
}
87+
88+
public override void Removed(Entity entity) {
89+
base.Removed(entity);
90+
if (SwitchLinkers.IsNotNullOrEmpty()) {
91+
foreach (SwitchLinker link in SwitchLinkers) {
92+
link.OnRemove();
93+
}
94+
SwitchLinkers = null;
95+
}
96+
}
97+
public override void EntityRemoved(Scene scene) {
98+
base.EntityRemoved(scene);
99+
if (SwitchLinkers.IsNotNullOrEmpty()) {
100+
foreach (SwitchLinker link in SwitchLinkers) {
101+
link.OnRemove();
102+
}
103+
SwitchLinkers = null;
104+
}
105+
}
106+
107+
public override void ClearHistoryData() {
108+
base.ClearHistoryData();
109+
Initialized = false;
110+
if (SwitchLinkers.IsNotNullOrEmpty()) {
111+
foreach (SwitchLinker link in SwitchLinkers) {
112+
link.OnRemove();
113+
}
114+
SwitchLinkers = null;
115+
}
116+
}
117+
}
118+
119+
internal class SwitchGateFactory : IRendererFactory {
120+
public Type GetTargetType() => typeof(SwitchGate);
121+
122+
public bool Inherited() => true;
123+
public RenderMode Mode() => Config.SwitchGate;
124+
public void AddComponent(Entity entity) {
125+
entity.Add(new SwitchGateRenderer(Mode()).SleepWhenUltraFastforward());
126+
}
127+
}
128+
129+
130+
131+

Source/Gameplay/HiresRendererHelper.cs

+9-1
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,6 @@ public static void AddIfNotPresent(THRenderer renderer) {
8585
}
8686
}
8787

88-
8988
public static void Remove(THRenderer renderer) {
9089
toRemove.Add(renderer);
9190
}
@@ -99,6 +98,15 @@ public static List<T> GetRenderers<T>() where T : THRenderer {
9998
return list.Select(x => (T)x).ToList();
10099
}
101100
return new List<T>();
101+
}
102+
103+
public static void RemoveRenderers<T>() where T : THRenderer {
104+
if (tracker.TryGetValue(typeof(T), out List<THRenderer> removingType)) {
105+
foreach (THRenderer renderer in removingType) {
106+
list.Remove(renderer);
107+
}
108+
removingType.Clear();
109+
}
102110
}
103111

104112
public static void UpdateLists() {

Source/Module/Menu/AutoWatchMenu.cs

+3
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,9 @@ public static class AutoWatchMenu {
101101
page.Add(new EnumerableSliderExt<RenderMode>("Auto Watch SwapBlock".ToDialogText(),
102102
CreateOptions(), TasHelperSettings.AutoWatch_SwapBlock).Change(value => TasHelperSettings.AutoWatch_SwapBlock = value));
103103

104+
page.Add(new EnumerableSliderExt<RenderMode>("Auto Watch SwitchGate".ToDialogText(),
105+
CreateOptions(), TasHelperSettings.AutoWatch_SwitchGate).Change(value => TasHelperSettings.AutoWatch_SwitchGate = value));
106+
104107
page.Add(new EnumerableSliderExt<RenderMode>("Auto Watch TheoCrystal".ToDialogText(),
105108
CreateOptions(), TasHelperSettings.AutoWatch_TheoCrystal).Change(value => TasHelperSettings.AutoWatch_TheoCrystal = value));
106109

Source/Module/TASHelperSettings.cs

+2
Original file line numberDiff line numberDiff line change
@@ -627,6 +627,8 @@ private void AutoWatchInitialize() {
627627

628628
public Mode AutoWatch_SwapBlock = Mode.Always;
629629

630+
public Mode AutoWatch_SwitchGate = Mode.Always;
631+
630632
public Mode AutoWatch_TheoCrystal = Mode.Always;
631633

632634
public Mode AutoWatch_Trigger = Mode.WhenWatched;

Source/TinySRT/ExtraSlActions.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ public static TH Create() {
221221
ExactSpinnerGroup.offsetGroup = TH_offsetGroup.TH_DeepCloneShared();
222222
MovementOvershootAssistant.MOA_Renderer.Instance = TH_MOA.TH_DeepCloneShared();
223223
Gameplay.AutoWatchEntity.CoreLogic.WhenWatchedRenderers = TH_WhenWatchedRenderers.TH_DeepCloneShared();
224-
AutoWatchRenderer.WakeUpAllAutoWatchRenderer();
224+
AutoWatchRenderer.EverythingOnClone();
225225
};
226226
Action clear = () => {
227227
TH_CachedNodes = null;
@@ -276,7 +276,7 @@ public static SRT CreateSRT() {
276276

277277
Gameplay.AutoWatchEntity.CoreLogic.WhenWatchedRenderers = SRT_WhenWatchedRenderers.DeepCloneShared();
278278

279-
AutoWatchRenderer.WakeUpAllAutoWatchRenderer();
279+
AutoWatchRenderer.EverythingOnClone();
280280

281281
PredictorCore.delayedClearFutures = true;
282282
PredictorCore.HasCachedFutures = false;

0 commit comments

Comments
 (0)