Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rubberduckycooly
GitHub Repository: rubberduckycooly/Sonic-Mania-Decompilation
Path: blob/master/SonicMania/Objects/HCZ/Jawz.c
338 views
1
// ---------------------------------------------------------------------
2
// RSDK Project: Sonic Mania
3
// Object Description: Jawz Object
4
// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges
5
// Decompiled by: Rubberduckycooly & RMGRich
6
// ---------------------------------------------------------------------
7
8
#include "Game.h"
9
10
ObjectJawz *Jawz;
11
12
void Jawz_Update(void)
13
{
14
RSDK_THIS(Jawz);
15
16
StateMachine_Run(self->state);
17
}
18
19
void Jawz_LateUpdate(void) {}
20
21
void Jawz_StaticUpdate(void) {}
22
23
void Jawz_Draw(void)
24
{
25
RSDK_THIS(Jawz);
26
27
RSDK.DrawSprite(&self->animator, NULL, false);
28
}
29
30
void Jawz_Create(void *data)
31
{
32
RSDK_THIS(Jawz);
33
34
self->visible = true;
35
self->drawGroup = Zone->objectDrawGroup[0];
36
self->drawFX |= FX_FLIP;
37
self->startPos = self->position;
38
self->active = ACTIVE_BOUNDS;
39
self->updateRange.x = 0x800000;
40
self->updateRange.y = 0x800000;
41
self->velocity.x = 0;
42
RSDK.SetSpriteAnimation(Jawz->aniFrames, 0, &self->animator, true, 0);
43
self->state = Jawz_State_CheckPlayerTrigger;
44
}
45
46
void Jawz_StageLoad(void)
47
{
48
if (RSDK.CheckSceneFolder("HCZ"))
49
Jawz->aniFrames = RSDK.LoadSpriteAnimation("HCZ/Jawz.bin", SCOPE_STAGE);
50
51
Jawz->hitboxBadnik.left = -20;
52
Jawz->hitboxBadnik.top = -5;
53
Jawz->hitboxBadnik.right = 20;
54
Jawz->hitboxBadnik.bottom = 5;
55
56
DEBUGMODE_ADD_OBJ(Jawz);
57
}
58
59
void Jawz_DebugSpawn(void)
60
{
61
RSDK_THIS(Jawz);
62
63
CREATE_ENTITY(Jawz, NULL, self->position.x, self->position.y);
64
}
65
66
void Jawz_DebugDraw(void)
67
{
68
RSDK.SetSpriteAnimation(Jawz->aniFrames, 0, &DebugMode->animator, true, 0);
69
RSDK.DrawSprite(&DebugMode->animator, NULL, false);
70
}
71
72
void Jawz_CheckPlayerCollisions(void)
73
{
74
RSDK_THIS(Jawz);
75
76
foreach_active(Player, player)
77
{
78
if (Player_CheckBadnikTouch(player, self, &Jawz->hitboxBadnik) && !Player_CheckBadnikBreak(player, self, true)) {
79
CREATE_ENTITY(Explosion, INT_TO_VOID(EXPLOSION_ENEMY), self->position.x, self->position.y)->drawGroup = Zone->objectDrawGroup[1];
80
RSDK.PlaySfx(Explosion->sfxDestroy, false, 255);
81
destroyEntity(self);
82
}
83
}
84
}
85
86
void Jawz_State_CheckPlayerTrigger(void)
87
{
88
RSDK_THIS(Jawz);
89
90
EntityPlayer *player = NULL;
91
if (Player->playerCount <= 1 || RSDK_GET_ENTITY(SLOT_PLAYER2, Player)->sidekick)
92
player = RSDK_GET_ENTITY(SLOT_PLAYER1, Player);
93
else
94
player = Player_GetNearestPlayer();
95
96
if (player) {
97
if (abs(player->position.x - self->position.x) < 0x1800000) {
98
99
int32 playerID = RSDK.GetEntitySlot(player);
100
switch (self->triggerDir) {
101
case JAWS_TRIGGER_BOTH:
102
if (player->position.x > self->position.x) {
103
self->direction = FLIP_X;
104
self->velocity.x = 0x20000;
105
self->position.x = (ScreenInfo[playerID].position.x - 64) << 16;
106
}
107
else if (player->position.x <= self->position.x) {
108
self->direction = FLIP_NONE;
109
self->velocity.x = -0x20000;
110
self->position.x = (ScreenInfo[playerID].position.x + ScreenInfo[playerID].size.x + 64) << 16;
111
}
112
break;
113
114
case JAWS_TRIGGER_LEFT:
115
if (player->position.x < self->position.x) {
116
self->direction = FLIP_NONE;
117
self->velocity.x = -0x20000;
118
self->position.x = (ScreenInfo[playerID].position.x + ScreenInfo[playerID].size.x + 64) << 16;
119
}
120
break;
121
122
case JAWS_TRIGGER_RIGHT:
123
if (player->position.x > self->position.x) {
124
self->direction = FLIP_X;
125
self->velocity.x = 0x20000;
126
self->position.x = (ScreenInfo[playerID].position.x - 64) << 16;
127
}
128
break;
129
}
130
}
131
}
132
133
if (self->velocity.x) {
134
self->active = ACTIVE_NORMAL;
135
self->visible = true;
136
137
self->state = Jawz_State_Triggered;
138
Jawz_State_Triggered();
139
}
140
else {
141
self->active = ACTIVE_BOUNDS;
142
self->visible = false;
143
}
144
}
145
146
void Jawz_State_Triggered(void)
147
{
148
RSDK_THIS(Jawz);
149
150
self->position.x += self->velocity.x;
151
RSDK.ProcessAnimation(&self->animator);
152
153
Jawz_CheckPlayerCollisions();
154
155
if (!RSDK.CheckOnScreen(self, NULL) && !RSDK.CheckPosOnScreen(&self->startPos, &self->updateRange)) {
156
self->position.x = self->startPos.x;
157
self->position.y = self->startPos.y;
158
159
Jawz_Create(NULL);
160
}
161
}
162
163
#if GAME_INCLUDE_EDITOR
164
void Jawz_EditorDraw(void)
165
{
166
RSDK_THIS(Jawz);
167
168
self->direction = self->triggerDir == JAWS_TRIGGER_RIGHT;
169
170
Jawz_Draw();
171
172
if (showGizmos()) {
173
RSDK_DRAWING_OVERLAY(true);
174
175
if (self->triggerDir < JAWS_TRIGGER_RIGHT)
176
DrawHelpers_DrawArrow(self->position.x, self->position.y, self->position.x - 0x300000, self->position.y, 0xFFFF00, INK_NONE, 0xFF);
177
178
if (self->triggerDir != JAWS_TRIGGER_LEFT)
179
DrawHelpers_DrawArrow(self->position.x, self->position.y, self->position.x + 0x300000, self->position.y, 0xFFFF00, INK_NONE, 0xFF);
180
181
RSDK_DRAWING_OVERLAY(false);
182
}
183
}
184
185
void Jawz_EditorLoad(void)
186
{
187
Jawz->aniFrames = RSDK.LoadSpriteAnimation("HCZ/Jawz.bin", SCOPE_STAGE);
188
189
RSDK_ACTIVE_VAR(Jawz, triggerDir);
190
RSDK_ENUM_VAR("Both", JAWS_TRIGGER_BOTH);
191
RSDK_ENUM_VAR("Left", JAWS_TRIGGER_LEFT);
192
RSDK_ENUM_VAR("Right", JAWS_TRIGGER_RIGHT);
193
}
194
#endif
195
196
void Jawz_Serialize(void) { RSDK_EDITABLE_VAR(Jawz, VAR_UINT8, triggerDir); }
197
198