Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rubberduckycooly
GitHub Repository: rubberduckycooly/Sonic-1-Sonic-2-2013-Script-Decompilation
Path: blob/master/Sonic 1/Scripts/SLZ/Eggman.txt
1482 views
1
// ----------------------------------
2
// RSDK Project: Sonic 1
3
// Script Description: SLZ Eggman Object
4
// Script Author: Christian Whitehead/Simon Thomley
5
// Unpacked by Rubberduckycooly's script unpacker
6
// ----------------------------------
7
8
// Using SLZEggman as a prefix here because there's like 6 "eggman" objects in the game so its less confusing this way
9
10
// ========================
11
// Aliases
12
// ========================
13
14
private alias object.value0 : object.originPos.x
15
private alias object.value1 : object.originPos.y
16
private alias object.value2 : object.oscillateAngle
17
private alias object.value4 : object.timer
18
private alias object.value5 : object.flameAnim
19
private alias object.value6 : object.flameAnimTimer
20
private alias object.value7 : object.health
21
private alias object.value8 : object.invincibilityTimer
22
private alias object.value9 : object.targetSeeSaw
23
private alias object.value10 : object.boundsL
24
private alias object.value11 : object.boundsR
25
private alias object.value12 : object.targetScreenPos.y
26
private alias object.value13 : object.playerHit // as in, if Eggman's been hit by the player at all (as opposed to getting hit by a seesaw bomb)
27
28
// SeeSaw Aliases
29
private alias object.value0 : object.orbTimer
30
private alias object.value8 : object.orbTargetPos.x
31
private alias object.value9 : object.orbTargetPos.y
32
private alias object.value10 : object.orbFrame
33
private alias object.value12 : object.stood
34
35
private alias 2 : SEESAW_ORB_LAUNCHED
36
private alias 3 : SEESAW_NO_ORB
37
38
// Eggman States
39
private alias 0 : SLZEGGMAN_AWAITPLAYER
40
private alias 1 : SLZEGGMAN_ENTEREGGMAN
41
private alias 2 : SLZEGGMAN_MOVEANDDROP
42
private alias 3 : SLZEGGMAN_DROPPEDBALL
43
private alias 4 : SLZEGGMAN_EXPLODE
44
private alias 5 : SLZEGGMAN_DEFEATFALL
45
private alias 6 : SLZEGGMAN_DEFEATRISE
46
private alias 7 : SLZEGGMAN_FLEE
47
private alias 8 : SLZEGGMAN_ESCAPE
48
49
// Eggman Animations
50
private alias 0 : SLZEGGANI_INVISIBLE
51
private alias 1 : SLZEGGANI_IDLE
52
private alias 2 : SLZEGGANI_LAUGH
53
private alias 3 : SLZEGGANI_HIT
54
private alias 4 : SLZEGGANI_DEFEATED
55
private alias 5 : SLZEGGANI_TOASTED
56
private alias 6 : SLZEGGANI_PANIC
57
58
// Flame Animations
59
private alias 0 : FLAME_INACTIVE
60
private alias 1 : FLAME_ACTIVE
61
private alias 2 : FLAME_EXPLODE
62
63
// Music Events
64
private alias 26 : SLOT_MUSICEVENT_BOSS
65
66
private alias 0 : MUSICEVENT_FADETOBOSS
67
private alias 1 : MUSICEVENT_FADETOSTAGE
68
private alias 2 : MUSICEVENT_TRANSITION
69
70
// Player Aliases
71
private alias object.xpos : player.xpos
72
private alias object.xvel : player.xvel
73
private alias object.speed : player.speed
74
private alias object.animation : player.animation
75
private alias object.collisionRight : player.collisionRight
76
77
private alias object.value40 : player.hitboxLeft
78
private alias object.value38 : player.hitboxTop
79
private alias object.value41 : player.hitboxRight
80
private alias object.value39 : player.hitboxBottom
81
82
// Achievement Aliases
83
private alias 7 : ACHIEVEMENT_BOMBSAWAY
84
85
86
// ========================
87
// Function Declarations
88
// ========================
89
90
reserve function SLZEggman_Hit
91
reserve function SLZEggman_DropSpikeBall
92
reserve function SLZEggman_Oscillate
93
94
95
// ========================
96
// Tables
97
// ========================
98
99
// entityPos offsets
100
private table SLZEggman_seesawSlotOffsets
101
2, 3, 1
102
end table
103
104
// x positions of where Eggman should drop bombs
105
private table SLZEggman_seesawDropPos[6]
106
107
108
// ========================
109
// Function Definitions
110
// ========================
111
112
private function SLZEggman_Hit
113
object.health--
114
if object.health == 0
115
#platform: USE_ORIGINS
116
CallNativeFunction2(NotifyCallback, NOTIFY_KILL_BOSS, 0)
117
CallNativeFunction2(NotifyCallback, NOTIFY_BOSS_END, true)
118
#endplatform
119
player.score += 1000
120
object.flameAnim = FLAME_INACTIVE
121
object.animation = SLZEGGANI_DEFEATED
122
object.animationTimer = 0
123
object.state = SLZEGGMAN_EXPLODE
124
if stage.debugMode == false
125
if object.playerHit == false
126
// Grant the "Bombs Away" Achievement
127
CallNativeFunction2(SetAchievement, ACHIEVEMENT_BOMBSAWAY, 100)
128
end if
129
end if
130
else
131
object.animation = SLZEGGANI_HIT
132
object.animationTimer = 0
133
object.invincibilityTimer = 32
134
PlaySfx(SfxName[Boss Hit], false)
135
end if
136
end function
137
138
139
private function SLZEggman_DropSpikeBall
140
arrayPos0 = object.entityPos
141
temp1 = object.targetSeeSaw
142
temp1 >>= 1
143
GetTableValue(temp2, temp1, SLZEggman_seesawSlotOffsets)
144
arrayPos0 -= temp2
145
if object[arrayPos0].state == SEESAW_NO_ORB
146
if object[arrayPos0].stood == false
147
object.xpos = temp0
148
object[arrayPos0].state = SEESAW_ORB_LAUNCHED
149
object[arrayPos0].xvel = 0
150
object[arrayPos0].yvel = 0
151
object[arrayPos0].orbTargetPos.x = object.xpos
152
object[arrayPos0].orbTargetPos.y = object.ypos
153
object[arrayPos0].orbTargetPos.y += 0x200000
154
object[arrayPos0].orbTimer = 240
155
object[arrayPos0].orbFrame = 2
156
object[arrayPos0].animationTimer = 44
157
object.timer = 40
158
object.flameAnim = FLAME_INACTIVE
159
object.state++ // should move state into SLZEGGMAN_DROPPEDBALL
160
end if
161
end if
162
end function
163
164
165
private function SLZEggman_Oscillate
166
Sin256(temp0, object.oscillateAngle)
167
temp0 <<= 10
168
object.ypos += temp0
169
object.oscillateAngle += 2
170
object.oscillateAngle &= 0xFF
171
end function
172
173
174
// ========================
175
// Events
176
// ========================
177
178
event ObjectUpdate
179
switch object.state
180
case SLZEGGMAN_AWAITPLAYER
181
if player[0].xpos >= object[-3].xpos
182
temp0 = object[-3].ixpos
183
temp0 -= screen.xcenter
184
stage.newXBoundary1 = temp0
185
temp0 = object[-3].ixpos
186
temp0 += screen.xcenter
187
stage.newXBoundary2 = temp0
188
if screen.yoffset == object.targetScreenPos.y
189
object.state++
190
object.priority = PRIORITY_ACTIVE
191
ResetObjectEntity(SLOT_MUSICEVENT_BOSS, TypeName[Music Event], MUSICEVENT_FADETOBOSS, 0, 0)
192
object[SLOT_MUSICEVENT_BOSS].priority = PRIORITY_ACTIVE
193
else
194
object.targetScreenPos.y = screen.yoffset
195
end if
196
end if
197
break
198
199
case SLZEGGMAN_ENTEREGGMAN
200
object.xpos += object.xvel
201
temp0 = object[-3].xpos
202
temp0 += 0x800000
203
if object.xpos < temp0
204
object.state++
205
temp1 = screen.xcenter
206
temp1 -= 4
207
temp1 <<= 8
208
temp1 /= 160
209
temp1 *= -512
210
object.xvel = temp1
211
end if
212
object.ypos = object.originPos.y
213
CallFunction(SLZEggman_Oscillate)
214
break
215
216
case SLZEGGMAN_MOVEANDDROP
217
object.xpos += object.xvel
218
if object.direction == FLIP_NONE
219
if object.xpos <= object.boundsL
220
object.xpos = object.boundsL
221
FlipSign(object.xvel)
222
object.direction ^= FLIP_X
223
else
224
GetTableValue(temp0, object.targetSeeSaw, SLZEggman_seesawDropPos)
225
if object.xpos <= temp0
226
CallFunction(SLZEggman_DropSpikeBall)
227
object.targetSeeSaw--
228
if object.targetSeeSaw < 0
229
object.targetSeeSaw = 1
230
end if
231
end if
232
object.targetSeeSaw &= 14
233
end if
234
else
235
if object.xpos >= object.boundsR
236
object.xpos = object.boundsR
237
FlipSign(object.xvel)
238
object.direction ^= FLIP_X
239
else
240
GetTableValue(temp0, object.targetSeeSaw, SLZEggman_seesawDropPos)
241
if object.xpos >= temp0
242
CallFunction(SLZEggman_DropSpikeBall)
243
object.targetSeeSaw++
244
if object.targetSeeSaw > 5
245
object.targetSeeSaw = 4
246
end if
247
end if
248
object.targetSeeSaw |= 1
249
end if
250
end if
251
object.ypos = object.originPos.y
252
CallFunction(SLZEggman_Oscillate)
253
break
254
255
case SLZEGGMAN_DROPPEDBALL
256
object.timer--
257
if object.timer <= 0
258
object.flameAnim = FLAME_ACTIVE
259
object.state--
260
end if
261
break
262
263
case SLZEGGMAN_EXPLODE
264
object.timer++
265
temp0 = object.timer
266
temp0 &= 7
267
if temp0 == 4
268
Rand(temp0, 96)
269
temp0 -= 48
270
temp0 <<= 16
271
temp0 += object.xpos
272
Rand(temp1, 48)
273
temp1 -= 24
274
temp1 <<= 16
275
temp1 += object.ypos
276
CreateTempObject(TypeName[Explosion], 0, temp0, temp1)
277
PlaySfx(SfxName[Explosion], false)
278
end if
279
280
if object.timer == 180
281
object.animation = SLZEGGANI_TOASTED
282
object.animationTimer = 0
283
object.timer = 0
284
object.direction = FLIP_X
285
ResetObjectEntity(SLOT_MUSICEVENT_BOSS, TypeName[Music Event], MUSICEVENT_FADETOSTAGE, 0, 0)
286
object[SLOT_MUSICEVENT_BOSS].priority = PRIORITY_ACTIVE
287
object.state++
288
end if
289
break
290
291
case SLZEGGMAN_DEFEATFALL
292
object.ypos += object.yvel
293
object.yvel += 0x1800
294
object.timer++
295
if object.timer == 38
296
object.yvel = 0
297
object.timer = 0
298
object.animationTimer = 0
299
object.state++
300
end if
301
break
302
303
case SLZEGGMAN_DEFEATRISE
304
if object.timer < 48
305
object.ypos += object.yvel
306
object.yvel -= 0x800
307
object.timer++
308
else
309
object.timer = 0
310
object.yvel = 0
311
object.originPos.y = object.ypos
312
object.state++
313
end if
314
break
315
316
case SLZEGGMAN_FLEE
317
object.ypos = object.originPos.y
318
CallFunction(SLZEggman_Oscillate)
319
if object.timer < 8
320
object.timer++
321
else
322
object.timer = 0
323
object.animation = SLZEGGANI_PANIC
324
object.animationTimer = 0
325
object.flameAnim = FLAME_EXPLODE
326
object.flameAnimTimer = 0
327
object.priority = PRIORITY_ACTIVE
328
temp0 = tileLayer[0].xsize
329
temp0 <<= 7
330
stage.newXBoundary2 = temp0
331
object.state++
332
end if
333
break
334
335
case SLZEGGMAN_ESCAPE
336
object.xpos += 0x40000
337
object.originPos.y -= 0x4000
338
object.ypos = object.originPos.y
339
CallFunction(SLZEggman_Oscillate)
340
341
if object.outOfBounds == true
342
object.type = TypeName[Blank Object]
343
object.priority = PRIORITY_BOUNDS
344
end if
345
break
346
347
end switch
348
349
if object.health != 0
350
if object.invincibilityTimer > 0
351
object.invincibilityTimer--
352
end if
353
354
foreach (GROUP_PLAYERS, currentPlayer, ACTIVE_ENTITIES)
355
if object.invincibilityTimer == 0
356
CheckEqual(player[currentPlayer].animation, ANI_HURT)
357
temp0 = checkResult
358
CheckEqual(player[currentPlayer].animation, ANI_DYING)
359
temp0 |= checkResult
360
CheckEqual(player[currentPlayer].animation, ANI_DROWNING)
361
temp0 |= checkResult
362
if temp0 != false
363
if object.animation != SLZEGGANI_LAUGH
364
object.animation = SLZEGGANI_LAUGH
365
object.animationTimer = 0
366
end if
367
end if
368
369
#platform: USE_STANDALONE
370
BoxCollisionTest(C_TOUCH, object.entityPos, -20, -16, 20, 16, currentPlayer, C_BOX, C_BOX, C_BOX, C_BOX)
371
#endplatform
372
#platform: USE_ORIGINS
373
BoxCollisionTest(C_TOUCH, object.entityPos, -20, -16, 20, 16, currentPlayer, player[currentPlayer].hitboxLeft, player[currentPlayer].hitboxTop, player[currentPlayer].hitboxRight, player[currentPlayer].hitboxBottom)
374
#endplatform
375
if checkResult == true
376
CallFunction(Player_CheckHit)
377
if checkResult == true
378
object.playerHit = true // since we've hit Eggman ourselves instead of using a seesaw bomb, we're no longer eligible for the Bombs Away achievement..
379
CallFunction(SLZEggman_Hit)
380
end if
381
end if
382
end if
383
next
384
385
if object.invincibilityTimer == 0
386
foreach (TypeName[SeeSaw], arrayPos0, ACTIVE_ENTITIES)
387
if object[arrayPos0].state != SEESAW_NO_ORB
388
temp0 = object[arrayPos0].xpos
389
temp1 = object[arrayPos0].ypos
390
object[arrayPos0].xpos = object[arrayPos0].orbTargetPos.x
391
object[arrayPos0].ypos = object[arrayPos0].orbTargetPos.y
392
BoxCollisionTest(C_TOUCH, object.entityPos, -20, -16, 20, 16, arrayPos0, -7, -7, 7, 7)
393
if checkResult == true
394
CallFunction(SLZEggman_Hit)
395
CreateTempObject(TypeName[Smoke Puff], 0, object[arrayPos0].orbTargetPos.x, object[arrayPos0].orbTargetPos.y)
396
PlaySfx(SfxName[Explosion], false)
397
object[arrayPos0].state = SEESAW_NO_ORB
398
object[arrayPos0].orbTimer = 0
399
end if
400
object[arrayPos0].xpos = temp0
401
object[arrayPos0].ypos = temp1
402
end if
403
next
404
end if
405
end if
406
407
if object.state < SLZEGGMAN_ESCAPE
408
foreach (GROUP_PLAYERS, currentPlayer, ACTIVE_ENTITIES)
409
temp0 = player[currentPlayer].collisionRight
410
temp0 <<= 16
411
temp0 += player[currentPlayer].xpos
412
temp1 = stage.curXBoundary2
413
temp1 <<= 16
414
if temp0 > temp1
415
player[currentPlayer].xvel = 0
416
player[currentPlayer].speed = 0
417
player[currentPlayer].xpos = temp1
418
temp0 = player[currentPlayer].collisionRight
419
temp0 <<= 16
420
player[currentPlayer].xpos -= temp0
421
end if
422
next
423
end if
424
end event
425
426
427
event ObjectDraw
428
switch object.animation
429
case SLZEGGANI_INVISIBLE
430
break
431
432
case SLZEGGANI_IDLE
433
temp0 = object.animationTimer
434
temp0 /= 6
435
object.animationTimer++
436
object.animationTimer %= 12
437
DrawSpriteFX(temp0, FX_FLIP, object.xpos, object.ypos)
438
DrawSpriteFX(20, FX_FLIP, object.xpos, object.ypos)
439
break
440
441
case SLZEGGANI_LAUGH
442
temp0 = object.animationTimer
443
temp0 %= 10
444
temp0 /= 5
445
temp0 += 9
446
object.animationTimer++
447
if object.animationTimer == 50
448
object.animationTimer = 0
449
if player[0].animation != ANI_DYING
450
object.animation = SLZEGGANI_IDLE
451
end if
452
end if
453
DrawSpriteFX(temp0, FX_FLIP, object.xpos, object.ypos)
454
DrawSpriteFX(20, FX_FLIP, object.xpos, object.ypos)
455
break
456
457
case SLZEGGANI_HIT
458
temp0 = object.animationTimer
459
temp0 &= 1
460
temp0 += 2
461
temp1 = temp0
462
temp1 += 17
463
object.animationTimer++
464
if object.animationTimer == 30
465
object.animationTimer = 0
466
object.animation = SLZEGGANI_IDLE
467
end if
468
DrawSpriteFX(temp0, FX_FLIP, object.xpos, object.ypos)
469
DrawSpriteFX(temp1, FX_FLIP, object.xpos, object.ypos)
470
break
471
472
case SLZEGGANI_DEFEATED
473
temp0 = object.animationTimer
474
temp0 >>= 5
475
temp0 += 4
476
object.animationTimer++
477
object.animationTimer &= 63
478
DrawSpriteFX(temp0, FX_FLIP, object.xpos, object.ypos)
479
DrawSpriteFX(20, FX_FLIP, object.xpos, object.ypos)
480
break
481
482
case SLZEGGANI_TOASTED
483
DrawSpriteFX(6, FX_FLIP, object.xpos, object.ypos)
484
DrawSpriteFX(20, FX_FLIP, object.xpos, object.ypos)
485
break
486
487
case SLZEGGANI_PANIC
488
temp0 = object.animationTimer
489
temp0 >>= 2
490
temp0 += 7
491
object.animationTimer++
492
object.animationTimer %= 7
493
DrawSpriteFX(temp0, FX_FLIP, object.xpos, object.ypos)
494
DrawSpriteFX(20, FX_FLIP, object.xpos, object.ypos)
495
break
496
497
end switch
498
499
switch object.flameAnim
500
case FLAME_ACTIVE
501
temp0 = object.flameAnimTimer
502
temp0 >>= 2
503
temp0 += 11
504
object.flameAnimTimer++
505
object.flameAnimTimer &= 7
506
DrawSpriteFX(temp0, FX_FLIP, object.xpos, object.ypos)
507
break
508
509
case FLAME_EXPLODE
510
temp0 = object.flameAnimTimer
511
temp0 /= 3
512
temp0 += 11
513
object.flameAnimTimer++
514
if object.flameAnimTimer > 21
515
object.flameAnimTimer = 18
516
end if
517
DrawSpriteFX(temp0, FX_FLIP, object.xpos, object.ypos)
518
break
519
520
end switch
521
end event
522
523
524
event ObjectStartup
525
LoadSpriteSheet("Global/Eggman.gif")
526
SpriteFrame(-28, -32, 64, 56, 1, 1)
527
SpriteFrame(-28, -32, 64, 56, 66, 1)
528
SpriteFrame(-28, -32, 64, 56, 131, 1)
529
SpriteFrame(-28, -32, 64, 56, 1, 58)
530
SpriteFrame(-28, -32, 64, 56, 1, 1)
531
SpriteFrame(-28, -32, 64, 56, 1, 58)
532
SpriteFrame(-28, -32, 64, 56, 66, 58)
533
SpriteFrame(-28, -32, 64, 56, 131, 58)
534
SpriteFrame(-28, -32, 64, 56, 66, 1)
535
SpriteFrame(-28, -32, 64, 56, 1, 115)
536
SpriteFrame(-28, -32, 64, 56, 66, 115)
537
SpriteFrame(34, 1, 10, 9, 196, 2)
538
SpriteFrame(33, 0, 15, 11, 196, 12)
539
SpriteFrame(34, -1, 22, 14, 213, 1)
540
SpriteFrame(34, -8, 32, 26, 213, 16)
541
SpriteFrame(34, -1, 22, 14, 213, 1)
542
SpriteFrame(34, -8, 32, 26, 213, 16)
543
SpriteFrame(34, 1, 10, 9, 196, 2)
544
SpriteFrame(33, 0, 15, 11, 196, 12)
545
SpriteFrame(-12, 17, 24, 16, 213, 135)
546
SpriteFrame(-12, 17, 24, 16, 213, 43)
547
548
foreach (TypeName[Eggman], arrayPos0, ALL_ENTITIES)
549
if object[arrayPos0].type == TypeName[Eggman]
550
object[arrayPos0].priority = PRIORITY_XBOUNDS
551
arrayPos1 = arrayPos0
552
arrayPos1 -= 3
553
object[arrayPos0].xpos = object[arrayPos1].xpos
554
object[arrayPos0].xpos += 0xE80000
555
object[arrayPos0].ypos = object[arrayPos1].ypos
556
object[arrayPos0].ypos -= 0xAC0000
557
558
temp1 = screen.xcenter
559
temp0 -= 4
560
temp1 <<= 8
561
temp1 /= 160
562
temp1 *= -256
563
object[arrayPos0].xvel = temp1
564
565
object[arrayPos0].targetSeeSaw = 4
566
object[arrayPos0].originPos.x = object[arrayPos0].xpos
567
object[arrayPos0].originPos.y = object[arrayPos0].ypos
568
object[arrayPos0].animation = SLZEGGANI_IDLE
569
570
#platform: USE_ORIGINS
571
if game.bossOneLife == false
572
object[arrayPos0].health = 8
573
else
574
object[arrayPos0].health = 1
575
end if
576
#endplatform
577
#platform: USE_STANDALONE
578
object[arrayPos0].health = 8
579
#endplatform
580
581
temp0 = screen.xcenter
582
temp0 -= 160 // xcenter if screen width was 320 like the original game
583
temp0 -= 4
584
if temp0 < 0
585
temp0 = 0
586
end if
587
temp0 <<= 16
588
object[arrayPos0].xpos += temp0
589
temp0 += 0x980000
590
591
object[arrayPos0].boundsL = object[arrayPos1].xpos
592
object[arrayPos0].boundsL -= temp0
593
object[arrayPos0].boundsR = object[arrayPos1].xpos
594
object[arrayPos0].boundsR += temp0
595
596
temp0 -= 0x980000
597
temp1 = object[arrayPos1].xpos
598
temp1 -= 0x280000
599
SetTableValue(temp1, 2, SLZEggman_seesawDropPos)
600
temp1 += 0x500000
601
SetTableValue(temp1, 3, SLZEggman_seesawDropPos)
602
arrayPos1++
603
604
object[arrayPos1].xpos -= temp0
605
temp1 = object[arrayPos1].xpos
606
temp1 -= 0x280000
607
SetTableValue(temp1, 0, SLZEggman_seesawDropPos)
608
temp1 += 0x500000
609
SetTableValue(temp1, 1, SLZEggman_seesawDropPos)
610
arrayPos1++
611
612
object[arrayPos1].xpos += temp0
613
temp1 = object[arrayPos1].xpos
614
temp1 -= 0x280000
615
SetTableValue(temp1, 4, SLZEggman_seesawDropPos)
616
temp1 += 0x500000
617
SetTableValue(temp1, 5, SLZEggman_seesawDropPos)
618
619
object[arrayPos0].flameAnim = FLAME_ACTIVE
620
end if
621
next
622
end event
623
624
625
// ========================
626
// Editor Events
627
// ========================
628
629
event RSDKDraw
630
DrawSpriteFX(0, FX_FLIP, object.xpos, object.ypos)
631
DrawSpriteFX(1, FX_FLIP, object.xpos, object.ypos)
632
end event
633
634
635
event RSDKLoad
636
LoadSpriteSheet("Global/Eggman.gif")
637
SpriteFrame(-28, -32, 64, 56, 1, 1)
638
SpriteFrame(-12, 17, 24, 16, 213, 43)
639
640
SetVariableAlias(ALIAS_VAR_PROPVAL, "unused")
641
end event
642
643