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/DeathEggRobot.txt
1482 views
1
// ----------------------------------
2
// RSDK Project: Sonic 2
3
// Script Description: Death Egg Robot 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
14
private alias object.value1 : object.headOffset.x
15
private alias object.value2 : object.headOffset.y
16
private alias object.value3 : object.movementCycle
17
private alias object.value4 : object.subState
18
private alias object.value5 : object.midpoint
19
private alias object.value6 : object.health
20
private alias object.value7 : object.invincibilityTimer
21
private alias object.value8 : object.exploding
22
private alias object.value9 : object.bombs // Offset used when spawning bombs
23
24
private alias object.value10 : object.flame.frame
25
private alias object.value11 : object.flame.timer
26
private alias object.value12 : object.flame.animSpeed
27
private alias object.value13 : object.flame.state
28
29
// Values used for the managing the following cutscene
30
private alias object.value14 : object.screenShake
31
private alias object.value15 : object.checkpoint // Offset to use for the One Way Doors checkpoints when making Sonic run away
32
private alias object.value16 : object.fadeValue
33
34
// States
35
private alias -1 : DERMAIN_STATIC
36
private alias 0 : DERMAIN_INIT
37
private alias 1 : DERMAIN_AWAITEGGMAN
38
private alias 2 : DERMAIN_RAISEHEAD
39
private alias 3 : DERMAIN_CLOSEHEAD
40
private alias 4 : DERMAIN_SUBPAUSE
41
private alias 5 : DERMAIN_RAISE
42
private alias 6 : DERMAIN_READYPAUSE
43
private alias 7 : DERMAIN_NEXTPHASE
44
private alias 8 : DERMAIN_WALKING
45
private alias 9 : DERMAIN_ASCEND // Includes being in the sky and landing, too
46
private alias 10 : DERMAIN_ARMSHOOT
47
private alias 11 : DERMAIN_EXPLODING
48
49
// The Death Egg Robot manages the ending cutscene too
50
private alias 12 : DERMAIN_SCREENSHAKE
51
private alias 13 : DERMAIN_CORRDIOREXPLODE
52
private alias 14 : DERMAIN_FADEOUT
53
54
// Substates used by "complete" states
55
56
// DERMAIN_WALKING substates
57
private alias 0 : DER_SUB_WALKING_INIT
58
private alias 1 : DER_SUB_WALKING_WALKAHEAD
59
private alias 2 : DER_SUB_WALKING_PAUSE
60
private alias 3 : DER_SUB_WALKING_BACKSTEP
61
62
// DERMAIN_ASCEND substates
63
private alias 0 : DER_SUB_ASCEND_INIT
64
private alias 1 : DER_SUB_ASCEND_JUMP
65
private alias 2 : DER_SUB_ASCEND_RISE
66
private alias 3 : DER_SUB_ASCEND_CREATETARGET
67
private alias 4 : DER_SUB_ASCEND_OFFSCREEN
68
private alias 5 : DER_SUB_ASCEND_FALL
69
private alias 6 : DER_SUB_ASCEND_LAND
70
private alias 7 : DER_SUB_ASCEND_BOMBPAUSE
71
72
// DERMAIN_ARMSHOOT substates
73
private alias 0 : DER_SUB_ARMSHOOT_INIT
74
private alias 1 : DER_SUB_ARMSHOOT_BENDDOWN
75
private alias 2 : DER_SUB_ARMSHOOT_LARMSHOT
76
private alias 3 : DER_SUB_ARMSHOOT_SHOOTRARM
77
private alias 4 : DER_SUB_ARMSHOOT_RARMSHOT
78
private alias 5 : DER_SUB_ARMSHOOT_GETUP
79
80
// entityPos offset aliases
81
// Not directly used, but here for reference
82
private alias 5 : DER_OFFSET_SHOULDER
83
private alias 4 : DER_OFFSET_FOOT_FRONT
84
private alias 3 : DER_OFFSET_HAND_FRONT
85
private alias 2 : DER_OFFSET_ARM
86
private alias 1 : DER_OFFSET_LEG_FRONT
87
private alias 0 : DER_OFFSET_DERMAIN
88
private alias -1 : DER_OFFSET_FOOT_BACK
89
private alias -2 : DER_OFFSET_HAND_BACK
90
private alias -3 : DER_OFFSET_LEG_BACK
91
92
// Player Aliases
93
private alias object.state : player.state
94
private alias object.xpos : player.xpos
95
private alias object.xvel : player.xvel
96
private alias object.speed : player.speed
97
private alias object.animation : player.animation
98
private alias object.collisionRight : player.collisionRight
99
private alias object.value40 : player.hitboxLeft
100
private alias object.value38 : player.hitboxTop
101
private alias object.value41 : player.hitboxRight
102
private alias object.value39 : player.hitboxBottom
103
104
// Shared DER appendages states
105
private alias 1 : BODYPART_DESTROYED
106
private alias 2 : BODYPART_ACTIVE
107
108
// DER Bomb Aliases
109
private alias object.value1 : DERBomb.originPos.y
110
111
// DER Hand Aliases
112
private alias object.value0 : DERHand.timer
113
private alias object.value1 : DERHand.originPos.y
114
115
private alias 3 : DERHAND_FIRE
116
117
// One Way Door Aliases
118
// (Used in cutscene)
119
private alias object.state : oneWayDoor.isOpen
120
121
// Game Mode Aliases
122
private alias 1 : MODE_SAVEGAME
123
124
// Reserved object slot Aliases
125
private alias 0 : SLOT_PLAYER1
126
private alias 25 : SLOT_MUSICEVENT_CHANGE
127
private alias 26 : SLOT_MUSICEVENT_BOSS
128
129
// Music Events
130
private alias 0 : MUSICEVENT_FADETOBOSS
131
private alias 2 : MUSICEVENT_TRANSITION
132
133
// Path ID Aliases
134
private alias 0 : PATH_A
135
136
137
// ========================
138
// Function Declarations
139
// ========================
140
141
reserve function DeathEggRobot_RestoreBodyParts
142
reserve function DeathEggRobot_CheckAnimEX
143
reserve function DeathEggRobot_AnimateBody
144
reserve function DeathEggRobot_CreateBombs
145
146
147
// ========================
148
// Tables (and lots of them!)
149
// ========================
150
151
// The cycle DER should follow
152
private table DeathEggRobot_phaseOrder
153
8 // DERMAIN_WALKING
154
9 // DERMAIN_ASCEND
155
10 // DERMAIN_ARMSHOOT
156
9 // DERMAIN_ASCEND
157
end table
158
159
// These DeathEggRobot_anim_* tables are root animation tables, used when calling animateBody
160
// The first entry in them gets replaced with a table ID, the rest of the numbers in them are animation flags
161
162
private table DeathEggRobot_anim_bendDown
163
0 // DeathEggRobot_anim_sub_bend gets placed here
164
0, 1, 2, 3, -1, 0
165
end table
166
167
private table DeathEggRobot_anim_getUp
168
0 // DeathEggRobot_anim_sub_bend gets placed here
169
5, 6, 7, 8, -1, 0
170
end table
171
172
private table DeathEggRobot_anim_land
173
0 // DeathEggRobot_anim_sub_bend gets placed here
174
0, 1, 2, 3, 4, 5, 6, 7, 8, 192
175
end table
176
177
// This is the anim sub-table used for the above proper anim tables
178
// (confusing system, I know)
179
private table DeathEggRobot_anim_sub_bend[9]
180
181
182
private table DeathEggRobot_anim_jump
183
0 // DeathEggRobot_anim_sub_jump gets placed here
184
0, 1, 2, 192
185
end table
186
187
188
// Also an anim sub-table
189
private table DeathEggRobot_anim_sub_jump[3]
190
191
192
private table DeathEggRobot_anim_stepAhead
193
0 // DeathEggRobot_anim_sub_walk gets placed here
194
0, 1, 2, 3, 64, 4, 5, 6, 7, 8, 64, 9, 10, 1, 2, 3, 64, 4, 5, 6, 7, 8, 64, 192
195
end table
196
197
198
private table DeathEggRobot_anim_stepBack
199
0 // DeathEggRobot_anim_sub_walk gets placed here
200
136, 135, 134, 133, 11, 64, 192
201
end table
202
203
204
// The last anim sub-table, also placed in a weird spot
205
private table DeathEggRobot_anim_sub_walk[12]
206
207
208
// All the way over here for some reason, this frame was likely added after the entire object had already been completed
209
private table DeathEggRobot_bend_frame_5
210
0
211
8
212
0, 0, 0
213
end table
214
215
// Similar story here to the above
216
private table DeathEggRobot_jump_frame_2
217
0
218
16
219
0, 0, 0
220
end table
221
222
// Holds the base positions of all DER body parts
223
// Format of the table:
224
// - First number is how many "entries" there are
225
// Then each entry consists of
226
// -> Object entity pos (relative to the current Death Egg Robot object)
227
// -> X offset (from this object's pos, will automatically get flipped when facing the other way)
228
// -> Y offset (from this object's pos)
229
private table DeathEggRobot_bodyPartsOrigin
230
6
231
4, -0x40000, 0x3C0000
232
3, -0xC0000, 0x080000
233
2, 0xC0000, -0x080000
234
1, 0x40000, 0x240000
235
-1, -0x40000, 0x3C0000
236
-2, -0xC0000, 0x080000
237
-3, 0x40000, 0x240000
238
end table
239
240
241
// All these remaining DeathEggRobot_*_frame_* tables are individual animation entries
242
// The format they follow is pretty similar to the above
243
// - First number is how many "entries" in the table there are (not counting the next number)
244
// - Second number is the delay for this frame in the animation
245
// Then, the rest of the table is individual component entries, each entry comprised of 3 numbers
246
// All offsets are relative to the main DER object
247
// - First number is the offset (entityPos-wise) for the target component
248
// - Second number is X offset for the component to move
249
// - Third number is the Y offset
250
251
// These first few are for the animations in which the DER bends down, like when jumping or shooting arms
252
253
private table DeathEggRobot_bend_frame_1
254
5
255
8
256
0, -0x2000, 0x0C00
257
3, -0x2000, 0x0C00
258
2, -0x2000, 0x0C00
259
-2, -0x2000, 0x0C00
260
1, -0x0800, 0x0400
261
-3, -0x0800, 0x0400
262
end table
263
264
private table DeathEggRobot_bend_frame_2
265
5
266
8
267
0, -0x1400, 0x1400
268
3, -0x1400, 0x1400
269
2, -0x1400, 0x1400
270
-2, -0x1400, 0x1400
271
1, -0x0600, 0x0600
272
-3, -0x0600, 0x0600
273
end table
274
275
private table DeathEggRobot_bend_frame_3
276
5
277
8
278
0, -0x0800, 0x1400
279
3, -0x0800, 0x1400
280
2, -0x0800, 0x1400
281
-2, -0x0800, 0x1400
282
1, -0x0200, 0x0400
283
-3, -0x0200, 0x0400
284
end table
285
286
private table DeathEggRobot_bend_frame_4
287
5
288
8
289
0, -0x0400, 0x0C00
290
3, -0x0400, 0x0C00
291
2, -0x0400, 0x0C00
292
-2, -0x0400, 0x0C00
293
1, 0x0000, 0x0200
294
-3, 0x0000, 0x0200
295
end table
296
297
// frame5 is all the way at the top, separate from these for some reason
298
// Perhaps it was added late in dev or something
299
300
private table DeathEggRobot_bend_frame_6
301
5
302
8
303
0, 0x0400, -0x1800
304
3, 0x0400, -0x1800
305
2, 0x0400, -0x1800
306
-2, 0x0400, -0x1800
307
1, 0x0200, -0x0600
308
-3, 0x0200, -0x0600
309
end table
310
311
private table DeathEggRobot_bend_frame_7
312
5
313
8
314
0, 0x0C00, -0x1800
315
3, 0x0C00, -0x1800
316
2, 0x0C00, -0x1800
317
-2, 0x0C00, -0x1800
318
1, 0x0400, -0x0400
319
-3, 0x0400, -0x0400
320
end table
321
322
private table DeathEggRobot_bend_frame_8
323
5
324
8
325
0, 0x1800, -0x0C00
326
3, 0x1800, -0x0C00
327
2, 0x1800, -0x0C00
328
-2, 0x1800, -0x0C00
329
1, 0x0400, -0x0400
330
-3, 0x0400, -0x0400
331
end table
332
333
private table DeathEggRobot_bend_frame_9
334
5
335
8
336
0, 0x1800, -0x0400
337
3, 0x1800, -0x0400
338
2, 0x1800, -0x0400
339
-2, 0x1800, -0x0400
340
1, 0x0600, -0x0200
341
-3, 0x0600, -0x0200
342
end table
343
344
// These next couple of tables are frames for the jumping animation
345
346
private table DeathEggRobot_jump_frame_1
347
5
348
16
349
0, 0x0000, 0x0400
350
3, 0x0000, 0x0400
351
2, 0x0000, 0x0400
352
-2, 0x0000, 0x0400
353
1, 0x0000, 0x0400
354
-3, 0x0000, 0x0400
355
end table
356
357
// frame2 is all the way near the end of the list, it seems it was added in post after everything else was done
358
359
private table DeathEggRobot_jump_frame_3
360
5
361
8
362
0, 0x0000, -0x0800
363
3, 0x0000, -0x0800
364
2, 0x0000, -0x0800
365
-2, 0x0000, -0x0800
366
1, 0x0000, -0x0800
367
-3, 0x0000, -0x0800
368
end table
369
370
// And finally, these last tables are frames for the walking animation
371
372
private table DeathEggRobot_walk_frame_1
373
6
374
32
375
1, -0x0800, -0x0800
376
4, -0x0800, -0x0800
377
0, 0x0000, -0x0400
378
3, 0x0400, -0x0500
379
2, 0x0300, -0x0500
380
-2, -0x0400, -0x0500
381
-3, 0x0000, -0x0200
382
end table
383
384
private table DeathEggRobot_walk_frame_2
385
6
386
16
387
1, -0x1000, -0x0400
388
4, -0x1000, -0x0400
389
0, -0x1000, -0x0400
390
3, -0x0C00, -0x0500
391
2, -0x0D00, -0x0500
392
-2, -0x1400, -0x0500
393
-3, -0x0800, 0x0000
394
end table
395
396
private table DeathEggRobot_walk_frame_3
397
5
398
16
399
1, -0x0800, 0x0400
400
4, -0x0800, 0x0400
401
0, -0x0800, 0x0400
402
3, -0x0400, 0x0300
403
2, -0x0500, 0x0300
404
-2, -0x0C00, 0x0300
405
end table
406
407
private table DeathEggRobot_walk_frame_4
408
6
409
16
410
1, -0x0400, 0x1000
411
4, -0x0800, 0x1000
412
0, 0x0000, 0x0800
413
3, -0x0800, 0x0A00
414
2, -0x0600, 0x0A00
415
-2, 0x0800, 0x0A00
416
-3, 0x0000, 0x0800
417
end table
418
419
private table DeathEggRobot_walk_frame_5
420
6
421
32
422
1, -0x0200, -0x0200
423
0, -0x0C00, -0x0400
424
3, -0x1000, -0x0300
425
2, -0x0F00, -0x0300
426
-2, -0x0800, -0x0300
427
-3, -0x1400, -0x0600
428
-1, -0x1800, -0x0400
429
end table
430
431
private table DeathEggRobot_walk_frame_6
432
4
433
32
434
-3, -0x0800, -0x0400
435
-1, -0x0800, -0x0400
436
3, -0x0400, -0x0100
437
2, -0x0300, -0x0100
438
-2, 0x0400, -0x0100
439
end table
440
441
private table DeathEggRobot_walk_frame_7
442
6
443
16
444
-3, -0x1000, -0x0400
445
-1, -0x1000, -0x0400
446
0, -0x1000, -0x0400
447
3, -0x1400, -0x0500
448
2, -0x1300, -0x0500
449
-2, -0x0C00, -0x0500
450
1, -0x0800, 0x0000
451
end table
452
453
private table DeathEggRobot_walk_frame_8
454
5
455
16
456
-3, -0x0800, 0x0400
457
-1, -0x0800, 0x0400
458
0, -0x0800, 0x0400
459
3, -0x0C00, 0x0300
460
2, -0x0B00, 0x0300
461
-2, -0x0400, 0x0300
462
end table
463
464
private table DeathEggRobot_walk_frame_9
465
6
466
16
467
-3, -0x0400, 0x1000
468
-1, -0x0800, 0x1000
469
0, 0x0000, 0x0800
470
3, 0x0800, 0x0A00
471
2, 0x0600, 0x0A00
472
-2, -0x0800, 0x0A00
473
1, 0x0000, 0x0800
474
end table
475
476
private table DeathEggRobot_walk_frame_10
477
6
478
32
479
-3, -0x0200, -0x0200
480
0, -0x0C00, -0x0400
481
3, -0x0800, -0x0300
482
2, -0x0900, -0x0300
483
-2, -0x0F00, -0x0300
484
1, -0x1400, -0x0600
485
4, -0x1800, -0x0400
486
end table
487
488
private table DeathEggRobot_walk_frame_11
489
4
490
32
491
1, -0x0800, -0x0600
492
4, -0x0800, -0x0400
493
3, 0x0400, -0x0100
494
2, 0x0300, -0x0100
495
-2, -0x0400, -0x0100
496
end table
497
498
private table DeathEggRobot_walk_frame_12
499
6
500
16
501
-3, 0x0000, 0x0800
502
-1, 0x0000, 0x0800
503
0, 0x0000, 0x0800
504
3, 0x0000, 0x0800
505
2, 0x0000, 0x0800
506
-2, 0x0000, 0x0800
507
1, 0x0000, 0x0800
508
end table
509
510
511
// And now, finally, the actual code starts!
512
513
// ========================
514
// Function Definitions
515
// ========================
516
517
private function DeathEggRobot_RestoreBodyParts
518
// Restores all the body parts back to their normal positions, used for cleanup quite often
519
520
// Preconditions:
521
// - temp0 is set to the table ID of a DER body part table (always DeathEggRobot_bodyPartsOrigin)
522
523
temp7 = 0
524
525
// First, get entry count
526
GetTableValue(temp6, temp7, temp0)
527
temp7++
528
while temp6 >= 0
529
530
// Get the object's entity pos offset
531
GetTableValue(temp1, temp7, temp0)
532
temp7++
533
arrayPos0 = object.entityPos
534
arrayPos0 += temp1
535
536
// Object xpos offset
537
GetTableValue(temp1, temp7, temp0)
538
temp7++
539
540
// Object ypos offset
541
GetTableValue(temp2, temp7, temp0)
542
temp7++
543
544
// Update xpos
545
object[arrayPos0].xpos = object.xpos
546
if object.direction == FLIP_NONE
547
object[arrayPos0].xpos += temp1
548
else
549
object[arrayPos0].xpos -= temp1
550
end if
551
552
// Update ypos
553
object[arrayPos0].ypos = object.ypos
554
object[arrayPos0].ypos += temp2
555
556
temp6--
557
loop
558
end function
559
560
561
private function DeathEggRobot_CheckAnimEX
562
temp7 = true
563
while temp7 == true
564
temp7 = false
565
temp0 &= 63
566
temp1 >>= 6
567
switch temp1
568
case 1
569
// Used when the legs are moving
570
if object.animationTimer == 0
571
object.frame++
572
PlaySfx(SfxName[Crusher], false)
573
GetTableValue(temp0, object.frame, temp6)
574
temp1 = temp0
575
temp1 &= 192
576
if temp1 != 0
577
temp7 = true
578
end if
579
end if
580
break
581
582
case 2
583
// Flip flag
584
temp4 = true
585
break
586
587
case 3
588
// Stop the object from animating (for this frame, at least)
589
object.frame = 1
590
checkResult = true
591
break
592
593
end switch
594
loop
595
end function
596
597
598
private function DeathEggRobot_AnimateBody
599
// Preconditions:
600
// - When this function is called, temp6 is holding an animation table
601
// This table is, itself, holding another table, where that table being held also contains a long string of tables
602
// Far too many tables to wrap your head around, to say the least...
603
604
// Essentially, what this function itself does is move and animate the body
605
606
GetTableValue(temp5, 0, temp6)
607
608
GetTableValue(temp0, object.frame, temp6)
609
temp1 = temp0
610
temp4 = false
611
temp1 &= 192
612
613
checkResult = false
614
if temp0 != 0
615
CallFunction(DeathEggRobot_CheckAnimEX)
616
end if
617
618
if checkResult == false
619
GetTableValue(temp2, temp0, temp5)
620
temp7 = 0
621
GetTableValue(temp0, temp7, temp2)
622
temp7++
623
GetTableValue(temp3, temp7, temp2)
624
temp7++
625
object.animationTimer++
626
if object.animationTimer >= temp3
627
object.animationTimer = 0
628
object.frame++
629
end if
630
631
while temp0 >= 0
632
GetTableValue(temp5, temp7, temp2)
633
temp7++
634
arrayPos0 = object.entityPos
635
arrayPos0 += temp5
636
GetTableValue(temp1, temp7, temp2)
637
temp7++
638
temp1 <<= 4
639
if object.direction == FLIP_NONE
640
if temp4 == false
641
object[arrayPos0].xpos += temp1
642
else
643
object[arrayPos0].xpos -= temp1
644
end if
645
else
646
if temp4 == false
647
object[arrayPos0].xpos -= temp1
648
else
649
object[arrayPos0].xpos += temp1
650
end if
651
end if
652
GetTableValue(temp1, temp7, temp2)
653
temp7++
654
temp1 <<= 4
655
if temp4 == false
656
object[arrayPos0].ypos += temp1
657
else
658
object[arrayPos0].ypos -= temp1
659
end if
660
temp0--
661
loop
662
end if
663
end function
664
665
666
private function DeathEggRobot_CreateBombs
667
arrayPos0 = object[-7].entityPos
668
669
// Offset the entity pos based on the last bombs used, in case there's more than one pair active
670
arrayPos0 += object.bombs
671
672
// Update the value with a cap of 3, there should only ever be 4 bombs (2 pairs) max active at one point
673
object.bombs += 2
674
object.bombs &= 3
675
676
// Create bomb 1
677
object[arrayPos0].type = TypeName[DER Bomb]
678
object[arrayPos0].xpos = object.xpos
679
if object.direction == FLIP_NONE
680
object[arrayPos0].xpos += 0x380000
681
object[arrayPos0].xvel = 0x6000
682
else
683
object[arrayPos0].xpos -= 0x380000
684
object[arrayPos0].xvel = -0x6000
685
end if
686
object[arrayPos0].ypos = object.ypos
687
object[arrayPos0].ypos -= 0x140000
688
object[arrayPos0].yvel = -0x80000
689
DERBomb[arrayPos0].originPos.y = object[arrayPos0].ypos
690
object[arrayPos0].priority = PRIORITY_ACTIVE
691
692
arrayPos0++
693
694
// And now create bomb 2
695
object[arrayPos0].type = TypeName[DER Bomb]
696
object[arrayPos0].xpos = object.xpos
697
if object.direction == FLIP_NONE
698
object[arrayPos0].xpos += 0x380000
699
object[arrayPos0].xvel = 0xC000
700
else
701
object[arrayPos0].xpos -= 0x380000
702
object[arrayPos0].xvel = -0xC000
703
end if
704
object[arrayPos0].ypos = object.ypos
705
object[arrayPos0].ypos -= 0x140000
706
object[arrayPos0].yvel = -0xA0000
707
DERBomb[arrayPos0].originPos.y = object[arrayPos0].ypos
708
object[arrayPos0].priority = PRIORITY_ACTIVE
709
end function
710
711
712
// ========================
713
// Events
714
// ========================
715
716
event ObjectUpdate
717
switch object.state
718
case DERMAIN_INIT
719
temp0 = stage.curYBoundary2
720
temp0 -= screen.ysize
721
stage.newYBoundary1 = temp0
722
723
temp0 = object.xpos
724
temp0 >>= 16
725
temp0 += 68
726
stage.newXBoundary2 = temp0
727
728
temp0 -= 0x200
729
stage.newXBoundary1 = temp0
730
object.priority = PRIORITY_ACTIVE
731
732
// Setup all the body parts
733
// - Order is important, as it also controls the order the sprites should be drawn
734
// - Back-most appendages are behind this object in entityPos, frontwise are, well, in-front in terms of both draw order and entityPos too
735
736
object[+5].type = TypeName[DER Shoulder]
737
object[+5].priority = PRIORITY_ACTIVE
738
739
// Front foot
740
object[+4].type = TypeName[DER Foot]
741
object[+4].priority = PRIORITY_ACTIVE
742
743
// Front hand
744
object[+3].type = TypeName[DER Hand]
745
object[+3].priority = PRIORITY_ACTIVE
746
747
object[+2].type = TypeName[DER Arm]
748
object[+2].priority = PRIORITY_ACTIVE
749
750
// Front leg
751
object[+1].type = TypeName[DER Leg]
752
object[+1].priority = PRIORITY_ACTIVE
753
754
// Back foot
755
object[-1].type = TypeName[DER Foot]
756
object[-1].priority = PRIORITY_ACTIVE
757
758
// Back hand
759
object[-2].type = TypeName[DER Hand]
760
object[-2].priority = PRIORITY_ACTIVE
761
762
// Back leg
763
object[-3].type = TypeName[DER Leg]
764
object[-3].priority = PRIORITY_ACTIVE
765
766
object.midpoint = object.xpos
767
object.midpoint -= 0xC00000
768
769
#platform: USE_STANDALONE
770
object.health = 12
771
#endplatform
772
#platform: USE_ORIGINS
773
if game.bossOneLife == false
774
object.health = 12
775
else
776
object.health = 1
777
end if
778
#endplatform
779
780
temp0 = DeathEggRobot_bodyPartsOrigin
781
CallFunction(DeathEggRobot_RestoreBodyParts)
782
object.frame = 1
783
object.flame.frame = 5
784
SetMusicTrack("FinalBoss.ogg", 4, true)
785
object.state = DERMAIN_AWAITEGGMAN
786
break
787
788
case DERMAIN_AWAITEGGMAN
789
break
790
791
case DERMAIN_RAISEHEAD
792
object.headOffset.y -= 0x10000
793
if object.headOffset.y <= -0x240000
794
object.state = DERMAIN_CLOSEHEAD
795
end if
796
break
797
798
case DERMAIN_CLOSEHEAD
799
object.headOffset.x -= 0x7800
800
object.rotation -= 4
801
if object.rotation <= 0
802
object.state = DERMAIN_SUBPAUSE
803
end if
804
break
805
806
case DERMAIN_SUBPAUSE
807
object.timer++
808
if object.timer == 112
809
vs.bossAttack = false
810
ResetObjectEntity(SLOT_MUSICEVENT_BOSS, TypeName[Music Event], MUSICEVENT_FADETOBOSS, 0, 0)
811
object[SLOT_MUSICEVENT_BOSS].priority = PRIORITY_ACTIVE
812
end if
813
814
if object.timer == 180
815
object.timer = 0
816
PlaySfx(SfxName[Large Wall], false)
817
object.flame.frame = 5
818
object.flame.animSpeed = 4
819
object.flame.state = 1
820
object.state = DERMAIN_RAISE
821
end if
822
break
823
824
case DERMAIN_RAISE
825
object.ypos -= 0x10000
826
object.timer++
827
if object.timer == 30
828
PlaySfx(SfxName[Large Wall], false)
829
end if
830
831
if object.timer == 120
832
object.timer = 0
833
834
// Tell the rest of the body to get ready
835
object[+5].state = BODYPART_ACTIVE
836
object[+4].state = BODYPART_ACTIVE
837
object[+3].state = BODYPART_ACTIVE
838
object[+2].state = BODYPART_ACTIVE
839
object[+1].state = BODYPART_ACTIVE
840
object[-1].state = BODYPART_ACTIVE
841
object[-2].state = BODYPART_ACTIVE
842
object[-3].state = BODYPART_ACTIVE
843
844
object.flame.state = 2
845
object.state = DERMAIN_READYPAUSE
846
end if
847
848
temp0 = DeathEggRobot_bodyPartsOrigin
849
CallFunction(DeathEggRobot_RestoreBodyParts)
850
break
851
852
case DERMAIN_READYPAUSE
853
object.timer++
854
if object.timer == 32
855
object.timer = 0
856
object.state = DERMAIN_NEXTPHASE
857
end if
858
break
859
860
case DERMAIN_NEXTPHASE
861
object.timer = 32
862
object.subState = 0
863
GetTableValue(object.state, object.movementCycle, DeathEggRobot_phaseOrder)
864
if object.state == DERMAIN_ASCEND
865
object.flame.frame = 5
866
object.flame.animSpeed = 16
867
object.flame.state = 1
868
end if
869
object.movementCycle++
870
object.movementCycle &= 3
871
break
872
873
case DERMAIN_WALKING
874
switch object.subState
875
case DER_SUB_WALKING_INIT
876
object.timer--
877
if object.timer < 0
878
object.subState = DER_SUB_WALKING_WALKAHEAD
879
end if
880
break
881
882
case DER_SUB_WALKING_WALKAHEAD
883
temp6 = DeathEggRobot_anim_stepAhead
884
CallFunction(DeathEggRobot_AnimateBody)
885
if checkResult == true
886
object.timer = 64
887
object.subState = DER_SUB_WALKING_PAUSE
888
end if
889
break
890
891
case DER_SUB_WALKING_PAUSE
892
object.timer--
893
if object.timer < 0
894
object.subState = DER_SUB_WALKING_BACKSTEP
895
end if
896
break
897
898
case DER_SUB_WALKING_BACKSTEP
899
temp6 = DeathEggRobot_anim_stepBack
900
CallFunction(DeathEggRobot_AnimateBody)
901
if checkResult == true
902
object.timer = 64
903
object.state = DERMAIN_NEXTPHASE
904
end if
905
break
906
907
end switch
908
break
909
910
case DERMAIN_ASCEND
911
switch object.subState
912
case DER_SUB_ASCEND_INIT
913
object.timer--
914
if object.timer < 0
915
object.subState = DER_SUB_ASCEND_JUMP
916
end if
917
break
918
919
case DER_SUB_ASCEND_JUMP
920
temp6 = DeathEggRobot_anim_jump
921
CallFunction(DeathEggRobot_AnimateBody)
922
if checkResult == true
923
object.timer = 128
924
PlaySfx(SfxName[Thruster], false)
925
object.subState = DER_SUB_ASCEND_RISE
926
end if
927
break
928
929
case DER_SUB_ASCEND_RISE
930
object.timer--
931
if object.timer < 0
932
object.subState = DER_SUB_ASCEND_CREATETARGET
933
else
934
object.ypos -= 0x20000
935
temp0 = oscillation
936
temp0 &= 31
937
if temp0 == 0
938
PlaySfx(SfxName[Thruster], false)
939
end if
940
temp0 = DeathEggRobot_bodyPartsOrigin
941
CallFunction(DeathEggRobot_RestoreBodyParts)
942
end if
943
break
944
945
case DER_SUB_ASCEND_CREATETARGET
946
// Because the timer isn't reset between this and the previous substate, this state only lasts for a single frame
947
object.timer--
948
if object.timer < 0
949
object.timer = 0
950
object.subState = DER_SUB_ASCEND_OFFSCREEN
951
object[+6].type = TypeName[DER Target]
952
object[+6].xpos = object[SLOT_PLAYER1].xpos
953
object[+6].ypos = object[SLOT_PLAYER1].ypos
954
end if
955
break
956
957
case DER_SUB_ASCEND_OFFSCREEN
958
if object.timer != 0
959
if object.xpos < object.midpoint
960
object.direction = FLIP_X
961
else
962
object.direction = FLIP_NONE
963
end if
964
965
object[+5].direction = object.direction
966
object[+4].direction = object.direction
967
object[+3].direction = object.direction
968
object[+2].direction = object.direction
969
object[+1].direction = object.direction
970
object[-1].direction = object.direction
971
object[-2].direction = object.direction
972
object[-3].direction = object.direction
973
974
object.timer = 32
975
temp0 = DeathEggRobot_bodyPartsOrigin
976
CallFunction(DeathEggRobot_RestoreBodyParts)
977
object.subState = DER_SUB_ASCEND_FALL
978
end if
979
break
980
981
case DER_SUB_ASCEND_FALL
982
object.timer--
983
if object.timer < 0
984
object.timer = 64
985
PlaySfx(SfxName[Ledge Break], false)
986
object.screenShake = 64
987
object.flame.state = 2
988
object.subState = DER_SUB_ASCEND_LAND
989
else
990
object.ypos += 0x80000
991
temp0 = DeathEggRobot_bodyPartsOrigin
992
CallFunction(DeathEggRobot_RestoreBodyParts)
993
end if
994
break
995
996
case DER_SUB_ASCEND_LAND
997
temp6 = DeathEggRobot_anim_land
998
CallFunction(DeathEggRobot_AnimateBody)
999
if checkResult == true
1000
temp0 = DeathEggRobot_bodyPartsOrigin
1001
CallFunction(DeathEggRobot_RestoreBodyParts)
1002
1003
temp0 = false
1004
1005
if object.direction == FLIP_NONE
1006
if object[SLOT_PLAYER1].xpos > object.xpos
1007
temp0 = true
1008
end if
1009
else
1010
if object[SLOT_PLAYER1].xpos < object.xpos
1011
temp0 = true
1012
end if
1013
end if
1014
1015
if temp0 == false
1016
object.state = DERMAIN_NEXTPHASE
1017
else
1018
object.timer = 96
1019
object.subState = DER_SUB_ASCEND_BOMBPAUSE
1020
CallFunction(DeathEggRobot_CreateBombs)
1021
end if
1022
end if
1023
break
1024
1025
case DER_SUB_ASCEND_BOMBPAUSE
1026
object.timer--
1027
if object.timer < 0
1028
object.state = DERMAIN_NEXTPHASE
1029
end if
1030
break
1031
1032
end switch
1033
break
1034
1035
case DERMAIN_ARMSHOOT
1036
switch object.subState
1037
case DER_SUB_ARMSHOOT_INIT
1038
object.timer--
1039
if object.timer < 0
1040
object.subState = DER_SUB_ARMSHOOT_BENDDOWN
1041
end if
1042
break
1043
1044
case DER_SUB_ARMSHOOT_BENDDOWN
1045
temp6 = DeathEggRobot_anim_bendDown
1046
CallFunction(DeathEggRobot_AnimateBody)
1047
if checkResult == true
1048
temp0 = false
1049
if object.direction == FLIP_NONE
1050
if object[SLOT_PLAYER1].xpos > object.xpos
1051
temp0 = true
1052
end if
1053
else
1054
if object[SLOT_PLAYER1].xpos < object.xpos
1055
temp0 = true
1056
end if
1057
end if
1058
1059
if temp0 == false
1060
object.timer = 64
1061
object[+3].state = DERHAND_FIRE
1062
DERHand[+3].timer = 16
1063
DERHand[+3].originPos.y = object[+3].ypos
1064
object.subState = DER_SUB_ARMSHOOT_LARMSHOT
1065
else
1066
object.timer = 32
1067
object.subState = DER_SUB_ARMSHOOT_RARMSHOT
1068
CallFunction(DeathEggRobot_CreateBombs)
1069
end if
1070
end if
1071
break
1072
1073
case DER_SUB_ARMSHOOT_LARMSHOT
1074
object.timer--
1075
if object.timer < 0
1076
object.subState = DER_SUB_ARMSHOOT_SHOOTRARM
1077
end if
1078
break
1079
1080
case DER_SUB_ARMSHOOT_SHOOTRARM
1081
object.timer--
1082
if object.timer < 0
1083
object.timer = 64
1084
object[-2].state = DERHAND_FIRE
1085
DERHand[-2].timer = 16
1086
DERHand[-2].originPos.y = object[-2].ypos
1087
object.subState = DER_SUB_ARMSHOOT_RARMSHOT
1088
end if
1089
break
1090
1091
case DER_SUB_ARMSHOOT_RARMSHOT
1092
object.timer--
1093
if object.timer < 0
1094
object.subState = DER_SUB_ARMSHOOT_GETUP
1095
end if
1096
break
1097
1098
case DER_SUB_ARMSHOOT_GETUP
1099
temp6 = DeathEggRobot_anim_getUp
1100
CallFunction(DeathEggRobot_AnimateBody)
1101
if checkResult == true
1102
object.state = DERMAIN_NEXTPHASE
1103
end if
1104
break
1105
1106
end switch
1107
break
1108
1109
case DERMAIN_EXPLODING
1110
object.timer++
1111
if object.timer == 120
1112
object.timer = 0
1113
object.exploding = false
1114
object.state++
1115
options.touchControls = false
1116
object[SLOT_PLAYER1].controlMode = CONTROLMODE_NONE
1117
object[SLOT_PLAYER1].jumpPress = false
1118
object[SLOT_PLAYER1].jumpHold = false
1119
object[SLOT_PLAYER1].up = false
1120
object[SLOT_PLAYER1].down = false
1121
object[SLOT_PLAYER1].left = false
1122
object[SLOT_PLAYER1].right = true
1123
stage.deathBoundary = 0x7FFF0000
1124
temp0 = tileLayer[0].xsize
1125
temp0 <<= 7
1126
stage.newXBoundary2 = temp0
1127
end if
1128
1129
object.ypos += object.yvel
1130
object.yvel += 0x3800
1131
ObjectTileCollision(CSIDE_FLOOR, 0, 36, PATH_A)
1132
if checkResult == true
1133
object.yvel >>= 2
1134
FlipSign(object.yvel)
1135
if object.yvel > -0x10000
1136
object.yvel = 0
1137
end if
1138
end if
1139
break
1140
1141
case DERMAIN_SCREENSHAKE
1142
object.timer++
1143
if object.timer == 30
1144
object.screenShake = 0xFFFF
1145
end if
1146
1147
temp0 = object.screenShake
1148
temp0 %= 40
1149
if temp0 == 8
1150
PlaySfx(SfxName[Rumble], false)
1151
end if
1152
1153
object[SLOT_PLAYER1].right = true
1154
if object[SLOT_PLAYER1].xpos > object[+7].xpos
1155
object.timer = -15
1156
object.state = DERMAIN_CORRDIOREXPLODE
1157
if object.screenShake == 0
1158
object.screenShake = 0xFFFF
1159
end if
1160
end if
1161
1162
temp0 = object.checkpoint
1163
arrayPos0 = object[+8].entityPos
1164
arrayPos0 += object.checkpoint
1165
temp1 = object[arrayPos0].xpos
1166
if object[SLOT_PLAYER1].xpos > temp1
1167
object.checkpoint++
1168
temp0++
1169
arrayPos0++
1170
end if
1171
1172
while temp0 < 7
1173
oneWayDoor[arrayPos0].isOpen = true
1174
arrayPos0++
1175
temp0++
1176
end if
1177
break
1178
1179
case DERMAIN_CORRDIOREXPLODE
1180
temp0 = object.screenShake
1181
temp0 %= 40
1182
if temp0 == 8
1183
PlaySfx(SfxName[Rumble], false)
1184
end if
1185
Rand(temp0, 96)
1186
temp0 -= 48
1187
temp0 <<= 16
1188
temp0 += object[SLOT_PLAYER1].xpos
1189
temp0 -= 0x400000
1190
Rand(temp1, 96)
1191
temp1 -= 48
1192
temp1 <<= 16
1193
temp1 += object[SLOT_PLAYER1].ypos
1194
CreateTempObject(TypeName[Explosion], 0, temp0, temp1)
1195
object[tempObjectPos].drawOrder = 5
1196
temp0 = oscillation
1197
temp0 &= 3
1198
if temp0 == 0
1199
PlaySfx(SfxName[Explosion], false)
1200
end if
1201
object.timer++
1202
1203
// Death Egg Robots with Property Values of 0 should trigger the ending cutscene after defeat
1204
if object.propertyValue == 0
1205
switch object.timer
1206
case 120
1207
case 180
1208
case 240
1209
PlaySfx(SfxName[Large Explosion], false)
1210
break
1211
1212
case 270
1213
#platform: USE_ORIGINS
1214
CallNativeFunction2(NotifyCallback, NOTIFY_BOSS_END, true)
1215
#endplatform
1216
object.state = DERMAIN_FADEOUT
1217
break
1218
1219
end switch
1220
else
1221
if object.timer > 140
1222
PlaySfx(SfxName[Large Explosion], false)
1223
ResetObjectEntity(object.entityPos, TypeName[Blank Object], 0, 0, 0)
1224
end if
1225
end if
1226
1227
object[SLOT_PLAYER1].right = true
1228
1229
temp0 = object.checkpoint
1230
arrayPos0 = object[+8].entityPos
1231
arrayPos0 += object.checkpoint
1232
temp1 = object[arrayPos0].xpos
1233
if object[SLOT_PLAYER1].xpos > temp1
1234
object.checkpoint++
1235
temp0++
1236
arrayPos0++
1237
end if
1238
1239
while temp0 < 7
1240
oneWayDoor[arrayPos0].isOpen = true
1241
arrayPos0++
1242
temp0++
1243
end if
1244
1245
// [Fallthrough]
1246
case DERMAIN_FADEOUT
1247
if object.timer >= 120
1248
music.volume--
1249
object.fadeValue += 2
1250
1251
// The fade value is updated regardless of if the Death Egg Robot should trigger the cutscene or not, it's just that the actual fade isn't applied if it doesn't need to be
1252
if object.propertyValue == 0
1253
SetScreenFade(255, 255, 255, object.fadeValue)
1254
end if
1255
1256
if object.fadeValue >= 0x300
1257
#platform: USE_ORIGINS
1258
if game.playMode != BOOT_PLAYMODE_BOSSRUSH
1259
temp0 = StageStatsUsabilityParam5
1260
temp0 &= 1
1261
temp1 = StageStatsUsabilityParam5
1262
temp1 &= 2
1263
temp2 = StageStatsUsabilityParam5
1264
temp2 &= 4
1265
CallNativeFunction4(NotifyCallback, NOTIFY_STATS_CHARA_ACTION, temp0, temp1, temp2)
1266
stage.timeEnabled = false
1267
CallNativeFunction2(NotifyCallback, NOTIFY_ACT_FINISH, 0)
1268
StageStatsUsabilityParam1 = 0
1269
StageStatsUsabilityParam2 = 0
1270
StageStatsUsabilityParam3 = 0
1271
StageStatsUsabilityParam4 = 0
1272
StageStatsUsabilityParam5 = 0
1273
StatsUsabilityParam1 = 0
1274
StatsUsabilityParam2 = 0
1275
StatsUsabilityParam3 = 0
1276
StatsUsabilityParam4 = 0
1277
StatsUsabilityParam5 = 0
1278
#endplatform
1279
1280
if stage.debugMode == false
1281
if options.stageSelectFlag == false
1282
CallNativeFunction2(SetLeaderboard, 22, player.score)
1283
end if
1284
end if
1285
1286
if options.gameMode == MODE_SAVEGAME
1287
// Mark the current save as a completed one
1288
arrayPos1 = options.saveSlot
1289
arrayPos1 <<= 3
1290
arrayPos1 += 4
1291
saveRAM[arrayPos1] = 22
1292
WriteSaveRAM()
1293
end if
1294
1295
#platform: USE_ORIGINS
1296
// This is already done earlier in DERMAIN_CORRDIOREXPLODE... but may as well do it again for good measure?
1297
CallNativeFunction2(NotifyCallback, NOTIFY_BOSS_END, true)
1298
1299
if game.oneStageFlag == false
1300
#endplatform
1301
// Start the Ending proper
1302
stage.activeList = PRESENTATION_STAGE
1303
stage.listPos = 1
1304
LoadStage()
1305
#platform: USE_ORIGINS
1306
else
1307
game.callbackResult = -1
1308
CallNativeFunction4(NotifyCallback, NOTIFY_STAGE_RETRY, 1, stage.listPos, 0)
1309
object.state = DERMAIN_STATIC
1310
end if
1311
end if
1312
#endplatform
1313
end if
1314
end if
1315
break
1316
1317
end switch
1318
1319
if object.state > DERMAIN_RAISE
1320
if object.health != 0
1321
if object.invincibilityTimer > 0
1322
object.invincibilityTimer--
1323
GetBit(temp0, object.invincibilityTimer, 0)
1324
if temp0 == true
1325
SetPaletteEntry(0, 192, 0xE0E0E0)
1326
else
1327
SetPaletteEntry(0, 192, 0x000000)
1328
end if
1329
end if
1330
1331
foreach (GROUP_PLAYERS, currentPlayer, ACTIVE_ENTITIES)
1332
if object.invincibilityTimer == 0
1333
BoxCollisionTest(C_TOUCH, object.entityPos, -32, -60, 32, 32, currentPlayer, player[currentPlayer].hitboxLeft, player[currentPlayer].hitboxTop, player[currentPlayer].hitboxRight, player[currentPlayer].hitboxBottom)
1334
1335
if checkResult == true
1336
CallFunction(Player_CheckHit)
1337
1338
if checkResult == true
1339
object.health--
1340
1341
if object.health == 0
1342
#platform: USE_ORIGINS
1343
CallNativeFunction2(NotifyCallback, NOTIFY_KILL_BOSS, 0)
1344
#endplatform
1345
1346
player.score += 1000
1347
object.exploding = true
1348
object.state = DERMAIN_EXPLODING
1349
object.timer = 0
1350
1351
// Make all the body parts fall off
1352
1353
// Shoulder
1354
object[+5].state = BODYPART_DESTROYED
1355
object[+5].xvel = 0x20000
1356
object[+5].yvel = -0x40000
1357
1358
// Front foot
1359
object[+4].state = BODYPART_DESTROYED
1360
object[+4].xvel = -0x10000
1361
object[+4].yvel = -0x10000
1362
1363
// Front hand
1364
object[+3].state = BODYPART_DESTROYED
1365
object[+3].xvel = 0x30000
1366
object[+3].yvel = -0x30000
1367
1368
// Front arm
1369
object[+2].state = BODYPART_DESTROYED
1370
object[+2].xvel = -0x10000
1371
object[+2].yvel = -0x40000
1372
1373
// Front leg
1374
object[+1].state = BODYPART_DESTROYED
1375
object[+1].xvel = 0x18000
1376
object[+1].yvel = -0x20000
1377
1378
// Back foot
1379
object[-1].state = BODYPART_DESTROYED
1380
object[-1].xvel = -0x20000
1381
object[-1].yvel = -0x30000
1382
1383
// Back hand
1384
object[-2].state = BODYPART_DESTROYED
1385
object[-2].xvel = 0
1386
object[-2].yvel = -0x40000
1387
1388
// Back leg
1389
object[-3].state = BODYPART_DESTROYED
1390
object[-3].xvel = 0x10000
1391
object[-3].yvel = -0x30000
1392
1393
object.flame.state = 3
1394
else
1395
object.invincibilityTimer = 60
1396
PlaySfx(SfxName[Boss Hit], false)
1397
end if
1398
end if
1399
else
1400
if object.direction == FLIP_NONE
1401
BoxCollisionTest(C_TOUCH, object.entityPos, 48, 16, 64, 32, currentPlayer, C_BOX, C_BOX, C_BOX, C_BOX)
1402
else
1403
BoxCollisionTest(C_TOUCH, object.entityPos, -64, 16, -48, 32, currentPlayer, C_BOX, C_BOX, C_BOX, C_BOX)
1404
end if
1405
1406
if checkResult == true
1407
CallFunction(Player_FireHit)
1408
end if
1409
end if
1410
end if
1411
next
1412
end if
1413
end if
1414
1415
if object.state <= DERMAIN_EXPLODING
1416
foreach (GROUP_PLAYERS, currentPlayer, ACTIVE_ENTITIES)
1417
temp0 = player[currentPlayer].collisionRight
1418
temp0 <<= 16
1419
temp0 += player[currentPlayer].xpos
1420
temp1 = stage.curXBoundary2
1421
temp1 <<= 16
1422
if temp0 > temp1
1423
player[currentPlayer].xvel = 0
1424
player[currentPlayer].speed = 0
1425
player[currentPlayer].xpos = temp1
1426
temp0 = player[currentPlayer].collisionRight
1427
temp0 <<= 16
1428
player[currentPlayer].xpos -= temp0
1429
end if
1430
next
1431
end if
1432
1433
if object.exploding == true
1434
temp0 = oscillation
1435
temp0 &= 7
1436
if temp0 == 0
1437
Rand(temp0, 48)
1438
temp0 -= 24
1439
temp0 <<= 16
1440
temp0 += object.xpos
1441
Rand(temp1, 48)
1442
temp1 -= 24
1443
temp1 <<= 16
1444
temp1 += object.ypos
1445
CreateTempObject(TypeName[Explosion], 0, temp0, temp1)
1446
object[tempObjectPos].drawOrder = 5
1447
PlaySfx(SfxName[Explosion], false)
1448
end if
1449
end if
1450
1451
if object.screenShake > 0
1452
object.screenShake--
1453
temp0 = object.screenShake
1454
temp0 &= 7
1455
if temp0 == 0
1456
screen.shakeX = 1
1457
end if
1458
temp0 = object.screenShake
1459
temp0 &= 3
1460
if temp0 == 0
1461
screen.shakeY = 2
1462
end if
1463
end if
1464
1465
switch object.flame.state
1466
case 0
1467
object.flame.frame -= 4
1468
object.flame.frame ^= 1
1469
object.flame.frame += 4
1470
break
1471
1472
case 1
1473
object.flame.timer += 2
1474
if object.flame.timer >= object.flame.animSpeed
1475
object.flame.timer = 0
1476
object.flame.frame -= 5
1477
object.flame.frame ^= 1
1478
object.flame.frame += 5
1479
if object.flame.animSpeed > 4
1480
object.flame.animSpeed--
1481
end if
1482
end if
1483
break
1484
1485
case 2
1486
object.flame.timer += 2
1487
if object.flame.timer >= object.flame.animSpeed
1488
object.flame.timer = 0
1489
object.flame.frame -= 5
1490
object.flame.frame ^= 1
1491
object.flame.frame += 5
1492
if object.flame.animSpeed < 16
1493
object.flame.animSpeed++
1494
if object.flame.animSpeed == 16
1495
object.flame.frame = 5
1496
object.flame.state = 0
1497
end if
1498
end if
1499
end if
1500
break
1501
1502
case 3
1503
object.flame.frame = 4
1504
break
1505
1506
end switch
1507
end event
1508
1509
1510
event ObjectDraw
1511
temp0 = object.xpos
1512
if object.direction == FLIP_NONE
1513
temp0 += object.headOffset.x
1514
else
1515
temp0 -= object.headOffset.x
1516
end if
1517
temp1 = object.ypos
1518
temp1 += object.headOffset.y
1519
DrawSpriteFX(2, FX_ROTATE, temp0, temp1)
1520
1521
DrawSpriteFX(3, FX_FLIP, object.xpos, object.ypos)
1522
DrawSpriteFX(object.flame.frame, FX_FLIP, object.xpos, object.ypos)
1523
end event
1524
1525
1526
event ObjectStartup
1527
CheckCurrentStageFolder("Zone12")
1528
if checkResult == true
1529
LoadSpriteSheet("DEZ/Objects.gif")
1530
1531
// These first two are unused pre-rotated Head sprites
1532
SpriteFrame(12, -16, 23, 32, 487, 150)
1533
SpriteFrame(-20, -13, 54, 29, 430, 125)
1534
1535
// In their place, a engine-rotated single Head sprite is used instead
1536
SpriteFrame(-32, -24, 71, 24, 414, 158)
1537
1538
// Main Body
1539
SpriteFrame(-44, -36, 112, 72, 399, 183)
1540
1541
// Flame Animation Sprites
1542
SpriteFrame(0, 0, 1, 1, 495, 106)
1543
SpriteFrame(48, 12, 16, 16, 495, 108)
1544
SpriteFrame(48, 12, 16, 24, 495, 83)
1545
else
1546
LoadSpriteSheet("MBZ/Objects.gif")
1547
1548
SpriteFrame(12, -16, 23, 32, 999, 150)
1549
SpriteFrame(-20, -13, 54, 29, 942, 125)
1550
1551
SpriteFrame(-32, -24, 71, 24, 926, 158)
1552
1553
SpriteFrame(-44, -36, 112, 72, 911, 183)
1554
1555
SpriteFrame(0, 0, 1, 1, 1007, 106)
1556
SpriteFrame(48, 12, 16, 16, 1007, 108)
1557
SpriteFrame(48, 12, 16, 24, 1007, 83)
1558
end if
1559
1560
foreach (TypeName[Death Egg Robot], arrayPos0, ALL_ENTITIES)
1561
object[arrayPos0].rotation = 0x80
1562
object[arrayPos0].headOffset.x = 0xB0000
1563
object[arrayPos0].headOffset.y = -0x40000
1564
next
1565
1566
// I sure hope you like tables, the compiler doesn't support putting tables in initial table declarations, so instead we have to manually place every value ourselves
1567
1568
SetTableValue(DeathEggRobot_anim_sub_bend, 0, DeathEggRobot_anim_bendDown)
1569
1570
SetTableValue(DeathEggRobot_anim_sub_bend, 0, DeathEggRobot_anim_getUp)
1571
1572
SetTableValue(DeathEggRobot_anim_sub_bend, 0, DeathEggRobot_anim_land)
1573
1574
SetTableValue(DeathEggRobot_anim_sub_jump, 0, DeathEggRobot_anim_jump)
1575
1576
SetTableValue(DeathEggRobot_anim_sub_walk, 0, DeathEggRobot_anim_stepAhead)
1577
1578
SetTableValue(DeathEggRobot_anim_sub_walk, 0, DeathEggRobot_anim_stepBack)
1579
1580
SetTableValue(DeathEggRobot_bend_frame_1, 0, DeathEggRobot_anim_sub_bend)
1581
SetTableValue(DeathEggRobot_bend_frame_2, 1, DeathEggRobot_anim_sub_bend)
1582
SetTableValue(DeathEggRobot_bend_frame_3, 2, DeathEggRobot_anim_sub_bend)
1583
SetTableValue(DeathEggRobot_bend_frame_4, 3, DeathEggRobot_anim_sub_bend)
1584
SetTableValue(DeathEggRobot_bend_frame_5, 4, DeathEggRobot_anim_sub_bend)
1585
SetTableValue(DeathEggRobot_bend_frame_6, 5, DeathEggRobot_anim_sub_bend)
1586
SetTableValue(DeathEggRobot_bend_frame_7, 6, DeathEggRobot_anim_sub_bend)
1587
SetTableValue(DeathEggRobot_bend_frame_8, 7, DeathEggRobot_anim_sub_bend)
1588
SetTableValue(DeathEggRobot_bend_frame_9, 8, DeathEggRobot_anim_sub_bend)
1589
1590
SetTableValue(DeathEggRobot_jump_frame_1, 0, DeathEggRobot_anim_sub_jump)
1591
SetTableValue(DeathEggRobot_jump_frame_2, 1, DeathEggRobot_anim_sub_jump)
1592
SetTableValue(DeathEggRobot_jump_frame_3, 2, DeathEggRobot_anim_sub_jump)
1593
1594
SetTableValue(DeathEggRobot_walk_frame_1, 0, DeathEggRobot_anim_sub_walk)
1595
SetTableValue(DeathEggRobot_walk_frame_2, 1, DeathEggRobot_anim_sub_walk)
1596
SetTableValue(DeathEggRobot_walk_frame_3, 2, DeathEggRobot_anim_sub_walk)
1597
SetTableValue(DeathEggRobot_walk_frame_4, 3, DeathEggRobot_anim_sub_walk)
1598
SetTableValue(DeathEggRobot_walk_frame_5, 4, DeathEggRobot_anim_sub_walk)
1599
SetTableValue(DeathEggRobot_walk_frame_6, 5, DeathEggRobot_anim_sub_walk)
1600
SetTableValue(DeathEggRobot_walk_frame_7, 6, DeathEggRobot_anim_sub_walk)
1601
SetTableValue(DeathEggRobot_walk_frame_8, 7, DeathEggRobot_anim_sub_walk)
1602
SetTableValue(DeathEggRobot_walk_frame_9, 8, DeathEggRobot_anim_sub_walk)
1603
SetTableValue(DeathEggRobot_walk_frame_10, 9, DeathEggRobot_anim_sub_walk)
1604
SetTableValue(DeathEggRobot_walk_frame_11, 10, DeathEggRobot_anim_sub_walk)
1605
SetTableValue(DeathEggRobot_walk_frame_12, 11, DeathEggRobot_anim_sub_walk)
1606
end event
1607
1608
1609
// ========================
1610
// Editor Events
1611
// ========================
1612
1613
event RSDKEdit
1614
if editor.returnVariable == true
1615
switch editor.variableID
1616
case EDIT_VAR_PROPVAL // property value
1617
checkResult = object.propertyValue
1618
break
1619
1620
case 0 // skipCutscene
1621
checkResult = object.propertyValue
1622
break
1623
1624
end switch
1625
else
1626
switch editor.variableID
1627
case EDIT_VAR_PROPVAL // property value
1628
object.propertyValue = editor.variableValue
1629
break
1630
1631
case 0 // skipCutscene
1632
object.propertyValue = editor.variableValue
1633
break
1634
1635
end switch
1636
end if
1637
end event
1638
1639
1640
event RSDKDraw
1641
DrawSprite(0)
1642
end event
1643
1644
1645
event RSDKLoad
1646
CheckCurrentStageFolder("Zone12")
1647
if checkResult == true
1648
LoadSpriteSheet("DEZ/Objects.gif")
1649
SpriteFrame(-44, -36, 112, 72, 399, 183)
1650
else
1651
LoadSpriteSheet("MBZ/Objects.gif")
1652
SpriteFrame(-44, -36, 112, 72, 911, 183)
1653
end if
1654
1655
AddEditorVariable("skipCutscene")
1656
SetActiveVariable("skipCutscene")
1657
AddEnumVariable("false", false) // Used in DEZ
1658
AddEnumVariable("true", true) // Used in MBZ & Boss Rush
1659
end event
1660
1661