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/SBZ/Transporter.txt
1480 views
1
// ----------------------------------
2
// RSDK Project: Sonic 1
3
// Script Description: Transporter 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.playerID
13
private alias object.value1 : object.nodePos.x
14
private alias object.value2 : object.nodePos.y
15
private alias object.value3 : object.nodeChangeDelay
16
private alias object.value4 : object.tablePtr
17
private alias object.value5 : object.tableSize
18
private alias object.value6 : object.tablePos
19
20
// States
21
private alias 0 : TRANSPORTER_WAITING
22
private alias 1 : TRANSPORTER_ACTIVATING
23
private alias 2 : TRANSPORTER_TRANSPORTING
24
25
// Types
26
private alias 0 : TRANSPORTER_TYPE_D_LONG
27
private alias 1 : TRANSPORTER_TYPE_D_MED
28
private alias 2 : TRANSPORTER_TYPE_URU
29
private alias 3 : TRANSPORTER_TYPE_D_SHORT
30
private alias 4 : TRANSPORTER_TYPE_DLD
31
private alias 5 : TRANSPORTER_TYPE_U
32
private alias 6 : TRANSPORTER_TYPE_ULU
33
private alias 7 : TRANSPORTER_TYPE_HIDDEN
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.animationSpeed : player.animationSpeed
44
private alias object.animation : player.animation
45
private alias object.scrollTracking : player.scrollTracking
46
private alias object.tileCollisions : player.tileCollisions
47
private alias object.value0 : player.rings
48
private alias object.value5 : player.rollAnimationSpeed
49
private alias object.value7 : player.invincibleTimer
50
51
// Achievement Aliases
52
private alias 8 : ACHIEVEMENT_HIDDENTRANSPORTER
53
54
55
// ========================
56
// Function Declarations
57
// ========================
58
59
reserve function Transporter_HandleNewNode
60
61
62
// ========================
63
// Tables
64
// ========================
65
66
private table Transporter_tableSizes
67
1, 1, 7, 1, 7, 1, 7, 1
68
end table
69
70
private table Transporter_tablePtrs[8]
71
72
// World Positions of the "nodes", kinda rigid way of doin it, but whatever works I suppose...
73
private table Transporter_movementTable0
74
0x7940000, 0x98C0000
75
end table
76
77
private table Transporter_movementTable1
78
0x940000, 0x38C0000
79
end table
80
81
private table Transporter_movementTable2
82
0x7940000, 0x2E80000
83
0x7A40000, 0x2C00000
84
0x7D00000, 0x2AC0000
85
0x8580000, 0x2AC0000
86
0x8840000, 0x2980000
87
0x8940000, 0x2700000
88
0x8940000, 0x1900000
89
end table
90
91
private table Transporter_movementTable3
92
0x8940000, 0x6900000
93
end table
94
95
private table Transporter_movementTable4
96
0x11940000, 0x4700000
97
0x11840000, 0x4980000
98
0x11580000, 0x4AC0000
99
0x0FD00000, 0x4AC0000
100
0x0FA40000, 0x4C00000
101
0x0F940000, 0x4E80000
102
0x0F940000, 0x5900000
103
end table
104
105
private table Transporter_movementTable5
106
0x12940000, 0x4900000
107
end table
108
109
private table Transporter_movementTable6
110
0x15940000, 0x7E80000
111
0x15840000, 0x7C00000
112
0x15600000, 0x7AC0000
113
0x14D00000, 0x7AC0000
114
0x14A40000, 0x7980000
115
0x14940000, 0x7700000
116
0x14940000, 0x5900000
117
end table
118
119
private table Transporter_movementTable7
120
0x8940000, 0x900000
121
end table
122
123
124
// ========================
125
// Function Definitions
126
// ========================
127
128
private function Transporter_HandleNewNode
129
temp0 = object.nodePos.x
130
temp2 = 0x1000
131
temp0 -= player[currentPlayer].xpos
132
if temp0 < 0
133
FlipSign(temp0)
134
FlipSign(temp2)
135
end if
136
137
temp0 >>= 16
138
temp1 = object.nodePos.y
139
temp3 = 0x1000
140
temp1 -= player[currentPlayer].ypos
141
if temp1 < 0
142
FlipSign(temp1)
143
FlipSign(temp3)
144
end if
145
146
temp1 >>= 16
147
if temp1 >= temp0
148
temp1 = object.nodePos.y
149
temp1 -= player[currentPlayer].ypos
150
temp1 &= 0xFFFF0000
151
temp1 /= temp3
152
153
temp0 = object.nodePos.x
154
temp0 -= player[currentPlayer].xpos
155
if temp0 != 0
156
temp0 &= 0xFFFF0000
157
temp0 /= temp1
158
end if
159
160
temp0 <<= 8
161
temp3 <<= 8
162
temp1 >>= 8
163
player[currentPlayer].xvel = temp0
164
player[currentPlayer].yvel = temp3
165
Abs(temp1)
166
object.nodeChangeDelay = temp1
167
else
168
temp0 = object.nodePos.x
169
temp0 -= player[currentPlayer].xpos
170
temp0 &= 0xFFFF0000
171
temp0 /= temp2
172
173
temp1 = object.nodePos.y
174
temp1 -= player[currentPlayer].ypos
175
if temp1 != 0
176
temp1 &= 0xFFFF0000
177
temp1 /= temp0
178
end if
179
180
temp1 <<= 8
181
temp2 <<= 8
182
temp0 >>= 8
183
player[currentPlayer].xvel = temp2
184
player[currentPlayer].yvel = temp1
185
Abs(temp0)
186
object.nodeChangeDelay = temp0
187
end if
188
end function
189
190
191
// ========================
192
// Events
193
// ========================
194
195
event ObjectUpdate
196
switch object.state
197
case TRANSPORTER_WAITING
198
foreach (GROUP_PLAYERS, currentPlayer, ACTIVE_ENTITIES)
199
if player[currentPlayer].state != Player_State_Static
200
temp0 = player[currentPlayer].xpos
201
temp0 -= object.xpos
202
if object.direction == FLIP_X
203
temp0 += 0xF0000
204
end if
205
206
if temp0 >= 0
207
if temp0 < 0x100000
208
temp1 = player[currentPlayer].ypos
209
temp1 -= object.ypos
210
temp1 += 0x200000
211
if temp1 >= 0
212
if temp1 < 0x400000
213
temp0 = true
214
215
if object.propertyValue == TRANSPORTER_TYPE_HIDDEN
216
if player[currentPlayer].rings < 50
217
temp0 = false
218
else
219
if stage.debugMode == false
220
if currentPlayer == 0
221
// Grant the "Hidden Transporter" Achievement
222
CallNativeFunction2(SetAchievement, ACHIEVEMENT_HIDDENTRANSPORTER, 100)
223
end if
224
end if
225
end if
226
end if
227
228
if temp0 == true
229
CreateTempObject(TypeName[Transporter], object.propertyValue, object.xpos, object.ypos)
230
GetTableValue(object[tempObjectPos].tablePtr, object.propertyValue, Transporter_tablePtrs)
231
GetTableValue(object[tempObjectPos].tableSize, object.propertyValue, Transporter_tableSizes)
232
object[tempObjectPos].state = TRANSPORTER_ACTIVATING
233
object[tempObjectPos].playerID = currentPlayer
234
player[currentPlayer].state = Player_State_Static
235
player[currentPlayer].tileCollisions = false
236
player[currentPlayer].animation = ANI_JUMPING
237
player[currentPlayer].rollAnimationSpeed = 0
238
player[currentPlayer].animationSpeed = 0
239
player[currentPlayer].xvel = 0
240
player[currentPlayer].yvel = 0
241
player[currentPlayer].gravity = GRAVITY_AIR
242
player[currentPlayer].scrollTracking = true
243
player[currentPlayer].xpos = object.xpos
244
player[currentPlayer].ypos = object.ypos
245
PlaySfx(SfxName[Rolling], false)
246
end if
247
end if
248
end if
249
end if
250
end if
251
end if
252
next
253
break
254
255
case TRANSPORTER_ACTIVATING
256
currentPlayer = object.playerID
257
258
// Oscillate a bit
259
Sin256(player[currentPlayer].ypos, object.angle)
260
object.angle += 2
261
player[currentPlayer].ypos <<= 11
262
FlipSign(player[currentPlayer].ypos)
263
player[currentPlayer].ypos += object.ypos
264
265
// Stay Invincible while in the transporter
266
if player[currentPlayer].invincibleTimer < 2
267
player[currentPlayer].invincibleTimer = 2
268
end if
269
270
if object.angle == 0x80
271
temp0 = object.tablePos
272
temp0 <<= 1
273
GetTableValue(object.nodePos.x, temp0, object.tablePtr)
274
temp0++
275
GetTableValue(object.nodePos.y, temp0, object.tablePtr)
276
277
if object.propertyValue == TRANSPORTER_TYPE_ULU // (this one uses screen wrapping)
278
player[currentPlayer].ypos += 0x8000000
279
if currentPlayer == 0
280
tileLayer[2].scrollPos -= 0x1000000
281
camera[0].ypos += 0x800
282
screen.yoffset += 0x800
283
end if
284
285
// Bug Details (kinda?):
286
// -> Rings are teleported in order to mask the screen wrap, but if P2 enters
287
// a teleporter without P1 then the rings will visibly disappear in front of the camera
288
foreach (TypeName[Ring], arrayPos0, ACTIVE_ENTITIES)
289
BoxCollisionTest(C_TOUCH, object.entityPos, -128, -256, 0, 0, arrayPos0, -8, -8, 8, 8)
290
if checkResult == true
291
object[arrayPos0].ypos += 0x8000000
292
end if
293
next
294
end if
295
296
CallFunction(Transporter_HandleNewNode)
297
object.state++
298
PlaySfx(SfxName[Release], false)
299
end if
300
break
301
302
case TRANSPORTER_TRANSPORTING
303
currentPlayer = object.playerID
304
object.nodeChangeDelay--
305
306
if object.nodeChangeDelay < 0
307
player[currentPlayer].xpos = object.nodePos.x
308
player[currentPlayer].ypos = object.nodePos.y
309
310
object.tablePos++
311
if object.tablePos >= object.tableSize
312
object.type = TypeName[Blank Object]
313
player[currentPlayer].ypos &= 0x7FF0000
314
#platform: USE_STANDALONE
315
player[currentPlayer].state = Player_State_Air
316
#endplatform
317
#platform: USE_ORIGINS
318
player[currentPlayer].state = Player_State_Air_NoDropDash
319
#endplatform
320
player[currentPlayer].animation = ANI_WALKING
321
player[currentPlayer].tileCollisions = true
322
player[currentPlayer].speed = 0
323
player[currentPlayer].xvel = 0
324
player[currentPlayer].yvel = 0x20000
325
else
326
temp0 = object.tablePos
327
temp0 <<= 1
328
GetTableValue(object.nodePos.x, temp0, object.tablePtr)
329
temp0++
330
GetTableValue(object.nodePos.y, temp0, object.tablePtr)
331
CallFunction(Transporter_HandleNewNode)
332
end if
333
end if
334
break
335
336
end switch
337
end event
338
339
340
event ObjectStartup
341
LoadSpriteSheet("SBZ/Objects.gif")
342
343
// Set position tables to the master table
344
SetTableValue(Transporter_movementTable0, TRANSPORTER_TYPE_D_LONG, Transporter_tablePtrs)
345
SetTableValue(Transporter_movementTable1, TRANSPORTER_TYPE_D_MED, Transporter_tablePtrs)
346
SetTableValue(Transporter_movementTable2, TRANSPORTER_TYPE_URU, Transporter_tablePtrs)
347
SetTableValue(Transporter_movementTable3, TRANSPORTER_TYPE_D_SHORT, Transporter_tablePtrs)
348
SetTableValue(Transporter_movementTable4, TRANSPORTER_TYPE_DLD, Transporter_tablePtrs)
349
SetTableValue(Transporter_movementTable5, TRANSPORTER_TYPE_U, Transporter_tablePtrs)
350
SetTableValue(Transporter_movementTable6, TRANSPORTER_TYPE_ULU, Transporter_tablePtrs)
351
SetTableValue(Transporter_movementTable7, TRANSPORTER_TYPE_HIDDEN, Transporter_tablePtrs)
352
end event
353
354
355
// ========================
356
// Editor Events
357
// ========================
358
359
event RSDKEdit
360
if editor.returnVariable == true
361
switch editor.variableID
362
case EDIT_VAR_PROPVAL // property value
363
checkResult = object.propertyValue
364
break
365
366
case 0 // type
367
checkResult = object.propertyValue
368
break
369
370
end switch
371
else
372
switch editor.variableID
373
case EDIT_VAR_PROPVAL // property value
374
object.propertyValue = editor.variableValue
375
break
376
377
case 0 // type
378
object.propertyValue = editor.variableValue
379
break
380
381
end switch
382
end if
383
end event
384
385
386
event RSDKDraw
387
DrawSprite(0)
388
389
if editor.showGizmos == true
390
editor.drawingOverlay = true
391
392
temp7 = object.xpos
393
temp6 = object.ypos
394
395
// TODO: attempt at drawing paths here, prolly broken though
396
397
temp0 = object.propertyValue
398
temp0 &= 7
399
400
GetTableValue(object.tablePtr, temp0, Transporter_tablePtrs)
401
GetTableValue(object.tableSize, temp0, Transporter_tableSizes)
402
object.tableSize *= 2
403
404
temp0 = 0
405
while temp0 < object.tableSize
406
GetTableValue(object.nodePos.x, temp0, object.tablePtr)
407
temp0++
408
GetTableValue(object.nodePos.y, temp0, object.tablePtr)
409
temp0++
410
411
DrawArrow(object.xpos, object.ypos, object.nodePos.x, object.nodePos.y, 0xFF, 0xFF, 0x00)
412
413
object.xpos = object.nodePos.x
414
object.ypos = object.nodePos.y
415
loop
416
417
object.xpos = temp7
418
object.ypos = temp6
419
420
editor.drawingOverlay = false
421
end if
422
end event
423
424
425
event RSDKLoad
426
LoadSpriteSheet("Global/Display.gif")
427
SpriteFrame(-8, -8, 16, 16, 239, 239) // "T" (-ransporter)
428
429
AddEditorVariable("type")
430
SetActiveVariable("type")
431
AddEnumVariable("Straight Down (Long)", TRANSPORTER_TYPE_D_LONG)
432
AddEnumVariable("Straight Down", TRANSPORTER_TYPE_D_MED)
433
AddEnumVariable("Up, Right, Up", TRANSPORTER_TYPE_URU)
434
AddEnumVariable("Straight Down (Short)", TRANSPORTER_TYPE_D_SHORT)
435
AddEnumVariable("Down, Left, Down", TRANSPORTER_TYPE_DLD)
436
AddEnumVariable("Straight Up", TRANSPORTER_TYPE_U)
437
AddEnumVariable("Up, Left, Up", TRANSPORTER_TYPE_ULU)
438
AddEnumVariable("Straight up if more than 49 rings (Awards Achievement)", TRANSPORTER_TYPE_HIDDEN)
439
440
SetTableValue(Transporter_movementTable0, TRANSPORTER_TYPE_D_LONG, Transporter_tablePtrs)
441
SetTableValue(Transporter_movementTable1, TRANSPORTER_TYPE_D_MED, Transporter_tablePtrs)
442
SetTableValue(Transporter_movementTable2, TRANSPORTER_TYPE_URU, Transporter_tablePtrs)
443
SetTableValue(Transporter_movementTable3, TRANSPORTER_TYPE_D_SHORT, Transporter_tablePtrs)
444
SetTableValue(Transporter_movementTable4, TRANSPORTER_TYPE_DLD, Transporter_tablePtrs)
445
SetTableValue(Transporter_movementTable5, TRANSPORTER_TYPE_U, Transporter_tablePtrs)
446
SetTableValue(Transporter_movementTable6, TRANSPORTER_TYPE_ULU, Transporter_tablePtrs)
447
SetTableValue(Transporter_movementTable7, TRANSPORTER_TYPE_HIDDEN, Transporter_tablePtrs)
448
end event
449
450