Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rubberduckycooly
GitHub Repository: rubberduckycooly/Sonic-Mania-Decompilation
Path: blob/master/SonicMania/Objects/TMZ/MagnetSphere.c
338 views
1
// ---------------------------------------------------------------------
2
// RSDK Project: Sonic Mania
3
// Object Description: MagnetSphere Object
4
// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges
5
// Decompiled by: Rubberduckycooly & RMGRich
6
// ---------------------------------------------------------------------
7
8
#include "Game.h"
9
10
ObjectMagnetSphere *MagnetSphere;
11
12
void MagnetSphere_Update(void)
13
{
14
RSDK_THIS(MagnetSphere);
15
16
RSDK.ProcessAnimation(&self->plasma1Animator);
17
RSDK.ProcessAnimation(&self->plasma2Animator);
18
RSDK.ProcessAnimation(&self->centerBallAnimator);
19
20
MagnetSphere_CheckPlayerCollision();
21
}
22
23
void MagnetSphere_LateUpdate(void) {}
24
25
void MagnetSphere_StaticUpdate(void) {}
26
27
void MagnetSphere_Draw(void)
28
{
29
RSDK_THIS(MagnetSphere);
30
31
self->inkEffect = INK_SUB;
32
RSDK.DrawSprite(&self->glassInnerAnimator, NULL, false);
33
34
self->inkEffect = INK_ADD;
35
RSDK.DrawSprite(&self->plasma1Animator, NULL, false);
36
37
self->direction = INK_ADD;
38
RSDK.DrawSprite(&self->plasma2Animator, NULL, false);
39
40
self->direction = INK_NONE;
41
RSDK.DrawSprite(&self->glassOuterAnimator, NULL, false);
42
43
self->inkEffect = INK_NONE;
44
RSDK.DrawSprite(&self->centerBallAnimator, NULL, false);
45
}
46
47
void MagnetSphere_Create(void *data)
48
{
49
RSDK_THIS(MagnetSphere);
50
51
self->drawFX = FX_FLIP;
52
self->visible = true;
53
self->drawGroup = Zone->objectDrawGroup[1];
54
self->active = ACTIVE_BOUNDS;
55
self->alpha = 0xFF;
56
self->updateRange.x = 0x400000;
57
self->updateRange.y = 0x400000;
58
59
RSDK.SetSpriteAnimation(MagnetSphere->aniFrames, 0, &self->glassInnerAnimator, true, 0);
60
RSDK.SetSpriteAnimation(MagnetSphere->aniFrames, 0, &self->glassOuterAnimator, true, 1);
61
RSDK.SetSpriteAnimation(MagnetSphere->aniFrames, 1, &self->plasma1Animator, true, 0);
62
RSDK.SetSpriteAnimation(MagnetSphere->aniFrames, 1, &self->plasma2Animator, true, 8);
63
RSDK.SetSpriteAnimation(MagnetSphere->aniFrames, 2, &self->centerBallAnimator, true, 0);
64
}
65
66
void MagnetSphere_StageLoad(void)
67
{
68
if (RSDK.CheckSceneFolder("TMZ1") || RSDK.CheckSceneFolder("TMZ2"))
69
MagnetSphere->aniFrames = RSDK.LoadSpriteAnimation("TMZ1/MagnetSphere.bin", SCOPE_STAGE);
70
71
MagnetSphere->hitbox.left = -56;
72
MagnetSphere->hitbox.top = -56;
73
MagnetSphere->hitbox.right = 56;
74
MagnetSphere->hitbox.bottom = 56;
75
76
MagnetSphere->sfxBumper = RSDK.GetSfx("Stage/Bumper3.wav");
77
MagnetSphere->sfxPlasmaBall = RSDK.GetSfx("TMZ1/PlasmaBall.wav");
78
79
DEBUGMODE_ADD_OBJ(MagnetSphere);
80
}
81
82
void MagnetSphere_DebugSpawn(void)
83
{
84
RSDK_THIS(DebugMode);
85
86
CREATE_ENTITY(MagnetSphere, NULL, self->position.x, self->position.y);
87
}
88
89
void MagnetSphere_DebugDraw(void)
90
{
91
RSDK.SetSpriteAnimation(MagnetSphere->aniFrames, 0, &DebugMode->animator, true, 1);
92
RSDK.DrawSprite(&DebugMode->animator, NULL, false);
93
}
94
95
void MagnetSphere_CheckPlayerCollision(void)
96
{
97
RSDK_THIS(MagnetSphere);
98
99
foreach_active(Player, player)
100
{
101
int32 playerID = RSDK.GetEntitySlot(player);
102
103
if ((1 << playerID) & self->activePlayers) {
104
if (player->state != Player_State_Static) {
105
self->playerTimers[playerID] = 30;
106
self->activePlayers &= ~(1 << playerID);
107
108
if (player->state != Player_State_Death)
109
player->tileCollisions = TILECOLLISION_DOWN;
110
}
111
else if (!player->jumpPress) {
112
if (player->left)
113
--MagnetSphere->playerAngles[playerID];
114
else if (player->right)
115
++MagnetSphere->playerAngles[playerID];
116
117
MagnetSphere_MovePlayer(player, playerID);
118
}
119
else {
120
int32 ang =
121
12
122
* RSDK.Sin256(MagnetSphere->angleTable[MagnetSphere->sphereAngle[playerID] >> 4] | (MagnetSphere->sphereAngle[playerID] & 0xF));
123
124
player->velocity.x = ang * RSDK.Sin256(MagnetSphere->playerAngles[playerID]);
125
player->velocity.y = -(ang * RSDK.Cos256(MagnetSphere->playerAngles[playerID]));
126
player->applyJumpCap = false;
127
player->jumpAbilityState = 1;
128
player->tileCollisions = TILECOLLISION_DOWN;
129
player->state = Player_State_Air;
130
self->playerTimers[playerID] = 30;
131
self->activePlayers &= ~(1 << playerID);
132
133
RSDK.PlaySfx(Player->sfxJump, false, 255);
134
}
135
}
136
else {
137
if (!self->playerTimers[playerID] && player->state != Player_State_Static) {
138
if (Player_CheckCollisionTouch(player, self, &MagnetSphere->hitbox)) {
139
int32 angle = RSDK.ATan2(self->position.x - player->position.x, self->position.y - player->position.y);
140
141
if (angle >= 0x80) {
142
MagnetSphere->sphereAngle[playerID] = -0x80;
143
MagnetSphere->playerAngles[playerID] = angle + -0x80;
144
}
145
else {
146
MagnetSphere->sphereAngle[playerID] = 0;
147
MagnetSphere->playerAngles[playerID] = angle;
148
}
149
MagnetSphere->playerAngles[playerID] += 0x40;
150
151
player->velocity.x = 0;
152
player->velocity.y = 0;
153
player->groundVel = 0;
154
RSDK.SetSpriteAnimation(player->aniFrames, ANI_JUMP, &player->animator, false, 0);
155
156
player->onGround = false;
157
player->tileCollisions = TILECOLLISION_NONE;
158
player->state = Player_State_Static;
159
player->nextAirState = StateMachine_None;
160
player->nextGroundState = StateMachine_None;
161
162
self->activePlayers |= 1 << playerID;
163
MagnetSphere_MovePlayer(player, playerID);
164
}
165
}
166
else if (self->playerTimers[playerID]) {
167
self->playerTimers[playerID]--;
168
}
169
}
170
}
171
}
172
173
void MagnetSphere_MovePlayer(EntityPlayer *player, int32 playerID)
174
{
175
RSDK_THIS(MagnetSphere);
176
177
int32 ang = 56 * RSDK.Cos256(MagnetSphere->sphereAngle[playerID]) >> 8;
178
player->velocity.x = -RSDK.Sin256(MagnetSphere->playerAngles[playerID]);
179
player->velocity.y = RSDK.Cos256(MagnetSphere->playerAngles[playerID]);
180
player->position.x = self->position.x - (ang * RSDK.Sin256(MagnetSphere->playerAngles[playerID]) << 8);
181
player->position.y = self->position.y + (ang * RSDK.Cos256(MagnetSphere->playerAngles[playerID]) << 8);
182
183
if (MagnetSphere->sphereAngle[playerID] >= 0x80) {
184
player->drawGroup = Zone->playerDrawGroup[1];
185
}
186
else {
187
player->drawGroup = Zone->playerDrawGroup[0];
188
player->velocity.x = -player->velocity.x;
189
player->velocity.y = -player->velocity.y;
190
}
191
192
uint8 angle = MagnetSphere->sphereAngle[playerID];
193
MagnetSphere->sphereAngle[playerID] += 4;
194
195
uint32 angVal = (((uint32)MagnetSphere->sphereAngle[playerID] + 64) >> 7) & 1;
196
uint8 angValPrev = ((angle + 64) >> 7) & 1;
197
if (angVal != angValPrev && !player->sidekick)
198
RSDK.PlaySfx(MagnetSphere->sfxPlasmaBall, false, 255);
199
}
200
201
#if GAME_INCLUDE_EDITOR
202
void MagnetSphere_EditorDraw(void) { MagnetSphere_Draw(); }
203
204
void MagnetSphere_EditorLoad(void) { MagnetSphere->aniFrames = RSDK.LoadSpriteAnimation("TMZ1/MagnetSphere.bin", SCOPE_STAGE); }
205
#endif
206
207
void MagnetSphere_Serialize(void) {}
208
209