Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rubberduckycooly
GitHub Repository: rubberduckycooly/Sonic-Mania-Decompilation
Path: blob/master/SonicMania/Objects/CPZ/ChemicalBall.c
338 views
1
// ---------------------------------------------------------------------
2
// RSDK Project: Sonic Mania
3
// Object Description: ChemicalBall Object
4
// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges
5
// Decompiled by: Rubberduckycooly & RMGRich
6
// ---------------------------------------------------------------------
7
8
#include "Game.h"
9
10
ObjectChemicalBall *ChemicalBall;
11
12
void ChemicalBall_Update(void)
13
{
14
RSDK_THIS(ChemicalBall);
15
16
if (globals->gameMode == MODE_TIMEATTACK && TimeAttackGate && TimeAttackGate->isFinished)
17
destroyEntity(self);
18
19
StateMachine_Run(self->state);
20
}
21
22
void ChemicalBall_LateUpdate(void) {}
23
24
void ChemicalBall_StaticUpdate(void) {}
25
26
void ChemicalBall_Draw(void)
27
{
28
RSDK_THIS(ChemicalBall);
29
30
RSDK.DrawSprite(&self->animator, &self->drawPos, false);
31
}
32
33
void ChemicalBall_Create(void *data)
34
{
35
RSDK_THIS(ChemicalBall);
36
37
self->visible = true;
38
self->drawGroup = Zone->objectDrawGroup[0];
39
self->startPos = self->position;
40
self->active = ACTIVE_BOUNDS;
41
self->updateRange.x = 0x1000000;
42
self->updateRange.y = 0x1000000;
43
44
if (!self->interval)
45
self->interval = 128;
46
47
self->drawPos = self->position;
48
49
if (self->direction == FLIP_NONE)
50
self->position.x += 0x320000;
51
else
52
self->position.x -= 0x320000;
53
54
if (self->type == CHEMICALBALL_VERTICAL)
55
self->position.y -= 0x480000;
56
57
RSDK.SetSpriteAnimation(ChemicalBall->aniFrames, 0, &self->animator, true, 0);
58
59
if (!self->type)
60
self->state = ChemicalBall_State_MoveArc;
61
else
62
self->state = ChemicalBall_State_MoveVertical;
63
}
64
65
void ChemicalBall_StageLoad(void)
66
{
67
ChemicalBall->aniFrames = RSDK.LoadSpriteAnimation("CPZ/ChemicalBall.bin", SCOPE_STAGE);
68
69
ChemicalBall->hitboxBall.left = -8;
70
ChemicalBall->hitboxBall.top = -8;
71
ChemicalBall->hitboxBall.right = 8;
72
ChemicalBall->hitboxBall.bottom = 8;
73
74
ChemicalBall->sfxBloop = RSDK.GetSfx("Stage/Bloop.wav");
75
}
76
77
void ChemicalBall_CheckHit(void)
78
{
79
RSDK_THIS(ChemicalBall);
80
81
foreach_active(Player, player)
82
{
83
Vector2 posStore = self->position;
84
self->position = self->drawPos;
85
if (Player_CheckCollisionTouch(player, self, &ChemicalBall->hitboxBall)) {
86
self->position = posStore;
87
Player_Hurt(player, self);
88
}
89
else {
90
self->position = posStore;
91
}
92
}
93
}
94
95
void ChemicalBall_State_MoveArc(void)
96
{
97
RSDK_THIS(ChemicalBall);
98
99
int32 timer = (Zone->timer + self->intervalOffset) % (2 * self->interval);
100
if (timer < self->interval == (self->direction != FLIP_NONE)) {
101
if (!self->direction)
102
timer -= self->interval;
103
104
if (timer >= 96) {
105
self->drawPos.x = ChemicalBall->arcOffsets[0];
106
self->drawPos.y = ChemicalBall->arcOffsets[1];
107
}
108
else {
109
self->drawPos.x = ChemicalBall->arcOffsets[2 * (97 - timer)];
110
self->drawPos.y = ChemicalBall->arcOffsets[2 * (97 - timer) + 1];
111
}
112
}
113
else {
114
if (self->direction == FLIP_X)
115
timer -= self->interval;
116
117
if (timer >= 97) {
118
self->drawPos.x = ChemicalBall->arcOffsets[194];
119
self->drawPos.y = ChemicalBall->arcOffsets[195];
120
}
121
else {
122
self->drawPos.x = ChemicalBall->arcOffsets[2 * timer];
123
self->drawPos.y = ChemicalBall->arcOffsets[2 * timer + 1];
124
}
125
}
126
127
self->drawPos.x += self->position.x;
128
self->drawPos.y += self->position.y;
129
130
if (!timer || timer == self->interval)
131
RSDK.PlaySfx(ChemicalBall->sfxBloop, false, 255);
132
133
ChemicalBall_CheckHit();
134
}
135
136
void ChemicalBall_State_MoveVertical(void)
137
{
138
RSDK_THIS(ChemicalBall);
139
140
int32 timer = (Zone->timer + self->intervalOffset) % self->interval;
141
if (timer < 98) {
142
if (timer >= 49) {
143
if (!self->direction)
144
self->drawPos.x = -0x320000;
145
else
146
self->drawPos.x = 0x2E0000;
147
self->drawPos.y = ChemicalBall->moveOffsets[97 - timer];
148
}
149
else {
150
if (!self->direction)
151
self->drawPos.x = 0x2E0000;
152
else
153
self->drawPos.x = -0x320000;
154
self->drawPos.y = ChemicalBall->moveOffsets[timer];
155
}
156
}
157
self->drawPos.x += self->position.x;
158
self->drawPos.y += self->position.y;
159
160
if (timer == 27 || timer == 48)
161
RSDK.PlaySfx(ChemicalBall->sfxBloop, false, 255);
162
163
ChemicalBall_CheckHit();
164
}
165
166
#if GAME_INCLUDE_EDITOR
167
void ChemicalBall_EditorDraw(void)
168
{
169
RSDK_THIS(ChemicalBall);
170
171
RSDK.SetSpriteAnimation(ChemicalBall->aniFrames, 0, &self->animator, true, 0);
172
173
self->drawPos = self->position;
174
if (self->direction == FLIP_NONE)
175
self->drawPos.x += 0x320000;
176
else
177
self->drawPos.x -= 0x320000;
178
179
if (self->type == CHEMICALBALL_VERTICAL)
180
self->drawPos.y -= 0x480000;
181
182
ChemicalBall_Draw();
183
184
if (showGizmos()) {
185
RSDK_DRAWING_OVERLAY(true);
186
187
self->drawPos = self->position;
188
self->inkEffect = INK_BLEND;
189
ChemicalBall_Draw();
190
self->inkEffect = INK_NONE;
191
192
RSDK_DRAWING_OVERLAY(false);
193
}
194
}
195
196
void ChemicalBall_EditorLoad(void)
197
{
198
ChemicalBall->aniFrames = RSDK.LoadSpriteAnimation("CPZ/ChemicalBall.bin", SCOPE_STAGE);
199
200
RSDK_ACTIVE_VAR(ChemicalBall, type);
201
RSDK_ENUM_VAR("Arc", CHEMICALBALL_ARC);
202
RSDK_ENUM_VAR("Vertical", CHEMICALBALL_VERTICAL);
203
204
RSDK_ACTIVE_VAR(ChemicalBall, direction);
205
RSDK_ENUM_VAR("No Flip", FLIP_NONE);
206
RSDK_ENUM_VAR("Flipped", FLIP_X);
207
}
208
#endif
209
210
void ChemicalBall_Serialize(void)
211
{
212
RSDK_EDITABLE_VAR(ChemicalBall, VAR_UINT8, type);
213
RSDK_EDITABLE_VAR(ChemicalBall, VAR_UINT8, direction);
214
RSDK_EDITABLE_VAR(ChemicalBall, VAR_UINT8, interval);
215
RSDK_EDITABLE_VAR(ChemicalBall, VAR_UINT8, intervalOffset);
216
RSDK_EDITABLE_VAR(ChemicalBall, VAR_BOOL, master); // unused, (looks to be set on the first instance of arc types)
217
}
218
219