Skip to content

Commit 48c7e6a

Browse files
authored
Merge pull request #87 from CPCTC/randomize-touch-switch
Feature: randomized moving touch switch
2 parents c5c86e1 + 332372a commit 48c7e6a

5 files changed

Lines changed: 78 additions & 12 deletions

File tree

Code/FLCC/CustomMovingTouchSwitch.cs

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using MonoMod.Utils;
66
using System;
77
using System.Collections;
8+
using System.Collections.Generic;
89
using System.Linq;
910

1011
namespace vitmod
@@ -14,6 +15,7 @@ namespace vitmod
1415
public class CustomMovingTouchSwitch : Entity
1516
{
1617
public EntityID ID;
18+
private Vector2[] node_set;
1719
private Vector2[] nodes;
1820
private Color inactiveColor;
1921
private Color movingColor;
@@ -24,6 +26,9 @@ public class CustomMovingTouchSwitch : Entity
2426
private bool allowDisable;
2527
private bool smoke;
2628
private bool badelineDeactivate;
29+
private bool randomOrder;
30+
private int pathLength;
31+
private bool revisitPreviousNodes;
2732

2833
public ISwitch Switch;
2934
private Vector2 startPosition;
@@ -44,7 +49,8 @@ public class CustomMovingTouchSwitch : Entity
4449
public CustomMovingTouchSwitch(EntityData data, Vector2 offset) : base(data.Position + offset)
4550
{
4651
ID = new EntityID(data.Level.Name, data.ID);
47-
nodes = data.NodesOffset(offset);
52+
node_set = data.NodesOffset(offset);
53+
nodes = [];
4854
var flag = data.Attr("flag");
4955
var inverted = data.Bool("inverted");
5056
var persistent = data.Bool("persistent");
@@ -57,6 +63,12 @@ public CustomMovingTouchSwitch(EntityData data, Vector2 offset) : base(data.Posi
5763
allowDisable = data.Bool("allowDisable");
5864
smoke = data.Bool("smoke", true);
5965
badelineDeactivate = data.Bool("badelineDeactivate");
66+
randomOrder = data.Bool("randomOrder");
67+
pathLength = data.Int("pathLength", -1);
68+
if (pathLength == -1) {
69+
pathLength = node_set.Length;
70+
}
71+
revisitPreviousNodes = data.Bool("revisitPreviousNodes");
6072
var iconName = data.Attr("icon", "vanilla");
6173
icon = new Sprite(GFX.Game, iconName == "vanilla" ? "objects/touchswitch/icon" : $"objects/{(iconName is "tall" or "triangle" or "circle" ? "CrystallineHelper/FLCC/" : "")}customMovingTouchSwitch/{iconName}/icon");
6274

@@ -258,6 +270,38 @@ private IEnumerator DrawPathParticles(Vector2 start, Vector2 end)
258270
}
259271
}
260272

273+
public override void Added(Scene scene) {
274+
base.Added(scene);
275+
if (randomOrder) {
276+
Calc.PushRandom(VitModule.GetSeed(SceneAs<Level>()));
277+
278+
List<Vector2> path = new List<Vector2>(pathLength);
279+
280+
List<int> idx_pool = new List<int>(node_set.Length);
281+
for (int i = 0; i < node_set.Length; i++) {
282+
idx_pool.Add(i);
283+
}
284+
285+
Vector2 prev = startPosition;
286+
287+
for (int i = 0; i < pathLength; i++) {
288+
List<int> idx_candidates = new List<int>(idx_pool);
289+
idx_candidates.RemoveAll(idx => node_set[idx] == prev);
290+
if (idx_candidates.Count == 0) break;
291+
int idx = Calc.Choose<int>(Calc.Random, idx_candidates);
292+
if (!revisitPreviousNodes) {
293+
idx_pool.Remove(idx);
294+
}
295+
path.Add(prev = node_set[idx]);
296+
}
297+
298+
nodes = path.ToArray();
299+
Calc.PopRandom();
300+
} else {
301+
nodes = node_set;
302+
}
303+
}
304+
261305
public override void Update()
262306
{
263307
timer += Engine.DeltaTime * 8f;

Code/TriggerTrigger.cs

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -387,11 +387,7 @@ private void ActivateTriggers(Player player) {
387387
trigger.OnEnter(player);
388388
}
389389
} else if (triggers.Count > 0) {
390-
if (VitModule.Settings.TriggerTriggerRandomizationType == RandomizationTypes.FileTimer) {
391-
Calc.PushRandom((int)(SaveData.Instance.Time % int.MaxValue));
392-
} else {
393-
Calc.PushRandom((int)(SceneAs<Level>().Session.Time % int.MaxValue));
394-
}
390+
Calc.PushRandom(VitModule.GetSeed(SceneAs<Level>()));
395391
chosenTrigger = Calc.Choose(Calc.Random, triggers);
396392
Calc.PopRandom();
397393

@@ -634,10 +630,6 @@ public enum ActivationTypes {
634630
OnGrounded,
635631
OnPlayerState,
636632
};
637-
public enum RandomizationTypes {
638-
FileTimer,
639-
ChapterTimer
640-
};
641633
public enum InputTypes {
642634
Left,
643635
Right,

Code/VitModule.cs

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,11 +55,11 @@ public class VitModuleSession : EverestModuleSession
5555

5656
public class VitModuleSettings : EverestModuleSettings
5757
{
58-
public TriggerTrigger.RandomizationTypes TriggerTriggerRandomizationType
58+
public RandomizationTypes RandomizationType
5959
{
6060
get;
6161
set;
62-
} = TriggerTrigger.RandomizationTypes.FileTimer;
62+
} = RandomizationTypes.FileTimer;
6363

6464
public bool DisplayDashSequence {
6565
get;
@@ -838,6 +838,19 @@ public override void Unload()
838838
On.Celeste.Level.Reload -= Level_Reload;
839839
}
840840

841+
public static int GetSeed(Level level) {
842+
if (Settings.RandomizationType == RandomizationTypes.FileTimer) {
843+
return (int)(SaveData.Instance.Time % int.MaxValue);
844+
} else {
845+
return (int)(level.Session.Time % int.MaxValue);
846+
}
847+
}
848+
849+
public enum RandomizationTypes {
850+
FileTimer,
851+
ChapterTimer
852+
};
853+
841854
public const string TimeFrozenFlag = "CrystallineHelper_TimeIsFrozen";
842855

843856
private float rainbowTimer;

Loenn/entities/custom_touch_switch.lua

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ customTouchSwitch.placements = {
2020
smoke = true,
2121
allowDisable = true,
2222
badelineDeactivate = false,
23+
randomOrder = false,
24+
pathLength = -1,
25+
revisitPreviousNodes = false,
2326
}
2427
}
2528
}
@@ -35,8 +38,19 @@ customTouchSwitch.fieldInformation = {
3538
icon = {
3639
options = {"vanilla", "tall", "triangle", "circle"},
3740
},
41+
pathLength = {
42+
fieldType = "integer",
43+
},
3844
}
3945

46+
function customTouchSwitch.ignoredFields(ent)
47+
if ent.randomOrder then
48+
return {"_name", "_id", "originX", "originY"}
49+
else
50+
return {"_name", "_id", "originX", "originY", "pathLength", "revisitPreviousNodes"}
51+
end
52+
end
53+
4054
customTouchSwitch.nodeLimits = {0, -1}
4155
customTouchSwitch.nodeLineRenderType = "line"
4256

Loenn/lang/en_gb.lang

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,9 @@ entities.vitellary/customtouchswitch.attributes.description.allowDisable=Whether
254254
entities.vitellary/customtouchswitch.attributes.description.badelineDeactivate=Whether the touch switch deactivates when touched by an interactive badeline chaser.
255255
entities.vitellary/customtouchswitch.attributes.description.moveTime=The time it takes for the switch to move between nodes.
256256
entities.vitellary/customtouchswitch.attributes.description.easing=The easing of the switch's movement between nodes.
257+
entities.vitellary/customtouchswitch.attributes.description.randomOrder=Should the order the nodes are visited be randomized? Off: Nodes are visited in order. On: `Path Length` of this entity's nodes are visited in a random order.
258+
entities.vitellary/customtouchswitch.attributes.description.pathLength=When using `Random Order`, the number of nodes that should be visited before finishing. -1 to use the number of attached nodes.
259+
entities.vitellary/customtouchswitch.attributes.description.revisitPreviousNodes=When using `Random Order`, am I allowed to revisit nodes I have already been to? The sequence may be finished early if there are no nodes left to visit.
257260

258261
# Trigger Beam
259262
entities.vitellary/triggerbeam.attributes.description.color=The color of the beam.

0 commit comments

Comments
 (0)