Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rubberduckycooly
GitHub Repository: rubberduckycooly/Sonic-Mania-Decompilation
Path: blob/master/SonicMania/Objects/Common/ForceSpin.c
338 views
1
// ---------------------------------------------------------------------
2
// RSDK Project: Sonic Mania
3
// Object Description: ForceSpin Object
4
// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges
5
// Decompiled by: Rubberduckycooly & RMGRich
6
// ---------------------------------------------------------------------
7
8
#include "Game.h"
9
10
ObjectForceSpin *ForceSpin;
11
12
void ForceSpin_Update(void)
13
{
14
RSDK_THIS(ForceSpin);
15
16
foreach_active(Player, player)
17
{
18
Vector2 pivotPos = player->position;
19
Vector2 pivotVel = player->velocity;
20
21
Zone_RotateOnPivot(&pivotPos, &self->position, self->negAngle);
22
Zone_RotateOnPivot(&pivotVel, &self->velocity, self->negAngle);
23
24
if (abs(pivotPos.x - self->position.x) < TO_FIXED(24) && abs(pivotPos.y - self->position.y) < self->size << 19) {
25
if (pivotPos.x >= self->position.x) {
26
if (self->direction) {
27
if (player->state == Player_State_TubeRoll || player->state == Player_State_TubeAirRoll) {
28
player->state = player->onGround ? Player_State_Roll : Player_State_Air;
29
player->nextGroundState = StateMachine_None;
30
player->nextAirState = StateMachine_None;
31
}
32
}
33
else {
34
ForceSpin_SetPlayerState(player);
35
}
36
}
37
else {
38
if (!self->direction) {
39
if (player->state == Player_State_TubeRoll || player->state == Player_State_TubeAirRoll) {
40
player->state = player->onGround ? Player_State_Roll : Player_State_Air;
41
player->nextGroundState = StateMachine_None;
42
player->nextAirState = StateMachine_None;
43
}
44
}
45
else {
46
ForceSpin_SetPlayerState(player);
47
}
48
}
49
}
50
}
51
52
self->visible = DebugMode->debugActive;
53
}
54
55
void ForceSpin_LateUpdate(void) {}
56
57
void ForceSpin_StaticUpdate(void) {}
58
59
void ForceSpin_Draw(void) { ForceSpin_DrawSprites(); }
60
61
void ForceSpin_Create(void *data)
62
{
63
RSDK_THIS(ForceSpin);
64
65
RSDK.SetSpriteAnimation(ForceSpin->aniFrames, 0, &self->animator, true, 0);
66
self->animator.frameID = 4;
67
self->drawFX |= FX_FLIP;
68
69
if (!SceneInfo->inEditor) {
70
self->active = ACTIVE_BOUNDS;
71
self->updateRange.x = TO_FIXED(32) + abs(self->size * RSDK.Sin256(self->angle) << 11);
72
self->updateRange.y = TO_FIXED(32) + abs(self->size * RSDK.Cos256(self->angle) << 11);
73
self->visible = false;
74
self->drawGroup = Zone->objectDrawGroup[0];
75
self->negAngle = -self->angle & 0xFF;
76
}
77
}
78
79
void ForceSpin_StageLoad(void) { ForceSpin->aniFrames = RSDK.LoadSpriteAnimation("Global/PlaneSwitch.bin", SCOPE_STAGE); }
80
81
void ForceSpin_DrawSprites(void)
82
{
83
RSDK_THIS(ForceSpin);
84
85
Vector2 drawPos;
86
drawPos.x = self->position.x;
87
drawPos.y = self->position.y - (self->size << 19);
88
Zone_RotateOnPivot(&drawPos, &self->position, self->angle);
89
90
for (int32 i = 0; i < self->size; ++i) {
91
RSDK.DrawSprite(&self->animator, &drawPos, false);
92
drawPos.x += RSDK.Sin256(self->angle) << 12;
93
drawPos.y += RSDK.Cos256(self->angle) << 12;
94
}
95
}
96
void ForceSpin_SetPlayerState(EntityPlayer *player)
97
{
98
RSDK_THIS(ForceSpin);
99
100
if (player->state != Player_State_TubeRoll && player->state != Player_State_TubeAirRoll) {
101
if (player->animator.animationID != ANI_JUMP) {
102
RSDK.PlaySfx(Player->sfxRoll, false, 0xFF);
103
RSDK.SetSpriteAnimation(player->aniFrames, ANI_JUMP, &player->animator, false, 0);
104
if (!player->collisionMode && player->onGround)
105
player->position.y += player->jumpOffset;
106
player->pushing = 0;
107
}
108
109
player->state = player->onGround ? Player_State_TubeRoll : Player_State_TubeAirRoll;
110
player->nextGroundState = StateMachine_None;
111
player->nextAirState = StateMachine_None;
112
113
if (abs(player->groundVel) < 0x10000) {
114
if (self->direction & FLIP_X)
115
player->groundVel = -0x40000;
116
else
117
player->groundVel = 0x40000;
118
}
119
}
120
}
121
122
#if GAME_INCLUDE_EDITOR
123
void ForceSpin_EditorDraw(void)
124
{
125
RSDK_THIS(ForceSpin);
126
127
self->updateRange.x = TO_FIXED(32) + abs(self->size * RSDK.Sin256(self->angle) << 11);
128
self->updateRange.y = TO_FIXED(32) + abs(self->size * RSDK.Cos256(self->angle) << 11);
129
130
ForceSpin_DrawSprites();
131
}
132
133
void ForceSpin_EditorLoad(void)
134
{
135
ForceSpin->aniFrames = RSDK.LoadSpriteAnimation("Global/PlaneSwitch.bin", SCOPE_STAGE);
136
137
RSDK_ACTIVE_VAR(ForceSpin, direction);
138
RSDK_ENUM_VAR("Enter From Right, Exit From Left", FLIP_NONE);
139
RSDK_ENUM_VAR("Enter From Left, Exit From Right", FLIP_X);
140
}
141
#endif
142
143
void ForceSpin_Serialize(void)
144
{
145
RSDK_EDITABLE_VAR(ForceSpin, VAR_UINT8, direction);
146
RSDK_EDITABLE_VAR(ForceSpin, VAR_ENUM, size);
147
RSDK_EDITABLE_VAR(ForceSpin, VAR_INT32, angle);
148
}
149
150