Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rubberduckycooly
GitHub Repository: rubberduckycooly/Sonic-CD-2011-Script-Decompilation
Path: blob/main/Scripts/R7/Kanabun.txt
1319 views
1
//------------------Sonic CD Kanabun Script-------------------//
2
//--------Scripted by Christian Whitehead 'The Taxman'--------//
3
//-------Unpacked By Rubberduckycooly's Script Unpacker-------//
4
5
// Aliases
6
#alias Object.Value0 : Object.Timer
7
#alias Object.Value1 : Object.Angle
8
#alias Object.Value2 : Object.StartPosX
9
#alias Object.Value3 : Object.StartPosY
10
#alias Object.Value4 : Object.Depth
11
#alias Object.Value5 : Object.ReturnDrawOrder
12
13
#alias Object.PropertyValue : Object.Quality
14
15
// States
16
#alias 0 : KANABUN_FLYL
17
#alias 1 : KANABUN_FLYR
18
#alias 2 : KANABUN_OFFSCREEN
19
20
// Badnik Quality / Property Values
21
#alias 0 : GOOD_QUALITY
22
#alias 1 : BAD_QUALITY
23
#alias 2 : HIGH_LAYER_GOOD
24
25
// Priority
26
#alias 0 : PRIORITY_BOUNDS
27
#alias 1 : PRIORITY_ACTIVE
28
29
30
sub ObjectMain
31
if Object.OutOfBounds == true
32
Object.State = KANABUN_OFFSCREEN
33
Object.Timer = 0
34
Object.Angle = 256
35
Object.Direction = FACING_RIGHT
36
Object.XPos = Object.StartPosX
37
Object.YPos = Object.StartPosY
38
end if
39
40
// The different Kanabun types have their own main update routines
41
// However, their main State Switches are exactly the same, it's only the small bit of code after that differs between the two
42
43
if Object.Quality == GOOD_QUALITY
44
switch Object.State
45
case KANABUN_FLYL
46
// This Kanabun is initially given always-active priority, in order for its OOB state to work properly
47
Object.Priority = PRIORITY_ACTIVE
48
49
// Move left at a rate of 0.25 pixels per frame
50
Object.XPos -= 0x4000
51
52
Object.Timer++
53
if Object.Timer == 256
54
// Turn around
55
56
Object.State = KANABUN_FLYR
57
Object.Direction = FACING_LEFT
58
end if
59
break
60
61
case KANABUN_FLYR
62
// When entering this state, it is assumed that Object.Timer is already 256
63
64
// Move right, still at a rate of 0.25 pixels per frame
65
Object.XPos += 0x4000
66
67
Object.Timer--
68
if Object.Timer == 0
69
// Turn back around again
70
71
Object.State = KANABUN_FLYL
72
Object.Direction = FACING_RIGHT
73
end if
74
break
75
76
case KANABUN_OFFSCREEN
77
// Buffer state to hold the Kanabun if it went off-screen
78
if Object.OutOfBounds == true
79
Object.State = KANABUN_FLYL
80
81
// It's safe to give it normal priority again
82
Object.Priority = PRIORITY_BOUNDS
83
end if
84
break
85
86
end switch
87
88
// Update the Kanabun's movement angle
89
Object.Angle += 4
90
Object.Angle &= 511
91
92
// And animate it, too
93
Object.Frame = Object.AnimationTimer
94
Object.Frame >>= 1
95
96
Object.AnimationTimer++
97
Object.AnimationTimer &= 3
98
else
99
switch Object.State
100
case KANABUN_FLYL
101
// Give the Kanabun active priority so that its offscreen state will work fine when needed
102
//(or else the object will go offscreen and immediately pause, not returning to its original position)
103
Object.Priority = PRIORITY_ACTIVE
104
105
// Go left at a rate of 0.25 pixels per frame
106
Object.XPos -= 0x4000
107
108
Object.Timer++
109
if Object.Timer == 256
110
// Turn the other way
111
Object.State = KANABUN_FLYR
112
Object.Direction = FACING_LEFT
113
end if
114
break
115
116
case KANABUN_FLYR
117
// Object.Timer is assumed to be 256 when going into this state
118
119
// Go right at a rate of 0.25 pixels per frame
120
Object.XPos += 0x4000
121
122
Object.Timer--
123
if Object.Timer == 0
124
// Turn the right way again
125
Object.State = KANABUN_FLYL
126
Object.Direction = FACING_RIGHT
127
end if
128
break
129
130
case KANABUN_OFFSCREEN
131
// Buffer state to hold the Kanabun if it went off-screen
132
if Object.OutOfBounds == true
133
Object.State = KANABUN_FLYL
134
135
// And give the object normal priority again, too
136
Object.Priority = PRIORITY_BOUNDS
137
end if
138
break
139
140
end switch
141
142
Object.Angle += 2
143
Object.Angle &= 511
144
145
Object.Frame = Object.AnimationTimer
146
Object.Frame >>= 2
147
Object.Frame += 6
148
149
Object.AnimationTimer++
150
Object.AnimationTimer &= 7
151
end if
152
153
// Make the Kanabun move around, vertically
154
// Object.Depth is 0, 2, or 4, based on how into the background the Kanabun is
155
// 0 for FG, 4 for furthest in the BG
156
// These also correspond to Sprite Frames, with smaller sprites
157
158
Sin(Object.YPos, Object.Angle)
159
if Object.Angle < 128
160
Object.DrawOrder = 5
161
162
Object.Depth = 0
163
if Object.YPos < -384
164
Object.Depth = 2
165
end if
166
167
if Object.YPos > 384
168
Object.Depth = 2
169
end if
170
else
171
if Object.Angle > 384
172
Object.DrawOrder = 5
173
174
Object.Depth = 0
175
if Object.YPos < -384
176
Object.Depth = 2
177
end if
178
179
if Object.YPos > 384
180
Object.Depth = 2
181
end if
182
else
183
Object.DrawOrder = Object.ReturnDrawOrder
184
185
Object.Depth = 4
186
if Object.YPos < -384
187
Object.Depth = 2
188
end if
189
190
if Object.YPos > 384
191
Object.Depth = 2
192
end if
193
end if
194
end if
195
196
Object.Frame += Object.Depth
197
198
Object.YPos <<= 13
199
Object.YPos += Object.StartPosY
200
201
// See if the Kanabun should become a Flower instead
202
CallFunction(StageSetup_CheckGoodFuture)
203
204
end sub
205
206
207
sub ObjectPlayerInteraction
208
if Object.State < KANABUN_OFFSCREEN
209
if Object.Depth == 0
210
// If in the Foreground, then act as a normal badnik
211
#platform: Use_Standalone
212
PlayerObjectCollision(C_TOUCH, -14, -14, 14, 14)
213
#endplatform
214
#platform: Use_Origins
215
PlayerObjectCollision(C_ENEMY, -14, -14, 14, 14)
216
#endplatform
217
if CheckResult == true
218
CallFunction(Player_BadnikBreak)
219
end if
220
else
221
// If in the BG, only interact with the player if the player is curled
222
// (Don't want to damage them unfairly!)
223
224
if Player.Animation == ANI_JUMPING
225
#platform: Use_Standalone
226
PlayerObjectCollision(C_TOUCH, -14, -14, 14, 14)
227
#endplatform
228
#platform: Use_Origins
229
PlayerObjectCollision(C_ENEMY, -14, -14, 14, 14)
230
#endplatform
231
if CheckResult == true
232
CallFunction(Player_BadnikBreak)
233
end if
234
end if
235
end if
236
end if
237
238
end sub
239
240
241
sub ObjectDraw
242
if Object.State < KANABUN_OFFSCREEN
243
DrawSpriteFX(Object.Frame, FX_FLIP, Object.XPos, Object.YPos)
244
end if
245
end sub
246
247
248
sub ObjectStartup
249
LoadSpriteSheet("R7/Objects.gif")
250
251
// All these Sprite Frames are in sets of 2 for all the depth levels of the Kanabun
252
253
// "Good" Kanabun Frames
254
255
// Nearest to the screen
256
SpriteFrame(-16, -16, 32, 32, 1, 100)
257
SpriteFrame(-16, -16, 32, 32, 1, 133)
258
259
// Middle depth to the screen
260
SpriteFrame(-12, -12, 24, 24, 34, 71)
261
SpriteFrame(-12, -12, 27, 27, 62, 43)
262
263
// Furthest away from the screen
264
SpriteFrame(-12, -12, 24, 24, 59, 71)
265
SpriteFrame(-12, -12, 24, 24, 84, 71)
266
267
// "Bad" Kanabun Frames
268
269
// Closest to the screen
270
SpriteFrame(-16, -16, 32, 32, 1, 34)
271
SpriteFrame(-16, -16, 32, 32, 1, 67)
272
273
// Somewhat away from the screen
274
SpriteFrame(-12, -12, 24, 24, 34, 18)
275
SpriteFrame(-12, -12, 27, 27, 34, 43)
276
277
// Farthest away from the screen
278
SpriteFrame(-12, -12, 24, 24, 59, 18)
279
SpriteFrame(-12, -12, 24, 24, 84, 18)
280
281
// Find all Kanabun objects in the level
282
ArrayPos0 = 32
283
while ArrayPos0 < 1056
284
if Object[ArrayPos0].Type == TypeName[Kanabun]
285
286
// Make the Kanabun start halfway across its movement cycle, right in the middle
287
Object[ArrayPos0].Angle = 256
288
289
// Store the Kanabun's starating position, not only for object resetting but also for Y movement calculations
290
Object[ArrayPos0].StartPosX = Object[ArrayPos0].XPos
291
Object[ArrayPos0].StartPosY = Object[ArrayPos0].YPos
292
293
// And setup where the Kanabun's gonna fly back to, only the Good variant can go back to the higher layer
294
if Object[ArrayPos0].Quality == HIGH_LAYER_GOOD
295
Object[ArrayPos0].Quality = GOOD_QUALITY
296
Object[ArrayPos0].ReturnDrawOrder = 3
297
else
298
Object[ArrayPos0].ReturnDrawOrder = 2
299
end if
300
end if
301
302
ArrayPos0++
303
loop
304
305
end sub
306
307
308
// ========================
309
// Editor Subs
310
// ========================
311
312
sub RSDKEdit
313
if Editor.ReturnVariable == true
314
switch Editor.VariableID
315
case EDIT_VAR_PROPVAL // Property Value
316
CheckResult = Object.PropertyValue
317
break
318
case 0 // Condition
319
CheckResult = Object.PropertyValue
320
break
321
end switch
322
else
323
switch Editor.VariableID
324
case EDIT_VAR_PROPVAL // Property Value
325
Object.PropertyValue = Editor.VariableValue
326
break
327
case 0 // Condition
328
Object.PropertyValue = Editor.VariableValue
329
break
330
end switch
331
end if
332
end sub
333
334
335
sub RSDKDraw
336
DrawSprite(Object.PropertyValue)
337
end sub
338
339
340
sub RSDKLoad
341
LoadSpriteSheet("R7/Objects.gif")
342
SpriteFrame(-16, -16, 32, 32, 1, 100)
343
SpriteFrame(-16, -16, 32, 32, 1, 34)
344
SpriteFrame(-16, -16, 32, 32, 1, 100)
345
346
AddEditorVariable("Condition")
347
SetActiveVariable("Condition")
348
AddEnumVariable("Good", GOOD_QUALITY)
349
AddEnumVariable("Bad", BAD_QUALITY)
350
AddEnumVariable("Good (Return to high layer)", HIGH_LAYER_GOOD)
351
end sub
352
353