Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rubberduckycooly
GitHub Repository: rubberduckycooly/Sonic-Mania-Decompilation
Path: blob/master/SonicMania/Objects/LRZ/DrillerdroidO.c
338 views
1
// ---------------------------------------------------------------------
2
// RSDK Project: Sonic Mania
3
// Object Description: DrillerdroidO Object
4
// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges
5
// Decompiled by: Rubberduckycooly & RMGRich
6
// ---------------------------------------------------------------------
7
8
#include "Game.h"
9
10
ObjectDrillerdroidO *DrillerdroidO;
11
12
void DrillerdroidO_Update(void)
13
{
14
RSDK_THIS(DrillerdroidO);
15
16
StateMachine_Run(self->state);
17
}
18
19
void DrillerdroidO_LateUpdate(void) {}
20
21
void DrillerdroidO_StaticUpdate(void)
22
{
23
if (DrillerdroidO->drillSfxTimer) {
24
if (!DrillerdroidO->playingDrillSfx) {
25
RSDK.PlaySfx(DrillerdroidO->sfxDrill, 43643, 0xFF);
26
DrillerdroidO->playingDrillSfx = true;
27
}
28
29
DrillerdroidO->drillSfxTimer = 0;
30
}
31
else if (DrillerdroidO->playingDrillSfx) {
32
RSDK.StopSfx(DrillerdroidO->sfxDrill);
33
DrillerdroidO->playingDrillSfx = false;
34
}
35
}
36
37
void DrillerdroidO_Draw(void)
38
{
39
RSDK_THIS(DrillerdroidO);
40
41
StateMachine_Run(self->stateDraw);
42
}
43
44
void DrillerdroidO_Create(void *data)
45
{
46
RSDK_THIS(DrillerdroidO);
47
48
if (!SceneInfo->inEditor) {
49
if (globals->gameMode < MODE_TIMEATTACK) {
50
self->visible = true;
51
52
if (data)
53
self->type = VOID_TO_INT(data);
54
55
switch (self->type) {
56
case DRILLERDROIDO_MAIN:
57
self->active = ACTIVE_BOUNDS;
58
self->updateRange.x = 0x800000;
59
self->updateRange.y = 0x800000;
60
61
RSDK.SetSpriteAnimation(DrillerdroidO->aniFrames, 0, &self->mainAnimator, true, 0);
62
RSDK.SetSpriteAnimation(DrillerdroidO->aniFrames, 5, &self->armorAnimator, true, 0);
63
64
self->drawGroup = Zone->objectDrawGroup[1];
65
66
DrillerdroidO->boss = self;
67
DrillerdroidO->childSlotStart = SceneInfo->entitySlot + 2;
68
DrillerdroidO->currentLevel = 4;
69
70
self->state = DrillerdroidO_State_SetupArena;
71
self->stateDraw = DrillerdroidO_Draw_Boss;
72
break;
73
74
case DRILLERDROIDO_FIREBALLEMITTER:
75
self->active = ACTIVE_BOUNDS;
76
self->drawFX = FX_FLIP;
77
self->updateRange.x = 0x800000;
78
self->updateRange.y = 0x800000;
79
80
RSDK.SetSpriteAnimation(DrillerdroidO->ticFrames, 0, &self->mainAnimator, true, 0);
81
82
self->drawGroup = Zone->objectDrawGroup[1];
83
self->state = DrillerdroidO_State_FireballEmitter;
84
self->stateDraw = DrillerdroidO_Draw_FireballEmitter;
85
break;
86
87
case DRILLERDROIDO_TARGET:
88
case DRILLERDROIDO_UNUSED1:
89
case DRILLERDROIDO_UNUSED2:
90
self->active = ACTIVE_NORMAL;
91
self->drawFX = FX_FLIP;
92
self->updateRange.x = 0x800000;
93
self->updateRange.y = 0x800000;
94
95
RSDK.SetSpriteAnimation(DrillerdroidO->aniFrames, 2, &self->mainAnimator, true, 0);
96
RSDK.SetSpriteAnimation(DrillerdroidO->aniFrames, 3, &self->armorAnimator, true, 0);
97
98
self->drawGroup = Zone->objectDrawGroup[1];
99
self->state = DrillerdroidO_State_Target;
100
self->stateDraw = DrillerdroidO_Draw_Target;
101
break;
102
103
default: break;
104
}
105
}
106
else {
107
destroyEntity(self);
108
}
109
}
110
}
111
112
void DrillerdroidO_StageLoad(void)
113
{
114
if (RSDK.CheckSceneFolder("LRZ1"))
115
DrillerdroidO->aniFrames = RSDK.LoadSpriteAnimation("LRZ1/Drillerdroid.bin", SCOPE_STAGE);
116
117
DrillerdroidO->ticFrames = RSDK.LoadSpriteAnimation("Global/TicMark.bin", SCOPE_STAGE);
118
119
DrillerdroidO->hitboxCore.left = -25;
120
DrillerdroidO->hitboxCore.top = -16;
121
DrillerdroidO->hitboxCore.right = 25;
122
DrillerdroidO->hitboxCore.bottom = 16;
123
124
DrillerdroidO->hitboxPistonL.left = -58;
125
DrillerdroidO->hitboxPistonL.top = -74;
126
DrillerdroidO->hitboxPistonL.right = -25;
127
DrillerdroidO->hitboxPistonL.bottom = 16;
128
129
DrillerdroidO->hitboxPistonR.left = 25;
130
DrillerdroidO->hitboxPistonR.top = -74;
131
DrillerdroidO->hitboxPistonR.right = 58;
132
DrillerdroidO->hitboxPistonR.bottom = 16;
133
134
DrillerdroidO->hitboxDrillL.left = -58;
135
DrillerdroidO->hitboxDrillL.top = 16;
136
DrillerdroidO->hitboxDrillL.right = -25;
137
DrillerdroidO->hitboxDrillL.bottom = 53;
138
139
DrillerdroidO->hitboxDrillR.left = 25;
140
DrillerdroidO->hitboxDrillR.top = 16;
141
DrillerdroidO->hitboxDrillR.right = 58;
142
DrillerdroidO->hitboxDrillR.bottom = 53;
143
144
DrillerdroidO->hitboxLandPosSegmentBreak.left = -6;
145
DrillerdroidO->hitboxLandPosSegmentBreak.top = 16;
146
DrillerdroidO->hitboxLandPosSegmentBreak.right = 6;
147
DrillerdroidO->hitboxLandPosSegmentBreak.bottom = 16;
148
149
DrillerdroidO->hitboxLandPosR.left = -58;
150
DrillerdroidO->hitboxLandPosR.top = 37;
151
DrillerdroidO->hitboxLandPosR.right = -42;
152
DrillerdroidO->hitboxLandPosR.bottom = 53;
153
154
DrillerdroidO->hitboxLandPosL.left = 42;
155
DrillerdroidO->hitboxLandPosL.top = 37;
156
DrillerdroidO->hitboxLandPosL.right = 58;
157
DrillerdroidO->hitboxLandPosL.bottom = 53;
158
159
DrillerdroidO->hitboxEmitterRange.left = -32;
160
DrillerdroidO->hitboxEmitterRange.top = -192;
161
DrillerdroidO->hitboxEmitterRange.right = 32;
162
DrillerdroidO->hitboxEmitterRange.bottom = 192;
163
164
DrillerdroidO->drillDelay[0] = 4;
165
DrillerdroidO->pistonDelay[0] = 4;
166
167
DrillerdroidO->drillDelay[1] = 0;
168
DrillerdroidO->pistonDelay[1] = 0;
169
170
DrillerdroidO->drillPos[0] = 0x100000;
171
DrillerdroidO->drillPos[1] = 0x100000;
172
173
DrillerdroidO->pistonPos[0] = 0;
174
DrillerdroidO->pistonPos[1] = 0;
175
176
DrillerdroidO->drillMoveDir[0] = FLIP_NONE;
177
DrillerdroidO->drillMoveDir[1] = FLIP_NONE;
178
179
DrillerdroidO->pistonMoveDir[0] = FLIP_NONE;
180
DrillerdroidO->pistonMoveDir[1] = FLIP_NONE;
181
182
DrillerdroidO->active = ACTIVE_ALWAYS;
183
184
DrillerdroidO->drillSfxTimer = 0;
185
DrillerdroidO->playingDrillSfx = false;
186
187
DrillerdroidO->emitFireballs = false;
188
189
DrillerdroidO->sfxHit = RSDK.GetSfx("Stage/BossHit.wav");
190
DrillerdroidO->sfxExplosion = RSDK.GetSfx("Stage/Explosion2.wav");
191
DrillerdroidO->sfxDrill = RSDK.GetSfx("LRZ/Drill.wav");
192
DrillerdroidO->sfxImpact = RSDK.GetSfx("Stage/Impact4.wav");
193
DrillerdroidO->sfxJump = RSDK.GetSfx("LRZ/DrillJump.wav");
194
DrillerdroidO->sfxTargeting = RSDK.GetSfx("Stage/Targeting1.wav");
195
DrillerdroidO->sfxSizzle = RSDK.GetSfx("LRZ/Sizzle.wav");
196
}
197
198
void DrillerdroidO_CheckPlayerCollisions(void)
199
{
200
RSDK_THIS(DrillerdroidO);
201
202
if (self->invincibilityTimer)
203
self->invincibilityTimer--;
204
205
foreach_active(Player, player)
206
{
207
int32 playerX = player->position.y;
208
int32 playerY = player->position.x;
209
int32 velX = player->velocity.x;
210
int32 velY = player->velocity.y;
211
int32 side = Player_CheckCollisionBox(player, self, &DrillerdroidO->hitboxCore);
212
213
switch (side) {
214
default: break;
215
216
case C_TOP:
217
Player_Hurt(player, self);
218
219
if (self->velocity.y <= 0)
220
player->collisionFlagV |= 1;
221
break;
222
223
case C_BOTTOM:
224
if (self->rotation) {
225
if (!self->invincibilityTimer) {
226
player->velocity.x = velX;
227
player->velocity.y = velY;
228
player->position.x = playerY;
229
player->position.y = playerX;
230
231
if (Player_CheckBossHit(player, self)) {
232
if (!--self->health) {
233
SceneInfo->timeEnabled = false;
234
Player_GiveScore(RSDK_GET_ENTITY(SLOT_PLAYER1, Player), 1000);
235
self->invincibilityTimer = 60;
236
DrillerdroidO->emitFireballs = false;
237
self->state = DrillerdroidO_State_Destroyed;
238
}
239
else {
240
RSDK.PlaySfx(DrillerdroidO->sfxHit, false, 255);
241
self->invincibilityTimer = 30;
242
}
243
}
244
}
245
}
246
else if (self->velocity.y >= 0) {
247
player->collisionFlagV |= 2;
248
}
249
break;
250
}
251
252
Player_CheckCollisionBox(player, self, &DrillerdroidO->hitboxPistonL);
253
Player_CheckCollisionBox(player, self, &DrillerdroidO->hitboxPistonR);
254
255
if (self->state == DrillerdroidO_State_Drilling) {
256
if (Player_CheckCollisionTouch(player, self, &DrillerdroidO->hitboxDrillL)
257
|| Player_CheckCollisionTouch(player, self, &DrillerdroidO->hitboxDrillR)) {
258
Player_Hurt(player, self);
259
}
260
}
261
else {
262
if (self->state == DrillerdroidO_State_Dropping
263
&& (Player_CheckCollisionBox(player, self, &DrillerdroidO->hitboxDrillL) == C_BOTTOM
264
|| Player_CheckCollisionBox(player, self, &DrillerdroidO->hitboxDrillR) == C_BOTTOM)) {
265
if (self->velocity.y >= 0)
266
player->collisionFlagV |= 2;
267
else
268
Player_Hurt(player, self);
269
}
270
}
271
}
272
}
273
274
void DrillerdroidO_Explode(void)
275
{
276
RSDK_THIS(DrillerdroidO);
277
278
if (!(Zone->timer & 3)) {
279
RSDK.PlaySfx(Drillerdroid->sfxExplosion, false, 255);
280
281
if (!(Zone->timer & 3)) {
282
int32 x = self->position.x + (RSDK.Rand(-19, 20) << 16);
283
int32 y = self->position.y + (RSDK.Rand(-24, 25) << 16);
284
CREATE_ENTITY(Explosion, INT_TO_VOID((RSDK.Rand(0, 256) > 192) + EXPLOSION_BOSS), x, y)->drawGroup = Zone->objectDrawGroup[1] + 2;
285
}
286
}
287
}
288
289
void DrillerdroidO_SpawnDebris(int32 offset)
290
{
291
RSDK_THIS(DrillerdroidO);
292
293
EntityDebris *debris = CREATE_ENTITY(Debris, Debris_State_Fall, offset + self->position.x, self->position.y + 0x400000);
294
RSDK.SetSpriteAnimation(DrillerdroidO->aniFrames, 1, &debris->animator, true, RSDK.Rand(0, 8));
295
debris->velocity.x = RSDK.Rand(0, 6) << 15;
296
debris->velocity.y = RSDK.Rand(-12, -8) << 15;
297
debris->gravityStrength = 0x3800;
298
debris->drawGroup = Zone->objectDrawGroup[0];
299
debris->updateRange.x = 0x400000;
300
debris->updateRange.y = 0x400000;
301
302
debris = CREATE_ENTITY(Debris, Debris_State_Fall, offset + self->position.x, self->position.y + 0x400000);
303
RSDK.SetSpriteAnimation(DrillerdroidO->aniFrames, 1, &debris->animator, true, RSDK.Rand(0, 8));
304
debris->velocity.x = RSDK.Rand(-6, 0) << 15;
305
debris->velocity.y = RSDK.Rand(-12, -8) << 15;
306
debris->gravityStrength = 0x3800;
307
debris->drawGroup = Zone->objectDrawGroup[0];
308
debris->updateRange.x = 0x400000;
309
debris->updateRange.y = 0x400000;
310
}
311
312
void DrillerdroidO_State_SetupArena(void)
313
{
314
RSDK_THIS(DrillerdroidO);
315
316
if (++self->timer >= 2) {
317
self->timer = 0;
318
319
Zone->playerBoundActiveR[0] = true;
320
Zone->playerBoundActiveB[0] = true;
321
Zone->cameraBoundsR[0] = (self->position.x >> 16) + ScreenInfo->center.x;
322
Zone->cameraBoundsB[0] = (self->position.y >> 16) + 96;
323
Zone->cameraBoundsT[0] = Zone->cameraBoundsB[0] - SCREEN_YSIZE;
324
325
self->startY = self->position.y;
326
self->active = ACTIVE_NORMAL;
327
self->position.y = (ScreenInfo->position.y - 192) << 16;
328
self->visible = true;
329
self->state = DrillerdroidO_State_AwaitPlayer;
330
}
331
}
332
333
void DrillerdroidO_State_AwaitPlayer(void)
334
{
335
RSDK_THIS(DrillerdroidO);
336
337
Zone->playerBoundActiveL[0] = true;
338
Zone->cameraBoundsL[0] = ScreenInfo->position.x;
339
340
if (RSDK_GET_ENTITY(SLOT_PLAYER1, Player)->position.x > self->position.x) {
341
Zone->playerBoundActiveL[0] = true;
342
Zone->cameraBoundsL[0] = (self->position.x >> 16) - ScreenInfo->center.x;
343
344
Music_TransitionTrack(TRACK_MINIBOSS, 0.0125);
345
self->health = 6;
346
347
CREATE_ENTITY(DrillerdroidO, INT_TO_VOID(DRILLERDROIDO_TARGET), self->position.x, self->startY);
348
self->position.x = 0;
349
350
RSDK.PlaySfx(DrillerdroidO->sfxTargeting, false, 255);
351
self->state = DrillerdroidO_State_DecidingDropPos;
352
DrillerdroidO->canBreakSegment = true;
353
DrillerdroidO->emitFireballs = true;
354
}
355
}
356
357
void DrillerdroidO_State_Dropping(void)
358
{
359
RSDK_THIS(DrillerdroidO);
360
361
self->position.y += self->velocity.y;
362
self->velocity.y += 0x3800;
363
DrillerdroidO_CheckPlayerCollisions();
364
365
if (self->position.y >= (Zone->cameraBoundsB[0] - 112) << 16) {
366
self->position.y = (Zone->cameraBoundsB[0] - 112) << 16;
367
RSDK.PlaySfx(DrillerdroidO->sfxImpact, false, 255);
368
369
EntityCamera *camera = RSDK_GET_ENTITY(SLOT_CAMERA1, Camera);
370
if (!camera->shakePos.y)
371
camera->shakePos.y = 4;
372
373
self->velocity.y >>= 1;
374
self->startY = self->position.y + 0x100000;
375
376
if (!DrillerdroidO->canBreakSegment) {
377
for (int32 i = 0; i < 4; ++i) {
378
DrillerdroidO_SpawnDebris(-0x300000);
379
DrillerdroidO_SpawnDebris(0x300000);
380
DrillerdroidO_SpawnDebris(-0x190000);
381
DrillerdroidO_SpawnDebris(0x190000);
382
}
383
}
384
385
EntityLRZRockPile *pile = RSDK_GET_ENTITY(SceneInfo->entitySlot + 1, LRZRockPile);
386
pile->timer = 1;
387
pile->canCollapse = true;
388
self->timer = 60;
389
self->angle = 0;
390
self->state = DrillerdroidO_State_Landed;
391
}
392
}
393
394
void DrillerdroidO_State_Landed(void)
395
{
396
RSDK_THIS(DrillerdroidO);
397
398
self->position.y += self->velocity.y;
399
self->velocity.y -= 0xE000;
400
401
DrillerdroidO->drillPos[0] = self->startY - self->position.y;
402
DrillerdroidO->drillPos[1] = self->startY - self->position.y;
403
404
DrillerdroidO_CheckPlayerCollisions();
405
406
if (self->velocity.y < 0) {
407
if (self->position.y < self->startY)
408
self->state = DrillerdroidO_State_LandRecoil;
409
}
410
}
411
412
void DrillerdroidO_State_LandRecoil(void)
413
{
414
RSDK_THIS(DrillerdroidO);
415
416
self->position.y += self->velocity.y;
417
self->velocity.y += 0x14000;
418
419
DrillerdroidO->drillPos[0] = self->startY - self->position.y;
420
DrillerdroidO->drillPos[1] = self->startY - self->position.y;
421
422
DrillerdroidO_CheckPlayerCollisions();
423
424
if (self->velocity.y > 0) {
425
if (self->position.y > self->startY) {
426
self->position.y = self->startY;
427
428
DrillerdroidO->drillPos[0] = 0;
429
DrillerdroidO->drillPos[1] = 0;
430
431
self->state = DrillerdroidO_State_BeginDrilling;
432
}
433
}
434
}
435
436
void DrillerdroidO_State_BeginDrilling(void)
437
{
438
RSDK_THIS(DrillerdroidO);
439
440
DrillerdroidO_CheckPlayerCollisions();
441
if (--self->timer <= 0) {
442
if (DrillerdroidO->canBreakSegment) {
443
EntityLavaGeyser *geyser = CREATE_ENTITY(LavaGeyser, NULL, self->position.x, self->position.y + 0x580000);
444
geyser->force = 56 << 12;
445
geyser->duration = 120;
446
geyser->drawGroup = Zone->objectDrawGroup[1];
447
geyser->state = LavaGeyser_HandleSetup;
448
}
449
450
self->timer = 240;
451
self->state = DrillerdroidO_State_Drilling;
452
}
453
}
454
455
void DrillerdroidO_State_Drilling(void)
456
{
457
RSDK_THIS(DrillerdroidO);
458
459
++DrillerdroidO->drillSfxTimer;
460
RSDK.ProcessAnimation(&self->mainAnimator);
461
462
for (int32 i = 0; i < 2; ++i) {
463
if (DrillerdroidO->pistonDelay[i]) {
464
DrillerdroidO->pistonDelay[i]--;
465
}
466
else if (DrillerdroidO->pistonMoveDir[i]) {
467
DrillerdroidO->pistonPos[i] -= 0x20000;
468
if (!DrillerdroidO->pistonPos[i]) {
469
DrillerdroidO->pistonMoveDir[i] = FLIP_NONE;
470
DrillerdroidO->pistonDelay[i] = 10;
471
}
472
}
473
else {
474
DrillerdroidO->pistonPos[i] += 0x40000;
475
if (DrillerdroidO->pistonPos[i] == 0x100000)
476
DrillerdroidO->pistonMoveDir[i] = FLIP_X;
477
}
478
479
if (DrillerdroidO->drillDelay[i]) {
480
DrillerdroidO->drillDelay[i]--;
481
}
482
else if (DrillerdroidO->drillMoveDir[i]) {
483
DrillerdroidO->drillPos[i] -= 0x40000;
484
if (!DrillerdroidO->drillPos[i]) {
485
DrillerdroidO->drillMoveDir[i] = FLIP_NONE;
486
DrillerdroidO->drillDelay[i] = 5;
487
}
488
}
489
else {
490
DrillerdroidO->drillPos[i] += 0x80000;
491
if (DrillerdroidO->drillPos[i] == 0x100000)
492
DrillerdroidO->drillMoveDir[i] = FLIP_X;
493
}
494
}
495
496
if (!DrillerdroidO->canBreakSegment) {
497
if (DrillerdroidO->drillPos[0] == 0x80000) {
498
DrillerdroidO_SpawnDebris(-0x300000);
499
DrillerdroidO_SpawnDebris(0x300000);
500
}
501
else if (DrillerdroidO->drillPos[1] == 0x80000) {
502
DrillerdroidO_SpawnDebris(-0x190000);
503
DrillerdroidO_SpawnDebris(0x190000);
504
}
505
}
506
507
EntityCamera *camera = RSDK_GET_ENTITY(SLOT_CAMERA1, Camera);
508
if (!camera->shakePos.y)
509
camera->shakePos.y = 4;
510
511
self->position.y ^= 0x10000;
512
DrillerdroidO_CheckPlayerCollisions();
513
514
if (DrillerdroidO->canBreakSegment && self->timer < 180) {
515
if (self->alpha < 0x200)
516
self->alpha += 4;
517
}
518
519
if (--self->timer <= 0)
520
self->state = DrillerdroidO_State_FinishDrilling;
521
}
522
523
void DrillerdroidO_State_FinishDrilling(void)
524
{
525
RSDK_THIS(DrillerdroidO);
526
527
DrillerdroidO->pistonPos[0] -= 0x20000;
528
if (DrillerdroidO->pistonPos[0] < 0)
529
DrillerdroidO->pistonPos[0] = 0;
530
531
DrillerdroidO->pistonPos[1] -= 0x20000;
532
if (DrillerdroidO->pistonPos[1] < 0)
533
DrillerdroidO->pistonPos[1] = 0;
534
535
DrillerdroidO->drillPos[0] -= 0x20000;
536
if (DrillerdroidO->drillPos[0] < 0)
537
DrillerdroidO->drillPos[0] = 0;
538
539
DrillerdroidO->drillPos[1] -= 0x20000;
540
if (DrillerdroidO->drillPos[1] < 0)
541
DrillerdroidO->drillPos[1] = 0;
542
543
if (!DrillerdroidO->pistonPos[0] && !DrillerdroidO->pistonPos[1] && !DrillerdroidO->drillPos[0] && !DrillerdroidO->drillPos[1]) {
544
self->timer = 60;
545
self->state = DrillerdroidO_State_Overheat;
546
}
547
}
548
549
void DrillerdroidO_State_Overheat(void)
550
{
551
RSDK_THIS(DrillerdroidO);
552
553
if (--self->timer <= 0) {
554
if (DrillerdroidO->canBreakSegment) {
555
DrillerdroidO->canBreakSegment = false;
556
RSDK.PlaySfx(DrillerdroidO->sfxSizzle, false, 255);
557
self->state = DrillerdroidO_State_OverheatRecoil_DestroyedSegment;
558
}
559
else {
560
self->state = DrillerdroidO_State_OverheatRecoil;
561
}
562
}
563
564
DrillerdroidO_CheckPlayerCollisions();
565
}
566
567
void DrillerdroidO_State_OverheatRecoil(void)
568
{
569
RSDK_THIS(DrillerdroidO);
570
571
DrillerdroidO->drillPos[0] += 0x10000;
572
DrillerdroidO->drillPos[1] += 0x10000;
573
574
self->position.y -= 0x10000;
575
576
DrillerdroidO_CheckPlayerCollisions();
577
578
if (DrillerdroidO->drillPos[0] == 0x100000) {
579
self->timer = 30;
580
self->state = DrillerdroidO_State_JumpTargetDelay;
581
}
582
}
583
584
void DrillerdroidO_State_JumpTargetDelay(void)
585
{
586
RSDK_THIS(DrillerdroidO);
587
588
DrillerdroidO_CheckPlayerCollisions();
589
590
if (--self->timer <= 0) {
591
self->velocity.y = 0x78000;
592
RSDK.PlaySfx(DrillerdroidO->sfxJump, false, 0xFF);
593
self->state = DrillerdroidO_State_PrepareJumpTarget;
594
}
595
}
596
597
void DrillerdroidO_State_PrepareJumpTarget(void)
598
{
599
RSDK_THIS(DrillerdroidO);
600
601
self->position.y += self->velocity.y;
602
self->velocity.y -= 0x1C000;
603
604
DrillerdroidO->drillPos[0] = self->startY - self->position.y;
605
DrillerdroidO->drillPos[1] = self->startY - self->position.y;
606
607
if (self->velocity.y < 0) {
608
if (DrillerdroidO->drillPos[0] >= 0x100000) {
609
DrillerdroidO->drillPos[0] = 0x100000;
610
DrillerdroidO->drillPos[1] = 0x100000;
611
612
self->state = DrillerdroidO_State_JumpTargeting;
613
}
614
}
615
}
616
617
void DrillerdroidO_State_JumpTargeting(void)
618
{
619
RSDK_THIS(DrillerdroidO);
620
621
self->position.y += self->velocity.y;
622
self->velocity.y += 0x3800;
623
624
if (self->velocity.y >= 0) {
625
DrillerdroidO->drillDelay[0] = 4;
626
DrillerdroidO->pistonDelay[0] = 4;
627
628
DrillerdroidO->drillDelay[1] = 0;
629
DrillerdroidO->pistonDelay[1] = 0;
630
631
DrillerdroidO->drillPos[0] = 0x100000;
632
DrillerdroidO->drillPos[1] = 0x100000;
633
634
DrillerdroidO->pistonPos[0] = 0;
635
DrillerdroidO->pistonPos[1] = 0;
636
637
DrillerdroidO->pistonMoveDir[0] = FLIP_NONE;
638
DrillerdroidO->pistonMoveDir[1] = FLIP_NONE;
639
640
DrillerdroidO->drillMoveDir[0] = FLIP_NONE;
641
DrillerdroidO->drillMoveDir[1] = FLIP_NONE;
642
643
self->position.x = 0;
644
645
if (self->health <= DrillerdroidO->currentLevel && DrillerdroidO->currentLevel) {
646
self->timer = 90;
647
DrillerdroidO->emitFireballs = false;
648
self->state = DrillerdroidO_State_DestroyRockPiles;
649
}
650
else {
651
EntityPlayer *player1 = RSDK_GET_ENTITY(SLOT_PLAYER1, Player);
652
CREATE_ENTITY(DrillerdroidO, INT_TO_VOID(DRILLERDROIDO_TARGET), player1->position.x, player1->position.y)->target = player1;
653
654
RSDK.PlaySfx(DrillerdroidO->sfxTargeting, false, 255);
655
self->state = DrillerdroidO_State_DecidingDropPos;
656
}
657
}
658
}
659
660
void DrillerdroidO_State_DestroyRockPiles(void)
661
{
662
RSDK_THIS(DrillerdroidO);
663
664
if (--self->timer <= 60) {
665
++DrillerdroidO->drillSfxTimer;
666
667
EntityCamera *camera = RSDK_GET_ENTITY(SLOT_CAMERA1, Camera);
668
if (!camera->shakePos.y)
669
camera->shakePos.y = 4;
670
}
671
672
if (self->timer <= 0) {
673
DrillerdroidO->currentLevel -= 2;
674
675
for (int32 i = 0; i < 4; ++i) {
676
EntityLRZRockPile *pile = RSDK_GET_ENTITY(DrillerdroidO->childSlotStart++, LRZRockPile);
677
pile->timer = 1;
678
pile->canCollapse = true;
679
}
680
681
self->timer = 30;
682
self->state = DrillerdroidO_State_NextLevelDelay;
683
}
684
}
685
686
void DrillerdroidO_State_NextLevelDelay(void)
687
{
688
RSDK_THIS(DrillerdroidO);
689
690
if (--self->timer <= 0) {
691
self->position.y += 0x1000000;
692
Zone->cameraBoundsB[0] += 256;
693
self->state = DrillerdroidO_State_MoveToNextLevel;
694
}
695
}
696
697
void DrillerdroidO_State_MoveToNextLevel(void)
698
{
699
RSDK_THIS(DrillerdroidO);
700
701
Zone->cameraBoundsT[0] = ScreenInfo->position.y;
702
703
if (Zone->cameraBoundsT[0] == Zone->cameraBoundsB[0] - SCREEN_YSIZE) {
704
EntityPlayer *player1 = RSDK_GET_ENTITY(SLOT_PLAYER1, Player);
705
CREATE_ENTITY(DrillerdroidO, INT_TO_VOID(DRILLERDROIDO_TARGET), player1->position.x, player1->position.y)->target = player1;
706
707
RSDK.PlaySfx(DrillerdroidO->sfxTargeting, false, 255);
708
DrillerdroidO->emitFireballs = true;
709
self->state = DrillerdroidO_State_DecidingDropPos;
710
}
711
}
712
713
void DrillerdroidO_State_DecidingDropPos(void)
714
{
715
RSDK_THIS(DrillerdroidO);
716
717
if (self->position.x) {
718
self->timer = 240;
719
self->state = DrillerdroidO_State_Dropping;
720
721
foreach_active(DrillerdroidO, fireballEmitter)
722
{
723
if (fireballEmitter->type == DRILLERDROIDO_FIREBALLEMITTER && self->position.y < fireballEmitter->position.y) {
724
if (RSDK.CheckObjectCollisionTouchBox(fireballEmitter, &DrillerdroidO->hitboxEmitterRange, self,
725
&DrillerdroidO->hitboxLandPosSegmentBreak)) {
726
self->position.x = fireballEmitter->position.x;
727
DrillerdroidO->canBreakSegment = true;
728
foreach_break;
729
}
730
}
731
}
732
733
foreach_active(DrillerdroidO, emitter)
734
{
735
if (emitter->type == DRILLERDROIDO_FIREBALLEMITTER && self->position.y < emitter->position.y) {
736
if (RSDK.CheckObjectCollisionTouchBox(emitter, &DrillerdroidO->hitboxEmitterRange, self, &DrillerdroidO->hitboxLandPosR)) {
737
self->position.x = emitter->position.x + 0x550000;
738
foreach_break;
739
}
740
741
if (RSDK.CheckObjectCollisionTouchBox(emitter, &DrillerdroidO->hitboxEmitterRange, self, &DrillerdroidO->hitboxLandPosL)) {
742
self->position.x = emitter->position.x - 0x550000;
743
foreach_break;
744
}
745
}
746
}
747
}
748
}
749
750
void DrillerdroidO_State_OverheatRecoil_DestroyedSegment(void)
751
{
752
RSDK_THIS(DrillerdroidO);
753
754
++self->rotation;
755
756
DrillerdroidO->drillPos[0] += 0x4000;
757
DrillerdroidO->drillPos[1] += 0x4000;
758
759
DrillerdroidO->pistonPos[0] += 0x4000;
760
DrillerdroidO->pistonPos[1] += 0x4000;
761
762
self->position.y -= 0x4000;
763
764
DrillerdroidO_CheckPlayerCollisions();
765
766
if (DrillerdroidO->drillPos[0] == 0x100000) {
767
self->timer = 90;
768
self->state = DrillerdroidO_State_Cooldown;
769
}
770
}
771
772
void DrillerdroidO_State_Cooldown(void)
773
{
774
RSDK_THIS(DrillerdroidO);
775
776
DrillerdroidO_CheckPlayerCollisions();
777
778
self->alpha -= 6;
779
if (self->alpha < 0)
780
self->alpha = 0;
781
782
if (--self->timer <= 0)
783
self->state = DrillerdroidO_State_ResetFromCooldown;
784
}
785
786
void DrillerdroidO_State_ResetFromCooldown(void)
787
{
788
RSDK_THIS(DrillerdroidO);
789
790
self->rotation -= 4;
791
792
DrillerdroidO->pistonPos[0] -= 0x10000;
793
DrillerdroidO->pistonPos[1] -= 0x10000;
794
795
DrillerdroidO_CheckPlayerCollisions();
796
797
if (!DrillerdroidO->pistonPos[0]) {
798
self->timer = 60;
799
self->state = DrillerdroidO_State_JumpTargetDelay;
800
}
801
}
802
803
void DrillerdroidO_State_Destroyed(void)
804
{
805
RSDK_THIS(DrillerdroidO);
806
807
DrillerdroidO_Explode();
808
809
if (!--self->invincibilityTimer) {
810
EntityDebris *debris = CREATE_ENTITY(Debris, Debris_State_FallAndFlicker, self->position.x - 0x300000, self->position.y);
811
RSDK.SetSpriteAnimation(DrillerdroidO->aniFrames, 0, &debris->animator, true, 1);
812
debris->velocity.x = RSDK.Rand(-4, 4) << 15;
813
debris->velocity.y = RSDK.Rand(-8, -4) << 15;
814
debris->gravityStrength = 0x3800;
815
debris->drawGroup = Zone->objectDrawGroup[1];
816
debris->updateRange.x = 0x400000;
817
debris->updateRange.y = 0x400000;
818
819
debris = CREATE_ENTITY(Debris, Debris_State_FallAndFlicker, self->position.x - 0x300000, self->position.y);
820
RSDK.SetSpriteAnimation(DrillerdroidO->aniFrames, 0, &debris->animator, true, 2);
821
debris->velocity.x = RSDK.Rand(-4, 4) << 15;
822
debris->velocity.y = RSDK.Rand(0, 2) << 15;
823
debris->gravityStrength = 0x3800;
824
debris->drawGroup = Zone->objectDrawGroup[1];
825
debris->updateRange.x = 0x400000;
826
debris->updateRange.y = 0x400000;
827
828
debris = CREATE_ENTITY(Debris, Debris_State_FallAndFlicker, self->position.x - 0x230000, self->position.y);
829
RSDK.SetSpriteAnimation(DrillerdroidO->aniFrames, 0, &debris->animator, true, 1);
830
debris->velocity.x = RSDK.Rand(-4, 4) << 15;
831
debris->velocity.y = RSDK.Rand(-8, -4) << 15;
832
debris->gravityStrength = 0x3800;
833
debris->drawGroup = Zone->objectDrawGroup[1];
834
debris->updateRange.x = 0x400000;
835
debris->updateRange.y = 0x400000;
836
837
debris = CREATE_ENTITY(Debris, Debris_State_FallAndFlicker, self->position.x - 0x230000, self->position.y);
838
RSDK.SetSpriteAnimation(DrillerdroidO->aniFrames, 0, &debris->animator, true, 2);
839
debris->velocity.x = RSDK.Rand(-4, 4) << 15;
840
debris->velocity.y = RSDK.Rand(0, 2) << 15;
841
debris->gravityStrength = 0x3800;
842
debris->drawGroup = Zone->objectDrawGroup[1];
843
debris->updateRange.x = 0x400000;
844
debris->updateRange.y = 0x400000;
845
846
debris = CREATE_ENTITY(Debris, Debris_State_FallAndFlicker, self->position.x + 0x300000, self->position.y);
847
RSDK.SetSpriteAnimation(DrillerdroidO->aniFrames, 0, &debris->animator, true, 1);
848
debris->velocity.x = RSDK.Rand(-4, 4) << 15;
849
debris->velocity.y = RSDK.Rand(-8, -4) << 15;
850
debris->gravityStrength = 0x3800;
851
debris->drawGroup = Zone->objectDrawGroup[1];
852
debris->updateRange.x = 0x400000;
853
debris->updateRange.y = 0x400000;
854
855
debris = CREATE_ENTITY(Debris, Debris_State_FallAndFlicker, self->position.x + 0x300000, self->position.y);
856
RSDK.SetSpriteAnimation(DrillerdroidO->aniFrames, 0, &debris->animator, true, 2);
857
debris->velocity.x = RSDK.Rand(-4, 4) << 15;
858
debris->velocity.y = RSDK.Rand(0, 2) << 15;
859
debris->gravityStrength = 0x3800;
860
debris->drawGroup = Zone->objectDrawGroup[1];
861
debris->updateRange.x = 0x400000;
862
debris->updateRange.y = 0x400000;
863
864
debris = CREATE_ENTITY(Debris, Debris_State_FallAndFlicker, self->position.x + 0x230000, self->position.y);
865
RSDK.SetSpriteAnimation(DrillerdroidO->aniFrames, 0, &debris->animator, true, 1);
866
debris->velocity.x = RSDK.Rand(-4, 4) << 15;
867
debris->velocity.y = RSDK.Rand(-8, -4) << 15;
868
debris->gravityStrength = 0x3800;
869
debris->drawGroup = Zone->objectDrawGroup[1];
870
debris->updateRange.x = 0x400000;
871
debris->updateRange.y = 0x400000;
872
873
debris = CREATE_ENTITY(Debris, Debris_State_FallAndFlicker, self->position.x + 0x230000, self->position.y);
874
RSDK.SetSpriteAnimation(DrillerdroidO->aniFrames, 0, &debris->animator, true, 2);
875
debris->velocity.x = RSDK.Rand(-4, 4) << 15;
876
debris->velocity.y = RSDK.Rand(0, 2) << 15;
877
debris->gravityStrength = 0x3800;
878
debris->drawGroup = Zone->objectDrawGroup[1];
879
debris->updateRange.x = 0x400000;
880
debris->updateRange.y = 0x400000;
881
882
debris = CREATE_ENTITY(Debris, Debris_State_FallAndFlicker, self->position.x, self->position.y);
883
RSDK.SetSpriteAnimation(DrillerdroidO->aniFrames, 0, &debris->animator, true, 3);
884
debris->velocity.x = RSDK.Rand(-4, 4) << 15;
885
debris->velocity.y = RSDK.Rand(-8, -4) << 15;
886
debris->gravityStrength = 0x3800;
887
debris->drawGroup = Zone->objectDrawGroup[1];
888
debris->updateRange.x = 0x400000;
889
debris->updateRange.y = 0x400000;
890
891
debris = CREATE_ENTITY(Debris, Debris_State_FallAndFlicker, self->position.x, self->position.y);
892
RSDK.SetSpriteAnimation(DrillerdroidO->aniFrames, 0, &debris->animator, true, 5);
893
debris->velocity.x = RSDK.Rand(-4, 4) << 15;
894
debris->velocity.y = RSDK.Rand(-8, -4) << 15;
895
debris->gravityStrength = 0x3800;
896
debris->drawGroup = Zone->objectDrawGroup[1];
897
debris->updateRange.x = 0x400000;
898
debris->updateRange.y = 0x400000;
899
900
self->velocity.x = RSDK.Rand(-4, 4) << 15;
901
self->velocity.y = (RSDK.Rand(-8, -4) << 15);
902
self->mainAnimator.frameID = 4;
903
self->stateDraw = DrillerdroidO_Draw_Simple;
904
self->state = DrillerdroidO_State_Finish;
905
}
906
}
907
908
void DrillerdroidO_State_Finish(void)
909
{
910
RSDK_THIS(DrillerdroidO);
911
912
self->position.x += self->velocity.x;
913
self->position.y += self->velocity.y;
914
self->velocity.y += 0x3800;
915
916
self->visible ^= true;
917
918
DrillerdroidO_Explode();
919
920
if (!RSDK.CheckOnScreen(self, NULL)) {
921
Zone->cameraBoundsR[0] += WIDE_SCR_XSIZE;
922
destroyEntity(self);
923
}
924
}
925
926
void DrillerdroidO_Draw_Boss(void)
927
{
928
RSDK_THIS(DrillerdroidO);
929
930
RSDK.SetLimitedFade(0, 1, 2, self->alpha, 32, 41);
931
932
if (self->invincibilityTimer & 1) {
933
RSDK.SetPaletteEntry(0, 32, 0xE0E0E0);
934
RSDK.SetPaletteEntry(0, 128, 0xE0E0E0);
935
}
936
937
// Piston (L1)
938
self->mainAnimator.frameID = 1;
939
Vector2 drawPos;
940
drawPos.x = self->position.x - 0x300000;
941
drawPos.y = self->position.y - DrillerdroidO->pistonPos[0];
942
RSDK.DrawSprite(&self->mainAnimator, &drawPos, false);
943
944
// Drill (L1)
945
self->mainAnimator.frameID = 2;
946
drawPos.y = self->position.y + DrillerdroidO->drillPos[0];
947
RSDK.DrawSprite(&self->mainAnimator, &drawPos, false);
948
949
// Piston (L2)
950
self->mainAnimator.frameID = 1;
951
drawPos.x += 0xD0000;
952
drawPos.y = self->position.y - DrillerdroidO->pistonPos[1];
953
RSDK.DrawSprite(&self->mainAnimator, &drawPos, false);
954
955
// Drill (L2)
956
self->mainAnimator.frameID = 2;
957
drawPos.y = self->position.y + DrillerdroidO->drillPos[1];
958
RSDK.DrawSprite(&self->mainAnimator, &drawPos, false);
959
960
// Piston (R1)
961
self->mainAnimator.frameID = 1;
962
drawPos.x += 0x530000;
963
drawPos.y = self->position.y - DrillerdroidO->pistonPos[0];
964
RSDK.DrawSprite(&self->mainAnimator, &drawPos, false);
965
966
// Drill (R1)
967
self->mainAnimator.frameID = 2;
968
drawPos.y = self->position.y + DrillerdroidO->drillPos[0];
969
RSDK.DrawSprite(&self->mainAnimator, &drawPos, false);
970
971
// Piston (R2)
972
self->mainAnimator.frameID = 1;
973
drawPos.x -= 0xD0000;
974
drawPos.y = self->position.y - DrillerdroidO->pistonPos[1];
975
RSDK.DrawSprite(&self->mainAnimator, &drawPos, false);
976
977
// Drill (R2)
978
self->mainAnimator.frameID = 2;
979
drawPos.y = self->position.y + DrillerdroidO->drillPos[1];
980
RSDK.DrawSprite(&self->mainAnimator, &drawPos, false);
981
982
// Main Body
983
self->mainAnimator.frameID = 0;
984
RSDK.DrawSprite(&self->mainAnimator, NULL, false);
985
986
self->drawFX |= FX_ROTATE;
987
988
// Core Armor (L)
989
drawPos.x = self->position.x + 0x10000;
990
drawPos.y = self->position.y - 0x140000;
991
self->armorAnimator.frameID = 0;
992
RSDK.DrawSprite(&self->armorAnimator, &drawPos, false);
993
994
// Core Armor (R)
995
self->armorAnimator.frameID = 1;
996
self->rotation = 0x200 - self->rotation;
997
RSDK.DrawSprite(&self->armorAnimator, &drawPos, false);
998
999
self->rotation = 0x200 - self->rotation;
1000
self->drawFX = FX_NONE;
1001
1002
RSDK.CopyPalette(1, 32, 0, 32, 10);
1003
1004
RSDK.SetPaletteEntry(0, 32, 0x282028);
1005
RSDK.SetPaletteEntry(0, 128, 0x000000);
1006
}
1007
1008
void DrillerdroidO_Draw_Simple(void)
1009
{
1010
RSDK_THIS(DrillerdroidO);
1011
1012
RSDK.DrawSprite(&self->mainAnimator, NULL, false);
1013
}
1014
1015
void DrillerdroidO_State_Target(void)
1016
{
1017
RSDK_THIS(DrillerdroidO);
1018
1019
RSDK.ProcessAnimation(&self->armorAnimator);
1020
RSDK.ProcessAnimation(&self->targetLockAnimator);
1021
1022
if (self->target) {
1023
self->position.x = self->target->position.x;
1024
self->position.y = self->target->position.y;
1025
}
1026
1027
self->alpha += 0x20;
1028
1029
self->targetEdgeOffset.x -= 0x20000;
1030
if (self->targetEdgeOffset.x <= 0xC0000) {
1031
self->alpha = 0;
1032
self->targetEdgeOffset.x = 0x2C0000;
1033
}
1034
1035
self->targetEdgeOffset.y = self->targetEdgeOffset.x;
1036
if (++self->timer == 60)
1037
RSDK.SetSpriteAnimation(Drillerdroid->aniFrames, 4, &self->targetLockAnimator, true, 0);
1038
1039
if (self->timer == 96) {
1040
self->target = NULL;
1041
DrillerdroidO->boss->position.x = self->position.x;
1042
1043
if (self->position.x < (Zone->cameraBoundsL[0] + 64) << 16 || self->position.x > (Zone->cameraBoundsR[0] - 64) << 16)
1044
DrillerdroidO->boss->position.x = (Zone->cameraBoundsL[0] + 64) << 16;
1045
else if (self->position.x > (Zone->cameraBoundsR[0] - 64) << 16)
1046
DrillerdroidO->boss->position.x = (Zone->cameraBoundsR[0] - 64) << 16;
1047
}
1048
1049
if (self->timer == 128)
1050
destroyEntity(self);
1051
}
1052
1053
void DrillerdroidO_Draw_Target(void)
1054
{
1055
RSDK_THIS(DrillerdroidO);
1056
1057
// Top-Left Edge
1058
self->mainAnimator.frameID = 0;
1059
self->inkEffect = INK_ALPHA;
1060
self->direction = FLIP_NONE;
1061
Vector2 drawPos;
1062
drawPos.x = self->position.x - self->targetEdgeOffset.x;
1063
drawPos.y = self->position.y - self->targetEdgeOffset.y;
1064
RSDK.DrawSprite(&self->mainAnimator, &drawPos, false);
1065
1066
// Top-Right Edge
1067
self->direction = FLIP_X;
1068
drawPos.x = self->position.x + self->targetEdgeOffset.x;
1069
drawPos.y = self->position.y - self->targetEdgeOffset.y;
1070
RSDK.DrawSprite(&self->mainAnimator, &drawPos, false);
1071
1072
// Bottom-Left Edge
1073
self->mainAnimator.frameID = 1;
1074
self->direction = FLIP_NONE;
1075
drawPos.x = self->position.x - self->targetEdgeOffset.x;
1076
drawPos.y = self->position.y + self->targetEdgeOffset.y;
1077
RSDK.DrawSprite(&self->mainAnimator, &drawPos, false);
1078
1079
// Bottom-Right Edge
1080
self->direction = FLIP_X;
1081
drawPos.x = self->position.x + self->targetEdgeOffset.x;
1082
drawPos.y = self->position.y + self->targetEdgeOffset.y;
1083
RSDK.DrawSprite(&self->mainAnimator, &drawPos, false);
1084
1085
// Target Reticle
1086
self->inkEffect = INK_NONE;
1087
self->direction = FLIP_NONE;
1088
RSDK.DrawSprite(&self->armorAnimator, NULL, false);
1089
RSDK.DrawSprite(&self->targetLockAnimator, NULL, false);
1090
}
1091
1092
void DrillerdroidO_State_FireballEmitter(void)
1093
{
1094
RSDK_THIS(DrillerdroidO);
1095
1096
bool32 collided = true;
1097
foreach_active(DrillerdroidO, drillerdroid)
1098
{
1099
if (drillerdroid->type == DRILLERDROIDO_MAIN
1100
&& RSDK.CheckObjectCollisionTouchBox(drillerdroid, &DrillerdroidO->hitboxLandPosSegmentBreak, self, &DrillerdroidO->hitboxEmitterRange)) {
1101
collided = false;
1102
foreach_break;
1103
}
1104
}
1105
1106
if (collided && DrillerdroidO->emitFireballs) {
1107
if (!(Zone->timer & 0x3F)) {
1108
EntityLRZFireball *fireball =
1109
CREATE_ENTITY(LRZFireball, LRZFireball_StateFireball_LauncherGravity, self->position.x, self->position.y + 0x940000);
1110
fireball->angle = 0xEE;
1111
fireball->rotation = 0xEE;
1112
fireball->groundVel = -0x300;
1113
fireball->velocity.x = fireball->groundVel * RSDK.Sin512(0x12);
1114
fireball->velocity.y = fireball->groundVel * RSDK.Cos512(0x100 - fireball->angle);
1115
1116
fireball = CREATE_ENTITY(LRZFireball, LRZFireball_StateFireball_LauncherGravity, self->position.x, self->position.y + 0x940000);
1117
fireball->angle = 0x116;
1118
fireball->rotation = 0x116;
1119
fireball->groundVel = -0x300;
1120
fireball->velocity.x = fireball->groundVel * RSDK.Sin512(-0x16);
1121
fireball->velocity.y = fireball->groundVel * RSDK.Cos512(0x100 - fireball->angle);
1122
RSDK.PlaySfx(LRZFireball->sfxFireball, false, 0xFF);
1123
}
1124
}
1125
}
1126
1127
void DrillerdroidO_Draw_FireballEmitter(void)
1128
{ /* Yeah :) */
1129
}
1130
1131
#if GAME_INCLUDE_EDITOR
1132
void DrillerdroidO_EditorDraw(void)
1133
{
1134
RSDK_THIS(DrillerdroidO);
1135
1136
DrillerdroidO->drillDelay[0] = 4;
1137
DrillerdroidO->pistonDelay[0] = 4;
1138
1139
DrillerdroidO->drillDelay[1] = 0;
1140
DrillerdroidO->pistonDelay[1] = 0;
1141
1142
DrillerdroidO->drillPos[0] = 0x100000;
1143
DrillerdroidO->drillPos[1] = 0x100000;
1144
1145
DrillerdroidO->pistonPos[0] = 0;
1146
DrillerdroidO->pistonPos[1] = 0;
1147
1148
DrillerdroidO->drillMoveDir[0] = FLIP_NONE;
1149
DrillerdroidO->drillMoveDir[1] = FLIP_NONE;
1150
1151
DrillerdroidO->pistonMoveDir[0] = FLIP_NONE;
1152
DrillerdroidO->pistonMoveDir[1] = FLIP_NONE;
1153
1154
DrillerdroidO->childSlotStart = SceneInfo->entitySlot + 2;
1155
1156
switch (self->type) {
1157
case DRILLERDROIDO_MAIN:
1158
RSDK.SetSpriteAnimation(DrillerdroidO->aniFrames, 0, &self->mainAnimator, true, 0);
1159
RSDK.SetSpriteAnimation(DrillerdroidO->aniFrames, 5, &self->armorAnimator, true, 0);
1160
DrillerdroidO_Draw_Boss();
1161
1162
if (showGizmos()) {
1163
RSDK_DRAWING_OVERLAY(true);
1164
1165
// Note: its actually centerX offset on left/right but mania is usually always at 424 width anyways so its pretty much the same
1166
DrawHelpers_DrawArenaBounds(-WIDE_SCR_XCENTER, -SCREEN_YSIZE, WIDE_SCR_XCENTER, 96, 1 | 2 | 4 | 8, 0x00C0F0);
1167
1168
if (LRZRockPile) {
1169
for (int32 i = 0; i < 9; ++i) {
1170
EntityLRZRockPile *pile = RSDK_GET_ENTITY(DrillerdroidO->childSlotStart++, LRZRockPile);
1171
1172
if (pile && pile->classID == LRZRockPile->classID)
1173
DrawHelpers_DrawArrow(self->position.x, self->position.y, pile->position.x, pile->position.y, 0xFFFF00, INK_NONE, 0xFF);
1174
}
1175
}
1176
1177
RSDK_DRAWING_OVERLAY(false);
1178
}
1179
break;
1180
1181
case DRILLERDROIDO_FIREBALLEMITTER:
1182
RSDK.SetSpriteAnimation(DrillerdroidO->ticFrames, 0, &self->mainAnimator, true, 0);
1183
RSDK.SetSpriteAnimation(-1, 3, &self->armorAnimator, true, 0);
1184
1185
DrawHelpers_DrawRectOutline(self->position.x, self->position.y + (0xC0 << 15), 0x40 << 16, 0xC0 << 16, 0xFFFF00);
1186
break;
1187
1188
default: break;
1189
}
1190
}
1191
1192
void DrillerdroidO_EditorLoad(void)
1193
{
1194
DrillerdroidO->aniFrames = RSDK.LoadSpriteAnimation("LRZ1/Drillerdroid.bin", SCOPE_STAGE);
1195
DrillerdroidO->ticFrames = RSDK.LoadSpriteAnimation("Global/TicMark.bin", SCOPE_STAGE);
1196
1197
RSDK_ACTIVE_VAR(DrillerdroidO, type);
1198
RSDK_ENUM_VAR("Drillerdroid", DRILLERDROIDO_MAIN);
1199
RSDK_ENUM_VAR("Fireball Emitter", DRILLERDROIDO_FIREBALLEMITTER);
1200
}
1201
#endif
1202
1203
void DrillerdroidO_Serialize(void) { RSDK_EDITABLE_VAR(DrillerdroidO, VAR_UINT8, type); }
1204
1205