Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rubberduckycooly
GitHub Repository: rubberduckycooly/Sonic-Mania-Decompilation
Path: blob/master/SonicMania/Objects/GHZ/Motobug.c
338 views
1
// ---------------------------------------------------------------------
2
// RSDK Project: Sonic Mania
3
// Object Description: Motobug Object
4
// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges
5
// Decompiled by: Rubberduckycooly & RMGRich
6
// ---------------------------------------------------------------------
7
8
#include "Game.h"
9
10
ObjectMotobug *Motobug;
11
12
void Motobug_Update(void)
13
{
14
RSDK_THIS(Motobug);
15
StateMachine_Run(self->state);
16
}
17
18
void Motobug_LateUpdate(void) {}
19
20
void Motobug_StaticUpdate(void) {}
21
22
void Motobug_Draw(void)
23
{
24
RSDK_THIS(Motobug);
25
RSDK.DrawSprite(&self->animator, NULL, false);
26
}
27
28
void Motobug_Create(void *data)
29
{
30
RSDK_THIS(Motobug);
31
self->visible = true;
32
self->drawFX |= FX_FLIP;
33
self->drawGroup = Zone->objectDrawGroup[0];
34
self->startPos = self->position;
35
self->startDir = self->direction;
36
self->active = ACTIVE_BOUNDS;
37
self->updateRange.x = 0x800000;
38
self->updateRange.y = 0x800000;
39
self->wasTurning = true;
40
41
if (data) {
42
RSDK.SetSpriteAnimation(Motobug->aniFrames, 3, &self->animator, true, 0);
43
self->state = Motobug_State_Smoke;
44
}
45
else {
46
self->timer = 16;
47
RSDK.SetSpriteAnimation(Motobug->aniFrames, 0, &self->animator, true, 0);
48
self->state = Motobug_State_Init;
49
}
50
}
51
52
void Motobug_StageLoad(void)
53
{
54
if (RSDK.CheckSceneFolder("GHZ"))
55
Motobug->aniFrames = RSDK.LoadSpriteAnimation("GHZ/Motobug.bin", SCOPE_STAGE);
56
else if (RSDK.CheckSceneFolder("Blueprint"))
57
Motobug->aniFrames = RSDK.LoadSpriteAnimation("Blueprint/Motobug.bin", SCOPE_STAGE);
58
59
Motobug->hitboxBadnik.left = -14;
60
Motobug->hitboxBadnik.top = -14;
61
Motobug->hitboxBadnik.right = 14;
62
Motobug->hitboxBadnik.bottom = 14;
63
64
DEBUGMODE_ADD_OBJ(Motobug);
65
}
66
67
void Motobug_DebugDraw(void)
68
{
69
RSDK.SetSpriteAnimation(Motobug->aniFrames, 0, &DebugMode->animator, true, 0);
70
RSDK.DrawSprite(&DebugMode->animator, NULL, false);
71
}
72
void Motobug_DebugSpawn(void)
73
{
74
RSDK_THIS(DebugMode);
75
76
CREATE_ENTITY(Motobug, NULL, self->position.x, self->position.y);
77
}
78
void Motobug_CheckOffScreen(void)
79
{
80
RSDK_THIS(Motobug);
81
82
if (!RSDK.CheckOnScreen(self, NULL) && !RSDK.CheckPosOnScreen(&self->startPos, &self->updateRange)) {
83
self->position = self->startPos;
84
self->direction = self->startDir;
85
Motobug_Create(NULL);
86
}
87
}
88
void Motobug_CheckPlayerCollisions(void)
89
{
90
RSDK_THIS(Motobug);
91
92
foreach_active(Player, player)
93
{
94
if (Player_CheckBadnikTouch(player, self, &Motobug->hitboxBadnik))
95
Player_CheckBadnikBreak(player, self, true);
96
}
97
}
98
void Motobug_State_Fall(void)
99
{
100
RSDK_THIS(Motobug);
101
102
RSDK.ProcessAnimation(&self->animator);
103
104
if (self->wasTurning)
105
self->position.x += self->velocity.x;
106
107
self->position.y += self->velocity.y;
108
self->velocity.y += 0x3800;
109
110
if (RSDK.ObjectTileGrip(self, Zone->collisionLayers, CMODE_FLOOR, 0, 0, 0xF0000, 8)) {
111
self->wasTurning = true;
112
self->velocity.y = 0;
113
RSDK.SetSpriteAnimation(Motobug->aniFrames, 0, &self->animator, true, 0);
114
self->state = Motobug_State_Move;
115
Motobug_State_Move();
116
}
117
else {
118
Motobug_CheckPlayerCollisions();
119
Motobug_CheckOffScreen();
120
}
121
}
122
void Motobug_State_Move(void)
123
{
124
RSDK_THIS(Motobug);
125
126
self->position.x += self->velocity.x;
127
128
if (!RSDK.ObjectTileGrip(self, Zone->collisionLayers, CMODE_FLOOR, 0, 0, 0xF0000, 8)) {
129
RSDK.SetSpriteAnimation(Motobug->aniFrames, 1, &self->animator, true, 0);
130
self->turnTimer = 0;
131
132
bool32 collided = false;
133
if (self->direction)
134
collided = RSDK.ObjectTileGrip(self, Zone->collisionLayers, CMODE_FLOOR, 0, -0x10000, 0xF0000, 8);
135
else
136
collided = RSDK.ObjectTileGrip(self, Zone->collisionLayers, CMODE_FLOOR, 0, 0x10000, 0xF0000, 8);
137
138
if (collided)
139
self->state = Motobug_State_Idle;
140
else
141
self->state = Motobug_State_Fall;
142
}
143
144
if (!--self->timer) {
145
self->timer = 16;
146
EntityMotobug *smoke = CREATE_ENTITY(Motobug, INT_TO_VOID(true), self->position.x, self->position.y);
147
if (self->direction == FLIP_X)
148
smoke->position.x -= 0x140000;
149
else
150
smoke->position.x += 0x140000;
151
}
152
153
RSDK.ProcessAnimation(&self->animator);
154
155
Motobug_CheckPlayerCollisions();
156
Motobug_CheckOffScreen();
157
}
158
void Motobug_State_Idle(void)
159
{
160
RSDK_THIS(Motobug);
161
162
RSDK.ProcessAnimation(&self->animator);
163
164
bool32 collided = false;
165
if (self->direction)
166
collided = RSDK.ObjectTileGrip(self, Zone->collisionLayers, CMODE_FLOOR, 0, -0x10000, 0xF0000, 8);
167
else
168
collided = RSDK.ObjectTileGrip(self, Zone->collisionLayers, CMODE_FLOOR, 0, 0x10000, 0xF0000, 8);
169
170
if (collided) {
171
++self->turnTimer;
172
if (self->turnTimer == 30) {
173
RSDK.SetSpriteAnimation(Motobug->aniFrames, 2, &self->animator, true, 0);
174
self->state = Motobug_State_Turn;
175
}
176
}
177
else {
178
self->wasTurning = false;
179
RSDK.SetSpriteAnimation(Motobug->aniFrames, 0, &self->animator, true, 0);
180
self->state = Motobug_State_Fall;
181
self->direction ^= FLIP_X;
182
self->velocity.x = -self->velocity.x;
183
}
184
185
Motobug_CheckPlayerCollisions();
186
Motobug_CheckOffScreen();
187
}
188
void Motobug_State_Init(void)
189
{
190
RSDK_THIS(Motobug);
191
192
self->active = ACTIVE_NORMAL;
193
self->velocity.x = -0x10000;
194
self->velocity.y = 0;
195
196
self->state = Motobug_State_Move;
197
Motobug_State_Move();
198
}
199
void Motobug_State_Smoke(void)
200
{
201
RSDK_THIS(Motobug);
202
203
RSDK.ProcessAnimation(&self->animator);
204
205
if (self->animator.frameID == self->animator.frameCount - 1)
206
destroyEntity(self);
207
}
208
void Motobug_State_Turn(void)
209
{
210
RSDK_THIS(Motobug);
211
212
RSDK.ProcessAnimation(&self->animator);
213
214
bool32 collided = false;
215
if (self->direction)
216
collided = RSDK.ObjectTileGrip(self, Zone->collisionLayers, CMODE_FLOOR, 0, -0x10000, 0xF0000, 8);
217
else
218
collided = RSDK.ObjectTileGrip(self, Zone->collisionLayers, CMODE_FLOOR, 0, 0x10000, 0xF0000, 8);
219
220
if (collided) {
221
if (self->animator.frameID == self->animator.frameCount - 1) {
222
RSDK.SetSpriteAnimation(Motobug->aniFrames, 0, &self->animator, true, 0);
223
self->direction ^= FLIP_X;
224
self->velocity.x = -self->velocity.x;
225
self->state = Motobug_State_Move;
226
Motobug_State_Move();
227
}
228
else {
229
Motobug_CheckPlayerCollisions();
230
Motobug_CheckOffScreen();
231
}
232
}
233
else {
234
self->wasTurning = false;
235
RSDK.SetSpriteAnimation(Motobug->aniFrames, 0, &self->animator, true, 0);
236
self->state = Motobug_State_Fall;
237
self->direction ^= FLIP_X;
238
self->velocity.x = -self->velocity.x;
239
}
240
}
241
242
#if GAME_INCLUDE_EDITOR
243
void Motobug_EditorDraw(void) { Motobug_Draw(); }
244
245
void Motobug_EditorLoad(void)
246
{
247
if (RSDK.CheckSceneFolder("GHZ"))
248
Motobug->aniFrames = RSDK.LoadSpriteAnimation("GHZ/Motobug.bin", SCOPE_STAGE);
249
else if (RSDK.CheckSceneFolder("Blueprint"))
250
Motobug->aniFrames = RSDK.LoadSpriteAnimation("Blueprint/Motobug.bin", SCOPE_STAGE);
251
}
252
#endif
253
254
void Motobug_Serialize(void) {}
255
256