Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rubberduckycooly
GitHub Repository: rubberduckycooly/Sonic-Mania-Decompilation
Path: blob/master/SonicMania/Objects/SSZ/Fireflies.c
338 views
1
// ---------------------------------------------------------------------
2
// RSDK Project: Sonic Mania
3
// Object Description: Fireflies Object
4
// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges
5
// Decompiled by: Rubberduckycooly & RMGRich
6
// ---------------------------------------------------------------------
7
8
#include "Game.h"
9
10
ObjectFireflies *Fireflies;
11
12
void Fireflies_Update(void)
13
{
14
RSDK_THIS(Fireflies);
15
16
StateMachine_Run(self->state);
17
}
18
19
void Fireflies_LateUpdate(void) {}
20
21
void Fireflies_StaticUpdate(void) {}
22
23
void Fireflies_Draw(void)
24
{
25
RSDK_THIS(Fireflies);
26
27
RSDK.DrawSprite(&self->animator, NULL, false);
28
}
29
30
void Fireflies_Create(void *data)
31
{
32
RSDK_THIS(Fireflies);
33
34
if (!SceneInfo->inEditor) {
35
self->active = ACTIVE_NORMAL;
36
self->drawGroup = Zone->objectDrawGroup[0];
37
self->visible = true;
38
self->drawFX = FX_FLIP;
39
self->updateRange.x = TO_FIXED(128);
40
self->updateRange.y = TO_FIXED(128);
41
42
if (data) {
43
self->inkEffect = INK_ADD;
44
self->state = Fireflies_State_Firefly;
45
}
46
else {
47
self->state = Fireflies_State_Spawner;
48
self->screenCount = RSDK.GetVideoSetting(VIDEOSETTING_SCREENCOUNT);
49
}
50
}
51
}
52
53
void Fireflies_StageLoad(void) { Fireflies->aniFrames = RSDK.LoadSpriteAnimation("SSZ1/Fireflies.bin", SCOPE_STAGE); }
54
55
void Fireflies_State_Spawner(void)
56
{
57
RSDK_THIS(Fireflies);
58
59
if (self->timer <= 0) {
60
self->timer = 1;
61
62
if (Fireflies->activeFireflyCount < 48) {
63
Vector2 startPos;
64
65
RSDKScreenInfo *screen = &ScreenInfo[self->screenID];
66
int32 screenCenterX = TO_FIXED(screen->position.x + (screen->size.x / 2));
67
int32 screenCenterY = TO_FIXED(screen->position.y + (screen->size.y / 2));
68
int32 offsetX = TO_FIXED(ZONE_RAND(-screen->size.x, screen->size.x));
69
int32 offsetY = TO_FIXED(ZONE_RAND(-screen->size.y, screen->size.y));
70
71
startPos.x = screenCenterX + offsetX;
72
startPos.y = screenCenterY + offsetY;
73
bool32 isLarge = ZONE_RAND(0, 10) > 7;
74
75
EntityFireflies *fireflies = CREATE_ENTITY(Fireflies, INT_TO_VOID(true), startPos.x, startPos.y);
76
RSDK.SetSpriteAnimation(Fireflies->aniFrames, isLarge ? 3 : 0, &fireflies->animator, true, 0);
77
fireflies->drawGroup = isLarge ? Zone->objectDrawGroup[1] : 1;
78
79
fireflies->duration = ZONE_RAND(45, 75);
80
fireflies->updateRange.x = TO_FIXED(128);
81
fireflies->updateRange.y = TO_FIXED(128);
82
fireflies->active = ACTIVE_NORMAL;
83
84
int32 points3_delta = ZONE_RAND(32, 128);
85
int32 points3_angle = ZONE_RAND(0, 511);
86
int32 points3_x = startPos.x + points3_delta * (RSDK.Cos512(points3_angle) << 7);
87
int32 points3_y = startPos.y + points3_delta * (RSDK.Sin512(points3_angle) << 7);
88
89
int32 points1_delta = ZONE_RAND(32, 64);
90
int32 points1_angle = ZONE_RAND(0, 511);
91
int32 points1_x = startPos.x + points1_delta * (RSDK.Cos512(points1_angle) << 7);
92
int32 points1_y = startPos.y + points1_delta * (RSDK.Sin512(points1_angle) << 7);
93
94
int32 points2_delta = ZONE_RAND(32, 64);
95
int32 points2_angle = ZONE_RAND(0, 511);
96
int32 points2_x = points3_x + points2_delta * (RSDK.Cos512(points2_angle) << 7);
97
int32 points2_y = points3_y + points2_delta * (RSDK.Sin512(points2_angle) << 7);
98
99
fireflies->points[0].x = startPos.x;
100
fireflies->points[0].y = startPos.y;
101
fireflies->points[1].x = points1_x;
102
fireflies->points[1].y = points1_y;
103
fireflies->points[2].x = points2_x;
104
fireflies->points[2].y = points2_y;
105
fireflies->points[3].x = points3_x;
106
fireflies->points[3].y = points3_y;
107
108
++Fireflies->activeFireflyCount;
109
110
self->screenID = (self->screenID + 1) % self->screenCount;
111
}
112
}
113
else {
114
self->timer--;
115
}
116
}
117
118
void Fireflies_State_Firefly(void)
119
{
120
RSDK_THIS(Fireflies);
121
122
int32 frame = 0, animLow = 0, animHigh = 0;
123
if (self->animator.animationID % 3 || self->animator.frameID != self->animator.frameCount - 1) {
124
if (self->timer == self->duration - 28) {
125
frame = 0;
126
animLow = 2;
127
animHigh = 5;
128
if (self->drawGroup == Zone->objectDrawGroup[1])
129
animLow = animHigh;
130
131
RSDK.SetSpriteAnimation(Fireflies->aniFrames, animLow, &self->animator, true, frame);
132
}
133
}
134
else {
135
frame = self->animator.animationID % 3;
136
animLow = 1;
137
animHigh = 4;
138
if (self->drawGroup == Zone->objectDrawGroup[1])
139
animLow = animHigh;
140
141
RSDK.SetSpriteAnimation(Fireflies->aniFrames, animLow, &self->animator, true, frame);
142
}
143
144
int32 percent = TO_FIXED(self->timer) / self->duration;
145
self->position = MathHelpers_GetBezierPoint(percent, self->points[0].x, self->points[0].y, self->points[1].x, self->points[1].y,
146
self->points[2].x, self->points[2].y, self->points[3].x, self->points[3].y);
147
148
if (!percent)
149
self->position = self->points[0];
150
151
if (self->timer + 8 < self->duration) {
152
if (self->alpha < 0x100)
153
self->alpha += 0x20;
154
}
155
else {
156
self->alpha -= 0x20;
157
}
158
159
if (self->timer >= self->duration) {
160
destroyEntity(self);
161
--Fireflies->activeFireflyCount;
162
}
163
164
RSDK.ProcessAnimation(&self->animator);
165
++self->timer;
166
}
167
168
#if GAME_INCLUDE_EDITOR
169
void Fireflies_EditorDraw(void)
170
{
171
RSDK_THIS(Fireflies);
172
173
self->drawFX = FX_FLIP;
174
RSDK.SetSpriteAnimation(Fireflies->aniFrames, 5, &self->animator, true, 0);
175
176
Fireflies_Draw();
177
}
178
179
void Fireflies_EditorLoad(void) { Fireflies->aniFrames = RSDK.LoadSpriteAnimation("SSZ1/Fireflies.bin", SCOPE_STAGE); }
180
#endif
181
182
void Fireflies_Serialize(void) {}
183
184