Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rubberduckycooly
GitHub Repository: rubberduckycooly/Sonic-Mania-Decompilation
Path: blob/master/SonicMania/Objects/SSZ/RTeleporter.c
338 views
1
// ---------------------------------------------------------------------
2
// RSDK Project: Sonic Mania
3
// Object Description: RTeleporter Object
4
// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges
5
// Decompiled by: Rubberduckycooly & RMGRich
6
// ---------------------------------------------------------------------
7
8
#include "Game.h"
9
10
ObjectRTeleporter *RTeleporter;
11
12
void RTeleporter_Update(void)
13
{
14
RSDK_THIS(RTeleporter);
15
16
StateMachine_Run(self->state);
17
}
18
19
void RTeleporter_LateUpdate(void) {}
20
21
void RTeleporter_StaticUpdate(void) {}
22
23
void RTeleporter_Draw(void)
24
{
25
RSDK_THIS(RTeleporter);
26
27
StateMachine_Run(self->stateDraw);
28
}
29
30
void RTeleporter_Create(void *data)
31
{
32
RSDK_THIS(RTeleporter);
33
34
self->drawFX = FX_FLIP;
35
36
if (!SceneInfo->inEditor) {
37
self->active = ACTIVE_BOUNDS;
38
self->visible = true;
39
self->drawGroup = Zone->objectDrawGroup[1];
40
self->updateRange.x = 0x800000;
41
self->updateRange.y = 0x800000;
42
43
RSDK.SetSpriteAnimation(RTeleporter->aniFrames, 0, &self->mainAnimator, true, 0);
44
RSDK.SetSpriteAnimation(RTeleporter->aniFrames, 1, &self->electricAnimator, true, 0);
45
46
self->originY = self->position.y;
47
self->state = RTeleporter_State_CheckPlayerCollisions;
48
self->stateDraw = RTeleporter_Draw_Active;
49
}
50
}
51
52
void RTeleporter_StageLoad(void)
53
{
54
if (RSDK.CheckSceneFolder("SSZ1") || RSDK.CheckSceneFolder("SSZ2"))
55
RTeleporter->aniFrames = RSDK.LoadSpriteAnimation("SSZ/RTeleporter.bin", SCOPE_STAGE);
56
else if (RSDK.CheckSceneFolder("MMZ1") || RSDK.CheckSceneFolder("MMZ2"))
57
RTeleporter->aniFrames = RSDK.LoadSpriteAnimation("MMZ/RTeleporter.bin", SCOPE_STAGE);
58
59
RTeleporter->hitboxTeleporter.top = -32;
60
RTeleporter->hitboxTeleporter.left = -34;
61
RTeleporter->hitboxTeleporter.right = 34;
62
RTeleporter->hitboxTeleporter.bottom = 32;
63
64
RTeleporter->sfxExplosion = RSDK.GetSfx("Stage/Explosion2.wav");
65
RTeleporter->sfxGoodFuture = RSDK.GetSfx("Stage/GoodFuture.wav");
66
}
67
68
void RTeleporter_State_CheckPlayerCollisions(void)
69
{
70
RSDK_THIS(RTeleporter);
71
72
RSDK.ProcessAnimation(&self->mainAnimator);
73
RSDK.ProcessAnimation(&self->electricAnimator);
74
75
self->position.y = BadnikHelpers_Oscillate(self->originY, 4, 9);
76
77
foreach_active(Player, player)
78
{
79
if (!player->onGround) {
80
if (Player_CheckCollisionTouch(player, self, &RTeleporter->hitboxTeleporter)) {
81
Player_CheckItemBreak(player, self, false);
82
self->state = RTeleporter_State_Destroyed;
83
self->stateDraw = RTeleporter_Draw_Exploding;
84
}
85
}
86
}
87
}
88
89
void RTeleporter_State_Destroyed(void)
90
{
91
RSDK_THIS(RTeleporter);
92
93
if (!(Zone->timer % 3)) {
94
RSDK.PlaySfx(RTeleporter->sfxExplosion, false, 255);
95
96
if (Zone->timer & 4) {
97
int32 x = self->position.x + (RSDK.Rand(-32, 32) << 16);
98
int32 y = self->position.y + (RSDK.Rand(-32, 32) << 16);
99
EntityExplosion *explosion = CREATE_ENTITY(Explosion, INT_TO_VOID(((RSDK.Rand(0, 256) > 192) + EXPLOSION_BOSS)), x, y);
100
explosion->drawGroup = Zone->objectDrawGroup[1];
101
}
102
}
103
104
if (++self->timer == 80) {
105
RSDK.PlaySfx(RTeleporter->sfxGoodFuture, false, 255);
106
RSDK.SetSpriteAnimation(RTeleporter->aniFrames, 2, &self->mainAnimator, true, 0);
107
108
self->position.y += 0x180000;
109
RSDK.ObjectTileGrip(self, Zone->collisionLayers, CMODE_FLOOR, 0, 0, 0x80000, 8);
110
111
self->state = StateMachine_None;
112
self->stateDraw = RTeleporter_Draw_Destroyed;
113
}
114
}
115
116
void RTeleporter_Draw_Active(void)
117
{
118
RSDK_THIS(RTeleporter);
119
Vector2 drawPos;
120
121
drawPos.x = self->position.x;
122
drawPos.y = self->position.y;
123
RSDK.DrawSprite(&self->mainAnimator, NULL, false);
124
125
self->direction = FLIP_Y;
126
RSDK.DrawSprite(&self->mainAnimator, NULL, false);
127
128
self->direction = FLIP_NONE;
129
RSDK.DrawSprite(&self->electricAnimator, NULL, false);
130
131
drawPos.x -= 0x100000;
132
RSDK.DrawSprite(&self->electricAnimator, &drawPos, false);
133
134
drawPos.x += 0x200000;
135
RSDK.DrawSprite(&self->electricAnimator, &drawPos, false);
136
}
137
138
void RTeleporter_Draw_Exploding(void)
139
{
140
RSDK_THIS(RTeleporter);
141
142
RSDK.DrawSprite(&self->mainAnimator, NULL, false);
143
144
self->direction = FLIP_Y;
145
RSDK.DrawSprite(&self->mainAnimator, NULL, false);
146
147
self->direction = FLIP_NONE;
148
}
149
150
void RTeleporter_Draw_Destroyed(void)
151
{
152
RSDK_THIS(RTeleporter);
153
154
RSDK.DrawSprite(&self->mainAnimator, NULL, false);
155
}
156
157
#if GAME_INCLUDE_EDITOR
158
void RTeleporter_EditorDraw(void)
159
{
160
RSDK_THIS(RTeleporter);
161
162
RSDK.SetSpriteAnimation(RTeleporter->aniFrames, 0, &self->mainAnimator, true, 0);
163
RSDK.SetSpriteAnimation(RTeleporter->aniFrames, 1, &self->electricAnimator, true, 0);
164
165
RTeleporter_Draw_Active();
166
}
167
168
void RTeleporter_EditorLoad(void)
169
{
170
if (RSDK.CheckSceneFolder("SSZ1") || RSDK.CheckSceneFolder("SSZ2"))
171
RTeleporter->aniFrames = RSDK.LoadSpriteAnimation("SSZ/RTeleporter.bin", SCOPE_STAGE);
172
else if (RSDK.CheckSceneFolder("MMZ1") || RSDK.CheckSceneFolder("MMZ2"))
173
RTeleporter->aniFrames = RSDK.LoadSpriteAnimation("MMZ/RTeleporter.bin", SCOPE_STAGE);
174
}
175
#endif
176
177
void RTeleporter_Serialize(void) {}
178
179