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/Enemies/Sol.txt
1479 views
1
// ----------------------------------
2
// RSDK Project: Sonic 2
3
// Script Description: Sol 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.unused // Set to 0, but never used again...
13
private alias object.value1 : object.activeFireballs // Bitfield, bits 1-4 are either true or false for the state of each of the Sol's 4 fireballs
14
private alias object.value2 : object.startPos.x
15
private alias object.value3 : object.fireOrbs // true if the Sol should attack the player (always true)
16
private alias object.value4 : object.targetPlayer
17
private alias object.value5 : object.backupTargetPlayer // if we cant target any players, target the last player detected (or P1 if none)
18
private alias object.value6 : object.targetPlayerDistance
19
private alias object.value7 : object.fireballFrame
20
private alias object.value8 : object.fireballFrameTimer
21
22
private alias 0 : SOL_AWAITPLAYER
23
private alias 1 : SOL_FIREFIREBALLS
24
private alias 2 : SOL_NOFIREBALLS
25
private alias 3 : SOL_FIREBALL
26
27
// Player Aliases
28
private alias object.xpos : player.xpos
29
private alias object.ypos : player.ypos
30
31
private alias object.value40 : player.hitboxLeft
32
private alias object.value38 : player.hitboxTop
33
private alias object.value41 : player.hitboxRight
34
private alias object.value39 : player.hitboxBottom
35
36
37
// ========================
38
// Function Declarations
39
// ========================
40
41
reserve function Sol_DebugDraw
42
reserve function Sol_DebugSpawn
43
reserve function Sol_CheckColFull
44
reserve function Sol_CheckColFireball
45
reserve function Sol_CheckOffScreen
46
47
48
// ========================
49
// Function Definitions
50
// ========================
51
52
private function Sol_DebugDraw
53
DrawSpriteFX(0, FX_FLIP, object.xpos, object.ypos)
54
end function
55
56
57
private function Sol_DebugSpawn
58
CreateTempObject(TypeName[Sol], 0, object.xpos, object.ypos)
59
object[tempObjectPos].startPos.x = object[tempObjectPos].xpos
60
object[tempObjectPos].activeFireballs = 15
61
object[tempObjectPos].fireOrbs = true
62
if object[tempObjectPos].propertyValue == 0
63
object[tempObjectPos].direction = FLIP_NONE
64
object[tempObjectPos].xvel = -0x4000
65
else
66
object[tempObjectPos].direction = FLIP_X
67
object[tempObjectPos].xvel = 0x4000
68
end if
69
end function
70
71
72
private function Sol_CheckColFull
73
// Called to check for collision of full entity (namely main Sol along with its fireballs)
74
75
// First check collision with the fireballs
76
temp0 = 0
77
temp7 = object.angle
78
temp1 = object.xpos
79
temp2 = object.ypos
80
while temp0 < 4
81
GetBit(temp6, object.activeFireballs, temp0)
82
if temp6 == true
83
Cos256(object.xpos, temp7)
84
object.xpos <<= 12
85
object.xpos += temp1
86
87
Sin256(object.ypos, temp7)
88
object.ypos <<= 12
89
object.ypos += temp2
90
91
foreach (GROUP_PLAYERS, currentPlayer, ACTIVE_ENTITIES)
92
BoxCollisionTest(C_TOUCH, object.entityPos, -4, -4, 4, 4, currentPlayer, C_BOX, C_BOX, C_BOX, C_BOX)
93
if checkResult == true
94
CallFunction(Player_FireHit)
95
end if
96
next
97
end if
98
temp7 += 0x40
99
temp7 &= 0xFF
100
temp0++
101
loop
102
103
// Then check collision with the Sol itself
104
object.xpos = temp1
105
object.ypos = temp2
106
foreach (GROUP_PLAYERS, currentPlayer, ACTIVE_ENTITIES)
107
BoxCollisionTest(C_TOUCH, object.entityPos, -8, -8, 8, 8, currentPlayer, player[currentPlayer].hitboxLeft, player[currentPlayer].hitboxTop, player[currentPlayer].hitboxRight, player[currentPlayer].hitboxBottom)
108
if checkResult == true
109
CallFunction(Player_BadnikBreak)
110
end if
111
next
112
end function
113
114
115
private function Sol_CheckColFireball
116
// Called to check collision ONLY with the fireball, this is called from the child fireball object, separate from the actual parent object Sol
117
foreach (GROUP_PLAYERS, currentPlayer, ACTIVE_ENTITIES)
118
BoxCollisionTest(C_TOUCH, object.entityPos, -4, -4, 4, 4, currentPlayer, C_BOX, C_BOX, C_BOX, C_BOX)
119
if checkResult == true
120
CallFunction(Player_FireHit)
121
end if
122
next
123
end function
124
125
126
private function Sol_CheckOffScreen
127
if object.outOfBounds == true
128
temp0 = object.xpos
129
object.xpos = object.startPos.x
130
if object.outOfBounds == true
131
// Reset the Sol
132
133
object.xpos = object.startPos.x
134
object.activeFireballs = 15
135
if object.propertyValue == 0
136
object.direction = FLIP_NONE
137
object.xvel = -0x4000
138
else
139
object.direction = FLIP_X
140
object.xvel = 0x4000
141
end if
142
object.unused = 0
143
object.animationTimer = 0
144
object.priority = PRIORITY_BOUNDS
145
object.state = SOL_AWAITPLAYER
146
object.angle = 0
147
else
148
object.xpos = temp0
149
end if
150
end if
151
end function
152
153
154
// ========================
155
// Events
156
// ========================
157
158
event ObjectUpdate
159
switch object.state
160
case SOL_AWAITPLAYER
161
object.priority = PRIORITY_ACTIVE
162
object.xpos += object.xvel
163
164
if object.direction == FLIP_NONE
165
object.angle++
166
else
167
object.angle--
168
end if
169
object.angle &= 0xFF
170
CallFunction(Sol_CheckColFull)
171
172
if object.fireOrbs == true
173
// (Attempt to) find a target player in order to throw fireballs at them
174
object.targetPlayerDistance = 0x7FFFFFFF
175
object.targetPlayer = 0xFFFF
176
object.backupTargetPlayer = 0
177
foreach (GROUP_PLAYERS, currentPlayer, ACTIVE_ENTITIES)
178
temp0 = player[currentPlayer].ypos
179
temp0 -= object.ypos
180
Abs(temp0)
181
if temp0 < object.targetPlayerDistance
182
object.targetPlayerDistance = temp0
183
object.backupTargetPlayer = currentPlayer
184
end if
185
186
if temp0 < 0x400000
187
if object.targetPlayer != 0xFFFF
188
arrayPos0 = object.targetPlayer
189
temp0 = player[currentPlayer].xpos
190
temp0 -= object.xpos
191
Abs(temp0)
192
temp1 = object[arrayPos0].xpos
193
temp1 -= object.xpos
194
Abs(temp1)
195
if temp0 < temp1
196
object.targetPlayer = currentPlayer
197
end if
198
else
199
object.targetPlayer = currentPlayer
200
end if
201
end if
202
next
203
204
if object.targetPlayer != 0xFFFF
205
arrayPos0 = object.targetPlayer
206
temp0 = object.xpos
207
temp0 -= object[arrayPos0].xpos
208
Abs(temp0)
209
if temp0 <= 0x800000
210
object.state = SOL_FIREFIREBALLS
211
212
// Frame 1 is just a dupe of frame 0, this doesn't matter much
213
object.frame = 1
214
end if
215
else
216
arrayPos0 = object.backupTargetPlayer
217
end if
218
219
if object[arrayPos0].xpos < object.xpos
220
object.direction = FLIP_NONE
221
object.xvel = -0x4000
222
else
223
object.direction = FLIP_X
224
object.xvel = 0x4000
225
end if
226
end if
227
CallFunction(Sol_CheckOffScreen)
228
break
229
230
case SOL_FIREFIREBALLS
231
object.xpos += object.xvel
232
if object.direction == FLIP_NONE
233
object.angle++
234
else
235
object.angle--
236
end if
237
object.angle &= 0xFF
238
239
temp0 = 0
240
temp7 = object.angle
241
while temp0 < 4
242
if temp7 == 64
243
GetBit(temp6, object.activeFireballs, temp0)
244
if temp6 == true
245
Cos256(temp1, temp7)
246
temp1 <<= 12
247
temp1 += object.xpos
248
Sin256(temp2, temp7)
249
temp2 <<= 12
250
temp2 += object.ypos
251
SetBit(object.activeFireballs, temp0, false)
252
CreateTempObject(TypeName[Sol], 0, temp1, temp2)
253
object[tempObjectPos].state = SOL_FIREBALL
254
object[tempObjectPos].fireballFrameTimer = object.fireballFrameTimer
255
object[tempObjectPos].fireballFrame = object.fireballFrame
256
if object.direction == FLIP_NONE
257
object[tempObjectPos].xvel = -0x20000
258
else
259
object[tempObjectPos].xvel = 0x20000
260
end if
261
end if
262
end if
263
temp7 += 64
264
temp7 &= 255
265
temp0++
266
loop
267
268
CallFunction(Sol_CheckColFull)
269
if object.activeFireballs == false
270
object.state = SOL_NOFIREBALLS
271
if object.direction == FLIP_NONE
272
object.xvel = -0x4000
273
else
274
object.xvel = 0x4000
275
end if
276
end if
277
278
if object.animationTimer < 16
279
object.animationTimer++
280
else
281
// Frame 2 is just a dupe of frame 0 (just like frame 1) so this doesn't matter much
282
object.frame = 2
283
end if
284
CallFunction(Sol_CheckOffScreen)
285
break
286
287
case SOL_NOFIREBALLS
288
object.xpos += object.xvel
289
CallFunction(Sol_CheckColFull)
290
CallFunction(Sol_CheckOffScreen)
291
break
292
293
case SOL_FIREBALL
294
object.xpos += object.xvel
295
CallFunction(Sol_CheckColFireball)
296
if object.outOfBounds == true
297
object.type = TypeName[Blank Object]
298
end if
299
break
300
301
end switch
302
303
object.fireballFrameTimer++
304
if object.fireballFrameTimer >= 12
305
object.fireballFrameTimer = 0
306
end if
307
308
object.fireballFrame = object.fireballFrameTimer
309
object.fireballFrame /= 6
310
object.fireballFrame += 3
311
end event
312
313
314
event ObjectDraw
315
switch object.state
316
case SOL_AWAITPLAYER
317
case SOL_FIREFIREBALLS
318
temp0 = 0
319
temp7 = object.angle
320
while temp0 < 4
321
GetBit(temp6, object.activeFireballs, temp0)
322
if temp6 == true
323
Cos256(temp1, temp7)
324
temp1 <<= 12
325
temp1 += object.xpos
326
Sin256(temp2, temp7)
327
temp2 <<= 12
328
temp2 += object.ypos
329
DrawSpriteXY(object.fireballFrame, temp1, temp2)
330
end if
331
temp7 += 0x40
332
temp7 &= 0xFF
333
temp0++
334
loop
335
336
DrawSpriteFX(object.frame, FX_FLIP, object.xpos, object.ypos)
337
break
338
339
case SOL_NOFIREBALLS
340
DrawSpriteFX(object.frame, FX_FLIP, object.xpos, object.ypos)
341
break
342
343
case SOL_FIREBALL
344
DrawSprite(object.fireballFrame)
345
break
346
347
end switch
348
end event
349
350
351
event ObjectStartup
352
CheckCurrentStageFolder("Zone05")
353
if checkResult == true
354
LoadSpriteSheet("HTZ/Objects.gif")
355
356
// Normal Frame
357
SpriteFrame(-8, -8, 16, 16, 91, 222)
358
359
// Getting Angry Frames (Same as above)
360
SpriteFrame(-8, -8, 16, 16, 91, 222)
361
SpriteFrame(-8, -8, 16, 16, 91, 222)
362
363
// Fireball Frames
364
SpriteFrame(-8, -8, 16, 16, 1, 33)
365
SpriteFrame(-8, -8, 16, 16, 18, 33)
366
else
367
LoadSpriteSheet("MBZ/Objects.gif")
368
369
// This SpriteFrame data is just duplicated from HTZ's sheet, so it appears broken when loaded
370
371
// Normal Frame
372
SpriteFrame(-8, -8, 16, 16, 91, 222)
373
374
// Getting Angry Frames (Same as above)
375
SpriteFrame(-8, -8, 16, 16, 91, 222)
376
SpriteFrame(-8, -8, 16, 16, 91, 222)
377
378
// Fireball Frames
379
SpriteFrame(-8, -8, 16, 16, 1, 33)
380
SpriteFrame(-8, -8, 16, 16, 18, 33)
381
end if
382
383
foreach (TypeName[Sol], arrayPos0, ALL_ENTITIES)
384
object[arrayPos0].startPos.x = object[arrayPos0].xpos
385
object[arrayPos0].activeFireballs = 15
386
object[arrayPos0].fireOrbs = true
387
if object[arrayPos0].propertyValue == 0
388
object[arrayPos0].direction = FLIP_NONE
389
object[arrayPos0].xvel = -0x4000
390
else
391
object[arrayPos0].direction = FLIP_X
392
object[arrayPos0].xvel = 0x4000
393
end if
394
next
395
396
SetTableValue(TypeName[Sol], DebugMode_ObjCount, DebugMode_TypesTable)
397
SetTableValue(Sol_DebugDraw, DebugMode_ObjCount, DebugMode_DrawTable)
398
SetTableValue(Sol_DebugSpawn, DebugMode_ObjCount, DebugMode_SpawnTable)
399
DebugMode_ObjCount++
400
end event
401
402
403
// ========================
404
// Editor Events
405
// ========================
406
407
event RSDKEdit
408
if editor.returnVariable == true
409
switch editor.variableID
410
case EDIT_VAR_PROPVAL // property value
411
checkResult = object.propertyValue
412
break
413
414
case 0 // direction
415
checkResult = object.propertyValue
416
break
417
418
end switch
419
else
420
switch editor.variableID
421
case EDIT_VAR_PROPVAL // property value
422
object.propertyValue = editor.variableValue
423
break
424
425
case 0 // direction
426
object.propertyValue = editor.variableValue
427
break
428
429
end switch
430
end if
431
end event
432
433
434
event RSDKDraw
435
GetBit(object.direction, object.propertyValue, 0)
436
437
temp0 = 0
438
temp3 = 0
439
while temp0 < 4
440
Cos256(temp1, temp3)
441
temp1 <<= 12
442
temp1 += object.xpos
443
444
Sin256(temp2, temp3)
445
temp2 <<= 12
446
temp2 += object.ypos
447
448
DrawSpriteXY(3, temp1, temp2)
449
temp3 += 0x40
450
temp3 &= 0xFF
451
temp0++
452
loop
453
454
DrawSpriteFX(object.frame, FX_FLIP, object.xpos, object.ypos)
455
end event
456
457
458
event RSDKLoad
459
CheckCurrentStageFolder("Zone05")
460
if checkResult == true
461
LoadSpriteSheet("HTZ/Objects.gif")
462
SpriteFrame(-8, -8, 16, 16, 91, 222)
463
SpriteFrame(-8, -8, 16, 16, 91, 222)
464
SpriteFrame(-8, -8, 16, 16, 91, 222)
465
SpriteFrame(-8, -8, 16, 16, 1, 33)
466
SpriteFrame(-8, -8, 16, 16, 18, 33)
467
else
468
LoadSpriteSheet("MBZ/Objects.gif")
469
470
// Still broken stuff here :(
471
SpriteFrame(-8, -8, 16, 16, 91, 222)
472
SpriteFrame(-8, -8, 16, 16, 91, 222)
473
SpriteFrame(-8, -8, 16, 16, 91, 222)
474
SpriteFrame(-8, -8, 16, 16, 1, 33)
475
SpriteFrame(-8, -8, 16, 16, 18, 33)
476
end if
477
478
AddEditorVariable("direction")
479
SetActiveVariable("direction")
480
AddEnumVariable("Left", 0)
481
AddEnumVariable("Right", 1)
482
end event
483
484