Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rubberduckycooly
GitHub Repository: rubberduckycooly/Sonic-1-Sonic-2-2013-Script-Decompilation
Path: blob/master/Sonic 1/Scripts/MZ/PushBlock.txt
1480 views
1
// ----------------------------------
2
// RSDK Project: Sonic 1
3
// Script Description: Push Block 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.drawPos.x
14
private alias object.value2 : object.solidBoxL
15
private alias object.value3 : object.solidBoxR
16
private alias object.value4 : object.pushBoxL
17
private alias object.value5 : object.pushBoxR
18
private alias object.value6 : object.beingPushed
19
private alias object.value7 : object.startPos.x
20
private alias object.value8 : object.startPos.y
21
private alias object.value9 : object.pushBoundary
22
private alias object.value10 : object.activePlayers
23
private alias object.value11 : object.activePriority
24
private alias object.value12 : object.storedPriority
25
26
private alias 0 : PUSHBLOCK_PUSHABLE
27
private alias 1 : PUSHBLOCK_MOVING
28
private alias 2 : PUSHBLOCK_FALLING
29
private alias 3 : PUSHBLOCK_INLAVA
30
private alias 4 : PUSHBLOCK_SINKING
31
32
// Player Aliases
33
private alias object.xpos : player.xpos
34
private alias object.ypos : player.ypos
35
private alias object.ixpos : player.ixpos
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.left : player.left
41
private alias object.right : player.right
42
private alias object.collisionRight : player.collisionRight
43
private alias object.collisionLeft : player.collisionLeft
44
45
// Debug Mode Aliases
46
private alias object.value17 : debugMode.currentSelection
47
48
// Chained Crusher Aliases
49
private alias object.value1 : chainedCrusher.crusherType
50
private alias object.value7 : chainedCrusher.dontPlaySfx
51
52
private alias 0 : CHAINCRUSHER_TYPE_LARGE
53
private alias 1 : CHAINCRUSHER_TYPE_MED
54
private alias 2 : CHAINCRUSHER_TYPE_SMALL
55
private alias 3 : CHAINCRUSHER_TYPE_SMALL_ACTIVE
56
57
// Tile Flag Aliases
58
private alias 1 : TILE_LAVA
59
60
// Tile Info ID Aliases
61
private alias 8 : TILEINFO_ANGLEB
62
63
// Path ID Aliases
64
private alias 0 : PATH_A
65
66
67
// ========================
68
// Function Declarations
69
// ========================
70
71
reserve function PushBlock_DebugDraw
72
reserve function PushBlock_DebugSpawn
73
reserve function PushBlock_HandlePushBounds
74
reserve function PushBlock_HandleObjectCollisions
75
reserve function PushBlock_HandleTileCollisions
76
77
78
// ========================
79
// Static Values
80
// ========================
81
82
private value PushBlock_startDebugID = 0
83
84
85
// ========================
86
// Function Definitions
87
// ========================
88
89
private function PushBlock_DebugDraw
90
temp0 = debugMode[0].currentSelection
91
temp0 -= PushBlock_startDebugID
92
DrawSprite(temp0)
93
end function
94
95
96
private function PushBlock_DebugSpawn
97
CreateTempObject(TypeName[Push Block], 0, object.xpos, object.ypos)
98
object[tempObjectPos].beingPushed = false
99
object[tempObjectPos].frame = debugMode[0].currentSelection
100
object[tempObjectPos].frame -= PushBlock_startDebugID
101
if object[tempObjectPos].frame == 0
102
object[tempObjectPos].solidBoxL = -16
103
object[tempObjectPos].solidBoxR = 16
104
object[tempObjectPos].pushBoxL = -17
105
object[tempObjectPos].pushBoxR = 17
106
else
107
object[tempObjectPos].solidBoxL = -64
108
object[tempObjectPos].solidBoxR = 64
109
object[tempObjectPos].pushBoxL = -65
110
object[tempObjectPos].pushBoxR = 65
111
object[tempObjectPos].drawOrder = 5
112
end if
113
end function
114
115
116
private function PushBlock_HandlePushBounds
117
if object.floorSensorC == false
118
if object.floorSensorL == false
119
object.xvel = -0x40000
120
object.pushBoundary = object.xpos
121
object.pushBoundary &= 0xFFFF00000
122
object.state++
123
else
124
if object.floorSensorR == false
125
object.xvel = 0x40000
126
object.pushBoundary = object.xpos
127
object.pushBoundary &= 0xFFFF00000
128
object.pushBoundary += 0x100000
129
object.state++
130
end if
131
end if
132
end if
133
end function
134
135
136
private function PushBlock_HandleObjectCollisions
137
object.activePlayers = 0
138
temp2 = 0
139
object.xvel = 0
140
141
foreach (GROUP_PLAYERS, currentPlayer, ACTIVE_ENTITIES)
142
CheckEqual(options.attractMode, true)
143
temp1 = checkResult
144
CheckEqual(currentPlayer, 1)
145
temp1 &= checkResult
146
147
if player[currentPlayer].gravity == GRAVITY_GROUND
148
if player[currentPlayer].xvel < 0
149
BoxCollisionTest(C_TOUCH, object.entityPos, 0, -12, object.pushBoxR, 12, currentPlayer, C_BOX, C_BOX, C_BOX, C_BOX)
150
if checkResult == true
151
if player[currentPlayer].left == true
152
if temp1 == false
153
SetBit(object.activePlayers, temp2, true)
154
object.xvel -= 0x6000
155
object.beingPushed = true
156
end if
157
end if
158
159
player[currentPlayer].xpos = player[currentPlayer].collisionRight
160
player[currentPlayer].xpos += object.solidBoxR
161
player[currentPlayer].xpos <<= 16
162
player[currentPlayer].xpos += object.drawPos.x
163
player[currentPlayer].xvel = 0
164
player[currentPlayer].speed = 0
165
player[currentPlayer].pushing = 2
166
end if
167
else
168
if player[currentPlayer].xvel > 0
169
BoxCollisionTest(C_TOUCH, object.entityPos, object.pushBoxL, -12, 0, 12, currentPlayer, C_BOX, C_BOX, C_BOX, C_BOX)
170
if checkResult == true
171
if player[currentPlayer].right == true
172
if temp1 == false
173
SetBit(object.activePlayers, temp2, true)
174
object.xvel += 0x6000
175
object.beingPushed = true
176
end if
177
end if
178
179
player[currentPlayer].xpos = player[currentPlayer].collisionLeft
180
player[currentPlayer].xpos += object.solidBoxL
181
player[currentPlayer].xpos <<= 16
182
player[currentPlayer].xpos += object.drawPos.x
183
player[currentPlayer].xvel = 0
184
player[currentPlayer].speed = 0
185
player[currentPlayer].pushing = 2
186
end if
187
else
188
BoxCollisionTest(C_SOLID, object.entityPos, object.solidBoxL, -16, object.solidBoxR, 16, currentPlayer, C_BOX, C_BOX, C_BOX, C_BOX)
189
end if
190
end if
191
else
192
BoxCollisionTest(C_SOLID, object.entityPos, object.solidBoxL, -16, object.solidBoxR, 16, currentPlayer, C_BOX, C_BOX, C_BOX, C_BOX)
193
end if
194
195
temp2++
196
next
197
198
if object.xvel != 0
199
object.xpos += object.xvel
200
if object.xvel < 0
201
ObjectTileCollision(CSIDE_RWALL, object.solidBoxL, 0, PATH_A)
202
else
203
ObjectTileCollision(CSIDE_LWALL, object.solidBoxR, 0, PATH_A)
204
end if
205
CallFunction(PushBlock_HandlePushBounds)
206
207
temp0 = oscillation
208
temp0 &= 31
209
if temp0 < 3
210
PlaySfx(SfxName[Push Block], false)
211
end if
212
213
temp0 = object.xpos
214
temp0 &= 0xFFFF0000
215
if object.drawPos.x != temp0
216
// No code?
217
// This check statement exists in the scripts... but there's nothing that actually happens
218
end if
219
end if
220
221
object.drawPos.x = object.xpos
222
object.drawPos.x &= 0xFFFF0000
223
temp2 = 0
224
foreach (GROUP_PLAYERS, currentPlayer, ACTIVE_ENTITIES)
225
GetBit(temp0, object.activePlayers, temp2)
226
if temp0 == true
227
if player[currentPlayer].xpos < object.xpos
228
player[currentPlayer].ixpos = player[currentPlayer].collisionRight
229
temp1 = object.solidBoxL
230
else
231
player[currentPlayer].ixpos = player[currentPlayer].collisionLeft
232
temp1 = object.solidBoxR
233
end if
234
235
FlipSign(player[currentPlayer].xpos)
236
temp1 <<= 16
237
player[currentPlayer].xpos += temp1
238
player[currentPlayer].xpos += object.xpos
239
else
240
BoxCollisionTest(C_SOLID, object.entityPos, object.solidBoxL, -16, object.solidBoxR, 16, currentPlayer, C_BOX, C_BOX, C_BOX, C_BOX)
241
end if
242
243
temp2++
244
next
245
end function
246
247
248
private function PushBlock_HandleTileCollisions
249
if object.beingPushed == true
250
if object.gravity == GRAVITY_AIR
251
object.yvel += 0x1800
252
object.ypos += object.yvel
253
254
temp0 = object.solidBoxL
255
temp0 += 2
256
ObjectTileCollision(CSIDE_FLOOR, temp0, 16, PATH_A)
257
object.floorSensorL = checkResult
258
object.gravity = checkResult
259
260
ObjectTileCollision(CSIDE_FLOOR, 0, 16, PATH_A)
261
object.floorSensorC = checkResult
262
object.gravity |= checkResult
263
264
temp0 = object.solidBoxR
265
temp0 -= 2
266
ObjectTileCollision(CSIDE_FLOOR, temp0, 16, PATH_A)
267
object.floorSensorR = checkResult
268
object.gravity |= checkResult
269
else
270
object.yvel = 0
271
272
temp0 = object.solidBoxL
273
temp0 += 2
274
ObjectTileGrip(CSIDE_FLOOR, temp0, 16, PATH_A)
275
object.floorSensorL = checkResult
276
object.gravity = checkResult
277
278
ObjectTileGrip(CSIDE_FLOOR, 0, 16, PATH_A)
279
object.floorSensorC = checkResult
280
object.gravity |= checkResult
281
282
temp0 = object.solidBoxR
283
temp0 -= 2
284
ObjectTileGrip(CSIDE_FLOOR, temp0, 16, PATH_A)
285
object.floorSensorR = checkResult
286
object.gravity |= checkResult
287
end if
288
object.gravity ^= GRAVITY_AIR
289
else
290
object.floorSensorL = true
291
object.floorSensorC = true
292
object.floorSensorR = true
293
end if
294
295
// Bug Details: (applies to all the below cases)
296
// - The code after the ObjectTileCollision check affects *all* active crushers in the vicinity,
297
// even though it should probably only affect the crusher that the block is actually currently on
298
// - (This doesn't matter normally because there aren't any times in the base game where blocks and several crushers are near each other, but it's still something worth noting)
299
foreach (TypeName[Chained Crusher], arrayPos0, ACTIVE_ENTITIES)
300
switch chainedCrusher[arrayPos0].crusherType
301
case CHAINCRUSHER_TYPE_LARGE
302
BoxCollisionTest(C_PLATFORM, arrayPos0, -56, -12, 56, 12, object.entityPos, object.solidBoxL, -16, object.solidBoxR, 16)
303
object.beingPushed |= checkResult
304
ObjectTileCollision(CSIDE_ROOF, 0, -17, PATH_A)
305
if checkResult == true
306
// If the block's being squished, then let's move the crusher back down a bit
307
object.ypos -= 0x10000
308
object[arrayPos0].ypos = object.ypos
309
object[arrayPos0].ypos += 0x1D0000
310
chainedCrusher[arrayPos0].dontPlaySfx = true
311
end if
312
break
313
314
case CHAINCRUSHER_TYPE_MED
315
BoxCollisionTest(C_PLATFORM, arrayPos0, -48, -12, 48, 12, object.entityPos, object.solidBoxL, -16, object.solidBoxR, 16)
316
object.beingPushed |= checkResult
317
ObjectTileCollision(CSIDE_ROOF, 0, -17, PATH_A)
318
if checkResult == true
319
// If the block's being squished, then let's move the crusher back down a bit
320
object.ypos -= 0x10000
321
object[arrayPos0].ypos = object.ypos
322
object[arrayPos0].ypos += 0x1D0000
323
chainedCrusher[arrayPos0].dontPlaySfx = true
324
end if
325
break
326
327
case CHAINCRUSHER_TYPE_SMALL
328
BoxCollisionTest(C_PLATFORM, arrayPos0, -16, -12, 16, 12, object.entityPos, object.solidBoxL, -16, object.solidBoxR, 16)
329
object.beingPushed |= checkResult
330
ObjectTileCollision(CSIDE_ROOF, 0, -17, PATH_A)
331
if checkResult == true
332
// If the block's being squished, then let's move the crusher back down a bit
333
object.ypos -= 0x10000
334
object[arrayPos0].ypos = object.ypos
335
object[arrayPos0].ypos += 0x1D0000
336
chainedCrusher[arrayPos0].dontPlaySfx = true
337
end if
338
break
339
340
// (nothing for CHAINCRUSHER_TYPE_SMALL_ACTIVE)
341
342
end switch
343
next
344
end function
345
346
347
// ========================
348
// Events
349
// ========================
350
351
event ObjectUpdate
352
temp6 = object.xpos
353
temp7 = object.ypos
354
switch object.state
355
case PUSHBLOCK_PUSHABLE
356
object.priority = object.activePriority
357
CallFunction(PushBlock_HandleObjectCollisions)
358
CallFunction(PushBlock_HandleTileCollisions)
359
break
360
361
case PUSHBLOCK_MOVING
362
object.xpos += object.xvel
363
if object.xvel > 0
364
if object.xpos >= object.pushBoundary
365
object.xpos = object.pushBoundary
366
object.gravity = GRAVITY_AIR
367
object.state = PUSHBLOCK_FALLING
368
end if
369
else
370
if object.xpos <= object.pushBoundary
371
object.xpos = object.pushBoundary
372
object.gravity = GRAVITY_AIR
373
object.state = PUSHBLOCK_FALLING
374
end if
375
end if
376
break
377
378
case PUSHBLOCK_FALLING
379
CallFunction(PushBlock_HandleTileCollisions)
380
if object.gravity == GRAVITY_GROUND
381
temp1 = object.iypos
382
temp1 += 12
383
Get16x16TileInfo(temp0, object.ixpos, temp1, TILEINFO_ANGLEB)
384
if temp0 == TILE_LAVA
385
object.state = PUSHBLOCK_INLAVA
386
if object.xvel > 0
387
object.xvel = 0x8000
388
else
389
object.xvel = -0x8000
390
end if
391
else
392
object.state = PUSHBLOCK_PUSHABLE
393
end if
394
end if
395
break
396
397
case PUSHBLOCK_INLAVA
398
temp0 = object.xpos
399
temp0 -= object.drawPos.x
400
temp0 += object.xvel
401
temp0 &= 0xFFFF0000
402
if object.gravity == GRAVITY_AIR
403
temp1 = object.ypos
404
temp1 &= 0xFFFF0000
405
object.yvel += 0x1800
406
object.ypos += object.yvel
407
ObjectTileCollision(CSIDE_FLOOR, 0, 16, PATH_A)
408
if checkResult == true
409
object.yvel = 0
410
object.gravity = GRAVITY_GROUND
411
end if
412
temp2 = object.ypos
413
temp2 &= 0xFFFF0000
414
temp2 -= temp1
415
temp3 = object.ypos
416
object.ypos = temp1
417
else
418
temp2 = 0
419
end if
420
421
object.xpos += object.xvel
422
if temp2 != 0
423
object.ypos = temp3
424
end if
425
426
if object.xvel > 0
427
ObjectTileCollision(CSIDE_LWALL, 16, 12, PATH_A)
428
if checkResult == true
429
object.xvel = 0
430
object.timer = 0
431
object.state = PUSHBLOCK_SINKING
432
end if
433
else
434
ObjectTileCollision(CSIDE_RWALL, -16, 12, PATH_A)
435
if checkResult == true
436
object.xvel = 0
437
object.timer = 0
438
object.state = PUSHBLOCK_SINKING
439
end if
440
end if
441
break
442
443
case PUSHBLOCK_SINKING
444
if object.timer < 320
445
object.timer++
446
temp0 = object.timer
447
temp0 &= 7
448
if temp0 == 0
449
object.ypos += 0x10000
450
end if
451
end if
452
break
453
454
end switch
455
456
temp0 = object.xpos
457
temp1 = object.ypos
458
temp4 = object.xpos
459
temp4 &= 0xFFFF0000
460
temp5 = object.ypos
461
temp5 &= 0xFFFF0000
462
object.xpos = temp6
463
object.ypos = temp7
464
temp6 &= 0xFFFF0000
465
temp7 &= 0xFFFF0000
466
temp4 -= temp6
467
temp5 -= temp7
468
469
foreach (GROUP_PLAYERS, currentPlayer, ACTIVE_ENTITIES)
470
CheckNotEqual(player[currentPlayer].pushing, false)
471
temp2 = checkResult
472
CheckEqual(object.state, PUSHBLOCK_PUSHABLE)
473
temp2 &= checkResult
474
if temp2 == false
475
BoxCollisionTest(C_SOLID, object.entityPos, object.solidBoxL, -16, object.solidBoxR, 16, currentPlayer, C_BOX, C_BOX, C_BOX, C_BOX)
476
if checkResult == COL_TOP
477
player[currentPlayer].xpos += temp4
478
player[currentPlayer].ypos += temp5
479
end if
480
end if
481
next
482
483
object.xpos = temp0
484
object.ypos = temp1
485
object.drawPos.x = object.xpos
486
object.drawPos.x &= 0xFFFF0000
487
488
if object.outOfBounds == true
489
temp0 = object.xpos
490
temp1 = object.ypos
491
object.xpos = object.startPos.x
492
object.ypos = object.startPos.y
493
if object.outOfBounds == true
494
object.yvel = 0
495
object.beingPushed = false
496
object.priority = object.storedPriority
497
object.state = PUSHBLOCK_PUSHABLE
498
else
499
object.xpos = temp0
500
object.ypos = temp1
501
end if
502
end if
503
end event
504
505
506
event ObjectDraw
507
DrawSpriteXY(object.frame, object.drawPos.x, object.ypos)
508
end event
509
510
511
event ObjectStartup
512
LoadSpriteSheet("MZ/Objects.gif")
513
SpriteFrame(-16, -16, 32, 32, 159, 322)
514
SpriteFrame(-64, -16, 128, 32, 159, 322)
515
516
foreach (TypeName[Push Block], arrayPos0, ALL_ENTITIES)
517
object[arrayPos0].frame = object[arrayPos0].propertyValue
518
object[arrayPos0].frame &= 1
519
if object[arrayPos0].frame == 0
520
object[arrayPos0].activePriority = PRIORITY_ACTIVE_SMALL
521
object[arrayPos0].storedPriority = PRIORITY_BOUNDS_SMALL
522
object[arrayPos0].priority = PRIORITY_BOUNDS_SMALL
523
else
524
object[arrayPos0].activePriority = PRIORITY_ACTIVE
525
object[arrayPos0].storedPriority = PRIORITY_BOUNDS
526
object[arrayPos0].priority = PRIORITY_BOUNDS
527
end if
528
529
object[arrayPos0].startPos.x = object[arrayPos0].xpos
530
object[arrayPos0].startPos.y = object[arrayPos0].ypos
531
object[arrayPos0].beingPushed = false
532
533
if object[arrayPos0].frame == 0
534
object[arrayPos0].solidBoxL = -16
535
object[arrayPos0].solidBoxR = 16
536
object[arrayPos0].pushBoxL = -17
537
object[arrayPos0].pushBoxR = 17
538
else
539
object[arrayPos0].solidBoxL = -64
540
object[arrayPos0].solidBoxR = 64
541
object[arrayPos0].pushBoxL = -65
542
object[arrayPos0].pushBoxR = 65
543
object[arrayPos0].drawOrder = 5
544
end if
545
next
546
547
temp0 = 0
548
PushBlock_startDebugID = DebugMode_ObjCount
549
while temp0 < 2
550
SetTableValue(TypeName[Push Block], DebugMode_ObjCount, DebugMode_TypesTable)
551
SetTableValue(PushBlock_DebugDraw, DebugMode_ObjCount, DebugMode_DrawTable)
552
SetTableValue(PushBlock_DebugSpawn, DebugMode_ObjCount, DebugMode_SpawnTable)
553
DebugMode_ObjCount++
554
temp0++
555
loop
556
end event
557
558
559
// ========================
560
// Editor Events
561
// ========================
562
563
event RSDKEdit
564
if editor.returnVariable == true
565
switch editor.variableID
566
case EDIT_VAR_PROPVAL // property value
567
checkResult = object.propertyValue
568
checkResult &= 1
569
break
570
571
case 0 // frameID
572
checkResult = object.propertyValue
573
checkResult &= 1
574
break
575
576
end switch
577
else
578
switch editor.variableID
579
case EDIT_VAR_PROPVAL // property value
580
object.propertyValue = editor.variableValue
581
object.propertyValue &= 1
582
break
583
584
case 0 // frameID
585
object.propertyValue = editor.variableValue
586
object.propertyValue &= 1
587
break
588
589
end switch
590
end if
591
end event
592
593
594
event RSDKDraw
595
GetBit(object.frame, object.propertyValue, 0)
596
DrawSprite(object.frame)
597
end event
598
599
600
event RSDKLoad
601
LoadSpriteSheet("MZ/Objects.gif")
602
SpriteFrame(-16, -16, 32, 32, 159, 322)
603
SpriteFrame(-64, -16, 128, 32, 159, 322)
604
605
AddEditorVariable("frameID")
606
SetActiveVariable("frameID")
607
AddEnumVariable("Small", 0)
608
AddEnumVariable("Long", 1)
609
end event
610
611