Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rubberduckycooly
GitHub Repository: rubberduckycooly/Sonic-Mania-Decompilation
Path: blob/master/SonicMania/Objects/SSZ/Bungee.c
338 views
1
// ---------------------------------------------------------------------
2
// RSDK Project: Sonic Mania
3
// Object Description: Bungee Object
4
// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges
5
// Decompiled by: Rubberduckycooly & RMGRich
6
// ---------------------------------------------------------------------
7
8
#include "Game.h"
9
10
ObjectBungee *Bungee;
11
12
void Bungee_Update(void)
13
{
14
RSDK_THIS(Bungee);
15
16
if (self->hasAttachedPlayer) {
17
EntityPlayer *player = self->attachedPlayer;
18
19
self->timer = 2;
20
#if GAME_VERSION != VER_100
21
if (player && !Player_CheckValidState(player)) {
22
self->attachedPlayer = NULL;
23
self->hasAttachedPlayer = false;
24
}
25
if (self->attachedPlayer) {
26
#endif
27
RSDK.GetHitbox(&player->animator, 0); // yeah
28
29
player->velocity.x = 0;
30
player->velocity.y = 0;
31
player->groundVel = 0;
32
player->angle = 0;
33
player->rotation = 0;
34
player->drawFX = FX_ROTATE | FX_FLIP;
35
player->position = self->bungeePos;
36
player->position.y += 0x1A0000;
37
#if GAME_VERSION != VER_100
38
}
39
#endif
40
41
if (self->velocity.y <= 0) {
42
self->stretchForce -= 0x800;
43
44
if (self->bungeePos.y <= self->startPos.y) {
45
self->bungeePos.x = self->startPos.x;
46
self->bungeePos.y = self->startPos.y;
47
self->hasAttachedPlayer = false;
48
49
if (self->attachedPlayer) {
50
player->tileCollisions = TILECOLLISION_DOWN;
51
player->velocity = self->velocity;
52
RSDK.SetSpriteAnimation(player->aniFrames, ANI_SPRING_TWIRL, &player->animator, true, 0);
53
54
player->rotation = 0;
55
player->animator.speed = 48;
56
player->onGround = false;
57
player->state = Player_State_Air;
58
}
59
}
60
}
61
else {
62
self->stretchForce = -0x2C00;
63
}
64
65
self->velocity.y += self->stretchForce;
66
self->bungeePos.x += self->velocity.x;
67
self->bungeePos.y += self->velocity.y;
68
}
69
else {
70
foreach_active(Player, player)
71
{
72
if (!player->sidekick) {
73
if (abs(player->position.y - self->position.y) < 0x180000) {
74
if (abs(player->position.x - self->position.x) < 0x180000 && self->playerY[player->playerID] <= self->position.y
75
&& player->position.y >= self->position.y) {
76
if (abs(player->groundVel) > 0x20000 || player->velocity.y > 0x20000) {
77
if (player->state != Player_State_Static && !self->hasAttachedPlayer && !self->timer) {
78
self->stretchForce = -0x2C00;
79
self->timer = 2;
80
self->attachedPlayer = player;
81
self->bungeePos.x = self->startPos.x;
82
self->bungeePos.y = self->startPos.y;
83
self->hasAttachedPlayer = true;
84
self->velocity.x = 0;
85
86
int32 velocity = player->onGround ? abs(player->groundVel) : player->velocity.y;
87
88
self->velocity.y = velocity >> 1;
89
player->velocity.x = 0;
90
player->velocity.y = 0;
91
player->groundVel = 0;
92
player->angle = 0;
93
player->rotation = 0;
94
player->position = self->bungeePos;
95
player->position.y += 0x1A0000;
96
player->onGround = false;
97
player->nextGroundState = StateMachine_None;
98
player->nextAirState = StateMachine_None;
99
player->tileCollisions = TILECOLLISION_NONE;
100
101
RSDK.SetSpriteAnimation(player->aniFrames, ANI_BUNGEE, &player->animator, true, 0);
102
player->state = Player_State_Static;
103
RSDK.PlaySfx(Player->sfxGrab, false, 255);
104
105
self->deathBoundary[player->playerID] = Zone->deathBoundary[player->playerID];
106
Zone->deathBoundary[player->playerID] = 0x7FFFFFFF;
107
}
108
}
109
}
110
}
111
}
112
113
self->playerY[player->playerID] = player->position.y;
114
}
115
}
116
117
if (self->timer) {
118
self->timer--;
119
}
120
else {
121
EntityPlayer *player = self->attachedPlayer;
122
if (player) {
123
Zone->deathBoundary[player->playerID] = self->deathBoundary[player->playerID];
124
self->deathBoundary[player->playerID] = 0;
125
self->attachedPlayer = NULL;
126
}
127
}
128
}
129
130
void Bungee_LateUpdate(void) {}
131
132
void Bungee_StaticUpdate(void) {}
133
134
void Bungee_Draw(void)
135
{
136
RSDK_THIS(Bungee);
137
138
if (self->hasAttachedPlayer) {
139
EntityPlayer *player = self->attachedPlayer;
140
Vector2 drawPos = self->startPos;
141
142
int32 playerY = player->position.y;
143
for (int32 i = 0; i < 9; ++i) {
144
int32 offset = i * ((playerY - 0x1A0000 - self->startPos.y) >> 3);
145
146
drawPos.x = self->startPos.x & 0xFFFF0000;
147
drawPos.y = (self->startPos.y + offset) & 0xFFFF0000;
148
RSDK.DrawSprite(&Bungee->animator, &drawPos, false);
149
}
150
}
151
else {
152
RSDK.DrawSprite(&Bungee->animator, NULL, false);
153
}
154
}
155
156
void Bungee_Create(void *data)
157
{
158
RSDK_THIS(Bungee);
159
160
self->active = ACTIVE_BOUNDS;
161
self->visible = true;
162
self->drawFX = FX_FLIP;
163
self->drawGroup = Zone->objectDrawGroup[1];
164
self->startPos.x = self->position.x;
165
self->startPos.y = self->position.y;
166
self->updateRange.x = 0x800000;
167
self->updateRange.y = 0x2000000;
168
}
169
170
void Bungee_StageLoad(void)
171
{
172
Bungee->aniFrames = RSDK.LoadSpriteAnimation("SSZ2/Bungee.bin", SCOPE_STAGE);
173
174
RSDK.SetSpriteAnimation(Bungee->aniFrames, 0, &Bungee->animator, true, 0);
175
}
176
177
#if GAME_INCLUDE_EDITOR
178
void Bungee_EditorDraw(void) { RSDK.DrawSprite(&Bungee->animator, NULL, false); }
179
180
void Bungee_EditorLoad(void) { Bungee_StageLoad(); }
181
#endif
182
183
void Bungee_Serialize(void) {}
184
185