Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rubberduckycooly
GitHub Repository: rubberduckycooly/Sonic-Mania-Decompilation
Path: blob/master/SonicMania/Objects/TMZ/JacobsLadder.c
338 views
1
// ---------------------------------------------------------------------
2
// RSDK Project: Sonic Mania
3
// Object Description: JacobsLadder Object
4
// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges
5
// Decompiled by: Rubberduckycooly & RMGRich
6
// ---------------------------------------------------------------------
7
8
#include "Game.h"
9
10
ObjectJacobsLadder *JacobsLadder;
11
12
void JacobsLadder_Update(void)
13
{
14
RSDK_THIS(JacobsLadder);
15
16
bool32 showElectricity = self->showElectricity;
17
18
self->electricFadeOut = false;
19
self->showElectricity = false;
20
self->direction = self->flip ? FLIP_Y : FLIP_NONE;
21
22
int32 timer = (self->intervalOffset + Zone->timer) % self->interval;
23
24
if (timer < self->duration) {
25
if (!showElectricity && self->onScreen == 1)
26
RSDK.PlaySfx(JacobsLadder->sfxLadder, false, 255);
27
28
self->showElectricity = true;
29
}
30
else if (timer < self->duration + 12)
31
self->electricFadeOut = true;
32
33
if (self->electricFadeOut) {
34
self->electricPos = self->height << 20;
35
RSDK.SetSpriteAnimation(JacobsLadder->aniFrames, 3, &self->electricAnimator, true, 10);
36
}
37
38
if (self->showElectricity) {
39
int32 storeX = self->position.x;
40
int32 storeY = self->position.y;
41
self->electricPos = timer * ((self->height << 20) / self->duration);
42
self->position.y += (2 * self->flip - 1) * (self->electricPos + 0x300000);
43
44
foreach_active(Player, player)
45
{
46
int32 playerID = RSDK.GetEntitySlot(player);
47
48
if (((1 << playerID) & self->activePlayers)) {
49
if (player->state == Player_State_Static && player->shield == SHIELD_LIGHTNING) {
50
if (player->jumpPress) {
51
self->playerTimers[playerID] = 15;
52
self->activePlayers &= ~(1 << playerID);
53
player->jumpAbilityState = 1;
54
player->state = Player_State_Air;
55
56
SceneInfo->entity = (Entity *)player;
57
StateMachine_Run(player->stateAbility);
58
SceneInfo->entity = (Entity *)self;
59
}
60
else {
61
player->position.x = self->position.x + self->playerPositions[playerID].x;
62
player->position.y = self->position.y + self->playerPositions[playerID].y;
63
}
64
}
65
else {
66
self->activePlayers &= ~(1 << playerID);
67
}
68
}
69
else {
70
if (self->playerTimers[playerID]) {
71
self->playerTimers[playerID]--;
72
}
73
else {
74
if (Player_CheckCollisionTouch(player, self, &self->hitbox)) {
75
if (player->shield == SHIELD_LIGHTNING) {
76
if (player->state != Player_State_Static) {
77
RSDK.SetSpriteAnimation(player->aniFrames, ANI_JUMP, &player->animator, false, 0);
78
player->state = Player_State_Static;
79
player->nextAirState = StateMachine_None;
80
player->nextGroundState = StateMachine_None;
81
82
self->playerPositions[playerID].x = player->position.x - self->position.x;
83
self->playerPositions[playerID].y = player->position.y - self->position.y;
84
85
player->velocity.x = 0;
86
player->velocity.y = 0;
87
player->groundVel = 0;
88
89
self->activePlayers |= 1 << playerID;
90
}
91
}
92
else {
93
Player_Hurt(player, self);
94
}
95
}
96
}
97
}
98
}
99
100
self->position.x = storeX;
101
self->position.y = storeY;
102
103
RSDK.ProcessAnimation(&self->electricAnimator);
104
}
105
else {
106
foreach_active(Player, player)
107
{
108
int32 playerID = RSDK.GetEntitySlot(player);
109
110
if ((1 << playerID) & self->activePlayers) {
111
self->activePlayers &= ~(1 << playerID);
112
113
if (player->state == Player_State_Static) {
114
player->velocity.x = 0;
115
player->velocity.y = 0;
116
player->groundVel = 0;
117
player->jumpAbilityState = 1;
118
player->state = Player_State_Air;
119
}
120
}
121
}
122
}
123
}
124
125
void JacobsLadder_LateUpdate(void) {}
126
127
void JacobsLadder_StaticUpdate(void) {}
128
129
void JacobsLadder_Draw(void)
130
{
131
RSDK_THIS(JacobsLadder);
132
133
self->drawFX = FX_FLIP;
134
self->inkEffect = INK_NONE;
135
self->alpha = 0xFF;
136
137
// what a line of code tbh
138
int32 direction = -(-(int32)self->flip != false) & 0xFFFFFF02;
139
140
int32 yOff = 0x300000 * (2 * (self->flip != false) - 1);
141
int32 side = 0;
142
for (int32 i = 0; i < 2; ++i) {
143
self->direction = direction ^ side;
144
145
Vector2 drawPos;
146
drawPos.x = self->position.x + ((2 * (side != false) - 1) << 21);
147
drawPos.y = self->position.y;
148
RSDK.SetSpriteAnimation(JacobsLadder->aniFrames, 0, &self->sideAnimator, true, 0);
149
RSDK.DrawSprite(&self->sideAnimator, &drawPos, false);
150
151
drawPos.y += yOff;
152
for (int32 y = 0; y < self->height; ++y) {
153
RSDK.SetSpriteAnimation(JacobsLadder->aniFrames, 1, &self->sideAnimator, true, 0);
154
RSDK.DrawSprite(&self->sideAnimator, &drawPos, false);
155
drawPos.y += (2 * (self->flip != false) - 1) << 20;
156
}
157
158
RSDK.SetSpriteAnimation(JacobsLadder->aniFrames, 2, &self->sideAnimator, true, 0);
159
RSDK.DrawSprite(&self->sideAnimator, &drawPos, false);
160
side++;
161
}
162
163
self->direction = direction;
164
if (self->showElectricity || self->electricFadeOut) {
165
self->inkEffect = INK_ADD;
166
if (self->electricFadeOut)
167
self->alpha = 21 * (self->duration - (self->intervalOffset + Zone->timer) % self->interval) + 255;
168
169
Vector2 drawPos;
170
drawPos.x = self->position.x;
171
drawPos.y = self->position.y + (2 * (self->flip != false) - 1) * (self->electricPos + 0x300000);
172
RSDK.DrawSprite(&self->electricAnimator, &drawPos, false);
173
RSDK.DrawSprite(&self->electricAnimator, &drawPos, false);
174
}
175
}
176
177
void JacobsLadder_Create(void *data)
178
{
179
RSDK_THIS(JacobsLadder);
180
181
self->active = ACTIVE_BOUNDS;
182
self->drawGroup = Zone->objectDrawGroup[0];
183
self->startPos = self->position;
184
self->visible = true;
185
self->updateRange.x = 0x800000;
186
self->updateRange.y = (self->height + 8) << 20;
187
self->drawFX = FX_FLIP;
188
self->direction = self->flip ? FLIP_Y : FLIP_NONE;
189
190
if (!self->interval)
191
self->interval = 120;
192
193
if (!self->duration)
194
self->duration = 60;
195
196
RSDK.SetSpriteAnimation(JacobsLadder->aniFrames, 3, &self->electricAnimator, true, 0);
197
198
self->hitbox.left = -35;
199
self->hitbox.top = -4;
200
self->hitbox.right = 35;
201
self->hitbox.bottom = 4;
202
}
203
204
void JacobsLadder_StageLoad(void)
205
{
206
JacobsLadder->aniFrames = RSDK.LoadSpriteAnimation("TMZ1/JacobsLadder.bin", SCOPE_STAGE);
207
208
JacobsLadder->sfxLadder = RSDK.GetSfx("TMZ1/JacobsLadder.wav");
209
}
210
211
#if GAME_INCLUDE_EDITOR
212
void JacobsLadder_EditorDraw(void)
213
{
214
JacobsLadder_Create(NULL);
215
JacobsLadder_Draw();
216
}
217
218
void JacobsLadder_EditorLoad(void) { JacobsLadder->aniFrames = RSDK.LoadSpriteAnimation("TMZ1/JacobsLadder.bin", SCOPE_STAGE); }
219
#endif
220
221
void JacobsLadder_Serialize(void)
222
{
223
RSDK_EDITABLE_VAR(JacobsLadder, VAR_UINT32, height);
224
RSDK_EDITABLE_VAR(JacobsLadder, VAR_ENUM, interval);
225
RSDK_EDITABLE_VAR(JacobsLadder, VAR_ENUM, intervalOffset);
226
RSDK_EDITABLE_VAR(JacobsLadder, VAR_ENUM, duration);
227
RSDK_EDITABLE_VAR(JacobsLadder, VAR_BOOL, flip);
228
}
229
230