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/OOZ/Eggman.txt
1482 views
1
// ----------------------------------
2
// RSDK Project: Sonic 2
3
// Script Description: Eggman Object
4
// Script Author: Christian Whitehead/Simon Thomley
5
// Unpacked by Rubberduckycooly's script unpacker
6
// ----------------------------------
7
8
// Using OOZEggman as a prefix here because there's like 12 "Eggman" objects in the game so its less confusing this way
9
10
// ========================
11
// Aliases
12
// ========================
13
14
private alias object.value0 : object.timer
15
private alias object.value1 : object.originPos.y
16
private alias object.value2 : object.oscillationAngle
17
private alias object.value3 : object.health
18
private alias object.value4 : object.invincibilityTimer
19
private alias object.value5 : object.exploding
20
private alias object.value6 : object.emergeTargetPos
21
private alias object.value7 : object.highestEmergePos
22
private alias object.value8 : object.submergeTargetPos
23
private alias object.value9 : object.spawnHarpoon
24
25
// Eggman States
26
private alias 0 : OOZEGGMAN_AWAITPLAYER
27
private alias 1 : OOZEGGMAN_STARTBOSS
28
private alias 2 : OOZEGGMAN_EMERGE
29
private alias 3 : OOZEGGMAN_LOOKAROUND
30
private alias 4 : OOZEGGMAN_SUBMERGE
31
private alias 5 : OOZEGGMAN_HARPOONATTACK
32
private alias 6 : OOZEGGMAN_CANNONATTACK
33
private alias 7 : OOZEGGMAN_EXPLODE
34
private alias 8 : OOZEGGMAN_DEFEATED
35
private alias 9 : OOZEGGMAN_ESCAPE
36
37
// Eggman Animations
38
private alias 0 : OOZEGGANI_INVISIBLE
39
private alias 1 : OOZEGGANI_IDLE
40
private alias 2 : OOZEGGANI_LAUGH
41
private alias 3 : OOZEGGANI_HIT
42
private alias 4 : OOZEGGANI_DEFEATED
43
private alias 5 : OOZEGGANI_TOASTED
44
private alias 6 : OOZEGGANI_PANIC
45
46
// Player Aliases
47
private alias object.xpos : player.xpos
48
private alias object.xvel : player.xvel
49
private alias object.speed : player.speed
50
private alias object.animation : player.animation
51
private alias object.collisionRight : player.collisionRight
52
53
private alias object.value40 : player.hitboxLeft
54
private alias object.value38 : player.hitboxTop
55
private alias object.value41 : player.hitboxRight
56
private alias object.value39 : player.hitboxBottom
57
58
// Music Events
59
private alias 26 : SLOT_MUSICEVENT_BOSS
60
61
private alias 0 : MUSICEVENT_FADETOBOSS
62
private alias 1 : MUSICEVENT_FADETOSTAGE
63
64
65
// ========================
66
// Function Declarations
67
// ========================
68
69
reserve function OOZEggman_Oscillate
70
71
72
// ========================
73
// Function Definitions
74
// ========================
75
76
private function OOZEggman_Oscillate
77
Sin256(object.ypos, object.oscillationAngle)
78
object.ypos <<= 9
79
object.ypos += object.originPos.y
80
object.oscillationAngle += 4
81
object.oscillationAngle &= 0xFF
82
end function
83
84
85
// ========================
86
// Events
87
// ========================
88
89
event ObjectUpdate
90
switch object.state
91
case OOZEGGMAN_AWAITPLAYER
92
if player[0].xpos > object.xpos
93
temp0 = screen.xcenter
94
FlipSign(temp0)
95
if temp0 > -192
96
temp0 = -192
97
end if
98
temp0 += object.ixpos
99
stage.newXBoundary1 = temp0
100
101
temp0 = screen.xcenter
102
if temp0 < 192
103
temp0 = 192
104
end if
105
temp0 += object.ixpos
106
stage.newXBoundary2 = temp0
107
108
temp0 = stage.newYBoundary2
109
temp0 -= screen.ysize
110
stage.newYBoundary1 = temp0
111
112
object.emergeTargetPos = object.ypos
113
object.emergeTargetPos -= 0x400000
114
object.highestEmergePos = object.ypos
115
object.highestEmergePos -= 0x440000
116
object.submergeTargetPos = object.ypos
117
object.animation = OOZEGGANI_IDLE
118
ResetObjectEntity(SLOT_MUSICEVENT_BOSS, TypeName[Music Event], MUSICEVENT_FADETOBOSS, 0, 0)
119
object[SLOT_MUSICEVENT_BOSS].priority = PRIORITY_ACTIVE
120
121
#platform: USE_STANDALONE
122
object.health = 8
123
#endplatform
124
#platform: USE_ORIGINS
125
if game.bossOneLife == false
126
object.health = 8
127
else
128
object.health = 1
129
end if
130
#endplatform
131
132
object.priority = PRIORITY_ACTIVE
133
object.state = OOZEGGMAN_STARTBOSS
134
end if
135
break
136
137
case OOZEGGMAN_STARTBOSS
138
object.timer++
139
if object.timer == 60
140
object.timer = 0
141
object.yvel = -0x8000
142
if player[0].xpos > object.xpos
143
object.direction = FLIP_NONE
144
else
145
object.direction = FLIP_X
146
end if
147
object.state = OOZEGGMAN_EMERGE
148
end if
149
break
150
151
case OOZEGGMAN_EMERGE
152
object.ypos += object.yvel
153
if object.ypos <= object.emergeTargetPos
154
object.ypos = object.emergeTargetPos
155
object.originPos.y = object.ypos
156
object.oscillationAngle = 0
157
object.state = OOZEGGMAN_LOOKAROUND
158
end if
159
160
if object.animation == OOZEGGANI_IDLE
161
object.animationTimer = 0
162
end if
163
break
164
165
case OOZEGGMAN_LOOKAROUND
166
CallFunction(OOZEggman_Oscillate)
167
168
// If we got hit, get outta here!
169
object.timer++
170
if object.invincibilityTimer > 0
171
object.timer = 168
172
end if
173
174
if object.timer == 168
175
object.timer = 0
176
object.yvel = -0x4000
177
object.state = OOZEGGMAN_SUBMERGE
178
end if
179
break
180
181
// This state also manages the harpoon/cannon
182
case OOZEGGMAN_SUBMERGE
183
object.ypos += object.yvel
184
if object.ypos < object.highestEmergePos
185
object.ypos = object.highestEmergePos
186
object.yvel = 0x8000
187
end if
188
189
if object.ypos >= object.submergeTargetPos
190
object.ypos = object.submergeTargetPos
191
object.yvel = -0x8000
192
if player[0].xpos > object.xpos
193
object.direction = FLIP_NONE
194
else
195
object.direction = FLIP_X
196
end if
197
198
if object.spawnHarpoon == true
199
temp0 = object.entityPos
200
temp0++
201
ResetObjectEntity(temp0, TypeName[Eggman Harpoon], object.direction, object.xpos, object.ypos)
202
object[+1].ypos -= 0x300000
203
object[+1].priority = PRIORITY_ACTIVE
204
object.state = OOZEGGMAN_HARPOONATTACK
205
else
206
temp0 = object.entityPos
207
temp0++
208
ResetObjectEntity(temp0, TypeName[Eggman Cannon], object.direction, object.xpos, object.ypos)
209
object[+1].ypos -= 0x200000
210
object[+1].priority = PRIORITY_ACTIVE
211
object.state = OOZEGGMAN_CANNONATTACK
212
end if
213
214
object.visible = false
215
object.spawnHarpoon = false
216
end if
217
218
if object.animation == OOZEGGANI_IDLE
219
object.animationTimer = 0
220
end if
221
break
222
223
// Wait for the harpoon attack to be over, then do the cannon attack
224
case OOZEGGMAN_HARPOONATTACK
225
if object[+1].type == TypeName[Blank Object]
226
temp0 = object.entityPos
227
temp0++
228
ResetObjectEntity(temp0, TypeName[Eggman Cannon], object.direction, object.xpos, object.ypos)
229
object[+1].ypos -= 0x200000
230
object[+1].priority = PRIORITY_ACTIVE
231
object.state = OOZEGGMAN_CANNONATTACK
232
end if
233
break
234
235
// Wait for the cannon attack to be over, then emerge
236
case OOZEGGMAN_CANNONATTACK
237
if object[+1].type == TypeName[Blank Object]
238
object.visible = true
239
object.state = OOZEGGMAN_EMERGE
240
end if
241
break
242
243
case OOZEGGMAN_EXPLODE
244
object.timer++
245
if object.timer == 180
246
object.timer = 0
247
object.animation = OOZEGGANI_TOASTED
248
object.exploding = false
249
object.state = OOZEGGMAN_DEFEATED
250
ResetObjectEntity(SLOT_MUSICEVENT_BOSS, TypeName[Music Event], MUSICEVENT_FADETOSTAGE, 0, 0)
251
object[SLOT_MUSICEVENT_BOSS].priority = PRIORITY_ACTIVE
252
temp0 = tileLayer[0].xsize
253
temp0 <<= 7
254
stage.newXBoundary2 = temp0
255
end if
256
break
257
258
case OOZEGGMAN_DEFEATED
259
object.timer++
260
if object.timer == 30
261
object.yvel = 0
262
object.timer = 0
263
object.state = OOZEGGMAN_ESCAPE
264
end if
265
break
266
267
case OOZEGGMAN_ESCAPE
268
if object.yvel < 0x10000
269
object.yvel += 0x400
270
end if
271
272
object.ypos += object.yvel
273
if object.ypos > object.submergeTargetPos
274
ResetObjectEntity(object.entityPos, TypeName[Blank Object], 0, 0, 0)
275
end if
276
break
277
278
end switch
279
280
if object.health != 0
281
if object.invincibilityTimer > 0
282
object.invincibilityTimer--
283
GetBit(temp0, object.invincibilityTimer, 0)
284
if temp0 == true
285
SetPaletteEntry(0, 192, 0xE0E0E0)
286
else
287
SetPaletteEntry(0, 192, 0x000000)
288
end if
289
end if
290
291
if object.visible == true
292
foreach (GROUP_PLAYERS, currentPlayer, ACTIVE_ENTITIES)
293
if object.invincibilityTimer < 32
294
CheckEqual(player[currentPlayer].animation, ANI_HURT)
295
temp0 = checkResult
296
CheckEqual(player[currentPlayer].animation, ANI_DYING)
297
temp0 |= checkResult
298
CheckEqual(player[currentPlayer].animation, ANI_DROWNING)
299
temp0 |= checkResult
300
if temp0 != 0
301
if object.animation != OOZEGGANI_LAUGH
302
object.animation = OOZEGGANI_LAUGH
303
object.animationTimer = 0
304
end if
305
end if
306
307
BoxCollisionTest(C_TOUCH, object.entityPos, -24, -10, 24, 24, currentPlayer, player[currentPlayer].hitboxLeft, player[currentPlayer].hitboxTop, player[currentPlayer].hitboxRight, player[currentPlayer].hitboxBottom)
308
if checkResult == true
309
CallFunction(Player_CheckHit)
310
if checkResult == true
311
object.health--
312
if object.health == 0
313
#platform: USE_ORIGINS
314
CallNativeFunction2(NotifyCallback, NOTIFY_KILL_BOSS, 0)
315
CallNativeFunction2(NotifyCallback, NOTIFY_BOSS_END, 1)
316
#endplatform
317
318
player.score += 1000
319
object.timer = 0
320
object.animation = OOZEGGANI_DEFEATED
321
object.animationTimer = 0
322
object.exploding = true
323
object.originPos.y = object.ypos
324
object.state = OOZEGGMAN_EXPLODE
325
SetPaletteEntry(0, 192, 0x000000)
326
else
327
object.animation = OOZEGGANI_HIT
328
object.animationTimer = 0
329
object.invincibilityTimer = 64
330
object.spawnHarpoon = true
331
PlaySfx(SfxName[Boss Hit], false)
332
end if
333
end if
334
end if
335
end if
336
next
337
end if
338
end if
339
340
// Handle Right Stage Boundary
341
if object.state != OOZEGGMAN_ESCAPE
342
foreach (GROUP_PLAYERS, currentPlayer, ACTIVE_ENTITIES)
343
temp0 = player[currentPlayer].collisionRight
344
temp0 <<= 16
345
temp0 += player[currentPlayer].xpos
346
temp1 = stage.curXBoundary2
347
temp1 <<= 16
348
if temp0 > temp1
349
player[currentPlayer].xvel = 0
350
player[currentPlayer].speed = 0
351
player[currentPlayer].xpos = temp1
352
temp0 = player[currentPlayer].collisionRight
353
temp0 <<= 16
354
player[currentPlayer].xpos -= temp0
355
end if
356
next
357
end if
358
359
// Exploding stuff
360
if object.exploding == true
361
temp0 = oscillation
362
temp0 &= 7
363
if temp0 == 0
364
Rand(temp0, 48)
365
temp0 -= 24
366
temp0 <<= 16
367
temp0 += object.xpos
368
369
Rand(temp1, 48)
370
temp1 -= 24
371
temp1 <<= 16
372
temp1 += object.ypos
373
374
CreateTempObject(TypeName[Explosion], 0, temp0, temp1)
375
object[tempObjectPos].drawOrder = 5
376
PlaySfx(SfxName[Explosion], false)
377
end if
378
end if
379
end event
380
381
382
event ObjectDraw
383
// Submarine
384
DrawSpriteFX(6, FX_FLIP, object.xpos, object.ypos)
385
386
switch object.animation
387
default
388
case OOZEGGANI_INVISIBLE
389
break
390
391
case OOZEGGANI_IDLE
392
temp0 = object.animationTimer
393
temp0 /= 40
394
object.animationTimer++
395
object.animationTimer %= 80
396
DrawSpriteFX(temp0, FX_FLIP, object.xpos, object.ypos)
397
break
398
399
case OOZEGGANI_LAUGH
400
temp0 = object.animationTimer
401
temp0 &= 15
402
temp0 >>= 3
403
temp0 += 2
404
object.animationTimer++
405
if object.animationTimer == 50
406
object.animationTimer = 0
407
if player[0].animation != ANI_DYING
408
object.animation = OOZEGGANI_IDLE
409
end if
410
end if
411
DrawSpriteFX(temp0, FX_FLIP, object.xpos, object.ypos)
412
break
413
414
case OOZEGGANI_HIT
415
temp0 = object.animationTimer
416
temp0 &= 1
417
temp0 += 2
418
object.animationTimer++
419
if object.animationTimer == 50
420
object.animationTimer = 0
421
object.animation = OOZEGGANI_IDLE
422
end if
423
DrawSpriteFX(4, FX_FLIP, object.xpos, object.ypos)
424
break
425
426
case OOZEGGANI_DEFEATED
427
temp0 = object.animationTimer
428
temp0 >>= 5
429
temp0 += 4
430
temp0 %= 5
431
object.animationTimer++
432
object.animationTimer &= 63
433
DrawSpriteFX(temp0, FX_FLIP, object.xpos, object.ypos)
434
break
435
436
case OOZEGGANI_TOASTED
437
DrawSpriteFX(5, FX_FLIP, object.xpos, object.ypos)
438
break
439
440
case OOZEGGANI_PANIC
441
DrawSpriteFX(5, FX_FLIP, object.xpos, object.ypos)
442
break
443
444
end switch
445
end event
446
447
448
event ObjectStartup
449
SetPaletteEntry(0, 192, 0x000000) // This is already reset in [OOZSetup]... does it really need to be done again here?
450
CheckCurrentStageFolder("Zone07")
451
if checkResult == true
452
LoadSpriteSheet("OOZ/Objects.gif")
453
SpriteFrame(-12, -12, 24, 12, 462, 118) // Eggman (Idle) - #0
454
SpriteFrame(-12, -12, 24, 12, 487, 118) // Eggman (Looking) - #1
455
SpriteFrame(-12, -12, 24, 12, 462, 131) // Eggman (Laugh 1) - #2
456
SpriteFrame(-12, -12, 24, 12, 487, 131) // Eggman (Laugh 2) - #3
457
SpriteFrame(-12, -12, 24, 12, 462, 144) // Eggman (Hit) - #4
458
SpriteFrame(-12, -12, 24, 12, 487, 144) // Eggman (Defeated) - #5
459
SpriteFrame(-48, -32, 96, 64, 365, 125) // Submarine - #6
460
461
if options.vsMode == true
462
foreach (TypeName[Eggman], arrayPos0, ALL_ENTITIES)
463
object[arrayPos0].type = TypeName[Blank Object]
464
next
465
end if
466
else
467
LoadSpriteSheet("MBZ/Objects.gif")
468
SpriteFrame(-12, -12, 24, 12, 413, 91) // Eggman (Idle) - #0
469
SpriteFrame(-12, -12, 24, 12, 438, 91) // Eggman (Looking) - #1
470
SpriteFrame(-12, -12, 24, 12, 413, 104) // Eggman (Laugh 1) - #2
471
SpriteFrame(-12, -12, 24, 12, 438, 104) // Eggman (Laugh 2) - #3
472
SpriteFrame(-12, -12, 24, 12, 413, 117) // Eggman (Hit) - #4
473
SpriteFrame(-12, -12, 24, 12, 438, 117) // Eggman (Defeated) - #5
474
SpriteFrame(-48, -32, 96, 64, 313, 112) // Submarine - #6
475
end if
476
end event
477
478
479
// ========================
480
// Editor Events
481
// ========================
482
483
event RSDKDraw
484
DrawSprite(1) // Sub
485
DrawSprite(0) // Eggman
486
end event
487
488
489
event RSDKLoad
490
CheckCurrentStageFolder("Zone07")
491
if checkResult == true
492
LoadSpriteSheet("OOZ/Objects.gif")
493
SpriteFrame(-12, -12, 24, 12, 462, 118) // Eggman (Idle) - #0
494
SpriteFrame(-48, -32, 96, 64, 365, 125) // Submarine - #1
495
else
496
LoadSpriteSheet("MBZ/Objects.gif")
497
SpriteFrame(-12, -12, 24, 12, 413, 91) // Eggman (Idle) - #0
498
SpriteFrame(-48, -32, 96, 64, 313, 112) // Submarine - #1
499
end if
500
501
SetVariableAlias(ALIAS_VAR_PROPVAL, "unused")
502
end event
503
504