Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rubberduckycooly
GitHub Repository: rubberduckycooly/Sonic-Mania-Decompilation
Path: blob/master/SonicMania/Objects/PGZ/DoorTrigger.c
338 views
1
// ---------------------------------------------------------------------
2
// RSDK Project: Sonic Mania
3
// Object Description: DoorTrigger Object
4
// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges
5
// Decompiled by: Rubberduckycooly & RMGRich
6
// ---------------------------------------------------------------------
7
8
#include "Game.h"
9
10
ObjectDoorTrigger *DoorTrigger;
11
12
void DoorTrigger_Update(void)
13
{
14
RSDK_THIS(DoorTrigger);
15
16
RSDK.ProcessAnimation(&self->baseAnimator);
17
18
if (self->bulbAnimator.frameID) {
19
if (!--self->id) {
20
self->id = RSDK.Rand(15, 121);
21
22
int32 anim = 0;
23
switch (self->orientation) {
24
case DOORTRIGGER_ORIENATION_L:
25
case DOORTRIGGER_ORIENATION_R: anim = 3; break;
26
27
case DOORTRIGGER_ORIENATION_U:
28
case DOORTRIGGER_ORIENATION_D: anim = 4; break;
29
30
default: break;
31
}
32
33
int32 x = self->position.x + (RSDK.Rand(-4, 5) << 16);
34
int32 y = self->position.y + (RSDK.Rand(-4, 5) << 16);
35
EntityDebris *shard = CREATE_ENTITY(Debris, NULL, x, y);
36
37
shard->state = Debris_State_Move;
38
shard->drawFX = FX_FLIP;
39
shard->direction = self->direction;
40
shard->drawGroup = Zone->objectDrawGroup[1] - 1;
41
RSDK.SetSpriteAnimation(DoorTrigger->aniFrames, anim, &shard->animator, true, 0);
42
}
43
}
44
else {
45
foreach_active(Player, player)
46
{
47
if (!player->sidekick && Player_CheckAttackingNoInvTimer(player, self)) {
48
if (Player_CheckCollisionTouch(player, self, &DoorTrigger->hitboxBulb[self->baseAnimator.frameID])) {
49
self->bulbAnimator.frameID = 1;
50
if (player->characterID == ID_KNUCKLES && player->animator.animationID == ANI_GLIDE) {
51
player->velocity.x = -player->velocity.x >> 1;
52
RSDK.SetSpriteAnimation(player->aniFrames, ANI_GLIDE_DROP, &player->animator, false, 0);
53
player->state = Player_State_KnuxGlideDrop;
54
}
55
else {
56
int32 x = 0, y = 0;
57
if (self->baseAnimator.frameID) {
58
x = player->position.x - self->position.x;
59
60
if (self->direction)
61
y = (player->position.y - self->position.y) - 0xE0000;
62
else
63
y = (player->position.y - self->position.y) + 0xE0000;
64
}
65
else {
66
if (self->direction)
67
x = (player->position.x - self->position.x) - 0xE0000;
68
else
69
x = (player->position.x - self->position.x) + 0xE0000;
70
71
y = player->position.y - self->position.y;
72
}
73
74
int32 angle = RSDK.ATan2(x, y);
75
#if MANIA_USE_PLUS
76
if (player->characterID == ID_MIGHTY && player->animator.animationID == ANI_HAMMERDROP) {
77
player->velocity.y -= 0x10000;
78
}
79
else {
80
#endif
81
player->velocity.x = 0x300 * RSDK.Cos256(angle);
82
player->groundVel = 0x300 * RSDK.Cos256(angle);
83
player->velocity.y = 0x300 * RSDK.Sin256(angle);
84
#if MANIA_USE_PLUS
85
}
86
#endif
87
88
player->applyJumpCap = false;
89
player->onGround = false;
90
}
91
92
RSDK.PlaySfx(DoorTrigger->sfxShatter, false, 255);
93
94
int32 spawnX = self->position.x;
95
int32 spawnY = self->position.y;
96
switch (self->orientation) {
97
case DOORTRIGGER_ORIENATION_L: spawnX -= 0x100000; break;
98
case DOORTRIGGER_ORIENATION_R: spawnX += 0x100000; break;
99
case DOORTRIGGER_ORIENATION_U: spawnY -= 0x100000; break;
100
case DOORTRIGGER_ORIENATION_D: spawnY += 0x100000; break;
101
default: break;
102
}
103
104
for (int32 i = 0; i < 8; ++i) {
105
EntityDebris *shard =
106
CREATE_ENTITY(Debris, NULL, spawnX + RSDK.Rand(-0xA0000, 0xA0000), spawnY + RSDK.Rand(-0xA0000, 0xA0000));
107
shard->state = Debris_State_Fall;
108
shard->gravityStrength = 0x4000;
109
shard->velocity.x = RSDK.Rand(0, 0x20000);
110
if (shard->position.x < self->position.x)
111
shard->velocity.x = -shard->velocity.x;
112
shard->velocity.y = RSDK.Rand(-0x40000, -0x10000);
113
shard->drawFX = FX_FLIP;
114
shard->direction = i & 3;
115
shard->drawGroup = Zone->objectDrawGroup[1];
116
RSDK.SetSpriteAnimation(ItemBox->aniFrames, 6, &shard->animator, true, RSDK.Rand(0, 4));
117
}
118
119
CREATE_ENTITY(Explosion, INT_TO_VOID(EXPLOSION_ENEMY), spawnX, spawnY)->drawGroup = Zone->objectDrawGroup[1];
120
}
121
}
122
else {
123
Player_CheckCollisionBox(player, self, &DoorTrigger->hitboxBulb[self->baseAnimator.frameID]);
124
}
125
}
126
}
127
}
128
129
void DoorTrigger_LateUpdate(void) {}
130
131
void DoorTrigger_StaticUpdate(void) {}
132
133
void DoorTrigger_Draw(void)
134
{
135
RSDK_THIS(DoorTrigger);
136
137
RSDK.DrawSprite(&self->baseAnimator, NULL, false);
138
RSDK.DrawSprite(&self->bulbAnimator, NULL, false);
139
140
if (!self->bulbAnimator.frameID && !(Zone->timer & 1)) {
141
self->inkEffect = INK_ADD;
142
self->bulbAnimator.frameID = 2;
143
self->alpha = 0xB8 + ((56 * RSDK.Sin256(Zone->timer)) >> 8);
144
RSDK.DrawSprite(&self->bulbAnimator, NULL, false);
145
146
self->bulbAnimator.frameID = 3;
147
RSDK.DrawSprite(&self->bulbAnimator, NULL, false);
148
149
self->bulbAnimator.frameID = 0;
150
self->inkEffect = INK_NONE;
151
}
152
}
153
154
void DoorTrigger_Create(void *data)
155
{
156
RSDK_THIS(DoorTrigger);
157
158
self->drawFX = FX_FLIP;
159
160
if (!SceneInfo->inEditor) {
161
self->active = ACTIVE_BOUNDS;
162
self->visible = true;
163
self->drawGroup = Zone->objectDrawGroup[1];
164
self->updateRange.y = 0x800000;
165
self->updateRange.x = 0x800000;
166
RSDK.SetSpriteAnimation(DoorTrigger->aniFrames, 0, &self->baseAnimator, true, 0);
167
168
self->direction = self->orientation & 1;
169
if (self->orientation < DOORTRIGGER_ORIENATION_U) {
170
RSDK.SetSpriteAnimation(DoorTrigger->aniFrames, 1, &self->bulbAnimator, true, 0);
171
}
172
else {
173
self->baseAnimator.frameID = 1;
174
self->direction *= FLIP_Y;
175
RSDK.SetSpriteAnimation(DoorTrigger->aniFrames, 2, &self->bulbAnimator, true, 0);
176
}
177
}
178
}
179
180
void DoorTrigger_StageLoad(void)
181
{
182
if (RSDK.CheckSceneFolder("PSZ1"))
183
DoorTrigger->aniFrames = RSDK.LoadSpriteAnimation("PSZ1/DoorTrigger.bin", SCOPE_STAGE);
184
185
// Active
186
DoorTrigger->hitboxBulb[0].top = -10;
187
DoorTrigger->hitboxBulb[0].left = -26;
188
DoorTrigger->hitboxBulb[0].bottom = 10;
189
DoorTrigger->hitboxBulb[0].right = 0;
190
191
// Busted
192
DoorTrigger->hitboxBulb[1].top = -26;
193
DoorTrigger->hitboxBulb[1].left = -10;
194
DoorTrigger->hitboxBulb[1].bottom = 0;
195
DoorTrigger->hitboxBulb[1].right = 10;
196
197
DoorTrigger->sfxShatter = RSDK.GetSfx("Stage/WindowShatter.wav");
198
}
199
200
#if GAME_INCLUDE_EDITOR
201
void DoorTrigger_EditorDraw(void)
202
{
203
RSDK_THIS(DoorTrigger);
204
205
self->active = ACTIVE_BOUNDS;
206
self->visible = true;
207
self->drawGroup = Zone->objectDrawGroup[1];
208
self->updateRange.y = 0x800000;
209
self->updateRange.x = 0x800000;
210
RSDK.SetSpriteAnimation(DoorTrigger->aniFrames, 0, &self->baseAnimator, true, 0);
211
212
self->direction = self->orientation & 1;
213
if (self->orientation < DOORTRIGGER_ORIENATION_U) {
214
RSDK.SetSpriteAnimation(DoorTrigger->aniFrames, 1, &self->bulbAnimator, true, 0);
215
}
216
else {
217
self->baseAnimator.frameID = 1;
218
self->direction *= FLIP_Y;
219
RSDK.SetSpriteAnimation(DoorTrigger->aniFrames, 2, &self->bulbAnimator, true, 0);
220
}
221
222
DoorTrigger_Draw();
223
}
224
225
void DoorTrigger_EditorLoad(void)
226
{
227
DoorTrigger->aniFrames = RSDK.LoadSpriteAnimation("PSZ1/DoorTrigger.bin", SCOPE_STAGE);
228
229
RSDK_ACTIVE_VAR(DoorTrigger, orientation);
230
RSDK_ENUM_VAR("Left", DOORTRIGGER_ORIENATION_L);
231
RSDK_ENUM_VAR("Right", DOORTRIGGER_ORIENATION_R);
232
RSDK_ENUM_VAR("Up", DOORTRIGGER_ORIENATION_U);
233
RSDK_ENUM_VAR("Down", DOORTRIGGER_ORIENATION_D);
234
}
235
#endif
236
237
void DoorTrigger_Serialize(void)
238
{
239
RSDK_EDITABLE_VAR(DoorTrigger, VAR_UINT8, orientation);
240
RSDK_EDITABLE_VAR(DoorTrigger, VAR_UINT8, id);
241
}
242
243