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/CNZ/Bumper.txt
1482 views
1
// ----------------------------------
2
// RSDK Project: Sonic 2
3
// Script Description: Bumper Object
4
// Script Author: Christian Whitehead/Simon Thomley
5
// Unpacked by Rubberduckycooly's script unpacker
6
// ----------------------------------
7
8
// Along with being used in Casino Night Zone, this Object is also used in Mission "Bounce House" - M036 - Mission_Zone09
9
// Do note, however, that in that stage this Object is given a name of `OBJECT NAME` instead, meaning all the `TypeName[Bumper]` uses
10
// you see here end up not working there
11
12
// ========================
13
// Aliases
14
// ========================
15
16
private alias object.value0 : object.timer
17
private alias object.value1 : object.bumpCount
18
private alias object.value2 : object.playerTimers
19
20
// States
21
private alias 0 : BUMPER_IDLE
22
private alias 1 : BUMPER_BUMPED
23
24
// Player Aliases
25
private alias object.state : player.state
26
private alias object.xpos : player.xpos
27
private alias object.ypos : player.ypos
28
private alias object.xvel : player.xvel
29
private alias object.yvel : player.yvel
30
private alias object.speed : player.speed
31
private alias object.gravity : player.gravity
32
private alias object.animation : player.animation
33
private alias object.tileCollisions : player.tileCollisions
34
private alias object.value1 : player.timer
35
private alias object.value16 : player.isSidekick // false if player 1, true if player 2
36
private alias object.value36 : player.flyCarryTimer // Tails assist lockout timer
37
private alias object.value40 : player.hitboxLeft
38
private alias object.value38 : player.hitboxTop
39
private alias object.value41 : player.hitboxRight
40
private alias object.value39 : player.hitboxBottom
41
42
// Global Variable ID Aliases
43
private alias 22 : GLOBAL_PLAYERSCORE
44
45
46
// ========================
47
// Function Declarations
48
// ========================
49
50
reserve function Bumper_DebugDraw
51
reserve function Bumper_DebugSpawn
52
53
54
// ========================
55
// Function Definitions
56
// ========================
57
58
private function Bumper_DebugDraw
59
DrawSprite(0)
60
end function
61
62
63
private function Bumper_DebugSpawn
64
CreateTempObject(TypeName[Bumper], 0, object.xpos, object.ypos)
65
object[tempObjectPos].drawOrder = 4
66
end function
67
68
69
// ========================
70
// Events
71
// ========================
72
73
event ObjectUpdate
74
if object.state > BUMPER_IDLE
75
object.frame = object.timer
76
object.frame /= 5
77
object.frame++
78
79
object.timer++
80
if object.timer > 15
81
object.timer = 0
82
object.state = BUMPER_IDLE
83
object.frame = 0
84
end if
85
end if
86
87
if object.outOfBounds == true
88
object.bumpCount = 0
89
object.priority = PRIORITY_BOUNDS
90
end if
91
92
temp7 = 0
93
foreach (GROUP_PLAYERS, currentPlayer, ACTIVE_ENTITIES)
94
temp6 = object.playerTimers
95
temp6 >>= temp7
96
temp6 &= 0xFF
97
if temp6 == false
98
#platform: USE_STANDALONE
99
if player[currentPlayer].animation != ANI_HURT
100
#endplatform
101
#platform: USE_ORIGINS
102
CheckNotEqual(player[currentPlayer].animation, ANI_HURT)
103
temp0 = checkResult
104
CheckNotEqual(player[currentPlayer].state, Player_State_Death)
105
temp0 &= checkResult
106
if temp0 != 0
107
#endplatform
108
BoxCollisionTest(C_TOUCH, object.entityPos, -7, -6, 7, 6, currentPlayer, player[currentPlayer].hitboxLeft, player[currentPlayer].hitboxTop, player[currentPlayer].hitboxRight, player[currentPlayer].hitboxBottom)
109
if checkResult == true
110
if object.state == BUMPER_IDLE
111
PlaySfx(SfxName[Bumper], false)
112
if object.bumpCount < 10
113
CreateTempObject(TypeName[Object Score], 16, object.xpos, object.ypos)
114
115
// global variable "array" (yes, this is actually how its done)
116
arrayPos0 = GLOBAL_PLAYERSCORE
117
#platform: USE_DECOMP
118
arrayPos0 = VarName[player.score]
119
#endplatform
120
if player[currentPlayer].isSidekick == false
121
arrayPos0 += currentPlayer
122
end if
123
global[arrayPos0] += 10
124
125
object.bumpCount++
126
end if
127
end if
128
129
if object.timer > 5
130
PlaySfx(SfxName[Bumper], false)
131
end if
132
133
object.state = BUMPER_BUMPED
134
object.priority = PRIORITY_ACTIVE
135
temp0 = player[currentPlayer].xpos
136
temp0 -= object.xpos
137
temp1 = player[currentPlayer].ypos
138
temp1 -= object.ypos
139
ATan2(temp2, temp0, temp1)
140
Cos256(temp0, temp2)
141
Sin256(temp1, temp2)
142
temp0 *= 0x700
143
temp1 *= 0x700
144
if player[currentPlayer].state == Player_State_Carried
145
player[1].flyCarryTimer = 30
146
end if
147
148
CheckEqual(player[currentPlayer].animation, ANI_GLIDING)
149
temp2 = checkResult
150
CheckEqual(player[currentPlayer].animation, ANI_GLIDING_STOP)
151
temp2 |= checkResult
152
CheckEqual(player[currentPlayer].animation, ANI_FLYING)
153
temp2 |= checkResult
154
CheckEqual(player[currentPlayer].state, Player_State_TubeRoll)
155
temp2 |= checkResult
156
CheckEqual(player[currentPlayer].state, Player_State_TubeAirRoll)
157
temp2 |= checkResult
158
if temp2 == false
159
#platform: USE_STANDALONE
160
player[currentPlayer].state = Player_State_Air
161
#endplatform
162
#platform: USE_ORIGINS
163
player[currentPlayer].state = Player_State_Air_NoDropDash
164
#endplatform
165
// Bug Details:
166
// This code wasn't updated in Origins Plus to include ANI_HAMMER_JUMP, so
167
// Amy will always start walking if she hits a Bumper with her hammer out
168
if player[currentPlayer].animation != ANI_JUMPING
169
if player[currentPlayer].animation != ANI_RUNNING
170
player[currentPlayer].animation = ANI_WALKING
171
end if
172
end if
173
end if
174
175
if player[currentPlayer].animation != ANI_GLIDING
176
player[currentPlayer].xvel = temp0
177
player[currentPlayer].speed = player[currentPlayer].xvel
178
player[currentPlayer].timer = 0
179
end if
180
181
player[currentPlayer].yvel = temp1
182
player[currentPlayer].gravity = GRAVITY_AIR
183
player[currentPlayer].tileCollisions = true
184
185
// 3 frame cooldown
186
temp6 = 3
187
temp6 <<= temp7
188
object.playerTimers |= temp6
189
end if
190
end if
191
else
192
// count down by 1 frame on the current player
193
temp5 = 1
194
temp5 <<= temp7
195
object.playerTimers -= temp5
196
end if
197
temp7 += 8
198
next
199
end event
200
201
202
event ObjectDraw
203
DrawSprite(object.frame)
204
end event
205
206
207
event ObjectStartup
208
CheckCurrentStageFolder("Zone04")
209
if checkResult == true
210
LoadSpriteSheet("CNZ/Objects.gif")
211
SpriteFrame(-16, -16, 32, 32, 148, 100)
212
SpriteFrame(-18, -18, 36, 36, 181, 100)
213
SpriteFrame(-16, -16, 32, 32, 148, 100)
214
SpriteFrame(-18, -18, 36, 36, 181, 100)
215
else
216
#platform: USE_ORIGINS
217
if game.playMode == BOOT_PLAYMODE_MISSION // Rather than just a "Zone09" check, check if it's Mission Mode as a whole instead
218
LoadSpriteSheet("MPZ/Objects2.gif")
219
SpriteFrame(-16, -16, 32, 32, 1, 1)
220
SpriteFrame(-18, -18, 36, 36, 34, 1)
221
SpriteFrame(-16, -16, 32, 32, 1, 1)
222
SpriteFrame(-18, -18, 36, 36, 34, 1)
223
else
224
#endplatform
225
LoadSpriteSheet("MBZ/Objects.gif")
226
SpriteFrame(-16, -16, 32, 32, 511, 339)
227
SpriteFrame(-18, -18, 36, 36, 544, 339)
228
SpriteFrame(-16, -16, 32, 32, 511, 339)
229
SpriteFrame(-18, -18, 36, 36, 544, 339)
230
#platform: USE_ORIGINS
231
end if
232
#endplatform
233
end if
234
235
// Bug Details:
236
// -> In Origins's MPZ "Bounce House" mission that uses this object, this foreach does not properly work
237
// This is because Bumpers are given the type name of [OBJECT NAME] instead, in that scene
238
// -> However, they did not update this foreach for that new name, which makes this TypeName invalid and resolve as 0 instead
239
// This means that not only do all Bumpers stay on Draw Order 3, but all Blank Objects get bumped up to 4 as well
240
foreach (TypeName[Bumper], arrayPos0, ALL_ENTITIES)
241
object[arrayPos0].drawOrder = 4
242
next
243
244
// Bug Details:
245
// -> This DebugMode_TypesTable entry doesn't work either in that same aforementioned scene,
246
// same reason here where it instead spawns an object with type ID 0 (Blank Object)
247
// -> Not too major at all but hey, I'm sure someone somewhere cares
248
SetTableValue(TypeName[Bumper], DebugMode_ObjCount, DebugMode_TypesTable)
249
SetTableValue(Bumper_DebugDraw, DebugMode_ObjCount, DebugMode_DrawTable)
250
SetTableValue(Bumper_DebugSpawn, DebugMode_ObjCount, DebugMode_SpawnTable)
251
DebugMode_ObjCount++
252
end event
253
254
255
// ========================
256
// Editor Events
257
// ========================
258
259
event RSDKDraw
260
DrawSprite(0)
261
end event
262
263
264
event RSDKLoad
265
CheckCurrentStageFolder("Zone04")
266
if checkResult == true
267
LoadSpriteSheet("CNZ/Objects.gif")
268
SpriteFrame(-16, -16, 32, 32, 148, 100)
269
else
270
CheckCurrentStageFolder("Zone09") // Technically not accurate to how it functions in-game, but we can't really replicate that behaviour either, so...
271
if checkResult == true
272
LoadSpriteSheet("MPZ/Objects2.gif")
273
SpriteFrame(-16, -16, 32, 32, 1, 1)
274
else
275
LoadSpriteSheet("MBZ/Objects.gif")
276
SpriteFrame(-16, -16, 32, 32, 511, 339)
277
end if
278
end if
279
280
SetVariableAlias(ALIAS_VAR_PROPVAL, "unused")
281
end event
282
283