Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rubberduckycooly
GitHub Repository: rubberduckycooly/Sonic-Mania-Decompilation
Path: blob/master/SonicMania/Objects/CPZ/CaterkillerJr.c
338 views
1
// ---------------------------------------------------------------------
2
// RSDK Project: Sonic Mania
3
// Object Description: CaterkillerJr Object
4
// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges
5
// Decompiled by: Rubberduckycooly & RMGRich
6
// ---------------------------------------------------------------------
7
8
#include "Game.h"
9
10
ObjectCaterkillerJr *CaterkillerJr;
11
12
void CaterkillerJr_Update(void)
13
{
14
RSDK_THIS(CaterkillerJr);
15
16
self->active = ACTIVE_NORMAL;
17
StateMachine_Run(self->state);
18
19
if (self->classID == CaterkillerJr->classID && !RSDK.CheckOnScreen(self, NULL) && !RSDK.CheckPosOnScreen(&self->startPos, &self->updateRange)) {
20
self->position = self->startPos;
21
CaterkillerJr_SetupPositions();
22
}
23
}
24
25
void CaterkillerJr_LateUpdate(void) {}
26
27
void CaterkillerJr_StaticUpdate(void) {}
28
29
void CaterkillerJr_Draw(void)
30
{
31
RSDK_THIS(CaterkillerJr);
32
int32 storeDir = self->direction;
33
34
for (int32 i = CATERKILLERJR_SEGMENT_COUNT - 1; i >= 0; --i) {
35
self->direction = self->bodyDirection[i];
36
RSDK.DrawSprite(&self->bodyAnimators[i], &self->bodyPosition[i], false);
37
}
38
39
self->direction = self->bodyDirection[3];
40
RSDK.DrawSprite(&self->smokePuffAnimators[2], &self->bodyPosition[3], false);
41
42
self->direction = self->bodyDirection[2];
43
RSDK.DrawSprite(&self->smokePuffAnimators[1], &self->bodyPosition[2], false);
44
45
self->direction = self->bodyDirection[1];
46
RSDK.DrawSprite(&self->smokePuffAnimators[0], &self->bodyPosition[1], false);
47
48
self->direction = storeDir;
49
}
50
51
void CaterkillerJr_Create(void *data)
52
{
53
RSDK_THIS(CaterkillerJr);
54
55
if (!SceneInfo->inEditor) {
56
self->visible = true;
57
self->drawGroup = Zone->objectDrawGroup[1];
58
self->startPos = self->position;
59
self->drawFX = FX_FLIP;
60
self->updateRange.x = 0x800000;
61
self->updateRange.y = 0x800000;
62
self->bodyVelocity[0].x = (2 * (self->direction != FLIP_NONE) - 1) << 16;
63
64
RSDK.SetSpriteAnimation(CaterkillerJr->aniFrames, 0, &self->bodyAnimators[0], true, 6);
65
RSDK.SetSpriteAnimation(CaterkillerJr->aniFrames, 1, &self->bodyAnimators[1], true, 6);
66
RSDK.SetSpriteAnimation(CaterkillerJr->aniFrames, 1, &self->bodyAnimators[2], true, 6);
67
RSDK.SetSpriteAnimation(CaterkillerJr->aniFrames, 1, &self->bodyAnimators[3], true, 6);
68
RSDK.SetSpriteAnimation(CaterkillerJr->aniFrames, 2, &self->bodyAnimators[4], true, 0);
69
RSDK.SetSpriteAnimation(CaterkillerJr->aniFrames, 3, &self->bodyAnimators[5], true, 0);
70
RSDK.SetSpriteAnimation(CaterkillerJr->aniFrames, 3, &self->bodyAnimators[6], true, 0);
71
RSDK.SetSpriteAnimation(CaterkillerJr->aniFrames, 4, &self->smokePuffAnimators[0], true, 0);
72
RSDK.SetSpriteAnimation(CaterkillerJr->aniFrames, 4, &self->smokePuffAnimators[1], true, 0);
73
RSDK.SetSpriteAnimation(CaterkillerJr->aniFrames, 4, &self->smokePuffAnimators[2], true, 0);
74
75
CaterkillerJr_SetupPositions();
76
}
77
}
78
79
void CaterkillerJr_StageLoad(void)
80
{
81
if (RSDK.CheckSceneFolder("CPZ"))
82
CaterkillerJr->aniFrames = RSDK.LoadSpriteAnimation("CPZ/CaterkillerJr.bin", SCOPE_STAGE);
83
#if MANIA_USE_PLUS
84
else if (RSDK.CheckSceneFolder("AIZ"))
85
CaterkillerJr->aniFrames = RSDK.LoadSpriteAnimation("AIZ/CaterkillerJr.bin", SCOPE_STAGE);
86
#endif
87
88
CaterkillerJr->hitbox.left = -16;
89
CaterkillerJr->hitbox.top = 8;
90
CaterkillerJr->hitbox.right = 0;
91
CaterkillerJr->hitbox.bottom = 8;
92
93
DEBUGMODE_ADD_OBJ(CaterkillerJr);
94
}
95
96
void CaterkillerJr_DebugDraw(void)
97
{
98
RSDK.SetSpriteAnimation(CaterkillerJr->aniFrames, 0, &DebugMode->animator, true, 0);
99
RSDK.DrawSprite(&DebugMode->animator, NULL, false);
100
}
101
102
void CaterkillerJr_DebugSpawn(void)
103
{
104
RSDK_THIS(CaterkillerJr);
105
106
CREATE_ENTITY(CaterkillerJr, NULL, self->position.x, self->position.y);
107
}
108
109
void CaterkillerJr_SetupPositions(void)
110
{
111
RSDK_THIS(CaterkillerJr);
112
113
for (int32 i = 0; i < CATERKILLERJR_SEGMENT_COUNT; ++i) {
114
self->bodyPosition[i].x = self->position.x;
115
self->bodyPosition[i].y = self->position.y;
116
self->bodyVelocity[i].x = 0;
117
self->bodyVelocity[i].y = 0;
118
self->bodyDirection[i] = self->direction;
119
self->bodyTimer[i] = 0;
120
}
121
122
if (self->direction) {
123
self->boundsL = self->position.x - 0x3C0000;
124
self->boundsR = self->position.x + 0xBC0000;
125
}
126
else {
127
self->boundsL = self->position.x - 0xBC0000;
128
self->boundsR = self->position.x + 0x3C0000;
129
}
130
131
self->timer = 0;
132
133
self->smokePuffAnimators[0].timer = 14;
134
self->smokePuffAnimators[1].timer = 10;
135
self->smokePuffAnimators[2].timer = 6;
136
self->smokePuffAnimators[0].frameID = 8;
137
self->smokePuffAnimators[1].frameID = 8;
138
self->smokePuffAnimators[2].frameID = 8;
139
140
self->bodyVelocity[0].x = (2 * (self->direction != FLIP_NONE) - 1) << 16;
141
self->active = ACTIVE_BOUNDS;
142
143
self->state = CaterkillerJr_State_SetupVelocities;
144
}
145
146
void CaterkillerJr_State_SetupVelocities(void)
147
{
148
RSDK_THIS(CaterkillerJr);
149
150
int32 velocity = (2 * (self->direction != FLIP_NONE) - 1) << 16;
151
152
switch (++self->timer) {
153
case 12: self->bodyVelocity[1].x = velocity; break;
154
case 24: self->bodyVelocity[2].x = velocity; break;
155
case 36: self->bodyVelocity[3].x = velocity; break;
156
case 48: self->bodyVelocity[4].x = velocity; break;
157
case 56: self->bodyVelocity[5].x = velocity; break;
158
case 64:
159
self->timer = 0;
160
self->bodyVelocity[6].x = velocity;
161
self->state = CaterkillerJr_State_Move;
162
break;
163
}
164
165
CaterkillerJr_State_Move();
166
}
167
168
void CaterkillerJr_State_Move(void)
169
{
170
RSDK_THIS(CaterkillerJr);
171
172
for (int32 i = 0; i < CATERKILLERJR_SEGMENT_COUNT; ++i) {
173
RSDK.ProcessAnimation(&self->bodyAnimators[i]);
174
175
self->bodyPosition[i].x += self->bodyVelocity[i].x;
176
if (self->bodyDirection[i] && self->bodyPosition[i].x >= self->boundsR - 0x80000) {
177
self->bodyDirection[i] ^= FLIP_X;
178
self->bodyAnimators[i].timer = 0;
179
self->bodyAnimators[i].frameID = 0;
180
}
181
else if (!self->bodyDirection[i] && self->bodyPosition[i].x <= self->boundsL + 0x80000) {
182
self->bodyDirection[i] ^= FLIP_X;
183
self->bodyAnimators[i].timer = 0;
184
self->bodyAnimators[i].frameID = 0;
185
}
186
187
if (self->bodyVelocity[i].x <= 0 && self->bodyPosition[i].x <= self->boundsL) {
188
self->bodyVelocity[i].x = -self->bodyVelocity[i].x;
189
self->bodyTimer[i] = 0xA00;
190
}
191
else if (self->bodyVelocity[i].x >= 0 && self->bodyPosition[i].x >= self->boundsR) {
192
self->bodyVelocity[i].x = -self->bodyVelocity[i].x;
193
self->bodyTimer[i] = 0xA00;
194
}
195
196
if (self->bodyVelocity[i].x) {
197
int32 sine = 0;
198
if (self->bodyTimer[i] >= 0x800) {
199
self->bodyTimer[i] += 8;
200
sine = RSDK.Sin1024(self->bodyTimer[i]) << 10;
201
}
202
else {
203
self->bodyTimer[i] += 17;
204
sine = RSDK.Sin1024(self->bodyTimer[i]) << 8;
205
}
206
self->bodyPosition[i].y = sine + self->startPos.y;
207
self->bodyTimer[i] %= 0xC00;
208
}
209
}
210
211
RSDK.ProcessAnimation(&self->smokePuffAnimators[0]);
212
RSDK.ProcessAnimation(&self->smokePuffAnimators[1]);
213
RSDK.ProcessAnimation(&self->smokePuffAnimators[2]);
214
215
foreach_active(Player, player)
216
{
217
self->position = self->bodyPosition[0];
218
if (Player_CheckBadnikTouch(player, self, &CaterkillerJr->hitbox) && Player_CheckBadnikBreak(player, self, false)) {
219
for (int32 i = 1; i < CATERKILLERJR_SEGMENT_COUNT; ++i) {
220
EntityDebris *debris = CREATE_ENTITY(Debris, Debris_State_FallAndFlicker, self->bodyPosition[i].x, self->bodyPosition[i].y);
221
debris->animator = self->bodyAnimators[i];
222
debris->velocity.x = RSDK.Rand(-16, 16) << 14;
223
debris->velocity.y = RSDK.Rand(-8, 8) << 14;
224
debris->gravityStrength = 0x3800;
225
debris->drawGroup = Zone->objectDrawGroup[0];
226
debris->updateRange.x = 0x400000;
227
debris->updateRange.y = 0x400000;
228
}
229
230
destroyEntity(self);
231
self->active = ACTIVE_DISABLED;
232
foreach_break;
233
}
234
235
if (self->classID != TYPE_BLANK) {
236
for (int32 i = 1; i < CATERKILLERJR_SEGMENT_COUNT; ++i) {
237
self->position.x = self->bodyPosition[i].x;
238
self->position.y = self->bodyPosition[i].y;
239
if (Player_CheckCollisionTouch(player, self, &CaterkillerJr->hitbox)) {
240
Player_Hurt(player, self);
241
}
242
}
243
self->position.x = self->bodyPosition[0].x;
244
self->position.y = self->bodyPosition[0].y;
245
}
246
}
247
}
248
249
#if GAME_INCLUDE_EDITOR
250
void CaterkillerJr_EditorDraw(void)
251
{
252
RSDK_THIS(CaterkillerJr);
253
254
self->visible = true;
255
self->drawFX = FX_FLIP;
256
self->startPos = self->position;
257
258
RSDK.SetSpriteAnimation(CaterkillerJr->aniFrames, 0, &self->bodyAnimators[0], true, 6);
259
RSDK.SetSpriteAnimation(CaterkillerJr->aniFrames, 1, &self->bodyAnimators[1], true, 6);
260
RSDK.SetSpriteAnimation(CaterkillerJr->aniFrames, 1, &self->bodyAnimators[2], true, 6);
261
RSDK.SetSpriteAnimation(CaterkillerJr->aniFrames, 1, &self->bodyAnimators[3], true, 6);
262
RSDK.SetSpriteAnimation(CaterkillerJr->aniFrames, 2, &self->bodyAnimators[4], true, 0);
263
RSDK.SetSpriteAnimation(CaterkillerJr->aniFrames, 3, &self->bodyAnimators[5], true, 0);
264
RSDK.SetSpriteAnimation(CaterkillerJr->aniFrames, 3, &self->bodyAnimators[6], true, 0);
265
RSDK.SetSpriteAnimation(CaterkillerJr->aniFrames, 4, &self->smokePuffAnimators[0], true, 0);
266
RSDK.SetSpriteAnimation(CaterkillerJr->aniFrames, 4, &self->smokePuffAnimators[1], true, 0);
267
RSDK.SetSpriteAnimation(CaterkillerJr->aniFrames, 4, &self->smokePuffAnimators[2], true, 0);
268
CaterkillerJr_SetupPositions();
269
270
CaterkillerJr_Draw();
271
}
272
273
void CaterkillerJr_EditorLoad(void)
274
{
275
if (RSDK.CheckSceneFolder("CPZ"))
276
CaterkillerJr->aniFrames = RSDK.LoadSpriteAnimation("CPZ/CaterkillerJr.bin", SCOPE_STAGE);
277
#if MANIA_USE_PLUS
278
else if (RSDK.CheckSceneFolder("AIZ"))
279
CaterkillerJr->aniFrames = RSDK.LoadSpriteAnimation("AIZ/CaterkillerJr.bin", SCOPE_STAGE);
280
#endif
281
282
RSDK_ACTIVE_VAR(CaterkillerJr, direction);
283
RSDK_ENUM_VAR("Left", FLIP_NONE);
284
RSDK_ENUM_VAR("Right", FLIP_X);
285
}
286
#endif
287
288
void CaterkillerJr_Serialize(void) { RSDK_EDITABLE_VAR(CaterkillerJr, VAR_UINT8, direction); }
289
290