Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rubberduckycooly
GitHub Repository: rubberduckycooly/Sonic-Mania-Decompilation
Path: blob/master/SonicMania/Objects/AIZ/AIZTornadoPath.c
338 views
1
// ---------------------------------------------------------------------
2
// RSDK Project: Sonic Mania
3
// Object Description: AIZTornadoPath Object
4
// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges
5
// Decompiled by: Rubberduckycooly & RMGRich
6
// ---------------------------------------------------------------------
7
8
#include "Game.h"
9
10
ObjectAIZTornadoPath *AIZTornadoPath;
11
12
void AIZTornadoPath_Update(void)
13
{
14
RSDK_THIS(AIZTornadoPath);
15
StateMachine_Run(self->state);
16
}
17
18
void AIZTornadoPath_LateUpdate(void) {}
19
20
void AIZTornadoPath_StaticUpdate(void) {}
21
22
void AIZTornadoPath_Draw(void) {}
23
24
void AIZTornadoPath_Create(void *data)
25
{
26
RSDK_THIS(AIZTornadoPath);
27
if (!SceneInfo->inEditor) {
28
switch (self->type) {
29
case AIZTORNADOPATH_START:
30
if (!StarPost->postIDs[0]) {
31
self->active = ACTIVE_NORMAL;
32
EntityCamera *camera = RSDK_GET_ENTITY(SLOT_CAMERA1, Camera);
33
if (camera) {
34
camera->state = StateMachine_None;
35
camera->position.x = self->position.x;
36
camera->position.y = self->position.y;
37
AIZTornadoPath->camera = camera;
38
}
39
40
foreach_all(Player, player) { player->camera = NULL; }
41
42
foreach_all(AIZTornado, tornado) { AIZTornadoPath->tornado = tornado; }
43
ScreenInfo->position.y = FROM_FIXED(self->position.y) - ScreenInfo->center.y;
44
self->speed = self->targetSpeed;
45
self->state = AIZTornadoPath_State_SetTornadoSpeed;
46
}
47
break;
48
49
case AIZTORNADOPATH_DUD: self->active = ACTIVE_NEVER; break;
50
51
case AIZTORNADOPATH_SETSPEED:
52
self->active = ACTIVE_NEVER;
53
self->timer = 1;
54
self->state = AIZTornadoPath_State_SetTornadoSpeed;
55
break;
56
57
case AIZTORNADOPATH_SETCAMERA:
58
self->active = ACTIVE_NEVER;
59
self->state = AIZTornadoPath_State_SetPlayerCamera;
60
break;
61
62
case AIZTORNADOPATH_DISABLEINTERACTIONS:
63
self->active = ACTIVE_NEVER;
64
self->state = AIZTornadoPath_State_DisablePlayerInteractions;
65
break;
66
67
case AIZTORNADOPATH_EXITTORNADO:
68
self->active = ACTIVE_NEVER;
69
self->timer = 1;
70
self->state = AIZTornadoPath_State_ExitTornadoSequence;
71
break;
72
73
case AIZTORNADOPATH_ENTERTORNADO:
74
self->state = AIZTornadoPath_State_PrepareCatchPlayer;
75
self->active = (StarPost->postIDs[0] > 0) ? ACTIVE_XBOUNDS : ACTIVE_NEVER;
76
self->speed = self->targetSpeed;
77
break;
78
79
case AIZTORNADOPATH_TARGETNODE:
80
self->active = ACTIVE_NEVER;
81
self->timer = 1;
82
self->speed = self->targetSpeed;
83
self->state = AIZTornadoPath_State_SetTornadoSpeed;
84
break;
85
86
default: break;
87
}
88
}
89
}
90
91
void AIZTornadoPath_StageLoad(void)
92
{
93
AIZTornadoPath->moveVel.x = 0;
94
AIZTornadoPath->moveVel.y = 0;
95
}
96
97
void AIZTornadoPath_HandleMoveSpeed(void)
98
{
99
RSDK_THIS(AIZTornadoPath);
100
bool32 usingCamPos = false;
101
EntityCamera *camera = AIZTornadoPath->camera;
102
EntityAIZTornado *tornado = AIZTornadoPath->tornado;
103
104
int32 x = 0, y = 0;
105
if (camera && camera->position.x >= ScreenInfo->size.x << 16) {
106
x = camera->position.x;
107
y = camera->position.y;
108
usingCamPos = true;
109
}
110
else {
111
x = tornado->newPos.x;
112
y = tornado->newPos.y;
113
}
114
115
EntityAIZTornadoPath *node = RSDK_GET_ENTITY(SceneInfo->entitySlot + 1, AIZTornadoPath);
116
int32 xDist = (x - node->position.x) >> 16;
117
int32 yDist = (y - node->position.y) >> 16;
118
self->angle = RSDK.ATan2(xDist, yDist);
119
int32 newPosX = x - self->speed * RSDK.Cos256(self->angle);
120
int32 newPosY = y - self->speed * RSDK.Sin256(self->angle);
121
if (usingCamPos) {
122
camera->position.x = newPosX;
123
camera->position.y = newPosY;
124
}
125
126
int32 spd = self->speed >> 3;
127
if (xDist * xDist + yDist * yDist < spd) {
128
self->active = ACTIVE_NEVER;
129
node->active = ACTIVE_NORMAL;
130
if (node->easeToSpeed)
131
node->speed = self->speed;
132
else
133
node->speed = self->targetSpeed;
134
}
135
AIZTornadoPath->moveVel.x = newPosX - x;
136
AIZTornadoPath->moveVel.y = newPosY - y;
137
}
138
139
void AIZTornadoPath_State_SetTornadoSpeed(void)
140
{
141
RSDK_THIS(AIZTornadoPath);
142
143
if (self->speed >= self->targetSpeed) {
144
if (self->speed > self->targetSpeed) {
145
self->speed -= 16;
146
if (self->speed < self->targetSpeed)
147
self->speed = self->targetSpeed;
148
}
149
}
150
else {
151
self->speed += 16;
152
if (self->speed > self->targetSpeed)
153
self->speed = self->targetSpeed;
154
}
155
156
if (self->timer > 0) {
157
self->timer--;
158
}
159
else {
160
AIZTornadoPath_HandleMoveSpeed();
161
}
162
}
163
164
void AIZTornadoPath_State_SetPlayerCamera(void)
165
{
166
EntityPlayer *player = RSDK_GET_ENTITY(SLOT_PLAYER1, Player);
167
EntityCamera *camera = AIZTornadoPath->camera;
168
169
if (camera) {
170
camera->state = Camera_State_FollowXY;
171
player->camera = camera;
172
AIZTornadoPath->camera = NULL;
173
}
174
}
175
176
void AIZTornadoPath_State_DisablePlayerInteractions(void)
177
{
178
RSDK_THIS(AIZTornadoPath);
179
EntityPlayer *player = RSDK_GET_ENTITY(SLOT_PLAYER1, Player);
180
player->collisionPlane = 1;
181
player->interaction = false;
182
183
foreach_active(Player, playerPtr) { playerPtr->drawGroup = Zone->playerDrawGroup[1]; }
184
185
AIZTornadoPath_HandleMoveSpeed();
186
self->state = AIZTornadoPath_State_SetTornadoSpeed;
187
}
188
189
void AIZTornadoPath_State_ExitTornadoSequence(void)
190
{
191
foreach_active(AIZTornado, tornado) { tornado->drawGroup = Zone->objectDrawGroup[0]; }
192
193
if (!tornado->disableInteractions) {
194
EntityPlayer *player = RSDK_GET_ENTITY(SLOT_PLAYER1, Player);
195
EntityCamera *camera = AIZTornadoPath->camera;
196
197
if (camera) {
198
camera->state = Camera_State_FollowXY;
199
player->camera = camera;
200
player->collisionPlane = 0;
201
player->interaction = true;
202
player->applyJumpCap = false;
203
player->drawGroup = Zone->playerDrawGroup[0];
204
AIZTornadoPath->camera = NULL;
205
}
206
player->groundVel = AIZTornadoPath->moveVel.x;
207
Player_Action_Jump(player);
208
player->right = true;
209
tornado->disableInteractions = true;
210
}
211
212
AIZTornadoPath_State_SetTornadoSpeed();
213
}
214
215
void AIZTornadoPath_State_PrepareCatchPlayer(void)
216
{
217
RSDK_THIS(AIZTornadoPath);
218
EntityPlayer *player = RSDK_GET_ENTITY(SLOT_PLAYER1, Player);
219
220
if (player->position.x > self->position.x) {
221
player->stateInput = StateMachine_None;
222
player->left = false;
223
player->right = true;
224
if (player->pushing > 0) {
225
player->jumpPress = true;
226
player->jumpHold = true;
227
self->state = AIZTornadoPath_State_CatchPlayer;
228
AIZTornadoPath->moveVel.x = 0;
229
AIZTornadoPath->moveVel.y = 0;
230
}
231
}
232
}
233
234
void AIZTornadoPath_State_CatchPlayer(void)
235
{
236
RSDK_THIS(AIZTornadoPath);
237
EntityPlayer *player = RSDK_GET_ENTITY(SLOT_PLAYER1, Player);
238
239
++self->timer;
240
if (self->timer == 60) {
241
foreach_all(AIZTornado, tornado)
242
{
243
tornado->position.x = player->position.x - 0x1400000;
244
tornado->position.y = player->position.y + 0x400000;
245
tornado->offsetX = 0x40000;
246
tornado->state = AIZTornado_State_Move;
247
tornado->active = ACTIVE_NORMAL;
248
}
249
}
250
251
if (self->timer == 90) {
252
self->timer = 0;
253
player->stateInput = Player_Input_P1;
254
int32 velX = 0;
255
foreach_all(AIZTornadoPath, node)
256
{
257
if (node->type == AIZTORNADOPATH_TARGETNODE) {
258
velX = node->position.x - player->position.x;
259
node->active = ACTIVE_NORMAL;
260
}
261
}
262
263
player->position.x += velX;
264
if (player->camera) {
265
player->camera->position.x += velX;
266
player->camera->state = StateMachine_None;
267
AIZTornadoPath->camera = player->camera;
268
player->camera = NULL;
269
}
270
271
foreach_active(AIZTornado, tornado)
272
{
273
tornado->position.x += velX;
274
tornado->offsetX = 0x80000;
275
}
276
}
277
}
278
279
#if GAME_INCLUDE_EDITOR
280
void AIZTornadoPath_EditorDraw(void)
281
{
282
RSDK_THIS(AIZTornadoPath);
283
RSDK.SetSpriteAnimation(AIZTornadoPath->aniFrames, 0, &self->unusedAnimator, true, 7);
284
RSDK.DrawSprite(&self->unusedAnimator, NULL, false);
285
}
286
287
void AIZTornadoPath_EditorLoad(void)
288
{
289
AIZTornadoPath->aniFrames = RSDK.LoadSpriteAnimation("Editor/EditorIcons.bin", SCOPE_STAGE);
290
RSDK.SetSpriteAnimation(AIZTornadoPath->aniFrames, 0, &AIZTornadoPath->unusedAnimator, true, 7);
291
292
RSDK_ACTIVE_VAR(AIZTornadoPath, type);
293
RSDK_ENUM_VAR("Start Node", AIZTORNADOPATH_START);
294
RSDK_ENUM_VAR("Blank Node", AIZTORNADOPATH_DUD);
295
RSDK_ENUM_VAR("Set Tornado Speed", AIZTORNADOPATH_SETSPEED);
296
RSDK_ENUM_VAR("Return Player Camera", AIZTORNADOPATH_SETCAMERA);
297
RSDK_ENUM_VAR("Disable Player Interactions", AIZTORNADOPATH_DISABLEINTERACTIONS);
298
RSDK_ENUM_VAR("Exit Tornado Sequence", AIZTORNADOPATH_EXITTORNADO);
299
RSDK_ENUM_VAR("Enter Tornado Sequence (Fly to Target Node)", AIZTORNADOPATH_ENTERTORNADO);
300
RSDK_ENUM_VAR("Set Tornado Speed (Target Node)", AIZTORNADOPATH_TARGETNODE);
301
}
302
#endif
303
304
void AIZTornadoPath_Serialize(void)
305
{
306
RSDK_EDITABLE_VAR(AIZTornadoPath, VAR_ENUM, type);
307
RSDK_EDITABLE_VAR(AIZTornadoPath, VAR_ENUM, targetSpeed);
308
RSDK_EDITABLE_VAR(AIZTornadoPath, VAR_ENUM, timer);
309
RSDK_EDITABLE_VAR(AIZTornadoPath, VAR_BOOL, easeToSpeed);
310
}
311
312