Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rubberduckycooly
GitHub Repository: rubberduckycooly/Sonic-Mania-Decompilation
Path: blob/master/SonicMania/Objects/SSZ/FlowerPod.c
338 views
1
// ---------------------------------------------------------------------
2
// RSDK Project: Sonic Mania
3
// Object Description: FlowerPod Object
4
// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges
5
// Decompiled by: Rubberduckycooly & RMGRich
6
// ---------------------------------------------------------------------
7
8
#include "Game.h"
9
10
ObjectFlowerPod *FlowerPod;
11
12
void FlowerPod_Update(void)
13
{
14
RSDK_THIS(FlowerPod);
15
16
StateMachine_Run(self->state);
17
}
18
19
void FlowerPod_LateUpdate(void) {}
20
21
void FlowerPod_StaticUpdate(void) {}
22
23
void FlowerPod_Draw(void)
24
{
25
RSDK_THIS(FlowerPod);
26
27
RSDK.DrawSprite(&self->podAnimator, NULL, false);
28
RSDK.DrawSprite(&self->stemAnimator, NULL, false);
29
}
30
31
void FlowerPod_Create(void *data)
32
{
33
RSDK_THIS(FlowerPod);
34
35
if (!SceneInfo->inEditor) {
36
self->active = ACTIVE_BOUNDS;
37
self->visible = true;
38
self->drawFX = FX_FLIP;
39
self->drawGroup = Zone->objectDrawGroup[0];
40
self->updateRange.x = 0x800000;
41
self->updateRange.y = 0x800000;
42
43
if (data) {
44
self->drawFX = FX_ROTATE | FX_FLIP;
45
RSDK.SetSpriteAnimation(FlowerPod->aniFrames, 3, &self->stemAnimator, true, 0);
46
self->active = ACTIVE_NORMAL;
47
self->state = FlowerPod_State_SeedFall;
48
}
49
else {
50
RSDK.SetSpriteAnimation(FlowerPod->aniFrames, 0, &self->stemAnimator, true, 0);
51
RSDK.SetSpriteAnimation(FlowerPod->aniFrames, 1, &self->podAnimator, true, 0);
52
self->state = FlowerPod_State_Pod;
53
}
54
}
55
}
56
57
void FlowerPod_StageLoad(void)
58
{
59
if (RSDK.CheckSceneFolder("SSZ1"))
60
FlowerPod->aniFrames = RSDK.LoadSpriteAnimation("SSZ1/FlowerPod.bin", SCOPE_STAGE);
61
62
FlowerPod->hitboxPod.top = -36;
63
FlowerPod->hitboxPod.left = -32;
64
FlowerPod->hitboxPod.right = 32;
65
FlowerPod->hitboxPod.bottom = 0;
66
67
FlowerPod->sfxExplosion = RSDK.GetSfx("Stage/Explosion2.wav");
68
FlowerPod->sfxTwinkle = RSDK.GetSfx("Global/Twinkle.wav");
69
}
70
71
void FlowerPod_SpawnSeeds(void)
72
{
73
RSDK_THIS(FlowerPod);
74
75
for (int32 v = -0x10000; v < 0x18000; v += 0x8000) {
76
EntityFlowerPod *seed = CREATE_ENTITY(FlowerPod, INT_TO_VOID(true), self->position.x, self->position.y);
77
seed->isPermanent = true;
78
seed->velocity.x = v;
79
seed->velocity.y = -0x30000;
80
seed->drawGroup = Zone->objectDrawGroup[0];
81
}
82
}
83
84
void FlowerPod_State_Pod(void)
85
{
86
RSDK_THIS(FlowerPod);
87
88
RSDK.ProcessAnimation(&self->podAnimator);
89
90
foreach_active(Player, player)
91
{
92
if (Player_CheckAttackingNoInvTimer(player, self) && Player_CheckBadnikTouch(player, self, &FlowerPod->hitboxPod))
93
self->state = FlowerPod_State_Exploding;
94
}
95
}
96
97
void FlowerPod_State_Exploding(void)
98
{
99
RSDK_THIS(FlowerPod);
100
101
if (!(Zone->timer % 3)) {
102
RSDK.PlaySfx(FlowerPod->sfxExplosion, false, 255);
103
104
if ((Zone->timer & 4)) {
105
int32 x = self->position.x + (RSDK.Rand(-32, 32) << 16);
106
int32 y = self->position.y + (RSDK.Rand(-32, 0) << 16);
107
EntityExplosion *explosion = CREATE_ENTITY(Explosion, INT_TO_VOID((RSDK.Rand(0, 256) > 192) + 2), x, y);
108
explosion->drawGroup = Zone->objectDrawGroup[1];
109
}
110
}
111
112
if (++self->timer == 30) {
113
RSDK.SetSpriteAnimation(FlowerPod->aniFrames, 2, &self->podAnimator, true, 0);
114
self->state = 0;
115
RSDK.PlaySfx(FlowerPod->sfxTwinkle, false, 255);
116
117
FlowerPod_SpawnSeeds();
118
self->timer = 48;
119
self->state = FlowerPod_State_Destroyed;
120
}
121
}
122
123
void FlowerPod_State_Destroyed(void)
124
{
125
RSDK_THIS(FlowerPod);
126
127
if (self->timer > 0) {
128
self->visible = (self->timer & 4) != 0;
129
self->timer--;
130
}
131
else {
132
destroyEntity(self);
133
}
134
}
135
136
void FlowerPod_State_SeedFall(void)
137
{
138
RSDK_THIS(FlowerPod);
139
140
self->velocity.y += 0x1C00;
141
self->position.x += self->velocity.x;
142
self->position.y += self->velocity.y;
143
144
self->rotation = 2 * RSDK.ATan2(self->velocity.x, self->velocity.y);
145
146
if (RSDK.ObjectTileCollision(self, Zone->collisionLayers, CMODE_FLOOR, 0, 0, 0, true)) {
147
self->rotation = 0;
148
self->timer = 30;
149
RSDK.SetSpriteAnimation(FlowerPod->aniFrames, 4, &self->stemAnimator, true, 0);
150
self->state = FlowerPod_State_SpawnBeanstalk;
151
}
152
153
RSDK.ProcessAnimation(&self->stemAnimator);
154
}
155
156
void FlowerPod_State_SpawnBeanstalk(void)
157
{
158
RSDK_THIS(FlowerPod);
159
160
if (self->timer <= 15) {
161
Hitbox hitboxSeed;
162
hitboxSeed.left = -4;
163
hitboxSeed.top = -4;
164
hitboxSeed.right = 4;
165
hitboxSeed.bottom = 4;
166
foreach_active(Beanstalk, beanstalk)
167
{
168
if (!beanstalk->type && RSDK.CheckObjectCollisionTouchBox(beanstalk, &Beanstalk->hitboxSeed, self, &hitboxSeed))
169
beanstalk->startGrowth = true;
170
}
171
172
RSDK.SetSpriteAnimation(FlowerPod->aniFrames, 5, &self->podAnimator, true, 0);
173
RSDK.SetSpriteAnimation(FlowerPod->aniFrames, 6, &self->stemAnimator, true, 0);
174
175
self->startPos = self->position;
176
self->state = FlowerPod_State_FlowerGrow;
177
}
178
else {
179
self->timer--;
180
}
181
182
RSDK.ProcessAnimation(&self->stemAnimator);
183
}
184
185
void FlowerPod_State_FlowerGrow(void)
186
{
187
RSDK_THIS(FlowerPod);
188
189
if (self->position.y <= self->startPos.y - 0x200000) {
190
self->active = ACTIVE_BOUNDS;
191
self->state = FlowerPod_State_Flower;
192
}
193
else {
194
self->position.y -= 0x40000;
195
}
196
197
FlowerPod_State_Flower();
198
}
199
200
void FlowerPod_State_Flower(void)
201
{
202
RSDK_THIS(FlowerPod);
203
204
RSDK.ProcessAnimation(&self->stemAnimator);
205
RSDK.ProcessAnimation(&self->podAnimator);
206
}
207
208
#if GAME_INCLUDE_EDITOR
209
void FlowerPod_EditorDraw(void)
210
{
211
RSDK_THIS(FlowerPod);
212
213
RSDK.SetSpriteAnimation(FlowerPod->aniFrames, 0, &self->stemAnimator, false, 0);
214
RSDK.SetSpriteAnimation(FlowerPod->aniFrames, 1, &self->podAnimator, false, 0);
215
216
FlowerPod_Draw();
217
}
218
219
void FlowerPod_EditorLoad(void) { FlowerPod->aniFrames = RSDK.LoadSpriteAnimation("SSZ1/FlowerPod.bin", SCOPE_STAGE); }
220
#endif
221
222
void FlowerPod_Serialize(void) {}
223
224