-
Notifications
You must be signed in to change notification settings - Fork 0
/
LiveSplit.WormsWMD.asl
187 lines (151 loc) · 6.2 KB
/
LiveSplit.WormsWMD.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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
// Define the executable and variables
state("Worms W.M.D") {
// Game is loading (true between the menu and game music playing)
bool loading : "Worms W.M.D.exe", 0xE0FBA12;
// Only true when player's turn hotseat timer
bool playerHotseatTimer : "Worms W.M.D.exe", 0xF10384D;
// Not the timer the player can see, but a general timer with microseconds precision
// starting from level load and ending on results page.
// Only pauses when pausing the game
float levelTimer : "Worms W.M.D.exe", 0xDCCF090;
// Training time looks like mm:ss.ms
string8 displayedTimer: "Worms W.M.D.exe", 0x0F103838, 0x2A8;
// Current training mission name if selected
string33 selectedTrainingMission : "Worms W.M.D.exe", 0x0F103540, 0xE8, 0x1C0, 0xDC, 0xAAC;
// True when replaying
bool replay : "Worms W.M.D.exe", 0x00415D8C, 0x0;
// True when on the results page
bool resultsPage : "Worms W.M.D.exe", 0xF10388D;
}
init {
// Whether the first hotseat timer of a level is active
vars.firstHotseatTimerEnded = false;
// Training
vars.isTraining = false; // whether we need to handle milliseconds
vars.lastEnteredLevelTotalMillisecondsPlayed = 0; // sum of seconds played on the same level, including restarts
vars.sumOfTurnTimesMs = 0; // SOTT, sum of turn times
vars.currentTimerMilliseconds = 0; // milliseconds elapsed since start or restart of a level
// bugfix #1: fixes restarting a level sometimes ignores the last game seconds.
// this temp var keeps the last game timer in memory
vars.tmpPreviousTimerMilliseconds = 0;
// Campaign
vars.currentTimerSecondsRemaining = 0; // seconds remaining since start or restart of a level
// Helper vars
vars.inGame = false;
vars.comingFromMainMenu = true;
vars.isFirstLevel = true;
vars.shouldReset = false;
}
reset {
if (vars.shouldReset) {
return true;
}
}
onReset {
// Needed as init{} is entered on game launch only
vars.sumOfTurnTimesMs = 0;
}
// State management
update {
//// Order of the following conditions matters
if (current.replay) {
// Fixes bug where timer would show replay time
return false;
}
if (current.levelTimer < old.levelTimer && vars.inGame
&& !current.replay) { // fixes bug where game replay triggers a restart)
print("Current level restarted");
if (vars.isFirstLevel) {
vars.shouldReset = true;
} else {
// Sum timers
if (vars.isTraining) {
if (vars.currentTimerMilliseconds == 0) {
// For bugfix #1: use previous timer value when occasionally the previous game timer already reset to 0
vars.lastEnteredLevelTotalMillisecondsPlayed += vars.tmpPreviousTimerMilliseconds;
} else {
vars.lastEnteredLevelTotalMillisecondsPlayed += vars.currentTimerMilliseconds;
}
}
}
}
// When the mission timer is visible and it just changed
if (current.displayedTimer != null && current.displayedTimer != old.displayedTimer || vars.shouldReset) {
string displayedTimer = current.displayedTimer;
double milliseconds = -1;
vars.isTraining = displayedTimer.IndexOf('.') != -1 && (
current.selectedTrainingMission.Contains("Basic") ||
current.selectedTrainingMission.Contains("Training") ||
current.selectedTrainingMission.Contains("Advanced"));
if (vars.isTraining) {
string[] splitDurationMs = displayedTimer.Split('.');
milliseconds = Convert.ToInt32(splitDurationMs[1]);
displayedTimer = splitDurationMs[0];
}
string[] splitDuration = displayedTimer.Split(':');
int minutes = Convert.ToInt32(splitDuration[0]);
int seconds = minutes * 60 + Convert.ToInt32(splitDuration[1]);
if (vars.isTraining && milliseconds != -1) {
milliseconds *= 10;
milliseconds += 1000 * seconds;
vars.tmpPreviousTimerMilliseconds = vars.currentTimerMilliseconds; // bugfix #1: keep previous timer value
vars.currentTimerMilliseconds = milliseconds;
} else if (seconds > 0) {
vars.currentTimerSecondsRemaining = seconds;
}
}
if (vars.comingFromMainMenu && (vars.currentTimerSecondsRemaining > 0 || vars.currentTimerMilliseconds > 0)) {
print("New level started");
// Set state
vars.inGame = true;
vars.comingFromMainMenu = false;
vars.isFirstLevel = false;
}
vars.firstHotseatTimerEnded = !current.playerHotseatTimer && current.playerHotseatTimer != old.playerHotseatTimer;
}
start {
if (current.displayedTimer != null && vars.firstHotseatTimerEnded) {
print("First level started");
if (vars.shouldReset) {
vars.shouldReset = false;
}
// Set state
vars.inGame = true;
vars.comingFromMainMenu = false;
vars.isFirstLevel = true;
return true;
}
}
split {
if (current.resultsPage && vars.inGame) {
print("Exited level, split");
// Sum & reset timers
if (vars.isTraining) {
vars.sumOfTurnTimesMs += vars.lastEnteredLevelTotalMillisecondsPlayed
+ vars.currentTimerMilliseconds;
vars.currentTimerMilliseconds = 0;
vars.lastEnteredLevelTotalMillisecondsPlayed = 0;
} else {
vars.currentTimerSecondsRemaining = 0;
}
// Set state
vars.inGame = false;
vars.comingFromMainMenu = true;
return true;
}
}
gameTime {
if (vars.isTraining) {
return TimeSpan.FromMilliseconds(
vars.sumOfTurnTimesMs
+ vars.lastEnteredLevelTotalMillisecondsPlayed
+ vars.currentTimerMilliseconds);
}
}
isLoading {
if (vars.isTraining) {
// Needed to prevent the timer from flashing (adding 0.01s) when paused
return true;
}
return current.loading;
}