Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rubberduckycooly
GitHub Repository: rubberduckycooly/Sonic-1-Sonic-2-2013-Script-Decompilation
Path: blob/master/Sonic 2/Scripts/Enemies/Flasher.txt
1480 views
1
// ----------------------------------
2
// RSDK Project: Sonic 2
3
// Script Description: Flasher Object
4
// Script Author: Christian Whitehead/Simon Thomley
5
// Unpacked by Rubberduckycooly's script unpacker
6
// ----------------------------------
7
8
// ========================
9
// Aliases
10
// ========================
11
12
private alias object.value0 : object.timer
13
private alias object.value1 : object.holdTimer
14
private alias object.value2 : object.moveIndex
15
private alias object.value3 : object.flip
16
private alias object.value4 : object.turnIndex
17
private alias object.value5 : object.startPos.x
18
private alias object.value6 : object.startPos.y
19
20
// States
21
private alias 0 : FLASHER_PAUSED
22
private alias 1 : FLASHER_MOVING
23
private alias 2 : FLASHER_CHARGING
24
private alias 3 : FLASHER_FLASHING
25
private alias 4 : FLASHER_DIMMING
26
27
// Player Aliases
28
private alias object.value37 : player.shield
29
private alias object.value40 : player.hitboxLeft
30
private alias object.value38 : player.hitboxTop
31
private alias object.value41 : player.hitboxRight
32
private alias object.value39 : player.hitboxBottom
33
34
private alias 4 : SHIELD_LIGHTNING
35
36
37
// ========================
38
// Function Declarations
39
// ========================
40
41
reserve function Flasher_DebugDraw
42
reserve function Flasher_DebugSpawn
43
44
// ========================
45
// Tables
46
// ========================
47
48
// How long the Flasher should pause between movements
49
private table Flasher_delayTable
50
256, 416, 520, 645, 768, 832, 912, 1088, 61440
51
end table
52
53
// Which way the flasher should turn after each cycle
54
// First value in an entry is if it should turn around X-wise, second is for Y
55
private table Flasher_directionTable
56
1, 1
57
0, 1
58
1, 1
59
0, 1
60
0, 1
61
1, 0
62
0, 1
63
0, 1
64
end table
65
66
// The three below are animation tables, with values corresponding to SpriteFrames
67
// This is parallel to how the object's animation was handled in the original Sonic 2
68
private table Flasher_aniCharging
69
1, 0, 0, 0
70
0, 0, 1, 0
71
0, 0, 0, 1
72
0, 0, 1, 0
73
1, 0, 1, 0
74
1, 0, 1, 0
75
1, 0
76
end table
77
78
private table Flasher_aniFlashing
79
2, 3, 4, 3, 2, 0, 2
80
0, 3, 0, 4, 0, 3, 0
81
end table
82
83
private table Flasher_aniDimming
84
4, 4, 4, 4
85
3, 3, 3, 3
86
2, 2, 2, 2
87
1, 1, 1, 1
88
0, 0, 0, 0
89
end table
90
91
92
// ========================
93
// Function Definitions
94
// ========================
95
96
private function Flasher_DebugDraw
97
DrawSpriteFX(0, FX_FLIP, object.xpos, object.ypos)
98
end function
99
100
101
private function Flasher_DebugSpawn
102
CreateTempObject(TypeName[Flasher], 0, object.xpos, object.ypos)
103
end function
104
105
106
// ========================
107
// Events
108
// ========================
109
110
event ObjectUpdate
111
switch object.state
112
case FLASHER_PAUSED
113
// State only used upon init, just pause for a moment before starting to attack the player
114
object.timer++
115
if object.timer == 64
116
object.timer = 128
117
object.xvel = -0x10000
118
object.yvel = 0x4000
119
object.speed = 512
120
object.state = FLASHER_MOVING
121
if object.priority != PRIORITY_XBOUNDS_DESTROY
122
object.priority = PRIORITY_ACTIVE
123
end if
124
end if
125
126
foreach (GROUP_PLAYERS, currentPlayer, ACTIVE_ENTITIES)
127
BoxCollisionTest(C_TOUCH, object.entityPos, -8, -8, 8, 8, currentPlayer, player[currentPlayer].hitboxLeft, player[currentPlayer].hitboxTop, player[currentPlayer].hitboxRight, player[currentPlayer].hitboxBottom)
128
if checkResult == true
129
CallFunction(Player_BadnikBreak)
130
end if
131
next
132
break
133
134
case FLASHER_MOVING
135
if object.timer > 0
136
object.timer--
137
if object.xvel < 0
138
object.direction = FLIP_NONE
139
else
140
object.direction = FLIP_X
141
end if
142
143
GetTableValue(temp0, object.moveIndex, Flasher_delayTable)
144
object.holdTimer++
145
if object.holdTimer == temp0
146
GetTableValue(object.flip, object.turnIndex, Flasher_directionTable)
147
if object.flip == true
148
FlipSign(object.speed)
149
end if
150
151
object.turnIndex++
152
GetTableValue(object.flip, object.turnIndex, Flasher_directionTable)
153
if object.flip == true
154
FlipSign(object.yvel)
155
end if
156
157
object.turnIndex++
158
object.turnIndex &= 15
159
160
object.moveIndex++
161
if object.moveIndex == 10
162
object.moveIndex = 0
163
object.holdTimer = 0
164
end if
165
end if
166
167
object.xvel += object.speed
168
object.xpos += object.xvel
169
object.ypos += object.yvel
170
else
171
object.state = FLASHER_CHARGING
172
end if
173
174
foreach (GROUP_PLAYERS, currentPlayer, ACTIVE_ENTITIES)
175
BoxCollisionTest(C_TOUCH, object.entityPos, -8, -8, 8, 8, currentPlayer, player[currentPlayer].hitboxLeft, player[currentPlayer].hitboxTop, player[currentPlayer].hitboxRight, player[currentPlayer].hitboxBottom)
176
if checkResult == true
177
CallFunction(Player_BadnikBreak)
178
end if
179
next
180
break
181
182
case FLASHER_CHARGING
183
GetTableValue(object.frame, object.timer, Flasher_aniCharging)
184
object.timer++
185
if object.timer == 26
186
object.timer = 0
187
object.state = FLASHER_FLASHING
188
end if
189
190
foreach (GROUP_PLAYERS, currentPlayer, ACTIVE_ENTITIES)
191
BoxCollisionTest(C_TOUCH, object.entityPos, -8, -8, 8, 8, currentPlayer, C_BOX, C_BOX, C_BOX, C_BOX)
192
if player[currentPlayer].shield != SHIELD_LIGHTNING
193
if checkResult == true
194
CallFunction(Player_LightningHit)
195
else
196
BoxCollisionTest(C_TOUCH, object.entityPos, -8, -8, 8, 8, currentPlayer, player[currentPlayer].hitboxLeft, player[currentPlayer].hitboxTop, player[currentPlayer].hitboxRight, player[currentPlayer].hitboxBottom)
197
if checkResult == true
198
CallFunction(Player_BadnikBreak)
199
end if
200
end if
201
else
202
if checkResult == true
203
CallFunction(Player_BadnikBreak)
204
end if
205
end if
206
next
207
break
208
209
case FLASHER_FLASHING
210
GetTableValue(object.frame, object.animationTimer, Flasher_aniFlashing)
211
object.animationTimer++
212
if object.animationTimer == 14
213
object.animationTimer = 6
214
end if
215
216
object.timer++
217
if object.timer == 128
218
object.timer = 0
219
object.state = FLASHER_DIMMING
220
end if
221
222
foreach (GROUP_PLAYERS, currentPlayer, ACTIVE_ENTITIES)
223
if player[currentPlayer].shield != SHIELD_LIGHTNING
224
BoxCollisionTest(C_TOUCH, object.entityPos, -12, -12, 12, 12, currentPlayer, C_BOX, C_BOX, C_BOX, C_BOX)
225
if checkResult == true
226
CallFunction(Player_LightningHit)
227
else
228
BoxCollisionTest(C_TOUCH, object.entityPos, -8, -8, 8, 8, currentPlayer, player[currentPlayer].hitboxLeft, player[currentPlayer].hitboxTop, player[currentPlayer].hitboxRight, player[currentPlayer].hitboxBottom)
229
if checkResult == true
230
CallFunction(Player_BadnikBreak)
231
end if
232
end if
233
else
234
BoxCollisionTest(C_TOUCH, object.entityPos, -8, -8, 8, 8, currentPlayer, player[currentPlayer].hitboxLeft, player[currentPlayer].hitboxTop, player[currentPlayer].hitboxRight, player[currentPlayer].hitboxBottom)
235
if checkResult == true
236
CallFunction(Player_BadnikBreak)
237
end if
238
end if
239
next
240
break
241
242
case FLASHER_DIMMING
243
GetTableValue(object.frame, object.timer, Flasher_aniDimming)
244
object.timer++
245
if object.timer == 20
246
object.timer = 128
247
object.state = FLASHER_MOVING
248
end if
249
250
foreach (GROUP_PLAYERS, currentPlayer, ACTIVE_ENTITIES)
251
BoxCollisionTest(C_TOUCH, object.entityPos, -8, -8, 8, 8, currentPlayer, C_BOX, C_BOX, C_BOX, C_BOX)
252
if player[currentPlayer].shield != SHIELD_LIGHTNING
253
if checkResult == true
254
CallFunction(Player_LightningHit)
255
else
256
BoxCollisionTest(C_TOUCH, object.entityPos, -8, -8, 8, 8, currentPlayer, player[currentPlayer].hitboxLeft, player[currentPlayer].hitboxTop, player[currentPlayer].hitboxRight, player[currentPlayer].hitboxBottom)
257
if checkResult == true
258
CallFunction(Player_BadnikBreak)
259
end if
260
end if
261
else
262
if checkResult == true
263
CallFunction(Player_BadnikBreak)
264
end if
265
end if
266
next
267
break
268
269
end switch
270
271
if object.outOfBounds == true
272
// Even if out of bounds, only despawn the Flasher if its startPos is OOB too
273
temp0 = object.xpos
274
temp1 = object.ypos
275
object.xpos = object.startPos.x
276
object.ypos = object.startPos.y
277
if object.outOfBounds == true
278
if object.priority != PRIORITY_XBOUNDS_DESTROY
279
object.timer = 0
280
object.frame = 0
281
object.state = FLASHER_PAUSED
282
object.priority = PRIORITY_BOUNDS
283
end if
284
else
285
// Object startPos is within bounds, move the Flasher back and continue as normal
286
object.xpos = temp0
287
object.ypos = temp1
288
end if
289
end if
290
end event
291
292
293
event ObjectDraw
294
DrawSpriteFX(object.frame, FX_FLIP, object.xpos, object.ypos)
295
end event
296
297
298
event ObjectStartup
299
CheckCurrentStageFolder("Zone06")
300
if checkResult == true
301
LoadSpriteSheet("MCZ/Objects.gif")
302
303
// Normal frame
304
SpriteFrame(-16, -8, 23, 15, 1, 1)
305
306
// Lighting Frames
307
SpriteFrame(-16, -8, 23, 15, 25, 1)
308
SpriteFrame(-16, -8, 24, 16, 1, 17)
309
SpriteFrame(-16, -12, 28, 24, 1, 34)
310
SpriteFrame(-16, -16, 32, 32, 1, 59)
311
else
312
// Note - even if these are spriteframes for MBZ, they're broken with values copied directly from MCZ's sheet
313
// Using these sheet positions results in some of Eggman's head frames
314
LoadSpriteSheet("MBZ/Objects.gif")
315
316
// Normal frame
317
SpriteFrame(-16, -8, 23, 15, 1, 1)
318
319
// Lighting Frames
320
SpriteFrame(-16, -8, 23, 15, 25, 1)
321
SpriteFrame(-16, -8, 24, 16, 1, 17)
322
SpriteFrame(-16, -12, 28, 24, 1, 34)
323
SpriteFrame(-16, -16, 32, 32, 1, 59)
324
end if
325
326
foreach (TypeName[Flasher], arrayPos0, ALL_ENTITIES)
327
object[arrayPos0].startPos.x = object[arrayPos0].xpos
328
object[arrayPos0].startPos.y = object[arrayPos0].ypos
329
next
330
331
SetTableValue(TypeName[Flasher], DebugMode_ObjCount, DebugMode_TypesTable)
332
SetTableValue(Flasher_DebugDraw, DebugMode_ObjCount, DebugMode_DrawTable)
333
SetTableValue(Flasher_DebugSpawn, DebugMode_ObjCount, DebugMode_SpawnTable)
334
DebugMode_ObjCount++
335
end event
336
337
338
// ========================
339
// Editor Events
340
// ========================
341
342
event RSDKDraw
343
DrawSpriteFX(0, FX_FLIP, object.xpos, object.ypos)
344
end event
345
346
347
event RSDKLoad
348
CheckCurrentStageFolder("Zone06")
349
if checkResult == true
350
LoadSpriteSheet("MCZ/Objects.gif")
351
SpriteFrame(-16, -8, 23, 15, 1, 1)
352
else
353
LoadSpriteSheet("MBZ/Objects.gif")
354
SpriteFrame(-16, -8, 23, 15, 125, 501) // Decomp note - using fixed frame here
355
end if
356
357
SetVariableAlias(ALIAS_VAR_PROPVAL, "unused")
358
end event
359
360