Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rubberduckycooly
GitHub Repository: rubberduckycooly/Sonic-Mania-Decompilation
Path: blob/master/SonicMania/Objects/MSZ/Armadiloid.c
338 views
1
// ---------------------------------------------------------------------
2
// RSDK Project: Sonic Mania
3
// Object Description: Armadiloid Object
4
// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges
5
// Decompiled by: Rubberduckycooly & RMGRich
6
// ---------------------------------------------------------------------
7
8
#include "Game.h"
9
10
ObjectArmadiloid *Armadiloid;
11
12
void Armadiloid_Update(void)
13
{
14
RSDK_THIS(Armadiloid);
15
16
StateMachine_Run(self->state);
17
}
18
19
void Armadiloid_LateUpdate(void) {}
20
21
void Armadiloid_StaticUpdate(void) {}
22
23
void Armadiloid_Draw(void)
24
{
25
RSDK_THIS(Armadiloid);
26
27
RSDK.DrawSprite(&self->boosterAnimator, NULL, false);
28
RSDK.DrawSprite(&self->headAnimator, NULL, false);
29
RSDK.DrawSprite(&self->bodyAnimator, NULL, false);
30
}
31
32
void Armadiloid_Create(void *data)
33
{
34
RSDK_THIS(Armadiloid);
35
36
self->visible = true;
37
self->drawGroup = Zone->objectDrawGroup[0];
38
self->startPos = self->position;
39
self->drawFX = FX_FLIP;
40
self->active = ACTIVE_BOUNDS;
41
self->updateRange.x = 0x800000;
42
self->updateRange.y = 0x800000;
43
44
if (data)
45
self->type = ARMADILOID_RIDER;
46
47
if (self->type != ARMADILOID_SHOOTER) {
48
self->hitbox.left = -10;
49
self->hitbox.top = -40;
50
self->hitbox.right = 10;
51
self->hitbox.bottom = -20;
52
53
RSDK.SetSpriteAnimation(Armadiloid->aniFrames, 4, &self->bodyAnimator, true, 0);
54
}
55
else {
56
self->hitbox.left = -24;
57
self->hitbox.top = -15;
58
self->hitbox.right = 24;
59
self->hitbox.bottom = -7;
60
61
self->velocity.x = 0x8000;
62
RSDK.SetSpriteAnimation(Armadiloid->aniFrames, 0, &self->bodyAnimator, true, 0);
63
RSDK.SetSpriteAnimation(Armadiloid->aniFrames, 1, &self->headAnimator, true, 0);
64
RSDK.SetSpriteAnimation(Armadiloid->aniFrames, 3, &self->boosterAnimator, true, 0);
65
}
66
self->state = Armadiloid_State_Init;
67
}
68
69
void Armadiloid_StageLoad(void)
70
{
71
if (RSDK.CheckSceneFolder("MSZ"))
72
Armadiloid->aniFrames = RSDK.LoadSpriteAnimation("MSZ/Armadiloid.bin", SCOPE_STAGE);
73
74
DEBUGMODE_ADD_OBJ(Armadiloid);
75
76
Armadiloid->sfxShot = RSDK.GetSfx("Stage/Shot.wav");
77
}
78
void Armadiloid_DebugSpawn(void)
79
{
80
RSDK_THIS(DebugMode);
81
CREATE_ENTITY(Armadiloid, NULL, self->position.x, self->position.y);
82
}
83
84
void Armadiloid_DebugDraw(void)
85
{
86
RSDK.SetSpriteAnimation(Armadiloid->aniFrames, 0, &DebugMode->animator, true, 0);
87
RSDK.DrawSprite(&DebugMode->animator, NULL, false);
88
}
89
90
void Armadiloid_State_Init(void)
91
{
92
RSDK_THIS(Armadiloid);
93
94
foreach_active(Armadiloid, armadiloid)
95
{
96
if (armadiloid != self) {
97
if (abs(self->position.x - armadiloid->position.x) < 0x300000) {
98
if (abs(self->position.y - armadiloid->position.y) < 0x300000) {
99
if (self->type) {
100
if (armadiloid->type != self->type) {
101
self->child = armadiloid;
102
self->state = Armadiloid_State_Rider;
103
foreach_break;
104
}
105
}
106
else if (armadiloid->type) {
107
self->parent = armadiloid;
108
self->state = Armadiloid_State_PlatformFlying;
109
foreach_break;
110
}
111
}
112
}
113
}
114
}
115
}
116
117
void Armadiloid_State_PlatformFlying(void)
118
{
119
RSDK_THIS(Armadiloid);
120
121
RSDK.ProcessAnimation(&self->boosterAnimator);
122
123
self->position.x += self->velocity.x;
124
125
if (self->parent) {
126
EntityPlayer *player = Player_GetNearestPlayerX();
127
128
if (abs(self->position.x - player->position.x) < 0x800000) {
129
RSDK.SetSpriteAnimation(Armadiloid->aniFrames, 2, &self->headAnimator, true, 0);
130
self->state = Armadiloid_PlatformShootDelay;
131
}
132
}
133
134
foreach_active(Player, player)
135
{
136
if (Player_CheckCollisionPlatform(player, self, &self->hitbox))
137
player->position.x += self->velocity.x;
138
}
139
}
140
141
void Armadiloid_PlatformShootDelay(void)
142
{
143
RSDK_THIS(Armadiloid);
144
145
RSDK.ProcessAnimation(&self->boosterAnimator);
146
147
self->position.x += self->velocity.x;
148
149
if (self->parent) {
150
if (++self->timer == 12) {
151
self->timer = 0;
152
self->state = Armadiloid_State_PlatformShoot;
153
}
154
155
foreach_active(Player, player)
156
{
157
if (Player_CheckCollisionPlatform(player, self, &self->hitbox))
158
player->position.x += self->velocity.x;
159
}
160
}
161
else {
162
self->timer = 0;
163
self->state = Armadiloid_State_PlatformFlying;
164
}
165
}
166
167
void Armadiloid_State_PlatformShoot(void)
168
{
169
RSDK_THIS(Armadiloid);
170
171
RSDK.ProcessAnimation(&self->boosterAnimator);
172
RSDK.ProcessAnimation(&self->headAnimator);
173
174
self->position.x += self->velocity.x;
175
176
if (self->headAnimator.frameID != 4 || self->timer) {
177
if (self->headAnimator.frameID == self->headAnimator.frameCount - 1) {
178
self->timer = 0;
179
RSDK.SetSpriteAnimation(Armadiloid->aniFrames, 2, &self->headAnimator, true, 0);
180
self->state = Armadiloid_State_PlatformFlying;
181
}
182
}
183
else {
184
self->timer = 1;
185
RSDK.PlaySfx(Armadiloid->sfxShot, false, 255);
186
187
EntityProjectile *projectile = CREATE_ENTITY(Projectile, Projectile_State_Move, self->position.x - 0x120000, self->position.y + 0x90000);
188
projectile->velocity.x = -0x18000;
189
projectile->drawGroup = Zone->objectDrawGroup[0];
190
projectile->hitbox.left = -4;
191
projectile->hitbox.top = -4;
192
projectile->hitbox.right = 4;
193
projectile->hitbox.bottom = 4;
194
projectile->type = PROJECTILE_BASIC2;
195
RSDK.SetSpriteAnimation(Armadiloid->aniFrames, 5, &projectile->animator, true, 0);
196
}
197
198
foreach_active(Player, player)
199
{
200
if (Player_CheckCollisionPlatform(player, self, &self->hitbox))
201
player->position.x += self->velocity.x;
202
}
203
}
204
205
void Armadiloid_State_Rider(void)
206
{
207
RSDK_THIS(Armadiloid);
208
209
RSDK.ProcessAnimation(&self->bodyAnimator);
210
211
EntityArmadiloid *child = self->child;
212
if (child) {
213
self->position.x = child->position.x;
214
self->position.y = child->position.y;
215
}
216
217
foreach_active(Player, player)
218
{
219
if (Player_CheckBadnikTouch(player, self, &self->hitbox) && Player_CheckBadnikBreak(player, self, true)) {
220
child->parent = NULL;
221
}
222
}
223
}
224
225
#if GAME_INCLUDE_EDITOR
226
void Armadiloid_EditorDraw(void)
227
{
228
RSDK_THIS(Armadiloid);
229
230
if (self->type != ARMADILOID_SHOOTER) {
231
RSDK.SetSpriteAnimation(Armadiloid->aniFrames, 4, &self->bodyAnimator, true, 0);
232
RSDK.SetSpriteAnimation(-1, 1, &self->headAnimator, true, 0);
233
RSDK.SetSpriteAnimation(-1, 3, &self->boosterAnimator, true, 0);
234
}
235
else {
236
RSDK.SetSpriteAnimation(Armadiloid->aniFrames, 0, &self->bodyAnimator, true, 0);
237
RSDK.SetSpriteAnimation(Armadiloid->aniFrames, 1, &self->headAnimator, true, 0);
238
RSDK.SetSpriteAnimation(Armadiloid->aniFrames, 3, &self->boosterAnimator, true, 0);
239
}
240
241
RSDK.DrawSprite(&self->boosterAnimator, NULL, false);
242
RSDK.DrawSprite(&self->headAnimator, NULL, false);
243
RSDK.DrawSprite(&self->bodyAnimator, NULL, false);
244
}
245
246
void Armadiloid_EditorLoad(void)
247
{
248
Armadiloid->aniFrames = RSDK.LoadSpriteAnimation("MSZ/Armadiloid.bin", SCOPE_STAGE);
249
250
RSDK_ACTIVE_VAR(Armadiloid, type);
251
RSDK_ENUM_VAR("Shooter", ARMADILOID_SHOOTER);
252
RSDK_ENUM_VAR("Rider", ARMADILOID_RIDER);
253
}
254
#endif
255
256
void Armadiloid_Serialize(void) { RSDK_EDITABLE_VAR(Armadiloid, VAR_ENUM, type); }
257
258