Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rubberduckycooly
GitHub Repository: rubberduckycooly/Sonic-1-Sonic-2-2013-Script-Decompilation
Path: blob/master/Sonic 2/Scripts/OOZ/CheckeredBall.txt
1480 views
1
// ----------------------------------
2
// RSDK Project: Sonic 2
3
// Script Description: Checkered Ball 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.unused // reset a couple of times, never used for anything noteworthy
13
private alias object.value1 : object.roundedPos.x
14
private alias object.value2 : object.roundedPos.y
15
private alias object.value3 : object.ballAngle
16
private alias object.value4 : object.groundAngle
17
private alias object.value5 : object.angleVel
18
private alias object.value6 : object.playerControlled
19
private alias object.value7 : object.startPos.x
20
private alias object.value8 : object.startPos.y
21
// object.value9 is unused
22
private alias object.value10 : object.activePlayers
23
private alias object.value11 : object.badnikBonus
24
private alias object.value12 : object.collisionOffset.x
25
private alias object.value13 : object.collisionOffset.y
26
// object.value14 is unused
27
private alias object.value15 : object.parent // Should be a ballcannon entity
28
29
// States
30
private alias 0 : CHECKEREDBALL_NORMAL
31
private alias 1 : CHECKEREDBALL_LAUNCHED
32
33
// Player Aliases
34
private alias object.xpos : player.xpos
35
private alias object.ypos : player.ypos
36
private alias object.xvel : player.xvel
37
private alias object.speed : player.speed
38
private alias object.gravity : player.gravity
39
private alias object.pushing : player.pushing
40
private alias object.controlLock : player.controlLock
41
private alias object.collisionLeft : player.collisionLeft
42
private alias object.collisionRight : player.collisionRight
43
private alias object.left : player.left
44
private alias object.right : player.right
45
46
private alias object.value20 : player.topSpeed
47
private alias object.value21 : player.acceleration
48
49
// Super States
50
private alias 1 : SUPERSTATE_SUPER
51
private alias 2 : SUPERSTATE_FADEOUT
52
53
// Monitor Aliases
54
private alias object.value0 : monitor.contentsPos.y
55
private alias object.value1 : monitor.timer
56
57
// Spring Aliases
58
private alias object.value0 : spring.timer
59
private alias object.value1 : spring.active
60
private alias object.value2 : spring.extraVelocity
61
62
// Plane Sw V Aliases
63
private alias object.value0 : planeSwV.extendTop
64
private alias object.value1 : planeSwV.extendBottom
65
private alias object.value2 : planeSwV.planeR
66
private alias object.value3 : planeSwV.planeL
67
private alias object.value4 : planeSwV.drawOrderR
68
private alias object.value5 : planeSwV.drawOrderL
69
private alias object.value6 : planeSwV.onGround
70
71
// Plane Sw H Aliases
72
private alias object.value0 : planeSwH.extendLeft
73
private alias object.value1 : planeSwH.extendRight
74
private alias object.value2 : planeSwH.planeR
75
private alias object.value3 : planeSwH.planeL
76
private alias object.value4 : planeSwH.drawOrderR
77
private alias object.value5 : planeSwH.drawOrderL
78
private alias object.value6 : planeSwH.onGround
79
80
// AnimalPrison Aliases
81
private alias object.value2 : animalPrison.buttonPos
82
private alias object.value3 : animalPrison.lockPos.x
83
private alias object.value4 : animalPrison.lockPos.y
84
85
// AnimalPrison States
86
private alias 0 : ANIMALPRISON_AWAITOPEN
87
private alias 1 : ANIMALPRISON_OPENING
88
89
// CFloor Aliases
90
private alias 0 : CFLOOR_ACTIVE
91
private alias 1 : CFLOOR_COLLAPSE
92
private alias 3 : CFLOOR_NONE
93
94
// SwingPlatform
95
private alias object.value1 : swingPlatform.drawPos.x
96
private alias object.value2 : swingPlatform.drawPos.y
97
private alias object.value3 : swingPlatform.collisionOffset.x
98
private alias object.value4 : swingPlatform.collisionOffset.y
99
100
// Tile Flag Aliases
101
private alias 0 : TILE_NORMAL
102
private alias 1 : TILE_OILPOOL
103
private alias 3 : TILE_OILSTRIP
104
private alias 5 : TILE_OILSLIDE
105
106
// Tile Info ID Aliases
107
private alias 8 : TILEINFO_ANGLEB
108
109
// VPushSpring Aliases
110
private alias object.value1 : vPushSpring.pushOffset
111
private alias object.value2 : vPushSpring.collisionOffset.y
112
private alias object.value3 : vPushSpring.beingPushed
113
114
// VPushSpring States
115
private alias 2 : VPUSHSPRING_RELEASE
116
117
// HPushSpring Aliases
118
private alias object.value1 : hPushSpring.pushOffset
119
private alias object.value2 : hPushSpring.beingPushed
120
121
// HPushSpring States
122
private alias 1 : HPUSHSPRING_PUSHING
123
124
// Elevator Aliases
125
private alias object.value4 : elevator.collisionOffset.y
126
127
// BallCannon Aliases
128
private alias object.value0 : ballCannon.timer
129
private alias object.value1 : ballCannon.tablePos
130
private alias object.value5 : ballCannon.activePlayers
131
private alias object.value6 : ballCannon.lastCannon
132
133
// BallCannon States
134
private alias 1 : BALLCANNON_ENTERED
135
private alias 4 : BALLCANNON_EXITED
136
137
// PushButton Aliases
138
private alias object.value0 : pushButton.pressed
139
private alias object.value1 : pushButton.stood
140
141
// GasBreakBlock States
142
private alias 0 : GASBREAKBLOCK_BLOCKS
143
private alias 1 : GASBREAKBLOCK_LAUNCHER
144
private alias 2 : GASBREAKBLOCK_DEBRIS
145
146
// GasPlatform Aliases
147
private alias object.value1 : gasPlatform.centerPos.y
148
private alias object.value2 : gasPlatform.collisionOffset.y
149
150
// OOZEggman Aliases
151
private alias object.value0 : oozEggman.timer
152
private alias object.value3 : oozEggman.health
153
private alias object.value4 : oozEggman.invincibilityTimer
154
private alias object.value5 : oozEggman.exploding
155
private alias object.value9 : oozEggman.spawnHarpoon
156
157
// OOZEggman States
158
private alias 7 : OOZEGGMAN_EXPLODE
159
160
// OOZEggman Animations
161
private alias 3 : OOZEGGANI_HIT
162
private alias 4 : OOZEGGANI_DEFEATED
163
164
165
// ========================
166
// Function Declarations
167
// ========================
168
169
reserve function CheckeredBall_DebugDraw
170
reserve function CheckeredBall_DebugSpawn
171
reserve function CheckeredBall_HandlePlayerMove
172
reserve function CheckeredBall_PlayerInteraction
173
reserve function CheckeredBall_BadnikBreak
174
reserve function CheckeredBall_ReflectProjectile
175
reserve function CheckeredBall_SpringBounce
176
reserve function CheckeredBall_CLedgeCollapse
177
reserve function CheckeredBall_HandlePhysics
178
179
180
// ========================
181
// Tables
182
// ========================
183
184
private table CheckeredBall_heightArray
185
0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 3, 3, 4, 4, 5, 6, 7, 8, 9, 10, 12, 14, 16, 20
186
end table
187
188
// Seems to be unused, and as such, its purpose is unknown...
189
// This same table exists in S1's and Mania's unused CheckeredBall objects as well, for whatever reason
190
private table CheckeredBall_unusedTable
191
253, 251, 248, 245, 243, 240, 237, 235, 232, 229, 226, 224, 221, 219, 216, 213, 210, 208, 205, 203, 200, 197, 195, 192
192
end table
193
194
195
// ========================
196
// Function Definitions
197
// ========================
198
199
private function CheckeredBall_DebugDraw
200
DrawSprite(1)
201
end function
202
203
204
private function CheckeredBall_DebugSpawn
205
CreateTempObject(TypeName[Checkered Ball], 0, object.xpos, object.ypos)
206
object[tempObjectPos].gravity = GRAVITY_AIR
207
object[tempObjectPos].startPos.x = object.xpos
208
object[tempObjectPos].startPos.y = object.ypos
209
object[tempObjectPos].roundedPos.x = object.xpos
210
object[tempObjectPos].roundedPos.y = object.ypos
211
end function
212
213
214
private function CheckeredBall_HandlePlayerMove
215
object.activePlayers = 0
216
217
temp2 = 0
218
foreach (GROUP_PLAYERS, currentPlayer, ACTIVE_ENTITIES)
219
CheckEqual(options.attractMode, true)
220
temp1 = checkResult
221
CheckEqual(currentPlayer, 1)
222
temp1 &= checkResult
223
temp0 = player[currentPlayer].acceleration
224
temp0 >>= 1
225
226
if player[currentPlayer].gravity == 0
227
if player[currentPlayer].xvel < 0
228
BoxCollisionTest(C_TOUCH, object.entityPos, 0, -14, 15, 14, currentPlayer, C_BOX, C_BOX, C_BOX, C_BOX)
229
if checkResult == true
230
if player[currentPlayer].left == true
231
if temp1 == false
232
SetBit(object.activePlayers, temp2, true)
233
temp1 = player[currentPlayer].topSpeed
234
FlipSign(temp1)
235
if object.speed > temp1
236
object.speed -= temp0
237
end if
238
object.playerControlled = true
239
end if
240
241
player[currentPlayer].xpos = player[currentPlayer].collisionRight
242
player[currentPlayer].xpos += 14
243
player[currentPlayer].xpos <<= 16
244
player[currentPlayer].xpos += object.roundedPos.x
245
246
if object.xvel < 0
247
if player[currentPlayer].speed < object.speed
248
player[currentPlayer].xvel = object.xvel
249
player[currentPlayer].speed = object.speed
250
end if
251
end if
252
253
player[currentPlayer].pushing = 2
254
end if
255
end if
256
else
257
if player[currentPlayer].xvel > 0
258
BoxCollisionTest(C_TOUCH, object.entityPos, -15, -14, 0, 14, currentPlayer, C_BOX, C_BOX, C_BOX, C_BOX)
259
if checkResult == true
260
if player[currentPlayer].right == true
261
if temp1 == false
262
SetBit(object.activePlayers, temp2, true)
263
if object.speed < player[currentPlayer].topSpeed
264
object.speed += temp0
265
end if
266
object.playerControlled = true
267
end if
268
269
player[currentPlayer].xpos = player[currentPlayer].collisionLeft
270
player[currentPlayer].xpos += -14
271
player[currentPlayer].xpos <<= 16
272
player[currentPlayer].xpos += object.roundedPos.x
273
274
if object.xvel > 0
275
if player[currentPlayer].speed > object.speed
276
player[currentPlayer].xvel = object.xvel
277
player[currentPlayer].speed = object.speed
278
end if
279
end if
280
281
player[currentPlayer].pushing = 2
282
end if
283
end if
284
end if
285
end if
286
end if
287
temp2++
288
next
289
end function
290
291
292
private function CheckeredBall_PlayerInteraction
293
temp6 = object.xpos
294
temp6 &= 0xFFFF0000
295
temp6 -= object.roundedPos.x
296
297
temp7 = object.ypos
298
temp7 &= 0xFFFF0000
299
temp7 -= object.roundedPos.y
300
301
temp4 = object.xpos
302
temp5 = object.ypos
303
object.xpos = object.roundedPos.x
304
object.ypos = object.roundedPos.y
305
306
temp2 = 0
307
foreach (GROUP_PLAYERS, currentPlayer, ACTIVE_ENTITIES)
308
BoxCollisionTest(C_TOUCH, object.entityPos, -2, -2, 2, 2, currentPlayer, C_BOX, C_BOX, C_BOX, C_BOX)
309
if checkResult == false
310
GetBit(temp0, object.activePlayers, temp2)
311
if temp0 == true
312
if player[currentPlayer].xpos < object.xpos
313
temp1 = player[currentPlayer].collisionRight
314
FlipSign(temp1)
315
temp1 -= 14
316
else
317
temp1 = player[currentPlayer].collisionLeft
318
FlipSign(temp1)
319
temp1 += 14
320
end if
321
322
temp1 <<= 16
323
player[currentPlayer].xpos = temp1
324
player[currentPlayer].xpos += temp4
325
else
326
BoxCollisionTest(C_SOLID, object.entityPos, -14, -14, 14, 14, currentPlayer, C_BOX, C_BOX, C_BOX, C_BOX)
327
if checkResult == COL_TOP
328
player[currentPlayer].xpos += temp6
329
temp0 = temp6
330
temp0 >>= 1
331
player[currentPlayer].xpos += temp0
332
player[currentPlayer].ypos += temp7
333
334
if player[currentPlayer].xvel != 0
335
temp0 = player[currentPlayer].acceleration
336
temp0 >>= 2
337
if player[currentPlayer].xvel > 0
338
FlipSign(temp0)
339
end if
340
else
341
temp0 = 0
342
end if
343
344
object.speed += temp0
345
if temp0 != 0
346
object.playerControlled = true
347
end if
348
349
object.xpos = temp4
350
object.ypos = temp5
351
BoxCollisionTest(C_SOLID, object.entityPos, -14, -14, 14, 14, currentPlayer, C_BOX, C_BOX, C_BOX, C_BOX)
352
object.xpos = object.roundedPos.x
353
object.ypos = object.roundedPos.y
354
if checkResult == COL_NONE
355
temp0 = temp6
356
temp1 = temp6
357
temp0 >>= 1
358
temp1 += temp0
359
player[currentPlayer].speed += temp0
360
player[currentPlayer].xvel = player[currentPlayer].speed
361
player[currentPlayer].gravity = GRAVITY_AIR
362
player[currentPlayer].controlLock = 15
363
end if
364
end if
365
366
if checkResult == COL_BOTTOM
367
if object.yvel >= 0
368
if player[currentPlayer].gravity == 0
369
CallFunction(Player_Kill)
370
end if
371
end if
372
end if
373
end if
374
375
temp2++
376
end if
377
next
378
379
object.xpos = temp4
380
object.ypos = temp5
381
end function
382
383
384
private function CheckeredBall_BadnikBreak
385
temp0 = object.xvel
386
temp0 |= object.yvel
387
if temp0 != 0
388
ResetObjectEntity(object[arrayPos0].entityPos, TypeName[Blank Object], 0, object[arrayPos0].xpos, object[arrayPos0].ypos)
389
Rand(checkResult, 32)
390
if checkResult >= 16
391
CreateTempObject(animalType1, 0, object[arrayPos0].xpos, object[arrayPos0].ypos)
392
else
393
CreateTempObject(animalType2, 0, object[arrayPos0].xpos, object[arrayPos0].ypos)
394
end if
395
object[tempObjectPos].priority = PRIORITY_ACTIVE_SMALL
396
397
CreateTempObject(TypeName[Smoke Puff], 0, object[arrayPos0].xpos, object[arrayPos0].ypos)
398
object[tempObjectPos].drawOrder = 4
399
400
CreateTempObject(TypeName[Object Score], object.badnikBonus, object[arrayPos0].xpos, object[arrayPos0].ypos)
401
object[tempObjectPos].drawOrder = 4
402
403
PlaySfx(SfxName[Destroy], false)
404
405
// No 2P trickery here!
406
switch object.badnikBonus
407
case 0
408
player.score += 100
409
break
410
411
case 1
412
player.score += 200
413
break
414
415
case 2
416
player.score += 500
417
break
418
419
case 3
420
case 4
421
case 5
422
case 6
423
case 7
424
case 8
425
case 9
426
case 10
427
case 11
428
case 12
429
case 13
430
case 14
431
player.score += 1000
432
break
433
434
case 15
435
player.score += 10000
436
break
437
438
end switch
439
440
if object.badnikBonus < 15
441
object.badnikBonus++
442
end if
443
end if
444
end function
445
446
447
private function CheckeredBall_ReflectProjectile
448
// Do some maths to find where the projectile should go now
449
temp0 = object.xpos
450
temp0 -= object[arrayPos0].xpos
451
temp1 = object.ypos
452
temp1 -= object[arrayPos0].ypos
453
454
ATan2(temp2, temp0, temp1)
455
Sin256(temp0, temp2)
456
Cos256(temp1, temp2)
457
458
object[arrayPos0].xvel = temp1
459
object[arrayPos0].xvel *= -0x800
460
object[arrayPos0].yvel = temp0
461
object[arrayPos0].yvel *= -0x800
462
end function
463
464
465
private function CheckeredBall_SpringBounce
466
switch object[arrayPos0].propertyValue
467
case 0
468
temp0 = spring[arrayPos0].active
469
if object.gravity == 1
470
temp0 = true
471
end if
472
473
if object.collisionMode > 0
474
if object.yvel < 0
475
temp0 = true
476
end if
477
end if
478
479
if temp0 == false
480
BoxCollisionTest(C_SOLID, object[arrayPos0].entityPos, -14, -8, 14, 8, object.entityPos, -14, -14, 14, 14)
481
BoxCollisionTest(C_TOUCH, object[arrayPos0].entityPos, -14, -10, 14, -6, object.entityPos, -14, -14, 14, 14)
482
if checkResult == true
483
spring[arrayPos0].timer = 1
484
object.tileCollisions = true
485
object.gravity = GRAVITY_AIR
486
object.speed = object.xvel
487
object.yvel = temp7
488
FlipSign(object.yvel)
489
object.yvel += spring[arrayPos0].extraVelocity
490
PlaySfx(SfxName[Spring], false)
491
end if
492
else
493
if object.yvel >= 0
494
BoxCollisionTest(C_PLATFORM, object[arrayPos0].entityPos, -14, -8, 14, 8, object.entityPos, -14, -14, 14, 14)
495
BoxCollisionTest(C_TOUCH, object[arrayPos0].entityPos, -14, -10, 14, -6, object.entityPos, -14, -14, 14, 14)
496
if checkResult == true
497
spring[arrayPos0].timer = 1
498
object.tileCollisions = true
499
object.gravity = GRAVITY_AIR
500
object.speed = object.xvel
501
object.yvel = temp7
502
FlipSign(object.yvel)
503
object.yvel += spring[arrayPos0].extraVelocity
504
PlaySfx(SfxName[Spring], false)
505
end if
506
end if
507
end if
508
break
509
510
case 1
511
BoxCollisionTest(C_SOLID, object[arrayPos0].entityPos, -8, -14, 8, 14, object.entityPos, -14, -14, 14, 14)
512
if object.gravity == 0
513
BoxCollisionTest(C_TOUCH, object[arrayPos0].entityPos, 6, -14, 10, 14, object.entityPos, -14, -14, 14, 14)
514
if checkResult == true
515
spring[arrayPos0].timer = 1
516
object.tileCollisions = true
517
object.speed = temp7
518
object.collisionMode = CMODE_FLOOR
519
object.direction = FLIP_NONE
520
PlaySfx(SfxName[Spring], false)
521
end if
522
end if
523
break
524
525
case 2
526
BoxCollisionTest(C_SOLID, object[arrayPos0].entityPos, -8, -14, 8, 14, object.entityPos, -14, -14, 14, 14)
527
if object.gravity == 0
528
BoxCollisionTest(C_TOUCH, object[arrayPos0].entityPos, -10, -14, -6, 14, object.entityPos, -14, -14, 14, 14)
529
if checkResult == true
530
spring[arrayPos0].timer = 1
531
object.tileCollisions = true
532
object.speed = temp7
533
FlipSign(object.speed)
534
object.collisionMode = CMODE_FLOOR
535
object.direction = FLIP_X
536
PlaySfx(SfxName[Spring], false)
537
end if
538
end if
539
break
540
541
case 3
542
BoxCollisionTest(C_SOLID, object[arrayPos0].entityPos, -14, -8, 14, 8, object.entityPos, -14, -14, 14, 14)
543
BoxCollisionTest(C_TOUCH, object[arrayPos0].entityPos, -14, 6, 14, 10, object.entityPos, -14, -14, 14, 14)
544
if checkResult == true
545
spring[arrayPos0].timer = 1
546
if object.collisionMode == 2
547
FlipSign(object.speed)
548
FlipSign(object.xvel)
549
end if
550
object.tileCollisions = true
551
object.gravity = GRAVITY_AIR
552
object.speed = object.xvel
553
object.yvel = temp7
554
PlaySfx(SfxName[Spring], false)
555
end if
556
break
557
558
end switch
559
end function
560
561
562
private function CheckeredBall_CLedgeCollapse
563
if object[arrayPos0].state < CFLOOR_NONE
564
565
// what? why is this here??
566
// If I had to guess, I'd say it's just a debugging leftover or something, but it's certainly very strange
567
player.score++
568
569
if object[arrayPos0].propertyValue < 2
570
if object.yvel >= 0
571
BoxCollisionTest(C_PLATFORM, arrayPos0, -64, -24, 64, 0, object.entityPos, -10, -14, 10, 14)
572
else
573
checkResult = COL_NONE
574
end if
575
else
576
BoxCollisionTest(C_SOLID, arrayPos0, -64, -16, 64, 16, object.entityPos, -10, -14, 10, 14)
577
end if
578
579
if checkResult == COL_TOP
580
if object[arrayPos0].state == CFLOOR_ACTIVE
581
object[arrayPos0].state = CFLOOR_COLLAPSE
582
object[arrayPos0].priority = PRIORITY_ACTIVE
583
end if
584
end if
585
end if
586
end function
587
588
589
private function CheckeredBall_HandlePhysics
590
if object.gravity == 1
591
object.yvel += 0x3800
592
object.speed = object.xvel
593
else
594
Sin256(temp0, object.groundAngle)
595
temp0 *= 0x2000
596
temp0 >>= 8
597
object.speed += temp0
598
object.angleVel = object.speed
599
if temp0 == 0
600
if object.playerControlled == false
601
if object.speed > 0
602
object.speed -= 0x400
603
if object.speed < 0
604
object.speed = 0
605
end if
606
else
607
object.speed += 0x400
608
if object.speed > 0
609
object.speed = 0
610
end if
611
end if
612
end if
613
end if
614
615
Cos256(temp0, object.groundAngle)
616
temp0 *= object.speed
617
temp0 >>= 8
618
object.xvel = temp0
619
620
Sin256(temp0, object.groundAngle)
621
temp0 *= object.speed
622
temp0 >>= 8
623
object.yvel = temp0
624
end if
625
626
object.playerControlled = false
627
end function
628
629
630
// ========================
631
// Events
632
// ========================
633
634
event ObjectUpdate
635
if object.state == CHECKEREDBALL_NORMAL
636
object.priority = PRIORITY_ACTIVE
637
CallFunction(CheckeredBall_HandlePlayerMove)
638
object.ballAngle += object.angleVel
639
object.collisionLeft = -14
640
object.collisionTop = -14
641
object.collisionRight = 14
642
object.collisionBottom = 14
643
CallFunction(CheckeredBall_HandlePhysics)
644
ProcessObjectMovement()
645
object.groundAngle = object.angle
646
else
647
object.collisionLeft = -14
648
object.collisionTop = -14
649
object.collisionRight = 14
650
object.collisionBottom = 14
651
ProcessObjectMovement()
652
object.ballAngle += 0x40000
653
end if
654
655
// Cycle through all objects
656
foreach (0, arrayPos0, ACTIVE_ENTITIES)
657
// Jump to the object's type
658
// If not listed here, it has no interaction
659
switch object[arrayPos0].type
660
case TypeName[Octus]
661
BoxCollisionTest(C_TOUCH, object.entityPos, -14, -14, 14, 14, arrayPos0, -16, -12, 16, 12)
662
if checkResult == true
663
CallFunction(CheckeredBall_BadnikBreak)
664
end if
665
break
666
667
case TypeName[Aquis]
668
BoxCollisionTest(C_TOUCH, object.entityPos, -14, -14, 14, 14, arrayPos0, -16, -10, 16, 10)
669
if checkResult == true
670
CallFunction(CheckeredBall_BadnikBreak)
671
end if
672
break
673
674
case TypeName[Octus Shot]
675
BoxCollisionTest(C_TOUCH, object.entityPos, -14, -14, 14, 14, arrayPos0, -4, -4, 4, 4)
676
if checkResult == true
677
CallFunction(CheckeredBall_ReflectProjectile)
678
end if
679
break
680
681
case TypeName[Aquis Shot]
682
BoxCollisionTest(C_TOUCH, object.entityPos, -14, -14, 14, 14, arrayPos0, -4, -4, 4, 4)
683
if checkResult == true
684
CallFunction(CheckeredBall_ReflectProjectile)
685
end if
686
break
687
688
case TypeName[Monitor]
689
BoxCollisionTest(C_TOUCH, object.entityPos, -14, -14, 14, 14, arrayPos0, -16, -14, 16, 16)
690
if checkResult == true
691
object[arrayPos0].state = 0
692
CreateTempObject(TypeName[Smoke Puff], 0, object[arrayPos0].xpos, object[arrayPos0].ypos)
693
object[tempObjectPos].drawOrder = 4
694
object[arrayPos0].type = TypeName[Broken Monitor]
695
696
if object[arrayPos0].priority != PRIORITY_XBOUNDS_DESTROY
697
object[arrayPos0].priority = PRIORITY_ACTIVE
698
end if
699
700
object[arrayPos0].alpha = 0xFF
701
monitor[arrayPos0].contentsPos.y = object[arrayPos0].ypos
702
monitor[arrayPos0].timer = -0x30000
703
PlaySfx(SfxName[Destroy], false)
704
end if
705
break
706
707
case TypeName[Spikes]
708
switch object[arrayPos0].propertyValue
709
case 0
710
BoxCollisionTest(C_SOLID, arrayPos0, -16, -16, 16, 16, object.entityPos, -14, -14, 14, 14)
711
break
712
713
case 1
714
BoxCollisionTest(C_SOLID, arrayPos0, -16, -16, 15, 16, object.entityPos, -14, -14, 14, 14)
715
break
716
717
case 2
718
BoxCollisionTest(C_SOLID, arrayPos0, -15, -16, 16, 16, object.entityPos, -14, -14, 14, 14)
719
break
720
721
case 3
722
BoxCollisionTest(C_SOLID, arrayPos0, -16, -16, 16, 15, object.entityPos, -14, -14, 14, 14)
723
break
724
725
end switch
726
727
switch checkResult
728
case COL_TOP
729
object.gravity = GRAVITY_GROUND
730
break
731
732
case COL_LEFT
733
if object.speed > 0
734
object.speed = 0
735
end if
736
break
737
738
case COL_RIGHT
739
if object.speed < 0
740
object.speed = 0
741
end if
742
break
743
end switch
744
break
745
746
case TypeName[Yellow Spring]
747
temp7 = 0xA0000
748
CallFunction(CheckeredBall_SpringBounce)
749
break
750
751
case TypeName[Red Spring]
752
temp7 = 0x100000
753
CallFunction(CheckeredBall_SpringBounce)
754
break
755
756
case TypeName[V Push Spring]
757
temp0 = vPushSpring[arrayPos0].pushOffset
758
temp0 -= vPushSpring[arrayPos0].collisionOffset.y
759
temp0 >>= 16
760
temp0 -= 20
761
BoxCollisionTest(C_SOLID, arrayPos0, -16, temp0, 16, 20, object.entityPos, -10, -14, 10, 14)
762
if checkResult == COL_TOP
763
vPushSpring[arrayPos0].beingPushed |= true
764
object.ypos += vPushSpring[arrayPos0].collisionOffset.y
765
if object[arrayPos0].state == VPUSHSPRING_RELEASE
766
if vPushSpring[arrayPos0].pushOffset == 0x120000
767
object.gravity = GRAVITY_AIR
768
object.yvel = -0x60000
769
object.unused = 0
770
PlaySfx(SfxName[Spring], false)
771
end if
772
end if
773
end if
774
break
775
776
case TypeName[H Push Spring]
777
if object[arrayPos0].direction == FLIP_NONE
778
temp0 = -20
779
temp1 = hPushSpring[arrayPos0].pushOffset
780
temp1 >>= 16
781
FlipSign(temp1)
782
temp1 += 22
783
else
784
temp0 = hPushSpring[arrayPos0].pushOffset
785
temp0 >>= 16
786
temp0 -= 22
787
temp1 = 20
788
end if
789
790
temp2 = object.speed
791
BoxCollisionTest(C_SOLID, arrayPos0, temp0, -16, temp1, 16, object.entityPos, -10, -14, 10, 14)
792
object.speed = temp2
793
switch checkResult
794
case COL_LEFT
795
temp0 >>= 8
796
object.speed -= temp0
797
if object.speed > 0
798
hPushSpring[arrayPos0].beingPushed |= true
799
end if
800
801
if object[arrayPos0].state == HPUSHSPRING_PUSHING
802
if hPushSpring[arrayPos0].pushOffset > 0x10000
803
object.speed = -12
804
object.speed *= hPushSpring[arrayPos0].pushOffset
805
object.speed /= 18
806
object.collisionMode = CMODE_FLOOR
807
PlaySfx(SfxName[Spring], false)
808
end if
809
end if
810
break
811
812
case COL_RIGHT
813
temp0 >>= 5
814
object.speed -= temp0
815
if object.speed < 0
816
hPushSpring[arrayPos0].beingPushed |= true
817
end if
818
819
if object[arrayPos0].state == HPUSHSPRING_PUSHING
820
if hPushSpring[arrayPos0].pushOffset > 0x10000
821
object.speed = 12
822
object.speed *= hPushSpring[arrayPos0].pushOffset
823
object.speed /= 18
824
PlaySfx(SfxName[Spring], false)
825
end if
826
end if
827
break
828
end switch
829
break
830
831
case TypeName[Ball Cannon]
832
BoxCollisionTest(C_TOUCH, arrayPos0, -4, -4, 4, 4, object.entityPos, -10, -14, 10, 14)
833
if checkResult == true
834
temp0 = 1
835
temp0 <<= 5
836
temp0 &= object[arrayPos0].activePlayers
837
if temp0 == false
838
object.state = CHECKEREDBALL_LAUNCHED
839
object.xpos = object[arrayPos0].xpos
840
object.ypos = object[arrayPos0].ypos
841
object.speed = 0
842
object.xvel = 0
843
object.yvel = 0
844
object.visible = false
845
object.tileCollisions = false
846
temp0 = 1
847
temp0 <<= 5
848
ballCannon[arrayPos0].activePlayers |= temp0
849
ballCannon[arrayPos0].timer = 0
850
ballCannon[arrayPos0].tablePos = 0
851
object[arrayPos0].state = BALLCANNON_ENTERED
852
if object[arrayPos0].priority != PRIORITY_XBOUNDS_DESTROY
853
object[arrayPos0].priority = PRIORITY_ACTIVE
854
end if
855
object.parent = arrayPos0
856
PlaySfx(SfxName[Rolling], false)
857
end if
858
end if
859
break
860
861
case TypeName[Gas Platform]
862
temp0 = object[arrayPos0].ypos
863
864
object[arrayPos0].ypos = gasPlatform[arrayPos0].centerPos.y
865
BoxCollisionTest(C_SOLID, arrayPos0, -32, 8, 32, 48, object.entityPos, -10, -14, 10, 14)
866
BoxCollisionTest(C_SOLID, arrayPos0, -16, 0, 16, 24, object.entityPos, -10, -14, 10, 14)
867
868
object[arrayPos0].ypos = temp0
869
object[arrayPos0].ypos -= gasPlatform[arrayPos0].collisionOffset.y
870
BoxCollisionTest(C_PLATFORM, arrayPos0, -24, -8, 24, 12, object.entityPos, -10, -14, 10, 14)
871
if checkResult == true
872
object.collisionOffset.y = gasPlatform[arrayPos0].collisionOffset.y
873
end if
874
875
object[arrayPos0].ypos += gasPlatform[arrayPos0].collisionOffset.y
876
break
877
878
case TypeName[Elevator]
879
object[arrayPos0].ypos -= elevator[arrayPos0].collisionOffset.y
880
881
if object[arrayPos0].frame == 0
882
BoxCollisionTest(C_PLATFORM, arrayPos0, -64, -12, 64, 12, object.entityPos, -10, -14, 10, 14)
883
else
884
BoxCollisionTest(C_PLATFORM, arrayPos0, -32, -12, 32, 12, object.entityPos, -10, -14, 10, 14)
885
end if
886
887
if checkResult == true
888
object.collisionOffset.y = elevator[arrayPos0].collisionOffset.y
889
end if
890
891
object[arrayPos0].ypos += elevator[arrayPos0].collisionOffset.y
892
break
893
894
case TypeName[Swing Platform]
895
temp0 = object[arrayPos0].xpos
896
temp1 = object[arrayPos0].ypos
897
object[arrayPos0].xpos = swingPlatform[arrayPos0].drawPos.x
898
object[arrayPos0].ypos = swingPlatform[arrayPos0].drawPos.y
899
object[arrayPos0].xpos -= swingPlatform[arrayPos0].collisionOffset.x
900
object[arrayPos0].ypos -= swingPlatform[arrayPos0].collisionOffset.y
901
BoxCollisionTest(C_PLATFORM, object[arrayPos0].entityPos, -32, -8, 32, 8, object.entityPos, -10, -14, 10, 14)
902
if checkResult == true
903
object.collisionOffset.x = swingPlatform[arrayPos0].collisionOffset.x
904
object.collisionOffset.y = swingPlatform[arrayPos0].collisionOffset.y
905
end if
906
object[arrayPos0].xpos = temp0
907
object[arrayPos0].ypos = temp1
908
break
909
910
case TypeName[C Floor]
911
CallFunction(CheckeredBall_CLedgeCollapse)
912
break
913
914
case TypeName[Plane Sw V]
915
// Why is this here, plane switches don't even exist in OOZ...
916
// (Likely just leftover from copying S1's CheckeredBall object, since there *are* path swappers in GHZ)
917
CheckEqual(planeSwV[arrayPos0].onGround, false)
918
temp0 = checkResult
919
CheckEqual(object.gravity, 0)
920
temp0 |= checkResult
921
if temp0 == true
922
BoxCollisionTest(C_TOUCH, object[arrayPos0].entityPos, -12, planeSwV[arrayPos0].extendTop, 12, planeSwV[arrayPos0].extendBottom, object.entityPos, -14, -2, 14, 2)
923
if checkResult == true
924
if object.xvel > 0
925
object.collisionPlane = planeSwV[arrayPos0].planeL
926
object.drawOrder = planeSwV[arrayPos0].drawOrderL
927
else
928
object.collisionPlane = planeSwV[arrayPos0].planeR
929
object.drawOrder = planeSwV[arrayPos0].drawOrderR
930
end if
931
end if
932
end if
933
break
934
935
case TypeName[Plane Sw H]
936
// See above note, likely the same story here
937
// Although the Origins version of the S1 GHZ Checkered Ball script broke Sw H interactions, this was left alone and still works just fine
938
CheckEqual(planeSwH[arrayPos0].onGround, false)
939
temp0 = checkResult
940
CheckEqual(object.gravity, 0)
941
temp0 |= checkResult
942
if temp0 == true
943
BoxCollisionTest(C_TOUCH, object[arrayPos0].entityPos, planeSwH[arrayPos0].extendLeft, -12, planeSwH[arrayPos0].extendRight, 12, object.entityPos, -14, -2, 14, 2)
944
if checkResult == true
945
if object.yvel > 0
946
object.collisionPlane = planeSwH[arrayPos0].planeL
947
object.drawOrder = planeSwH[arrayPos0].drawOrderL
948
else
949
object.collisionPlane = planeSwH[arrayPos0].planeL
950
object.drawOrder = planeSwH[arrayPos0].drawOrderR
951
end if
952
end if
953
end if
954
break
955
956
case TypeName[Eggman]
957
if oozEggman[arrayPos0].health != 0
958
if object[arrayPos0].visible == true
959
if oozEggman[arrayPos0].invincibilityTimer == 0
960
BoxCollisionTest(C_TOUCH, arrayPos0, -24, -10, 24, 24, object.entityPos, -14, -14, 14, 14)
961
if checkResult == true
962
oozEggman[arrayPos0].health--
963
if oozEggman[arrayPos0].health == 0
964
player.score += 1000
965
object[arrayPos0].animationTimer = 0
966
object[arrayPos0].animation = OOZEGGANI_DEFEATED
967
oozEggman[arrayPos0].exploding = true
968
oozEggman[arrayPos0].timer = 0
969
object[arrayPos0].state = OOZEGGMAN_EXPLODE
970
SetPaletteEntry(0, 192, 0x000000)
971
else
972
object[arrayPos0].animationTimer = 0
973
object[arrayPos0].animation = OOZEGGANI_HIT
974
oozEggman[arrayPos0].invincibilityTimer = 64
975
oozEggman[arrayPos0].spawnHarpoon = true
976
PlaySfx(SfxName[Boss Hit], false)
977
end if
978
end if
979
end if
980
end if
981
end if
982
break
983
984
case TypeName[Push Button]
985
if object[arrayPos0].frame == 0
986
BoxCollisionTest(C_SOLID, arrayPos0, -14, -6, 14, 12, object.entityPos, -14, -14, 14, 14)
987
if checkResult == COL_TOP
988
pushButton[arrayPos0].stood = true
989
pushButton[arrayPos0].pressed = true
990
object.ypos += 40000
991
PlaySfx(SfxName[Button Press], false)
992
end if
993
else
994
if object.yvel >= 0
995
BoxCollisionTest(C_PLATFORM, arrayPos0, -14, -6, 14, 12, object.entityPos, -14, -14, 14, 14)
996
if checkResult == true
997
pushButton[arrayPos0].stood = true
998
object.ypos += 0x20000
999
else
1000
BoxCollisionTest(C_TOUCH, arrayPos0, -20, -12, 20, 8, object.entityPos, -14, -14, 14, 14)
1001
if checkResult == true
1002
object.ypos = object.collisionBottom
1003
FlipSign(object.ypos)
1004
object.ypos <<= 16
1005
object.ypos += object[arrayPos0].ypos
1006
object.ypos -= 0x20000
1007
object.gravity = GRAVITY_AIR
1008
end if
1009
end if
1010
end if
1011
end if
1012
break
1013
1014
case TypeName[Checkered Ball]
1015
if arrayPos0 != object.entityPos
1016
temp0 = object.xpos
1017
temp0 -= object[arrayPos0].xpos
1018
Abs(temp0)
1019
temp0 >>= 17
1020
if temp0 >= 16
1021
temp0 = 15
1022
end if
1023
GetTableValue(temp6, temp0, CheckeredBall_heightArray)
1024
temp0 = temp6
1025
temp0 >>= 1
1026
temp6 += temp0
1027
temp6 -= 14
1028
temp7 = temp6
1029
FlipSign(temp7)
1030
temp0 = object.xvel
1031
temp1 = object.yvel
1032
temp2 = object.speed
1033
BoxCollisionTest(C_SOLID, arrayPos0, -14, temp6, 14, temp7, object.entityPos, -14, -14, 14, 14)
1034
switch checkResult
1035
case COL_LEFT
1036
case COL_RIGHT
1037
CheckGreater(temp0, 0)
1038
temp3 = checkResult
1039
CheckLower(object.xpos, object[arrayPos0].xpos)
1040
temp3 &= checkResult
1041
CheckLower(temp0, 0)
1042
temp4 = checkResult
1043
CheckGreater(object.xpos, object[arrayPos0].xpos)
1044
temp4 &= checkResult
1045
temp3 |= temp4
1046
if temp3 != 0
1047
object.xvel = object[arrayPos0].xvel
1048
object.speed = object[arrayPos0].speed
1049
object[arrayPos0].xvel = temp0
1050
object[arrayPos0].speed = temp2
1051
end if
1052
break
1053
1054
case COL_TOP
1055
if object.xpos < object[arrayPos0].xpos
1056
object.speed -= 0xC00
1057
object.xvel -= 0xC00
1058
object[arrayPos0].speed += 0xC00
1059
object[arrayPos0].xvel += 0xC00
1060
object[arrayPos0].angleVel += 0xC00
1061
else
1062
object.speed += 0xC00
1063
object.xvel += 0xC00
1064
object[arrayPos0].speed -= 0xC00
1065
object[arrayPos0].xvel -= 0xC00
1066
object[arrayPos0].angleVel -= 0xC00
1067
end if
1068
// [Fallthrough]
1069
case COL_BOTTOM
1070
CheckGreater(temp1, 0)
1071
temp3 = checkResult
1072
CheckLower(object.ypos, object[arrayPos0].ypos)
1073
temp3 &= checkResult
1074
CheckLower(temp1, 0)
1075
temp4 = checkResult
1076
CheckGreater(object.ypos, object[arrayPos0].ypos)
1077
temp4 &= checkResult
1078
temp3 |= temp4
1079
if temp3 != 0
1080
object.yvel = object[arrayPos0].yvel
1081
object[arrayPos0].yvel = temp1
1082
end if
1083
break
1084
1085
end switch
1086
1087
BoxCollisionTest(C_TOUCH, arrayPos0, -14, temp6, 14, temp7, object.entityPos, -14, -14, 14, 14)
1088
if checkResult == true
1089
if object.xpos < object[arrayPos0].xpos
1090
object.xpos -= 0x10000
1091
else
1092
object.xpos += 0x10000
1093
end if
1094
if object.ypos < object[arrayPos0].ypos
1095
object.ypos -= 0x10000
1096
else
1097
object.ypos += 0x10000
1098
end if
1099
end if
1100
end if
1101
break
1102
1103
case TypeName[Gas Break Block]
1104
switch object[arrayPos0].state
1105
case GASBREAKBLOCK_BLOCKS
1106
temp0 = object.yvel
1107
BoxCollisionTest(C_SOLID, arrayPos0, -16, -16, 16, 16, object.entityPos, -14, -14, 14, 14)
1108
object.yvel = temp0
1109
if checkResult == COL_TOP
1110
object.gravity = GRAVITY_AIR
1111
temp0 = 0
1112
temp1 = 0
1113
while temp0 < 16
1114
CreateTempObject(TypeName[Gas Break Block], 0, object[arrayPos0].xpos, object[arrayPos0].ypos)
1115
GetTableValue(object[tempObjectPos].frame, temp0, GasBreakBlock_blockFrames)
1116
GetTableValue(temp2, temp1, GasBreakBlock_blockOffsets)
1117
GetTableValue(object[tempObjectPos].xvel, temp1, GasBreakBlock_blockVelocities)
1118
temp1++
1119
GetTableValue(temp3, temp1, GasBreakBlock_blockOffsets)
1120
GetTableValue(object[tempObjectPos].yvel, temp1, GasBreakBlock_blockVelocities)
1121
temp1++
1122
object[tempObjectPos].xpos += temp2
1123
object[tempObjectPos].ypos += temp3
1124
object[tempObjectPos].state = GASBREAKBLOCK_DEBRIS
1125
object[tempObjectPos].drawOrder = 5
1126
temp0++
1127
loop
1128
object[arrayPos0].state++
1129
if object[arrayPos0].priority != PRIORITY_XBOUNDS_DESTROY
1130
object[arrayPos0].priority = PRIORITY_ACTIVE
1131
end if
1132
PlaySfx(SfxName[Block Break], false)
1133
end if
1134
break
1135
1136
case GASBREAKBLOCK_LAUNCHER
1137
if object.state == CHECKEREDBALL_NORMAL
1138
BoxCollisionTest(C_TOUCH, arrayPos0, -8, -4, 8, 4, object.entityPos, -10, -14, 10, 14)
1139
if checkResult == true
1140
object.state = CHECKEREDBALL_LAUNCHED
1141
object.xpos = object[arrayPos0].xpos
1142
object.ypos = object[arrayPos0].ypos
1143
if object[arrayPos0].propertyValue == 0
1144
object.xvel = 0
1145
object.yvel = -0x80000
1146
else
1147
object.xvel = 0x80000
1148
object.yvel = 0
1149
end if
1150
PlaySfx(SfxName[Rolling], false)
1151
end if
1152
end if
1153
break
1154
1155
end switch // object[arrayPos0].state
1156
break
1157
1158
case TypeName[Animal Prison]
1159
animalPrison[arrayPos0].buttonPos = object[arrayPos0].ypos
1160
animalPrison[arrayPos0].buttonPos -= 0x300000
1161
temp2 = animalPrison[arrayPos0].buttonPos
1162
temp2 += 0x80000
1163
BoxCollisionTest(C_SOLID, arrayPos0, -32, -24, 32, 32, object.entityPos, -10, -14, 10, 14)
1164
BoxCollisionTest(C_SOLID, arrayPos0, -16, -40, 16, -24, object.entityPos, -10, -14, 10, 14)
1165
if object[arrayPos0].state == ANIMALPRISON_AWAITOPEN
1166
if checkResult == COL_TOP
1167
object[arrayPos0].state = ANIMALPRISON_OPENING
1168
stage.timeEnabled = false
1169
if Player_superState == SUPERSTATE_SUPER
1170
Player_superState = SUPERSTATE_FADEOUT
1171
end if
1172
object[arrayPos0].xvel = 0x80000
1173
object[arrayPos0].yvel = -0x40000
1174
animalPrison[arrayPos0].lockPos.x = object[arrayPos0].xpos
1175
animalPrison[arrayPos0].lockPos.y = object[arrayPos0].ypos
1176
CreateTempObject(TypeName[Smoke Puff], 0, object[arrayPos0].xpos, object[arrayPos0].ypos)
1177
object[tempObjectPos].ypos -= 0x180000
1178
PlaySfx(SfxName[Destroy], false)
1179
end if
1180
end if
1181
1182
BoxCollisionTest(C_TOUCH, arrayPos0, -15, -48, 15, -24, object.entityPos, -10, -14, 10, 14)
1183
if checkResult == true
1184
temp0 = object.collisionBottom
1185
temp0 <<= 16
1186
temp0 += object.ypos
1187
if temp0 > animalPrison[arrayPos0].buttonPos
1188
if temp0 <= temp2
1189
animalPrison[arrayPos0].buttonPos = temp0
1190
end if
1191
end if
1192
end if
1193
break
1194
1195
end switch
1196
next
1197
1198
if object.parent != 0
1199
arrayPos0 = object.parent
1200
if object[arrayPos0].state == BALLCANNON_EXITED
1201
if ballCannon[arrayPos0].lastCannon == true
1202
object.state = CHECKEREDBALL_NORMAL
1203
object.gravity = GRAVITY_AIR
1204
object.tileCollisions = true
1205
end if
1206
object.visible = true
1207
object.unused = 0
1208
object.speed = object[arrayPos0].xvel
1209
object.xvel = object[arrayPos0].xvel
1210
object.yvel = object[arrayPos0].yvel
1211
end if
1212
end if
1213
1214
temp1 = object.xpos
1215
temp1 >>= 16
1216
temp2 = object.ypos
1217
temp2 >>= 16
1218
temp2 += 6
1219
Get16x16TileInfo(temp0, temp1, temp2, TILEINFO_ANGLEB)
1220
switch temp0
1221
default
1222
case TILE_NORMAL
1223
break
1224
1225
case TILE_OILPOOL
1226
if object.yvel > -1
1227
object.gravity = GRAVITY_GROUND
1228
object.yvel = 0
1229
object.ypos += 0x10000
1230
end if
1231
temp0 = object.speed
1232
temp0 >>= 5
1233
object.speed -= temp0
1234
break
1235
1236
case TILE_OILSTRIP
1237
break
1238
1239
case TILE_OILSLIDE
1240
break
1241
1242
end switch
1243
1244
if object.state == CHECKEREDBALL_NORMAL
1245
CallFunction(CheckeredBall_PlayerInteraction)
1246
temp0 = object.collisionOffset.x
1247
temp0 |= object.collisionOffset.y
1248
if temp0 != 0
1249
foreach (GROUP_PLAYERS, currentPlayer, ACTIVE_ENTITIES)
1250
BoxCollisionTest(C_TOUCH, object.entityPos, -2, -2, 2, 2, currentPlayer, C_BOX, C_BOX, C_BOX, C_BOX)
1251
if checkResult == false
1252
BoxCollisionTest(C_SOLID, object.entityPos, -14, -14, 14, 14, currentPlayer, C_BOX, C_BOX, C_BOX, C_BOX)
1253
if checkResult == COL_TOP
1254
player[currentPlayer].xpos += object.collisionOffset.x
1255
player[currentPlayer].ypos += object.collisionOffset.y
1256
end if
1257
end if
1258
next
1259
1260
object.xpos += object.collisionOffset.x
1261
object.ypos += object.collisionOffset.y
1262
object.collisionOffset.x = 0
1263
object.collisionOffset.y = 0
1264
end if
1265
end if
1266
1267
if object.outOfBounds == true
1268
temp0 = object.xpos
1269
temp1 = object.ypos
1270
object.xpos = object.startPos.x
1271
object.ypos = object.startPos.y
1272
if object.outOfBounds == true
1273
object.roundedPos.x = object.xpos
1274
object.roundedPos.y = object.ypos
1275
object.xvel = 0
1276
object.yvel = 0
1277
object.speed = 0
1278
object.badnikBonus = 0
1279
object.groundAngle = 0
1280
object.activePlayers = 0
1281
object.ballAngle = 0
1282
object.angleVel = 0
1283
object.playerControlled = false
1284
object.priority = PRIORITY_BOUNDS
1285
object.state = 0
1286
else
1287
object.xpos = temp0
1288
object.ypos = temp1
1289
end if
1290
end if
1291
1292
object.roundedPos.x = object.xpos
1293
object.roundedPos.x &= 0xFFFF0000
1294
object.roundedPos.y = object.ypos
1295
object.roundedPos.y &= 0xFFFF0000
1296
end event
1297
1298
1299
event ObjectDraw
1300
// Draw the ball frame
1301
object.rotation = object.ballAngle
1302
object.rotation >>= 14
1303
temp0 = object.rotation
1304
temp0 += 8
1305
temp0 >>= 4
1306
temp0 &= 7
1307
temp0++
1308
DrawSprite(temp0)
1309
1310
// And draw the shine ontop of it too
1311
object.inkEffect = 3
1312
object.alpha = 0xA0
1313
DrawSpriteFX(0, FX_INK, object.xpos, object.ypos)
1314
end event
1315
1316
1317
event ObjectStartup
1318
LoadSpriteSheet("OOZ/Objects.gif")
1319
1320
// Checkered Ball Frames
1321
SpriteFrame(-16, -16, 32, 32, 396, 190)
1322
SpriteFrame(-16, -16, 32, 32, 429, 190)
1323
SpriteFrame(-16, -16, 32, 32, 273, 133)
1324
SpriteFrame(-16, -16, 32, 32, 322, 100)
1325
SpriteFrame(-16, -16, 32, 32, 289, 100)
1326
SpriteFrame(-16, -16, 32, 32, 256, 100)
1327
SpriteFrame(-16, -16, 32, 32, 256, 67)
1328
SpriteFrame(-16, -16, 32, 32, 256, 34)
1329
SpriteFrame(-16, -16, 32, 32, 256, 1)
1330
1331
// Load the animation file... but why?
1332
// Nothing's ever really done with it...
1333
LoadAnimation("WreckingBallJr.ani")
1334
1335
// Setup all Checkered Ball objects in the level
1336
// Do note though that, at least in the normal game, this never really does anything since there aren't any Checkered Ball objects placed in the level
1337
foreach (TypeName[Checkered Ball], arrayPos0, ALL_ENTITIES)
1338
object[arrayPos0].gravity = GRAVITY_AIR
1339
object[arrayPos0].startPos.x = object.xpos
1340
object[arrayPos0].startPos.y = object.ypos
1341
next
1342
1343
// Add this object to the debug object list
1344
SetTableValue(TypeName[Checkered Ball], DebugMode_ObjCount, DebugMode_TypesTable)
1345
SetTableValue(CheckeredBall_DebugDraw, DebugMode_ObjCount, DebugMode_DrawTable)
1346
SetTableValue(CheckeredBall_DebugSpawn, DebugMode_ObjCount, DebugMode_SpawnTable)
1347
DebugMode_ObjCount++
1348
end event
1349
1350
1351
// ========================
1352
// Editor Events
1353
// ========================
1354
1355
event RSDKDraw
1356
DrawSprite(0)
1357
1358
object.inkEffect = INK_ADD
1359
object.alpha = 0xA0
1360
DrawSpriteFX(1, FX_INK, object.xpos, object.ypos)
1361
end event
1362
1363
1364
event RSDKLoad
1365
LoadSpriteSheet("OOZ/Objects.gif")
1366
SpriteFrame(-16, -16, 32, 32, 429, 190)
1367
SpriteFrame(-16, -16, 32, 32, 396, 190)
1368
1369
SetVariableAlias(ALIAS_VAR_PROPVAL, "unused")
1370
end event
1371
1372