Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rubberduckycooly
GitHub Repository: rubberduckycooly/Sonic-Mania-Decompilation
Path: blob/master/SonicMania/Objects/SPZ/HeavyGunner.c
338 views
1
// ---------------------------------------------------------------------
2
// RSDK Project: Sonic Mania
3
// Object Description: HeavyGunner Object
4
// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges
5
// Decompiled by: Rubberduckycooly & RMGRich
6
// ---------------------------------------------------------------------
7
8
#include "Game.h"
9
10
ObjectHeavyGunner *HeavyGunner;
11
12
void HeavyGunner_Update(void)
13
{
14
RSDK_THIS(HeavyGunner);
15
16
StateMachine_Run(self->state);
17
}
18
19
void HeavyGunner_LateUpdate(void) {}
20
21
void HeavyGunner_StaticUpdate(void) {}
22
23
void HeavyGunner_Draw(void)
24
{
25
RSDK_THIS(HeavyGunner);
26
27
StateMachine_Run(self->stateDraw);
28
}
29
30
void HeavyGunner_Create(void *data)
31
{
32
RSDK_THIS(HeavyGunner);
33
34
if (!SceneInfo->inEditor) {
35
if (globals->gameMode < MODE_TIMEATTACK) {
36
if (data) {
37
self->type = VOID_TO_INT(data);
38
self->active = ACTIVE_NORMAL;
39
self->visible = true;
40
self->drawGroup = Zone->objectDrawGroup[0] - 1;
41
42
switch (self->type) {
43
case HEAVYGUNNER_HELI:
44
RSDK.SetSpriteAnimation(HeavyGunner->aniFrames, 6, &self->mainAnimator, true, 0);
45
RSDK.SetSpriteAnimation(HeavyGunner->aniFrames, 14, &self->pilotAnimator, true, 0);
46
RSDK.SetSpriteAnimation(HeavyGunner->aniFrames, 7, &self->frontAnimator, true, 0);
47
RSDK.SetSpriteAnimation(HeavyGunner->aniFrames, 8, &self->tBladeAnimator, true, 0);
48
RSDK.SetSpriteAnimation(HeavyGunner->aniFrames, 9, &self->rBladeAnimator, true, 0);
49
RSDK.SetSpriteAnimation(HeavyGunner->aniFrames, 10, &self->beaconAnimator, true, 0);
50
RSDK.SetSpriteAnimation(HeavyGunner->aniFrames, 11, &self->feetAnimator, true, 0);
51
RSDK.SetSpriteAnimation(HeavyGunner->aniFrames, 11, &self->feet2Animator, true, 2);
52
RSDK.SetSpriteAnimation(HeavyGunner->aniFrames, 0, &self->gunnerAnimator, true, 0);
53
54
self->drawFX = FX_ROTATE;
55
self->rotation = 0x40;
56
self->state = HeavyGunner_StateHeli_AwaitPlayer;
57
self->stateDraw = HeavyGunner_Draw_Heli;
58
break;
59
60
case HEAVYGUNNER_EGGROBO:
61
RSDK.SetSpriteAnimation(HeavyGunner->aniFrames, 17, &self->feetAnimator, true, 0);
62
RSDK.SetSpriteAnimation(HeavyGunner->aniFrames, 16, &self->mainAnimator, true, RSDK.Rand(0, 4));
63
self->drawFX = FX_SCALE | FX_ROTATE;
64
self->state = HeavyGunner_StateEggRobo_Patrolling;
65
self->stateDraw = HeavyGunner_Draw_EggRobo;
66
self->scale.x = 0x200;
67
self->scale.y = 0x200;
68
self->targetScale = 512;
69
self->parentOffset = RSDK.Rand(-0x200000, 0x600000);
70
self->timer = 240;
71
break;
72
73
case HEAVYGUNNER_GUN:
74
RSDK.SetSpriteAnimation(HeavyGunner->aniFrames, 20, &self->mainAnimator, true, 0);
75
self->drawFX = FX_ROTATE;
76
self->rotation = 64;
77
self->state = HeavyGunner_StateGun_Thrown;
78
self->stateDraw = HeavyGunner_Draw_Simple;
79
break;
80
81
case HEAVYGUNNER_MISSILE_F:
82
case HEAVYGUNNER_MISSILE:
83
if (self->type == HEAVYGUNNER_MISSILE_F)
84
RSDK.SetSpriteAnimation(HeavyGunner->aniFrames, 29, &self->mainAnimator, true, 0);
85
else
86
RSDK.SetSpriteAnimation(HeavyGunner->aniFrames, 30, &self->mainAnimator, true, 0);
87
self->drawFX = FX_SCALE | FX_ROTATE | FX_FLIP;
88
self->velocity.x = 0x40000;
89
self->velocity.y = -0x38000;
90
self->scale.x = 0x100;
91
self->scale.y = 0x100;
92
self->rotation = -24;
93
self->state = HeavyGunner_StateMissile_Launched;
94
self->stateDraw = HeavyGunner_Draw_Missile;
95
self->drawGroup = Zone->objectDrawGroup[0];
96
break;
97
98
case HEAVYGUNNER_ESCAPE_HBH:
99
RSDK.SetSpriteAnimation(HeavyGunner->aniFrames, 5, &self->mainAnimator, true, 0);
100
self->velocity.x = -0x20000;
101
self->velocity.y = -0x20000;
102
self->state = HeavyGunner_StateEscapeHBH_Hover;
103
self->stateDraw = HeavyGunner_Draw_Simple;
104
self->drawGroup = Zone->objectDrawGroup[0];
105
break;
106
107
default: break;
108
}
109
}
110
else {
111
Zone->autoScrollSpeed = 0;
112
self->active = ACTIVE_XBOUNDS;
113
self->updateRange.x = 0x800000;
114
self->updateRange.y = 0x800000;
115
self->state = HeavyGunner_StateManager_SetupArena;
116
}
117
}
118
else {
119
destroyEntity(self);
120
}
121
}
122
}
123
124
void HeavyGunner_StageLoad(void)
125
{
126
HeavyGunner->aniFrames = RSDK.LoadSpriteAnimation("SPZ1/Boss.bin", SCOPE_STAGE);
127
128
HeavyGunner->sfxFire = RSDK.GetSfx("Stage/CannonFire.wav");
129
HeavyGunner->sfxJet = RSDK.GetSfx("Stage/RocketJet.wav");
130
HeavyGunner->sfxHit = RSDK.GetSfx("Stage/BossHit.wav");
131
HeavyGunner->sfxDestroy = RSDK.GetSfx("Global/Destroy.wav");
132
HeavyGunner->sfxExplosion2 = RSDK.GetSfx("Stage/Explosion2.wav");
133
HeavyGunner->sfxExplosion3 = RSDK.GetSfx("Stage/Explosion3.wav");
134
HeavyGunner->sfxCharge = RSDK.GetSfx("SPZ1/BazookaCharge.wav");
135
HeavyGunner->sfxThrow = RSDK.GetSfx("SPZ1/BazookaThrow.wav");
136
HeavyGunner->sfxFlyIn = RSDK.GetSfx("SPZ1/EggRoboFlyIn.wav");
137
HeavyGunner->sfxWooshIn = RSDK.GetSfx("SPZ1/HeliWooshIn.wav");
138
HeavyGunner->sfxWooshOut = RSDK.GetSfx("SPZ1/HeliWooshOut.wav");
139
HeavyGunner->sfxFlip = RSDK.GetSfx("SPZ1/RocketFlip.wav");
140
HeavyGunner->sfxRumble = RSDK.GetSfx("SPZ1/Rumble.wav");
141
142
Soundboard_LoadSfx("SPZ1/HBHSurprise.wav", true, HeavyGunner_SfxCheck_HBHSurprise, StateMachine_None);
143
Soundboard_LoadSfx("SPZ1/HeliProp.wav", true, HeavyGunner_SfxCheck_HeliProp, StateMachine_None);
144
Soundboard_LoadSfx("SPZ1/RocketBurn.wav", true, HeavyGunner_SfxCheck_RocketBurn, StateMachine_None);
145
146
// Absolutely zero clue what these are for
147
HeavyGunner->unused1 = 0x470000;
148
HeavyGunner->unused2 = 0x2D0000;
149
HeavyGunner->unused3 = 0x100000;
150
HeavyGunner->unused4 = 0x80000;
151
152
HeavyGunner->hitboxMissileF.left = -32;
153
HeavyGunner->hitboxMissileF.top = -8;
154
HeavyGunner->hitboxMissileF.right = 32;
155
HeavyGunner->hitboxMissileF.bottom = 8;
156
157
HeavyGunner->hitboxMissile.left = -16;
158
HeavyGunner->hitboxMissile.top = -8;
159
HeavyGunner->hitboxMissile.right = 16;
160
HeavyGunner->hitboxMissile.bottom = 8;
161
162
HeavyGunner->active = ACTIVE_NEVER;
163
}
164
165
bool32 HeavyGunner_SfxCheck_HeliProp(void)
166
{
167
Vector2 range;
168
169
range.x = 0x800000;
170
range.y = 0x800000;
171
bool32 active = false;
172
173
foreach_active(HeavyGunner, gunner)
174
{
175
if (RSDK.CheckOnScreen(gunner, &range) && gunner->tBladeAnimator.animationID == 8)
176
active = true;
177
}
178
return active;
179
}
180
181
bool32 HeavyGunner_SfxCheck_HBHSurprise(void)
182
{
183
Vector2 range;
184
185
range.x = 0x800000;
186
range.y = 0x800000;
187
bool32 active = false;
188
189
foreach_active(HeavyGunner, gunner)
190
{
191
if (RSDK.CheckOnScreen(gunner, &range) && gunner->gunnerAnimator.animationID == 3 && gunner->mainAnimator.animationID != 12)
192
active = true;
193
}
194
195
return active;
196
}
197
198
bool32 HeavyGunner_SfxCheck_RocketBurn(void)
199
{
200
Vector2 range;
201
202
range.x = 0x800000;
203
range.y = 0x800000;
204
bool32 active = false;
205
206
foreach_active(HeavyGunner, gunner)
207
{
208
if (RSDK.CheckOnScreen(gunner, &range) && gunner->exhaustAnimator.animationID == 25)
209
active = true;
210
}
211
return active;
212
}
213
214
void HeavyGunner_HandleBGWrap(int32 multiplier)
215
{
216
TileLayer *background1 = RSDK.GetTileLayer(0);
217
for (int32 s = 0; s < background1->scrollInfoCount; ++s) {
218
background1->scrollInfo[s].scrollPos += multiplier * background1->scrollInfo[s].parallaxFactor;
219
}
220
221
TileLayer *background2 = RSDK.GetTileLayer(1);
222
for (int32 s = 0; s < background2->scrollInfoCount; ++s) {
223
background2->scrollInfo[s].scrollPos += multiplier * background2->scrollInfo[s].parallaxFactor;
224
}
225
226
TileLayer *background3 = RSDK.GetTileLayer(2);
227
for (int32 s = 0; s < background3->scrollInfoCount; ++s) {
228
background3->scrollInfo[s].scrollPos += multiplier * background3->scrollInfo[s].parallaxFactor;
229
}
230
}
231
232
void HeavyGunner_DestroyAllMissiles(void)
233
{
234
RSDK_THIS(HeavyGunner);
235
236
foreach_active(HeavyGunner, gunner)
237
{
238
if (gunner != self) {
239
if (gunner->type == HEAVYGUNNER_MISSILE_F || gunner->type == HEAVYGUNNER_MISSILE) {
240
RSDK.PlaySfx(HeavyGunner->sfxFlip, false, 0xFF);
241
gunner->velocity.x = -0x10000;
242
RSDK.SetSpriteAnimation(-1, 0, &gunner->exhaustAnimator, true, 0);
243
244
gunner->direction = FLIP_NONE;
245
gunner->rotation = 256;
246
gunner->state = HeavyGunner_StateMissile_Malfunction;
247
}
248
}
249
}
250
}
251
252
void HeavyGunner_Draw_Heli(void)
253
{
254
RSDK_THIS(HeavyGunner);
255
Vector2 drawPos;
256
257
drawPos.x = self->position.x + 0x1B0000;
258
drawPos.y = self->position.y;
259
260
RSDK.DrawSprite(&self->feetAnimator, &drawPos, false);
261
RSDK.DrawSprite(&self->mainAnimator, NULL, false);
262
RSDK.DrawSprite(&self->pilotAnimator, NULL, false);
263
RSDK.DrawSprite(&self->frontAnimator, NULL, false);
264
RSDK.DrawSprite(&self->tBladeAnimator, NULL, false);
265
RSDK.DrawSprite(&self->rBladeAnimator, NULL, false);
266
RSDK.DrawSprite(&self->beaconAnimator, NULL, false);
267
RSDK.DrawSprite(&self->feet2Animator, NULL, false);
268
RSDK.DrawSprite(&self->gunnerAnimator, NULL, false);
269
}
270
271
void HeavyGunner_Draw_EggRobo(void)
272
{
273
RSDK_THIS(HeavyGunner);
274
275
RSDK.DrawSprite(&self->feetAnimator, NULL, false);
276
RSDK.DrawSprite(&self->mainAnimator, NULL, false);
277
RSDK.DrawSprite(&self->armAnimator, NULL, false);
278
}
279
280
void HeavyGunner_Draw_Missile(void)
281
{
282
RSDK_THIS(HeavyGunner);
283
284
RSDK.DrawSprite(&self->mainAnimator, NULL, false);
285
RSDK.DrawSprite(&self->exhaustAnimator, NULL, false);
286
}
287
288
void HeavyGunner_Draw_Simple(void)
289
{
290
RSDK_THIS(HeavyGunner);
291
RSDK.DrawSprite(&self->mainAnimator, NULL, false);
292
}
293
294
void HeavyGunner_Draw_FadeOut(void)
295
{
296
RSDK_THIS(HeavyGunner);
297
298
RSDK.FillScreen(0xF0F0F0, self->timer, self->timer - 128, self->timer - 256);
299
}
300
301
void HeavyGunner_StateManager_SetupArena(void)
302
{
303
RSDK_THIS(HeavyGunner);
304
305
if (++self->timer >= 8) {
306
EntityPlayer *player1 = RSDK_GET_ENTITY(SLOT_PLAYER1, Player);
307
308
if (player1->position.x >= self->position.x - 0x1000000) {
309
HeavyGunner->active = ACTIVE_ALWAYS;
310
self->timer = 0;
311
self->active = ACTIVE_NORMAL;
312
313
EntityCamera *camera = RSDK_GET_ENTITY(SLOT_CAMERA1, Camera);
314
self->position.x = camera->position.x - 0x100000;
315
self->position.y = camera->position.y;
316
317
Zone->playerBoundActiveL[0] = true;
318
Zone->playerBoundActiveR[0] = true;
319
HeavyGunner->boundsL = Zone->cameraBoundsL[0];
320
HeavyGunner->boundsR = Zone->cameraBoundsR[0];
321
HeavyGunner->boundsT = Zone->cameraBoundsT[0];
322
HeavyGunner->boundsB = 0xC00;
323
HeavyGunner->stageWrapActive = true;
324
325
int32 mult = -0x1E00 * ScreenInfo->position.y;
326
327
TileLayer *background1 = RSDK.GetTileLayer(0);
328
background1->scrollPos += mult;
329
background1->parallaxFactor = 88;
330
331
TileLayer *background2 = RSDK.GetTileLayer(1);
332
background2->scrollPos += mult;
333
background2->parallaxFactor = 88;
334
335
TileLayer *background3 = RSDK.GetTileLayer(2);
336
background3->scrollPos += mult;
337
background3->parallaxFactor = 88;
338
339
foreach_active(ParallaxSprite, sprite)
340
{
341
sprite->parallaxFactor.y = 0x5800;
342
sprite->position.y -= mult;
343
}
344
345
Zone->autoScrollSpeed = player1->velocity.x;
346
347
EntityHeavyGunner *robo1 = RSDK_GET_ENTITY(SceneInfo->entitySlot + 1, HeavyGunner);
348
int32 x = robo1->position.x;
349
int32 y = robo1->position.y;
350
RSDK.ResetEntitySlot(SceneInfo->entitySlot + 1, HeavyGunner->classID, INT_TO_VOID(HEAVYGUNNER_EGGROBO));
351
robo1->position.x = x;
352
robo1->position.y = y;
353
robo1->parent = RSDK_GET_ENTITY(SceneInfo->entitySlot + 4, HeavyGunner);
354
robo1->angle = 0;
355
RSDK.SetSpriteAnimation(HeavyGunner->aniFrames, 22, &robo1->armAnimator, true, 0);
356
357
EntityHeavyGunner *robo2 = RSDK_GET_ENTITY(SceneInfo->entitySlot + 2, HeavyGunner);
358
x = robo2->position.x;
359
y = robo2->position.y;
360
RSDK.ResetEntitySlot(SceneInfo->entitySlot + 2, HeavyGunner->classID, INT_TO_VOID(HEAVYGUNNER_EGGROBO));
361
robo2->position.x = x;
362
robo2->position.y = y;
363
robo2->parent = RSDK_GET_ENTITY(SceneInfo->entitySlot + 4, HeavyGunner);
364
robo2->angle = 80;
365
RSDK.SetSpriteAnimation(HeavyGunner->aniFrames, 23, &robo2->armAnimator, true, 0);
366
367
EntityHeavyGunner *robo3 = RSDK_GET_ENTITY(SceneInfo->entitySlot + 3, HeavyGunner);
368
x = robo3->position.x;
369
y = robo3->position.y;
370
RSDK.ResetEntitySlot(SceneInfo->entitySlot + 3, HeavyGunner->classID, INT_TO_VOID(HEAVYGUNNER_EGGROBO));
371
robo3->position.x = x;
372
robo3->position.y = y;
373
robo3->parent = RSDK_GET_ENTITY(SceneInfo->entitySlot + 4, HeavyGunner);
374
robo3->angle = 160;
375
robo3->timer = 0;
376
robo3->state = HeavyGunner_StateEggRobo_FlyIn;
377
RSDK.SetSpriteAnimation(HeavyGunner->aniFrames, 19, &robo3->armAnimator, true, 0);
378
379
EntityHeavyGunner *heli = RSDK_GET_ENTITY(SceneInfo->entitySlot + 4, HeavyGunner);
380
x = heli->position.x;
381
y = heli->position.y;
382
RSDK.ResetEntitySlot(SceneInfo->entitySlot + 4, HeavyGunner->classID, INT_TO_VOID(HEAVYGUNNER_HELI));
383
heli->position.x = x;
384
heli->position.y = y;
385
386
self->state = HeavyGunner_StateManager_HandleStageWrap;
387
Music_TransitionTrack(TRACK_HBHBOSS, 0.0125);
388
}
389
}
390
}
391
392
void HeavyGunner_StateManager_HandleStageWrap(void)
393
{
394
RSDK_THIS(HeavyGunner);
395
396
self->position.x += Zone->autoScrollSpeed;
397
398
if (HeavyGunner->stageWrapActive) {
399
if (self->position.x >= 0x49800000) {
400
HeavyGunner_HandleBGWrap(0x80000);
401
402
foreach_active(HeavyGunner, gunner) { gunner->position.x -= 0x8000000; }
403
404
for (int32 p = 0; p < Player->playerCount; ++p) {
405
EntityPlayer *player = RSDK_GET_ENTITY(p, Player);
406
player->position.x -= 0x8000000;
407
}
408
409
foreach_active(Ring, ring) { ring->position.x -= 0x8000000; }
410
411
foreach_active(ImageTrail, imageTrail)
412
{
413
imageTrail->position.x -= 0x8000000;
414
imageTrail->currentPos.x -= 0x8000000;
415
for (int32 i = 0; i < IMAGETRAIL_TRACK_COUNT; ++i) imageTrail->statePos[i].x -= 0x8000000;
416
}
417
}
418
419
Zone->cameraBoundsL[0] = (self->position.x >> 16) - ScreenInfo->center.x;
420
Zone->cameraBoundsR[0] = (self->position.x >> 16) + ScreenInfo->center.x;
421
Zone->playerBoundsL[0] = Zone->cameraBoundsL[0] << 16;
422
Zone->playerBoundsR[0] = Zone->cameraBoundsR[0] << 16;
423
424
EntityCamera *camera = RSDK_GET_ENTITY(SLOT_CAMERA1, Camera);
425
camera->boundsL = Zone->cameraBoundsL[0];
426
camera->boundsR = Zone->cameraBoundsR[0];
427
428
if (self->flyInTimer == 120) {
429
if (!RSDK.ObjectTileGrip(self, Zone->collisionLayers, CMODE_FLOOR, 0, 0, 0x800000, 0x40))
430
self->position.y += 0x80000;
431
Zone->cameraBoundsB[0] = (self->position.y >> 16) + 168;
432
Zone->cameraBoundsT[0] = Zone->cameraBoundsB[0] - ScreenInfo->size.y;
433
}
434
else {
435
self->flyInTimer++;
436
}
437
}
438
else if (self->position.x < 0x49800000) {
439
Zone->cameraBoundsL[0] = (self->position.x >> 16) - ScreenInfo->center.x;
440
Zone->cameraBoundsR[0] = (self->position.x >> 16) + ScreenInfo->center.x;
441
Zone->playerBoundsL[0] = Zone->cameraBoundsL[0] << 16;
442
Zone->playerBoundsR[0] = Zone->cameraBoundsR[0] << 16;
443
444
EntityCamera *camera = RSDK_GET_ENTITY(SLOT_CAMERA1, Camera);
445
camera->boundsL = Zone->cameraBoundsL[0];
446
camera->boundsR = Zone->cameraBoundsR[0];
447
448
if (self->flyInTimer == 120) {
449
if (!RSDK.ObjectTileGrip(self, Zone->collisionLayers, CMODE_FLOOR, 0, 0, 0x800000, 0x40))
450
self->position.y += 0x80000;
451
Zone->cameraBoundsB[0] = (self->position.y >> 16) + 168;
452
Zone->cameraBoundsT[0] = Zone->cameraBoundsB[0] - ScreenInfo->size.y;
453
}
454
else {
455
self->flyInTimer++;
456
}
457
}
458
else {
459
Zone->cameraBoundsL[0] = HeavyGunner->boundsL;
460
Zone->cameraBoundsR[0] = HeavyGunner->boundsR;
461
Zone->cameraBoundsT[0] = HeavyGunner->boundsT;
462
Zone->cameraBoundsB[0] = HeavyGunner->boundsB;
463
Zone->playerBoundActiveR[0] = false;
464
465
for (int32 p = 0; p < Player->playerCount; ++p) {
466
EntityPlayer *player = RSDK_GET_ENTITY(p, Player);
467
if (player->stateInput == Player_Input_P1) {
468
player->stateInput = HeavyGunner_Input_LockedP1;
469
}
470
else if (player->stateInput == Player_Input_P2_Player) {
471
player->stateInput = HeavyGunner_Input_LockedP2;
472
}
473
else if (player->stateInput == Player_Input_P2_AI) {
474
player->stateInput = HeavyGunner_Input_LockedP2_AI;
475
}
476
}
477
478
self->state = HeavyGunner_StateManager_HandlePathChange;
479
}
480
481
if (Zone->autoScrollSpeed > 0x70000) {
482
Zone->autoScrollSpeed -= 0x2000;
483
if (Zone->autoScrollSpeed < 0x70000)
484
Zone->autoScrollSpeed = 0x70000;
485
}
486
else if (Zone->autoScrollSpeed < 0x70000) {
487
Zone->autoScrollSpeed += 0x2000;
488
if (Zone->autoScrollSpeed > 0x70000)
489
Zone->autoScrollSpeed = 0x70000;
490
}
491
492
for (int32 p = 0; p < Player->playerCount; ++p) {
493
EntityPlayer *player = RSDK_GET_ENTITY(p, Player);
494
495
if (player->groundVel < Zone->autoScrollSpeed - 0x20000)
496
player->groundVel = Zone->autoScrollSpeed - 0x20000;
497
498
player->direction = FLIP_NONE;
499
player->topSpeed = Zone->autoScrollSpeed + 0x20000;
500
501
if (player->state == Player_State_KnuxGlideLeft) {
502
player->timer = 0;
503
player->animator.frameID = 6;
504
player->state = Player_State_KnuxGlideRight;
505
player->abilitySpeed = Zone->autoScrollSpeed - 0x18000;
506
}
507
else if (player->state == Player_State_KnuxGlideRight) {
508
if (player->abilitySpeed < Zone->autoScrollSpeed - 0x18000)
509
player->abilitySpeed = Zone->autoScrollSpeed - 0x18000;
510
}
511
512
if (player->groundVel > player->topSpeed)
513
player->groundVel = player->topSpeed;
514
}
515
}
516
517
void HeavyGunner_StateManager_HandlePathChange(void)
518
{
519
RSDK_THIS(HeavyGunner);
520
521
EntityCamera *camera = RSDK_GET_ENTITY(SLOT_CAMERA1, Camera);
522
if (camera->position.x <= 0x51800000) {
523
for (int32 p = 0; p < Player->playerCount; ++p) {
524
EntityPlayer *player = RSDK_GET_ENTITY(p, Player);
525
526
if (player->onGround) {
527
if (player->groundVel < 0x80000)
528
player->groundVel = 0x80000;
529
}
530
else if (player->velocity.x < 0x80000) {
531
player->velocity.x = 0x80000;
532
}
533
534
player->direction = FLIP_NONE;
535
536
if (player->state == Player_State_KnuxGlideLeft) {
537
player->timer = 0;
538
player->animator.frameID = 6;
539
player->state = Player_State_KnuxGlideRight;
540
player->abilitySpeed = Zone->autoScrollSpeed;
541
}
542
else if (player->state == Player_State_KnuxGlideRight) {
543
if (player->abilitySpeed < Zone->autoScrollSpeed)
544
player->abilitySpeed = Zone->autoScrollSpeed;
545
}
546
}
547
}
548
else {
549
camera->position.x -= 0x10000000;
550
self->position.x = camera->position.x - 0x100000;
551
self->position.y = camera->position.y - 0x800000;
552
HeavyGunner_HandleBGWrap(0x100000);
553
554
for (int32 p = 0; p < Player->playerCount; ++p) {
555
EntityPlayer *player = RSDK_GET_ENTITY(p, Player);
556
player->position.x -= 0x10000000;
557
if (player->velocity.x > Zone->autoScrollSpeed)
558
Zone->autoScrollSpeed = player->velocity.x;
559
}
560
561
foreach_active(Ring, ring) { ring->position.x -= 0x10000000; }
562
563
foreach_active(ImageTrail, imageTrail)
564
{
565
imageTrail->position.x -= 0x10000000;
566
imageTrail->currentPos.x -= 0x10000000;
567
for (int32 i = 0; i < IMAGETRAIL_TRACK_COUNT; ++i) imageTrail->statePos[i].x -= 0x10000000;
568
}
569
570
for (int32 p = 0; p < Player->playerCount; ++p) {
571
EntityPlayer *player = RSDK_GET_ENTITY(p, Player);
572
573
if (player->stateInput == HeavyGunner_Input_LockedP1)
574
player->stateInput = Player_Input_P1;
575
else if (player->stateInput == HeavyGunner_Input_LockedP2)
576
player->stateInput = Player_Input_P2_Player;
577
else if (player->stateInput == HeavyGunner_Input_LockedP2_AI)
578
player->stateInput = Player_Input_P2_AI;
579
}
580
581
Zone->playerBoundActiveR[0] = true;
582
HeavyGunner->stageWrapActive = true;
583
self->state = HeavyGunner_StateManager_HandleStageWrap;
584
585
EntityHeavyGunner *heli = RSDK_GET_ENTITY(SceneInfo->entitySlot + 4, HeavyGunner);
586
heli->position.x = camera->position.x - 0x1200000;
587
heli->position.y = camera->position.y - 0xC00000;
588
RSDK.SetSpriteAnimation(HeavyGunner->aniFrames, 1, &heli->gunnerAnimator, true, 0);
589
heli->state = HeavyGunner_StateHeli_AwaitPlayer;
590
591
for (int32 c = 3 - heli->nextRoboID; c > 0; --c) {
592
EntityHeavyGunner *robo = RSDK_GET_ENTITY(SceneInfo->entitySlot + c, HeavyGunner);
593
robo->position.x = camera->position.x - 0x200000;
594
robo->position.y = camera->position.y - 0xC00000;
595
}
596
}
597
}
598
599
void HeavyGunner_Input_LockedP1(void)
600
{
601
RSDK_THIS(Player);
602
603
Player_Input_P1();
604
605
if (self->state != Player_State_Static) {
606
self->up = false;
607
self->down = false;
608
self->jumpPress = false;
609
self->jumpHold = false;
610
}
611
}
612
613
void HeavyGunner_Input_LockedP2(void)
614
{
615
RSDK_THIS(Player);
616
617
Player_Input_P2_Player();
618
619
self->up = false;
620
self->down = false;
621
self->jumpPress = false;
622
self->jumpHold = false;
623
624
if (self->stateInput == Player_Input_P2_AI)
625
self->stateInput = HeavyGunner_Input_LockedP2_AI;
626
}
627
628
void HeavyGunner_Input_LockedP2_AI(void)
629
{
630
RSDK_THIS(Player);
631
Player_Input_P2_AI();
632
633
self->up = false;
634
self->down = false;
635
self->jumpPress = false;
636
self->jumpHold = false;
637
638
if (self->stateInput == Player_Input_P2_Player)
639
self->stateInput = HeavyGunner_Input_LockedP2;
640
}
641
642
void HeavyGunner_StateEggRobo_Patrolling(void)
643
{
644
RSDK_THIS(HeavyGunner);
645
EntityHeavyGunner *parent = self->parent;
646
647
RSDK.ProcessAnimation(&self->mainAnimator);
648
RSDK.ProcessAnimation(&self->feetAnimator);
649
RSDK.ProcessAnimation(&self->armAnimator);
650
651
int32 angle = RSDK.Sin256(self->angle);
652
if (self->position.x > parent->position.x)
653
angle -= 0x40;
654
655
self->position.x += (angle << 9) + Zone->autoScrollSpeed;
656
self->rotation = (RSDK.Sin256(self->angle) >> 4) - 32;
657
self->angle = (self->angle + 1) & 0xFF;
658
659
if (self->scale.x < self->targetScale)
660
self->scale.x += 2;
661
else if (self->scale.x > self->targetScale)
662
self->scale.x -= 2;
663
664
self->scale.y = self->scale.x;
665
if (self->scale.x <= 0x200)
666
self->drawGroup = Zone->objectDrawGroup[0] - 1;
667
else
668
self->drawGroup = Zone->objectDrawGroup[1];
669
670
if (parent->state == HeavyGunner_StateHeli_EscapeMissile)
671
self->velocity.y = -0x8000;
672
else
673
self->velocity.y += ((parent->position.y + self->parentOffset - self->position.y) >> 8) - (self->velocity.y >> 4);
674
675
self->position.y += self->velocity.y;
676
if (--self->timer <= 0) {
677
self->timer = RSDK.Rand(120, 240);
678
679
self->parentOffset = RSDK.Rand(-0x200000, 0x600000);
680
switch (RSDK.Rand(0, 8)) {
681
case 0:
682
case 1:
683
case 2:
684
case 3:
685
case 4: self->targetScale = 0x200; break;
686
687
case 5:
688
case 6: self->targetScale = 0x180; break;
689
690
case 7: self->targetScale = 0x300; break;
691
692
default: break;
693
}
694
}
695
}
696
697
void HeavyGunner_StateEggRobo_FlyIn(void)
698
{
699
RSDK_THIS(HeavyGunner);
700
701
if (++self->timer == 120) {
702
self->position.x = self->parent->position.x - 0x1800000;
703
self->position.y = self->parent->position.y + 0x800000;
704
self->scale.x = 0x400;
705
self->scale.y = 0x400;
706
self->velocity.x = 0x6A000;
707
self->drawGroup = Zone->objectDrawGroup[1];
708
RSDK.PlaySfx(HeavyGunner->sfxFlyIn, false, 0xFF);
709
self->state = HeavyGunner_StateEggRobo_ThrowGun;
710
}
711
}
712
713
void HeavyGunner_StateEggRobo_ThrowGun(void)
714
{
715
RSDK_THIS(HeavyGunner);
716
717
RSDK.ProcessAnimation(&self->mainAnimator);
718
RSDK.ProcessAnimation(&self->feetAnimator);
719
RSDK.ProcessAnimation(&self->armAnimator);
720
721
self->velocity.x -= 0x1000;
722
self->position.x += self->velocity.x + Zone->autoScrollSpeed;
723
self->position.y += self->velocity.y + ((self->parent->position.y - self->position.y + 0x400000) >> 6);
724
725
self->rotation = (self->velocity.x - 0x40000) >> 13;
726
727
if (self->velocity.x < 0 && self->position.x < self->parent->position.x + 0x600000) {
728
self->drawGroup = Zone->objectDrawGroup[0] - 1;
729
RSDK.SetSpriteAnimation(HeavyGunner->aniFrames, 21, &self->armAnimator, true, 0);
730
self->state = HeavyGunner_StateEggRobo_ThrownGun;
731
732
EntityHeavyGunner *child = CREATE_ENTITY(HeavyGunner, INT_TO_VOID(HEAVYGUNNER_GUN), self->position.x + 0x80000, self->position.y - 0x80000);
733
child->velocity.x = -0x34000;
734
child->velocity.y = -0x80000;
735
child->parent = self->parent;
736
RSDK.PlaySfx(HeavyGunner->sfxThrow, false, 0xFF);
737
}
738
739
if (self->scale.x > 0x200) {
740
self->scale.x -= 4;
741
self->scale.y = self->scale.x;
742
}
743
}
744
745
void HeavyGunner_StateEggRobo_ThrownGun(void)
746
{
747
RSDK_THIS(HeavyGunner);
748
749
RSDK.ProcessAnimation(&self->mainAnimator);
750
RSDK.ProcessAnimation(&self->feetAnimator);
751
RSDK.ProcessAnimation(&self->armAnimator);
752
753
self->position.x += Zone->autoScrollSpeed;
754
self->velocity.y += ((self->parent->position.y - self->position.y + 0x400000) >> 8) - (self->velocity.y >> 4);
755
self->position.y += self->velocity.y;
756
757
if (self->armAnimator.frameID >= self->armAnimator.frameCount - 1) {
758
RSDK.SetSpriteAnimation(HeavyGunner->aniFrames, 18, &self->armAnimator, true, 0);
759
self->timer = 0;
760
self->state = HeavyGunner_StateEggRobo_Patrolling;
761
}
762
}
763
764
void HeavyGunner_StateGun_Thrown(void)
765
{
766
RSDK_THIS(HeavyGunner);
767
768
EntityHeavyGunner *parent = self->parent;
769
770
self->velocity.y += 0x4000;
771
self->rotation = (self->rotation - 16) & 0x1FF;
772
self->position.x += self->velocity.x + Zone->autoScrollSpeed;
773
self->position.y += self->velocity.y;
774
775
if (self->position.x < parent->position.x - 0x180000)
776
self->velocity.x = 0;
777
778
if (self->velocity.y > 0 && self->position.y > parent->position.y - 0x200000) {
779
RSDK.SetSpriteAnimation(HeavyGunner->aniFrames, 1, &parent->gunnerAnimator, true, 0);
780
RSDK.PlaySfx(Player->sfxGrab, false, 255);
781
self->drawGroup = Zone->hudDrawGroup;
782
self->state = HeavyGunner_StateGun_Grabbed;
783
self->timer = 0x200;
784
self->stateDraw = HeavyGunner_Draw_FadeOut;
785
}
786
}
787
788
void HeavyGunner_StateGun_Grabbed(void)
789
{
790
RSDK_THIS(HeavyGunner);
791
792
self->timer -= 64;
793
if (!self->timer)
794
destroyEntity(self);
795
}
796
797
void HeavyGunner_StateMissile_Launched(void)
798
{
799
RSDK_THIS(HeavyGunner);
800
801
RSDK.ProcessAnimation(&self->mainAnimator);
802
803
self->velocity.x -= 0x1800;
804
self->velocity.y += 0x3800;
805
806
self->position.x += self->velocity.x + Zone->autoScrollSpeed;
807
self->position.y += self->velocity.y;
808
809
self->scale.x += ((0x200 - self->scale.x) >> 3);
810
self->scale.y = self->scale.x;
811
812
if (self->rotation < 0)
813
self->rotation++;
814
815
if (++self->timer == 32) {
816
self->scale.x = 0x200;
817
self->timer = self->missileID + 48;
818
self->scale.y = 0x200;
819
RSDK.SetSpriteAnimation(HeavyGunner->aniFrames, 26, &self->exhaustAnimator, true, 0);
820
self->state = HeavyGunner_StateMissile_BlastOff;
821
RSDK.PlaySfx(HeavyGunner->sfxJet, false, 255);
822
}
823
}
824
825
void HeavyGunner_StateMissile_BlastOff(void)
826
{
827
RSDK_THIS(HeavyGunner);
828
829
RSDK.ProcessAnimation(&self->mainAnimator);
830
RSDK.ProcessAnimation(&self->exhaustAnimator);
831
832
if (self->velocity.x < 0x80000)
833
self->velocity.x += 0x3800;
834
835
self->position.x += self->velocity.x + Zone->autoScrollSpeed;
836
837
if (self->exhaustAnimator.animationID == 26 && self->exhaustAnimator.frameID == self->exhaustAnimator.frameCount - 1)
838
RSDK.SetSpriteAnimation(HeavyGunner->aniFrames, 25, &self->exhaustAnimator, true, 0);
839
840
if (!(Zone->timer & 3)) {
841
EntityExplosion *explosion = CREATE_ENTITY(Explosion, INT_TO_VOID(EXPLOSION_BOSSPUFF), self->position.x - 0x180000, self->position.y);
842
explosion->drawGroup = Zone->objectDrawGroup[0] - 1;
843
explosion->drawFX = FX_ROTATE;
844
explosion->rotation = 128;
845
}
846
847
if (--self->timer <= 0) {
848
self->timer = 0;
849
self->state = HeavyGunner_StateMissile_FindFloor;
850
}
851
}
852
853
void HeavyGunner_StateMissile_FindFloor(void)
854
{
855
RSDK_THIS(HeavyGunner);
856
857
self->position.x += Zone->autoScrollSpeed;
858
self->position.y += 0x20000;
859
860
if (RSDK.ObjectTileCollision(self, Zone->collisionLayers, CMODE_FLOOR, 0, 0, 0x100000, true)) {
861
self->direction = FLIP_X;
862
self->velocity.x = self->type == HEAVYGUNNER_MISSILE ? -0x10000 : -0x20000;
863
self->state = HeavyGunner_StateMissile_AttackPlayer;
864
}
865
}
866
867
void HeavyGunner_StateMissile_AttackPlayer(void)
868
{
869
RSDK_THIS(HeavyGunner);
870
871
RSDK.ProcessAnimation(&self->mainAnimator);
872
RSDK.ProcessAnimation(&self->exhaustAnimator);
873
874
self->position.x += self->velocity.x + Zone->autoScrollSpeed;
875
RSDK.ObjectTileGrip(self, Zone->collisionLayers, CMODE_FLOOR, 0, 0, 0x100000, 64);
876
877
Hitbox *hitbox = self->type == HEAVYGUNNER_MISSILE ? &HeavyGunner->hitboxMissile : &HeavyGunner->hitboxMissileF;
878
879
foreach_active(Player, player)
880
{
881
if (Player_CheckBadnikTouch(player, self, hitbox)) {
882
if (Player_CheckAttacking(player, self) && self->type == HEAVYGUNNER_MISSILE) {
883
if (player->onGround) {
884
player->groundVel = Zone->autoScrollSpeed - 0x20000;
885
}
886
#if MANIA_USE_PLUS
887
else if (player->state != Player_State_MightyHammerDrop) {
888
#endif
889
player->velocity.y = -player->velocity.y;
890
if (player->velocity.y > -0x40000)
891
player->velocity.y = -0x40000;
892
#if MANIA_USE_PLUS
893
}
894
#endif
895
self->velocity.x = -0x10000;
896
RSDK.SetSpriteAnimation(-1, 0, &self->exhaustAnimator, true, 0);
897
self->direction = FLIP_NONE;
898
self->rotation = 256;
899
self->state = HeavyGunner_StateMissile_Malfunction;
900
901
RSDK.PlaySfx(HeavyGunner->sfxHit, false, 255);
902
RSDK.PlaySfx(HeavyGunner->sfxFlip, false, 255);
903
}
904
else {
905
Player_Hurt(player, self);
906
RSDK.PlaySfx(HeavyGunner->sfxExplosion3, false, 255);
907
908
int32 x = RSDK.Cos512(self->rotation) << 11;
909
int32 y = RSDK.Sin512(self->rotation) << 11;
910
EntityDebris *debris = CREATE_ENTITY(Debris, Debris_State_Move, self->position.x + x, self->position.y + y);
911
912
RSDK.SetSpriteAnimation(Explosion->aniFrames, EXPLOSION_BOSS, &debris->animator, true, 0);
913
debris->velocity.x = self->velocity.x + Zone->autoScrollSpeed;
914
debris->drawGroup = Zone->objectDrawGroup[0];
915
debris->timer = 41;
916
destroyEntity(self);
917
}
918
}
919
}
920
}
921
922
void HeavyGunner_StateMissile_Malfunction(void)
923
{
924
RSDK_THIS(HeavyGunner);
925
926
RSDK.ProcessAnimation(&self->mainAnimator);
927
928
self->position.x += self->velocity.x + Zone->autoScrollSpeed + (RSDK.Cos512(self->rotation) << 8);
929
self->position.y += (RSDK.Sin512(self->rotation) - 0x200) << 8;
930
931
self->rotation += 0x20;
932
933
if (!(Zone->timer & 3)) {
934
int32 x = RSDK.Cos512(self->rotation) << 11;
935
int32 y = RSDK.Sin512(self->rotation) << 11;
936
CREATE_ENTITY(Explosion, INT_TO_VOID(EXPLOSION_BOSSPUFF), self->position.x - x, self->position.y - y);
937
}
938
939
if (self->rotation == 0x400) {
940
EntityHeavyGunner *parent = self->parent;
941
if (parent->gunnerAnimator.animationID == 3) {
942
EntityDebris *debris = CREATE_ENTITY(Debris, Debris_State_Move, self->position.x, self->position.y);
943
RSDK.SetSpriteAnimation(Explosion->aniFrames, 2, &debris->animator, true, 0);
944
debris->velocity.x = Zone->autoScrollSpeed;
945
debris->drawGroup = Zone->objectDrawGroup[1];
946
debris->drawFX = FX_SCALE;
947
debris->scale.x = 0x300;
948
debris->scale.y = 0x300;
949
debris->timer = 52;
950
--parent->missileID;
951
destroyEntity(self);
952
RSDK.PlaySfx(HeavyGunner->sfxExplosion3, false, 255);
953
}
954
else {
955
self->state = HeavyGunner_StateMissile_ReturnToSender;
956
self->rotation = 0;
957
self->velocity.x = 0;
958
RSDK.SetSpriteAnimation(HeavyGunner->aniFrames, 3, &parent->gunnerAnimator, true, 0);
959
RSDK.PlaySfx(HeavyGunner->sfxJet, false, 255);
960
}
961
}
962
}
963
964
void HeavyGunner_StateMissile_ReturnToSender(void)
965
{
966
RSDK_THIS(HeavyGunner);
967
EntityHeavyGunner *parent = self->parent;
968
969
RSDK.ProcessAnimation(&self->mainAnimator);
970
971
self->position.x += self->velocity.x + Zone->autoScrollSpeed;
972
self->position.y += self->velocity.y;
973
974
self->velocity.y += ((parent->position.y - self->position.y) >> 8) - (self->velocity.y >> 4);
975
976
self->velocity.x = CLAMP(self->velocity.x, -0x20000, 0x70000);
977
978
if (self->rotation <= -0x100 || self->direction) {
979
self->rotation = 0;
980
self->direction = FLIP_X;
981
self->velocity.x -= RSDK.Cos512(self->rotation) << 6;
982
983
int32 x = 0, y = 0;
984
EntityDebris *debris = NULL;
985
switch (Zone->timer & 3) {
986
default: break;
987
988
case 0:
989
x = RSDK.Cos512(self->rotation) << 11;
990
y = RSDK.Sin512(self->rotation) << 11;
991
debris = CREATE_ENTITY(Debris, Debris_State_Move, self->position.x + x, self->position.y + y);
992
993
RSDK.SetSpriteAnimation(Explosion->aniFrames, EXPLOSION_BOSSPUFF, &debris->animator, true, 0);
994
debris->velocity.x = (RSDK.Cos512(self->rotation) << 8) + Zone->autoScrollSpeed;
995
debris->velocity.y = 16 * RSDK.Cos512(self->rotation);
996
debris->drawGroup = Zone->objectDrawGroup[0];
997
debris->timer = 41;
998
break;
999
1000
case 2:
1001
x = 0x600 * RSDK.Cos512(self->rotation);
1002
y = 0x600 * RSDK.Sin512(self->rotation);
1003
debris = CREATE_ENTITY(Debris, Debris_State_Move, self->position.x - x, self->position.y - y);
1004
1005
RSDK.SetSpriteAnimation(Explosion->aniFrames, 2, &debris->animator, true, 0);
1006
debris->velocity.x = Zone->autoScrollSpeed;
1007
debris->drawGroup = Zone->objectDrawGroup[1];
1008
debris->drawFX = FX_SCALE;
1009
debris->scale.x = RSDK.Rand(0x80, 0x180);
1010
debris->scale.y = debris->scale.x;
1011
debris->timer = 52;
1012
break;
1013
}
1014
1015
if (self->position.x - parent->position.x < TO_FIXED(160)) {
1016
if (parent->nextRoboID >= 3) {
1017
parent->velocity.y = 0;
1018
parent->timer = 0;
1019
parent->state = HeavyGunner_StateHeli_IncomingMissile;
1020
self->state = HeavyGunner_StateMissile_AttackGunner;
1021
}
1022
else {
1023
parent->nextRoboID++;
1024
self->parent = RSDK_GET_ENTITY(RSDK.GetEntitySlot(parent) - parent->nextRoboID, HeavyGunner);
1025
parent->state = HeavyGunner_StateHeli_EscapeMissile;
1026
self->state = HeavyGunner_StateMissile_AttackRobo;
1027
RSDK.PlaySfx(HeavyGunner->sfxWooshOut, false, 255);
1028
}
1029
1030
self->groundVel = 0x100;
1031
}
1032
}
1033
else {
1034
self->rotation -= 4;
1035
self->velocity.x += RSDK.Cos512(self->rotation) << 6;
1036
1037
int32 x = 0, y = 0;
1038
EntityDebris *debris = NULL;
1039
switch (Zone->timer & 3) {
1040
default: break;
1041
1042
case 0:
1043
x = RSDK.Cos512(self->rotation) << 11;
1044
y = RSDK.Sin512(self->rotation) << 11;
1045
debris = CREATE_ENTITY(Debris, Debris_State_Move, self->position.x - x, self->position.y - y);
1046
1047
RSDK.SetSpriteAnimation(Explosion->aniFrames, EXPLOSION_BOSSPUFF, &debris->animator, true, 0);
1048
debris->velocity.x = Zone->autoScrollSpeed - (RSDK.Cos512(self->rotation) << 8);
1049
debris->velocity.y = -16 * RSDK.Cos512(self->rotation);
1050
debris->drawGroup = Zone->objectDrawGroup[0];
1051
debris->timer = 41;
1052
break;
1053
1054
case 2:
1055
x = 0x600 * RSDK.Cos512(self->rotation);
1056
y = 0x600 * RSDK.Sin512(self->rotation);
1057
debris = CREATE_ENTITY(Debris, Debris_State_Move, self->position.x - x, self->position.y - y);
1058
1059
RSDK.SetSpriteAnimation(Explosion->aniFrames, EXPLOSION_BOSS, &debris->animator, true, 0);
1060
debris->velocity.x = Zone->autoScrollSpeed;
1061
debris->drawGroup = Zone->objectDrawGroup[1];
1062
debris->drawFX = FX_SCALE;
1063
debris->scale.x = RSDK.Rand(0x80, 0x180);
1064
debris->scale.y = debris->scale.x;
1065
debris->timer = 52;
1066
break;
1067
}
1068
}
1069
}
1070
1071
void HeavyGunner_StateMissile_AttackRobo(void)
1072
{
1073
RSDK_THIS(HeavyGunner);
1074
1075
EntityHeavyGunner *parent = self->parent;
1076
1077
RSDK.ProcessAnimation(&self->mainAnimator);
1078
1079
int32 angle = RSDK.ATan2(self->position.x - parent->position.x, self->position.y - parent->position.y);
1080
self->groundVel += 16;
1081
self->rotation = 2 * angle;
1082
1083
self->velocity.x = self->groundVel * RSDK.Cos512(self->rotation);
1084
self->velocity.y = self->groundVel * RSDK.Sin512(self->rotation);
1085
self->position.x += Zone->autoScrollSpeed - self->velocity.x;
1086
self->position.y -= self->velocity.y;
1087
1088
if (self->scale.x >= parent->scale.x) {
1089
if (self->scale.x > parent->scale.x)
1090
self->scale.x -= 2;
1091
}
1092
else {
1093
self->scale.x += 2;
1094
}
1095
1096
self->scale.y = self->scale.x;
1097
self->drawGroup = parent->drawGroup;
1098
if (Zone->timer & 3) {
1099
if ((Zone->timer & 3) == 2) {
1100
int32 x = 0x600 * RSDK.Cos512(self->rotation);
1101
int32 y = 0x600 * RSDK.Sin512(self->rotation);
1102
EntityDebris *debris = CREATE_ENTITY(Debris, Debris_State_Move, self->position.x - x, self->position.y - y);
1103
RSDK.SetSpriteAnimation(Explosion->aniFrames, 2, &debris->animator, true, 0);
1104
debris->velocity.x = Zone->autoScrollSpeed;
1105
debris->drawGroup = Zone->objectDrawGroup[1];
1106
debris->drawFX = FX_SCALE;
1107
debris->scale.x = RSDK.Rand(0x80, 0x180);
1108
debris->scale.y = debris->scale.x;
1109
debris->timer = 52;
1110
}
1111
}
1112
else {
1113
int32 x = RSDK.Cos512(self->rotation) << 11;
1114
int32 y = RSDK.Sin512(self->rotation) << 11;
1115
EntityDebris *debris = CREATE_ENTITY(Debris, Debris_State_Move, x + self->position.x, y + self->position.y);
1116
RSDK.SetSpriteAnimation(Explosion->aniFrames, EXPLOSION_BOSSPUFF, &debris->animator, true, 0);
1117
debris->velocity.x = (RSDK.Cos512(self->rotation) << 8) + Zone->autoScrollSpeed;
1118
debris->velocity.y = 16 * RSDK.Cos512(self->rotation);
1119
debris->drawGroup = Zone->objectDrawGroup[0];
1120
debris->timer = 41;
1121
}
1122
1123
int32 rx = (self->position.x - parent->position.x) >> 16;
1124
int32 ry = (self->position.y - parent->position.y) >> 16;
1125
if (rx * rx + ry * ry < 0x100) {
1126
for (int32 i = 0; i < 12; ++i) {
1127
int32 x = self->position.x + RSDK.Rand(-0xC0000, 0xC0000);
1128
int32 y = self->position.y + RSDK.Rand(-0xC0000, 0xC0000);
1129
EntityDebris *debris = CREATE_ENTITY(Debris, Debris_State_Fall, x, y);
1130
RSDK.SetSpriteAnimation(HeavyGunner->aniFrames, 28, &debris->animator, true, i >> 1);
1131
debris->velocity.x = Zone->autoScrollSpeed + RSDK.Rand(-0x20000, 0x20000);
1132
debris->velocity.y = RSDK.Rand(-0x20000, 0x20000) - 0x40000;
1133
debris->gravityStrength = 0x3800;
1134
debris->scale = parent->scale;
1135
debris->rotSpeed = RSDK.Rand(-24, 24);
1136
debris->drawGroup = Zone->objectDrawGroup[0];
1137
if (i >> 1 < 3)
1138
debris->drawFX = FX_SCALE | FX_ROTATE;
1139
}
1140
1141
EntityDebris *debris = CREATE_ENTITY(Debris, Debris_State_Move, parent->position.x, parent->position.y);
1142
RSDK.SetSpriteAnimation(Explosion->aniFrames, EXPLOSION_ENEMY, &debris->animator, true, 0);
1143
debris->velocity.x = Zone->autoScrollSpeed;
1144
debris->drawGroup = Zone->objectDrawGroup[1];
1145
debris->timer = 32;
1146
HeavyGunner->stageWrapActive = false;
1147
1148
int32 plane = RSDK.Rand(0, 2);
1149
foreach_active(Player, player) { player->collisionPlane = plane; }
1150
1151
--parent->parent->missileID;
1152
destroyEntity(self);
1153
destroyEntity(parent);
1154
RSDK.PlaySfx(HeavyGunner->sfxDestroy, false, 255);
1155
RSDK.PlaySfx(HeavyGunner->sfxExplosion3, false, 255);
1156
HeavyGunner_DestroyAllMissiles();
1157
}
1158
}
1159
1160
void HeavyGunner_StateMissile_AttackGunner(void)
1161
{
1162
RSDK_THIS(HeavyGunner);
1163
EntityHeavyGunner *parent = self->parent;
1164
1165
RSDK.ProcessAnimation(&self->mainAnimator);
1166
1167
int32 angle = RSDK.ATan2(self->position.x - parent->position.x, self->position.y - parent->position.y);
1168
self->groundVel += 16;
1169
self->rotation = 2 * angle;
1170
1171
self->velocity.x = self->groundVel * RSDK.Cos512(self->rotation);
1172
self->velocity.y = self->groundVel * RSDK.Sin512(self->rotation);
1173
self->position.x += Zone->autoScrollSpeed - self->velocity.x;
1174
self->position.y -= self->velocity.y;
1175
1176
if (Zone->timer & 3) {
1177
if ((Zone->timer & 3) == 2) {
1178
int32 x = 0x600 * RSDK.Cos512(self->rotation);
1179
int32 y = 0x600 * RSDK.Sin512(self->rotation);
1180
EntityDebris *debris = CREATE_ENTITY(Debris, Debris_State_Move, self->position.x - x, self->position.y - y);
1181
RSDK.SetSpriteAnimation(Explosion->aniFrames, 2, &debris->animator, true, 0);
1182
debris->velocity.x = Zone->autoScrollSpeed;
1183
debris->drawGroup = Zone->objectDrawGroup[1];
1184
debris->drawFX = FX_SCALE;
1185
debris->scale.x = RSDK.Rand(0x80, 0x180);
1186
debris->scale.y = debris->scale.x;
1187
debris->timer = 52;
1188
}
1189
}
1190
else {
1191
int32 x = RSDK.Cos512(self->rotation) << 11;
1192
int32 y = RSDK.Sin512(self->rotation) << 11;
1193
EntityDebris *debris = CREATE_ENTITY(Debris, Debris_State_Move, x + self->position.x, y + self->position.y);
1194
RSDK.SetSpriteAnimation(Explosion->aniFrames, EXPLOSION_BOSSPUFF, &debris->animator, true, 0);
1195
debris->velocity.x = (RSDK.Cos512(self->rotation) << 8) + Zone->autoScrollSpeed;
1196
debris->velocity.y = 16 * RSDK.Cos512(self->rotation);
1197
debris->drawGroup = Zone->objectDrawGroup[0];
1198
debris->timer = 41;
1199
}
1200
1201
int32 rx = (self->position.x - parent->position.x) >> 16;
1202
int32 ry = (self->position.y - parent->position.y) >> 16;
1203
if (rx * rx + ry * ry < 0x300) {
1204
for (int32 i = 0; i < 12; ++i) {
1205
int32 x = self->position.x + RSDK.Rand(0x60000, 0x180000);
1206
int32 y = self->position.y + RSDK.Rand(-0xC0000, 0xC0000);
1207
EntityDebris *debris = CREATE_ENTITY(Debris, Debris_State_Fall, x, y);
1208
RSDK.SetSpriteAnimation(HeavyGunner->aniFrames, 28, &debris->animator, true, i >> 1);
1209
debris->velocity.x = Zone->autoScrollSpeed + RSDK.Rand(-0x20000, 0x20000);
1210
debris->velocity.y = RSDK.Rand(-0x20000, 0x20000) - 0x40000;
1211
debris->gravityStrength = 0x3800;
1212
debris->rotSpeed = RSDK.Rand(-24, 24);
1213
debris->drawGroup = Zone->objectDrawGroup[1];
1214
if (i >> 1 < 3)
1215
debris->drawFX = FX_ROTATE;
1216
}
1217
1218
EntityDebris *debris = CREATE_ENTITY(Debris, Debris_State_Fall, self->position.x, self->position.y - 0x200000);
1219
RSDK.SetSpriteAnimation(HeavyGunner->aniFrames, 13, &debris->animator, true, 0);
1220
debris->velocity.x = Zone->autoScrollSpeed + RSDK.Rand(-0x20000, 0x20000);
1221
debris->velocity.y = RSDK.Rand(-0x20000, 0x20000) - 0x40000;
1222
debris->gravityStrength = 0x3800;
1223
debris->drawGroup = Zone->objectDrawGroup[1];
1224
1225
debris = CREATE_ENTITY(Debris, Debris_State_Move, self->position.x + 0x60000, self->position.y - 0x40000);
1226
RSDK.SetSpriteAnimation(Explosion->aniFrames, EXPLOSION_BOSS, &debris->animator, true, 0);
1227
debris->velocity.x = Zone->autoScrollSpeed;
1228
debris->drawGroup = Zone->objectDrawGroup[1];
1229
debris->drawFX = FX_SCALE;
1230
debris->scale.x = 768;
1231
debris->scale.y = 768;
1232
debris->timer = 52;
1233
1234
destroyEntity(self);
1235
RSDK.SetSpriteAnimation(HeavyGunner->aniFrames, 12, &parent->mainAnimator, true, 0);
1236
RSDK.SetSpriteAnimation(HeavyGunner->aniFrames, 12, &parent->frontAnimator, true, 1);
1237
RSDK.SetSpriteAnimation(HeavyGunner->aniFrames, 12, &parent->tBladeAnimator, true, 2);
1238
RSDK.SetSpriteAnimation(HeavyGunner->aniFrames, 12, &parent->beaconAnimator, true, 3);
1239
RSDK.SetSpriteAnimation(-1, 0, &parent->pilotAnimator, true, 0);
1240
1241
--parent->missileID;
1242
parent->state = HeavyGunner_StateHeli_Exploding;
1243
SceneInfo->timeEnabled = false;
1244
Player_GiveScore(RSDK_GET_ENTITY(SLOT_PLAYER1, Player), 1000);
1245
RSDK.PlaySfx(HeavyGunner->sfxExplosion3, false, 255);
1246
self->defeated = true; // ? self was destroyed, this wont do a thing right??
1247
HeavyGunner_DestroyAllMissiles();
1248
}
1249
}
1250
1251
void HeavyGunner_StateHeli_AwaitPlayer(void)
1252
{
1253
RSDK_THIS(HeavyGunner);
1254
1255
if (RSDK_GET_ENTITY(SLOT_PLAYER1, Player)->position.x > self->position.x) {
1256
self->velocity.x = 0x40000;
1257
self->velocity.y = 0;
1258
self->drawFX = FX_ROTATE;
1259
self->state = HeavyGunner_StateHeli_WooshIn;
1260
1261
Camera_ShakeScreen(0, 12, 12);
1262
RSDK.PlaySfx(HeavyGunner->sfxRumble, false, 255);
1263
RSDK.PlaySfx(HeavyGunner->sfxWooshIn, false, 255);
1264
Zone->deathBoundary[0] += 0x8000000;
1265
}
1266
}
1267
1268
void HeavyGunner_StateHeli_WooshIn(void)
1269
{
1270
RSDK_THIS(HeavyGunner);
1271
1272
RSDK.ProcessAnimation(&self->mainAnimator);
1273
RSDK.ProcessAnimation(&self->pilotAnimator);
1274
RSDK.ProcessAnimation(&self->frontAnimator);
1275
RSDK.ProcessAnimation(&self->tBladeAnimator);
1276
RSDK.ProcessAnimation(&self->rBladeAnimator);
1277
RSDK.ProcessAnimation(&self->beaconAnimator);
1278
RSDK.ProcessAnimation(&self->feetAnimator);
1279
RSDK.ProcessAnimation(&self->feet2Animator);
1280
RSDK.ProcessAnimation(&self->gunnerAnimator);
1281
1282
self->position.x += self->velocity.x;
1283
self->position.x += Zone->autoScrollSpeed;
1284
self->position.y += 0x10000;
1285
1286
self->rotation = (self->velocity.x + 0x40000) >> 13;
1287
if (self->rotation < 0)
1288
self->rotation = 0;
1289
1290
RSDK.ObjectTileCollision(self, Zone->collisionLayers, CMODE_FLOOR, 0, 0, 0x800000, true);
1291
if (self->position.x > Zone->playerBoundsL[0] + ((ScreenInfo->center.x - 16) << 16))
1292
self->state = HeavyGunner_StateHeli_FindFloor;
1293
}
1294
1295
void HeavyGunner_StateHeli_FindFloor(void)
1296
{
1297
RSDK_THIS(HeavyGunner);
1298
1299
RSDK.ProcessAnimation(&self->mainAnimator);
1300
RSDK.ProcessAnimation(&self->pilotAnimator);
1301
RSDK.ProcessAnimation(&self->frontAnimator);
1302
RSDK.ProcessAnimation(&self->tBladeAnimator);
1303
RSDK.ProcessAnimation(&self->rBladeAnimator);
1304
RSDK.ProcessAnimation(&self->beaconAnimator);
1305
RSDK.ProcessAnimation(&self->feetAnimator);
1306
RSDK.ProcessAnimation(&self->feet2Animator);
1307
RSDK.ProcessAnimation(&self->gunnerAnimator);
1308
1309
self->velocity.x -= 0x1000;
1310
self->position.x += self->velocity.x;
1311
self->position.x += Zone->autoScrollSpeed;
1312
self->position.y += 0x10000;
1313
1314
self->rotation = (self->velocity.x + 0x40000) >> 13;
1315
if (self->rotation < 0)
1316
self->rotation = 0;
1317
1318
bool32 collided = RSDK.ObjectTileCollision(self, Zone->collisionLayers, CMODE_FLOOR, 0, 0, 0x800000, true);
1319
if (self->velocity.x < 0 && collided && self->position.x < Zone->playerBoundsL[0] + ((ScreenInfo->center.x - 16) << 16)) {
1320
self->velocity.x = 0;
1321
self->drawFX = FX_NONE;
1322
if (self->nextRoboID > 0)
1323
self->timer = 240;
1324
1325
self->state = HeavyGunner_StateHeli_HandleAttacks;
1326
}
1327
}
1328
1329
void HeavyGunner_StateHeli_HandleAttacks(void)
1330
{
1331
RSDK_THIS(HeavyGunner);
1332
1333
RSDK.ProcessAnimation(&self->mainAnimator);
1334
RSDK.ProcessAnimation(&self->pilotAnimator);
1335
RSDK.ProcessAnimation(&self->frontAnimator);
1336
RSDK.ProcessAnimation(&self->tBladeAnimator);
1337
RSDK.ProcessAnimation(&self->rBladeAnimator);
1338
RSDK.ProcessAnimation(&self->beaconAnimator);
1339
RSDK.ProcessAnimation(&self->feetAnimator);
1340
RSDK.ProcessAnimation(&self->feet2Animator);
1341
RSDK.ProcessAnimation(&self->gunnerAnimator);
1342
1343
self->position.x += Zone->autoScrollSpeed;
1344
RSDK.ObjectTileGrip(self, Zone->collisionLayers, CMODE_FLOOR, 0, 0, 0x800000, 64);
1345
1346
self->position.y += RSDK.Sin256(self->angle) << 11;
1347
self->angle = (self->angle + 3) & 0xFF;
1348
1349
if (self->gunnerAnimator.animationID == 3)
1350
self->timer = 0;
1351
1352
if (++self->timer == 320) {
1353
RSDK.SetSpriteAnimation(HeavyGunner->aniFrames, 2, &self->gunnerAnimator, true, 0);
1354
RSDK.PlaySfx(HeavyGunner->sfxCharge, false, 255);
1355
}
1356
1357
if (self->timer == 380) {
1358
RSDK.SetSpriteAnimation(HeavyGunner->aniFrames, 1, &self->gunnerAnimator, true, 0);
1359
self->timer = 0;
1360
self->state = HeavyGunner_StateHeli_ShotsFired;
1361
self->drawFX = FX_ROTATE;
1362
self->velocity.x = -0x30000;
1363
1364
int32 dudID = RSDK.Rand(0, 3);
1365
1366
EntityHeavyGunner *child =
1367
CREATE_ENTITY(HeavyGunner, INT_TO_VOID((dudID == 0) + HEAVYGUNNER_MISSILE_F), self->position.x - 0x200000, self->position.y - 0x100000);
1368
child->velocity.y -= 0x10000;
1369
child->parent = self;
1370
child->missileID = 0;
1371
++self->missileID;
1372
1373
child =
1374
CREATE_ENTITY(HeavyGunner, INT_TO_VOID((dudID == 1) + HEAVYGUNNER_MISSILE_F), self->position.x - 0x200000, self->position.y - 0x100000);
1375
child->parent = self;
1376
child->missileID = 15 * ((dudID != 1) + 1);
1377
++self->missileID;
1378
1379
child =
1380
CREATE_ENTITY(HeavyGunner, INT_TO_VOID((dudID == 2) + HEAVYGUNNER_MISSILE_F), self->position.x - 0x200000, self->position.y - 0x100000);
1381
child->velocity.y += 0x10000;
1382
child->parent = self;
1383
child->missileID = 30 * ((dudID != 2) + 1);
1384
++self->missileID;
1385
1386
EntityDebris *debris = CREATE_ENTITY(Debris, Debris_State_Move, self->position.x - 0x200000, self->position.y - 0x140000);
1387
RSDK.SetSpriteAnimation(HeavyGunner->aniFrames, 27, &debris->animator, true, 0);
1388
debris->timer = 22;
1389
debris->drawGroup = Zone->objectDrawGroup[1];
1390
debris->velocity.x = Zone->autoScrollSpeed;
1391
RSDK.PlaySfx(HeavyGunner->sfxFire, false, 255);
1392
}
1393
}
1394
1395
void HeavyGunner_StateHeli_ShotsFired(void)
1396
{
1397
RSDK_THIS(HeavyGunner);
1398
1399
RSDK.ProcessAnimation(&self->mainAnimator);
1400
RSDK.ProcessAnimation(&self->pilotAnimator);
1401
RSDK.ProcessAnimation(&self->frontAnimator);
1402
RSDK.ProcessAnimation(&self->tBladeAnimator);
1403
RSDK.ProcessAnimation(&self->rBladeAnimator);
1404
RSDK.ProcessAnimation(&self->beaconAnimator);
1405
RSDK.ProcessAnimation(&self->feetAnimator);
1406
RSDK.ProcessAnimation(&self->feet2Animator);
1407
RSDK.ProcessAnimation(&self->gunnerAnimator);
1408
1409
self->velocity.x += 0x1800;
1410
self->position.x += self->velocity.x + Zone->autoScrollSpeed;
1411
self->rotation = self->velocity.x >> 14;
1412
1413
RSDK.ObjectTileGrip(self, Zone->collisionLayers, CMODE_FLOOR, 0, 0, 0x800000, 64);
1414
1415
self->position.y += RSDK.Sin256(self->angle) << 11;
1416
self->angle = (self->angle + 3) & 0xFF;
1417
1418
if (self->rotation > 0)
1419
self->rotation = 0;
1420
1421
if (self->position.x > Zone->playerBoundsL[0] + ((ScreenInfo->center.x - 16) << 16)) {
1422
self->velocity.x = 0;
1423
self->drawFX = FX_NONE;
1424
self->state = HeavyGunner_StateHeli_HandleAttacks;
1425
}
1426
}
1427
1428
void HeavyGunner_StateHeli_EscapeMissile(void)
1429
{
1430
RSDK_THIS(HeavyGunner);
1431
1432
RSDK.ProcessAnimation(&self->mainAnimator);
1433
RSDK.ProcessAnimation(&self->pilotAnimator);
1434
RSDK.ProcessAnimation(&self->frontAnimator);
1435
RSDK.ProcessAnimation(&self->tBladeAnimator);
1436
RSDK.ProcessAnimation(&self->rBladeAnimator);
1437
RSDK.ProcessAnimation(&self->beaconAnimator);
1438
RSDK.ProcessAnimation(&self->feetAnimator);
1439
RSDK.ProcessAnimation(&self->feet2Animator);
1440
RSDK.ProcessAnimation(&self->gunnerAnimator);
1441
1442
self->position.x += self->velocity.x + Zone->autoScrollSpeed;
1443
self->position.y += self->velocity.y;
1444
self->velocity.y -= 0x4000;
1445
}
1446
1447
void HeavyGunner_StateHeli_IncomingMissile(void)
1448
{
1449
RSDK_THIS(HeavyGunner);
1450
1451
RSDK.ProcessAnimation(&self->mainAnimator);
1452
RSDK.ProcessAnimation(&self->pilotAnimator);
1453
RSDK.ProcessAnimation(&self->frontAnimator);
1454
RSDK.ProcessAnimation(&self->tBladeAnimator);
1455
RSDK.ProcessAnimation(&self->rBladeAnimator);
1456
RSDK.ProcessAnimation(&self->beaconAnimator);
1457
RSDK.ProcessAnimation(&self->feetAnimator);
1458
RSDK.ProcessAnimation(&self->feet2Animator);
1459
1460
self->position.x += self->velocity.x + Zone->autoScrollSpeed;
1461
self->velocity.x -= 0xE00;
1462
1463
if (self->velocity.y < 0x400)
1464
self->velocity.y += 16;
1465
1466
self->position.y += self->velocity.y * RSDK.Sin256(self->angle);
1467
self->angle = (self->angle + 6) & 0xFF;
1468
1469
if (!self->timer) {
1470
self->timer = 1;
1471
RSDK.SetSpriteAnimation(-1, 0, &self->gunnerAnimator, true, 0);
1472
CREATE_ENTITY(HeavyGunner, INT_TO_VOID(HEAVYGUNNER_ESCAPE_HBH), self->position.x - 0x80000, self->position.y - 0x20000);
1473
1474
EntityDebris *debris = CREATE_ENTITY(Debris, Debris_State_Fall, self->position.x - 0x300000, self->position.y - 0x240000);
1475
RSDK.SetSpriteAnimation(HeavyGunner->aniFrames, 20, &debris->animator, true, 0);
1476
debris->velocity.y = -0x20000;
1477
debris->velocity.x = Zone->autoScrollSpeed - 0x20000;
1478
debris->gravityStrength = 0x3800;
1479
debris->drawFX = FX_ROTATE;
1480
debris->rotSpeed = -16;
1481
debris->drawGroup = Zone->objectDrawGroup[1];
1482
}
1483
}
1484
1485
void HeavyGunner_StateHeli_Exploding(void)
1486
{
1487
RSDK_THIS(HeavyGunner);
1488
1489
RSDK.ProcessAnimation(&self->mainAnimator);
1490
RSDK.ProcessAnimation(&self->rBladeAnimator);
1491
RSDK.ProcessAnimation(&self->feetAnimator);
1492
RSDK.ProcessAnimation(&self->feet2Animator);
1493
1494
self->position.x += self->velocity.x + Zone->autoScrollSpeed;
1495
if (self->velocity.x < 0x8000)
1496
self->velocity.x += 0xE00;
1497
1498
self->position.y += self->velocity.y * RSDK.Sin256(self->angle);
1499
self->angle = (self->angle + 6) & 0xFF;
1500
1501
++self->timer;
1502
if ((self->timer & 7) == 2)
1503
RSDK.PlaySfx(HeavyGunner->sfxExplosion2, false, 255);
1504
1505
if (!(self->timer & 0x1F))
1506
RSDK.PlaySfx(HeavyGunner->sfxHit, false, 255);
1507
1508
if (!(self->timer & 3)) {
1509
int32 x = self->position.x + RSDK.Rand(-0x300000, 0x300000);
1510
int32 y = self->position.y + RSDK.Rand(-0x300000, 0x300000);
1511
1512
EntityExplosion *explosion = CREATE_ENTITY(Explosion, INT_TO_VOID(RSDK.Rand(EXPLOSION_BOSS, EXPLOSION_BOSSPUFF + 1)), x, y);
1513
explosion->drawGroup = Zone->objectDrawGroup[1];
1514
explosion->drawFX = FX_SCALE;
1515
explosion->scale.x = RSDK.Rand(0x100, 0x300);
1516
explosion->scale.y = explosion->scale.x;
1517
}
1518
1519
if (self->timer > 60) {
1520
self->timer = 0;
1521
1522
EntityDebris *debris = CREATE_ENTITY(Debris, Debris_State_Fall, self->position.x, self->position.y);
1523
RSDK.SetSpriteAnimation(HeavyGunner->aniFrames, 11, &debris->animator, true, self->feetAnimator.frameID);
1524
debris->velocity.y = -0x10000;
1525
debris->velocity.x = Zone->autoScrollSpeed - 0x10000;
1526
debris->gravityStrength = 0x3800;
1527
debris->drawGroup = Zone->objectDrawGroup[1];
1528
1529
debris = CREATE_ENTITY(Debris, Debris_State_Fall, self->position.x + 0x1B0000, self->position.y);
1530
RSDK.SetSpriteAnimation(HeavyGunner->aniFrames, 11, &debris->animator, true, self->feet2Animator.frameID);
1531
debris->velocity.y = -0x10000;
1532
debris->velocity.x = Zone->autoScrollSpeed + 0x10000;
1533
debris->gravityStrength = 0x3800;
1534
debris->drawGroup = Zone->objectDrawGroup[0] - 1;
1535
RSDK.SetSpriteAnimation(-1, 0, &self->feetAnimator, true, 0);
1536
RSDK.SetSpriteAnimation(-1, 0, &self->feet2Animator, true, 0);
1537
self->state = HeavyGunner_StateHeli_ExplodeAndFall;
1538
}
1539
}
1540
1541
void HeavyGunner_StateHeli_ExplodeAndFall(void)
1542
{
1543
RSDK_THIS(HeavyGunner);
1544
1545
RSDK.ProcessAnimation(&self->mainAnimator);
1546
RSDK.ProcessAnimation(&self->rBladeAnimator);
1547
1548
self->velocity.y += 0x3800;
1549
self->position.x += self->velocity.x + Zone->autoScrollSpeed;
1550
self->position.y += self->velocity.y;
1551
1552
if (RSDK.ObjectTileCollision(self, Zone->collisionLayers, CMODE_FLOOR, 0, 0, 0x200000, true))
1553
self->velocity.y = -(self->velocity.y >> 1);
1554
1555
self->timer++;
1556
if ((self->timer & 7) == 2)
1557
RSDK.PlaySfx(HeavyGunner->sfxExplosion2, false, 255);
1558
1559
if (!(self->timer & 0x1F))
1560
RSDK.PlaySfx(HeavyGunner->sfxHit, false, 255);
1561
1562
if (!(self->timer & 3)) {
1563
int32 x = self->position.x + RSDK.Rand(-0x300000, 0x300000);
1564
int32 y = self->position.y + RSDK.Rand(-0x300000, 0x300000);
1565
EntityExplosion *explosion = CREATE_ENTITY(Explosion, INT_TO_VOID(RSDK.Rand(EXPLOSION_BOSS, EXPLOSION_BOSSPUFF + 1)), x, y);
1566
1567
explosion->drawGroup = Zone->objectDrawGroup[1];
1568
explosion->drawFX = FX_SCALE;
1569
explosion->scale.x = RSDK.Rand(0x100, 0x200);
1570
explosion->scale.y = explosion->scale.x;
1571
}
1572
1573
if (self->timer > 200) {
1574
self->drawGroup = Zone->hudDrawGroup;
1575
self->state = HeavyGunner_StateHeli_FadeOutDestroy;
1576
self->timer = 768;
1577
self->stateDraw = HeavyGunner_Draw_FadeOut;
1578
1579
Music_TransitionTrack(TRACK_STAGE, 0.0125);
1580
RSDK.PlaySfx(HeavyGunner->sfxExplosion3, false, 255);
1581
1582
EntityCamera *camera = RSDK_GET_ENTITY(SLOT_CAMERA1, Camera);
1583
camera->position.x = 0x57C00000;
1584
if (camera->position.y <= 0x6600000) {
1585
camera->position.y = 0x2EC0000;
1586
if (camera->position.y > 0x3800000)
1587
camera->position.y = 0x5EC0000;
1588
}
1589
else {
1590
camera->position.y = 0x8EC0000;
1591
}
1592
1593
foreach_active(Player, player)
1594
{
1595
player->position.x = 0x57C00000;
1596
player->position.y = camera->position.y;
1597
}
1598
1599
foreach_all(SignPost, signPost)
1600
{
1601
signPost->position.y = camera->position.y;
1602
Zone->cameraBoundsL[0] = (signPost->position.x >> 16) - 512;
1603
RSDK.ObjectTileGrip(signPost, Zone->collisionLayers, CMODE_FLOOR, 0, 0, 0x180000, 0x40);
1604
}
1605
1606
Zone->autoScrollSpeed = 0;
1607
Zone->cameraBoundsR[0] = HeavyGunner->boundsR;
1608
Zone->playerBoundActiveR[0] = false;
1609
destroyEntitySlot(SceneInfo->entitySlot - 4);
1610
}
1611
}
1612
1613
void HeavyGunner_StateEscapeHBH_Hover(void)
1614
{
1615
RSDK_THIS(HeavyGunner);
1616
1617
RSDK.ProcessAnimation(&self->mainAnimator);
1618
1619
self->velocity.y += 0x3800;
1620
self->position.x += self->velocity.x + Zone->autoScrollSpeed;
1621
self->position.y += self->velocity.y;
1622
1623
if (++self->timer == 30) {
1624
self->timer = 0;
1625
RSDK.SetSpriteAnimation(HeavyGunner->aniFrames, 4, &self->mainAnimator, true, 0);
1626
self->state = HeavyGunner_StateEscapeHBH_FlyAway;
1627
RSDK.PlaySfx(HeavyGunner->sfxJet, false, 0xFF);
1628
}
1629
}
1630
1631
void HeavyGunner_StateEscapeHBH_FlyAway(void)
1632
{
1633
RSDK_THIS(HeavyGunner);
1634
1635
RSDK.ProcessAnimation(&self->mainAnimator);
1636
1637
self->velocity.y -= 0x6000;
1638
self->position.x += self->velocity.x + Zone->autoScrollSpeed;
1639
self->position.y += self->velocity.y;
1640
if (++self->timer == 60)
1641
destroyEntity(self);
1642
}
1643
1644
void HeavyGunner_StateHeli_FadeOutDestroy(void)
1645
{
1646
RSDK_THIS(HeavyGunner);
1647
1648
self->timer -= 8;
1649
if (!self->timer)
1650
destroyEntity(self);
1651
}
1652
1653
#if GAME_INCLUDE_EDITOR
1654
void HeavyGunner_EditorDraw(void)
1655
{
1656
RSDK_THIS(HeavyGunner);
1657
1658
RSDK.SetSpriteAnimation(HeavyGunner->aniFrames, 6, &self->mainAnimator, true, 0);
1659
RSDK.SetSpriteAnimation(HeavyGunner->aniFrames, 14, &self->pilotAnimator, true, 0);
1660
RSDK.SetSpriteAnimation(HeavyGunner->aniFrames, 7, &self->frontAnimator, true, 0);
1661
RSDK.SetSpriteAnimation(HeavyGunner->aniFrames, 8, &self->tBladeAnimator, true, 0);
1662
RSDK.SetSpriteAnimation(HeavyGunner->aniFrames, 9, &self->rBladeAnimator, true, 0);
1663
RSDK.SetSpriteAnimation(HeavyGunner->aniFrames, 10, &self->beaconAnimator, true, 0);
1664
RSDK.SetSpriteAnimation(HeavyGunner->aniFrames, 11, &self->feetAnimator, true, 0);
1665
RSDK.SetSpriteAnimation(HeavyGunner->aniFrames, 11, &self->feet2Animator, true, 2);
1666
RSDK.SetSpriteAnimation(HeavyGunner->aniFrames, 0, &self->gunnerAnimator, true, 0);
1667
self->drawFX = FX_ROTATE;
1668
self->rotation = 0x40;
1669
1670
HeavyGunner_Draw_Heli();
1671
1672
if (showGizmos()) {
1673
RSDK_DRAWING_OVERLAY(true);
1674
1675
for (int32 i = 0; i < 4; ++i) {
1676
EntityHeavyGunner *child = RSDK_GET_ENTITY(SceneInfo->entitySlot + 1 + i, HeavyGunner);
1677
1678
if (child)
1679
DrawHelpers_DrawArrow(self->position.x, self->position.y, child->position.x, child->position.y, 0xE0E0E0, INK_NONE, 0xFF);
1680
}
1681
1682
RSDK_DRAWING_OVERLAY(false);
1683
}
1684
}
1685
1686
void HeavyGunner_EditorLoad(void) { HeavyGunner->aniFrames = RSDK.LoadSpriteAnimation("SPZ1/Boss.bin", SCOPE_STAGE); }
1687
#endif
1688
1689
void HeavyGunner_Serialize(void) {}
1690
1691