-
Notifications
You must be signed in to change notification settings - Fork 1
/
kl2.asl
119 lines (101 loc) · 3.42 KB
/
kl2.asl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
state("kl2")
{
byte loadingScreenVisible : 0x00B64638; // True whenever there is a loading screen. Sometimes when alt-tabbed, will switch itself to 0.
string80 loadingLevelWav : 0x010F3824; // Gives you the name of the level (actually, a wav file relating to the level) about 50% of the way through a load. Clears when loading is finished.
byte cutsceneCandidate : 0x0116B3C6; // 0 when a cutscene is not playing, 2 when there is.
}
startup
{
settings.Add("pauseCutscenes", false, "Pause timer during cutscenes.");
print("Hello, world!");
}
init
{
vars.old = old;
Func<bool> isLoading = () => current.loadingScreenVisible == 1; // Current gets updated in place.
Func<bool> wasLoading = () => vars.old.loadingScreenVisible == 1; // Old is a new object every time.
Func<bool> startedLoading = () => isLoading() && !wasLoading();
Func<bool> stoppedLoading = () => !isLoading() && wasLoading();
Func<bool> inCutscene = () => current.cutsceneCandidate == 2;
Func<bool> wasInCutscene = () => vars.old.cutsceneCandidate != 2;
Func<bool> beganCutscene = () => inCutscene() && !wasInCutscene();
Func<bool> finishedCutscene = () => !inCutscene() && wasInCutscene();
bool startPrimed = false;
// Prime the ability to start the run when we've loaded into the first real level.
Action tryPrimeStart = () => {
if (!startPrimed) {
startPrimed = vars.old.loadingLevelWav.StartsWith("SCENES\\Locations\\L01") && !current.loadingLevelWav.StartsWith("SCENES\\Locations\\L01");
}
};
// Fire the start condition when the first cutscene finishes and we gain control of the characters.
Func<bool> tryFireStart = () => {
if (startPrimed && finishedCutscene()) {
startPrimed = false;
print("Run started, good luck!");
return true;
} else {
return false;
}
};
bool endingPrimed = false;
// Prime the ability to end the run (split on last segment) when we've loaded into the last level.
Action tryPrimeEnd = () => {
if (!endingPrimed) {
endingPrimed = vars.old.loadingLevelWav.StartsWith("SCENES\\Locations\\L11") && !current.loadingLevelWav.StartsWith("SCENES\\Locations\\L11");
if (endingPrimed) print("You're almost there, try not to crash...");
}
};
// Fire the end condition when the last cutscene plays.
Func<bool> tryFireEnd = () => {
if (endingPrimed && beganCutscene()) {
endingPrimed = false;
print("You did it, congrats!");
return true;
} else {
return false;
}
};
// Reset conditions for splitting and starting.
Action forceResetPrimes = () => {
startPrimed = false;
endingPrimed = false;
};
vars.IsLoading = isLoading;
vars.WasLoading = wasLoading;
vars.StartedLoading = startedLoading;
vars.InCutscene = inCutscene;
vars.BeganCutscene = beganCutscene;
vars.TryPrimeStart = tryPrimeStart;
vars.TryFireStart = tryFireStart;
vars.TryPrimeEnd = tryPrimeEnd;
vars.TryFireEnd = tryFireEnd;
vars.ForceResetPrimes = forceResetPrimes;
}
update
{
vars.old = old;
vars.TryPrimeStart();
vars.TryPrimeEnd();
}
isLoading
{
return vars.IsLoading() || (settings["pauseCutscenes"] && vars.InCutscene());
}
start
{
return vars.TryFireStart();
}
split
{
return vars.StartedLoading() || vars.TryFireEnd();
}
reset
{
// Intro/title scene
if (current.loadingLevelWav.StartsWith("SCENES\\Locations\\L00")) {
vars.ForceResetPrimes();
return true;
} else {
return false;
}
}