Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rubberduckycooly
GitHub Repository: rubberduckycooly/Sonic-CD-2011-Script-Decompilation
Path: blob/main/Scripts/Special/UFO.txt
1319 views
1
//--------------------Sonic CD UFO Script---------------------//
2
//--------Scripted by Christian Whitehead 'The Taxman'--------//
3
//-------Unpacked By Rubberduckycooly's Script Unpacker-------//
4
5
// Aliases
6
#alias Object.YPos : Object.ZPos
7
8
#alias Object.Value0 : Object.TargetNode
9
#alias Object.Value1 : Object.XVelocity
10
#alias Object.Value2 : Object.ZVelocity
11
#alias Object.Value3 : Object.Timer
12
#alias Object.Value4 : Object.ScreenXPos // Difference from the center of the camera (which is where Sonic is always located)
13
#alias Object.Value5 : Object.ScreenDepth
14
15
// HUD Alias
16
#alias Object.Value0 : HUD.UFOsCount // Initially set via a loop in the UFO script
17
#alias Object.Value1 : HUD.TimeSeconds // Displayed time
18
#alias Object.Value3 : HUD.Rings
19
#alias Object.Value4 : HUD.LastUFOType // Used by UFOs for ring streak bonus
20
#alias Object.Value5 : HUD.SpeedShoesTimer // Used to transmit between player and UFO
21
#alias Object.Value6 : HUD.BonusUFONo // "No" akin to Entity No, not as in "is there no UFO?"
22
23
// UFOPowerUp Aliases
24
#alias Object.Value0 : UFOPowerUp.ExplosionDir
25
#alias Object.Value1 : UFOPowerUp.ExplosionXVel
26
#alias Object.Value2 : UFOPowerUp.ExplosionYVel
27
#alias Object.Value4 : UFOPowerUp.YVelocity
28
#alias Object.Value5 : UFOPowerUp.ScreenDepth
29
#alias Object.Value7 : UFOPowerUp.StartResults
30
31
// SFX Aliases
32
#alias 1 : SFX_G_RING
33
34
// Property Value
35
#alias 0 : UFO_CONTENTS_RINGS
36
#alias 1 : UFO_CONTENTS_SPEEDSHOES
37
#alias 2 : UFO_CONTENTS_TIME
38
39
// Priority
40
#alias 1 : PRIORITY_ACTIVE
41
42
43
sub ObjectMain
44
// Update movement
45
if Object.Timer == 0
46
ArrayPos0 = Object.TargetNode
47
if Object[ArrayPos0].Type != TypeName[UFO Node]
48
Object.TargetNode = Object.EntityNo
49
Object.TargetNode++
50
ArrayPos0 = Object.TargetNode
51
end if
52
53
Object.XPos = Object[ArrayPos0].XPos
54
Object.ZPos = Object[ArrayPos0].ZPos
55
Object.Timer = Object[ArrayPos0].PropertyValue
56
Object.Timer *= 2
57
58
ArrayPos0++
59
Object.TargetNode++
60
if Object[ArrayPos0].Type != TypeName[UFO Node]
61
Object.TargetNode = Object.EntityNo
62
Object.TargetNode++
63
ArrayPos0 = Object.TargetNode
64
end if
65
66
Object.XVelocity = Object[ArrayPos0].XPos
67
Object.XVelocity -= Object.XPos
68
Object.XVelocity /= Object.Timer
69
70
Object.ZVelocity = Object[ArrayPos0].ZPos
71
Object.ZVelocity -= Object.ZPos
72
Object.ZVelocity /= Object.Timer
73
else
74
// Following a node - just update movement for now
75
76
Object.Timer--
77
Object.XPos += Object.XVelocity
78
Object.ZPos += Object.ZVelocity
79
end if
80
81
// Check player interaction in this (rather lengthy) process
82
83
// X difference
84
TempValue0 = Object.XPos
85
TempValue0 -= TileLayer[0].XPos
86
TempValue0 >>= 8
87
88
// Z mutliplier
89
TempValue1 = Object.ZPos
90
TempValue1 -= TileLayer[0].ZPos
91
TempValue1 >>= 8
92
93
// Calculating the X difference
94
Sin(TempValue2, TileLayer[0].Angle)
95
TempValue2 *= TempValue1
96
Cos(TempValue3, TileLayer[0].Angle)
97
TempValue3 *= TempValue0
98
Object.ScreenXPos = TempValue2
99
Object.ScreenXPos -= TempValue3
100
Object.ScreenXPos >>= 9
101
102
// Calculating the Z difference
103
Cos(TempValue2, TileLayer[0].Angle)
104
TempValue2 *= TempValue1
105
Sin(TempValue3, TileLayer[0].Angle)
106
TempValue3 *= TempValue0
107
Object.ScreenDepth = TempValue2
108
Object.ScreenDepth += TempValue3
109
Object.ScreenDepth >>= 9
110
111
// Long list of checks for the hitbox detection
112
113
// The Player has to be more than 54 pixels off the ground, but lower than 122 pixels towards the sky
114
if Player.YPos > 0x360000
115
if Player.YPos < 0x7A0000
116
117
// The UFO has to be within the 2100 range from the player, who's at a depth of 0x5800 normally
118
if Object.ScreenDepth < 0x58C8
119
if Object.ScreenDepth > 0x5094
120
121
// The UFO has to be between -0.125 and +0.125 pixels away from the screen centre
122
if Object.ScreenXPos > -0x2000
123
if Object.ScreenXPos < 0x2000
124
125
// All those checks passed, let's destroy this UFO!
126
127
TempValue0 = Object.ScreenXPos
128
TempValue0 *= 192
129
TempValue0 /= Object.ScreenDepth
130
TempValue0 += Screen.CenterX
131
TempValue0 <<= 16
132
133
TempValue1 = TileLayer[0].YPos
134
TempValue1 >>= 8
135
TempValue1 -= 0x6000
136
TempValue1 *= 96
137
TempValue1 /= Object.ScreenDepth
138
TempValue1 += 128
139
TempValue1 <<= 16
140
141
// Play the ring SFX
142
PlaySfx(SFX_G_RING, false)
143
144
#platform: Use_Haptics
145
// Do shake index 55 to really sell the impact of hitting a floating UFO
146
HapticEffect(55, 0, 0, 0)
147
#endplatform
148
149
switch Object.PropertyValue
150
case UFO_CONTENTS_RINGS
151
// Decrease the UFO count and give some bonus rings
152
HUD[4].UFOsCount--
153
if HUD[4].LastUFOType == Object.PropertyValue
154
// If the last UFO caught was a rings variant too, then double the player's rings rather than adding 20
155
HUD[4].Rings <<= 1
156
else
157
HUD[4].Rings += 20
158
end if
159
break
160
161
case UFO_CONTENTS_SPEEDSHOES
162
// Decrease the UFO count and give the player some new faster shoes
163
HUD[4].UFOsCount--
164
HUD[4].SpeedShoesTimer = 600
165
break
166
167
case UFO_CONTENTS_TIME
168
// Aadd some time to the clock
169
// (Not decreasing the UFO count because time UFOs don't count towards the whole)
170
HUD[4].TimeSeconds += 30
171
break
172
173
end switch
174
175
HUD[4].LastUFOType = Object.PropertyValue
176
177
// Create the UFO powerup icon
178
CreateTempObject(TypeName[UFO PowerUp], Object.PropertyValue, TempValue0, TempValue1)
179
Rand(UFOPowerUp[TempObjectPos].ExplosionDir, 100)
180
UFOPowerUp[TempObjectPos].ExplosionXVel = TempValue0
181
UFOPowerUp[TempObjectPos].ExplosionYVel = TempValue1
182
UFOPowerUp[TempObjectPos].YVelocity = -0x40000
183
UFOPowerUp[TempObjectPos].ScreenDepth = 0x58C8
184
185
// If the last UFO was just destroyed, then signal that to the PowerUp object too
186
if HUD[4].UFOsCount == 0
187
UFOPowerUp[TempObjectPos].StartResults = true
188
end if
189
190
// Blank this UFO object since it's been
191
ResetObjectEntity(Object.EntityNo, TypeName[Blank Object], 0, 0, 0)
192
193
// And now, close a whole lotta end if's...
194
195
end if
196
end if
197
end if
198
end if
199
end if
200
end if
201
202
end sub
203
204
205
sub ObjectDraw
206
if Object.ScreenDepth > 256 // Don't draw if the UFO is too close to the screen
207
208
// Do some maths to find the position & scale the UFO should be at
209
210
Object.Scale = 0xC00000
211
Object.Scale /= Object.ScreenDepth
212
213
TempValue0 = 768
214
TempValue0 -= Object.Scale
215
TempValue0 /= 6
216
217
TempValue1 = Object.ScreenDepth
218
TempValue1 >>= 12
219
220
if TempValue0 > 0
221
Object.Scale += TempValue0
222
Object.Scale -= TempValue1
223
end if
224
225
TempValue0 = Object.ScreenXPos
226
TempValue0 *= 192
227
TempValue0 /= Object.ScreenDepth
228
TempValue0 += Screen.CenterX
229
230
TempValue1 = TileLayer[0].YPos
231
TempValue1 >>= 8
232
TempValue1 -= 0x6000
233
TempValue1 *= 96
234
TempValue1 /= Object.ScreenDepth
235
TempValue1 += 128
236
237
// Draw the UFO now
238
DrawSpriteScreenFX(Object.PropertyValue, FX_SCALE, TempValue0, TempValue1)
239
240
// Find the ground position
241
TempValue1 = TileLayer[0].YPos
242
TempValue1 >>= 8
243
TempValue1 *= 96
244
TempValue1 /= Object.ScreenDepth
245
TempValue1 += 128
246
247
// Draw the shadow on the ground
248
DrawSpriteScreenFX(3, FX_SCALE, TempValue0, TempValue1)
249
250
end if
251
252
end sub
253
254
255
sub ObjectStartup
256
257
LoadSpriteSheet("Special/Objects.gif")
258
259
// UFO Frames
260
261
// 0 - 10 Rings Variant
262
SpriteFrame(-40, -28, 80, 56, 1, 1)
263
264
// 1 - Speed Shoes Variant
265
SpriteFrame(-40, -28, 80, 56, 82, 1)
266
267
// 2 - Extra Time Variant
268
SpriteFrame(-40, -28, 80, 56, 163, 1)
269
270
// 3 - UFO Shadow Frame
271
SpriteFrame(-40, -8, 80, 16, 1, 117)
272
273
// Cycle through all UFO objects in the scene and set them up
274
ArrayPos0 = 32
275
while ArrayPos0 < 1056
276
if Object[ArrayPos0].Type == TypeName[UFO]
277
278
// Set the UFO to always be active
279
Object[ArrayPos0].Priority = PRIORITY_ACTIVE
280
281
if Object[ArrayPos0].PropertyValue < 2
282
283
// Increase the UFO count
284
HUD[4].UFOsCount++
285
286
else
287
288
// Bonus UFO Spawn point, delete the UFO for right now and store its EntityPos into the HUD value
289
// (We need to make sure the Time UFO is spawned in the correct slot because of its Nodes)
290
291
Object[ArrayPos0].Type = TypeName[Blank Object]
292
HUD[4].BonusUFONo = ArrayPos0
293
294
end if
295
end if
296
297
ArrayPos0++
298
loop
299
300
end sub
301
302
303
// ========================
304
// Editor Subs
305
// ========================
306
307
sub RSDKEdit
308
if Editor.ReturnVariable == true
309
switch Editor.VariableID
310
case EDIT_VAR_PROPVAL // Property Value
311
CheckResult = Object.PropertyValue
312
break
313
case 0 // Contents
314
CheckResult = Object.PropertyValue
315
break
316
end switch
317
else
318
switch Editor.VariableID
319
case EDIT_VAR_PROPVAL // Property Value
320
Object.PropertyValue = Editor.VariableValue
321
break
322
case 0 // Contents
323
Object.PropertyValue = Editor.VariableValue
324
break
325
end switch
326
end if
327
end sub
328
329
330
sub RSDKDraw
331
DrawSprite(Object.PropertyValue)
332
333
if Editor.ShowGizmos == true
334
// Draw arrows to show the network of UFO nodes
335
336
Editor.DrawingOverlay = true
337
338
ArrayPos1 = Object.EntityNo
339
ArrayPos0 = Object.EntityNo
340
ArrayPos0++
341
342
// TODO: change this to "UFO Node" once GetObjectType works with spaces
343
GetObjectType(TempValue0, "UFONode")
344
345
while Object[ArrayPos0].Type == TempValue0
346
DrawArrow(Object[ArrayPos1].XPos, Object[ArrayPos1].ZPos, Object[ArrayPos0].XPos, Object[ArrayPos0].ZPos, 255, 255, 0)
347
ArrayPos0++
348
ArrayPos1++
349
loop
350
351
ArrayPos0 = Object.EntityNo
352
ArrayPos0++
353
if ArrayPos1 != Object.EntityNo
354
DrawArrow(Object[ArrayPos1].XPos, Object[ArrayPos1].ZPos, Object[ArrayPos0].XPos, Object[ArrayPos0].ZPos, 255, 255, 0)
355
end if
356
357
Editor.DrawingOverlay = false
358
end if
359
end sub
360
361
362
sub RSDKLoad
363
LoadSpriteSheet("Special/Objects.gif")
364
SpriteFrame(-40, -28, 80, 56, 1, 1)
365
SpriteFrame(-40, -28, 80, 56, 82, 1)
366
SpriteFrame(-40, -28, 80, 56, 163, 1)
367
368
AddEditorVariable("Contents")
369
SetActiveVariable("Contents")
370
AddEnumVariable("10 Rings", UFO_CONTENTS_RINGS)
371
AddEnumVariable("Speed Shoes", UFO_CONTENTS_SPEEDSHOES)
372
AddEnumVariable("Extra Time", UFO_CONTENTS_TIME)
373
end sub
374
375