Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rubberduckycooly
GitHub Repository: rubberduckycooly/Sonic-Mania-Decompilation
Path: blob/master/SonicMania/Objects/HCZ/HCZOneWayDoor.c
338 views
1
// ---------------------------------------------------------------------
2
// RSDK Project: Sonic Mania
3
// Object Description: HCZOneWayDoor Object
4
// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges
5
// Decompiled by: Rubberduckycooly & RMGRich
6
// ---------------------------------------------------------------------
7
8
#include "Game.h"
9
10
ObjectHCZOneWayDoor *HCZOneWayDoor;
11
12
void HCZOneWayDoor_Update(void)
13
{
14
RSDK_THIS(HCZOneWayDoor);
15
16
bool32 shouldShut = false;
17
int32 storeX = self->position.x;
18
int32 storeY = self->position.y;
19
20
foreach_active(Player, player)
21
{
22
self->position.x = storeX;
23
self->position.y = storeY;
24
Player_CheckCollisionBox(player, self, &self->hitboxSolid);
25
26
self->position = self->startPos;
27
if (!player->sidekick) {
28
if (Player_CheckCollisionTouch(player, self, &self->hitboxTrigger))
29
shouldShut = true;
30
}
31
}
32
33
self->position.x = storeX;
34
self->position.y = storeY;
35
36
if (shouldShut) {
37
if (self->movePos >= self->duration) {
38
switch (self->orientation) {
39
case HCZONEWAYDOOR_UP: self->position.y = self->startPos.y - self->size.y; break;
40
case HCZONEWAYDOOR_LEFT: self->position.x = self->startPos.x - self->size.x; break;
41
case HCZONEWAYDOOR_DOWN: self->position.y = self->startPos.y + self->size.y; break;
42
case HCZONEWAYDOOR_RIGHT: self->position.x = self->startPos.x + self->size.x; break;
43
}
44
}
45
else {
46
switch (self->orientation) {
47
case HCZONEWAYDOOR_UP: self->position.y = self->startPos.y - self->movePos * (self->size.y / self->duration); break;
48
case HCZONEWAYDOOR_LEFT: self->position.x = self->startPos.x - self->movePos * (self->size.x / self->duration); break;
49
case HCZONEWAYDOOR_DOWN: self->position.y = self->startPos.y + self->movePos * (self->size.y / self->duration); break;
50
case HCZONEWAYDOOR_RIGHT: self->position.x = self->startPos.x + self->movePos * (self->size.x / self->duration); break;
51
}
52
53
if (++self->movePos >= self->duration) {
54
if (self->onScreen)
55
RSDK.PlaySfx(HCZOneWayDoor->sfxClack, false, 255);
56
}
57
}
58
}
59
else {
60
if (self->movePos > 0) {
61
switch (self->orientation) {
62
case HCZONEWAYDOOR_UP: self->position.y = self->startPos.y - self->movePos * (self->size.y / self->duration); break;
63
case HCZONEWAYDOOR_LEFT: self->position.x = self->startPos.x - self->movePos * (self->size.x / self->duration); break;
64
case HCZONEWAYDOOR_DOWN: self->position.y = self->startPos.y + self->movePos * (self->size.y / self->duration); break;
65
case HCZONEWAYDOOR_RIGHT: self->position.x = self->startPos.x + self->movePos * (self->size.x / self->duration); break;
66
}
67
68
if (--self->movePos <= 0) {
69
if (self->onScreen)
70
RSDK.PlaySfx(HCZOneWayDoor->sfxClack, false, 255);
71
}
72
}
73
else {
74
switch (self->orientation) {
75
case HCZONEWAYDOOR_UP: self->position.y = self->startPos.y; break;
76
case HCZONEWAYDOOR_LEFT: self->position.x = self->startPos.x; break;
77
case HCZONEWAYDOOR_DOWN: self->position.y = self->startPos.y; break;
78
case HCZONEWAYDOOR_RIGHT: self->position.x = self->startPos.x; break;
79
}
80
}
81
}
82
}
83
84
void HCZOneWayDoor_LateUpdate(void) {}
85
86
void HCZOneWayDoor_StaticUpdate(void) {}
87
88
void HCZOneWayDoor_Draw(void) { HCZOneWayDoor_DrawSprites(); }
89
90
void HCZOneWayDoor_Create(void *data)
91
{
92
RSDK_THIS(HCZOneWayDoor);
93
94
if (!self->duration)
95
self->duration = 6;
96
97
if (!self->length)
98
self->length = 2;
99
100
self->active = ACTIVE_BOUNDS;
101
self->drawGroup = Zone->objectDrawGroup[0];
102
self->startPos = self->position;
103
self->visible = true;
104
self->drawFX = FX_FLIP;
105
HCZOneWayDoor_SetupHitboxes();
106
self->updateRange.x = 0x800000 + self->size.x;
107
self->updateRange.y = 0x800000 + self->size.y;
108
RSDK.SetSpriteAnimation(HCZOneWayDoor->aniFrames, 0, &self->animator, true, 0);
109
}
110
111
void HCZOneWayDoor_StageLoad(void)
112
{
113
HCZOneWayDoor->aniFrames = RSDK.LoadSpriteAnimation("HCZ/ButtonDoor.bin", SCOPE_STAGE);
114
115
HCZOneWayDoor->sfxClack = RSDK.GetSfx("Stage/Clack2.wav");
116
}
117
118
void HCZOneWayDoor_SetupHitboxes(void)
119
{
120
RSDK_THIS(HCZOneWayDoor);
121
122
self->size.x = 0x200000;
123
self->size.y = 0x200000;
124
self->initialSize.x = self->size.x;
125
self->initialSize.y = self->size.y;
126
127
if (self->orientation == HCZONEWAYDOOR_UP || self->orientation == HCZONEWAYDOOR_DOWN)
128
self->size.y = self->length << 21;
129
else if (self->orientation == HCZONEWAYDOOR_LEFT || self->orientation == HCZONEWAYDOOR_RIGHT)
130
self->size.x = self->length << 21;
131
132
self->hitboxSolid.right = self->size.x >> 17;
133
self->hitboxSolid.bottom = self->size.y >> 17;
134
self->hitboxSolid.left = -(self->size.x >> 17);
135
self->hitboxSolid.top = -(self->size.y >> 17);
136
137
switch (self->orientation) {
138
case HCZONEWAYDOOR_UP:
139
case HCZONEWAYDOOR_DOWN:
140
self->hitboxTrigger.top = -(self->size.y >> 17);
141
self->hitboxTrigger.left = -(self->size.x >> 17);
142
self->hitboxTrigger.right = self->size.x >> 17;
143
self->hitboxTrigger.bottom = self->size.y >> 17;
144
145
if (self->detectDirection == FLIP_X)
146
self->hitboxTrigger.right = (self->size.x >> 17) + (self->initialSize.y >> 14);
147
else if (self->detectDirection == FLIP_NONE)
148
self->hitboxTrigger.left = -(self->size.x >> 17) - (self->initialSize.y >> 14);
149
break;
150
151
case HCZONEWAYDOOR_LEFT:
152
case HCZONEWAYDOOR_RIGHT:
153
self->hitboxTrigger.right = self->size.y >> 17;
154
self->hitboxTrigger.top = -(self->size.y >> 17);
155
self->hitboxTrigger.left = -(self->size.x >> 17);
156
self->hitboxTrigger.bottom = self->size.y >> 17;
157
158
if (self->detectDirection == FLIP_X)
159
self->hitboxTrigger.top = -(self->size.y >> 17) - (self->initialSize.x >> 14);
160
else if (self->detectDirection == FLIP_NONE)
161
self->hitboxTrigger.bottom = (self->size.y >> 17) + (self->initialSize.x >> 14);
162
break;
163
164
default: break;
165
}
166
}
167
168
void HCZOneWayDoor_DrawSprites(void)
169
{
170
RSDK_THIS(HCZOneWayDoor);
171
172
Vector2 drawPos = self->position;
173
174
int32 offsetX = 0, offsetY = 0;
175
if (self->orientation == HCZONEWAYDOOR_UP || self->orientation == HCZONEWAYDOOR_DOWN) {
176
drawPos.y = (self->initialSize.y >> 1) + self->position.y - (self->size.y >> 1);
177
offsetY = self->initialSize.y;
178
}
179
else if (self->orientation == HCZONEWAYDOOR_LEFT || self->orientation == HCZONEWAYDOOR_RIGHT) {
180
drawPos.x = (self->initialSize.x >> 1) + self->position.x - (self->size.x >> 1);
181
offsetX = self->initialSize.x;
182
}
183
184
for (int32 i = 0; i < self->length; ++i) {
185
RSDK.DrawSprite(&self->animator, &drawPos, false);
186
drawPos.x += offsetX;
187
drawPos.y += offsetY;
188
}
189
}
190
191
#if GAME_INCLUDE_EDITOR
192
void HCZOneWayDoor_EditorDraw(void) { HCZOneWayDoor_DrawSprites(); }
193
194
void HCZOneWayDoor_EditorLoad(void)
195
{
196
HCZOneWayDoor->aniFrames = RSDK.LoadSpriteAnimation("HCZ/ButtonDoor.bin", SCOPE_STAGE);
197
198
RSDK_ACTIVE_VAR(HCZOneWayDoor, orientation);
199
RSDK_ENUM_VAR("Up", HCZONEWAYDOOR_UP);
200
RSDK_ENUM_VAR("Left", HCZONEWAYDOOR_LEFT);
201
RSDK_ENUM_VAR("Down", HCZONEWAYDOOR_DOWN);
202
RSDK_ENUM_VAR("Right", HCZONEWAYDOOR_RIGHT);
203
204
RSDK_ACTIVE_VAR(HCZOneWayDoor, detectDirection);
205
RSDK_ENUM_VAR("No Flip", FLIP_NONE); // Left/Top
206
RSDK_ENUM_VAR("Flipped", FLIP_X); // Right/Bottom
207
}
208
#endif
209
210
void HCZOneWayDoor_Serialize(void)
211
{
212
RSDK_EDITABLE_VAR(HCZOneWayDoor, VAR_ENUM, length);
213
RSDK_EDITABLE_VAR(HCZOneWayDoor, VAR_ENUM, duration);
214
RSDK_EDITABLE_VAR(HCZOneWayDoor, VAR_UINT8, orientation);
215
RSDK_EDITABLE_VAR(HCZOneWayDoor, VAR_UINT8, detectDirection);
216
}
217
218