Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rubberduckycooly
GitHub Repository: rubberduckycooly/Sonic-Mania-Decompilation
Path: blob/master/SonicMania/Objects/MMZ/BladePole.c
338 views
1
// ---------------------------------------------------------------------
2
// RSDK Project: Sonic Mania
3
// Object Description: BladePole Object
4
// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges
5
// Decompiled by: Rubberduckycooly & RMGRich
6
// ---------------------------------------------------------------------
7
8
#include "Game.h"
9
10
ObjectBladePole *BladePole;
11
12
void BladePole_Update(void)
13
{
14
RSDK_THIS(BladePole);
15
16
RSDK.ProcessAnimation(&self->bladeTopAnimator);
17
RSDK.ProcessAnimation(&self->bladeBottomAnimator);
18
19
StateMachine_Run(self->state);
20
}
21
22
void BladePole_LateUpdate(void) {}
23
24
void BladePole_StaticUpdate(void) {}
25
26
void BladePole_Draw(void) { BladePole_DrawSprites(); }
27
28
void BladePole_Create(void *data)
29
{
30
RSDK_THIS(BladePole);
31
32
self->active = ACTIVE_BOUNDS;
33
self->visible = true;
34
self->drawGroup = Zone->objectDrawGroup[0];
35
self->drawFX = FX_FLIP;
36
self->updateRange.x = 0x800000;
37
self->updateRange.y = 0x800000;
38
39
RSDK.SetSpriteAnimation(BladePole->aniFrames, 0, &self->poleAnimator, true, 0);
40
RSDK.SetSpriteAnimation(BladePole->aniFrames, 1, &self->bladeTopAnimator, true, 0);
41
RSDK.SetSpriteAnimation(BladePole->aniFrames, 1, &self->bladeBottomAnimator, true, 0);
42
43
// Why is this initialized here?? wouldn't StageLoad be better?
44
BladePole->hitboxBottom.left = -24;
45
BladePole->hitboxBottom.top = 20;
46
BladePole->hitboxBottom.right = 24;
47
BladePole->hitboxBottom.bottom = BladePole->hitboxBottom.top + 24;
48
49
BladePole->hitboxTop.left = -24;
50
BladePole->hitboxTop.top = -32;
51
BladePole->hitboxTop.right = 24;
52
BladePole->hitboxTop.bottom = BladePole->hitboxTop.top + 24;
53
54
self->state = BladePole_State_TopBladeActive;
55
}
56
57
void BladePole_StageLoad(void) { BladePole->aniFrames = RSDK.LoadSpriteAnimation("MMZ/BladePole.bin", SCOPE_STAGE); }
58
59
void BladePole_DrawSprites(void)
60
{
61
RSDK_THIS(BladePole);
62
63
self->direction = FLIP_NONE;
64
Vector2 drawPos = self->position;
65
RSDK.DrawSprite(&self->poleAnimator, &drawPos, false);
66
67
drawPos.y -= 0xC0000;
68
RSDK.DrawSprite(&self->poleAnimator, &drawPos, false);
69
70
drawPos.y -= 0xC0000;
71
RSDK.DrawSprite(&self->poleAnimator, &drawPos, false);
72
73
drawPos.x = self->position.x;
74
drawPos.y = self->position.y - 0x180000;
75
RSDK.DrawSprite(&self->bladeTopAnimator, &drawPos, false);
76
77
if (SceneInfo->inEditor) {
78
drawPos.y += 0x180000;
79
}
80
else {
81
self->direction = FLIP_Y;
82
drawPos.y += 0x3C0000;
83
}
84
85
RSDK.DrawSprite(&self->bladeBottomAnimator, &drawPos, false);
86
self->direction = FLIP_NONE;
87
}
88
89
bool32 BladePole_SetAnimation(Animator *animator)
90
{
91
RSDK_THIS(BladePole);
92
93
switch (animator->animationID) {
94
case 1: RSDK.SetSpriteAnimation(BladePole->aniFrames, 2, animator, true, 0); break;
95
96
case 2:
97
if (animator->frameID == animator->frameCount - 1)
98
RSDK.SetSpriteAnimation(BladePole->aniFrames, 3, animator, true, 0);
99
break;
100
101
case 3:
102
if (self->timer >= 74 && !animator->frameID)
103
RSDK.SetSpriteAnimation(BladePole->aniFrames, 4, animator, true, 0);
104
break;
105
106
case 4:
107
if (animator->frameID == animator->frameCount - 1) {
108
RSDK.SetSpriteAnimation(BladePole->aniFrames, 1, animator, true, 0);
109
return true;
110
}
111
break;
112
113
default: break;
114
}
115
116
return false;
117
}
118
119
void BladePole_CheckPlayerCollisions(Hitbox *hitbox)
120
{
121
RSDK_THIS(BladePole);
122
123
foreach_active(Player, player)
124
{
125
if (Player_CheckCollisionTouch(player, self, hitbox)) {
126
int32 storeX = self->position.x;
127
int32 storeY = self->position.y;
128
129
self->position.y = ((BladePole->hitboxBottom.bottom - BladePole->hitboxBottom.top) << 15) + storeY;
130
#if MANIA_USE_PLUS
131
if (!Player_CheckMightyUnspin(player, 0x400, 2, &player->uncurlTimer))
132
#endif
133
Player_Hurt(player, self);
134
135
self->position.x = storeX;
136
self->position.y = storeY;
137
}
138
}
139
}
140
141
void BladePole_State_TopBladeActive(void)
142
{
143
RSDK_THIS(BladePole);
144
145
if (BladePole_SetAnimation(&self->bladeTopAnimator)) {
146
self->state = BladePole_State_BottomBladeActive;
147
self->timer = 0;
148
}
149
150
if (self->bladeTopAnimator.animationID == 3)
151
BladePole_CheckPlayerCollisions(&BladePole->hitboxTop);
152
153
++self->timer;
154
}
155
156
void BladePole_State_BottomBladeActive(void)
157
{
158
RSDK_THIS(BladePole);
159
160
if (BladePole_SetAnimation(&self->bladeBottomAnimator)) {
161
self->state = BladePole_State_TopBladeActive;
162
self->timer = 0;
163
}
164
165
if (self->bladeBottomAnimator.animationID == 3)
166
BladePole_CheckPlayerCollisions(&BladePole->hitboxBottom);
167
168
++self->timer;
169
}
170
171
#if GAME_INCLUDE_EDITOR
172
void BladePole_EditorDraw(void) { BladePole_DrawSprites(); }
173
174
void BladePole_EditorLoad(void) { BladePole->aniFrames = RSDK.LoadSpriteAnimation("MMZ/BladePole.bin", SCOPE_STAGE); }
175
#endif
176
177
void BladePole_Serialize(void) {}
178
179