Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rubberduckycooly
GitHub Repository: rubberduckycooly/Sonic-1-Sonic-2-2013-Script-Decompilation
Path: blob/master/Sonic 2/Scripts/CNZ/TargetBumper.txt
1480 views
1
// ----------------------------------
2
// RSDK Project: Sonic 2
3
// Script Description: Target Bumper 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.offset.x
14
private alias object.value2 : object.offset.y
15
private alias object.value3 : object.bounceCount
16
private alias object.value4 : object.frameOffset
17
private alias object.value5 : object.comboType
18
private alias object.value6 : object.playerTimers
19
20
// States
21
private alias 0 : TARGETBUMPER_IDLE
22
private alias 1 : TARGETBUMPER_BUMPED
23
24
// Player Aliases
25
private alias object.state : player.state
26
private alias object.xpos : player.xpos
27
private alias object.ypos : player.ypos
28
private alias object.xvel : player.xvel
29
private alias object.yvel : player.yvel
30
private alias object.speed : player.speed
31
private alias object.gravity : player.gravity
32
private alias object.animation : player.animation
33
private alias object.tileCollisions : player.tileCollisions
34
35
private alias object.value1 : player.timer
36
private alias object.value16 : player.isSidekick // 0/false is player 1, 1/true if player 2
37
private alias object.value17 : debugMode.currentSelection
38
private alias object.value36 : player.flyCarryTimer // Tails assist lockout timer
39
40
// Global Variable ID Aliases
41
private alias 22 : GLOBAL_PLAYERSCORE
42
43
44
// ========================
45
// Function Declarations
46
// ========================
47
48
reserve function TargetBumper_DebugDraw
49
reserve function TargetBumper_DebugSpawn
50
reserve function TargetBumper_ProcessHit
51
52
// ========================
53
// Static Values
54
// ========================
55
56
private value TargetBumper_startDebugID = 0
57
58
59
// ========================
60
// Function Definitions
61
// ========================
62
63
private function TargetBumper_DebugDraw
64
temp0 = debugMode[0].currentSelection
65
temp0 -= TargetBumper_startDebugID
66
temp1 = object.direction
67
switch temp0
68
case 0
69
object.direction = FLIP_NONE
70
temp0 = 0
71
break
72
73
case 1
74
object.direction = FLIP_NONE
75
temp0 = 3
76
break
77
78
case 2
79
object.direction = FLIP_X
80
temp0 = 3
81
break
82
83
case 3
84
object.direction = FLIP_NONE
85
temp0 = 6
86
break
87
88
case 4
89
object.direction = FLIP_X
90
temp0 = 6
91
break
92
93
end switch
94
95
DrawSpriteFX(temp0, FX_FLIP, object.xpos, object.ypos)
96
object.direction = temp1
97
end function
98
99
100
private function TargetBumper_DebugSpawn
101
temp0 = debugMode[0].currentSelection
102
temp0 -= TargetBumper_startDebugID
103
CreateTempObject(TypeName[Target Bumper], temp0, object.xpos, object.ypos)
104
105
object[tempObjectPos].drawOrder = 4
106
switch object[tempObjectPos].propertyValue
107
case 0
108
object[tempObjectPos].direction = FLIP_NONE
109
object[tempObjectPos].frameOffset = 0
110
object[tempObjectPos].offset.x = 0
111
object[tempObjectPos].offset.y = 0x20000
112
break
113
114
case 1
115
object[tempObjectPos].direction = FLIP_NONE
116
object[tempObjectPos].frameOffset = 3
117
object[tempObjectPos].offset.x = -0x20000
118
object[tempObjectPos].offset.y = 0x20000
119
break
120
121
case 2
122
object[tempObjectPos].direction = FLIP_X
123
object[tempObjectPos].frameOffset = 3
124
object[tempObjectPos].offset.x = 0x20000
125
object[tempObjectPos].offset.y = 0x20000
126
break
127
128
case 3
129
object[tempObjectPos].direction = FLIP_NONE
130
object[tempObjectPos].frameOffset = 6
131
object[tempObjectPos].offset.x = -0x20000
132
object[tempObjectPos].offset.y = 0
133
break
134
135
case 4
136
object[tempObjectPos].direction = FLIP_X
137
object[tempObjectPos].frameOffset = 6
138
object[tempObjectPos].offset.x = 0x20000
139
object[tempObjectPos].offset.y = 0
140
break
141
142
end switch
143
end function
144
145
146
private function TargetBumper_ProcessHit
147
switch object.propertyValue
148
case 0
149
object.xvel = player[currentPlayer].xvel
150
if player[currentPlayer].ypos > object.ypos
151
object.yvel = 0x70000
152
else
153
object.yvel = -0x70000
154
end if
155
break
156
157
case 1
158
ATan2(temp0, player[currentPlayer].xvel, player[currentPlayer].yvel)
159
temp0 -= 96
160
temp1 = temp0
161
Abs(temp1)
162
FlipSign(temp0)
163
temp0 += 96
164
temp2 = temp1
165
temp2 &= 0xFF
166
if temp2 >= 64
167
temp1 -= 128
168
FlipSign(temp1)
169
temp2 = temp1
170
temp2 &= 0xFF
171
if temp2 >= 56
172
temp0 = 96
173
temp0 += 128
174
end if
175
else
176
if temp2 >= 56
177
temp0 = 96
178
end if
179
end if
180
temp0 &= 0xFF
181
Cos256(object.xvel, temp0)
182
Sin256(object.yvel, temp0)
183
object.xvel *= -0x700
184
object.yvel *= -0x700
185
break
186
187
case 2
188
ATan2(temp0, player[currentPlayer].xvel, player[currentPlayer].yvel)
189
temp0 -= 32
190
temp1 = temp0
191
Abs(temp1)
192
FlipSign(temp0)
193
temp0 += 32
194
temp2 = temp1
195
temp2 &= 0xFF
196
if temp2 >= 64
197
temp1 -= 128
198
FlipSign(temp1)
199
temp2 = temp1
200
temp2 &= 0xFF
201
if temp2 >= 56
202
temp0 = 32
203
temp0 += 128
204
end if
205
else
206
if temp2 >= 56
207
temp0 = 32
208
end if
209
end if
210
temp0 &= 0xFF
211
Cos256(object.xvel, temp0)
212
Sin256(object.yvel, temp0)
213
object.xvel *= -0x700
214
object.yvel *= -0x700
215
break
216
217
case 3
218
object.yvel = player[currentPlayer].yvel
219
if player[currentPlayer].xpos > object.xpos
220
object.xvel = 0x70000
221
else
222
object.xvel = -0x70000
223
end if
224
break
225
226
case 4
227
object.yvel = player[currentPlayer].yvel
228
if player[currentPlayer].xpos > object.xpos
229
object.xvel = 0x70000
230
else
231
object.xvel = -0x70000
232
end if
233
break
234
235
end switch
236
237
if player[currentPlayer].state == Player_State_Carried
238
player[1].flyCarryTimer = 30
239
end if
240
241
CheckEqual(player[currentPlayer].animation, ANI_GLIDING)
242
temp2 = checkResult
243
CheckEqual(player[currentPlayer].animation, ANI_GLIDING_STOP)
244
temp2 |= checkResult
245
CheckEqual(player[currentPlayer].animation, ANI_FLYING)
246
temp2 |= checkResult
247
CheckEqual(player[currentPlayer].state, Player_State_TubeRoll)
248
temp2 |= checkResult
249
CheckEqual(player[currentPlayer].state, Player_State_TubeAirRoll)
250
temp2 |= checkResult
251
if temp2 == false
252
#platform: USE_STANDALONE
253
player[currentPlayer].state = Player_State_Air
254
#endplatform
255
#platform: USE_ORIGINS
256
player[currentPlayer].state = Player_State_Air_NoDropDash
257
#endplatform
258
// Bug Details:
259
// This code wasn't updated in Origins Plus to include ANI_HAMMER_JUMP, so
260
// Amy will always start walking if she hits a Bumper with her hammer out
261
if player[currentPlayer].animation != ANI_JUMPING
262
if player[currentPlayer].animation != ANI_RUNNING
263
player[currentPlayer].animation = ANI_WALKING
264
end if
265
end if
266
end if
267
268
if player[currentPlayer].animation == ANI_GLIDING
269
if object.xvel > 0
270
if player[currentPlayer].xvel < 0
271
player[currentPlayer].animation = ANI_GLIDING_DROP
272
player[currentPlayer].state = Player_State_GlideDrop
273
else
274
player[currentPlayer].state = Player_State_GlideRight
275
end if
276
else
277
if player[currentPlayer].xvel > 0
278
player[currentPlayer].animation = ANI_GLIDING_DROP
279
player[currentPlayer].state = Player_State_GlideDrop
280
else
281
player[currentPlayer].state = Player_State_GlideLeft
282
end if
283
end if
284
end if
285
286
player[currentPlayer].xvel = object.xvel
287
player[currentPlayer].speed = player[currentPlayer].xvel
288
if player[currentPlayer].animation == ANI_GLIDING
289
if object.xvel < 0
290
FlipSign(player[currentPlayer].speed)
291
end if
292
end if
293
294
player[currentPlayer].timer = 0
295
player[currentPlayer].yvel = object.yvel
296
player[currentPlayer].gravity = GRAVITY_AIR
297
player[currentPlayer].tileCollisions = true
298
end function
299
300
301
// ========================
302
// Events
303
// ========================
304
305
event ObjectUpdate
306
if object.state > TARGETBUMPER_IDLE
307
object.animationTimer = object.timer
308
object.animationTimer >>= 2
309
object.animationTimer++
310
311
object.timer++
312
if object.timer > 12
313
object.timer = 0
314
object.state = TARGETBUMPER_IDLE
315
object.animationTimer = 0
316
if object.bounceCount > 2
317
object.type = TypeName[Blank Object]
318
end if
319
end if
320
end if
321
322
if object.visible == true
323
temp7 = 0
324
foreach (GROUP_PLAYERS, currentPlayer, ACTIVE_ENTITIES)
325
temp6 = object.playerTimers
326
temp6 >>= temp7
327
temp6 &= 0xFF
328
if temp6 == false
329
switch object.propertyValue
330
case 0
331
BoxCollisionTest(C_TOUCH, object.entityPos, -14, -4, 14, 4, currentPlayer, C_BOX, C_BOX, C_BOX, C_BOX)
332
break
333
334
case 1
335
BoxCollisionTest(C_TOUCH, object.entityPos, -8, -8, 8, 8, currentPlayer, C_BOX, C_BOX, C_BOX, C_BOX)
336
break
337
338
case 2
339
BoxCollisionTest(C_TOUCH, object.entityPos, -8, -8, 8, 8, currentPlayer, C_BOX, C_BOX, C_BOX, C_BOX)
340
break
341
342
case 3
343
BoxCollisionTest(C_TOUCH, object.entityPos, -4, -14, 4, 14, currentPlayer, C_BOX, C_BOX, C_BOX, C_BOX)
344
break
345
346
case 4
347
BoxCollisionTest(C_TOUCH, object.entityPos, -4, -14, 4, 14, currentPlayer, C_BOX, C_BOX, C_BOX, C_BOX)
348
break
349
end switch
350
351
if checkResult == true
352
if object.state == TARGETBUMPER_IDLE
353
PlaySfx(SfxName[Target Bumper], false)
354
if object.bounceCount < 3
355
switch object.comboType
356
case 0
357
CheckNotEqual(object[+1].type, TypeName[Target Bumper])
358
temp0 = checkResult
359
CheckNotEqual(object[+2].type, TypeName[Target Bumper])
360
temp0 &= checkResult
361
break
362
363
case 1
364
CheckNotEqual(object[-1].type, TypeName[Target Bumper])
365
temp0 = checkResult
366
CheckNotEqual(object[+1].type, TypeName[Target Bumper])
367
temp0 &= checkResult
368
break
369
370
case 2
371
CheckNotEqual(object[-1].type, TypeName[Target Bumper])
372
temp0 = checkResult
373
CheckNotEqual(object[-2].type, TypeName[Target Bumper])
374
temp0 &= checkResult
375
break
376
end switch
377
378
CheckEqual(object.bounceCount, 2)
379
temp0 &= checkResult
380
381
// global variable "array" (yes, this is actually how its done)
382
arrayPos0 = GLOBAL_PLAYERSCORE
383
#platform: USE_DECOMP
384
arrayPos0 = VarName[player.score]
385
#endplatform
386
if player[currentPlayer].isSidekick == false
387
arrayPos0 += currentPlayer
388
end if
389
390
if temp0 == false
391
CreateTempObject(TypeName[Object Score], 16, object.xpos, object.ypos)
392
global[arrayPos0] += 10
393
else
394
CreateTempObject(TypeName[Object Score], 2, object.xpos, object.ypos)
395
global[arrayPos0] += 500
396
end if
397
object.bounceCount++
398
end if
399
400
CallFunction(TargetBumper_ProcessHit)
401
else
402
if object.timer > 5
403
PlaySfx(SfxName[Target Bumper], false)
404
CallFunction(TargetBumper_ProcessHit)
405
end if
406
end if
407
object.state = TARGETBUMPER_BUMPED
408
409
object.priority = PRIORITY_ACTIVE
410
temp6 = 3
411
temp6 <<= temp7
412
object.playerTimers |= temp6
413
end if
414
else
415
temp5 = 1
416
temp5 <<= temp7
417
object.playerTimers -= temp5
418
end if
419
temp7 += 8
420
next
421
end if
422
end event
423
424
425
event ObjectDraw
426
if object.visible == true
427
temp0 = object.animationTimer
428
temp0 &= 1
429
430
object.frame = object.frameOffset
431
if object.bounceCount < 2
432
object.frame += object.bounceCount
433
else
434
object.frame += 2
435
end if
436
437
if temp0 == 0
438
DrawSpriteFX(object.frame, FX_FLIP, object.xpos, object.ypos)
439
else
440
temp1 = object.xpos
441
temp1 += object.offset.x
442
temp2 = object.ypos
443
temp2 += object.offset.y
444
DrawSpriteFX(object.frame, FX_FLIP, temp1, temp2)
445
end if
446
end if
447
end event
448
449
450
event ObjectStartup
451
LoadSpriteSheet("CNZ/Objects.gif")
452
SpriteFrame(-16, -6, 32, 12, 1, 166) // Green (V) - #0
453
SpriteFrame(-16, -6, 32, 12, 1, 153) // Yellow (V) - #1
454
SpriteFrame(-16, -6, 32, 12, 1, 140) // Red (V) - #2
455
456
SpriteFrame(-12, -12, 24, 24, 1, 229) // Green (D) - #3
457
SpriteFrame(-12, -12, 24, 24, 1, 204) // Yellow (D) - #4
458
SpriteFrame(-12, -12, 24, 24, 1, 179) // Red (D) - #5
459
460
SpriteFrame(-6, -16, 12, 32, 60, 140) // Green (H) - #6
461
SpriteFrame(-6, -16, 12, 32, 47, 140) // Yellow (H) - #7
462
SpriteFrame(-6, -16, 12, 32, 34, 140) // Red (H) - #8
463
464
foreach (TypeName[Target Bumper], arrayPos0, ALL_ENTITIES)
465
object[arrayPos0].comboType = object[arrayPos0].propertyValue
466
object[arrayPos0].comboType >>= 6
467
468
// Orientation
469
object[arrayPos0].propertyValue &= 0x3F
470
switch object[arrayPos0].propertyValue
471
case 0
472
object[arrayPos0].direction = FACING_RIGHT
473
object[arrayPos0].frameOffset = 0
474
object[arrayPos0].offset.x = 0
475
object[arrayPos0].offset.y = 0x20000
476
break
477
478
case 1
479
object[arrayPos0].direction = FACING_RIGHT
480
object[arrayPos0].frameOffset = 3
481
object[arrayPos0].offset.x = -0x20000
482
object[arrayPos0].offset.y = 0x20000
483
break
484
485
case 2
486
object[arrayPos0].direction = FACING_LEFT
487
object[arrayPos0].frameOffset = 3
488
object[arrayPos0].offset.x = 0x20000
489
object[arrayPos0].offset.y = 0x20000
490
break
491
492
case 3
493
object[arrayPos0].direction = FACING_RIGHT
494
object[arrayPos0].frameOffset = 6
495
object[arrayPos0].offset.x = -0x20000
496
object[arrayPos0].offset.y = 0
497
break
498
499
case 4
500
object[arrayPos0].direction = FACING_LEFT
501
object[arrayPos0].frameOffset = 6
502
object[arrayPos0].offset.x = 0x20000
503
object[arrayPos0].offset.y = 0
504
break
505
506
end switch
507
next
508
509
temp0 = 0
510
TargetBumper_startDebugID = DebugMode_ObjCount
511
while temp0 < 5
512
SetTableValue(TypeName[Target Bumper], DebugMode_ObjCount, DebugMode_TypesTable)
513
SetTableValue(TargetBumper_DebugDraw, DebugMode_ObjCount, DebugMode_DrawTable)
514
SetTableValue(TargetBumper_DebugSpawn, DebugMode_ObjCount, DebugMode_SpawnTable)
515
DebugMode_ObjCount++
516
temp0++
517
loop
518
end event
519
520
521
// ========================
522
// Editor Events
523
// ========================
524
525
event RSDKEdit
526
if editor.returnVariable == true
527
switch editor.variableID
528
case EDIT_VAR_PROPVAL // property value
529
checkResult = object.propertyValue
530
break
531
532
case 0 // type
533
checkResult = object.propertyValue
534
checkResult &= 0x3F
535
break
536
537
case 1 // comboType
538
checkResult = object.propertyValue
539
checkResult >>= 6
540
break
541
542
end switch
543
else
544
switch editor.variableID
545
case EDIT_VAR_PROPVAL // property value
546
object.propertyValue = editor.variableValue
547
break
548
549
case 0 // type
550
editor.variableValue &= 0x3F
551
object.propertyValue &= 0xC0
552
553
object.propertyValue |= editor.variableValue
554
break
555
556
case 1 // comboType
557
editor.variableValue &= 3
558
editor.variableValue <<= 6
559
object.propertyValue &= 0x3F
560
561
object.propertyValue |= editor.variableValue
562
break
563
564
end switch
565
end if
566
end event
567
568
569
event RSDKDraw
570
temp0 = object.propertyValue
571
temp0 &= 0x3F
572
573
switch temp0
574
case 0
575
default
576
object.direction = FLIP_NONE
577
object.frame = 0
578
break
579
580
case 1
581
object.direction = FLIP_NONE
582
object.frame = 1
583
break
584
585
case 2
586
object.direction = FLIP_X
587
object.frame = 1
588
break
589
590
case 3
591
object.direction = FLIP_NONE
592
object.frame = 2
593
break
594
595
case 4
596
object.direction = FLIP_X
597
object.frame = 2
598
break
599
600
end switch
601
602
DrawSpriteFX(object.frame, FX_FLIP, object.xpos, object.ypos)
603
604
if editor.showGizmos == true
605
editor.drawingOverlay = true
606
607
// Draw lines to this Bumper's combo set
608
609
// First, find combo type
610
temp0 = object.propertyValue
611
temp0 >>= 6
612
613
// Now, jump as needed
614
// -> case 3, the standalone type, won't do anything here
615
switch temp0
616
case 0
617
DrawArrow(object.xpos, object.ypos, object[+1].xpos, object[+1].ypos, 255, 255, 0)
618
DrawArrow(object.xpos, object.ypos, object[+2].xpos, object[+2].ypos, 255, 255, 0)
619
break
620
621
case 1
622
DrawArrow(object.xpos, object.ypos, object[-1].xpos, object[-1].ypos, 255, 255, 0)
623
DrawArrow(object.xpos, object.ypos, object[+1].xpos, object[+1].ypos, 255, 255, 0)
624
break
625
626
case 2
627
DrawArrow(object.xpos, object.ypos, object[-1].xpos, object[-1].ypos, 255, 255, 0)
628
DrawArrow(object.xpos, object.ypos, object[-2].xpos, object[-2].ypos, 255, 255, 0)
629
break
630
631
end switch
632
633
editor.drawingOverlay = false
634
end if
635
end event
636
637
638
event RSDKLoad
639
LoadSpriteSheet("CNZ/Objects.gif")
640
SpriteFrame(-16, -6, 32, 12, 1, 166) // Green (V) - #0
641
SpriteFrame(-12, -12, 24, 24, 1, 229) // Green (D) - #1
642
SpriteFrame(-6, -16, 12, 32, 60, 140) // Green (H) - #2
643
644
AddEditorVariable("type")
645
SetActiveVariable("type")
646
AddEnumVariable("Vertical", 0)
647
AddEnumVariable("Diagonal (Right)", 1)
648
AddEnumVariable("Diagonal (Left)", 2)
649
AddEnumVariable("Horizontal (Right)", 3)
650
AddEnumVariable("Horizontal (Left)", 4)
651
652
AddEditorVariable("comboType")
653
SetActiveVariable("comboType")
654
AddEnumVariable("Left (slot+1 & slot+2 are required)", 0)
655
AddEnumVariable("Middle (slot-1 & slot+1 are required)", 1)
656
AddEnumVariable("Right (slot-1 & slot-2 are required)", 2)
657
AddEnumVariable("Standalone", 3)
658
end event
659
660