Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rubberduckycooly
GitHub Repository: rubberduckycooly/Sonic-Mania-Decompilation
Path: blob/master/SonicMania/Objects/PGZ/Dragonfly.c
338 views
1
// ---------------------------------------------------------------------
2
// RSDK Project: Sonic Mania
3
// Object Description: Dragonfly Object
4
// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges
5
// Decompiled by: Rubberduckycooly & RMGRich
6
// ---------------------------------------------------------------------
7
8
#include "Game.h"
9
10
ObjectDragonfly *Dragonfly;
11
12
void Dragonfly_Update(void)
13
{
14
RSDK_THIS(Dragonfly);
15
16
StateMachine_Run(self->state);
17
}
18
19
void Dragonfly_LateUpdate(void) {}
20
21
void Dragonfly_StaticUpdate(void) {}
22
23
void Dragonfly_Draw(void)
24
{
25
RSDK_THIS(Dragonfly);
26
27
if (self->animator.animationID == 3) {
28
RSDK.DrawSprite(&self->animator, NULL, false);
29
}
30
else {
31
for (int32 i = 0; i < DRAGONFLY_SPINE_COUNT; ++i) {
32
self->bodyAnimator.frameID = i == 0;
33
self->direction = self->directions[i];
34
RSDK.DrawSprite(&self->bodyAnimator, &self->positions[i], false);
35
}
36
37
self->direction = false;
38
RSDK.DrawSprite(&self->animator, NULL, false);
39
40
self->inkEffect = INK_ALPHA;
41
RSDK.DrawSprite(&self->wingAnimator, NULL, false);
42
43
self->inkEffect = INK_NONE;
44
}
45
}
46
47
void Dragonfly_Create(void *data)
48
{
49
RSDK_THIS(Dragonfly);
50
51
self->visible = true;
52
self->drawGroup = Zone->objectDrawGroup[0];
53
54
if (!SceneInfo->inEditor) {
55
if (!self->speed) {
56
self->dist = 0x40;
57
self->speed = 0x04;
58
}
59
self->drawFX |= FX_FLIP;
60
61
if (data) {
62
self->active = ACTIVE_NORMAL;
63
self->updateRange.x = 0x100000;
64
self->updateRange.y = 0x100000;
65
RSDK.SetSpriteAnimation(Dragonfly->aniFrames, 3, &self->animator, true, 0);
66
self->state = Dragonfly_State_Debris;
67
}
68
else {
69
self->active = ACTIVE_BOUNDS;
70
self->updateRange.x = 0x800000;
71
self->updateRange.y = (self->dist + 0x80) << 16;
72
self->startPos = self->position;
73
self->alpha = 0x80;
74
75
RSDK.SetSpriteAnimation(Dragonfly->aniFrames, 2, &self->wingAnimator, true, 0);
76
RSDK.SetSpriteAnimation(Dragonfly->aniFrames, 3, &self->bodyAnimator, true, 0);
77
self->state = Dragonfly_State_Init;
78
}
79
}
80
}
81
82
void Dragonfly_StageLoad(void)
83
{
84
if (RSDK.CheckSceneFolder("PSZ1"))
85
Dragonfly->aniFrames = RSDK.LoadSpriteAnimation("PSZ1/Dragonfly.bin", SCOPE_STAGE);
86
else if (RSDK.CheckSceneFolder("PSZ2"))
87
Dragonfly->aniFrames = RSDK.LoadSpriteAnimation("PSZ2/Dragonfly.bin", SCOPE_STAGE);
88
89
Dragonfly->hitboxBadnik.left = -8;
90
Dragonfly->hitboxBadnik.top = -8;
91
Dragonfly->hitboxBadnik.right = 8;
92
Dragonfly->hitboxBadnik.bottom = 8;
93
94
Dragonfly->hitboxSpine.left = -5;
95
Dragonfly->hitboxSpine.top = -3;
96
Dragonfly->hitboxSpine.right = 5;
97
Dragonfly->hitboxSpine.bottom = 2;
98
99
DEBUGMODE_ADD_OBJ(Dragonfly);
100
}
101
102
void Dragonfly_DebugDraw(void)
103
{
104
RSDK.SetSpriteAnimation(Dragonfly->aniFrames, 0, &DebugMode->animator, true, 0);
105
RSDK.DrawSprite(&DebugMode->animator, NULL, false);
106
}
107
108
// rdc would probably not shut the fuck up if i didn't add this /hj
109
void Dragonfly_CheckOffScreen(void)
110
{
111
RSDK_THIS(Dragonfly);
112
113
if (!RSDK.CheckOnScreen(self, NULL) && !RSDK.CheckPosOnScreen(&self->startPos, &self->updateRange)) {
114
self->position.x = self->startPos.x;
115
self->position.y = self->startPos.y;
116
Dragonfly_Create(NULL);
117
}
118
}
119
120
void Dragonfly_DebugSpawn(void)
121
{
122
RSDK_THIS(Dragonfly);
123
124
CREATE_ENTITY(Dragonfly, NULL, self->position.x, self->position.y);
125
}
126
127
void Dragonfly_CheckPlayerCollisions(void)
128
{
129
RSDK_THIS(Dragonfly);
130
131
foreach_active(Player, player)
132
{
133
if (Player_CheckBadnikTouch(player, self, &Dragonfly->hitboxBadnik)) {
134
if (Player_CheckBadnikBreak(player, self, false)) {
135
for (int32 i = 0; i < DRAGONFLY_SPINE_COUNT; ++i) {
136
EntityDragonfly *child = CREATE_ENTITY(Dragonfly, INT_TO_VOID(true), self->positions[i].x, self->positions[i].y);
137
child->animator.frameID = i == 0;
138
child->velocity.x = RSDK.Rand(-4, 4) << 15;
139
child->velocity.y = RSDK.Rand(-5, 1) << 15;
140
}
141
142
destroyEntity(self);
143
}
144
}
145
else {
146
Vector2 storePos = self->position;
147
for (int32 i = 0; i < DRAGONFLY_SPINE_COUNT; ++i) {
148
self->position = self->positions[i];
149
if (Player_CheckCollisionTouch(player, self, &Dragonfly->hitboxSpine)) {
150
self->position = storePos;
151
Player_Hurt(player, self);
152
}
153
}
154
155
self->position = storePos;
156
}
157
}
158
}
159
160
void Dragonfly_State_Init(void)
161
{
162
RSDK_THIS(Dragonfly);
163
self->active = ACTIVE_NORMAL;
164
165
if (!self->dir) {
166
self->angle = 0;
167
RSDK.SetSpriteAnimation(Dragonfly->aniFrames, 0, &self->animator, true, 0);
168
}
169
else {
170
self->angle = 0x200;
171
RSDK.SetSpriteAnimation(Dragonfly->aniFrames, 1, &self->animator, true, 0);
172
}
173
174
self->state = Dragonfly_State_Move;
175
Dragonfly_State_Move();
176
}
177
178
void Dragonfly_State_Move(void)
179
{
180
RSDK_THIS(Dragonfly);
181
182
self->angle += self->speed;
183
184
self->position.x = self->startPos.x + 0xC00 * RSDK.Cos256(self->angle + 0x40);
185
self->position.y = self->startPos.y + (self->dist << 6) * RSDK.Sin1024(self->angle);
186
187
int32 currentAngle = self->angle - (((DRAGONFLY_SPINE_COUNT * 13) + 13) - 1);
188
for (int32 i = 0; i < DRAGONFLY_SPINE_COUNT; ++i) {
189
self->directions[i] = ((currentAngle + 0x100) & 0x3FF) < 0x200 ? 2 : 0;
190
191
self->positions[i].x = self->startPos.x + 0xC00 * RSDK.Cos256(currentAngle + 0x40);
192
self->positions[i].y = self->startPos.y + (self->dist << 6) * RSDK.Sin1024(currentAngle);
193
194
currentAngle += 13;
195
}
196
197
bool32 dir = ((self->angle + 0x100) & 0x3FF) < 0x200;
198
if (self->animator.animationID == 1) {
199
if (dir)
200
RSDK.SetSpriteAnimation(Dragonfly->aniFrames, 0, &self->animator, true, 0);
201
}
202
else if (!dir)
203
RSDK.SetSpriteAnimation(Dragonfly->aniFrames, 1, &self->animator, true, 0);
204
205
RSDK.ProcessAnimation(&self->animator);
206
RSDK.ProcessAnimation(&self->wingAnimator);
207
208
Dragonfly_CheckPlayerCollisions();
209
Dragonfly_CheckOffScreen();
210
}
211
212
void Dragonfly_State_Debris(void)
213
{
214
RSDK_THIS(Dragonfly);
215
216
self->position.x += self->velocity.x;
217
self->position.y += self->velocity.y;
218
self->velocity.y += 0x3800;
219
220
self->visible ^= true;
221
222
if (!RSDK.CheckOnScreen(self, NULL))
223
destroyEntity(self);
224
}
225
226
#if GAME_INCLUDE_EDITOR
227
void Dragonfly_EditorDraw(void)
228
{
229
RSDK_THIS(Dragonfly);
230
231
self->active = ACTIVE_BOUNDS;
232
self->updateRange.x = 0x800000;
233
self->updateRange.y = (self->dist + 0x80) << 16;
234
self->startPos = self->position;
235
self->alpha = 0x80;
236
237
RSDK.SetSpriteAnimation(Dragonfly->aniFrames, 2, &self->wingAnimator, true, 0);
238
RSDK.SetSpriteAnimation(Dragonfly->aniFrames, 3, &self->bodyAnimator, true, 0);
239
240
if (!self->dir) {
241
self->angle = 0;
242
RSDK.SetSpriteAnimation(Dragonfly->aniFrames, 0, &self->animator, true, 4);
243
}
244
else {
245
self->angle = 0x200;
246
RSDK.SetSpriteAnimation(Dragonfly->aniFrames, 1, &self->animator, true, 4);
247
}
248
249
self->position.x = self->startPos.x + 0xC00 * RSDK.Cos256(self->angle + 0x40);
250
self->position.y = self->startPos.y + (self->dist << 6) * RSDK.Sin1024(self->angle);
251
252
int32 currentAngle = self->angle - (((DRAGONFLY_SPINE_COUNT * 13) + 13) - 1);
253
for (int32 i = 0; i < DRAGONFLY_SPINE_COUNT; ++i) {
254
self->directions[i] = ((currentAngle + 0x100) & 0x3FF) < 0x200 ? 2 : 0;
255
256
self->positions[i].x = self->startPos.x + 0xC00 * RSDK.Cos256(currentAngle + 0x40);
257
self->positions[i].y = self->startPos.y + (self->dist << 6) * RSDK.Sin1024(currentAngle);
258
currentAngle += 13;
259
}
260
261
Dragonfly_Draw();
262
263
self->position = self->startPos;
264
}
265
266
void Dragonfly_EditorLoad(void)
267
{
268
if (RSDK.CheckSceneFolder("PSZ1"))
269
Dragonfly->aniFrames = RSDK.LoadSpriteAnimation("PSZ1/Dragonfly.bin", SCOPE_STAGE);
270
else if (RSDK.CheckSceneFolder("PSZ2"))
271
Dragonfly->aniFrames = RSDK.LoadSpriteAnimation("PSZ2/Dragonfly.bin", SCOPE_STAGE);
272
273
RSDK_ACTIVE_VAR(Dragonfly, dir);
274
RSDK_ENUM_VAR("Down", FLIP_NONE);
275
RSDK_ENUM_VAR("Up", FLIP_X);
276
}
277
#endif
278
279
void Dragonfly_Serialize(void)
280
{
281
RSDK_EDITABLE_VAR(Dragonfly, VAR_UINT8, dir);
282
RSDK_EDITABLE_VAR(Dragonfly, VAR_UINT8, dist);
283
RSDK_EDITABLE_VAR(Dragonfly, VAR_UINT8, speed);
284
}
285