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/DEZ/MechaSonic.txt
1480 views
1
// ----------------------------------
2
// RSDK Project: Sonic 2
3
// Script Description: Mecha Sonic 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.movementCycle
14
private alias object.value2 : object.spriteIndex
15
private alias object.value3 : object.moveDir
16
17
// value4 actually has two seaparate uses in this script, so for clarity's sake there are just two aliases for it
18
private alias object.value4 : object.turns // Used when boosting across the ground to count how many turns to make are left
19
private alias object.value4 : object.firedSpikes // Used when jumping to determine whether spikes have bene fired yet or not
20
21
private alias object.value5 : object.health
22
private alias object.value6 : object.invincibilityTimer
23
private alias object.value7 : object.exploding
24
25
// Constant values, set upon init
26
private alias object.value8 : object.gndStartSpeed // How fast Mecha Sonic should go when on the ground
27
private alias object.value9 : object.gndAcceleration
28
private alias object.value10 : object.airStartSpeed
29
30
// The sprite the rockets should use, kept to 15 when no rockets are to be displayed
31
private alias object.value11 : object.rocketsFrame
32
33
// States
34
private alias 0 : MECHASONIC_AWAITPLAYER
35
private alias 1 : MECHASONIC_INITPAUSE
36
private alias 2 : MECHASONIC_DESCENDING
37
private alias 3 : MECHASONIC_STANDING
38
39
private alias 4 : MECHASONIC_GROUNDROLL_START
40
private alias 5 : MECHASONIC_GROUNDROLL_CHARGE
41
private alias 6 : MECHASONIC_GROUNDROLL_MAIN
42
43
private alias 7 : MECHASONIC_ROCKETBOOST_START
44
private alias 8 : MECHASONIC_ROCKETBOOST_CHARGE
45
private alias 9 : MECHASONIC_ROCKETBOOST_MAIN
46
47
private alias 10 : MECHASONIC_JUMPNORMAL_START
48
private alias 11 : MECHASONIC_JUMPNORMAL_CHARGE
49
private alias 12 : MECHASONIC_JUMPNORMAL_MAIN
50
51
private alias 13 : MECHASONIC_JUMPSPIKES_START
52
private alias 14 : MECHASONIC_JUMPSPIKES_CHARGE
53
private alias 15 : MECHASONIC_JUMPSPIKES_MAIN
54
55
private alias 16 : MECHASONIC_UNCURL
56
private alias 17 : MECHASONIC_EXPLODING
57
private alias 18 : MECHASONIC_DISSAPPEAR
58
59
// Animations
60
private alias 0 : MECHASONICANI_NONE
61
private alias 1 : MECHASONICANI_IDLE
62
private alias 2 : MECHASONICANI_ROCKETBOOST
63
private alias 3 : MECHASONICANI_TURN
64
private alias 4 : MECHASONICANI_CURL
65
private alias 5 : MECHASONICANI_ROLLING
66
private alias 6 : MECHASONICANI_UNCURL
67
68
// Eggman Window (object[-9]) Aliases
69
private alias 0 : EGGMANWINDOWANI_WINDOWCLOSED
70
private alias 1 : EGGMANWINDOWANI_OPENWINDOW
71
private alias 2 : EGGMANWINDOWANI_IDLE
72
private alias 3 : EGGMANWINDOWANI_LAUGH
73
private alias 4 : EGGMANWINDOWANI_STUNNED
74
private alias 5 : EGGMANWINDOWANI_CLOSEWINDOW
75
76
// One Way Door alias
77
private alias object.state : object.isOpen
78
79
// Player aliases
80
private alias object.state : player.state
81
private alias object.xpos : player.xpos
82
private alias object.xvel : player.xvel
83
private alias object.speed : player.speed
84
private alias object.animation : player.animation
85
private alias object.collisionRight : player.collisionRight
86
private alias object.value38 : player.hitboxTop
87
private alias object.value39 : player.hitboxBottom
88
private alias object.value40 : player.hitboxLeft
89
private alias object.value41 : player.hitboxRight
90
91
// Reserved object slots
92
private alias 0 : SLOT_PLAYER1
93
private alias 26 : SLOT_MUSICEVENT_BOSS
94
95
// Music Events
96
private alias 0 : MUSICEVENT_FADETOBOSS
97
private alias 1 : MUSICEVENT_FADETOSTAGE
98
private alias 2 : MUSICEVENT_TRANSITION
99
100
private alias 0 : MUSICEVENT_FLAG_NOCHANGE
101
private alias 1 : MUSICEVENT_FLAG_SPEEDUP
102
private alias 2 : MUSICEVENT_FLAG_SLOWDOWN
103
104
// Path ID Aliases
105
private alias 0 : PATH_A
106
107
108
// ========================
109
// Function Declarations
110
// ========================
111
112
reserve function MechaSonic_CheckEggmanChuckle
113
reserve function MechaSonic_Reset
114
115
116
// ========================
117
// Tables
118
// ========================
119
120
// Values to apply to projectile spikes in order of:
121
// - xoffset, yoffset, xvel, yvel
122
private table MechaSonic_spikeSpawnData
123
0x000000, -0x180000, 0x00000, -0x30000
124
-0x100000, -0x100000, -0x20000, -0x20000
125
-0x180000, 0x000000, -0x30000, 0x00000
126
-0x100000, 0x100000, -0x20000, 0x20000
127
0x000000, 0x180000, 0x00000, 0x30000
128
0x100000, 0x100000, 0x20000, 0x20000
129
0x180000, 0x000000, 0x30000, 0x00000
130
0x100000, -0x100000, 0x20000, -0x20000
131
end table
132
133
134
// Below three tables are used for animations, each entry corresponds to a Mecha Sonic SpriteFrame
135
136
// The last 252 value is unused, it's actually a control code from the original S2 Mecha Sonic animation bank
137
// (that means they grabbed this ani data from the original ROM, really interesting stuff)
138
private table MechaSonic_animation_turn
139
4, 5, 4, 3, 252
140
end table
141
142
private table MechaSonic_animation_curl
143
3, 3, 6, 6, 6, 7, 7, 7, 8, 8, 8, 6, 6, 7, 7, 8, 8, 6, 7, 8
144
end table
145
146
private table MechaSonic_animation_uncurl
147
8, 7, 6, 8, 8, 7, 7, 6, 6, 8, 8, 8, 7, 7, 7, 6, 6, 6, 3, 3
148
end table
149
150
// Table to hold the pattern Mecha Sonic will follow
151
// All the values are set in ObjectStartup, as aliases values can't be put in table declarations
152
private table MechaSonic_movementCycleStates[16]
153
154
155
// ========================
156
// Function Definitions
157
// ========================
158
159
private function MechaSonic_CheckEggmanChuckle
160
// Called to check if Robotnik should start chuckling after the player's been hit
161
if object[-9].animation > EGGMANWINDOWANI_OPENWINDOW
162
CheckEqual(player[currentPlayer].animation, ANI_HURT)
163
temp0 = checkResult
164
CheckEqual(player[currentPlayer].animation, ANI_DYING)
165
temp0 |= checkResult
166
CheckEqual(player[currentPlayer].animation, ANI_DROWNING)
167
temp0 |= checkResult
168
if temp0 != false
169
if object[-9].animation != EGGMANWINDOWANI_LAUGH
170
// If not already laughing, then start doing so
171
object[-9].animation = EGGMANWINDOWANI_LAUGH
172
object[-9].animationTimer = 0
173
end if
174
end if
175
end if
176
end function
177
178
179
private function MechaSonic_Reset
180
// Called to make the object return to its initial Standing state
181
object.timer = 100
182
PlaySfx(SfxName[Saw], false)
183
object.animation = MECHASONICANI_IDLE
184
object.state = MECHASONIC_STANDING
185
end function
186
187
188
// ========================
189
// Events
190
// ========================
191
192
event ObjectUpdate
193
switch object.state
194
case MECHASONIC_AWAITPLAYER
195
temp0 = object.xpos
196
temp0 >>= 16
197
temp0 += 30
198
temp1 = screen.xcenter
199
temp1 -= 160
200
temp0 += temp1
201
stage.newXBoundary2 = temp0
202
203
temp0 -= 320
204
temp0 -= temp1
205
stage.newXBoundary1 = temp0
206
207
temp0 = object.xpos
208
temp0 -= 0x880000
209
if player[SLOT_PLAYER1].xpos >= temp0
210
// Set Mecha Sonic's movement values
211
if temp1 > 32
212
temp1 = 32
213
end if
214
temp2 = temp1
215
temp1 += 160
216
217
object.gndStartSpeed = 0x80000
218
object.gndStartSpeed *= temp1
219
object.gndStartSpeed /= 160
220
temp2 <<= 8
221
object.gndStartSpeed += temp2
222
temp2 >>= 2
223
object.gndStartSpeed += temp2
224
temp2 >>= 6
225
226
object.gndAcceleration = 0x2000
227
object.gndAcceleration *= temp1
228
object.gndAcceleration /= 160
229
230
object.airStartSpeed = 0x40000
231
object.airStartSpeed *= temp1
232
object.airStartSpeed /= 160
233
temp2 <<= 8
234
object.airStartSpeed += temp2
235
temp2 >>= 2
236
object.airStartSpeed += temp2
237
temp2 >>= 6
238
temp2 <<= 16
239
240
object.xpos += temp2
241
242
#platform: USE_STANDALONE
243
object.health = 8
244
#endplatform
245
#platform: USE_ORIGINS
246
if game.bossOneLife == false
247
object.health = 8
248
else
249
object.health = 1
250
end if
251
#endplatform
252
253
object.ypos -= 0xC40000
254
255
ResetObjectEntity(SLOT_MUSICEVENT_BOSS, TypeName[Music Event], MUSICEVENT_FADETOBOSS, 0, 0)
256
object[SLOT_MUSICEVENT_BOSS].priority = PRIORITY_ACTIVE
257
object.state = MECHASONIC_INITPAUSE
258
end if
259
break
260
261
case MECHASONIC_INITPAUSE
262
// Just chilling above screen for a moment before starting to actually come down
263
object.timer++
264
if object.timer >= 45
265
object.timer = 0
266
PlaySfx(SfxName[Thruster], false)
267
object.state = MECHASONIC_DESCENDING
268
end if
269
break
270
271
case MECHASONIC_DESCENDING
272
object.timer++
273
if object.timer == 60
274
PlaySfx(SfxName[Thruster], false)
275
end if
276
277
if object.timer == 120
278
PlaySfx(SfxName[Thruster], false)
279
end if
280
281
object.rocketsFrame = oscillation
282
object.rocketsFrame &= 3
283
object.rocketsFrame >>= 1
284
object.rocketsFrame += 11
285
object.ypos += 0x10000
286
287
// If landed on the floor, start the fight proper
288
ObjectTileCollision(CSIDE_FLOOR, 0, 28, PATH_A)
289
if checkResult == true
290
object[-9].animation = EGGMANWINDOWANI_OPENWINDOW
291
object.rocketsFrame = 15 // Blank frame, no rockets thrusting just yet
292
CallFunction(MechaSonic_Reset)
293
end if
294
break
295
296
case MECHASONIC_STANDING
297
object.timer--
298
if object.timer == 50
299
// You'd think there'd be a space in its name, but there isn't...
300
PlaySfx(SfxName[Saw2], false)
301
end if
302
303
if object.timer == 0
304
GetTableValue(object.state, object.movementCycle, MechaSonic_movementCycleStates)
305
object.movementCycle++
306
object.movementCycle &= 15
307
end if
308
break
309
310
case MECHASONIC_GROUNDROLL_START
311
case MECHASONIC_JUMPNORMAL_START
312
case MECHASONIC_JUMPSPIKES_START
313
object.animation = MECHASONICANI_CURL
314
object.animationTimer = 1
315
object.spriteIndex = 0
316
object.timer = 148
317
object.state++
318
break
319
320
case MECHASONIC_GROUNDROLL_CHARGE
321
object.timer--
322
if object.timer < 0
323
object.timer = 64
324
object.xvel = object.gndStartSpeed
325
if object.moveDir == 0
326
FlipSign(object.xvel)
327
end if
328
object.moveDir ^= 1
329
object.state++
330
end if
331
break
332
333
case MECHASONIC_JUMPNORMAL_CHARGE
334
case MECHASONIC_JUMPSPIKES_CHARGE
335
object.timer--
336
if object.timer < 0
337
object.timer = 64
338
object.xvel = object.airStartSpeed
339
if object.moveDir == 0
340
FlipSign(object.xvel)
341
end if
342
object.moveDir ^= 1
343
object.state++
344
end if
345
break
346
347
case MECHASONIC_GROUNDROLL_MAIN
348
object.xpos += object.xvel
349
object.timer--
350
if object.timer < 0
351
object.animation = MECHASONICANI_UNCURL
352
object.animationTimer = 1
353
object.spriteIndex = 8
354
object.direction ^= FLIP_X
355
object.state = MECHASONIC_UNCURL
356
end if
357
358
if object.moveDir == 0
359
object.xvel -= object.gndAcceleration
360
else
361
object.xvel += object.gndAcceleration
362
end if
363
break
364
365
case MECHASONIC_UNCURL
366
break
367
368
case MECHASONIC_JUMPNORMAL_MAIN
369
object.xpos += object.xvel
370
371
if object.yvel != 0
372
object.ypos += object.yvel
373
object.yvel += 0x3800
374
if object.yvel > 0
375
ObjectTileCollision(CSIDE_FLOOR, 0, 28, PATH_A)
376
if checkResult == true
377
object.yvel = 0
378
end if
379
end if
380
end if
381
382
object.timer--
383
if object.timer == 60
384
object.yvel = -0x60000
385
end if
386
387
if object.timer < 0
388
object.animation = MECHASONICANI_UNCURL
389
object.animationTimer = 1
390
object.spriteIndex = 8
391
object.direction ^= FLIP_X
392
object.state = MECHASONIC_UNCURL
393
end if
394
break
395
396
case MECHASONIC_JUMPSPIKES_MAIN
397
object.xpos += object.xvel
398
if object.yvel != 0
399
object.ypos += object.yvel
400
object.yvel += 0x3800
401
if object.yvel > 0
402
if object.firedSpikes == false
403
temp0 = 0
404
temp7 = 0
405
arrayPos0 = object[-8].entityPos
406
while temp7 < 8
407
object[arrayPos0].type = TypeName[MechaSonicSpike]
408
object[arrayPos0].xpos = object.xpos
409
GetTableValue(temp1, temp0, MechaSonic_spikeSpawnData)
410
temp0++
411
object[arrayPos0].xpos += temp1
412
object[arrayPos0].ypos = object.ypos
413
GetTableValue(temp1, temp0, MechaSonic_spikeSpawnData)
414
temp0++
415
object[arrayPos0].ypos += temp1
416
GetTableValue(object[arrayPos0].xvel, temp0, MechaSonic_spikeSpawnData)
417
temp0++
418
GetTableValue(object[arrayPos0].yvel, temp0, MechaSonic_spikeSpawnData)
419
temp0++
420
object[arrayPos0].frame = temp7
421
arrayPos0++
422
423
temp7++
424
loop
425
426
PlaySfx(SfxName[Spikes Move], false)
427
object.firedSpikes = true
428
end if
429
430
ObjectTileCollision(CSIDE_FLOOR, 0, 28, PATH_A)
431
if checkResult == true
432
object.yvel = 0
433
end if
434
end if
435
end if
436
437
object.timer--
438
if object.timer == 60
439
object.yvel = -0x60000
440
end if
441
442
if object.timer < 0
443
object.firedSpikes = false
444
object.animation = MECHASONICANI_UNCURL
445
object.animationTimer = 1
446
object.spriteIndex = 8
447
object.direction ^= FLIP_X
448
object.state = MECHASONIC_UNCURL
449
end if
450
break
451
452
case MECHASONIC_ROCKETBOOST_START
453
object.animation = MECHASONICANI_ROCKETBOOST
454
object.timer = 32
455
object.turns = 2
456
object.state = MECHASONIC_ROCKETBOOST_CHARGE
457
break
458
459
case MECHASONIC_ROCKETBOOST_CHARGE
460
object.timer--
461
if object.timer < 0
462
object.timer = 64
463
object.xvel = object.gndStartSpeed
464
if object.moveDir == 0
465
FlipSign(object.xvel)
466
end if
467
object.moveDir ^= 1
468
PlaySfx(SfxName[Release], false)
469
object.state++
470
end if
471
break
472
473
case MECHASONIC_ROCKETBOOST_MAIN
474
object.xpos += object.xvel
475
object.timer--
476
if object.timer == 32
477
object.animationTimer = 0
478
object.spriteIndex = 0
479
object.rocketsFrame = 15
480
object.animation = MECHASONICANI_TURN
481
end if
482
483
if object.timer < 0
484
object.turns--
485
if object.turns > 0
486
object.timer = 32
487
object.animation = MECHASONICANI_ROCKETBOOST
488
object.state = MECHASONIC_ROCKETBOOST_CHARGE
489
else
490
CallFunction(MechaSonic_Reset)
491
end if
492
end if
493
494
if object.moveDir == 0
495
object.xvel -= object.gndAcceleration
496
else
497
object.xvel += object.gndAcceleration
498
end if
499
break
500
501
case MECHASONIC_EXPLODING
502
object.timer++
503
if object.timer == 240
504
object.timer = 0
505
object.exploding = false
506
temp0 = tileLayer[0].xsize
507
temp0 <<= 7
508
stage.newXBoundary2 = temp0
509
object.frame = 15
510
object.state = MECHASONIC_DISSAPPEAR
511
end if
512
break
513
514
case MECHASONIC_DISSAPPEAR
515
object.timer++
516
if object.timer == 60
517
object.type = TypeName[Blank Object]
518
end if
519
break
520
521
end switch
522
523
// Animate the object here
524
// Notably different front other boss objects, since those animate themselves in ObjectDraw instead
525
// However, since Mecha Sonic should pause upon death, animation is done here
526
switch object.animation
527
case MECHASONICANI_NONE
528
break
529
530
case MECHASONICANI_IDLE
531
object.animationTimer++
532
if object.animationTimer >= 3
533
object.animationTimer = 0
534
object.frame++
535
if object.frame >= 3
536
object.frame = 0
537
end if
538
end if
539
break
540
541
case MECHASONICANI_ROCKETBOOST
542
// This is the animation for boosting across the stage, with the rockets on Mecha Sonic's back
543
544
// Mecha Sonic's frame is constant...
545
object.frame = 3
546
547
// ...but still update the rockets' sprite
548
object.rocketsFrame = oscillation
549
object.rocketsFrame &= 3
550
object.rocketsFrame >>= 1
551
if object.state == MECHASONIC_ROCKETBOOST_MAIN
552
// Rockets
553
object.rocketsFrame += 9
554
else
555
// Sparks
556
object.rocketsFrame += 13
557
end if
558
break
559
560
case MECHASONICANI_TURN
561
object.animationTimer--
562
if object.animationTimer <= 0
563
object.animationTimer = 4
564
GetTableValue(object.frame, object.spriteIndex, MechaSonic_animation_turn)
565
object.spriteIndex++
566
if object.frame == 5
567
object.direction ^= FLIP_X
568
end if
569
570
if object.frame == 3
571
object.spriteIndex = 0
572
object.animationTimer = 255
573
end if
574
end if
575
break
576
577
case MECHASONICANI_CURL
578
object.animationTimer--
579
if object.animationTimer <= 0
580
object.animationTimer = 4
581
GetTableValue(object.frame, object.spriteIndex, MechaSonic_animation_curl)
582
object.spriteIndex++
583
if object.spriteIndex == 21
584
PlaySfx(SfxName[Buzzsaw], false)
585
object.spriteIndex = 0
586
object.frame = 6
587
object.animationTimer = 0
588
object.animation = MECHASONICANI_ROLLING
589
end if
590
end if
591
break
592
593
case MECHASONICANI_ROLLING
594
object.animationTimer++
595
if object.animationTimer >= 3
596
object.animationTimer = 0
597
object.frame++
598
if object.frame >= 9
599
object.frame = 6
600
end if
601
end if
602
break
603
604
case MECHASONICANI_UNCURL
605
object.animationTimer--
606
if object.animationTimer <= 0
607
object.animationTimer = 4
608
GetTableValue(object.frame, object.spriteIndex, MechaSonic_animation_uncurl)
609
object.spriteIndex++
610
if object.spriteIndex == 21
611
object.spriteIndex = 0
612
CallFunction(MechaSonic_Reset)
613
end if
614
end if
615
break
616
617
end switch
618
619
// Make sure the door for exiting the arena is closed, as long as Mecha Sonic is alive
620
object[+1].isOpen = false
621
622
if object.state > MECHASONIC_DESCENDING
623
if object.health != 0
624
if object.invincibilityTimer > 0
625
object.invincibilityTimer--
626
627
// Update the flashing black color
628
GetBit(temp0, object.invincibilityTimer, 0)
629
if temp0 == true
630
SetPaletteEntry(0, 192, 0xE0E0E0)
631
else
632
SetPaletteEntry(0, 192, 0x000000)
633
end if
634
end if
635
636
// Frames 6-8 are the jumping frames, where Mecha Sonic is completely wrapped with spikes (and undamagable as a result)
637
CheckEqual(object.frame, 6)
638
temp0 = checkResult
639
CheckEqual(object.frame, 7)
640
temp0 |= checkResult
641
CheckEqual(object.frame, 8)
642
temp0 |= checkResult
643
if temp0 != false
644
foreach (GROUP_PLAYERS, currentPlayer, ACTIVE_ENTITIES)
645
CallFunction(MechaSonic_CheckEggmanChuckle)
646
BoxCollisionTest(C_TOUCH, object.entityPos, -12, -12, 12, 12, currentPlayer, C_BOX, C_BOX, C_BOX, C_BOX)
647
if checkResult == true
648
CallFunction(Player_Hit)
649
end if
650
next
651
else
652
foreach (GROUP_PLAYERS, currentPlayer, ACTIVE_ENTITIES)
653
CallFunction(MechaSonic_CheckEggmanChuckle)
654
if object.animation == MECHASONICANI_IDLE
655
if object.direction == FLIP_NONE
656
if player[currentPlayer].xpos >= object.xpos
657
BoxCollisionTest(C_TOUCH, object.entityPos, -12, -12, 12, 12, currentPlayer, C_BOX, C_BOX, C_BOX, C_BOX)
658
if checkResult == true
659
CallFunction(Player_Hit)
660
end if
661
end if
662
else
663
if player[currentPlayer].xpos <= object.xpos
664
BoxCollisionTest(C_TOUCH, object.entityPos, -12, -12, 12, 12, currentPlayer, C_BOX, C_BOX, C_BOX, C_BOX)
665
if checkResult == true
666
CallFunction(Player_Hit)
667
end if
668
end if
669
end if
670
end if
671
672
if object.invincibilityTimer == 0
673
if player[currentPlayer].state != Player_State_GotHit
674
BoxCollisionTest(C_TOUCH, object.entityPos, -12, -12, 12, 12, currentPlayer, player[currentPlayer].hitboxLeft, player[currentPlayer].hitboxTop, player[currentPlayer].hitboxRight, player[currentPlayer].hitboxBottom)
675
if checkResult == true
676
CallFunction(Player_CheckHit)
677
if checkResult == true
678
object.health--
679
if object.health == 0
680
#platform: USE_ORIGINS
681
CallNativeFunction2(NotifyCallback, NOTIFY_KILL_BOSS, 0)
682
#endplatform
683
684
// None of the special global variable array stuff done here, since there's no multiplayer in DEZ
685
player.score += 1000
686
687
// Make Window Robotnik start running
688
object[-9].frame = 4
689
object[-9].animationTimer = 0
690
object[-9].animation = EGGMANWINDOWANI_CLOSEWINDOW
691
692
object.exploding = true
693
object.state = MECHASONIC_EXPLODING
694
object.timer = 0
695
696
StopSfx(SfxName[Saw])
697
StopSfx(SfxName[Release])
698
StopSfx(SfxName[Buzzsaw])
699
700
object.animation = MECHASONICANI_NONE
701
object.rocketsFrame = 15
702
else
703
object.invincibilityTimer = 32
704
// Even through a window, Eggman will still recoil when his machines are hit
705
if object[-9].animation > EGGMANWINDOWANI_OPENWINDOW
706
object[-9].animationTimer = 0
707
object[-9].animation = EGGMANWINDOWANI_STUNNED
708
end if
709
PlaySfx(SfxName[Boss Hit], false)
710
end if
711
end if
712
end if
713
end if
714
end if
715
next
716
end if
717
end if
718
end if
719
720
if object.state != MECHASONIC_DISSAPPEAR
721
// Sonic should never be able to reach the right side of the screen anyway - there's already a wall there - but enforce right bounds regardless
722
723
foreach (GROUP_PLAYERS, currentPlayer, ACTIVE_ENTITIES)
724
temp0 = player[currentPlayer].collisionRight
725
temp0 <<= 16
726
temp0 += player[currentPlayer].xpos
727
temp1 = stage.curXBoundary2
728
temp1 <<= 16
729
if temp0 > temp1
730
player[currentPlayer].xvel = 0
731
player[currentPlayer].speed = 0
732
player[currentPlayer].xpos = temp1
733
temp0 = player[currentPlayer].collisionRight
734
temp0 <<= 16
735
player[currentPlayer].xpos -= temp0
736
end if
737
next
738
end if
739
740
if object.exploding == true
741
temp0 = oscillation
742
temp0 &= 7
743
if temp0 == 0
744
Rand(temp0, 48)
745
temp0 -= 24
746
temp0 <<= 16
747
temp0 += object.xpos
748
Rand(temp1, 48)
749
temp1 -= 24
750
temp1 <<= 16
751
temp1 += object.ypos
752
CreateTempObject(TypeName[Explosion], 0, temp0, temp1)
753
object[tempObjectPos].drawOrder = 5
754
PlaySfx(SfxName[Explosion], false)
755
end if
756
end if
757
end event
758
759
760
event ObjectDraw
761
// Unlike other boss objects, Mecha Sonic's animation is kept in ObjectUpdate rather than being done here
762
763
if object.state > MECHASONIC_AWAITPLAYER
764
DrawSpriteFX(object.rocketsFrame, FX_FLIP, object.xpos, object.ypos)
765
DrawSpriteFX(object.frame, FX_FLIP, object.xpos, object.ypos)
766
end if
767
end event
768
769
770
event ObjectStartup
771
CheckCurrentStageFolder("Zone12")
772
if checkResult == true
773
LoadSpriteSheet("DEZ/Objects.gif")
774
775
// 0 - 2: Idle Frames
776
SpriteFrame(-20, -28, 40, 56, 1, 1)
777
SpriteFrame(-20, -28, 40, 56, 42, 1)
778
SpriteFrame(-20, -28, 40, 56, 83, 1)
779
780
// 3: Rocket Thrusting Frame
781
SpriteFrame(-20, -27, 40, 55, 124, 1)
782
783
// 4 - 5: Turning Frames
784
SpriteFrame(-22, -27, 42, 55, 165, 1)
785
SpriteFrame(-22, -27, 44, 55, 208, 1)
786
787
// 6 - 8: Jumping Frames
788
SpriteFrame(-24, -18, 48, 48, 255, 1)
789
SpriteFrame(-24, -18, 48, 48, 304, 1)
790
SpriteFrame(-24, -18, 48, 48, 353, 1)
791
792
// 9 - 10: Back Rocket Frames
793
SpriteFrame(14, 4, 24, 24, 402, 1)
794
SpriteFrame(14, 5, 24, 22, 427, 1)
795
796
// 11 - 12: Vertical Flame Sprites
797
SpriteFrame(-12, 28, 16, 8, 402, 26)
798
SpriteFrame(-12, 28, 16, 22, 419, 26)
799
800
// 13 - 14: Sparks Frames
801
SpriteFrame(19, 20, 19, 8, 452, 1)
802
SpriteFrame(20, 20, 18, 7, 452, 10)
803
804
// 15: Blank Frame (Used when rockets shouldn't show up)
805
SpriteFrame(0, 0, 1, 1, 1, 1)
806
else
807
LoadSpriteSheet("MBZ/Objects.gif")
808
809
// 0 - 2: Idle Frames
810
SpriteFrame(-20, -28, 40, 56, 513, 1)
811
SpriteFrame(-20, -28, 40, 56, 554, 1)
812
SpriteFrame(-20, -28, 40, 56, 595, 1)
813
814
// 3: Rocket Thrusting Frame
815
SpriteFrame(-20, -27, 40, 55, 636, 1)
816
817
// 4 - 5: Turning Frames
818
SpriteFrame(-22, -27, 42, 55, 677, 1)
819
SpriteFrame(-22, -27, 44, 55, 720, 1)
820
821
// 6 - 8: Jumping Frames
822
SpriteFrame(-24, -18, 48, 48, 767, 1)
823
SpriteFrame(-24, -18, 48, 48, 816, 1)
824
SpriteFrame(-24, -18, 48, 48, 865, 1)
825
826
// 9 - 10: Back Rocket Frames
827
SpriteFrame(14, 4, 24, 24, 914, 1)
828
SpriteFrame(14, 5, 24, 22, 939, 1)
829
830
// 11 - 12: Vertical Flame Sprites
831
SpriteFrame(-12, 28, 16, 8, 914, 26)
832
SpriteFrame(-12, 28, 16, 22, 931, 26)
833
834
// 13 - 14: Sparks Frames
835
SpriteFrame(19, 20, 19, 8, 964, 1)
836
SpriteFrame(20, 20, 18, 7, 964, 10)
837
838
// 15: Blank Frame (Interestingly, even for being blank this frame was still updated for MBZ despite being, well, blank)
839
SpriteFrame(0, 0, 1, 1, 513, 1)
840
end if
841
842
// Set all the movement cycle states into the table
843
// The compiler doesn't allow for aliased values to be in tables, which is why they're all set here instead
844
// (Though, it would've been far better for us if they just updated the compiler to allow for such instead...)
845
SetTableValue(MECHASONIC_GROUNDROLL_START, 0, MechaSonic_movementCycleStates)
846
SetTableValue(MECHASONIC_ROCKETBOOST_START, 1, MechaSonic_movementCycleStates)
847
SetTableValue(MECHASONIC_JUMPNORMAL_START, 2, MechaSonic_movementCycleStates)
848
SetTableValue(MECHASONIC_GROUNDROLL_START, 3, MechaSonic_movementCycleStates)
849
SetTableValue(MECHASONIC_GROUNDROLL_START, 4, MechaSonic_movementCycleStates)
850
SetTableValue(MECHASONIC_JUMPSPIKES_START, 5, MechaSonic_movementCycleStates)
851
SetTableValue(MECHASONIC_ROCKETBOOST_START, 6, MechaSonic_movementCycleStates)
852
SetTableValue(MECHASONIC_JUMPNORMAL_START, 7, MechaSonic_movementCycleStates)
853
SetTableValue(MECHASONIC_GROUNDROLL_START, 8, MechaSonic_movementCycleStates)
854
SetTableValue(MECHASONIC_GROUNDROLL_START, 9, MechaSonic_movementCycleStates)
855
SetTableValue(MECHASONIC_JUMPNORMAL_START, 10, MechaSonic_movementCycleStates)
856
SetTableValue(MECHASONIC_GROUNDROLL_START, 11, MechaSonic_movementCycleStates)
857
SetTableValue(MECHASONIC_ROCKETBOOST_START, 12, MechaSonic_movementCycleStates)
858
SetTableValue(MECHASONIC_GROUNDROLL_START, 13, MechaSonic_movementCycleStates)
859
SetTableValue(MECHASONIC_JUMPNORMAL_START, 14, MechaSonic_movementCycleStates)
860
SetTableValue(MECHASONIC_JUMPSPIKES_START, 15, MechaSonic_movementCycleStates)
861
end event
862
863
864
// ========================
865
// Editor Events
866
// ========================
867
868
event RSDKDraw
869
DrawSprite(0)
870
end event
871
872
873
event RSDKLoad
874
CheckCurrentStageFolder("Zone12")
875
if checkResult == true
876
LoadSpriteSheet("DEZ/Objects.gif")
877
SpriteFrame(-20, -28, 40, 56, 1, 1)
878
else
879
LoadSpriteSheet("MBZ/Objects.gif")
880
SpriteFrame(-20, -28, 40, 56, 513, 1)
881
end if
882
883
SetVariableAlias(ALIAS_VAR_PROPVAL, "unused")
884
end event
885
886