Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rubberduckycooly
GitHub Repository: rubberduckycooly/Sonic-Mania-Decompilation
Path: blob/master/SonicMania/Objects/HPZ/Batbot.c
338 views
1
// ---------------------------------------------------------------------
2
// RSDK Project: Sonic Mania
3
// Object Description: Batbot Object
4
// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges
5
// Decompiled by: Rubberduckycooly & RMGRich
6
// ---------------------------------------------------------------------
7
8
#include "Game.h"
9
10
ObjectBatbot *Batbot = NULL;
11
12
void Batbot_Update(void)
13
{
14
RSDK_THIS(Batbot);
15
RSDK.ProcessAnimation(&self->bodyAnimator);
16
if (self->bodyAnimator.animationID == 1)
17
self->direction = self->swoopDir ^ Batbot->directionTable[self->bodyAnimator.frameID];
18
19
StateMachine_Run(self->state);
20
21
Batbot_CheckPlayerCollisions();
22
if (self->state != Batbot_State_Init) {
23
if (!RSDK.CheckOnScreen(self, NULL) && !RSDK.CheckPosOnScreen(&self->startPos, &self->updateRange)) {
24
self->direction = self->startDir;
25
self->position = self->startPos;
26
Batbot_Create(NULL);
27
}
28
}
29
}
30
31
void Batbot_LateUpdate(void) {}
32
33
void Batbot_StaticUpdate(void) {}
34
35
void Batbot_Draw(void)
36
{
37
RSDK_THIS(Batbot);
38
RSDK.DrawSprite(&self->bodyAnimator, NULL, false);
39
if (self->showJet)
40
RSDK.DrawSprite(&self->jetAnimator, NULL, false);
41
}
42
43
void Batbot_Create(void *data)
44
{
45
RSDK_THIS(Batbot);
46
self->visible = true;
47
self->drawGroup = Zone->objectDrawGroup[0];
48
self->startPos = self->position;
49
self->startDir = self->direction;
50
self->drawFX = FX_FLIP;
51
self->active = ACTIVE_BOUNDS;
52
self->updateRange.x = 0x800000;
53
self->updateRange.y = 0x800000;
54
self->state = Batbot_State_Init;
55
}
56
57
void Batbot_StageLoad(void)
58
{
59
if (RSDK.CheckSceneFolder("HPZ"))
60
Batbot->aniFrames = RSDK.LoadSpriteAnimation("HPZ/Batbot.bin", SCOPE_STAGE);
61
62
Batbot->hitboxBadnik.left = -16;
63
Batbot->hitboxBadnik.top = -12;
64
Batbot->hitboxBadnik.right = 16;
65
Batbot->hitboxBadnik.bottom = 12;
66
67
Batbot->hitboxSpinCheck.left = -96;
68
Batbot->hitboxSpinCheck.top = -64;
69
Batbot->hitboxSpinCheck.right = 96;
70
Batbot->hitboxSpinCheck.bottom = 128;
71
72
Batbot->hitboxAttack.left = -80;
73
Batbot->hitboxAttack.top = -64;
74
Batbot->hitboxAttack.right = 80;
75
Batbot->hitboxAttack.bottom = 96;
76
77
Batbot->hitboxPlayer.left = 0;
78
Batbot->hitboxPlayer.top = 0;
79
Batbot->hitboxPlayer.right = 0;
80
Batbot->hitboxPlayer.bottom = 0;
81
82
Batbot->directionTable[0] = FLIP_NONE;
83
Batbot->directionTable[1] = FLIP_NONE;
84
Batbot->directionTable[2] = FLIP_NONE;
85
Batbot->directionTable[3] = FLIP_X;
86
Batbot->directionTable[4] = FLIP_X;
87
88
DEBUGMODE_ADD_OBJ(Batbot);
89
}
90
91
void Batbot_DebugSpawn(void)
92
{
93
RSDK_THIS(DebugMode);
94
95
EntityBatbot *batBot = CREATE_ENTITY(Batbot, NULL, self->position.x, self->position.y);
96
batBot->direction = self->direction;
97
batBot->startDir = self->direction;
98
}
99
100
void Batbot_DebugDraw(void)
101
{
102
RSDK.SetSpriteAnimation(Batbot->aniFrames, 0, &DebugMode->animator, true, 3);
103
RSDK.DrawSprite(&DebugMode->animator, NULL, false);
104
}
105
106
void Batbot_CheckPlayerCollisions(void)
107
{
108
RSDK_THIS(Batbot);
109
foreach_active(Player, player)
110
{
111
if (Player_CheckBadnikTouch(player, self, &Batbot->hitboxBadnik))
112
Player_CheckBadnikBreak(player, self, true);
113
}
114
}
115
116
void Batbot_State_Init(void)
117
{
118
RSDK_THIS(Batbot);
119
self->timer = 0;
120
self->unused3 = 0;
121
self->originY = self->position.y;
122
self->active = ACTIVE_NORMAL;
123
self->showJet = true;
124
RSDK.SetSpriteAnimation(Batbot->aniFrames, 3, &self->jetAnimator, true, 0);
125
RSDK.SetSpriteAnimation(Batbot->aniFrames, 0, &self->bodyAnimator, true, 0);
126
self->state = Batbot_State_Idle;
127
Batbot_State_Idle();
128
}
129
130
void Batbot_State_Idle(void)
131
{
132
RSDK_THIS(Batbot);
133
134
self->arcAngle = (self->arcAngle + 8) & 0x1FF;
135
self->position.y = (RSDK.Sin512(self->arcAngle) << 9) + self->originY;
136
bool32 spin = false;
137
138
foreach_active(Player, player)
139
{
140
if (RSDK.CheckObjectCollisionTouchBox(player, &Batbot->hitboxPlayer, self, &Batbot->hitboxSpinCheck)) {
141
RSDK.SetSpriteAnimation(Batbot->aniFrames, 1, &self->bodyAnimator, false, 0);
142
spin = true;
143
}
144
145
if (RSDK.CheckObjectCollisionTouchBox(player, &Batbot->hitboxPlayer, self, &Batbot->hitboxAttack)) {
146
self->playerPtr = player;
147
self->state = Batbot_State_Attack;
148
}
149
}
150
151
if (!spin)
152
RSDK.SetSpriteAnimation(Batbot->aniFrames, 0, &self->bodyAnimator, false, 0);
153
}
154
155
void Batbot_State_Attack(void)
156
{
157
RSDK_THIS(Batbot);
158
159
if (self->arcAngle) {
160
self->arcAngle = (self->arcAngle + 8) & 0x1FF;
161
self->position.y = (RSDK.Sin512(self->arcAngle) << 9) + self->originY;
162
}
163
164
if (++self->timer == 20) {
165
self->timer = 0;
166
self->landPos = self->position;
167
if (self->playerPtr->position.x > self->position.x) {
168
self->landPos.x += 0x500000;
169
self->swoopAngle = 0x100;
170
self->swoopDir = FLIP_X;
171
self->state = Batbot_State_SwoopRight;
172
}
173
else {
174
self->landPos.x -= 0x500000;
175
self->swoopAngle = 0x000;
176
self->swoopDir = FLIP_NONE;
177
self->state = Batbot_State_SwoopLeft;
178
}
179
self->showJet = false;
180
RSDK.SetSpriteAnimation(Batbot->aniFrames, 2, &self->bodyAnimator, true, 0);
181
}
182
}
183
184
void Batbot_State_SwoopLeft(void)
185
{
186
RSDK_THIS(Batbot);
187
self->swoopAngle += 4;
188
self->position.x = self->landPos.x + 0x2800 * RSDK.Cos512(self->swoopAngle);
189
self->position.y = self->landPos.y + 0x2800 * RSDK.Sin512(self->swoopAngle);
190
if (self->swoopAngle == 0x100) {
191
self->showJet = true;
192
RSDK.SetSpriteAnimation(Batbot->aniFrames, 0, &self->bodyAnimator, true, 0);
193
self->state = Batbot_State_Idle;
194
}
195
}
196
197
void Batbot_State_SwoopRight(void)
198
{
199
RSDK_THIS(Batbot);
200
self->swoopAngle -= 4;
201
self->position.x = self->landPos.x + 0x2800 * RSDK.Cos512(self->swoopAngle);
202
self->position.y = self->landPos.y + 0x2800 * RSDK.Sin512(self->swoopAngle);
203
if (self->swoopAngle == 0x000) {
204
self->showJet = true;
205
RSDK.SetSpriteAnimation(Batbot->aniFrames, 0, &self->bodyAnimator, true, 0);
206
self->state = Batbot_State_Idle;
207
}
208
}
209
210
#if GAME_INCLUDE_EDITOR
211
void Batbot_EditorDraw(void)
212
{
213
RSDK_THIS(Batbot);
214
215
RSDK.SetSpriteAnimation(Batbot->aniFrames, 3, &self->jetAnimator, true, 0);
216
RSDK.SetSpriteAnimation(Batbot->aniFrames, 0, &self->bodyAnimator, true, 0);
217
218
Batbot_Draw();
219
}
220
221
void Batbot_EditorLoad(void)
222
{
223
Batbot->aniFrames = RSDK.LoadSpriteAnimation("HPZ/Batbot.bin", SCOPE_STAGE);
224
225
RSDK_ACTIVE_VAR(Batbot, direction);
226
RSDK_ENUM_VAR("No Flip", FLIP_NONE);
227
RSDK_ENUM_VAR("Flip X", FLIP_X);
228
}
229
#endif
230
231
void Batbot_Serialize(void) { RSDK_EDITABLE_VAR(Batbot, VAR_UINT8, direction); }
232
233