Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rubberduckycooly
GitHub Repository: rubberduckycooly/Sonic-Mania-Decompilation
Path: blob/master/SonicMania/Objects/LRZ/Drillerdroid.c
338 views
1
// ---------------------------------------------------------------------
2
// RSDK Project: Sonic Mania
3
// Object Description: Drillerdroid Object
4
// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges
5
// Decompiled by: Rubberduckycooly & RMGRich
6
// ---------------------------------------------------------------------
7
8
#include "Game.h"
9
10
ObjectDrillerdroid *Drillerdroid;
11
12
void Drillerdroid_Update(void)
13
{
14
RSDK_THIS(Drillerdroid);
15
16
StateMachine_Run(self->state);
17
}
18
19
void Drillerdroid_LateUpdate(void) {}
20
21
void Drillerdroid_StaticUpdate(void)
22
{
23
if (Drillerdroid->drillSfxTimer) {
24
if (!Drillerdroid->playingDrillSfx) {
25
RSDK.PlaySfx(Drillerdroid->sfxDrill, 43643, 0xFF);
26
Drillerdroid->playingDrillSfx = true;
27
}
28
29
Drillerdroid->drillSfxTimer = 0;
30
}
31
else if (Drillerdroid->playingDrillSfx) {
32
RSDK.StopSfx(Drillerdroid->sfxDrill);
33
Drillerdroid->playingDrillSfx = false;
34
}
35
}
36
37
void Drillerdroid_Draw(void)
38
{
39
RSDK_THIS(Drillerdroid);
40
41
StateMachine_Run(self->stateDraw);
42
}
43
44
void Drillerdroid_Create(void *data)
45
{
46
RSDK_THIS(Drillerdroid);
47
48
if (!SceneInfo->inEditor) {
49
if (globals->gameMode < MODE_TIMEATTACK) {
50
self->visible = true;
51
if (data)
52
self->type = VOID_TO_INT(data);
53
54
switch (self->type) {
55
case DRILLERDROID_MAIN:
56
self->active = ACTIVE_BOUNDS;
57
self->updateRange.x = 0x800000;
58
self->updateRange.y = 0x800000;
59
RSDK.SetSpriteAnimation(Drillerdroid->aniFrames, 0, &self->mainAnimator, true, 0);
60
RSDK.SetSpriteAnimation(Drillerdroid->aniFrames, 5, &self->armorAnimator, true, 0);
61
self->drawGroup = Zone->objectDrawGroup[1];
62
Drillerdroid->boss = self;
63
self->state = Drillerdroid_State_SetupArena;
64
self->stateDraw = Drillerdroid_Draw_Boss;
65
break;
66
67
case DRILLERDROID_TARGET:
68
case DRILLERDROID_UNUSED:
69
self->active = ACTIVE_NORMAL;
70
self->drawFX = FX_FLIP;
71
self->updateRange.x = 0x800000;
72
self->updateRange.y = 0x800000;
73
RSDK.SetSpriteAnimation(Drillerdroid->aniFrames, 2, &self->mainAnimator, true, 0);
74
RSDK.SetSpriteAnimation(Drillerdroid->aniFrames, 3, &self->armorAnimator, true, 0);
75
self->drawGroup = Zone->objectDrawGroup[1];
76
self->state = Drillerdroid_State_Target;
77
self->stateDraw = Drillerdroid_Draw_Target;
78
break;
79
}
80
}
81
else {
82
destroyEntity(self);
83
}
84
}
85
}
86
87
void Drillerdroid_StageLoad(void)
88
{
89
if (RSDK.CheckSceneFolder("LRZ1"))
90
Drillerdroid->aniFrames = RSDK.LoadSpriteAnimation("LRZ1/Drillerdroid.bin", SCOPE_STAGE);
91
92
Drillerdroid->ticFrames = RSDK.LoadSpriteAnimation("Global/TicMark.bin", SCOPE_STAGE);
93
94
Drillerdroid->hitboxCore.left = -25;
95
Drillerdroid->hitboxCore.top = -16;
96
Drillerdroid->hitboxCore.right = 25;
97
Drillerdroid->hitboxCore.bottom = 16;
98
99
Drillerdroid->hitboxPistonL.left = -58;
100
Drillerdroid->hitboxPistonL.top = -74;
101
Drillerdroid->hitboxPistonL.right = -25;
102
Drillerdroid->hitboxPistonL.bottom = 16;
103
104
Drillerdroid->hitboxPistonR.left = 25;
105
Drillerdroid->hitboxPistonR.top = -74;
106
Drillerdroid->hitboxPistonR.right = 58;
107
Drillerdroid->hitboxPistonR.bottom = 16;
108
109
Drillerdroid->hitboxDrillL.left = -58;
110
Drillerdroid->hitboxDrillL.top = 16;
111
Drillerdroid->hitboxDrillL.right = -25;
112
Drillerdroid->hitboxDrillL.bottom = 53;
113
114
Drillerdroid->hitboxDrillR.left = 25;
115
Drillerdroid->hitboxDrillR.top = 16;
116
Drillerdroid->hitboxDrillR.right = 58;
117
Drillerdroid->hitboxDrillR.bottom = 53;
118
119
Drillerdroid->pistonPos[0] = 0;
120
Drillerdroid->pistonPos[1] = 0;
121
122
Drillerdroid->drillPos[0] = 0x100000;
123
Drillerdroid->drillPos[1] = 0x100000;
124
125
Drillerdroid->pistonDelay[0] = 4;
126
Drillerdroid->pistonDelay[1] = 0;
127
128
Drillerdroid->drillDelay[0] = 4;
129
Drillerdroid->drillDelay[1] = 0;
130
131
Drillerdroid->pistonMoveDir[0] = 0;
132
Drillerdroid->pistonMoveDir[1] = 0;
133
134
Drillerdroid->drillMoveDir[0] = 0;
135
Drillerdroid->drillMoveDir[1] = 0;
136
137
Drillerdroid->platformActive[0] = true;
138
Drillerdroid->platformActive[1] = true;
139
Drillerdroid->platformActive[2] = true;
140
Drillerdroid->platformActive[3] = true;
141
Drillerdroid->platformActive[4] = true;
142
143
Drillerdroid->active = ACTIVE_ALWAYS;
144
145
Drillerdroid->drillSfxTimer = 0;
146
Drillerdroid->playingDrillSfx = false;
147
148
Drillerdroid->armorHealth = 3;
149
Drillerdroid->jumpsRemaining = 0;
150
151
Drillerdroid->sfxHit = RSDK.GetSfx("Stage/BossHit.wav");
152
Drillerdroid->sfxExplosion = RSDK.GetSfx("Stage/Explosion2.wav");
153
Drillerdroid->sfxDrill = RSDK.GetSfx("LRZ/Drill.wav");
154
Drillerdroid->sfxImpact = RSDK.GetSfx("Stage/Impact4.wav");
155
Drillerdroid->sfxJump = RSDK.GetSfx("LRZ/DrillJump.wav");
156
Drillerdroid->sfxTargeting = RSDK.GetSfx("Stage/Targeting1.wav");
157
Drillerdroid->sfxSizzle = RSDK.GetSfx("LRZ/Sizzle.wav");
158
Drillerdroid->sfxDrop = RSDK.GetSfx("Stage/Drop.wav");
159
Drillerdroid->sfxFail = RSDK.GetSfx("Stage/Fail.wav");
160
Drillerdroid->sfxClang = RSDK.GetSfx("Stage/Clang2.wav");
161
}
162
163
void Drillerdroid_Hit(void)
164
{
165
RSDK_THIS(Drillerdroid);
166
167
if (--self->health > 0) {
168
RSDK.PlaySfx(Drillerdroid->sfxHit, false, 255);
169
self->invincibilityTimer = 45;
170
}
171
else {
172
SceneInfo->timeEnabled = false;
173
Player_GiveScore(RSDK_GET_ENTITY(SLOT_PLAYER1, Player), 1000);
174
self->invincibilityTimer = 60;
175
self->state = Drillerdroid_State_Destroyed;
176
}
177
}
178
179
void Drillerdroid_CheckPlayerCollisions(void)
180
{
181
RSDK_THIS(Drillerdroid);
182
183
if (self->invincibilityTimer) {
184
self->invincibilityTimer--;
185
}
186
else {
187
foreach_active(Player, player)
188
{
189
if (!self->invincibilityTimer) {
190
int32 playerID = RSDK.GetEntitySlot(player);
191
192
if (Drillerdroid->playerTimers[playerID]) {
193
Drillerdroid->playerTimers[playerID]--;
194
}
195
else if (Player_CheckBadnikTouch(player, self, &Drillerdroid->hitboxCore)) {
196
if (player->position.y < self->position.y) {
197
Player_Hurt(player, self);
198
}
199
else if (self->alpha > 0x80 && player->shield != SHIELD_FIRE && !player->blinkTimer && !player->invincibleTimer) {
200
Player_Hurt(player, self);
201
}
202
else if (Player_CheckBossHit(player, self)) {
203
if (Drillerdroid->armorHealth <= 1) {
204
Drillerdroid_Hit();
205
}
206
else {
207
RSDK.PlaySfx(Drillerdroid->sfxClang, false, 255);
208
Drillerdroid->playerTimers[playerID] = 15;
209
}
210
}
211
}
212
else {
213
if (Player_CheckBadnikTouch(player, self, &Drillerdroid->hitboxPistonL)
214
|| Player_CheckBadnikTouch(player, self, &Drillerdroid->hitboxPistonR)) {
215
if (self->alpha > 0x80 && player->shield != SHIELD_FIRE && !player->blinkTimer && !player->invincibleTimer) {
216
Player_Hurt(player, self);
217
}
218
else if (Player_CheckBossHit(player, self)) {
219
if (!Drillerdroid->armorHealth) {
220
Drillerdroid_Hit();
221
}
222
else {
223
RSDK.PlaySfx(Drillerdroid->sfxClang, false, 255);
224
Drillerdroid->playerTimers[playerID] = 15;
225
}
226
}
227
}
228
else if (Player_CheckCollisionTouch(player, self, &Drillerdroid->hitboxDrillL)
229
|| Player_CheckCollisionTouch(player, self, &Drillerdroid->hitboxDrillR)) {
230
Player_Hurt(player, self);
231
}
232
}
233
}
234
}
235
}
236
}
237
238
void Drillerdroid_Explode(void)
239
{
240
RSDK_THIS(Drillerdroid);
241
242
if (!(Zone->timer & 3)) {
243
RSDK.PlaySfx(Drillerdroid->sfxExplosion, false, 255);
244
245
if (!(Zone->timer & 3)) {
246
int32 x = self->position.x + (RSDK.Rand(-19, 20) << 16);
247
int32 y = self->position.y + (RSDK.Rand(-24, 25) << 16);
248
CREATE_ENTITY(Explosion, INT_TO_VOID((RSDK.Rand(0, 256) > 192) + EXPLOSION_BOSS), x, y)->drawGroup = Zone->objectDrawGroup[1] + 2;
249
}
250
}
251
}
252
253
void Drillerdroid_SpawnDebris(int32 offset)
254
{
255
RSDK_THIS(Drillerdroid);
256
257
EntityDebris *debris = CREATE_ENTITY(Debris, Debris_State_Fall, offset + self->position.x, self->position.y + 0x400000);
258
RSDK.SetSpriteAnimation(Drillerdroid->aniFrames, 1, &debris->animator, true, RSDK.Rand(0, 8));
259
debris->velocity.x = RSDK.Rand(0, 6) << 15;
260
debris->velocity.y = RSDK.Rand(-12, -8) << 15;
261
debris->gravityStrength = 0x3800;
262
debris->drawGroup = Zone->objectDrawGroup[0];
263
debris->updateRange.x = 0x400000;
264
debris->updateRange.y = 0x400000;
265
266
debris = CREATE_ENTITY(Debris, Debris_State_Fall, offset + self->position.x, self->position.y + 0x400000);
267
RSDK.SetSpriteAnimation(Drillerdroid->aniFrames, 1, &debris->animator, true, RSDK.Rand(0, 8));
268
debris->velocity.x = RSDK.Rand(-6, 0) << 15;
269
debris->velocity.y = RSDK.Rand(-12, -8) << 15;
270
debris->gravityStrength = 0x3800;
271
debris->drawGroup = Zone->objectDrawGroup[0];
272
debris->updateRange.x = 0x400000;
273
debris->updateRange.y = 0x400000;
274
}
275
276
void Drillerdroid_State_SetupArena(void)
277
{
278
RSDK_THIS(Drillerdroid);
279
280
if (++self->timer >= 2) {
281
self->timer = 0;
282
283
Zone->playerBoundActiveR[0] = true;
284
Zone->playerBoundActiveB[0] = true;
285
Zone->cameraBoundsR[0] = (self->position.x >> 16) + 324;
286
Zone->cameraBoundsB[0] = (self->position.y >> 16) + 96;
287
Zone->cameraBoundsT[0] = Zone->cameraBoundsB[0] - SCREEN_YSIZE;
288
289
self->startY = self->position.y;
290
self->active = ACTIVE_NORMAL;
291
self->position.y = (ScreenInfo->position.y - 192) << 16;
292
self->visible = true;
293
self->state = Drillerdroid_State_AwaitPlayer;
294
}
295
}
296
297
void Drillerdroid_State_AwaitPlayer(void)
298
{
299
RSDK_THIS(Drillerdroid);
300
301
EntityPlayer *player1 = RSDK_GET_ENTITY(SLOT_PLAYER1, Player);
302
303
Zone->playerBoundActiveL[0] = true;
304
Zone->cameraBoundsL[0] = ScreenInfo->position.x;
305
306
if (player1->position.x > self->position.x) {
307
Zone->playerBoundActiveL[0] = true;
308
Zone->cameraBoundsL[0] = (self->position.x >> 16) - 328;
309
310
Music_TransitionTrack(TRACK_MINIBOSS, 0.0125);
311
self->health = 6;
312
CREATE_ENTITY(Drillerdroid, INT_TO_VOID(DRILLERDROID_TARGET), self->position.x, self->startY)->target = player1;
313
self->position.x = 0;
314
RSDK.PlaySfx(Drillerdroid->sfxTargeting, false, 255);
315
self->state = Drillerdroid_State_DecidingDropPos;
316
}
317
}
318
319
void Drillerdroid_State_Dropping(void)
320
{
321
RSDK_THIS(Drillerdroid);
322
323
self->position.y += self->velocity.y;
324
self->velocity.y += 0x3800;
325
326
Drillerdroid_CheckPlayerCollisions();
327
328
if (self->position.y >= ((Zone->cameraBoundsB[0] - 112) << 16)) {
329
self->position.y = ((Zone->cameraBoundsB[0] - 112) << 16);
330
331
RSDK.PlaySfx(Drillerdroid->sfxImpact, false, 255);
332
Camera_ShakeScreen(0, 0, 4);
333
334
self->velocity.y >>= 1;
335
self->startY = self->position.y + 0x100000;
336
337
if (!Drillerdroid->canBreakSegment) {
338
for (int32 i = 0; i < 4; ++i) {
339
Drillerdroid_SpawnDebris(-0x300000);
340
Drillerdroid_SpawnDebris(0x300000);
341
Drillerdroid_SpawnDebris(-0x190000);
342
Drillerdroid_SpawnDebris(0x190000);
343
}
344
345
Drillerdroid->jumpsRemaining = 2;
346
}
347
348
self->timer = 7;
349
self->angle = 0;
350
self->state = Drillerdroid_State_Landed;
351
}
352
}
353
354
void Drillerdroid_State_Landed(void)
355
{
356
RSDK_THIS(Drillerdroid);
357
358
self->position.y += self->velocity.y;
359
Drillerdroid->drillPos[0] = self->startY - self->position.y;
360
Drillerdroid->drillPos[1] = self->startY - self->position.y;
361
362
self->velocity.y -= 0xE000;
363
364
Drillerdroid_CheckPlayerCollisions();
365
366
if (self->velocity.y < 0) {
367
if (self->position.y < self->startY)
368
self->state = Drillerdroid_State_LandRecoil;
369
}
370
}
371
372
void Drillerdroid_State_LandRecoil(void)
373
{
374
RSDK_THIS(Drillerdroid);
375
376
self->position.y += self->velocity.y;
377
Drillerdroid->drillPos[0] = self->startY - self->position.y;
378
Drillerdroid->drillPos[1] = self->startY - self->position.y;
379
380
self->velocity.y += 0x14000;
381
382
Drillerdroid_CheckPlayerCollisions();
383
384
if (self->velocity.y > 0) {
385
if (self->position.y > self->startY) {
386
self->position.y = self->startY;
387
Drillerdroid->drillPos[0] = 0;
388
Drillerdroid->drillPos[1] = 0;
389
self->state = Drillerdroid_State_DecideNextMove;
390
}
391
}
392
}
393
394
void Drillerdroid_State_DecideNextMove(void)
395
{
396
RSDK_THIS(Drillerdroid);
397
398
Drillerdroid_CheckPlayerCollisions();
399
400
if (--self->timer <= 0) {
401
if (Drillerdroid->jumpsRemaining) {
402
self->timer = 240;
403
self->velocity.y = 0x27000;
404
RSDK.PlaySfx(Drillerdroid->sfxJump, false, 255);
405
self->state = Drillerdroid_State_PrepareJump;
406
}
407
else if (Drillerdroid->canBreakSegment) {
408
self->timer = 180;
409
Drillerdroid->stalactiteOffset = 6 * RSDK.Rand(-2, 3);
410
self->state = Drillerdroid_State_Drilling;
411
}
412
else {
413
self->timer = 60;
414
self->state = Drillerdroid_State_Overheat;
415
}
416
}
417
}
418
419
void Drillerdroid_State_PrepareJump(void)
420
{
421
RSDK_THIS(Drillerdroid);
422
423
self->position.y += self->velocity.y;
424
Drillerdroid->drillPos[0] = self->startY - self->position.y;
425
Drillerdroid->drillPos[1] = self->startY - self->position.y;
426
427
self->velocity.y -= 0x8000;
428
429
Drillerdroid_CheckPlayerCollisions();
430
431
if (self->velocity.y < 0) {
432
if (Drillerdroid->drillPos[0] >= 0x40000) {
433
self->timer = self->velocity.y;
434
Drillerdroid->drillPos[0] = 0x40000;
435
Drillerdroid->drillPos[1] = 0x40000;
436
self->state = Drillerdroid_State_Jumping;
437
}
438
}
439
}
440
441
void Drillerdroid_State_Jumping(void)
442
{
443
RSDK_THIS(Drillerdroid);
444
445
self->position.y += self->velocity.y;
446
self->velocity.y += 0x3800;
447
448
Drillerdroid_CheckPlayerCollisions();
449
450
if (self->velocity.y > 0) {
451
if (self->position.y >= (Zone->cameraBoundsB[0] - 96) << 16) {
452
self->position.y = (Zone->cameraBoundsB[0] - 96) << 16;
453
454
RSDK.PlaySfx(Drillerdroid->sfxImpact, false, 255);
455
Camera_ShakeScreen(0, 0, 4);
456
457
self->velocity.y >>= 1;
458
self->startY = self->position.y;
459
self->angle = 0;
460
461
if (--Drillerdroid->jumpsRemaining) {
462
RSDK.PlaySfx(Drillerdroid->sfxJump, false, 255);
463
self->state = Drillerdroid_State_PrepareJump;
464
}
465
else {
466
RSDK.PlaySfx(Drillerdroid->sfxDrop, false, 255);
467
EntityPlayer *player1 = RSDK_GET_ENTITY(SLOT_PLAYER1, Player);
468
469
EntityBuckwildBall *ball = CREATE_ENTITY(BuckwildBall, NULL, self->position.x, ScreenInfo->position.y << 16);
470
ball->startPos.x = 0;
471
472
int32 ballSlot = 0;
473
if (Drillerdroid->arenaSegment) {
474
if (Drillerdroid->arenaSegment == 4 || player1->position.x < self->position.x) {
475
ball->position.x -= 0x800000;
476
ball->direction = FLIP_NONE;
477
ballSlot = Drillerdroid->arenaSegment - 1;
478
}
479
else {
480
ball->position.x += 0x800000;
481
ball->direction = FLIP_X;
482
ballSlot = Drillerdroid->arenaSegment + 1;
483
}
484
}
485
else {
486
ball->position.x += 0x800000;
487
ball->direction = FLIP_X;
488
ballSlot = Drillerdroid->arenaSegment + 1;
489
}
490
491
ball->bossBallSlot = ballSlot;
492
ball->visible = true;
493
ball->active = ACTIVE_NORMAL;
494
ball->drawGroup = Zone->objectDrawGroup[0];
495
ball->respawn = false;
496
ball->timerSfx = 0;
497
RSDK.SetSpriteAnimation(BuckwildBall->aniFrames, 0, &ball->animator, true, 0);
498
499
ball->state = BuckwildBall_State_Falling;
500
self->state = Drillerdroid_State_Landed;
501
}
502
}
503
}
504
}
505
506
void Drillerdroid_State_Drilling(void)
507
{
508
RSDK_THIS(Drillerdroid);
509
510
++Drillerdroid->drillSfxTimer;
511
RSDK.ProcessAnimation(&self->mainAnimator);
512
513
for (int32 i = 0; i < 2; ++i) {
514
if (Drillerdroid->pistonDelay[i]) {
515
Drillerdroid->pistonDelay[i]--;
516
}
517
else if (Drillerdroid->pistonMoveDir[i]) {
518
Drillerdroid->pistonPos[i] -= 0x20000;
519
520
if (!Drillerdroid->pistonPos[i]) {
521
Drillerdroid->pistonMoveDir[i] = FLIP_NONE;
522
Drillerdroid->pistonDelay[i] = 10;
523
}
524
}
525
else {
526
Drillerdroid->pistonPos[i] += 0x40000;
527
528
if (Drillerdroid->pistonPos[i] == 0x100000)
529
Drillerdroid->pistonMoveDir[i] = FLIP_X;
530
}
531
532
if (Drillerdroid->drillDelay[i]) {
533
Drillerdroid->drillDelay[i]--;
534
}
535
else if (Drillerdroid->drillMoveDir[i]) {
536
Drillerdroid->drillPos[i] -= 0x40000;
537
538
if (!Drillerdroid->drillPos[i]) {
539
Drillerdroid->drillMoveDir[i] = FLIP_NONE;
540
Drillerdroid->drillDelay[i] = 5;
541
}
542
}
543
else {
544
Drillerdroid->drillPos[i] += 0x80000;
545
546
if (Drillerdroid->drillPos[i] == 0x100000)
547
Drillerdroid->drillMoveDir[i] = FLIP_X;
548
}
549
}
550
551
if (Drillerdroid->canBreakSegment) {
552
if (self->timer == 120) {
553
EntityLavaGeyser *geyser = CREATE_ENTITY(LavaGeyser, NULL, self->position.x, self->position.y + 0x580000);
554
geyser->duration = 60;
555
geyser->active = ACTIVE_NORMAL;
556
geyser->force = 56 << 12;
557
geyser->drawGroup = Zone->objectDrawGroup[1] - 1;
558
geyser->state = LavaGeyser_HandleSetup;
559
}
560
else if (self->timer < 60) {
561
if (self->alpha < 0x200)
562
self->alpha += 4;
563
}
564
}
565
else if (Drillerdroid->drillPos[0] == 0x80000) {
566
Drillerdroid_SpawnDebris(-0x300000);
567
Drillerdroid_SpawnDebris(0x300000);
568
}
569
else if (Drillerdroid->drillPos[1] == 0x80000) {
570
Drillerdroid_SpawnDebris(-0x190000);
571
Drillerdroid_SpawnDebris(0x190000);
572
}
573
574
EntityCamera *camera = RSDK_GET_ENTITY(SLOT_CAMERA1, Camera);
575
if (!camera->shakePos.y)
576
camera->shakePos.y = 4;
577
578
if (!(Zone->timer & 7)) {
579
if (Zone->timer & 0xF) {
580
int32 x = (32 * RSDK.Rand(0, ScreenInfo->size.x >> 5) + ScreenInfo->position.x) << 16;
581
int32 y = (ScreenInfo->position.y + 24) << 16;
582
EntityDebris *debris = CREATE_ENTITY(Debris, Debris_State_Fall, x, y);
583
584
RSDK.SetSpriteAnimation(Drillerdroid->aniFrames, 7, &debris->animator, true, RSDK.Rand(0, 4));
585
debris->gravityStrength = 0x1800;
586
debris->drawGroup = Zone->objectDrawGroup[0];
587
debris->updateRange.x = 0x400000;
588
debris->updateRange.y = 0x400000;
589
}
590
else {
591
int32 x = (48 * RSDK.Rand(0, ScreenInfo->size.x / 48) + Drillerdroid->stalactiteOffset + ScreenInfo->position.x) << 16;
592
int32 y = (ScreenInfo->position.y + 24) << 16;
593
EntityStalactite *stalactite = CREATE_ENTITY(Stalactite, Stalactite_State_Falling_Boss, x, y);
594
595
stalactite->updateRange.x = 0x400000;
596
stalactite->updateRange.y = 0x400000;
597
}
598
}
599
600
self->position.y ^= 0x10000;
601
Drillerdroid_CheckPlayerCollisions();
602
603
if (--self->timer <= 0)
604
self->state = Drillerdroid_State_FinishDrilling;
605
}
606
607
void Drillerdroid_State_FinishDrilling(void)
608
{
609
RSDK_THIS(Drillerdroid);
610
611
Drillerdroid->pistonPos[0] -= 0x20000;
612
if (Drillerdroid->pistonPos[0] < 0)
613
Drillerdroid->pistonPos[0] = 0;
614
615
Drillerdroid->pistonPos[1] -= 0x20000;
616
if (Drillerdroid->pistonPos[1] < 0)
617
Drillerdroid->pistonPos[1] = 0;
618
619
Drillerdroid->drillPos[0] -= 0x20000;
620
if (Drillerdroid->drillPos[0] < 0)
621
Drillerdroid->drillPos[0] = 0;
622
623
Drillerdroid->drillPos[1] -= 0x20000;
624
if (Drillerdroid->drillPos[1] < 0)
625
Drillerdroid->drillPos[1] = 0;
626
627
if (!Drillerdroid->pistonPos[0] && !Drillerdroid->pistonPos[1] && !Drillerdroid->drillPos[0] && !Drillerdroid->drillPos[1]) {
628
self->timer = 60;
629
self->state = Drillerdroid_State_Overheat;
630
}
631
}
632
633
void Drillerdroid_State_Overheat(void)
634
{
635
RSDK_THIS(Drillerdroid);
636
637
if (--self->timer <= 0) {
638
if (Drillerdroid->canBreakSegment) {
639
Drillerdroid->canBreakSegment = false;
640
RSDK.PlaySfx(Drillerdroid->sfxSizzle, false, 255);
641
642
EntityDebris *debris = NULL;
643
switch (Drillerdroid->armorHealth) {
644
default: break;
645
646
case 0:
647
self->state = Drillerdroid_State_OverheatRecoil_DestroyedSegment;
648
Drillerdroid_Hit();
649
break;
650
651
case 1: {
652
debris = CREATE_ENTITY(Debris, Debris_State_FallAndFlicker, self->position.x, self->position.y);
653
RSDK.SetSpriteAnimation(Drillerdroid->aniFrames, 5, &debris->animator, true, 6);
654
debris->velocity.x = -0x10000;
655
debris->velocity.y = -0x30000;
656
debris->gravityStrength = 0x3800;
657
debris->drawGroup = Zone->objectDrawGroup[1];
658
debris->updateRange.x = 0x400000;
659
debris->updateRange.y = 0x400000;
660
661
debris = CREATE_ENTITY(Debris, Debris_State_FallAndFlicker, self->position.x, self->position.y);
662
RSDK.SetSpriteAnimation(Drillerdroid->aniFrames, 5, &debris->animator, true, 6);
663
debris->direction = FLIP_X;
664
debris->drawFX = FX_FLIP;
665
debris->velocity.x = 0x10000;
666
debris->velocity.y = -0x30000;
667
debris->gravityStrength = 0x3800;
668
debris->drawGroup = Zone->objectDrawGroup[1];
669
debris->updateRange.x = 0x400000;
670
debris->updateRange.y = 0x400000;
671
672
int32 spawnX = self->position.x - 0x300000;
673
debris = CREATE_ENTITY(Debris, Debris_State_FallAndFlicker, spawnX, self->position.y);
674
RSDK.SetSpriteAnimation(Drillerdroid->aniFrames, 5, &debris->animator, true, 7);
675
debris->velocity.x = -0x30000;
676
debris->velocity.y = -0x40000;
677
debris->gravityStrength = 0x3800;
678
debris->drawGroup = Zone->objectDrawGroup[1];
679
debris->updateRange.x = 0x400000;
680
debris->updateRange.y = 0x400000;
681
682
spawnX += 0xD0000;
683
debris = CREATE_ENTITY(Debris, Debris_State_FallAndFlicker, spawnX, self->position.y);
684
RSDK.SetSpriteAnimation(Drillerdroid->aniFrames, 5, &debris->animator, true, 7);
685
debris->velocity.x = 0x20000;
686
debris->velocity.y = -0x40000;
687
debris->gravityStrength = 0x3800;
688
debris->drawGroup = Zone->objectDrawGroup[1];
689
debris->updateRange.x = 0x400000;
690
debris->updateRange.y = 0x400000;
691
692
spawnX += 0x530000;
693
debris = CREATE_ENTITY(Debris, Debris_State_FallAndFlicker, spawnX, self->position.y);
694
RSDK.SetSpriteAnimation(Drillerdroid->aniFrames, 5, &debris->animator, true, 7);
695
debris->velocity.x = 0x30000;
696
debris->velocity.y = -0x40000;
697
debris->gravityStrength = 0x3800;
698
debris->drawGroup = Zone->objectDrawGroup[1];
699
debris->updateRange.x = 0x400000;
700
debris->updateRange.y = 0x400000;
701
702
debris = CREATE_ENTITY(Debris, Debris_State_FallAndFlicker, spawnX - 851968, self->position.y);
703
RSDK.SetSpriteAnimation(Drillerdroid->aniFrames, 5, &debris->animator, true, 7);
704
debris->velocity.x = -0x20000;
705
debris->velocity.y = -0x40000;
706
debris->gravityStrength = 0x3800;
707
debris->drawGroup = Zone->objectDrawGroup[1];
708
debris->updateRange.x = 0x400000;
709
debris->updateRange.y = 0x400000;
710
break;
711
}
712
713
case 2:
714
debris = CREATE_ENTITY(Debris, Debris_State_FallAndFlicker, self->position.x, self->position.y);
715
RSDK.SetSpriteAnimation(Drillerdroid->aniFrames, 5, &debris->animator, true, 4);
716
debris->velocity.x = -0x10000;
717
debris->velocity.y = -0x40000;
718
debris->gravityStrength = 0x3800;
719
debris->drawGroup = Zone->objectDrawGroup[1];
720
debris->updateRange.x = 0x300000;
721
debris->updateRange.y = 0x300000;
722
723
debris = CREATE_ENTITY(Debris, Debris_State_FallAndFlicker, self->position.x, self->position.y);
724
RSDK.SetSpriteAnimation(Drillerdroid->aniFrames, 5, &debris->animator, true, 5);
725
debris->velocity.x = 0x10000;
726
debris->velocity.y = -0x40000;
727
debris->gravityStrength = 0x3800;
728
debris->drawGroup = Zone->objectDrawGroup[1];
729
debris->updateRange.x = 0x300000;
730
debris->updateRange.y = 0x300000;
731
break;
732
}
733
734
if (Drillerdroid->armorHealth > 0) {
735
RSDK.PlaySfx(Drillerdroid->sfxHit, false, 255);
736
self->invincibilityTimer = 45;
737
--Drillerdroid->armorHealth;
738
self->state = Drillerdroid_State_OverheatRecoil_DestroyedSegment;
739
}
740
741
}
742
else {
743
self->state = Drillerdroid_State_OverheatRecoil;
744
}
745
}
746
747
Drillerdroid_CheckPlayerCollisions();
748
}
749
750
void Drillerdroid_State_OverheatRecoil(void)
751
{
752
RSDK_THIS(Drillerdroid);
753
754
Drillerdroid->drillPos[0] += 0x10000;
755
Drillerdroid->drillPos[1] += 0x10000;
756
757
self->position.y -= 0x10000;
758
759
Drillerdroid_CheckPlayerCollisions();
760
761
if (Drillerdroid->drillPos[0] == 0x100000) {
762
self->timer = 15;
763
self->state = Drillerdroid_State_JumpTargetDelay;
764
}
765
}
766
767
void Drillerdroid_State_JumpTargetDelay(void)
768
{
769
RSDK_THIS(Drillerdroid);
770
771
Drillerdroid_CheckPlayerCollisions();
772
773
if (--self->timer <= 0) {
774
self->velocity.y = 0x78000;
775
RSDK.PlaySfx(Drillerdroid->sfxJump, false, 0xFF);
776
self->state = Drillerdroid_State_PrepareJumpTarget;
777
}
778
}
779
780
void Drillerdroid_State_PrepareJumpTarget(void)
781
{
782
RSDK_THIS(Drillerdroid);
783
784
self->position.y += self->velocity.y;
785
self->velocity.y -= 0x1C000;
786
787
Drillerdroid->drillPos[0] = self->startY - self->position.y;
788
Drillerdroid->drillPos[1] = self->startY - self->position.y;
789
790
Drillerdroid_CheckPlayerCollisions();
791
792
if (self->velocity.y < 0) {
793
if (Drillerdroid->drillPos[0] >= 0x100000) {
794
Drillerdroid->drillPos[0] = 0x100000;
795
Drillerdroid->drillPos[1] = 0x100000;
796
self->state = Drillerdroid_State_JumpTargeting;
797
}
798
}
799
}
800
801
void Drillerdroid_State_JumpTargeting(void)
802
{
803
RSDK_THIS(Drillerdroid);
804
805
self->position.y += self->velocity.y;
806
self->velocity.y += 0x3800;
807
808
if (self->velocity.y >= 0) {
809
Drillerdroid->pistonPos[0] = 0;
810
Drillerdroid->pistonPos[1] = 0;
811
812
Drillerdroid->drillPos[0] = 0x100000;
813
Drillerdroid->drillPos[1] = 0x100000;
814
815
Drillerdroid->pistonDelay[0] = 4;
816
Drillerdroid->pistonDelay[1] = 0;
817
818
Drillerdroid->drillDelay[0] = 4;
819
Drillerdroid->drillDelay[1] = 0;
820
821
Drillerdroid->pistonMoveDir[0] = FLIP_NONE;
822
Drillerdroid->pistonMoveDir[1] = FLIP_NONE;
823
824
Drillerdroid->drillMoveDir[0] = FLIP_NONE;
825
Drillerdroid->drillMoveDir[1] = FLIP_NONE;
826
827
self->position.x = 0;
828
829
EntityPlayer *player1 = RSDK_GET_ENTITY(SLOT_PLAYER1, Player);
830
CREATE_ENTITY(Drillerdroid, INT_TO_VOID(DRILLERDROID_TARGET), player1->position.x, player1->position.y)->target = player1;
831
RSDK.PlaySfx(Drillerdroid->sfxTargeting, false, 255);
832
self->state = Drillerdroid_State_DecidingDropPos;
833
}
834
}
835
836
void Drillerdroid_State_DecidingDropPos(void)
837
{
838
RSDK_THIS(Drillerdroid);
839
840
if (self->position.x) {
841
self->timer = 240;
842
self->velocity.y = -0x40000;
843
self->state = Drillerdroid_State_Dropping;
844
self->position.x = (RSDK_GET_ENTITY(SLOT_PLAYER1, Player)->position.x + 0x400000) & 0xFF800000;
845
846
bool32 failed = self->position.x < Zone->cameraBoundsL[0] << 16 || self->position.x > Zone->cameraBoundsR[0] << 16;
847
bool32 platformActive = false;
848
if (!failed) {
849
Drillerdroid->arenaSegment = (((self->position.x >> 16) - Zone->cameraBoundsL[0] + 64) >> 7) - 1;
850
platformActive = Drillerdroid->platformActive[Drillerdroid->arenaSegment];
851
failed = platformActive == 0xFF;
852
}
853
854
if (failed) {
855
self->position.x = 0;
856
RSDK.PlaySfx(Drillerdroid->sfxFail, false, 255);
857
RSDK.StopSfx(Drillerdroid->sfxTargeting);
858
self->timer = 60;
859
self->state = Drillerdroid_State_DropFailReset;
860
}
861
else if (platformActive) {
862
EntityLRZRockPile *rocks = RSDK_GET_ENTITY(SceneInfo->entitySlot + 1 + Drillerdroid->arenaSegment, LRZRockPile);
863
rocks->active = ACTIVE_NORMAL;
864
rocks->timer = 120;
865
rocks->canCollapse = true;
866
Drillerdroid->canBreakSegment = true;
867
Drillerdroid->platformActive[Drillerdroid->arenaSegment] = false;
868
}
869
}
870
}
871
872
void Drillerdroid_State_DropFailReset(void)
873
{
874
RSDK_THIS(Drillerdroid);
875
876
if (--self->timer <= 0) {
877
EntityPlayer *player1 = RSDK_GET_ENTITY(SLOT_PLAYER1, Player);
878
CREATE_ENTITY(Drillerdroid, INT_TO_VOID(DRILLERDROID_TARGET), player1->position.x, player1->position.y)->target = player1;
879
RSDK.PlaySfx(Drillerdroid->sfxTargeting, false, 255);
880
self->state = Drillerdroid_State_DecidingDropPos;
881
}
882
}
883
884
void Drillerdroid_State_OverheatRecoil_DestroyedSegment(void)
885
{
886
RSDK_THIS(Drillerdroid);
887
888
// Leftover from DrillerdroilO
889
++self->rotation;
890
891
Drillerdroid->drillPos[0] += 0x4000;
892
Drillerdroid->drillPos[1] += 0x4000;
893
894
Drillerdroid->pistonPos[0] += 0x4000;
895
Drillerdroid->pistonPos[1] += 0x4000;
896
897
self->position.y -= 0x4000;
898
899
Drillerdroid_CheckPlayerCollisions();
900
901
if (Drillerdroid->drillPos[0] == 0x100000) {
902
self->timer = 90;
903
self->state = Drillerdroid_State_Cooldown;
904
}
905
}
906
907
void Drillerdroid_State_Cooldown(void)
908
{
909
RSDK_THIS(Drillerdroid);
910
911
Drillerdroid_CheckPlayerCollisions();
912
913
self->alpha -= 8;
914
if (self->alpha <= 0) {
915
self->alpha = 0;
916
self->state = Drillerdroid_State_ResetFromCooldown;
917
}
918
}
919
920
void Drillerdroid_State_ResetFromCooldown(void)
921
{
922
RSDK_THIS(Drillerdroid);
923
924
// Leftover from DrillerdroilO
925
self->rotation -= 4;
926
927
Drillerdroid->pistonPos[0] -= 0x10000;
928
Drillerdroid->pistonPos[1] -= 0x10000;
929
930
Drillerdroid_CheckPlayerCollisions();
931
932
if (!Drillerdroid->pistonPos[0]) {
933
self->timer = 30;
934
self->state = Drillerdroid_State_JumpTargetDelay;
935
}
936
}
937
938
void Drillerdroid_State_Destroyed(void)
939
{
940
RSDK_THIS(Drillerdroid);
941
942
Drillerdroid_Explode();
943
944
if (!--self->invincibilityTimer) {
945
EntityDebris *debris = CREATE_ENTITY(Debris, Debris_State_FallAndFlicker, self->position.x - 0x300000, self->position.y);
946
RSDK.SetSpriteAnimation(Drillerdroid->aniFrames, 0, &debris->animator, true, 1);
947
debris->velocity.x = RSDK.Rand(-6, 6) << 15;
948
debris->velocity.y = RSDK.Rand(-10, -6) << 15;
949
debris->gravityStrength = 0x3800;
950
debris->drawGroup = Zone->objectDrawGroup[1];
951
debris->updateRange.x = 0x400000;
952
debris->updateRange.y = 0x400000;
953
954
debris = CREATE_ENTITY(Debris, Debris_State_FallAndFlicker, self->position.x - 0x300000, self->position.y);
955
RSDK.SetSpriteAnimation(Drillerdroid->aniFrames, 0, &debris->animator, true, 2);
956
debris->velocity.x = RSDK.Rand(-6, 6) << 15;
957
debris->velocity.y = RSDK.Rand(0, 2) << 15;
958
debris->gravityStrength = 0x3800;
959
debris->drawGroup = Zone->objectDrawGroup[1];
960
debris->updateRange.x = 0x400000;
961
debris->updateRange.y = 0x400000;
962
963
debris = CREATE_ENTITY(Debris, Debris_State_FallAndFlicker, self->position.x - 0x230000, self->position.y);
964
RSDK.SetSpriteAnimation(Drillerdroid->aniFrames, 0, &debris->animator, true, 1);
965
debris->velocity.x = RSDK.Rand(-6, 6) << 15;
966
debris->velocity.y = RSDK.Rand(-10, -6) << 15;
967
debris->gravityStrength = 0x3800;
968
debris->drawGroup = Zone->objectDrawGroup[1];
969
debris->updateRange.x = 0x400000;
970
debris->updateRange.y = 0x400000;
971
972
debris = CREATE_ENTITY(Debris, Debris_State_FallAndFlicker, self->position.x - 0x230000, self->position.y);
973
RSDK.SetSpriteAnimation(Drillerdroid->aniFrames, 0, &debris->animator, true, 2);
974
debris->velocity.x = RSDK.Rand(-6, 6) << 15;
975
debris->velocity.y = RSDK.Rand(0, 2) << 15;
976
debris->gravityStrength = 0x3800;
977
debris->drawGroup = Zone->objectDrawGroup[1];
978
debris->updateRange.x = 0x400000;
979
debris->updateRange.y = 0x400000;
980
981
debris = CREATE_ENTITY(Debris, Debris_State_FallAndFlicker, self->position.x + 0x300000, self->position.y);
982
RSDK.SetSpriteAnimation(Drillerdroid->aniFrames, 0, &debris->animator, true, 1);
983
debris->velocity.x = RSDK.Rand(-6, 6) << 15;
984
debris->velocity.y = RSDK.Rand(-10, -6) << 15;
985
debris->gravityStrength = 0x3800;
986
debris->drawGroup = Zone->objectDrawGroup[1];
987
debris->updateRange.x = 0x400000;
988
debris->updateRange.y = 0x400000;
989
990
debris = CREATE_ENTITY(Debris, Debris_State_FallAndFlicker, self->position.x + 0x300000, self->position.y);
991
RSDK.SetSpriteAnimation(Drillerdroid->aniFrames, 0, &debris->animator, true, 2);
992
debris->velocity.x = RSDK.Rand(-6, 6) << 15;
993
debris->velocity.y = RSDK.Rand(0, 2) << 15;
994
debris->gravityStrength = 0x3800;
995
debris->drawGroup = Zone->objectDrawGroup[1];
996
debris->updateRange.x = 0x400000;
997
debris->updateRange.y = 0x400000;
998
999
debris = CREATE_ENTITY(Debris, Debris_State_FallAndFlicker, self->position.x + 0x230000, self->position.y);
1000
RSDK.SetSpriteAnimation(Drillerdroid->aniFrames, 0, &debris->animator, true, 1);
1001
debris->velocity.x = RSDK.Rand(-6, 6) << 15;
1002
debris->velocity.y = RSDK.Rand(-10, -6) << 15;
1003
debris->gravityStrength = 0x3800;
1004
debris->drawGroup = Zone->objectDrawGroup[1];
1005
debris->updateRange.x = 0x400000;
1006
debris->updateRange.y = 0x400000;
1007
1008
debris = CREATE_ENTITY(Debris, Debris_State_FallAndFlicker, self->position.x + 0x230000, self->position.y);
1009
RSDK.SetSpriteAnimation(Drillerdroid->aniFrames, 0, &debris->animator, true, 2);
1010
debris->velocity.x = RSDK.Rand(-6, 6) << 15;
1011
debris->velocity.y = RSDK.Rand(0, 2) << 15;
1012
debris->gravityStrength = 0x3800;
1013
debris->drawGroup = Zone->objectDrawGroup[1];
1014
debris->updateRange.x = 0x400000;
1015
debris->updateRange.y = 0x400000;
1016
1017
debris = CREATE_ENTITY(Debris, Debris_State_FallAndFlicker, self->position.x, self->position.y);
1018
RSDK.SetSpriteAnimation(Drillerdroid->aniFrames, 0, &debris->animator, true, 3);
1019
debris->velocity.x = RSDK.Rand(-6, 6) << 15;
1020
debris->velocity.y = RSDK.Rand(-10, -6) << 15;
1021
debris->gravityStrength = 0x3800;
1022
debris->drawGroup = Zone->objectDrawGroup[1];
1023
debris->updateRange.x = 0x400000;
1024
debris->updateRange.y = 0x400000;
1025
1026
debris = CREATE_ENTITY(Debris, Debris_State_FallAndFlicker, self->position.x, self->position.y);
1027
RSDK.SetSpriteAnimation(Drillerdroid->aniFrames, 0, &debris->animator, true, 5);
1028
debris->velocity.x = RSDK.Rand(-6, 6) << 15;
1029
debris->velocity.y = RSDK.Rand(-10, -6) << 15;
1030
debris->gravityStrength = 0x3800;
1031
debris->drawGroup = Zone->objectDrawGroup[1];
1032
debris->updateRange.x = 0x400000;
1033
debris->updateRange.y = 0x400000;
1034
1035
if (Drillerdroid->armorHealth == 1) {
1036
debris = CREATE_ENTITY(Debris, Debris_State_FallAndFlicker, self->position.x, self->position.y);
1037
RSDK.SetSpriteAnimation(Drillerdroid->aniFrames, 5, &debris->animator, true, 6);
1038
debris->velocity.x = RSDK.Rand(-6, 6) << 15;
1039
debris->velocity.y = RSDK.Rand(-10, -6) << 15;
1040
debris->gravityStrength = 0x3800;
1041
debris->drawGroup = Zone->objectDrawGroup[1];
1042
debris->updateRange.x = 0x400000;
1043
debris->updateRange.y = 0x400000;
1044
1045
debris = CREATE_ENTITY(Debris, Debris_State_FallAndFlicker, self->position.x, self->position.y);
1046
RSDK.SetSpriteAnimation(Drillerdroid->aniFrames, 5, &debris->animator, true, 6);
1047
debris->direction = FLIP_X;
1048
debris->drawFX = FX_FLIP;
1049
debris->velocity.x = RSDK.Rand(-6, 6) << 15;
1050
debris->velocity.y = RSDK.Rand(-10, -6) << 15;
1051
debris->gravityStrength = 14336;
1052
debris->drawGroup = Zone->objectDrawGroup[1];
1053
debris->updateRange.x = 0x400000;
1054
debris->updateRange.y = 0x400000;
1055
1056
int32 spawnX = self->position.x - 0x300000;
1057
debris = CREATE_ENTITY(Debris, Debris_State_FallAndFlicker, spawnX, self->position.y);
1058
RSDK.SetSpriteAnimation(Drillerdroid->aniFrames, 5, &debris->animator, true, 7);
1059
debris->velocity.x = RSDK.Rand(-6, 6) << 15;
1060
debris->velocity.y = RSDK.Rand(-10, -6) << 15;
1061
debris->gravityStrength = 0x3800;
1062
debris->drawGroup = Zone->objectDrawGroup[1];
1063
debris->updateRange.x = 0x400000;
1064
debris->updateRange.y = 0x400000;
1065
1066
spawnX += 0xD0000;
1067
debris = CREATE_ENTITY(Debris, Debris_State_FallAndFlicker, spawnX, self->position.y);
1068
RSDK.SetSpriteAnimation(Drillerdroid->aniFrames, 5, &debris->animator, true, 7);
1069
debris->velocity.x = RSDK.Rand(-6, 6) << 15;
1070
debris->velocity.y = RSDK.Rand(-10, -6) << 15;
1071
debris->gravityStrength = 0x3800;
1072
debris->drawGroup = Zone->objectDrawGroup[1];
1073
debris->updateRange.x = 0x400000;
1074
debris->updateRange.y = 0x400000;
1075
1076
spawnX += 0x530000;
1077
debris = CREATE_ENTITY(Debris, Debris_State_FallAndFlicker, spawnX, self->position.y);
1078
RSDK.SetSpriteAnimation(Drillerdroid->aniFrames, 5, &debris->animator, true, 7);
1079
debris->velocity.x = RSDK.Rand(-6, 6) << 15;
1080
debris->velocity.y = RSDK.Rand(-10, -6) << 15;
1081
debris->gravityStrength = 0x3800;
1082
debris->drawGroup = Zone->objectDrawGroup[1];
1083
debris->updateRange.x = 0x400000;
1084
debris->updateRange.y = 0x400000;
1085
1086
debris = CREATE_ENTITY(Debris, Debris_State_FallAndFlicker, spawnX - 851968, self->position.y);
1087
RSDK.SetSpriteAnimation(Drillerdroid->aniFrames, 5, &debris->animator, true, 7);
1088
debris->velocity.x = RSDK.Rand(-6, 6) << 15;
1089
debris->velocity.y = RSDK.Rand(-10, -6) << 15;
1090
debris->gravityStrength = 0x3800;
1091
debris->drawGroup = Zone->objectDrawGroup[1];
1092
debris->updateRange.x = 0x400000;
1093
debris->updateRange.y = 0x400000;
1094
}
1095
1096
self->velocity.x = RSDK.Rand(-6, 6) << 15;
1097
self->velocity.y = RSDK.Rand(-10, -6) << 15;
1098
self->mainAnimator.frameID = 4;
1099
self->stateDraw = Drillerdroid_Draw_Simple;
1100
self->state = Drillerdroid_State_Finish;
1101
1102
foreach_active(SignPost, signPost) { signPost->position.x = self->position.x; }
1103
}
1104
}
1105
1106
void Drillerdroid_State_Finish(void)
1107
{
1108
RSDK_THIS(Drillerdroid);
1109
1110
self->position.x += self->velocity.x;
1111
self->position.y += self->velocity.y;
1112
self->velocity.y += 0x3800;
1113
1114
self->visible ^= true;
1115
1116
Drillerdroid_Explode();
1117
1118
if (!RSDK.CheckOnScreen(self, NULL)) {
1119
Music_TransitionTrack(TRACK_STAGE, 0.0125);
1120
self->timer = 0;
1121
self->state = Drillerdroid_State_DropSignPost;
1122
}
1123
}
1124
1125
void Drillerdroid_State_DropSignPost(void)
1126
{
1127
RSDK_THIS(Drillerdroid);
1128
1129
if (++self->timer == 60) {
1130
foreach_all(SignPost, signPost)
1131
{
1132
signPost->active = ACTIVE_NORMAL;
1133
signPost->state = SignPost_State_Falling;
1134
RSDK.PlaySfx(SignPost->sfxTwinkle, false, 255);
1135
}
1136
1137
LRZ1Setup->fadeTimer = 1;
1138
destroyEntity(self);
1139
}
1140
}
1141
1142
void Drillerdroid_Draw_Boss(void)
1143
{
1144
RSDK_THIS(Drillerdroid);
1145
1146
RSDK.SetLimitedFade(0, 1, 2, self->alpha, 32, 41);
1147
1148
if (self->invincibilityTimer & 1) {
1149
RSDK.SetPaletteEntry(0, 32, 0xE0E0E0);
1150
RSDK.SetPaletteEntry(0, 128, 0xE0E0E0);
1151
}
1152
1153
// Piston (L1)
1154
self->mainAnimator.frameID = 1;
1155
Vector2 drawPos;
1156
drawPos.x = self->position.x - 0x300000;
1157
drawPos.y = self->position.y - Drillerdroid->pistonPos[0];
1158
RSDK.DrawSprite(&self->mainAnimator, &drawPos, false);
1159
1160
// Drill (L1)
1161
self->mainAnimator.frameID = 2;
1162
drawPos.y = self->position.y + Drillerdroid->drillPos[0];
1163
RSDK.DrawSprite(&self->mainAnimator, &drawPos, false);
1164
1165
// Piston (L2)
1166
self->mainAnimator.frameID = 1;
1167
drawPos.x += 0xD0000;
1168
drawPos.y = self->position.y - Drillerdroid->pistonPos[1];
1169
RSDK.DrawSprite(&self->mainAnimator, &drawPos, false);
1170
1171
// Drill (L2)
1172
self->mainAnimator.frameID = 2;
1173
drawPos.y = self->position.y + Drillerdroid->drillPos[1];
1174
RSDK.DrawSprite(&self->mainAnimator, &drawPos, false);
1175
1176
// Piston (R1)
1177
self->mainAnimator.frameID = 1;
1178
drawPos.x += 0x530000;
1179
drawPos.y = self->position.y - Drillerdroid->pistonPos[0];
1180
RSDK.DrawSprite(&self->mainAnimator, &drawPos, false);
1181
1182
// Drill (R1)
1183
self->mainAnimator.frameID = 2;
1184
drawPos.y = self->position.y + Drillerdroid->drillPos[0];
1185
RSDK.DrawSprite(&self->mainAnimator, &drawPos, false);
1186
1187
// Piston (R2)
1188
self->mainAnimator.frameID = 1;
1189
drawPos.x -= 0xD0000;
1190
drawPos.y = self->position.y - Drillerdroid->pistonPos[1];
1191
RSDK.DrawSprite(&self->mainAnimator, &drawPos, false);
1192
1193
// Drill (R2)
1194
self->mainAnimator.frameID = 2;
1195
drawPos.y = self->position.y + Drillerdroid->drillPos[1];
1196
RSDK.DrawSprite(&self->mainAnimator, &drawPos, false);
1197
1198
// Main Body
1199
self->mainAnimator.frameID = 0;
1200
RSDK.DrawSprite(&self->mainAnimator, NULL, false);
1201
1202
switch (Drillerdroid->armorHealth) {
1203
default:
1204
case 0: break;
1205
1206
case 1:
1207
// Drill (L) Armor
1208
drawPos = self->position;
1209
self->armorAnimator.frameID = 6;
1210
RSDK.DrawSprite(&self->armorAnimator, NULL, false);
1211
1212
// Drill (R) Armor
1213
self->drawFX |= FX_FLIP;
1214
self->direction = FLIP_X;
1215
RSDK.DrawSprite(&self->armorAnimator, NULL, false);
1216
1217
self->direction = FLIP_NONE;
1218
self->drawFX = FX_NONE;
1219
self->armorAnimator.frameID = 7;
1220
1221
// Piston (L1) Armor
1222
drawPos.x -= 0x300000;
1223
drawPos.y -= Drillerdroid->pistonPos[0];
1224
RSDK.DrawSprite(&self->armorAnimator, &drawPos, false);
1225
1226
// Piston (L2) Armor
1227
drawPos.x += 0xD0000;
1228
drawPos.y = self->position.y - Drillerdroid->pistonPos[1];
1229
RSDK.DrawSprite(&self->armorAnimator, &drawPos, false);
1230
1231
// Piston (R1) Armor
1232
drawPos.x += 0x530000;
1233
drawPos.y = self->position.y - Drillerdroid->pistonPos[0];
1234
RSDK.DrawSprite(&self->armorAnimator, &drawPos, false);
1235
1236
// Piston (R2) Armor
1237
drawPos.x -= 0xD0000;
1238
drawPos.y = self->position.y - Drillerdroid->pistonPos[1];
1239
RSDK.DrawSprite(&self->armorAnimator, &drawPos, false);
1240
break;
1241
1242
case 2:
1243
// Core Armor (L)
1244
drawPos.x = self->position.x + 0x10000;
1245
drawPos.y = self->position.y - 0x140000;
1246
self->armorAnimator.frameID = 4;
1247
RSDK.DrawSprite(&self->armorAnimator, &drawPos, false);
1248
1249
self->armorAnimator.frameID = 5;
1250
//[Fallthrough]
1251
1252
case 3:
1253
if (Drillerdroid->armorHealth == 3) {
1254
// Core Armor (R)
1255
drawPos.x = self->position.x + 0x10000;
1256
drawPos.y = self->position.y - 0x140000;
1257
self->armorAnimator.frameID = 0;
1258
RSDK.DrawSprite(&self->armorAnimator, &drawPos, false);
1259
1260
self->armorAnimator.frameID = 1;
1261
}
1262
1263
// Core Armor (R)
1264
RSDK.DrawSprite(&self->armorAnimator, &drawPos, false);
1265
1266
// Drill (L) Armor
1267
drawPos = self->position;
1268
self->armorAnimator.frameID = 2;
1269
RSDK.DrawSprite(&self->armorAnimator, NULL, false);
1270
1271
// Drill (R) Armor
1272
self->drawFX |= FX_FLIP;
1273
self->direction = FLIP_X;
1274
RSDK.DrawSprite(&self->armorAnimator, NULL, false);
1275
1276
self->direction = FLIP_NONE;
1277
self->drawFX = FX_NONE;
1278
self->armorAnimator.frameID = 3;
1279
1280
// Piston (L1) Armor
1281
drawPos.x -= 0x300000;
1282
drawPos.y = self->position.y - Drillerdroid->pistonPos[0];
1283
RSDK.DrawSprite(&self->armorAnimator, &drawPos, false);
1284
1285
// Piston (L2) Armor
1286
drawPos.x += 0xD0000;
1287
drawPos.y = self->position.y - Drillerdroid->pistonPos[1];
1288
RSDK.DrawSprite(&self->armorAnimator, &drawPos, false);
1289
1290
// Piston (R1) Armor
1291
drawPos.x += 0x530000;
1292
drawPos.y = self->position.y - Drillerdroid->pistonPos[0];
1293
RSDK.DrawSprite(&self->armorAnimator, &drawPos, false);
1294
1295
// Piston (R2) Armor
1296
drawPos.x -= 0xD0000;
1297
drawPos.y = self->position.y - Drillerdroid->pistonPos[1];
1298
RSDK.DrawSprite(&self->armorAnimator, &drawPos, false);
1299
break;
1300
}
1301
1302
RSDK.CopyPalette(1, 32, 0, 32, 10);
1303
RSDK.SetPaletteEntry(0, 32, 0x282028);
1304
RSDK.SetPaletteEntry(0, 128, 0x000000);
1305
}
1306
1307
void Drillerdroid_Draw_Simple(void)
1308
{
1309
RSDK_THIS(Drillerdroid);
1310
1311
RSDK.DrawSprite(&self->mainAnimator, NULL, false);
1312
}
1313
1314
void Drillerdroid_State_Target(void)
1315
{
1316
RSDK_THIS(Drillerdroid);
1317
1318
RSDK.ProcessAnimation(&self->armorAnimator);
1319
RSDK.ProcessAnimation(&self->targetLockAnimator);
1320
1321
if (self->target) {
1322
self->position.x = self->target->position.x;
1323
self->position.y = self->target->position.y;
1324
}
1325
1326
self->alpha += 0x20;
1327
self->targetEdgeOffset.x -= 0x20000;
1328
if (self->targetEdgeOffset.x <= 0xC0000) {
1329
self->alpha = 0;
1330
self->targetEdgeOffset.x = 0x2C0000;
1331
}
1332
1333
self->targetEdgeOffset.y = self->targetEdgeOffset.x;
1334
if (++self->timer == 60)
1335
RSDK.SetSpriteAnimation(Drillerdroid->aniFrames, 4, &self->targetLockAnimator, true, 0);
1336
1337
if (self->timer == 96) {
1338
self->target = NULL;
1339
Drillerdroid->boss->position.x = self->position.x;
1340
1341
if (self->position.x < (Zone->cameraBoundsL[0] + 64) << 16 || self->position.x > (Zone->cameraBoundsR[0] - 64) << 16)
1342
Drillerdroid->boss->position.x = (Zone->cameraBoundsL[0] + 64) << 16;
1343
else if (self->position.x > (Zone->cameraBoundsR[0] - 64) << 16)
1344
Drillerdroid->boss->position.x = (Zone->cameraBoundsR[0] - 64) << 16;
1345
}
1346
1347
if (self->timer == 128)
1348
destroyEntity(self);
1349
}
1350
1351
void Drillerdroid_Draw_Target(void)
1352
{
1353
RSDK_THIS(Drillerdroid);
1354
1355
int32 x = ((self->position.x + 0x400000) & 0xFF800000) - 0x400000;
1356
if (!(Zone->timer & 8)) {
1357
RSDK.DrawLine(x + 0x10000, self->position.y, x + 0x7F0000, self->position.y, 0xE0E0E0, 192, INK_ADD, false);
1358
RSDK.DrawLine(x, self->position.y - 0x80000, x, self->position.y + 0x80000, 0xE0E0E0, 160, INK_ADD, false);
1359
RSDK.DrawLine(x + 0x800000, self->position.y - 0x80000, x + 0x800000, self->position.y + 0x80000, 0xE0E0E0, 160, INK_ADD, false);
1360
}
1361
1362
// Top-Left Edge
1363
self->mainAnimator.frameID = 0;
1364
self->inkEffect = INK_ALPHA;
1365
self->direction = FLIP_NONE;
1366
Vector2 drawPos;
1367
drawPos.x = self->position.x - self->targetEdgeOffset.x;
1368
drawPos.y = self->position.y - self->targetEdgeOffset.y;
1369
RSDK.DrawSprite(&self->mainAnimator, &drawPos, false);
1370
1371
// Top-Right Edge
1372
self->direction = FLIP_X;
1373
drawPos.x = self->position.x + self->targetEdgeOffset.x;
1374
drawPos.y = self->position.y - self->targetEdgeOffset.y;
1375
RSDK.DrawSprite(&self->mainAnimator, &drawPos, false);
1376
1377
// Bottom-Left Edge
1378
self->mainAnimator.frameID = 1;
1379
self->direction = FLIP_NONE;
1380
drawPos.x = self->position.x - self->targetEdgeOffset.x;
1381
drawPos.y = self->position.y + self->targetEdgeOffset.y;
1382
RSDK.DrawSprite(&self->mainAnimator, &drawPos, false);
1383
1384
// Bottom-Right Edge
1385
self->direction = FLIP_X;
1386
drawPos.x = self->position.x + self->targetEdgeOffset.x;
1387
drawPos.y = self->position.y + self->targetEdgeOffset.y;
1388
RSDK.DrawSprite(&self->mainAnimator, &drawPos, false);
1389
1390
// Target Reticle
1391
self->inkEffect = INK_NONE;
1392
self->direction = FLIP_NONE;
1393
RSDK.DrawSprite(&self->armorAnimator, NULL, false);
1394
RSDK.DrawSprite(&self->targetLockAnimator, NULL, false);
1395
}
1396
1397
#if GAME_INCLUDE_EDITOR
1398
void Drillerdroid_EditorDraw(void)
1399
{
1400
RSDK_THIS(Drillerdroid);
1401
1402
Drillerdroid->pistonPos[0] = 0;
1403
Drillerdroid->pistonPos[1] = 0;
1404
1405
Drillerdroid->drillPos[0] = 0x100000;
1406
Drillerdroid->drillPos[1] = 0x100000;
1407
1408
self->drawFX = FX_NONE;
1409
RSDK.SetSpriteAnimation(Drillerdroid->aniFrames, 0, &self->mainAnimator, true, 0);
1410
RSDK.SetSpriteAnimation(Drillerdroid->aniFrames, 5, &self->armorAnimator, true, 0);
1411
1412
Drillerdroid_Draw_Boss();
1413
1414
if (showGizmos()) {
1415
RSDK_DRAWING_OVERLAY(true);
1416
1417
DrawHelpers_DrawArenaBounds(-328, -SCREEN_YSIZE, 324, 96, 1 | 2 | 4 | 8, 0x00C0F0);
1418
1419
if (CollapsingPlatform) {
1420
int32 slot = SceneInfo->entitySlot + 1;
1421
for (int32 s = 0; s < 5; ++s) {
1422
EntityCollapsingPlatform *platform = RSDK_GET_ENTITY(slot++, CollapsingPlatform);
1423
1424
if (platform && platform->classID == CollapsingPlatform->classID)
1425
DrawHelpers_DrawArrow(self->position.x, self->position.y, platform->position.x, platform->position.y, 0xFFFF00, INK_NONE, 0xFF);
1426
}
1427
}
1428
1429
RSDK_DRAWING_OVERLAY(false);
1430
}
1431
}
1432
1433
void Drillerdroid_EditorLoad(void)
1434
{
1435
Drillerdroid->aniFrames = RSDK.LoadSpriteAnimation("LRZ1/Drillerdroid.bin", SCOPE_STAGE);
1436
Drillerdroid->ticFrames = RSDK.LoadSpriteAnimation("Global/TicMark.bin", SCOPE_STAGE);
1437
1438
RSDK_ACTIVE_VAR(Drillerdroid, type);
1439
RSDK_ENUM_VAR("Drillerdroid", DRILLERDROID_MAIN);
1440
}
1441
#endif
1442
1443
void Drillerdroid_Serialize(void) { RSDK_EDITABLE_VAR(Drillerdroid, VAR_UINT8, type); }
1444
1445