Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rubberduckycooly
GitHub Repository: rubberduckycooly/Sonic-Mania-Decompilation
Path: blob/master/SonicMania/Objects/MSZ/Hatterkiller.c
338 views
1
// ---------------------------------------------------------------------
2
// RSDK Project: Sonic Mania
3
// Object Description: Hatterkiller Object
4
// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges
5
// Decompiled by: Rubberduckycooly & RMGRich
6
// ---------------------------------------------------------------------
7
8
#include "Game.h"
9
10
ObjectHatterkiller *Hatterkiller;
11
12
void Hatterkiller_Update(void)
13
{
14
RSDK_THIS(Hatterkiller);
15
16
for (int32 s = 0; s < HATTERKILLER_SEGMENT_COUNT; ++s) {
17
if (self->bodyDelays[s] <= 0) {
18
self->bodyVelocities[s].y += 0x3800;
19
self->bodyPositions[s].x += self->bodyVelocities[s].x + TornadoPath->moveVel.x;
20
self->bodyPositions[s].y += self->bodyVelocities[s].y + TornadoPath->moveVel.y;
21
}
22
else {
23
self->bodyDelays[s]--;
24
self->bodyPositions[s].x += TornadoPath->moveVel.x;
25
self->bodyPositions[s].y += TornadoPath->moveVel.y;
26
}
27
}
28
29
if (HeavyMystic->curtainLinePos) {
30
if (!(Zone->timer & 3))
31
HeavyMystic_SpawnParticleFX(self->position.x, self->position.y);
32
33
if (++self->timer == 40) {
34
Music_TransitionTrack(TRACK_MINIBOSS, 0.0125);
35
RSDK.PlaySfx(Hatterkiller->sfxTransform2, false, 255);
36
RSDK.PlaySfx(Hatterkiller->sfxPowerup, false, 255);
37
38
CREATE_ENTITY(FXSpinRay, NULL, self->position.x, self->position.y)->parent = (Entity *)self;
39
40
EntityFXFade *fade = CREATE_ENTITY(FXFade, INT_TO_VOID(0xF0F0F0), self->position.x, self->position.y);
41
fade->speedIn = 8;
42
fade->speedOut = 8;
43
}
44
}
45
else {
46
47
foreach_active(Player, player)
48
{
49
self->position.x = self->bodyPositions[0].x;
50
self->position.y = self->bodyPositions[0].y;
51
if (Player_CheckBadnikTouch(player, self, &Hatterkiller->hitboxSegment) && Player_CheckBadnikBreak(player, self, false)) {
52
for (int32 s = 1; s < HATTERKILLER_SEGMENT_COUNT; ++s) {
53
Vector2 *position = &self->bodyPositions[s];
54
Animator *animator = self->bodyAnimators[s];
55
EntityDebris *debris = CREATE_ENTITY(Debris, Debris_State_FallAndFlicker, position->x, position->y);
56
57
RSDK.SetSpriteAnimation(Hatterkiller->aniFrames, animator->animationID, &debris->animator, true, animator->frameID);
58
debris->velocity.x = RSDK.Rand(-0x20000, 0x20000);
59
debris->velocity.y = RSDK.Rand(-0x20000, -0x10000);
60
debris->gravityStrength = 0x4800;
61
debris->drawGroup = Zone->objectDrawGroup[1];
62
debris->updateRange.x = 0x400000;
63
debris->updateRange.y = 0x400000;
64
}
65
66
destroyEntity(self);
67
self->active = ACTIVE_DISABLED;
68
foreach_break;
69
}
70
71
for (int32 s = 1; s < HATTERKILLER_SEGMENT_COUNT; ++s) {
72
self->position.x = self->bodyPositions[s].x;
73
self->position.y = self->bodyPositions[s].y;
74
75
if (Player_CheckCollisionTouch(player, self, &Hatterkiller->hitboxSegment)) {
76
#if MANIA_USE_PLUS
77
if (!Player_CheckMightyUnspin(player, 0x200, 2, &player->uncurlTimer))
78
#endif
79
Player_Hurt(player, self);
80
}
81
}
82
}
83
}
84
85
if (HeavyMystic->curtainLinePos) {
86
self->position = self->bodyPositions[9];
87
88
if (!RSDK.CheckOnScreen(self, NULL)) {
89
if (HeavyMystic->curtainLinePos == 1 && !RSDK.CheckOnScreen(self, NULL)) {
90
foreach_active(ParallaxSprite, sprite) { sprite->visible = false; }
91
++HeavyMystic->curtainLinePos;
92
}
93
94
CREATE_ENTITY(UberCaterkiller, NULL, self->bodyPositions[HATTERKILLER_SEGMENT_COUNT - 1].x,
95
(ScreenInfo->position.y + 64 + ScreenInfo->size.y) << 16);
96
97
destroyEntity(self);
98
}
99
}
100
else if (!RSDK.CheckOnScreen(self, NULL)) {
101
destroyEntity(self);
102
}
103
104
self->position.x = self->bodyPositions[0].x;
105
self->position.y = self->bodyPositions[0].y;
106
}
107
108
void Hatterkiller_LateUpdate(void) {}
109
110
void Hatterkiller_StaticUpdate(void) {}
111
112
void Hatterkiller_Draw(void)
113
{
114
RSDK_THIS(Hatterkiller);
115
116
for (int32 s = HATTERKILLER_SEGMENT_COUNT - 1; s >= 0; --s) RSDK.DrawSprite(self->bodyAnimators[s], &self->bodyPositions[s], false);
117
}
118
119
void Hatterkiller_Create(void *data)
120
{
121
RSDK_THIS(Hatterkiller);
122
123
if (!SceneInfo->inEditor) {
124
self->visible = true;
125
self->active = ACTIVE_NORMAL;
126
self->drawGroup = Zone->objectDrawGroup[0] + 1;
127
self->updateRange.x = 0x400000;
128
self->updateRange.y = 0x400000;
129
130
int32 delay = 0;
131
for (int32 s = 0; s < HATTERKILLER_SEGMENT_COUNT; ++s) {
132
self->bodyVelocities[s].x = VOID_TO_INT(data);
133
self->bodyVelocities[s].y = -0x40000;
134
self->bodyAnimators[s] = &self->bodyAnimator;
135
self->bodyDelays[s] = delay;
136
self->bodyPositions[s] = self->position;
137
delay += 4;
138
}
139
140
self->bodyAnimators[0] = &self->headAnimator;
141
142
if (VOID_TO_INT(data) >= 0)
143
RSDK.SetSpriteAnimation(Hatterkiller->aniFrames, 3, &self->headAnimator, true, 0);
144
else
145
RSDK.SetSpriteAnimation(Hatterkiller->aniFrames, 2, &self->headAnimator, true, 0);
146
147
RSDK.SetSpriteAnimation(Hatterkiller->aniFrames, 1, &self->bodyAnimator, true, 0);
148
RSDK.SetSpriteAnimation(Hatterkiller->aniFrames, 4, &self->tailAnimator, true, 0);
149
}
150
}
151
152
void Hatterkiller_StageLoad(void)
153
{
154
Hatterkiller->aniFrames = RSDK.LoadSpriteAnimation("MSZ/RattleKiller.bin", SCOPE_STAGE);
155
156
Hatterkiller->hitboxSegment.left = -8;
157
Hatterkiller->hitboxSegment.top = -8;
158
Hatterkiller->hitboxSegment.right = 8;
159
Hatterkiller->hitboxSegment.bottom = 8;
160
161
Hatterkiller->sfxRocketJet = RSDK.GetSfx("Stage/RocketJet.wav");
162
Hatterkiller->sfxTransform2 = RSDK.GetSfx("Stage/Transform2.wav");
163
Hatterkiller->sfxPowerup = RSDK.GetSfx("Stage/PowerUp.wav");
164
165
DEBUGMODE_ADD_OBJ(Hatterkiller);
166
}
167
168
void Hatterkiller_DebugDraw(void)
169
{
170
RSDK.SetSpriteAnimation(Hatterkiller->aniFrames, 0, &DebugMode->animator, true, 0);
171
RSDK.DrawSprite(&DebugMode->animator, NULL, false);
172
}
173
174
void Hatterkiller_DebugSpawn(void)
175
{
176
RSDK_THIS(DebugMode);
177
178
CREATE_ENTITY(Hatterkiller, INT_TO_VOID(-0x20000), self->position.x, self->position.y);
179
}
180
181
#if GAME_INCLUDE_EDITOR
182
void Hatterkiller_EditorDraw(void)
183
{
184
RSDK_THIS(Hatterkiller);
185
186
self->visible = true;
187
self->active = ACTIVE_NORMAL;
188
self->updateRange.x = 0x400000;
189
self->updateRange.y = 0x400000;
190
191
int32 delay = 0;
192
for (int32 s = 0; s < HATTERKILLER_SEGMENT_COUNT; ++s) {
193
self->bodyAnimators[s] = &self->bodyAnimator;
194
self->bodyDelays[s] = delay;
195
self->bodyPositions[s] = self->position;
196
delay += 4;
197
}
198
199
self->bodyAnimators[0] = &self->headAnimator;
200
201
RSDK.SetSpriteAnimation(Hatterkiller->aniFrames, 2, &self->headAnimator, true, 0);
202
RSDK.SetSpriteAnimation(Hatterkiller->aniFrames, 1, &self->bodyAnimator, true, 0);
203
RSDK.SetSpriteAnimation(Hatterkiller->aniFrames, 4, &self->tailAnimator, true, 0);
204
205
Hatterkiller_Draw();
206
}
207
208
void Hatterkiller_EditorLoad(void) { Hatterkiller->aniFrames = RSDK.LoadSpriteAnimation("MSZ/RattleKiller.bin", SCOPE_STAGE); }
209
#endif
210
211
void Hatterkiller_Serialize(void) {}
212
213