Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rubberduckycooly
GitHub Repository: rubberduckycooly/Sonic-Mania-Decompilation
Path: blob/master/SonicMania/Objects/MSZ/GiantPistol.c
338 views
1
// ---------------------------------------------------------------------
2
// RSDK Project: Sonic Mania
3
// Object Description: GiantPistol Object
4
// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges
5
// Decompiled by: Rubberduckycooly & RMGRich
6
// ---------------------------------------------------------------------
7
8
#include "Game.h"
9
10
ObjectGiantPistol *GiantPistol;
11
12
void GiantPistol_Update(void)
13
{
14
RSDK_THIS(GiantPistol);
15
16
StateMachine_Run(self->state);
17
}
18
19
void GiantPistol_LateUpdate(void) {}
20
21
void GiantPistol_StaticUpdate(void) {}
22
23
void GiantPistol_Draw(void)
24
{
25
RSDK_THIS(GiantPistol);
26
27
if (SceneInfo->currentDrawGroup == Zone->objectDrawGroup[0]) {
28
RSDK.DrawSprite(&self->pistolEntryAnimator, NULL, false);
29
RSDK.DrawSprite(&self->handLowAnimator, NULL, false);
30
31
RSDK.AddDrawListRef(Zone->objectDrawGroup[1], SceneInfo->entitySlot);
32
}
33
else {
34
RSDK.DrawSprite(&self->triggerAnimator, NULL, false);
35
RSDK.DrawSprite(&self->hammerAnimator, NULL, false);
36
RSDK.DrawSprite(&self->chamberAnimator, NULL, false);
37
RSDK.DrawSprite(&self->pistolAnimator, NULL, false);
38
RSDK.DrawSprite(&self->handHighAnimator, NULL, false);
39
RSDK.DrawSprite(&self->triggerFingerAnimator, NULL, false);
40
}
41
}
42
43
void GiantPistol_Create(void *data)
44
{
45
RSDK_THIS(GiantPistol);
46
47
self->drawFX = FX_FLIP;
48
if (!SceneInfo->inEditor) {
49
RSDK.SetSpriteAnimation(GiantPistol->aniFrames, 0, &self->pistolAnimator, true, 0);
50
RSDK.SetSpriteAnimation(GiantPistol->aniFrames, 0, &self->pistolEntryAnimator, true, 1);
51
RSDK.SetSpriteAnimation(GiantPistol->aniFrames, 5, &self->chamberAnimator, true, 0);
52
RSDK.SetSpriteAnimation(GiantPistol->aniFrames, 6, &self->hammerAnimator, true, 0);
53
RSDK.SetSpriteAnimation(GiantPistol->aniFrames, 4, &self->triggerAnimator, true, 0);
54
RSDK.SetSpriteAnimation(GiantPistol->aniFrames, 1, &self->handLowAnimator, true, 0);
55
RSDK.SetSpriteAnimation(GiantPistol->aniFrames, 2, &self->handHighAnimator, true, 0);
56
RSDK.SetSpriteAnimation(GiantPistol->aniFrames, 3, &self->triggerFingerAnimator, true, 0);
57
58
self->active = ACTIVE_BOUNDS;
59
self->updateRange.x = 0x800000;
60
self->updateRange.y = 0x800000;
61
self->visible = true;
62
self->drawGroup = Zone->objectDrawGroup[0];
63
self->startPos = self->position;
64
65
self->pivot.x = self->position.x + (self->direction == FLIP_NONE ? 0x300000 : -0x300000);
66
self->pivot.y = self->position.y + 0x180000;
67
self->state = GiantPistol_State_AwaitPlayerEntry;
68
}
69
}
70
71
void GiantPistol_StageLoad(void)
72
{
73
GiantPistol->aniFrames = RSDK.LoadSpriteAnimation("MSZ/Pistol.bin", SCOPE_STAGE);
74
75
GiantPistol->hitboxFront.left = -80;
76
GiantPistol->hitboxFront.top = -58;
77
GiantPistol->hitboxFront.right = 4;
78
GiantPistol->hitboxFront.bottom = -16;
79
80
GiantPistol->hitboxEntry.left = 4;
81
GiantPistol->hitboxEntry.top = -26;
82
GiantPistol->hitboxEntry.right = 44;
83
GiantPistol->hitboxEntry.bottom = -16;
84
85
GiantPistol->hitboxRear.left = 44;
86
GiantPistol->hitboxRear.top = -58;
87
GiantPistol->hitboxRear.right = 64;
88
GiantPistol->hitboxRear.bottom = -16;
89
90
GiantPistol->sfxClack = RSDK.GetSfx("Stage/Clack.wav");
91
GiantPistol->sfxCannonFire = RSDK.GetSfx("Stage/CannonFire.wav");
92
}
93
94
void GiantPistol_State_AwaitPlayerEntry(void)
95
{
96
RSDK_THIS(GiantPistol);
97
98
foreach_active(Player, player)
99
{
100
int32 side = Player_CheckCollisionBox(player, self, &GiantPistol->hitboxEntry);
101
102
if (side == C_TOP && (!player->sidekick || self->state == GiantPistol_State_CloseChamber)) {
103
player->state = Player_State_Static;
104
player->nextAirState = StateMachine_None;
105
player->nextGroundState = StateMachine_None;
106
player->velocity.x = 0;
107
player->velocity.y = 0;
108
109
RSDK.SetSpriteAnimation(player->aniFrames, ANI_JUMP, &player->animator, false, 0);
110
self->activePlayers |= 1 << player->playerID;
111
self->state = GiantPistol_State_CloseChamber;
112
self->playerPos = self->direction == FLIP_NONE ? 0x180000 : -0x180000;
113
RSDK.PlaySfx(GiantPistol->sfxClack, false, 255);
114
}
115
116
Player_CheckCollisionBox(player, self, &GiantPistol->hitboxFront);
117
Player_CheckCollisionBox(player, self, &GiantPistol->hitboxRear);
118
}
119
}
120
121
void GiantPistol_State_CloseChamber(void)
122
{
123
RSDK_THIS(GiantPistol);
124
125
RSDK.ProcessAnimation(&self->chamberAnimator);
126
127
foreach_active(Player, player)
128
{
129
if (((1 << (player->playerID)) & self->activePlayers) > 0) {
130
player->position.x += (self->position.x + self->playerPos - player->position.x) >> 3;
131
player->position.y += (self->position.y - player->position.y - 0x200000) >> 3;
132
player->velocity.x = 0;
133
player->velocity.y = 0;
134
}
135
}
136
137
if (self->chamberAnimator.frameID >= self->chamberAnimator.frameCount - 1) {
138
self->state = GiantPistol_State_SpinGun;
139
self->drawFX = FX_ROTATE | FX_FLIP;
140
self->handLowAnimator.frameID = 1;
141
self->handHighAnimator.frameID = 1;
142
self->velocity.y = -0x20000;
143
self->rotationVel = 6;
144
145
foreach_active(Player, playerPtr)
146
{
147
if (((1 << (playerPtr->playerID)) & self->activePlayers) > 0) {
148
playerPtr->blinkTimer = 0;
149
playerPtr->visible = false;
150
if (playerPtr->camera)
151
playerPtr->camera->state = StateMachine_None;
152
}
153
}
154
}
155
}
156
157
void GiantPistol_State_SpinGun(void)
158
{
159
RSDK_THIS(GiantPistol);
160
161
self->position.y += self->velocity.y;
162
self->velocity.y += 0x1800;
163
164
if (self->position.y >= self->startPos.y) {
165
self->position.y = self->startPos.y;
166
self->velocity.y = 0;
167
}
168
169
if (self->rotationVel > -64)
170
self->rotationVel--;
171
172
self->angle += self->direction ? -self->rotationVel : self->rotationVel;
173
174
self->rotation = self->angle & 0x1FF;
175
int32 angle = 0x100 - (self->rotation >> 1);
176
177
foreach_active(Player, player)
178
{
179
if (((1 << (player->playerID)) & self->activePlayers) > 0) {
180
player->position.x = self->position.x + self->playerPos;
181
player->position.y = self->position.y - 0x200000;
182
183
Zone_RotateOnPivot(&player->position, &self->position, angle);
184
}
185
}
186
187
if (self->angle <= -0x1FC || self->angle >= 0x1FC) {
188
self->angle = 0;
189
self->rotationVel = -(self->rotationVel >> 1);
190
self->rotation = 0;
191
RSDK.SetSpriteAnimation(GiantPistol->aniFrames, 7, &self->handLowAnimator, true, 0);
192
RSDK.SetSpriteAnimation(GiantPistol->aniFrames, 7, &self->handHighAnimator, true, 1);
193
self->state = GiantPistol_State_Aiming;
194
self->active = ACTIVE_NORMAL;
195
196
foreach_active(Player, playerPtr)
197
{
198
if (((1 << (playerPtr->playerID)) & self->activePlayers) > 0) {
199
if (playerPtr->camera)
200
playerPtr->camera->state = Camera_State_FollowXY;
201
}
202
}
203
}
204
}
205
206
void GiantPistol_State_Aiming(void)
207
{
208
RSDK_THIS(GiantPistol);
209
210
if (self->timer) {
211
self->timer--;
212
}
213
else {
214
if (self->rotationVel > 4)
215
self->rotationVel--;
216
217
self->angle += self->direction ? -self->rotationVel : self->rotationVel;
218
self->angle &= 0x1FF;
219
}
220
221
self->position = self->startPos;
222
self->rotation = (-RSDK.Sin512(self->angle) >> 3) & 0x1FF;
223
int32 angle = 0x100 - (self->rotation >> 1);
224
Zone_RotateOnPivot(&self->position, &self->pivot, angle);
225
226
self->position.x -= RSDK.Sin512(self->rotation) << 10;
227
self->position.y -= RSDK.Sin512(self->rotation) << 10;
228
229
if (self->direction) {
230
if (self->playerPos <= 0x500000)
231
self->playerPos += 0x40000;
232
}
233
else {
234
if (self->playerPos > -0x500000)
235
self->playerPos -= 0x40000;
236
}
237
238
uint8 jumpPressed = 0;
239
#if MANIA_USE_PLUS
240
if (GiantPistol->inCutscene) {
241
#else
242
if (!Zone->actID && !CHECK_CHARACTER_ID(ID_KNUCKLES, 1)) {
243
#endif
244
if (self->angle == 0x76 && self->activePlayers > 0) {
245
#if MANIA_USE_PLUS
246
if (SceneInfo->filter & FILTER_ENCORE) {
247
MSZSetup_ReloadBGParallax();
248
MSZSetup_ReloadBGParallax_Multiply(0x000);
249
}
250
else
251
#endif
252
MSZSetup_ReloadBGParallax_Multiply(0x400);
253
254
jumpPressed = true;
255
}
256
}
257
else {
258
foreach_active(Player, player)
259
{
260
if (((1 << (player->playerID)) & self->activePlayers) > 0)
261
jumpPressed |= player->jumpPress;
262
}
263
}
264
265
foreach_active(Player, player)
266
{
267
if (((1 << (player->playerID)) & self->activePlayers) > 0) {
268
player->position.x = self->position.x + self->playerPos;
269
player->position.y = self->position.y - 0x200000;
270
271
Zone_RotateOnPivot(&player->position, &self->position, angle);
272
if (jumpPressed) {
273
player->state = Player_State_Air;
274
player->onGround = false;
275
player->jumpAbilityState = 0;
276
player->applyJumpCap = false;
277
player->jumpPress = false;
278
player->jumpHold = false;
279
280
if (self->direction) {
281
player->velocity.x = 0xC00 * RSDK.Cos512(self->rotation);
282
player->velocity.y = 0xC00 * RSDK.Sin512(self->rotation);
283
}
284
else {
285
player->velocity.x = -0xC00 * RSDK.Cos512(self->rotation);
286
player->velocity.y = -0xC00 * RSDK.Sin512(self->rotation);
287
}
288
289
#if MANIA_USE_PLUS
290
if (SceneInfo->filter == (FILTER_BOTH | FILTER_ENCORE) && GiantPistol->inCutscene) {
291
player->velocity.x += 0x18000;
292
player->state = GiantPistol_PlayerState_PistolAir;
293
player->nextGroundState = GiantPistol_PlayerState_PistolGround;
294
}
295
else if (!Zone->actID && !CHECK_CHARACTER_ID(ID_KNUCKLES, 1)) {
296
player->jumpAbilityState = 0;
297
}
298
#else
299
if (!Zone->actID && !CHECK_CHARACTER_ID(ID_KNUCKLES, 1))
300
player->jumpAbilityState = 0;
301
#endif
302
303
self->activePlayers &= ~(1 << player->playerID);
304
self->timer = 16;
305
306
player->velocity.x = CLAMP(player->velocity.x, -0x120000, 0x120000);
307
player->visible = true;
308
Camera_ShakeScreen(player->playerID, -8, -8);
309
RSDK.PlaySfx(GiantPistol->sfxCannonFire, false, 255);
310
}
311
}
312
}
313
314
if (!self->activePlayers && !self->timer) {
315
if (self->rotation > 0x100)
316
self->rotation -= 0x200;
317
318
self->state = GiantPistol_State_FiredPlayers;
319
}
320
}
321
322
void GiantPistol_State_FiredPlayers(void)
323
{
324
RSDK_THIS(GiantPistol);
325
326
if (self->rotation <= 0) {
327
self->rotation += 4;
328
329
if (self->rotation > 0)
330
self->rotation = 0;
331
}
332
else {
333
self->rotation -= 4;
334
335
if (self->rotation < 0)
336
self->rotation = 0;
337
}
338
339
if (self->chamberAnimator.frameID > 0)
340
self->chamberAnimator.frameID--;
341
342
self->position.x += (self->startPos.x - self->position.x) >> 3;
343
self->position.y += (self->startPos.y - self->position.y) >> 3;
344
345
if (++self->timer == 60) {
346
self->position = self->startPos;
347
self->timer = 0;
348
self->angle = 0;
349
self->drawFX = FX_FLIP;
350
self->active = ACTIVE_BOUNDS;
351
self->state = GiantPistol_State_AwaitPlayerEntry;
352
353
RSDK.SetSpriteAnimation(GiantPistol->aniFrames, 5, &self->chamberAnimator, true, 0);
354
RSDK.SetSpriteAnimation(GiantPistol->aniFrames, 1, &self->handLowAnimator, true, 0);
355
RSDK.SetSpriteAnimation(GiantPistol->aniFrames, 2, &self->handHighAnimator, true, 0);
356
}
357
}
358
359
#if MANIA_USE_PLUS
360
void GiantPistol_PlayerState_PistolAir(void)
361
{
362
RSDK_THIS(Player);
363
364
self->left = false;
365
self->right = true;
366
self->up = false;
367
self->down = false;
368
self->jumpPress = false;
369
self->jumpHold = false;
370
371
Player_State_Air();
372
373
self->nextGroundState = GiantPistol_PlayerState_PistolGround;
374
}
375
376
void GiantPistol_PlayerState_PistolGround(void)
377
{
378
RSDK_THIS(Player);
379
380
self->left = true;
381
self->right = false;
382
self->up = false;
383
self->down = false;
384
self->jumpPress = false;
385
self->jumpHold = false;
386
387
Player_State_Ground();
388
389
self->state = GiantPistol_PlayerState_PistolGround;
390
self->nextGroundState = GiantPistol_PlayerState_PistolGround;
391
392
if (self->groundVel <= 0) {
393
RSDK.SetSpriteAnimation(self->aniFrames, ANI_IDLE, &self->animator, true, 0);
394
self->left = false;
395
self->skidding = 0;
396
self->groundVel = 0;
397
self->velocity.x = 0;
398
self->direction = FLIP_NONE;
399
self->state = Player_State_Ground;
400
self->nextGroundState = Player_State_Ground;
401
}
402
}
403
#endif
404
405
#if GAME_INCLUDE_EDITOR
406
void GiantPistol_EditorDraw(void)
407
{
408
RSDK_THIS(GiantPistol);
409
410
RSDK.SetSpriteAnimation(GiantPistol->aniFrames, 0, &self->pistolAnimator, true, 0);
411
RSDK.SetSpriteAnimation(GiantPistol->aniFrames, 0, &self->pistolEntryAnimator, true, 1);
412
RSDK.SetSpriteAnimation(GiantPistol->aniFrames, 5, &self->chamberAnimator, true, 0);
413
RSDK.SetSpriteAnimation(GiantPistol->aniFrames, 6, &self->hammerAnimator, true, 0);
414
RSDK.SetSpriteAnimation(GiantPistol->aniFrames, 4, &self->triggerAnimator, true, 0);
415
RSDK.SetSpriteAnimation(GiantPistol->aniFrames, 1, &self->handLowAnimator, true, 0);
416
RSDK.SetSpriteAnimation(GiantPistol->aniFrames, 2, &self->handHighAnimator, true, 0);
417
RSDK.SetSpriteAnimation(GiantPistol->aniFrames, 3, &self->triggerFingerAnimator, true, 0);
418
419
RSDK.DrawSprite(&self->pistolEntryAnimator, NULL, false);
420
RSDK.DrawSprite(&self->handLowAnimator, NULL, false);
421
RSDK.DrawSprite(&self->triggerAnimator, NULL, false);
422
RSDK.DrawSprite(&self->hammerAnimator, NULL, false);
423
RSDK.DrawSprite(&self->chamberAnimator, NULL, false);
424
RSDK.DrawSprite(&self->pistolAnimator, NULL, false);
425
RSDK.DrawSprite(&self->handHighAnimator, NULL, false);
426
RSDK.DrawSprite(&self->triggerFingerAnimator, NULL, false);
427
}
428
429
void GiantPistol_EditorLoad(void)
430
{
431
GiantPistol->aniFrames = RSDK.LoadSpriteAnimation("MSZ/Pistol.bin", SCOPE_STAGE);
432
433
RSDK_ACTIVE_VAR(GiantPistol, direction);
434
RSDK_ENUM_VAR("Left", FLIP_NONE);
435
RSDK_ENUM_VAR("Right", FLIP_X);
436
}
437
#endif
438
439
void GiantPistol_Serialize(void) { RSDK_EDITABLE_VAR(GiantPistol, VAR_UINT8, direction); }
440
441