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/HTZ/SeeSaw.txt
1480 views
1
// ----------------------------------
2
// RSDK Project: Sonic 2
3
// Script Description: SeeSaw 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.orbTimer // Always 0, its functionality is leftover from S1's SLZ
13
private alias object.value1 : object.tiltTimerL
14
private alias object.value2 : object.tiltTimerM
15
private alias object.value3 : object.tiltTimerR
16
private alias object.value4 : object.tilt
17
private alias object.value5 : object.prevTilt
18
private alias object.value6 : object.targetTilt
19
private alias object.value7 : object.launchVelocity
20
private alias object.value8 : object.orbTargetPos.x
21
private alias object.value9 : object.orbTargetPos.y
22
private alias object.value10 : object.orbFrame
23
private alias object.value11 : object.orbSide
24
private alias object.value12 : object.stood // it gets set a couple of times but otherwise it's unused
25
26
private alias 0 : SEESAW_ORB_IDLE
27
private alias 1 : SEESAW_NONE
28
private alias 2 : SEESAW_ORB_LAUNCHED
29
private alias 3 : SEESAW_NO_ORB
30
31
private alias 0 : SEESAW_TILT_L
32
private alias 1 : SEESAW_TILT_M
33
private alias 2 : SEESAW_TILT_R
34
35
// Player Aliases
36
private alias object.state : player.state
37
private alias object.xpos : player.xpos
38
private alias object.ypos : player.ypos
39
private alias object.xvel : player.xvel
40
private alias object.yvel : player.yvel
41
private alias object.speed : player.speed
42
private alias object.gravity : player.gravity
43
private alias object.animation : player.animation
44
private alias object.value1 : player.timer
45
46
47
// ========================
48
// Function Declarations
49
// ========================
50
51
reserve function SeeSaw_DebugDraw
52
reserve function SeeSaw_DebugSpawn
53
reserve function SeeSaw_SetupHitbox
54
55
56
// ========================
57
// Tables
58
// ========================
59
60
private table SeeSaw_tiltHeightTable
61
36, 36, 38, 40, 42, 44, 42, 40, 38, 36, 35, 34, 33, 32, 31, 30
62
29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14
63
13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 2, 2, 2, 2
64
end table
65
66
67
// ========================
68
// Function Definitions
69
// ========================
70
71
private function SeeSaw_DebugDraw
72
DrawSprite(0)
73
end function
74
75
76
private function SeeSaw_DebugSpawn
77
CreateTempObject(TypeName[SeeSaw], 0, object.xpos, object.ypos)
78
object[tempObjectPos].orbTargetPos.x = object.xpos
79
object[tempObjectPos].orbTargetPos.x += 0x280000
80
object[tempObjectPos].orbTargetPos.y = object.ypos
81
object[tempObjectPos].orbTargetPos.y -= 8 // Simply "8" is the wrong value, 0x80000 is actually what's needed. It doesn't matter, though, as the orb pos gets reset when the object updates anyway
82
object[tempObjectPos].orbFrame = 2
83
object[tempObjectPos].tilt = SEESAW_TILT_R
84
object[tempObjectPos].targetTilt = SEESAW_TILT_R
85
if object[tempObjectPos].propertyValue != 0 // A propertyValue check for a newly created temp object? This won't do much...
86
object[tempObjectPos].state = SEESAW_NO_ORB
87
end if
88
end function
89
90
91
private function SeeSaw_SetupHitbox
92
temp2 = 0
93
if temp7 == SEESAW_TILT_M
94
temp0 = -21
95
temp1 = -6
96
temp2 = 48
97
else
98
temp1 = player[currentPlayer].xpos
99
temp1 -= object.xpos
100
temp1 >>= 16
101
temp1 += 48
102
temp3 = temp1
103
if temp1 >= 0
104
if temp1 < 96
105
temp1 >>= 1
106
if temp7 == SEESAW_TILT_L
107
FlipSign(temp1)
108
temp1 += 47
109
end if
110
GetTableValue(temp0, temp1, SeeSaw_tiltHeightTable)
111
FlipSign(temp0)
112
temp1 = temp0
113
temp1 += 18
114
temp2 = 40
115
end if
116
end if
117
end if
118
end function
119
120
121
// ========================
122
// Events
123
// ========================
124
125
event ObjectUpdate
126
temp0 = object.tiltTimerL
127
temp0 |= object.tiltTimerR
128
if temp0 == 0
129
if object.tiltTimerM != SEESAW_TILT_L
130
object.targetTilt = SEESAW_TILT_M
131
end if
132
else
133
if object.tiltTimerL == object.tiltTimerR
134
object.targetTilt = SEESAW_TILT_M
135
else
136
if object.tiltTimerL > object.tiltTimerR
137
object.targetTilt = SEESAW_TILT_L
138
else
139
object.targetTilt = SEESAW_TILT_R
140
end if
141
end if
142
end if
143
144
if object.tilt != object.targetTilt
145
if object.tilt > object.targetTilt
146
object.tilt--
147
else
148
object.tilt++
149
end if
150
151
if object.state == SEESAW_NONE
152
if object.targetTilt == SEESAW_TILT_M
153
temp0 = -0x11400
154
temp1 = -0x81800
155
else
156
if object.orbTimer == 0
157
if object.launchVelocity >= 0xA0000
158
temp0 = -0xA000
159
temp1 = -0xE0000
160
else
161
temp0 = -0xCC00
162
temp1 = -0xAF000
163
end if
164
else
165
if object.launchVelocity >= 0x9C000
166
temp0 = -0x8000
167
temp1 = -0xA2000
168
else
169
temp0 = -0xF400
170
temp1 = -0x96000
171
end if
172
end if
173
end if
174
175
if object.orbTargetPos.x < object.xpos
176
FlipSign(temp0)
177
end if
178
object.xvel = temp0
179
object.yvel = temp1
180
object.state++
181
object.priority = PRIORITY_ACTIVE
182
end if
183
end if
184
185
if object.orbTargetPos.x < object.xpos
186
switch object.tilt
187
case SEESAW_TILT_L
188
temp0 = -0x280000
189
temp1 = -0x80000
190
break
191
192
case SEESAW_TILT_M
193
temp0 = -0x280000
194
temp1 = -0x1C0000
195
break
196
197
case SEESAW_TILT_R
198
temp0 = -0x280000
199
temp1 = -0x2F0000
200
break
201
202
end switch
203
else
204
switch object.tilt
205
case SEESAW_TILT_L
206
temp0 = 0x280000
207
temp1 = -0x2F0000
208
break
209
210
case SEESAW_TILT_M
211
temp0 = 0x280000
212
temp1 = -0x1C0000
213
break
214
215
case SEESAW_TILT_R
216
temp0 = 0x280000
217
temp1 = -0x80000
218
break
219
220
end switch
221
end if
222
223
switch object.state
224
case SEESAW_ORB_IDLE
225
object.orbTargetPos.x = object.xpos
226
object.orbTargetPos.x += temp0
227
object.orbTargetPos.y = object.ypos
228
object.orbTargetPos.y += temp1
229
object.launchVelocity = 0
230
break
231
232
case SEESAW_NONE
233
break
234
235
case SEESAW_ORB_LAUNCHED
236
object.orbTargetPos.x += object.xvel
237
object.orbTargetPos.y += object.yvel
238
object.yvel += 0x3800
239
if object.yvel > 0
240
temp1 += object.ypos
241
if object.orbTargetPos.y >= temp1
242
object.orbTargetPos.y = temp1
243
object.state = SEESAW_ORB_IDLE
244
if object.orbTimer != 0
245
if object.xvel != 0
246
CreateTempObject(TypeName[Smoke Puff], 0, object.orbTargetPos.x, object.orbTargetPos.y)
247
PlaySfx(SfxName[Explosion], false)
248
object.state = SEESAW_NO_ORB
249
object.orbTimer = 0
250
end if
251
end if
252
if object.orbTargetPos.x < object.xpos
253
object.targetTilt = SEESAW_TILT_L
254
object.orbSide = 1
255
else
256
object.targetTilt = SEESAW_TILT_R
257
object.orbSide = 2
258
end if
259
object.priority = PRIORITY_BOUNDS
260
end if
261
end if
262
break
263
264
case SEESAW_NO_ORB
265
break
266
267
end switch
268
269
object.tiltTimerL = 0
270
object.tiltTimerM = 0
271
object.tiltTimerR = 0
272
object.stood = false
273
274
foreach (GROUP_PLAYERS, currentPlayer, ACTIVE_ENTITIES)
275
temp7 = object.prevTilt
276
CallFunction(SeeSaw_SetupHitbox)
277
if temp2 != 0
278
temp3 = temp2
279
FlipSign(temp3)
280
if player[currentPlayer].yvel > object.launchVelocity
281
temp4 = player[currentPlayer].yvel
282
temp4 += 0x7000
283
else
284
temp4 = object.launchVelocity
285
end if
286
287
BoxCollisionTest(C_PLATFORM, object.entityPos, temp3, temp0, temp2, temp1, currentPlayer, C_BOX, C_BOX, C_BOX, C_BOX)
288
if checkResult == true
289
object.stood = true
290
if object.tilt != object.prevTilt
291
temp6 = temp0
292
temp7 = object.tilt
293
CallFunction(SeeSaw_SetupHitbox)
294
temp0 -= temp6
295
temp0 <<= 16
296
player[currentPlayer].ypos += temp0
297
end if
298
299
player[currentPlayer].ypos += 0x20000
300
if object.orbSide == 0
301
if object.state == SEESAW_ORB_IDLE
302
object.state = SEESAW_NONE
303
else
304
if object.state == SEESAW_ORB_LAUNCHED
305
temp4 = object.launchVelocity
306
end if
307
end if
308
309
temp0 = player[currentPlayer].xpos
310
temp0 -= object.xpos
311
Abs(temp0)
312
if temp0 < 0x80000
313
object.tiltTimerM++
314
else
315
if player[currentPlayer].xpos < object.xpos
316
object.tiltTimerL++
317
if object.targetTilt != SEESAW_TILT_L
318
object.launchVelocity = temp4
319
end if
320
else
321
object.tiltTimerR++
322
if object.targetTilt != SEESAW_TILT_R
323
object.launchVelocity = temp4
324
end if
325
end if
326
end if
327
else
328
temp0 = player[currentPlayer].xpos
329
temp0 -= object.xpos
330
Abs(temp0)
331
temp4 = object.yvel
332
if temp0 >= 0x80000
333
if player[currentPlayer].xpos < object.xpos
334
if object.orbSide == 1
335
temp4 = 0
336
end if
337
else
338
if object.orbSide == 2
339
temp4 = 0
340
end if
341
end if
342
end if
343
344
if temp4 != 0
345
#platform: USE_STANDALONE
346
player[currentPlayer].state = Player_State_Air
347
#endplatform
348
#platform: USE_ORIGINS
349
player[currentPlayer].state = Player_State_Air_NoDropDash
350
#endplatform
351
player[currentPlayer].gravity = GRAVITY_AIR
352
player[currentPlayer].speed = player[currentPlayer].xvel
353
if object.state == SEESAW_NO_ORB
354
player[currentPlayer].animation = ANI_JUMPING
355
else
356
if object.orbTimer != 0
357
player[currentPlayer].animation = ANI_JUMPING
358
else
359
player[currentPlayer].animation = ANI_BOUNCING
360
end if
361
end if
362
player[currentPlayer].timer = 0
363
PlaySfx(SfxName[Spring], false)
364
player[currentPlayer].yvel = temp4
365
FlipSign(player[currentPlayer].yvel)
366
end if
367
end if
368
end if
369
end if
370
next
371
372
object.orbSide = 0
373
object.prevTilt = object.tilt
374
375
object.frame = object.tilt
376
object.frame &= 1
377
object.direction = object.tilt
378
object.direction >>= 1
379
object.direction ^= FLIP_X
380
381
if object.orbTimer != 0
382
object.animationTimer--
383
if object.animationTimer <= 0
384
object.orbFrame ^= 1
385
if object.orbTimer > 120
386
object.animationTimer = 10
387
else
388
if object.orbTimer > 60
389
object.animationTimer = 5
390
else
391
object.animationTimer = 2
392
end if
393
end if
394
end if
395
396
if object.state == SEESAW_ORB_IDLE
397
object.orbTimer--
398
if object.orbTimer == 0
399
CreateTempObject(TypeName[Smoke Puff], 0, object.orbTargetPos.x, object.orbTargetPos.y)
400
401
// ???
402
// Seems like they just dummied out SLZ's orb explosion rather than actually removing it
403
// The [Bomb Shrapnel] object type doesn't exist in HTZ, so this effectively creates a bunch of useless Blank Objects
404
405
CreateTempObject(TypeName[Bomb Shrapnel], 0, object.orbTargetPos.x, object.orbTargetPos.y)
406
object[tempObjectPos].xvel = -0x10000
407
object[tempObjectPos].yvel = -0x34000
408
409
CreateTempObject(TypeName[Bomb Shrapnel], 0, object.orbTargetPos.x, object.orbTargetPos.y)
410
object[tempObjectPos].xvel = -0xA000
411
object[tempObjectPos].yvel = -0x24000
412
413
CreateTempObject(TypeName[Bomb Shrapnel], 0, object.orbTargetPos.x, object.orbTargetPos.y)
414
object[tempObjectPos].xvel = 0x10000
415
object[tempObjectPos].yvel = -0x34000
416
417
CreateTempObject(TypeName[Bomb Shrapnel], 0, object.orbTargetPos.x, object.orbTargetPos.y)
418
object[tempObjectPos].xvel = 0xA000
419
object[tempObjectPos].yvel = -0x24000
420
421
PlaySfx(SfxName[Explosion], false)
422
object.state = SEESAW_NO_ORB
423
end if
424
end if
425
else
426
object.animationTimer++
427
object.animationTimer &= 7
428
object.orbFrame = object.animationTimer
429
object.orbFrame >>= 2
430
object.orbFrame += 2
431
end if
432
433
if object.state < SEESAW_NO_ORB
434
temp0 = object.xpos
435
temp1 = object.ypos
436
437
object.xpos = object.orbTargetPos.x
438
object.ypos = object.orbTargetPos.y
439
foreach (GROUP_PLAYERS, currentPlayer, ACTIVE_ENTITIES)
440
BoxCollisionTest(C_TOUCH, object.entityPos, -7, -7, 7, 7, currentPlayer, C_BOX, C_BOX, C_BOX, C_BOX)
441
if checkResult == true
442
CallFunction(Player_Hit)
443
end if
444
next
445
446
object.xpos = temp0
447
object.ypos = temp1
448
end if
449
end event
450
451
452
event ObjectDraw
453
if object.state < SEESAW_NO_ORB
454
temp0 = object.direction
455
if player[0].xpos < object.orbTargetPos.x
456
object.direction = FLIP_NONE
457
else
458
object.direction = FLIP_X
459
end if
460
461
DrawSpriteFX(object.orbFrame, FX_FLIP, object.orbTargetPos.x, object.orbTargetPos.y)
462
object.direction = temp0
463
end if
464
465
DrawSpriteFX(object.frame, FX_FLIP, object.xpos, object.ypos)
466
end event
467
468
469
event ObjectStartup
470
LoadSpriteSheet("HTZ/Objects.gif")
471
SpriteFrame(-44, -44, 91, 56, 164, 1) // SeeSaw (Tilted) - #0
472
SpriteFrame(-48, -24, 96, 36, 159, 58) // SeeSaw (Flat) - #1
473
SpriteFrame(-8, -8, 16, 16, 91, 222) // Orb (Red) - #2
474
SpriteFrame(-8, -8, 16, 16, 91, 239) // Orb (Yellow) - #3
475
476
foreach (TypeName[SeeSaw], arrayPos0, ALL_ENTITIES)
477
object[arrayPos0].orbTargetPos.x = object[arrayPos0].xpos
478
object[arrayPos0].orbTargetPos.x += 0x280000
479
object[arrayPos0].orbTargetPos.y = object[arrayPos0].ypos
480
object[arrayPos0].orbTargetPos.y -= 8 // Just 8, that's it? This is supposed to be a 16-shifted position...
481
object[arrayPos0].orbFrame = 2
482
object[arrayPos0].tilt = SEESAW_TILT_R
483
object[arrayPos0].targetTilt = SEESAW_TILT_R
484
if object[arrayPos0].propertyValue != 0
485
object[arrayPos0].state = SEESAW_NO_ORB
486
end if
487
next
488
489
SetTableValue(TypeName[SeeSaw], DebugMode_ObjCount, DebugMode_TypesTable)
490
SetTableValue(SeeSaw_DebugDraw, DebugMode_ObjCount, DebugMode_DrawTable)
491
SetTableValue(SeeSaw_DebugSpawn, DebugMode_ObjCount, DebugMode_SpawnTable)
492
DebugMode_ObjCount++
493
end event
494
495
496
// ========================
497
// Editor Events
498
// ========================
499
500
event RSDKEdit
501
if editor.returnVariable == true
502
switch editor.variableID
503
case EDIT_VAR_PROPVAL // property value
504
checkResult = object.propertyValue
505
break
506
507
case 0 // orbType
508
checkResult = object.propertyValue
509
break
510
511
end switch
512
else
513
switch editor.variableID
514
case EDIT_VAR_PROPVAL // property value
515
object.propertyValue = editor.variableValue
516
break
517
518
case 0 // orbType
519
object.propertyValue = editor.variableValue
520
break
521
522
end switch
523
end if
524
end event
525
526
527
event RSDKDraw
528
if object.propertyValue == 0
529
temp0 = object.xpos
530
temp0 += 0x280000
531
temp1 = object.ypos
532
temp1 -= 0x80000
533
DrawSpriteXY(2, temp0, temp1)
534
end if
535
536
DrawSprite(0)
537
end event
538
539
540
event RSDKLoad
541
LoadSpriteSheet("HTZ/Objects.gif")
542
SpriteFrame(-44, -44, 91, 56, 164, 1)
543
SpriteFrame(-48, -24, 96, 36, 159, 58)
544
SpriteFrame(-8, -8, 16, 16, 91, 222)
545
SpriteFrame(-8, -8, 16, 16, 91, 239)
546
547
AddEditorVariable("orbType")
548
SetActiveVariable("orbType")
549
AddEnumVariable("Has Orb", 0)
550
AddEnumVariable("No Orb", 255)
551
end event
552
553