Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rubberduckycooly
GitHub Repository: rubberduckycooly/Sonic-Mania-Decompilation
Path: blob/master/SonicMania/Objects/AIZ/Bloominator.c
338 views
1
// ---------------------------------------------------------------------
2
// RSDK Project: Sonic Mania
3
// Object Description: Bloominator Object
4
// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges
5
// Decompiled by: Rubberduckycooly & RMGRich
6
// ---------------------------------------------------------------------
7
8
#include "Game.h"
9
10
#if MANIA_USE_PLUS
11
ObjectBloominator *Bloominator;
12
13
void Bloominator_Update(void)
14
{
15
RSDK_THIS(Bloominator);
16
StateMachine_Run(self->state);
17
}
18
19
void Bloominator_LateUpdate(void) {}
20
21
void Bloominator_StaticUpdate(void) {}
22
23
void Bloominator_Draw(void)
24
{
25
RSDK_THIS(Bloominator);
26
RSDK.DrawSprite(&self->animator, NULL, false);
27
}
28
29
void Bloominator_Create(void *data)
30
{
31
RSDK_THIS(Bloominator);
32
self->visible = true;
33
self->drawFX |= FX_FLIP;
34
self->drawGroup = Zone->objectDrawGroup[0];
35
self->active = ACTIVE_BOUNDS;
36
self->updateRange.x = 0x800000;
37
self->updateRange.y = 0x800000;
38
39
if (data) {
40
--self->drawGroup;
41
RSDK.SetSpriteAnimation(Bloominator->aniFrames, 2, &self->animator, true, 0);
42
self->state = Bloominator_State_Spikeball;
43
}
44
else {
45
RSDK.SetSpriteAnimation(Bloominator->aniFrames, 0, &self->animator, true, 0);
46
self->state = Bloominator_State_Init;
47
}
48
}
49
50
void Bloominator_StageLoad(void)
51
{
52
if (RSDK.CheckSceneFolder("AIZ"))
53
Bloominator->aniFrames = RSDK.LoadSpriteAnimation("AIZ/Bloominator.bin", SCOPE_STAGE);
54
55
Bloominator->hitboxBadnik.left = -12;
56
Bloominator->hitboxBadnik.top = -20;
57
Bloominator->hitboxBadnik.right = 12;
58
Bloominator->hitboxBadnik.bottom = 20;
59
60
Bloominator->hitboxProjectile.left = -4;
61
Bloominator->hitboxProjectile.top = -4;
62
Bloominator->hitboxProjectile.right = 4;
63
Bloominator->hitboxProjectile.bottom = 4;
64
65
Bloominator->sfxShot = RSDK.GetSfx("Stage/Shot.wav");
66
67
DEBUGMODE_ADD_OBJ(Bloominator);
68
}
69
70
void Bloominator_DebugDraw(void)
71
{
72
RSDK.SetSpriteAnimation(Bloominator->aniFrames, 0, &DebugMode->animator, true, 0);
73
RSDK.DrawSprite(&DebugMode->animator, NULL, false);
74
}
75
76
void Bloominator_DebugSpawn(void)
77
{
78
RSDK_THIS(Bloominator);
79
80
CREATE_ENTITY(Bloominator, NULL, self->position.x, self->position.y);
81
}
82
83
void Bloominator_CheckPlayerCollisions(void)
84
{
85
RSDK_THIS(Bloominator);
86
87
foreach_active(Player, player)
88
{
89
if (Player_CheckBadnikTouch(player, self, &Bloominator->hitboxBadnik))
90
Player_CheckBadnikBreak(player, self, true);
91
}
92
}
93
94
void Bloominator_CheckOffScreen(void)
95
{
96
RSDK_THIS(Bloominator);
97
98
if (!RSDK.CheckOnScreen(self, NULL))
99
Bloominator_Create(NULL);
100
}
101
102
void Bloominator_State_Init(void)
103
{
104
RSDK_THIS(Bloominator);
105
106
self->active = ACTIVE_NORMAL;
107
self->timer = 0;
108
109
self->state = Bloominator_State_Idle;
110
Bloominator_State_Idle();
111
}
112
113
void Bloominator_State_Idle(void)
114
{
115
RSDK_THIS(Bloominator);
116
117
if (self->onScreen) {
118
if (++self->timer >= 60) {
119
self->timer = 0;
120
RSDK.SetSpriteAnimation(Bloominator->aniFrames, 1, &self->animator, true, 0);
121
self->state = Bloominator_State_Firing;
122
}
123
}
124
125
RSDK.ProcessAnimation(&self->animator);
126
127
Bloominator_CheckPlayerCollisions();
128
Bloominator_CheckOffScreen();
129
}
130
131
void Bloominator_State_Firing(void)
132
{
133
RSDK_THIS(Bloominator);
134
EntityBloominator *spikeBall = NULL;
135
136
switch (++self->timer) {
137
case 15:
138
spikeBall = CREATE_ENTITY(Bloominator, INT_TO_VOID(true), self->position.x - 0x10000, self->position.y - 0x160000);
139
spikeBall->velocity.x = -0x10000;
140
spikeBall->velocity.y = -0x50000;
141
RSDK.PlaySfx(Bloominator->sfxShot, false, 255);
142
break;
143
144
case 45:
145
spikeBall = CREATE_ENTITY(Bloominator, INT_TO_VOID(true), self->position.x - 0x10000, self->position.y - 0x160000);
146
spikeBall->velocity.x = 0x10000;
147
spikeBall->velocity.y = -0x50000;
148
RSDK.PlaySfx(Bloominator->sfxShot, false, 255);
149
break;
150
151
case 50:
152
self->timer = -60;
153
RSDK.SetSpriteAnimation(Bloominator->aniFrames, 0, &self->animator, true, 0);
154
self->state = Bloominator_State_Idle;
155
break;
156
}
157
158
RSDK.ProcessAnimation(&self->animator);
159
160
Bloominator_CheckPlayerCollisions();
161
Bloominator_CheckOffScreen();
162
}
163
164
void Bloominator_State_Spikeball(void)
165
{
166
RSDK_THIS(Bloominator);
167
168
if (RSDK.CheckOnScreen(self, NULL)) {
169
self->position.x += self->velocity.x;
170
self->position.y += self->velocity.y;
171
self->velocity.y += 0x3800;
172
173
RSDK.ProcessAnimation(&self->animator);
174
175
foreach_active(Player, player)
176
{
177
if (Player_CheckCollisionTouch(player, self, &Bloominator->hitboxProjectile)) {
178
Player_ProjectileHurt(player, self);
179
}
180
}
181
}
182
else {
183
destroyEntity(self);
184
}
185
}
186
187
#if GAME_INCLUDE_EDITOR
188
void Bloominator_EditorDraw(void) { Bloominator_Draw(); }
189
190
void Bloominator_EditorLoad(void) { Bloominator->aniFrames = RSDK.LoadSpriteAnimation("AIZ/Bloominator.bin", SCOPE_STAGE); }
191
#endif
192
193
void Bloominator_Serialize(void) {}
194
#endif
195
196