Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rubberduckycooly
GitHub Repository: rubberduckycooly/Sonic-Mania-Decompilation
Path: blob/master/SonicMania/Objects/HCZ/Blastoid.c
338 views
1
// ---------------------------------------------------------------------
2
// RSDK Project: Sonic Mania
3
// Object Description: Blastoid Object
4
// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges
5
// Decompiled by: Rubberduckycooly & RMGRich
6
// ---------------------------------------------------------------------
7
8
#include "Game.h"
9
10
ObjectBlastoid *Blastoid;
11
12
void Blastoid_Update(void)
13
{
14
RSDK_THIS(Blastoid);
15
16
StateMachine_Run(self->state);
17
}
18
19
void Blastoid_LateUpdate(void) {}
20
21
void Blastoid_StaticUpdate(void) {}
22
23
void Blastoid_Draw(void)
24
{
25
RSDK_THIS(Blastoid);
26
27
RSDK.DrawSprite(&self->animator, NULL, false);
28
}
29
30
void Blastoid_Create(void *data)
31
{
32
RSDK_THIS(Blastoid);
33
34
self->visible = true;
35
self->drawGroup = Zone->objectDrawGroup[0];
36
self->drawFX |= FX_FLIP;
37
38
if (!SceneInfo->inEditor) {
39
if (data) {
40
self->active = ACTIVE_NORMAL;
41
self->updateRange.x = 0x200000;
42
self->updateRange.y = 0x200000;
43
RSDK.SetSpriteAnimation(Blastoid->aniFrames, 1, &self->animator, true, 0);
44
self->state = Blastoid_State_Projectile;
45
}
46
else {
47
self->active = ACTIVE_BOUNDS;
48
self->updateRange.x = 0x800000;
49
self->updateRange.y = 0x800000;
50
RSDK.SetSpriteAnimation(Blastoid->aniFrames, 0, &self->animator, true, 1);
51
self->state = Blastoid_State_Init;
52
}
53
}
54
}
55
56
void Blastoid_StageLoad(void)
57
{
58
if (RSDK.CheckSceneFolder("HCZ"))
59
Blastoid->aniFrames = RSDK.LoadSpriteAnimation("HCZ/Blastoid.bin", SCOPE_STAGE);
60
61
Blastoid->hitboxBody.left = -12;
62
Blastoid->hitboxBody.top = -9;
63
Blastoid->hitboxBody.right = 12;
64
Blastoid->hitboxBody.bottom = 12;
65
66
Blastoid->hitboxProjectile.left = -3;
67
Blastoid->hitboxProjectile.top = -3;
68
Blastoid->hitboxProjectile.right = 3;
69
Blastoid->hitboxProjectile.bottom = 3;
70
71
Blastoid->sfxShot = RSDK.GetSfx("Stage/Shot.wav");
72
73
DEBUGMODE_ADD_OBJ(Blastoid);
74
}
75
76
void Blastoid_DebugSpawn(void)
77
{
78
RSDK_THIS(Blastoid);
79
80
CREATE_ENTITY(Blastoid, NULL, self->position.x, self->position.y);
81
}
82
83
void Blastoid_DebugDraw(void)
84
{
85
RSDK.SetSpriteAnimation(Blastoid->aniFrames, 0, &DebugMode->animator, true, 0);
86
RSDK.DrawSprite(&DebugMode->animator, NULL, false);
87
}
88
89
void Blastoid_CheckPlayerCollisions(void)
90
{
91
RSDK_THIS(Blastoid);
92
93
foreach_active(Player, player)
94
{
95
if (Player_CheckBadnikTouch(player, self, &Blastoid->hitboxBody) && Player_CheckBadnikBreak(player, self, false)) {
96
EntityCollapsingPlatform *platform = RSDK_GET_ENTITY(SceneInfo->entitySlot - 1, CollapsingPlatform);
97
if (platform->classID == CollapsingPlatform->classID) {
98
platform->active = ACTIVE_NORMAL;
99
platform->collapseDelay = 30;
100
platform->stoodPos.x = self->position.x;
101
}
102
destroyEntity(self);
103
}
104
}
105
}
106
107
void Blastoid_State_Init(void)
108
{
109
RSDK_THIS(Blastoid);
110
111
self->active = ACTIVE_NORMAL;
112
113
EntityCollapsingPlatform *platform = RSDK_GET_ENTITY(SceneInfo->entitySlot - 1, CollapsingPlatform);
114
if (platform->classID == CollapsingPlatform->classID)
115
platform->active = ACTIVE_NEVER;
116
117
self->state = Blastoid_State_Body;
118
}
119
120
void Blastoid_State_Body(void)
121
{
122
RSDK_THIS(Blastoid);
123
124
RSDK.ProcessAnimation(&self->animator);
125
126
switch (++self->timer) {
127
case 1:
128
case 16:
129
case 31: {
130
EntityBlastoid *projectile = CREATE_ENTITY(Blastoid, INT_TO_VOID(true), self->position.x, self->position.y);
131
132
if (self->direction & FLIP_X) {
133
projectile->position.x += 0x100000;
134
projectile->velocity.x = 0x20000;
135
}
136
else {
137
projectile->position.x -= 0x100000;
138
projectile->velocity.x = -0x20000;
139
}
140
141
if (self->direction & FLIP_Y) {
142
projectile->position.y += 0x60000;
143
projectile->velocity.y = 0x10000;
144
}
145
else {
146
projectile->position.y -= 0x60000;
147
projectile->velocity.y = -0x10000;
148
}
149
150
RSDK.SetSpriteAnimation(Blastoid->aniFrames, 0, &self->animator, true, 0);
151
RSDK.PlaySfx(Blastoid->sfxShot, false, 0xFF);
152
break;
153
}
154
155
case 121: self->timer = 0; break;
156
157
default: break;
158
}
159
160
Blastoid_CheckPlayerCollisions();
161
162
if (!RSDK.CheckOnScreen(self, NULL)) {
163
self->timer = 0;
164
self->active = ACTIVE_BOUNDS;
165
}
166
}
167
168
void Blastoid_State_Projectile(void)
169
{
170
RSDK_THIS(Blastoid);
171
172
if (!RSDK.CheckOnScreen(self, NULL)) {
173
destroyEntity(self);
174
}
175
else {
176
self->position.x += self->velocity.x;
177
self->position.y += self->velocity.y;
178
179
RSDK.ProcessAnimation(&self->animator);
180
181
// Bug(?): setPos value is 4??????
182
// This implies these used to be "ObjectTileGrip" at some point, and were then changed to "ObjectTileCollision" without changing the last
183
// parameter Not that it *really* matters, since 4 will evaluate to true since it's non-zero
184
185
if (RSDK.ObjectTileCollision(self, Zone->collisionLayers, CMODE_FLOOR, 0, 0, Blastoid->hitboxProjectile.top << 13, 4)
186
|| RSDK.ObjectTileCollision(self, Zone->collisionLayers, CMODE_LWALL, 0, Blastoid->hitboxProjectile.left << 13, 0, 4)
187
|| RSDK.ObjectTileCollision(self, Zone->collisionLayers, CMODE_ROOF, 0, 0, Blastoid->hitboxProjectile.bottom << 13, 4)
188
|| RSDK.ObjectTileCollision(self, Zone->collisionLayers, CMODE_RWALL, 0, Blastoid->hitboxProjectile.right << 13, 0, 4)) {
189
destroyEntity(self);
190
}
191
else {
192
foreach_active(Player, player)
193
{
194
int32 shield = player->shield;
195
// HCZBubble overrides active shields for collision
196
if (Water_GetPlayerBubble(player))
197
player->shield = SHIELD_BUBBLE;
198
199
if (Player_CheckCollisionTouch(player, self, &Blastoid->hitboxProjectile))
200
Player_ProjectileHurt(player, self);
201
player->shield = shield;
202
}
203
}
204
}
205
}
206
207
#if GAME_INCLUDE_EDITOR
208
void Blastoid_EditorDraw(void)
209
{
210
RSDK_THIS(Blastoid);
211
212
RSDK.SetSpriteAnimation(Blastoid->aniFrames, 0, &self->animator, false, 0);
213
214
Blastoid_Draw();
215
216
if (showGizmos()) {
217
RSDK_DRAWING_OVERLAY(true);
218
219
EntityCollapsingPlatform *platform = RSDK_GET_ENTITY(SceneInfo->entitySlot - 1, CollapsingPlatform);
220
if (CollapsingPlatform && platform->classID == CollapsingPlatform->classID)
221
DrawHelpers_DrawArrow(self->position.x, self->position.y, platform->position.x, platform->position.y, 0xFFFF00, INK_NONE, 0xFF);
222
223
RSDK_DRAWING_OVERLAY(false);
224
}
225
}
226
227
void Blastoid_EditorLoad(void)
228
{
229
Blastoid->aniFrames = RSDK.LoadSpriteAnimation("HCZ/Blastoid.bin", SCOPE_STAGE);
230
231
RSDK_ACTIVE_VAR(Blastoid, direction);
232
RSDK_ENUM_VAR("Left", FLIP_NONE);
233
RSDK_ENUM_VAR("Right", FLIP_X);
234
RSDK_ENUM_VAR("Left (Flipped)", FLIP_Y);
235
RSDK_ENUM_VAR("Right (Flipped)", FLIP_XY);
236
}
237
#endif
238
239
void Blastoid_Serialize(void) { RSDK_EDITABLE_VAR(Blastoid, VAR_UINT8, direction); }
240
241