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/CNZ/Eggman.txt
1487 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 CNZEggman 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.oscillateAngle
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.boundsL
21
private alias object.value7 : object.boundsR
22
private alias object.value8 : object.boundsT
23
private alias object.value9 : object.boundsB
24
private alias object.value10 : object.isClawWide
25
private alias object.value11 : object.bombDropDisabled
26
private alias object.value12 : object.sparkSfxTimer
27
private alias object.value13 : object.paletteTimer
28
private alias object.value14 : object.isCNZ
29
30
// Eggman States
31
private alias 0 : CNZEGGMAN_AWAITPLAYER
32
private alias 1 : CNZEGGMAN_ENTERDELAY
33
private alias 2 : CNZEGGMAN_MOVEH
34
private alias 3 : CNZEGGMAN_MOVEV_DOWN
35
private alias 4 : CNZEGGMAN_MOVEV_UP
36
private alias 5 : CNZEGGMAN_DROPBOMB
37
private alias 6 : CNZEGGMAN_DROPPEDBOMB
38
private alias 7 : CNZEGGMAN_EXPLODE
39
private alias 8 : CNZEGGMAN_DEFEATFALL
40
private alias 9 : CNZEGGMAN_DEFEATRISE
41
private alias 10 : CNZEGGMAN_FLEE
42
private alias 11 : CNZEGGMAN_ESCAPE
43
44
// Eggman Animations
45
private alias 0 : CNZEGGANI_INVISIBLE
46
private alias 1 : CNZEGGANI_IDLE
47
private alias 2 : CNZEGGANI_LAUGH
48
private alias 3 : CNZEGGANI_HIT
49
private alias 4 : CNZEGGANI_DEFEATED
50
private alias 5 : CNZEGGANI_TOASTED
51
private alias 6 : CNZEGGANI_PANIC
52
53
// EggmanClaw Aliases
54
private alias object.value1 : eggmanClaw.parent
55
private alias object.value2 : eggmanClaw.electricityActive
56
57
// EggmanClaw States
58
private alias 1 : CNZEGGMANCLAW_DEBRIS
59
60
// EggmanBomb Aliases
61
private alias object.value1 : eggmanBomb.parent
62
private alias object.value2 : eggmanBomb.offset.y
63
64
// EggmanBomb States
65
private alias 1 : CNZEGGMANBOMB_DROPPED
66
67
// BossWall States
68
private alias 1 : CNZBOSSWALL_APPEAR
69
private alias 3 : CNZBOSSWALL_DELWALL
70
71
// Player Aliases
72
private alias object.xpos : player.xpos
73
private alias object.ypos : player.ypos
74
private alias object.xvel : player.xvel
75
private alias object.speed : player.speed
76
private alias object.animation : player.animation
77
private alias object.collisionRight : player.collisionRight
78
79
private alias object.value40 : player.hitboxLeft
80
private alias object.value38 : player.hitboxTop
81
private alias object.value41 : player.hitboxRight
82
private alias object.value39 : player.hitboxBottom
83
84
// Music Events
85
private alias 26 : SLOT_MUSICEVENT_BOSS
86
87
private alias 0 : MUSICEVENT_FADETOBOSS
88
private alias 1 : MUSICEVENT_FADETOSTAGE
89
90
// ========================
91
// Function Declarations
92
// ========================
93
94
reserve function CNZEggman_Oscillate
95
96
97
// ========================
98
// Function Definitions
99
// ========================
100
101
private function CNZEggman_Oscillate
102
Sin256(object.ypos, object.oscillateAngle)
103
object.ypos <<= 10
104
object.ypos += object.originPos.y
105
106
object.oscillateAngle += 2
107
object.oscillateAngle &= 0xFF
108
end function
109
110
111
// ========================
112
// Events
113
// ========================
114
115
event ObjectUpdate
116
if object.isCNZ == true
117
object.paletteTimer++
118
if object.paletteTimer == 4
119
object.paletteTimer = 0
120
RotatePalette(0, 194, 196, false)
121
RotatePalette(0, 197, 202, false)
122
end if
123
else
124
// In MBZ/Egg Gauntlet, where the palette indices used are different
125
object.paletteTimer++
126
if object.paletteTimer == 4
127
object.paletteTimer = 0
128
RotatePalette(0, 112, 114, false)
129
RotatePalette(0, 115, 120, false)
130
end if
131
end if
132
133
switch object.state
134
case CNZEGGMAN_AWAITPLAYER
135
if player[0].xpos > object[-1].xpos
136
temp0 = -32
137
temp0 *= screen.xsize
138
temp0 /= 320
139
temp0 -= 192
140
temp0 += object[-1].ixpos
141
stage.newXBoundary1 = temp0
142
143
temp0 = 32
144
temp0 *= screen.xsize
145
temp0 /= 320
146
temp0 += 192
147
temp0 += object[-1].ixpos
148
stage.newXBoundary2 = temp0
149
150
object.boundsL = object[-1].xpos
151
object.boundsL -= 0x800000
152
153
object.boundsR = object[-1].xpos
154
object.boundsR += 0x800000
155
156
object.boundsT = object.ypos
157
object.boundsB = object.ypos
158
object.boundsB += 0x2C0000
159
160
object.animation = CNZEGGANI_IDLE
161
ResetObjectEntity(SLOT_MUSICEVENT_BOSS, TypeName[Music Event], MUSICEVENT_FADETOBOSS, 0, 0)
162
object[SLOT_MUSICEVENT_BOSS].priority = PRIORITY_ACTIVE
163
164
object[-2].type = TypeName[Eggman Claw]
165
object[-2].propertyValue = 0 // left claw
166
eggmanClaw[-2].parent = object.entityPos
167
168
object[+1].type = TypeName[Eggman Claw]
169
object[+1].propertyValue = 1 // right claw
170
eggmanClaw[+1].parent = object.entityPos
171
172
173
object[+2].priority = PRIORITY_ACTIVE
174
object[+2].state = CNZBOSSWALL_APPEAR
175
176
object.xvel = -0x18000
177
object.originPos.y = object.ypos
178
179
CheckCurrentStageFolder("Zone04")
180
if checkResult == true
181
object.isCNZ = true
182
else
183
// We're gonna assume that we're in MBZ, then
184
object.isCNZ = false
185
end if
186
187
#platform: USE_STANDALONE
188
object.health = 8
189
#endplatform
190
#platform: USE_ORIGINS
191
if game.bossOneLife == false
192
object.health = 8
193
else
194
object.health = 1
195
end if
196
#endplatform
197
198
object.priority = PRIORITY_ACTIVE
199
object.state = CNZEGGMAN_ENTERDELAY
200
end if
201
break
202
203
case CNZEGGMAN_ENTERDELAY
204
object.timer++
205
if object.timer == 60
206
object.timer = 0
207
object.state = CNZEGGMAN_MOVEH
208
end if
209
break
210
211
case CNZEGGMAN_MOVEH
212
CallFunction(CNZEggman_Oscillate)
213
object.xpos += object.xvel
214
215
if object.xvel > 0
216
if object.xpos > object.boundsR
217
object.xpos = object.boundsR
218
object.direction ^= FLIP_X
219
FlipSign(object.xvel)
220
object.bombDropDisabled = false
221
end if
222
else
223
if object.xpos < object.boundsL
224
object.xpos = object.boundsL
225
object.direction ^= FLIP_X
226
FlipSign(object.xvel)
227
object.bombDropDisabled = false
228
end if
229
end if
230
231
object.timer++
232
if object.timer == 60
233
object.timer = 0
234
eggmanClaw[-2].electricityActive = true
235
object.isClawWide ^= true
236
end if
237
238
object.sparkSfxTimer++
239
if object.sparkSfxTimer == 32
240
object.sparkSfxTimer = 0
241
PlaySfx(SfxName[BossSpark], false)
242
end if
243
244
foreach (GROUP_PLAYERS, currentPlayer, ACTIVE_ENTITIES)
245
if object.state == CNZEGGMAN_MOVEH
246
if player[currentPlayer].ypos > object.ypos
247
temp0 = player[currentPlayer].xpos
248
temp0 -= object.xpos
249
Abs(temp0)
250
if temp0 < 0x100000
251
temp0 = player[currentPlayer].ypos
252
temp0 -= object.ypos
253
Abs(temp0)
254
if temp0 < 0x600000
255
object.state = CNZEGGMAN_MOVEV_DOWN
256
else
257
if object.bombDropDisabled == false
258
object.timer = 0
259
object.isClawWide = false
260
object.state = CNZEGGMAN_DROPBOMB
261
end if
262
end if
263
end if
264
end if
265
end if
266
next
267
break
268
269
case CNZEGGMAN_MOVEV_DOWN
270
object.isClawWide = true
271
object.ypos += 0x18000
272
273
if object.ypos > object.boundsB
274
object.state = CNZEGGMAN_MOVEV_UP
275
end if
276
277
object.sparkSfxTimer++
278
if object.sparkSfxTimer == 32
279
object.sparkSfxTimer = 0
280
PlaySfx(SfxName[BossSpark], false)
281
end if
282
break
283
284
case CNZEGGMAN_MOVEV_UP
285
object.isClawWide = false
286
object.ypos -= 0x18000
287
288
if object.ypos < object.boundsT
289
object.ypos = object.boundsT
290
object.originPos.y = object.boundsT
291
object.state = CNZEGGMAN_MOVEH
292
end if
293
294
object.sparkSfxTimer++
295
if object.sparkSfxTimer == 32
296
object.sparkSfxTimer = 0
297
PlaySfx(SfxName[BossSpark], false)
298
end if
299
break
300
301
case CNZEGGMAN_DROPBOMB
302
CallFunction(CNZEggman_Oscillate)
303
304
object.timer++
305
if object.timer == 1
306
eggmanClaw[-2].electricityActive = false
307
arrayPos0 = object.entityPos
308
arrayPos0--
309
ResetObjectEntity(arrayPos0, TypeName[Eggman Bomb], 0, object.xpos, object.ypos)
310
eggmanBomb[arrayPos0].parent = object.entityPos
311
else
312
object[-1].ypos = object.ypos
313
object[-1].ypos += eggmanBomb[-1].offset.y
314
end if
315
316
if object.timer == 80
317
object.timer = 0
318
object.isClawWide = true
319
object[-1].state = CNZEGGMANBOMB_DROPPED
320
object.state = CNZEGGMAN_DROPPEDBOMB
321
end if
322
break
323
324
case CNZEGGMAN_DROPPEDBOMB
325
CallFunction(CNZEggman_Oscillate)
326
327
object.timer++
328
if object.timer == 20
329
object.timer = 0
330
object.isClawWide = false
331
object.bombDropDisabled = true
332
eggmanClaw[-2].electricityActive = true
333
object.state = CNZEGGMAN_MOVEH
334
end if
335
break
336
337
case CNZEGGMAN_EXPLODE
338
object.timer++
339
if object.timer == 60
340
if object.direction == FLIP_NONE
341
object[-2].xvel = -0x10000
342
else
343
object[-2].xvel = 0x10000
344
end if
345
object[-2].yvel = 0
346
object[-2].state = CNZEGGMANCLAW_DEBRIS
347
end if
348
349
if object.timer == 120
350
if object.direction == FLIP_NONE
351
object[+1].xvel = 0x10000
352
else
353
object[+1].xvel = -0x10000
354
end if
355
object[+1].yvel = 0
356
object[+1].state = CNZEGGMANCLAW_DEBRIS
357
end if
358
359
if object.timer == 180
360
object.timer = 0
361
object.animation = CNZEGGANI_TOASTED
362
object.exploding = false
363
object.state++
364
ResetObjectEntity(SLOT_MUSICEVENT_BOSS, TypeName[Music Event], MUSICEVENT_FADETOSTAGE, 0, 0)
365
object[SLOT_MUSICEVENT_BOSS].priority = PRIORITY_ACTIVE
366
object[+3].priority = PRIORITY_ACTIVE
367
object[+3].state = CNZBOSSWALL_DELWALL
368
temp0 = tileLayer[0].xsize
369
temp0 <<= 7
370
stage.newXBoundary2 = temp0
371
end if
372
break
373
374
case CNZEGGMAN_DEFEATFALL
375
object.ypos += object.yvel
376
object.yvel += 0x1800
377
378
object.timer++
379
if object.timer == 16
380
object.yvel = 0
381
object.timer = 0
382
object.animationTimer = 0
383
object.state++
384
end if
385
break
386
387
case CNZEGGMAN_DEFEATRISE
388
if object.timer < 24
389
object.ypos += object.yvel
390
object.yvel -= 0x800
391
object.timer++
392
else
393
object.timer = 0
394
object.yvel = 0
395
object.originPos.y = object.ypos
396
object.state++
397
end if
398
break
399
400
case CNZEGGMAN_FLEE
401
CallFunction(CNZEggman_Oscillate)
402
if object.timer < 8
403
object.timer++
404
else
405
object.timer = 0
406
object.animation = CNZEGGANI_PANIC
407
object.animationTimer = 0
408
object.direction = FLIP_X
409
object.priority = PRIORITY_ACTIVE
410
411
#platform: USE_STANDALONE
412
temp0 = tileLayer[0].xsize
413
temp0 <<= 7
414
stage.newXBoundary2 = temp0
415
#endplatform
416
417
object.state++
418
end if
419
break
420
421
case CNZEGGMAN_ESCAPE
422
object.xpos += 0x40000
423
object.originPos.y -= 0x4000
424
CallFunction(CNZEggman_Oscillate)
425
426
if object.outOfBounds == true
427
ResetObjectEntity(object.entityPos, TypeName[Blank Object], 0, 0, 0)
428
end if
429
break
430
431
end switch
432
433
if object.health != 0
434
if object.invincibilityTimer > 0
435
object.invincibilityTimer--
436
GetBit(temp0, object.invincibilityTimer, 0)
437
if temp0 == true
438
SetPaletteEntry(0, 192, 0xE0E0E0)
439
else
440
SetPaletteEntry(0, 192, 0x000000)
441
end if
442
end if
443
444
foreach (GROUP_PLAYERS, currentPlayer, ACTIVE_ENTITIES)
445
if object.invincibilityTimer == 0
446
CheckEqual(player[currentPlayer].animation, ANI_HURT)
447
temp0 = checkResult
448
CheckEqual(player[currentPlayer].animation, ANI_DYING)
449
temp0 |= checkResult
450
CheckEqual(player[currentPlayer].animation, ANI_DROWNING)
451
temp0 |= checkResult
452
if temp0 != 0
453
if object.animation != CNZEGGANI_LAUGH
454
object.animation = CNZEGGANI_LAUGH
455
object.animationTimer = 0
456
end if
457
end if
458
459
BoxCollisionTest(C_TOUCH, object.entityPos, -24, -24, 24, 24, currentPlayer, player[currentPlayer].hitboxLeft, player[currentPlayer].hitboxTop, player[currentPlayer].hitboxRight, player[currentPlayer].hitboxBottom)
460
if checkResult == true
461
CallFunction(Player_CheckHit)
462
if checkResult == true
463
object.health--
464
if object.health == 0
465
#platform: USE_ORIGINS
466
CallNativeFunction2(NotifyCallback, NOTIFY_KILL_BOSS, 0)
467
CallNativeFunction2(NotifyCallback, NOTIFY_BOSS_END, 1)
468
#endplatform
469
470
player.score += 1000
471
eggmanClaw[-2].electricityActive = false
472
object.timer = 0
473
object.animation = CNZEGGANI_DEFEATED
474
object.animationTimer = 0
475
object.exploding = true
476
object.originPos.y = object.ypos
477
object.state = CNZEGGMAN_EXPLODE
478
if object[-1].type == TypeName[Eggman Bomb]
479
temp0 = object.entityPos
480
temp0--
481
ResetObjectEntity(temp0, TypeName[Explosion], 0, object[-1].xpos, object[-1].ypos)
482
end if
483
else
484
object.animation = CNZEGGANI_HIT
485
object.animationTimer = 0
486
object.invincibilityTimer = 64
487
PlaySfx(SfxName[Boss Hit], false)
488
end if
489
end if
490
end if
491
end if
492
next
493
end if
494
495
if object.state != CNZEGGMAN_ESCAPE
496
foreach (GROUP_PLAYERS, currentPlayer, ACTIVE_ENTITIES)
497
temp0 = player[currentPlayer].collisionRight
498
temp0 <<= 16
499
temp0 += player[currentPlayer].xpos
500
temp1 = stage.curXBoundary2
501
temp1 <<= 16
502
if temp0 > temp1
503
player[currentPlayer].xvel = 0
504
player[currentPlayer].speed = 0
505
player[currentPlayer].xpos = temp1
506
temp0 = player[currentPlayer].collisionRight
507
temp0 <<= 16
508
player[currentPlayer].xpos -= temp0
509
end if
510
next
511
end if
512
513
if object.exploding == true
514
temp0 = oscillation
515
temp0 &= 7
516
if temp0 == 0
517
Rand(temp0, 48)
518
temp0 -= 24
519
temp0 <<= 16
520
temp0 += object.xpos
521
Rand(temp1, 48)
522
temp1 -= 24
523
temp1 <<= 16
524
temp1 += object.ypos
525
CreateTempObject(TypeName[Explosion], 0, temp0, temp1)
526
object[tempObjectPos].drawOrder = 5
527
PlaySfx(SfxName[Explosion], false)
528
end if
529
end if
530
end event
531
532
533
event ObjectDraw
534
DrawSpriteFX(6, FX_FLIP, object.xpos, object.ypos)
535
536
switch object.animation
537
default
538
case CNZEGGANI_INVISIBLE
539
break
540
541
case CNZEGGANI_IDLE
542
temp0 = object.animationTimer
543
temp0 >>= 3
544
object.animationTimer++
545
object.animationTimer &= 15
546
DrawSpriteFX(temp0, FX_FLIP, object.xpos, object.ypos)
547
break
548
549
case CNZEGGANI_LAUGH
550
temp0 = object.animationTimer
551
temp0 &= 15
552
temp0 >>= 3
553
temp0 += 2
554
555
object.animationTimer++
556
if object.animationTimer == 50
557
object.animationTimer = 0
558
if player[0].animation != ANI_DYING
559
object.animation = CNZEGGANI_IDLE
560
end if
561
end if
562
563
DrawSpriteFX(temp0, FX_FLIP, object.xpos, object.ypos)
564
break
565
566
case CNZEGGANI_HIT
567
temp0 = object.animationTimer
568
temp0 &= 1
569
temp0 += 2
570
571
object.animationTimer++
572
if object.animationTimer == 50
573
object.animationTimer = 0
574
object.animation = CNZEGGANI_IDLE
575
end if
576
577
DrawSpriteFX(4, FX_FLIP, object.xpos, object.ypos)
578
break
579
580
case CNZEGGANI_DEFEATED
581
temp0 = object.animationTimer
582
temp0 >>= 5
583
temp0 += 4
584
temp0 %= 5
585
object.animationTimer++
586
object.animationTimer &= 63
587
DrawSpriteFX(temp0, FX_FLIP, object.xpos, object.ypos)
588
break
589
590
case CNZEGGANI_TOASTED
591
DrawSpriteFX(5, FX_FLIP, object.xpos, object.ypos)
592
break
593
594
case CNZEGGANI_PANIC
595
temp0 = object.animationTimer
596
temp0 >>= 3
597
object.animationTimer++
598
object.animationTimer &= 15
599
DrawSpriteFX(temp0, FX_FLIP, object.xpos, object.ypos)
600
601
temp0 = object.animationTimer
602
temp0 >>= 2
603
temp0 &= 1
604
if temp0 == true
605
DrawSpriteFX(7, FX_FLIP, object.xpos, object.ypos)
606
end if
607
break
608
609
end switch
610
end event
611
612
613
event ObjectStartup
614
CheckCurrentStageFolder("Zone04")
615
if checkResult == true
616
LoadSpriteSheet("CNZ/Objects.gif")
617
SpriteFrame(-28, -16, 44, 16, 76, 140) // Idle 1 - #0
618
SpriteFrame(-28, -16, 44, 16, 121, 140) // Idle 2 - #1
619
SpriteFrame(-28, -16, 44, 16, 166, 140) // Laugh 1 - #2
620
SpriteFrame(-28, -16, 44, 16, 211, 140) // Laugh 2 - #3
621
SpriteFrame(-28, -16, 44, 16, 166, 157) // Hit - #4
622
SpriteFrame(-28, -16, 44, 16, 211, 157) // Destroyed - #5
623
SpriteFrame(-40, -40, 80, 72, 175, 183) // Eggmobile - #6
624
SpriteFrame(-3, -18, 11, 8, 154, 157) // Panic Sweat - #7
625
626
if options.vsMode == true
627
foreach (TypeName[Eggman], arrayPos0, ALL_ENTITIES)
628
object[arrayPos0].type = TypeName[Blank Object]
629
next
630
end if
631
else
632
LoadSpriteSheet("MBZ/Objects.gif")
633
SpriteFrame(-28, -16, 44, 16, 1, 5) // Idle 1 - #0
634
SpriteFrame(-28, -16, 44, 16, 62, 5) // Idle 2 - #1
635
SpriteFrame(-28, -16, 44, 16, 1, 26) // Laugh 1 - #2
636
SpriteFrame(-28, -16, 44, 16, 62, 26) // Laugh 2 - #3
637
SpriteFrame(-28, -16, 44, 16, 1, 47) // Hit - #4
638
SpriteFrame(-28, -16, 44, 16, 62, 47) // Destroyed - #5
639
SpriteFrame(-40, -40, 80, 72, 232, 112) // Eggmobile - #6
640
SpriteFrame(-3, -18, 11, 8, 45, 88) // Panic Sweat - #7
641
end if
642
end event
643
644
645
// ========================
646
// Editor Events
647
// ========================
648
649
event RSDKDraw
650
DrawSprite(1)
651
DrawSprite(0)
652
end event
653
654
655
event RSDKLoad
656
CheckCurrentStageFolder("Zone04")
657
if checkResult == true
658
LoadSpriteSheet("CNZ/Objects.gif")
659
SpriteFrame(-28, -16, 44, 16, 76, 140) // Idle 1
660
SpriteFrame(-40, -40, 80, 72, 175, 183) // Eggmobile
661
else
662
LoadSpriteSheet("MBZ/Objects.gif")
663
SpriteFrame(-28, -16, 44, 16, 1, 5) // Idle 1
664
SpriteFrame(-40, -40, 80, 72, 232, 112) // Eggmobile
665
end if
666
667
SetVariableAlias(ALIAS_VAR_PROPVAL, "unused")
668
end event
669
670