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/Crawlton.txt
1483 views
1
// ----------------------------------
2
// RSDK Project: Sonic 2
3
// Script Description: Crawlton 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.timer
13
private alias object.value1 : object.extend.length
14
private alias object.value2 : object.extend.x
15
private alias object.value3 : object.extend.y
16
private alias object.value4 : object.head.x
17
private alias object.value5 : object.head.y
18
private alias object.value6 : object.target.distance
19
private alias object.value7 : object.target.entityPos
20
21
// States
22
private alias 0 : CRAWLTON_AWAITPLAYER
23
private alias 1 : CRAWLTON_EXTENDDELAY
24
private alias 2 : CRAWLTON_EXTEND
25
private alias 3 : CRAWLTON_RETRACTDELAY
26
private alias 4 : CRAWLTON_RETRACT
27
28
// Player Aliases
29
private alias object.xpos : player.xpos
30
private alias object.ypos : player.ypos
31
32
private alias object.value40 : player.hitboxLeft
33
private alias object.value38 : player.hitboxTop
34
private alias object.value41 : player.hitboxRight
35
private alias object.value39 : player.hitboxBottom
36
37
38
// ========================
39
// Function Declarations
40
// ========================
41
42
reserve function Crawlton_DebugDraw
43
reserve function Crawlton_DebugSpawn
44
reserve function Crawlton_CheckPlayerDist
45
46
47
// ========================
48
// Function Definitions
49
// ========================
50
51
private function Crawlton_DebugDraw
52
DrawSpriteFX(0, FX_FLIP, object.xpos, object.ypos)
53
end function
54
55
56
private function Crawlton_DebugSpawn
57
CreateTempObject(TypeName[Crawlton], 0, object.xpos, object.ypos)
58
end function
59
60
61
private function Crawlton_CheckPlayerDist
62
// This function calculates the total distance of player from Crawlton,
63
// `object.target.distance` is like the function's "return value" of sorts
64
65
temp0 = player[currentPlayer].xpos
66
temp0 -= object.xpos
67
temp0 >>= 16
68
object.target.distance = temp0
69
object.target.distance *= temp0
70
71
temp0 = player[currentPlayer].ypos
72
temp0 -= object.ypos
73
temp0 >>= 16
74
temp1 = temp0
75
temp1 *= temp0
76
77
object.target.distance += temp1
78
end function
79
80
81
// ========================
82
// Events
83
// ========================
84
85
event ObjectUpdate
86
switch object.state
87
case CRAWLTON_AWAITPLAYER
88
foreach (GROUP_PLAYERS, currentPlayer, ACTIVE_ENTITIES)
89
if object.state == CRAWLTON_AWAITPLAYER // It may seem redundant with the switch-case, but this is making sure a target player hasn't been found already from previous loops of this foreach
90
if player[currentPlayer].xpos < object.xpos
91
object.direction = FLIP_NONE
92
else
93
object.direction = FLIP_X
94
end if
95
96
CallFunction(Crawlton_CheckPlayerDist)
97
if object.target.distance < 0x4000
98
object.target.entityPos = currentPlayer
99
object.state = CRAWLTON_EXTENDDELAY
100
end if
101
end if
102
next
103
break
104
105
case CRAWLTON_EXTENDDELAY
106
currentPlayer = object.target.entityPos
107
108
// Turn to face the target player if needed
109
if player[currentPlayer].xpos < object.xpos
110
object.direction = FLIP_NONE
111
else
112
object.direction = FLIP_X
113
end if
114
115
object.timer++
116
if object.timer == 32
117
CallFunction(Crawlton_CheckPlayerDist)
118
if object.target.distance < 0x4000
119
object.extend.x = player[currentPlayer].xpos
120
object.extend.x -= object.xpos
121
object.extend.x /= 0x12000
122
123
object.extend.y = player[currentPlayer].ypos
124
object.extend.y -= object.ypos
125
object.extend.y /= 0x12000
126
else
127
temp0 = player[currentPlayer].xpos
128
temp0 -= object.xpos
129
130
temp1 = player[currentPlayer].ypos
131
temp1 -= object.ypos
132
133
ATan2(temp2, temp0, temp1)
134
135
Cos256(object.extend.x, temp2)
136
Sin256(object.extend.y, temp2)
137
138
object.extend.x *= 224
139
object.extend.y *= 224
140
141
object.extend.x >>= 9
142
object.extend.y >>= 9
143
end if
144
145
object.timer = 0
146
object.state = CRAWLTON_EXTEND
147
end if
148
break
149
150
case CRAWLTON_EXTEND
151
if object.extend.length < 0x1C0000
152
object.extend.length += 0x10000
153
else
154
object.state = CRAWLTON_RETRACTDELAY
155
end if
156
break
157
158
case CRAWLTON_RETRACTDELAY
159
object.timer++
160
if object.timer == 32
161
object.timer = 0
162
object.state = CRAWLTON_RETRACT
163
end if
164
break
165
166
case CRAWLTON_RETRACT
167
if object.extend.length > 0
168
object.extend.length -= 0x10000
169
else
170
object.state = CRAWLTON_AWAITPLAYER
171
end if
172
break
173
174
end switch
175
176
// Calculate head position
177
object.head.x = object.extend.x
178
object.head.x *= object.extend.length
179
object.head.x /= 28
180
object.head.x += object.xpos
181
182
object.head.y = object.extend.y
183
object.head.y *= object.extend.length
184
object.head.y /= 28
185
object.head.y += object.ypos
186
187
// Backup the object position and move the object to its head pos for collision checks
188
temp6 = object.xpos
189
temp7 = object.ypos
190
191
object.xpos = object.head.x
192
object.ypos = object.head.y
193
194
foreach (GROUP_PLAYERS, currentPlayer, ACTIVE_ENTITIES)
195
BoxCollisionTest(C_TOUCH, object.entityPos, -10, -8, 10, 8, currentPlayer, player[currentPlayer].hitboxLeft, player[currentPlayer].hitboxTop, player[currentPlayer].hitboxRight, player[currentPlayer].hitboxBottom)
196
197
if checkResult == true
198
CallFunction(Player_BadnikBreak)
199
end if
200
next
201
202
// If the badnik was broken it'd be an Animal object now, which is why this check is here to
203
// make sure the Freed Animal doesn't teleport
204
if object.type == TypeName[Crawlton]
205
// The object is still a Crawlton, it's safe to move it back
206
object.xpos = temp6
207
object.ypos = temp7
208
if object.outOfBounds == true
209
// Dunno why this condition is here though, if it's just empty
210
end if
211
end if
212
end event
213
214
215
event ObjectDraw
216
// Draw a body piece at the object base regardless of state
217
DrawSpriteFX(1, FX_FLIP, object.xpos, object.ypos)
218
219
// Then, draw extra body pieces depending on what the Crawlton is doing
220
switch object.state
221
case CRAWLTON_EXTEND
222
temp0 = object.extend.length
223
temp0 &= 0x3FFFF
224
while temp0 < object.extend.length
225
temp1 = object.extend.x
226
temp1 *= temp0
227
temp1 /= 28
228
temp1 += object.xpos
229
230
temp2 = object.extend.y
231
temp2 *= temp0
232
temp2 /= 28
233
temp2 += object.ypos
234
235
DrawSpriteFX(1, FX_FLIP, temp1, temp2)
236
temp0 += 0x40000
237
loop
238
break
239
240
case CRAWLTON_RETRACTDELAY
241
case CRAWLTON_RETRACT
242
temp0 = 0x40000
243
while temp0 < object.extend.length
244
temp1 = object.extend.x
245
temp1 *= temp0
246
temp1 /= 28
247
temp1 += object.xpos
248
249
temp2 = object.extend.y
250
temp2 *= temp0
251
temp2 /= 28
252
temp2 += object.ypos
253
254
DrawSpriteFX(1, FX_FLIP, temp1, temp2)
255
temp0 += 0x40000
256
loop
257
break
258
259
end switch
260
261
// And draw the head regardless of state too
262
DrawSpriteFX(0, FX_FLIP, object.head.x, object.head.y)
263
end event
264
265
266
event ObjectStartup
267
CheckCurrentStageFolder("Zone06")
268
if checkResult == true
269
LoadSpriteSheet("MCZ/Objects.gif")
270
SpriteFrame(-16, -8, 24, 16, 152, 114) // 0 - Head Frame
271
SpriteFrame(-8, -8, 16, 15, 135, 114) // 1 - Body Frame
272
else
273
// Note - even if these are spriteframes for MBZ, they're broken with values copied directly from MCZ's sheet
274
// Using these sheet positions results in the middle of CPZ's chemical dropper and CNZ's boss electricity
275
LoadSpriteSheet("MBZ/Objects.gif")
276
SpriteFrame(-16, -8, 24, 16, 152, 114)
277
SpriteFrame(-8, -8, 16, 15, 135, 114)
278
end if
279
280
SetTableValue(TypeName[Crawlton], DebugMode_ObjCount, DebugMode_TypesTable)
281
SetTableValue(Crawlton_DebugDraw, DebugMode_ObjCount, DebugMode_DrawTable)
282
SetTableValue(Crawlton_DebugSpawn, DebugMode_ObjCount, DebugMode_SpawnTable)
283
DebugMode_ObjCount++
284
end event
285
286
287
// ========================
288
// Editor Events
289
// ========================
290
291
event RSDKDraw
292
DrawSpriteFX(1, FX_FLIP, object.xpos, object.ypos)
293
DrawSpriteFX(0, FX_FLIP, object.xpos, object.ypos)
294
end event
295
296
297
event RSDKLoad
298
CheckCurrentStageFolder("Zone06")
299
if checkResult == true
300
LoadSpriteSheet("MCZ/Objects.gif")
301
SpriteFrame(-16, -8, 24, 16, 152, 114)
302
SpriteFrame(-8, -8, 16, 15, 135, 114)
303
else
304
LoadSpriteSheet("MBZ/Objects.gif")
305
// Decomp note - using fixed frames here
306
SpriteFrame(-16, -8, 24, 16, 534, 289)
307
SpriteFrame(-8, -8, 16, 15, 559, 289)
308
end if
309
310
SetVariableAlias(ALIAS_VAR_PROPVAL, "unused")
311
end event
312
313