Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rubberduckycooly
GitHub Repository: rubberduckycooly/Sonic-Mania-Decompilation
Path: blob/master/SonicMania/Objects/ERZ/ERZGunner.c
338 views
1
// ---------------------------------------------------------------------
2
// RSDK Project: Sonic Mania
3
// Object Description: ERZGunner Object
4
// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges
5
// Decompiled by: Rubberduckycooly & RMGRich
6
// ---------------------------------------------------------------------
7
8
#include "Game.h"
9
10
ObjectERZGunner *ERZGunner;
11
12
void ERZGunner_Update(void)
13
{
14
RSDK_THIS(ERZGunner);
15
16
StateMachine_Run(self->state);
17
}
18
19
void ERZGunner_LateUpdate(void) {}
20
21
void ERZGunner_StaticUpdate(void) {}
22
23
void ERZGunner_Draw(void)
24
{
25
RSDK_THIS(ERZGunner);
26
27
if (self->stateDraw) {
28
StateMachine_Run(self->stateDraw);
29
}
30
else {
31
RSDK.DrawSprite(&self->mainAnimator, NULL, false);
32
}
33
}
34
35
void ERZGunner_Create(void *data)
36
{
37
RSDK_THIS(ERZGunner);
38
39
if (!SceneInfo->inEditor) {
40
self->visible = true;
41
self->drawGroup = 1;
42
self->active = ACTIVE_NORMAL;
43
self->updateRange.x = 0x800000;
44
self->updateRange.y = 0x800000;
45
46
self->type = VOID_TO_INT(data);
47
switch (self->type) {
48
case ERZGUNNER_BOSS:
49
self->drawFX = FX_FLIP;
50
RSDK.SetSpriteAnimation(ERZGunner->aniFrames, 0, &self->mainAnimator, true, 0);
51
RSDK.SetSpriteAnimation(ERZGunner->aniFrames, 1, &self->fxAnimator, true, 0);
52
53
self->originPos = self->position;
54
self->screenPos = ScreenInfo->position;
55
56
self->stateDraw = ERZGunner_Draw_Gunner;
57
self->state = ERZGunner_State_Idle;
58
break;
59
60
case ERZGUNNER_LAUNCHROCKET:
61
RSDK.SetSpriteAnimation(ERZGunner->aniFrames, 10, &self->mainAnimator, true, 0);
62
RSDK.SetSpriteAnimation(ERZGunner->aniFrames, 11, &self->fxAnimator, true, 0);
63
64
self->stateDraw = ERZGunner_Draw_RocketLaunch;
65
self->state = ERZGunner_State_LaunchedRocket;
66
break;
67
68
case ERZGUNNER_NAPALM_EXPLOSION:
69
self->originPos = self->position;
70
71
self->state = ERZGunner_State_NapalmExplosion;
72
break;
73
74
case ERZGUNNER_MORTAR_EXPLOSION:
75
self->originPos = self->position;
76
77
self->state = ERZGunner_State_MortarExplosion;
78
break;
79
80
default: break;
81
}
82
}
83
}
84
85
void ERZGunner_StageLoad(void)
86
{
87
ERZGunner->aniFrames = RSDK.LoadSpriteAnimation("Phantom/PhantomGunner.bin", SCOPE_STAGE);
88
89
ERZGunner->hitboxNapalm.left = -8;
90
ERZGunner->hitboxNapalm.top = -4;
91
ERZGunner->hitboxNapalm.right = 4;
92
ERZGunner->hitboxNapalm.bottom = 26;
93
94
ERZGunner->hitboxMortar.left = -16;
95
ERZGunner->hitboxMortar.top = -32;
96
ERZGunner->hitboxMortar.right = 16;
97
ERZGunner->hitboxMortar.bottom = -16;
98
99
ERZGunner->hitboxDud.left = -8;
100
ERZGunner->hitboxDud.top = -8;
101
ERZGunner->hitboxDud.right = 8;
102
ERZGunner->hitboxDud.bottom = 8;
103
}
104
105
void ERZGunner_HandleDudExhaust(void)
106
{
107
RSDK_THIS(ERZGunner);
108
if (!(Zone->timer & 7)) {
109
int32 x = self->position.x + (RSDK.Sin512(self->rotation) << 11);
110
int32 y = self->position.y - (RSDK.Cos512(self->rotation) << 11);
111
EntityDebris *debris = CREATE_ENTITY(Debris, Debris_State_Move, x, y);
112
113
RSDK.SetSpriteAnimation(Explosion->aniFrames, 3, &debris->animator, true, 0);
114
debris->velocity.x = RSDK.Sin512(self->rotation) << 8;
115
debris->velocity.y = RSDK.Sin512(self->rotation) << 4;
116
debris->drawGroup = Zone->objectDrawGroup[0];
117
debris->timer = 41;
118
}
119
}
120
121
void ERZGunner_HandleMalfunctionDudExhaust(void)
122
{
123
RSDK_THIS(ERZGunner);
124
125
if (Zone->timer & 3) {
126
if ((Zone->timer & 3) == 2) {
127
int32 x = self->position.x + (RSDK.Sin512(self->rotation) * 0x600);
128
int32 y = self->position.y - (RSDK.Cos512(self->rotation) * 0x600);
129
EntityDebris *debris = CREATE_ENTITY(Debris, Debris_State_Move, x, y);
130
131
RSDK.SetSpriteAnimation(Explosion->aniFrames, 2, &debris->animator, true, 0);
132
debris->drawGroup = Zone->objectDrawGroup[1];
133
debris->drawFX = FX_SCALE;
134
debris->timer = 52;
135
debris->scale.x = (self->scale.x * RSDK.Rand(128, 384)) >> 9;
136
debris->scale.y = debris->scale.x;
137
}
138
}
139
else {
140
int32 x = self->position.x + (RSDK.Sin512(self->rotation) << 11);
141
int32 y = self->position.y - (RSDK.Cos512(self->rotation) << 11);
142
EntityDebris *debris = CREATE_ENTITY(Debris, Debris_State_Move, x, y);
143
144
RSDK.SetSpriteAnimation(Explosion->aniFrames, 3, &debris->animator, true, 0);
145
debris->velocity.x = RSDK.Sin512(self->rotation) << 8;
146
debris->velocity.y = RSDK.Sin512(self->rotation) << 4;
147
debris->drawGroup = Zone->objectDrawGroup[0];
148
debris->drawFX = FX_SCALE;
149
debris->timer = 41;
150
debris->scale.y = self->scale.x;
151
}
152
}
153
154
void ERZGunner_SpawnDust(void)
155
{
156
RSDK_THIS(ERZGunner);
157
158
for (int32 i = 0; i < 4; ++i) {
159
int32 x = self->position.x + RSDK.Rand(-0x100000, 0x100000);
160
int32 y = self->position.y + RSDK.Rand(-0x280000, -0x180000);
161
EntityDust *dust = CREATE_ENTITY(Dust, NULL, x, y);
162
163
dust->state = Dust_State_DustPuff;
164
dust->drawGroup = Zone->objectDrawGroup[1];
165
}
166
}
167
168
void ERZGunner_HandleRotations(int32 angle)
169
{
170
RSDK_THIS(ERZGunner);
171
172
int32 ang = angle - self->rotation;
173
174
if (abs(angle - self->rotation) >= abs(angle - self->rotation - 0x200)) {
175
if (abs(angle - self->rotation - 0x200) < abs(angle - self->rotation + 0x200))
176
self->rotation += (ang - 0x200) >> 4;
177
else
178
self->rotation += (ang + 0x200) >> 4;
179
}
180
else {
181
if (abs(angle - self->rotation) < abs(angle - self->rotation + 0x200))
182
self->rotation += ang >> 4;
183
else
184
self->rotation += (ang + 0x200) >> 4;
185
}
186
187
self->rotation &= 0x1FF;
188
}
189
190
void ERZGunner_CheckPlayerMissileCollisions(void)
191
{
192
RSDK_THIS(ERZGunner);
193
194
foreach_active(Player, player)
195
{
196
if (self->parachuteAnimator.frameID > 0 && player->velocity.y >= 0 && Player_CheckBadnikTouch(player, self, &ERZGunner->hitboxMortar)
197
&& player->animator.animationID != ANI_HURT) {
198
RSDK.SetSpriteAnimation(-1, 0, &self->parachuteAnimator, true, 0);
199
player->velocity.y = -0x60000;
200
201
ERZGunner_SpawnDust();
202
self->state = ERZGunner_State_Napalm;
203
}
204
else {
205
if (Player_CheckBadnikTouch(player, self, &ERZGunner->hitboxNapalm)) {
206
int32 anim = player->animator.animationID;
207
if (anim == ANI_JUMP || anim == ANI_SPINDASH || anim == ANI_DROPDASH) {
208
EntityExplosion *explosion = CREATE_ENTITY(Explosion, INT_TO_VOID(EXPLOSION_ENEMY), self->position.x, self->position.y);
209
explosion->interaction = false;
210
explosion->drawGroup = Zone->objectDrawGroup[1];
211
212
if (self->parachuteAnimator.animationID == 12 && self->parachuteAnimator.frameID > 0)
213
ERZGunner_SpawnDust();
214
215
RSDK.PlaySfx(ERZKing->sfxExplosion2, false, 255);
216
217
destroyEntity(self);
218
foreach_break;
219
}
220
}
221
}
222
}
223
}
224
225
void ERZGunner_CheckPlayerExplosionCollisions(void)
226
{
227
foreach_active(Player, player)
228
{
229
foreach_active(Explosion, explosion)
230
{
231
if (explosion->animator.frameID <= 6) {
232
if (Player_CheckCollisionTouch(player, explosion, &ERZGunner->hitboxDud)) {
233
Player_ElementHurt(player, explosion, SHIELD_FIRE);
234
}
235
}
236
}
237
}
238
}
239
240
void ERZGunner_Hit(EntityERZGunner *entity)
241
{
242
RSDK.PlaySfx(ERZKing->sfxHit, false, 255);
243
entity->invincibilityTimer = 48;
244
}
245
246
void ERZGunner_Draw_Gunner(void)
247
{
248
RSDK_THIS(ERZGunner);
249
250
if (self->invincibilityTimer & 1) {
251
RSDK.CopyPalette(2, 128, 0, 128, 128);
252
253
RSDK.DrawSprite(&self->mainAnimator, NULL, false);
254
255
self->direction = FLIP_X;
256
RSDK.DrawSprite(&self->fxAnimator, NULL, false);
257
258
self->direction = FLIP_NONE;
259
RSDK.DrawSprite(&self->fxAnimator, NULL, false);
260
261
RSDK.CopyPalette(1, 128, 0, 128, 128);
262
}
263
else {
264
RSDK.DrawSprite(&self->mainAnimator, NULL, false);
265
266
self->direction = FLIP_X;
267
RSDK.DrawSprite(&self->fxAnimator, NULL, false);
268
269
self->direction = FLIP_NONE;
270
RSDK.DrawSprite(&self->fxAnimator, NULL, false);
271
}
272
}
273
274
void ERZGunner_Draw_RocketLaunch(void)
275
{
276
RSDK_THIS(ERZGunner);
277
278
EntityERZGunner *parent = self->parent;
279
280
RSDK.SetClipBounds(0, 0, 0, ScreenInfo->size.x, ((self->originPos.y + parent->position.y) >> 16) - ScreenInfo->position.y);
281
282
Vector2 drawPos;
283
drawPos.x = parent->position.x + self->originPos.x;
284
drawPos.y = self->position.y;
285
RSDK.DrawSprite(&self->mainAnimator, &drawPos, false);
286
287
RSDK.SetClipBounds(0, 0, 0, ScreenInfo->size.x, ScreenInfo->size.y);
288
289
drawPos.y = self->originPos.y + parent->position.y;
290
RSDK.DrawSprite(&self->fxAnimator, &drawPos, false);
291
}
292
293
void ERZGunner_Draw_Rocket(void)
294
{
295
RSDK_THIS(ERZGunner);
296
297
RSDK.DrawSprite(&self->mainAnimator, NULL, false);
298
RSDK.DrawSprite(&self->tailAnimator, NULL, false);
299
RSDK.DrawSprite(&self->parachuteAnimator, NULL, false);
300
}
301
302
void ERZGunner_State_Idle(void)
303
{
304
RSDK_THIS(ERZGunner);
305
306
if (self->invincibilityTimer > 0)
307
self->invincibilityTimer--;
308
309
self->position.x += (ScreenInfo->position.x - self->screenPos.x) << 15;
310
self->position.y = BadnikHelpers_Oscillate(self->originPos.y, 3, 11);
311
312
self->screenPos = ScreenInfo->position;
313
314
RSDK.ProcessAnimation(&self->fxAnimator);
315
316
self->fireAnimTimer = 8;
317
if (++self->timer < 120 || RSDK.GetEntityCount(ERZGunner->classID, true) >= 2) {
318
ERZGunner_CheckPlayerExplosionCollisions();
319
}
320
else {
321
if (++self->rocketLaunchCount == 2) {
322
foreach_all(ERZKing, king) { king->active = ACTIVE_NORMAL; }
323
destroyEntity(self);
324
}
325
else {
326
ERZGunner->launchedRocketID = 0;
327
self->timer = 0;
328
RSDK.SetSpriteAnimation(ERZGunner->aniFrames, 2, &self->mainAnimator, true, 0);
329
330
self->state = ERZGunner_State_LaunchRockets;
331
ERZGunner_CheckPlayerExplosionCollisions();
332
}
333
}
334
}
335
336
void ERZGunner_State_LaunchRockets(void)
337
{
338
RSDK_THIS(ERZGunner);
339
340
if (self->invincibilityTimer > 0)
341
self->invincibilityTimer--;
342
343
self->position.x += (ScreenInfo->position.x - self->screenPos.x) << 15;
344
self->position.y = BadnikHelpers_Oscillate(self->originPos.y, 3, 11);
345
346
self->screenPos = ScreenInfo->position;
347
348
RSDK.ProcessAnimation(&self->mainAnimator);
349
RSDK.ProcessAnimation(&self->fxAnimator);
350
351
if (++self->timer == 8) {
352
EntityERZGunner *rocket = CREATE_ENTITY(ERZGunner, INT_TO_VOID(ERZGUNNER_LAUNCHROCKET), self->position.x, self->position.y);
353
rocket->parent = self;
354
rocket->originPos.x = ERZGunner->rocketOffsets[self->rocketOffsetID] << 16;
355
rocket->originPos.y = ERZGunner->rocketOffsets[self->rocketOffsetID + 1] << 16;
356
rocket->position.x += rocket->originPos.x;
357
rocket->position.y += rocket->originPos.y + 0x100000;
358
359
self->rocketOffsetID = (self->rocketOffsetID - 14) & 0x1F;
360
}
361
362
if (self->mainAnimator.frameID == self->mainAnimator.frameCount - 1) {
363
self->timer = 0;
364
365
if (--self->fireAnimTimer > 0) {
366
if (!(self->fireAnimTimer & 1))
367
RSDK.SetSpriteAnimation(ERZGunner->aniFrames, 2, &self->mainAnimator, true, 0);
368
else
369
RSDK.SetSpriteAnimation(ERZGunner->aniFrames, 3, &self->mainAnimator, true, 0);
370
}
371
else {
372
RSDK.SetSpriteAnimation(ERZGunner->aniFrames, 0, &self->mainAnimator, true, 0);
373
self->state = ERZGunner_State_Idle;
374
}
375
}
376
377
ERZGunner_CheckPlayerExplosionCollisions();
378
}
379
380
void ERZGunner_State_LaunchedRocket(void)
381
{
382
RSDK_THIS(ERZGunner);
383
384
RSDK.ProcessAnimation(&self->mainAnimator);
385
RSDK.ProcessAnimation(&self->fxAnimator);
386
387
self->position.y -= 0x80000;
388
389
if (++self->timer == 60) {
390
EntityERZGunner *parent = self->parent;
391
392
self->timer = 0;
393
394
if ((ERZGunner->launchedRocketID & 3) == 3)
395
self->type = ERZGUNNER_DUD;
396
else
397
self->type = (ERZGunner->launchedRocketID & 1) + ERZGUNNER_MORTAR;
398
399
++ERZGunner->launchedRocketID;
400
401
self->drawGroup = Zone->objectDrawGroup[0];
402
self->position.y = (ScreenInfo->position.y - 64) << 16;
403
404
bool32 canFire = false;
405
while (!canFire) {
406
canFire = true;
407
self->position.x = parent->position.x + RSDK.Rand(-0x1000000, 0x1000000);
408
409
foreach_active(ERZGunner, gunner)
410
{
411
if (gunner != self && gunner->type >= ERZGUNNER_MORTAR) {
412
int32 dist = abs(gunner->position.x - self->position.x);
413
if (dist < 0x180000 && gunner->position.y - self->position.y < 0x800000)
414
canFire = false;
415
}
416
}
417
}
418
419
if (self->type == ERZGUNNER_MORTAR) {
420
RSDK.SetSpriteAnimation(ERZGunner->aniFrames, 4, &self->mainAnimator, true, 0);
421
RSDK.SetSpriteAnimation(ERZGunner->aniFrames, 5, &self->tailAnimator, true, 0);
422
RSDK.SetSpriteAnimation(ERZGunner->aniFrames, 12, &self->parachuteAnimator, true, 0);
423
424
self->state = ERZGunner_State_Mortar;
425
self->timer = RSDK.Rand(0, 2) << 8;
426
self->stateDraw = ERZGunner_Draw_Rocket;
427
}
428
else if (self->type == ERZGUNNER_NAPALM) {
429
RSDK.SetSpriteAnimation(ERZGunner->aniFrames, 6, &self->mainAnimator, true, 0);
430
RSDK.SetSpriteAnimation(ERZGunner->aniFrames, 7, &self->tailAnimator, true, 0);
431
432
self->state = ERZGunner_State_Napalm;
433
self->stateDraw = ERZGunner_Draw_Rocket;
434
}
435
else if (self->type == ERZGUNNER_DUD) {
436
RSDK.SetSpriteAnimation(ERZGunner->aniFrames, 8, &self->mainAnimator, true, 0);
437
RSDK.SetSpriteAnimation(ERZGunner->aniFrames, 9, &self->tailAnimator, true, 0);
438
439
self->position.x = parent->position.x;
440
self->drawFX = FX_ROTATE;
441
self->state = ERZGunner_State_Dud_Active;
442
self->velocity.x = (Zone->timer & 1) ? -0x40000 : 0x40000;
443
self->stateDraw = ERZGunner_Draw_Rocket;
444
}
445
}
446
}
447
448
void ERZGunner_State_Mortar(void)
449
{
450
RSDK_THIS(ERZGunner);
451
452
RSDK.ProcessAnimation(&self->parachuteAnimator);
453
RSDK.ProcessAnimation(&self->tailAnimator);
454
455
if (self->parachuteAnimator.frameID) {
456
self->drawFX = FX_ROTATE;
457
if (self->velocity.y > 0xC000)
458
self->velocity.y -= 0x3800;
459
460
self->rotation = RSDK.Sin512(self->timer) >> 6;
461
self->timer = (self->timer + 4) & 0x1FF;
462
}
463
else {
464
if (self->velocity.y < 0x40000)
465
self->velocity.y += 0x3800;
466
}
467
468
self->position.y += self->velocity.y;
469
470
ERZGunner_CheckPlayerMissileCollisions();
471
472
if (self->classID) {
473
if (RSDK.ObjectTileCollision(self, Zone->collisionLayers, CMODE_FLOOR, 0, 0, 0x100000, true)) {
474
if (self->type == ERZGUNNER_NAPALM) {
475
EntityERZGunner *napalm = CREATE_ENTITY(ERZGunner, INT_TO_VOID(ERZGUNNER_NAPALM_EXPLOSION), self->position.x, self->position.y);
476
napalm->velocity.x = self->velocity.y > 0x20000 ? 0x80000 : 0x40000;
477
478
destroyEntity(self);
479
}
480
else {
481
CREATE_ENTITY(ERZGunner, INT_TO_VOID(ERZGUNNER_MORTAR_EXPLOSION), self->position.x, self->position.y);
482
483
destroyEntity(self);
484
}
485
}
486
}
487
}
488
489
void ERZGunner_State_Napalm(void)
490
{
491
RSDK_THIS(ERZGunner);
492
493
RSDK.ProcessAnimation(&self->tailAnimator);
494
495
if (self->velocity.y < 0x40000)
496
self->velocity.y += 0x1800;
497
498
self->position.y += self->velocity.y;
499
500
ERZGunner_CheckPlayerMissileCollisions();
501
502
if (self->classID) {
503
if (RSDK.ObjectTileCollision(self, Zone->collisionLayers, CMODE_FLOOR, 0, 0, 0x100000, true)) {
504
if (self->type == ERZGUNNER_NAPALM) {
505
EntityERZGunner *napalm = CREATE_ENTITY(ERZGunner, INT_TO_VOID(ERZGUNNER_NAPALM_EXPLOSION), self->position.x, self->position.y);
506
napalm->velocity.x = self->velocity.y > 0x20000 ? 0x80000 : 0x40000;
507
508
destroyEntity(self);
509
}
510
else {
511
CREATE_ENTITY(ERZGunner, INT_TO_VOID(ERZGUNNER_MORTAR_EXPLOSION), self->position.x, self->position.y);
512
513
destroyEntity(self);
514
}
515
}
516
}
517
}
518
519
void ERZGunner_State_Dud_Active(void)
520
{
521
RSDK_THIS(ERZGunner);
522
523
RSDK.ProcessAnimation(&self->tailAnimator);
524
525
EntityERZGunner *parent = self->parent;
526
527
++self->timer;
528
529
self->velocity.x = RSDK.Cos256(self->timer) << 11;
530
if (self->position.y < parent->position.y - 0x800000) {
531
if (self->velocity.y < 0x20000)
532
self->velocity.y += 0x2000;
533
}
534
if (self->position.y > parent->position.y - 0x200000) {
535
if (self->velocity.y > -0x20000)
536
self->velocity.y -= 0x2000;
537
}
538
539
self->position.x += self->velocity.x;
540
self->position.y += self->velocity.y;
541
542
ERZGunner_HandleDudExhaust();
543
544
int32 angle = RSDK.ATan2(self->velocity.y, -self->velocity.x);
545
ERZGunner_HandleRotations(2 * angle);
546
547
if (self->timer == 320) {
548
EntityExplosion *explosion = CREATE_ENTITY(Explosion, INT_TO_VOID(EXPLOSION_ITEMBOX), self->position.x, self->position.y);
549
explosion->interaction = false;
550
explosion->drawGroup = Zone->objectDrawGroup[1];
551
destroyEntity(self);
552
}
553
else {
554
foreach_active(Player, player)
555
{
556
if (Player_CheckBadnikTouch(player, self, &ERZGunner->hitboxDud)) {
557
self->angle = self->rotation << 8;
558
self->timer = 0;
559
self->drawFX = FX_SCALE | FX_ROTATE;
560
self->groundVel = 0x4000;
561
self->scale.x = 0x200;
562
self->scale.y = 0x200;
563
self->state = ERZGunner_State_Dud_HitByPlayer;
564
RSDK.PlaySfx(ERZKing->sfxHit, false, 255);
565
}
566
}
567
}
568
}
569
570
void ERZGunner_State_Dud_HitByPlayer(void)
571
{
572
RSDK_THIS(ERZGunner);
573
574
RSDK.ProcessAnimation(&self->tailAnimator);
575
576
self->angle += self->groundVel;
577
self->rotation = self->angle >> 8;
578
self->groundVel -= (self->groundVel >> 3);
579
580
ERZGunner_HandleDudExhaust();
581
582
if (self->groundVel < 128)
583
self->state = ERZGunner_State_Dud_Malfunction;
584
}
585
586
void ERZGunner_State_Dud_Malfunction(void)
587
{
588
RSDK_THIS(ERZGunner);
589
590
RSDK.ProcessAnimation(&self->tailAnimator);
591
592
EntityERZGunner *parent = self->parent;
593
594
int32 angle = RSDK.ATan2((parent->position.y - self->position.y) >> 16, -((parent->position.x - self->position.x) >> 16));
595
ERZGunner_HandleRotations(2 * angle);
596
597
self->rotation &= 0x1FF;
598
self->position.x -= RSDK.Sin512(self->rotation) << 9;
599
self->position.y += RSDK.Cos512(self->rotation) << 9;
600
self->scale.x -= 6;
601
self->scale.y = self->scale.x;
602
603
ERZGunner_HandleMalfunctionDudExhaust();
604
605
if (self->scale.x < 0x80) {
606
ERZGunner_Hit(parent);
607
self->position.x = parent->position.x;
608
self->position.y = parent->position.y;
609
self->visible = false;
610
self->state = ERZGunner_State_Dud_Explode;
611
}
612
}
613
614
void ERZGunner_State_Dud_Explode(void)
615
{
616
RSDK_THIS(ERZGunner);
617
618
if (!(Zone->timer % 3) && !(Zone->timer & 4)) {
619
int32 x = self->position.x + RSDK.Rand(-0x100000, 0x100000);
620
int32 y = self->position.y + RSDK.Rand(-0x100000, 0x100000);
621
EntityExplosion *explosion = CREATE_ENTITY(Explosion, INT_TO_VOID((RSDK.Rand(0, 256) > 192) + EXPLOSION_BOSS), x, y);
622
623
explosion->interaction = false;
624
explosion->drawGroup = 1;
625
explosion->scale = self->scale;
626
}
627
628
if (++self->timer == 16)
629
destroyEntity(self);
630
}
631
632
void ERZGunner_State_NapalmExplosion(void)
633
{
634
RSDK_THIS(ERZGunner);
635
636
if (!(Zone->timer & 3)) {
637
CREATE_ENTITY(Explosion, INT_TO_VOID(EXPLOSION_BOSS), self->originPos.x - self->napalmExplosionPos, self->position.y);
638
CREATE_ENTITY(Explosion, INT_TO_VOID(EXPLOSION_BOSS), self->originPos.x + self->napalmExplosionPos, self->position.y);
639
}
640
641
self->napalmExplosionPos += self->velocity.x;
642
643
if (++self->timer == 16)
644
destroyEntity(self);
645
}
646
647
void ERZGunner_State_MortarExplosion(void)
648
{
649
RSDK_THIS(ERZGunner);
650
651
if (!(Zone->timer & 3))
652
CREATE_ENTITY(Explosion, INT_TO_VOID(EXPLOSION_ITEMBOX), self->position.x, self->position.y);
653
654
self->position.y -= 0x40000;
655
656
if (++self->timer == 16)
657
destroyEntity(self);
658
}
659
660
#if GAME_INCLUDE_EDITOR
661
void ERZGunner_EditorDraw(void)
662
{
663
RSDK_THIS(ERZGunner);
664
665
self->drawFX = FX_FLIP;
666
RSDK.SetSpriteAnimation(ERZGunner->aniFrames, 0, &self->mainAnimator, false, 0);
667
RSDK.SetSpriteAnimation(ERZGunner->aniFrames, 1, &self->fxAnimator, false, 0);
668
669
self->originPos = self->position;
670
self->screenPos = ScreenInfo->position;
671
672
ERZGunner_Draw_Gunner();
673
}
674
675
void ERZGunner_EditorLoad(void) { ERZGunner->aniFrames = RSDK.LoadSpriteAnimation("Phantom/PhantomGunner.bin", SCOPE_STAGE); }
676
#endif
677
678
void ERZGunner_Serialize(void) {}
679
680