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/MCZ/SwingSpikes.txt
1482 views
1
// ----------------------------------
2
// RSDK Project: Sonic 2
3
// Script Description: Swing Spikes 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.propertyValue : object.length
13
14
private alias object.value0 : object.timer
15
private alias object.value1 : object.drawPos.x
16
private alias object.value2 : object.drawPos.y
17
private alias object.value3 : object.collisionOffset.x
18
private alias object.value4 : object.collisionOffset.y
19
private alias object.value5 : object.moveDir
20
private alias object.value6 : object.swingAngle
21
22
private alias 0 : SWINGSPIKES_AWAITPLAYER
23
private alias 1 : SWINGSPIKES_MOVEDELAY
24
private alias 2 : SWINGSPIKES_MOVING
25
private alias 3 : SWINGSPIKES_FINISHEDMOVE
26
private alias 4 : SWINGSPIKES_RETURN
27
28
// Player Aliases
29
private alias object.xpos : player.xpos
30
private alias object.ypos : player.ypos
31
32
33
// ========================
34
// Function Declarations
35
// ========================
36
37
reserve function SwingSpikes_DebugDraw
38
reserve function SwingSpikes_DebugSpawn
39
40
41
// ========================
42
// Function Definitions
43
// ========================
44
45
private function SwingSpikes_DebugDraw
46
DrawSprite(0)
47
end function
48
49
50
private function SwingSpikes_DebugSpawn
51
CreateTempObject(TypeName[Swing Spikes], 8, object.xpos, object.ypos)
52
object[tempObjectPos].moveDir = object.direction
53
if object[tempObjectPos].moveDir == FACING_RIGHT
54
// Rotating clockwise
55
object[tempObjectPos].swingAngle = 0x8000
56
else
57
// Rotating counter-clockwise
58
object[tempObjectPos].swingAngle = 0x0000
59
end if
60
end function
61
62
63
// ========================
64
// Events
65
// ========================
66
67
event ObjectUpdate
68
switch object.state
69
case SWINGSPIKES_AWAITPLAYER
70
foreach (GROUP_PLAYERS, currentPlayer, ACTIVE_ENTITIES)
71
BoxCollisionTest(C_TOUCH, object.entityPos, -30, 0, 30, 128, currentPlayer, C_BOX, C_BOX, C_BOX, C_BOX)
72
if checkResult == true
73
object.state = SWINGSPIKES_MOVEDELAY
74
75
if object.priority != PRIORITY_XBOUNDS_DESTROY
76
object.priority = PRIORITY_ACTIVE
77
end if
78
end if
79
next
80
break
81
82
case SWINGSPIKES_MOVEDELAY
83
object.timer++
84
if object.timer == 60
85
object.timer = 0
86
object.state++
87
end if
88
break
89
90
case SWINGSPIKES_MOVING
91
object.speed += 8
92
if object.moveDir == 0
93
object.swingAngle -= object.speed
94
95
if object.swingAngle <= 0x4000
96
object.speed = 0
97
object.swingAngle = 0x4000
98
object.state++
99
end if
100
else
101
object.swingAngle += object.speed
102
103
if object.swingAngle >= 0x4000
104
object.speed = 0
105
object.swingAngle = 0x4000
106
object.state++
107
end if
108
end if
109
break
110
111
case SWINGSPIKES_FINISHEDMOVE
112
object.timer++
113
if object.timer == 60
114
object.timer = 0
115
object.state++
116
end if
117
break
118
119
case SWINGSPIKES_RETURN
120
object.speed += 8
121
if object.moveDir == 0
122
object.swingAngle += object.speed
123
124
if object.swingAngle >= 0x8000
125
object.speed = 0
126
object.swingAngle = 0x8000
127
object.state = SWINGSPIKES_MOVEDELAY
128
end if
129
else
130
object.swingAngle -= object.speed
131
132
if object.swingAngle <= 0
133
object.speed = 0
134
object.swingAngle = 0x0000
135
object.state = SWINGSPIKES_MOVEDELAY
136
end if
137
end if
138
break
139
140
end switch
141
142
// Backup object position
143
temp2 = object.xpos
144
temp3 = object.ypos
145
146
// Get the "actual" angle for the upcoming trigonometry calculations
147
object.angle = object.swingAngle
148
object.angle >>= 7
149
150
temp1 = object.length
151
temp1++
152
temp1 <<= 4
153
temp1 -= 8
154
object.xpos = object.drawPos.x
155
object.ypos = object.drawPos.y
156
157
// Calculate pplatform X Pos
158
Cos(object.collisionOffset.x, object.angle)
159
object.collisionOffset.x *= temp1
160
object.collisionOffset.x <<= 7
161
object.collisionOffset.x += temp2
162
object.collisionOffset.x &= 0xFFFF0000
163
object.drawPos.x = object.collisionOffset.x
164
object.collisionOffset.x -= object.xpos
165
166
// And then calculate pplatform Y Pos
167
Sin(object.collisionOffset.y, object.angle)
168
object.collisionOffset.y *= temp1
169
object.collisionOffset.y <<= 7
170
object.collisionOffset.y += temp3
171
object.collisionOffset.y &= 0xFFFF0000
172
object.drawPos.y = object.collisionOffset.y
173
object.collisionOffset.y -= object.ypos
174
175
foreach (GROUP_PLAYERS, currentPlayer, ACTIVE_ENTITIES)
176
BoxCollisionTest(C_SOLID2, object.entityPos, -30, -8, 30, 8, currentPlayer, C_BOX, C_BOX, C_BOX, C_BOX)
177
switch checkResult
178
case COL_TOP
179
player[currentPlayer].xpos += object.collisionOffset.x
180
player[currentPlayer].ypos += object.collisionOffset.y
181
break
182
183
case COL_LEFT
184
CallFunction(Player_Hit)
185
break
186
187
case COL_RIGHT
188
CallFunction(Player_Hit)
189
break
190
191
end switch
192
next
193
194
// Restore the object's position
195
object.xpos = temp2
196
object.ypos = temp3
197
198
if object.outOfBounds == true
199
if object.priority != PRIORITY_XBOUNDS_DESTROY
200
object.priority = PRIORITY_BOUNDS
201
202
if object.moveDir == FACING_RIGHT
203
object.swingAngle = 0x8000
204
else
205
object.swingAngle = 0x0000
206
end if
207
end if
208
end if
209
end event
210
211
212
event ObjectDraw
213
// Draw all the chains first
214
temp0 = 0
215
temp1 = 16
216
while temp0 < object.length
217
Cos(temp2, object.angle)
218
temp2 *= temp1
219
temp2 <<= 7
220
temp2 += object.xpos
221
Sin(temp3, object.angle)
222
temp3 *= temp1
223
temp3 <<= 7
224
temp3 += object.ypos
225
DrawSpriteXY(1, temp2, temp3)
226
temp0++
227
temp1 += 16
228
loop
229
temp1 -= 8
230
231
// Calculate where to draw the platform
232
Cos(object.drawPos.x, object.angle)
233
object.drawPos.x *= temp1
234
object.drawPos.x <<= 7
235
object.drawPos.x += object.xpos
236
object.drawPos.x &= 0xFFFF0000
237
238
Sin(object.drawPos.y, object.angle)
239
object.drawPos.y *= temp1
240
object.drawPos.y <<= 7
241
object.drawPos.y += object.ypos
242
object.drawPos.y &= 0xFFFF0000
243
244
// Rock base
245
DrawSprite(0)
246
247
// Platform
248
DrawSpriteXY(2, object.drawPos.x, object.drawPos.y)
249
end event
250
251
252
event ObjectStartup
253
LoadSpriteSheet("MCZ/Objects.gif")
254
255
SpriteFrame(-12, -12, 23, 33, 152, 131) // 0 - Rock frame
256
SpriteFrame(-8, -8, 16, 16, 135, 148) // 1 - Chain frame
257
SpriteFrame(-31, -8, 62, 16, 30, 32) // 2 - Platform frame
258
259
foreach (TypeName[Swing Spikes], arrayPos0, ALL_ENTITIES)
260
if object[arrayPos0].propertyValue > 0
261
object[arrayPos0].propertyValue--
262
end if
263
264
// Spin direction is the 4th bit in the property value
265
// Many Swing Spikes objects in the scene have the FlipX attr too, though that isn't used in-game
266
object[arrayPos0].moveDir = object[arrayPos0].propertyValue
267
object[arrayPos0].moveDir >>= 3
268
object[arrayPos0].moveDir &= 1
269
if object[arrayPos0].moveDir == 0
270
object[arrayPos0].swingAngle = 0x8000
271
else
272
object[arrayPos0].swingAngle = 0x0000
273
end if
274
275
// First three bits in property value are chain length
276
object[arrayPos0].propertyValue &= 7
277
object[arrayPos0].propertyValue++
278
next
279
280
SetTableValue(TypeName[Swing Spikes], DebugMode_ObjCount, DebugMode_TypesTable)
281
SetTableValue(SwingSpikes_DebugDraw, DebugMode_ObjCount, DebugMode_DrawTable)
282
SetTableValue(SwingSpikes_DebugSpawn, DebugMode_ObjCount, DebugMode_SpawnTable)
283
DebugMode_ObjCount++
284
end event
285
286
287
// ========================
288
// Editor Events
289
// ========================
290
291
event RSDKEdit
292
if editor.returnVariable == true
293
switch editor.variableID
294
case EDIT_VAR_PROPVAL // property value
295
checkResult = object.propertyValue
296
break
297
298
case 0 // length
299
checkResult = object.propertyValue
300
checkResult &= 7
301
break
302
303
case 1 // swingDir
304
GetBit(checkResult, object.propertyValue, 4)
305
break
306
307
end switch
308
else
309
switch editor.variableID
310
case EDIT_VAR_PROPVAL // property value
311
object.propertyValue = editor.variableValue
312
break
313
314
case 0 // length
315
temp0 = 7
316
Not(temp0)
317
object.propertyValue &= temp0
318
editor.variableValue &= 7
319
320
object.propertyValue |= editor.variableValue
321
break
322
323
case 1 // swingDir
324
CheckNotEqual(editor.variableValue, 0)
325
SetBit(object.propertyValue, 4, checkResult)
326
break
327
328
end switch
329
end if
330
end event
331
332
333
event RSDKDraw
334
GetBit(temp0, object.propertyValue, 4)
335
if temp0 == 0
336
temp6 = 0x3e
337
else
338
temp6 = 0x00
339
end if
340
341
temp7 = object.propertyValue
342
temp7 &= 7
343
344
// Draw all the chains first
345
temp0 = 0
346
temp1 = 16
347
while temp0 < temp7
348
Cos(temp2, temp6)
349
temp2 *= temp1
350
temp2 <<= 7
351
temp2 += object.xpos
352
Sin(temp3, temp6)
353
354
temp3 *= temp1
355
temp3 <<= 7
356
temp3 += object.ypos
357
358
DrawSpriteXY(1, temp2, temp3)
359
360
temp0++
361
temp1 += 16
362
loop
363
temp1 -= 8
364
365
// Calculate where to draw the platform
366
Cos(temp2, temp6)
367
temp2 *= temp1
368
temp2 <<= 7
369
temp2 += object.xpos
370
temp2 &= 0xFFFF0000
371
372
Sin(temp3, temp6)
373
temp3 *= temp1
374
temp3 <<= 7
375
temp3 += object.ypos
376
temp3 &= 0xFFFF0000
377
378
// Rock base
379
DrawSprite(0)
380
381
// Platform
382
DrawSpriteXY(2, temp2, temp3)
383
end event
384
385
386
event RSDKLoad
387
LoadSpriteSheet("MCZ/Objects.gif")
388
SpriteFrame(-12, -12, 23, 33, 152, 131)
389
SpriteFrame(-8, -8, 16, 16, 135, 148)
390
SpriteFrame(-31, -8, 62, 16, 30, 32)
391
392
AddEditorVariable("length")
393
SetActiveVariable("length")
394
395
AddEditorVariable("swingDir")
396
SetActiveVariable("swingDir")
397
AddEnumVariable("left", 0)
398
AddEnumVariable("right", 1)
399
end event
400
401