]> git.mxchange.org Git - quix0rs-blobwars.git/blob - src/finalBattle.cpp
Don't define variables in header files.
[quix0rs-blobwars.git] / src / finalBattle.cpp
1 /*
2 Copyright (C) 2004-2011 Parallel Realities
3 Copyright (C) 2011-2015 Perpendicular Dimensions
4
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License
7 as published by the Free Software Foundation; either version 2
8 of the License, or (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13
14 See the GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19
20 */
21
22 #include "finalBattle.h"
23
24 void galdovMiniAttack();
25 void galdovFinalFlee1();
26 void blackDroidAttack();
27
28 // ************************ Black Droids for Part 2 *************************************
29
30 void blackDroidFire()
31 {       
32         (self->x < player.x) ? self->face = 0 : self->face = 1;
33         
34         if (!hasClearShot(self))
35                 return;
36         
37         self->setActionFinished(9);
38         self->setThinkTime(2);
39         self->think = &blackDroidFire;
40         
41         addBullet((Entity*)self, 0, 0);
42         
43         self->custom--;
44         if (self->custom == 0)
45         {
46                 self->think = &blackDroidAttack;
47         }
48 }
49
50 void blackDroidDie()
51 {
52         self->health--;
53         Math::removeBit(&self->flags, ENT_FLIES);
54         
55         if (self->health < -10)
56         {
57                 if ((self->health % 3) == 0)
58                 {
59                         addExplosion(self->x, self->y, 35, self);
60                         addSmokeAndFire(self, Math::rrand(-15, 15), Math::rrand(-15, 15), 2);
61                 }
62         }
63         
64         if (self->health <= -60)
65         {
66                 if ((Math::prand() % 2) == 0)
67                 {
68                         dropItems((int)self->x, (int)self->y);
69                         dropItems((int)self->x, (int)self->y);
70                 }
71                 else
72                 {
73                         addItem(100, "Red Keycard", (int)self->x, (int)self->y, "RedKeyCard", 240, 1, ENT_DYING, true);
74                 }
75                 self->active = false;
76                 self->place(9999, 9999);
77         }
78 }
79
80 void blackDroidChasePlayer()
81 {
82         self->think = &blackDroidAttack;
83         
84         (self->x < player.x) ? self->face = 0 : self->face = 1;
85         
86         float dx, dy;
87         
88         Math::calculateSlope(player.x, player.y, self->x, self->y, &dx, &dy);
89         
90         self->dx = (dx * 2);
91         self->dy = (dy * 2);
92         
93         self->setThinkTime(10);
94         self->setActionFinished(10);
95 }
96
97 void blackDroidMoveRandom()
98 {
99         (self->x < player.x) ? self->face = 0 : self->face = 1;
100         
101         self->think = &blackDroidAttack;
102         
103         self->dx = Math::rrand(-200, 200);
104         self->dy = Math::rrand(-200, 200);
105
106         self->dx *= 0.01;
107         self->dy *= 0.01;
108
109         self->setThinkTime(2);
110         self->setActionFinished(Math::rrand(60, 90));
111 }
112
113 void blackDroidAttack()
114 {
115         self->think = blackDroidAttack;
116         self->setThinkTime(2);
117         self->setActionFinished(2);
118         
119         int r = Math::prand() % 15;
120         
121         if (r <= 2)
122         {
123                 self->think = &blackDroidFire;
124                 self->setThinkTime(2);
125                 self->setActionFinished(2);
126                 self->custom = Math::rrand(2, 4) * game.skill;
127         }
128         else if (r < 5)
129         {
130                 self->think = &blackDroidChasePlayer;
131                 self->setThinkTime(2);
132                 self->setActionFinished(2);
133         }
134         else
135         {
136                 self->think = &blackDroidMoveRandom;
137                 self->setThinkTime(2);
138                 self->setActionFinished(2);
139         }
140 }
141
142 void galdovInitBlackDroids()
143 {
144         for (int i = 6 ; i < 10 ; i++)
145         {
146                 if (map.boss[i] == NULL)
147                 {
148                         map.boss[i] = new Boss();
149                 }
150                 debug(("BlackDroid %d init\n", i));
151                 strlcpy(map.boss[i]->name, "BlackDrod", sizeof map.boss[i]->name);
152                 map.boss[i]->health = -90;
153                 map.boss[i]->maxHealth = -90;
154                 map.boss[i]->setSprites(graphics.getSprite("BlackDroidRight", true), graphics.getSprite("BlackDroidLeft", true), graphics.getSprite("BlackDroidDie", true));
155                 map.boss[i]->currentWeapon = &weapon[WP_PLASMARIFLE];
156                 map.boss[i]->face = 0;
157                 map.boss[i]->active = false;
158                 map.boss[i]->place(9999, 9999);
159                 map.boss[i]->immune = 0;
160                 map.boss[i]->setThinkTime(2);
161                 map.boss[i]->think = &blackDroidAttack;
162                 map.boss[i]->react = NULL;
163                 map.boss[i]->die = &blackDroidDie;
164                 map.boss[i]->setActionFinished(120);
165                 Math::addBit(&map.boss[i]->flags, ENT_FLIES);
166                 Math::addBit(&map.boss[i]->flags, ENT_AIMS);
167                 Math::removeBit(&map.boss[i]->flags, ENT_FIRETRAIL);
168         }
169 }
170
171 // ************************ First part of final battle **********************************
172
173 void galdovFinalKeepAlive1()
174 {
175         map.boss[0]->health = 30 * game.skill;
176 }
177
178 void galdovFinalPainThrow()
179 {
180         self->dx = -3;
181         self->dy = -12;
182         
183         self->think = &galdovFinalFlee1;
184         self->setThinkTime(2);
185         self->setActionFinished(140);
186 }
187
188 void galdovFinalDropCrystal()
189 {
190         self->setThinkTime(2);
191         self->setActionFinished(2);
192         
193         int x = (int)player.x >> BRICKSHIFT;
194         int y = (int)player.y >> BRICKSHIFT;
195         x += Math::rrand(-2, 2);
196         y += Math::rrand(-2, 2);
197         
198         Math::limitInt(&x, 2, 62);
199         Math::limitInt(&y, 2, 26);
200         
201         if (map.data[x][y] == MAP_AIR)
202         {
203                 x = x << BRICKSHIFT;
204                 y = y << BRICKSHIFT;
205                 self->x = x;
206                 self->y = y;
207                 addTeleportParticles(self->x + 10, self->y + 10, 50, SND_TELEPORT2);
208                 addItem(101, "Reality Crystal", (int)self->x, (int)self->y, "RealityCrystal", 100, 1, 0, true);
209                 self->think = &galdovFinalPainThrow;
210                 self->react = &galdovFinalKeepAlive1;
211                 Math::removeBit(&self->flags, ENT_FLIES);
212                 Math::removeBit(&self->flags, ENT_FIRETRAIL);
213                 map.setMainBossPart(NULL);
214                 map.boss[0]->health = 30 * game.skill;
215                 map.boss[0]->setSprites(graphics.getSprite("GaldovPain", true), graphics.getSprite("GaldovPain", true), graphics.getSprite("GaldovPain", true));
216                 engine.setInfoMessage("Galdov has dropped the crystal! Quick! Get it!!", 99, INFO_HINT);
217                 audio.playSound(SND_BOSSCUSTOM2, CH_AMBIANCE, x);
218         }
219 }
220
221 void galdovFinalDie()
222 {
223         if (game.missionOverReason == MIS_INPROGRESS)
224         {
225                 game.missionOverReason = MIS_GAMECOMPLETE;
226                 audio.stopMusic();
227                 audio.playSound(SND_BOSSCUSTOM3, CH_AMBIANCE, self->x);
228                 player.health = 10;
229                 self->dx = 5;
230                 self->dy = -6;
231                 self->react = NULL;
232                 Math::removeBit(&self->flags, ENT_FLIES);
233                 Math::removeBit(&self->flags, ENT_FIRETRAIL);
234                 presentPlayerMedal("Final_Battle");
235         }
236         
237         self->setActionFinished(1);
238         self->setThinkTime(1);
239         
240         self->health--;
241         
242         if (self->health > -35)
243                 return;
244         
245         if (self->health == -99)
246         {
247                 checkObjectives(self->name, false);
248         }
249         
250         Math::wrapInt(&self->health, -99, -41);
251         
252         if ((self->health % 3) == 0)
253         {
254                 self->setActionFinished(5);
255                 self->setThinkTime(2);
256                 
257                 self->dx = Math::rrand(-5, 5);
258                 self->dy = Math::rrand(-5, 5);
259                 
260                 addExplosion(self->x, self->y, 50, &player);
261                 addSmokeAndFire(self, Math::rrand(-5, 5), Math::rrand(-5, 5), 2);
262         }
263 }
264
265 void galdovMiniFire()
266 {       
267         (self->x < player.x) ? self->face = 0 : self->face = 1;
268         
269         if (!hasClearShot(self))
270                 return;
271         
272         self->setActionFinished(9);
273         self->setThinkTime(2);
274         self->think = &galdovMiniFire;
275         
276         addBullet((Entity*)self, 0, 0);
277         
278         self->custom--;
279         if (self->custom == 0)
280         {
281                 self->think = &galdovMiniAttack;
282         }
283 }
284
285 void galdovFinalTeleport()
286 {
287         self->setThinkTime(2);
288         self->setActionFinished(2);
289         
290         int x = (int)player.x >> BRICKSHIFT;
291         int y = (int)player.y >> BRICKSHIFT;
292         x += Math::rrand(-10, 10);
293         y += Math::rrand(-10, 10);
294         
295         Math::limitInt(&x, 2, 62);
296         Math::limitInt(&y, 2, 26);
297         
298         if (self == map.boss[0])
299         {
300                 if (self->health < 45 * game.skill)
301                 {
302                         Math::limitInt(&x, 23, 62);
303                         Math::limitInt(&y, 42, 61);
304                         self->currentWeapon = getRandomGaldovWeapon();
305                 }
306         }
307         
308         if (map.data[x][y] == MAP_AIR)
309         {
310                 x = x << BRICKSHIFT;
311                 y = y << BRICKSHIFT;
312                 self->x = x;
313                 self->y = y;
314                 addTeleportParticles(self->x + 10, self->y + 10, 50, SND_TELEPORT2);
315                 self->think = &galdovMiniAttack;
316         }
317 }
318
319 void galdovMiniChasePlayer()
320 {
321         (self->x < player.x) ? self->face = 0 : self->face = 1;
322         
323         float dx, dy;
324         
325         Math::calculateSlope(player.x, player.y, self->x, self->y, &dx, &dy);
326         
327         self->dx = (dx * 2);
328         self->dy = (dy * 2);
329         
330         self->setThinkTime(10);
331         self->setActionFinished(10);
332         self->think = &galdovMiniAttack;
333 }
334
335 void galdovMiniMoveRandom()
336 {
337         self->think = &galdovMiniAttack;
338         
339         if (self->flags & ENT_FLIES)
340         {
341                 self->dx = Math::rrand(-200, 200);
342                 self->dy = Math::rrand(-200, 200);
343         
344                 self->dx *= 0.01;
345                 self->dy *= 0.01;
346         
347                 self->setThinkTime(2);
348                 self->setActionFinished(Math::rrand(60, 90));
349         }
350         else
351         {
352                 self->dy = Math::rrand(-12, 0);
353         
354                 (player.x < self->x) ? self->dx = -3 : self->dx = 3;
355                 
356                 self->think = &galdovMiniAttack;
357                 self->setActionFinished(45);
358         }
359 }
360
361 void galdovMiniAttack()
362 {
363         if (player.health < 1)
364         {
365                 self->dx = self->dy = 0;
366                 return;
367         }
368         
369         (self->x < player.x) ? self->face = 0 : self->face = 1;
370         
371         self->think = &galdovMiniAttack;
372         self->setThinkTime(2);
373         self->setActionFinished(2);
374         
375         int r = Math::prand() % 100;
376         
377         if (r < 10)
378         {
379                 self->think = &galdovMiniFire;
380                 self->custom = Math::rrand(1, 8);
381         }
382         else if (r < 15)
383         {
384                 addTeleportParticles(self->x + 10, self->y + 10, 50, SND_TELEPORT2);
385                 self->x = -9999;
386                 self->y = -9999;
387                 self->setActionFinished(120);
388                 self->setThinkTime(2);
389                 self->think = &galdovFinalTeleport;
390         }
391         else if (r < 80)
392         {
393                 self->think = &galdovMiniChasePlayer;
394         }
395         else if (r < 90)
396         {
397                 self->think = &galdovMiniMoveRandom;
398         }
399         else
400         {
401                 if ((self->flags & ENT_FLIES) && (Math::prand() % 5) == 0)
402                 {
403                         Math::removeBit(&self->flags, ENT_FLIES);
404                         Math::removeBit(&self->flags, ENT_FIRETRAIL);
405                 }
406                 else
407                 {
408                         Math::addBit(&self->flags, ENT_FLIES);
409                         Math::addBit(&self->flags, ENT_FIRETRAIL);
410                 }
411         }
412 }
413
414 void galdovMiniDie()
415 {
416         addExplosion(self->x, self->y, 5, self);
417         dropItems((int)self->x, (int)self->y);
418         self->setThinkTime(2);
419         self->setActionFinished(2);
420         self->active = false;
421         self->place(9999, 9999);
422         
423         // Don't kill it properly(!!)
424         self->health = -1;
425         
426         bool allDead = true;
427         
428         for (int i = 1 ; i < 10 ; i++)
429         {
430                 if (map.boss[i]->health > 0)
431                 {
432                         allDead = false;
433                 }
434         }
435         
436         if (allDead)
437         {
438                 map.boss[0]->think = &galdovFinalDropCrystal;
439                 map.boss[0]->setThinkTime(2);
440                 map.boss[0]->setActionFinished(2);
441         }
442 }
443
444 void galdovRejoin()
445 {
446         debug(("galdovRejoin\n"));
447         
448         for (int i = 1 ; i < 10 ; i++)
449         {
450                 if (map.boss[i] != NULL)
451                 {
452                         addTeleportParticles(map.boss[i]->x + 4, map.boss[i]->y + 4, 75, -1);
453                         
454                         if ((Math::prand() % (2 + (game.skill))) == 0)
455                         {
456                                 dropItems((int)map.boss[i]->x, (int)map.boss[i]->y);
457                         }
458                         
459                         map.boss[i]->place(9999, 9999);
460                         map.boss[i]->active = false;
461                 }
462         }
463         
464         self->setThinkTime(2);
465         self->setActionFinished(120);
466         self->think = &galdovFinalTeleport;
467         self->currentWeapon = getRandomGaldovWeapon();
468         
469         audio.playSound(SND_BOSSCUSTOM1, CH_AMBIANCE, self->x);
470         
471         map.setMainBossPart(map.boss[0]);
472         
473         debug(("galdovRejoin: Done\n"));
474 }
475
476 void galdovFinalMiniReact()
477 {
478         if (self->health > 0)
479         {
480                 map.setMainBossPart(self);
481         }
482         else
483         {
484                 map.setMainBossPart(NULL);
485         }
486 }
487
488 void galdovFinalSplit()
489 {
490         debug(("galdovFinalSplit\n"));
491         
492         for (int i = 1 ; i < 10 ; i++)
493         {
494                 if (map.boss[i] == NULL)
495                 {
496                         map.boss[i] = new Boss();
497                         strlcpy(map.boss[i]->name, "MiniGaldov", sizeof map.boss[i]->name);
498                         map.boss[i]->health = 10 * game.skill;
499                         map.boss[i]->maxHealth = 10 * game.skill;
500                 }
501                 map.boss[i]->setSprites(graphics.getSprite("GaldovMiniRight", true), graphics.getSprite("GaldovMiniLeft", true), graphics.getSprite("GaldovMiniLeft", true));
502                 map.boss[i]->currentWeapon = getRandomAimedWeapon();
503                 map.boss[i]->face = 0;
504                 map.boss[i]->active = true;
505                 
506                 if (map.boss[i]->health > 0)
507                 {
508                         map.boss[i]->dx = Math::rrand(-2, 2);
509                         map.boss[i]->dy = Math::rrand(-2, 2);
510                         map.boss[i]->x = map.boss[0]->x;
511                         map.boss[i]->y = map.boss[0]->y;
512                 }
513                 else
514                 {
515                         map.boss[i]->active = false;
516                 }
517                 
518                 map.boss[i]->immune = 0;
519                 map.boss[i]->setThinkTime(2);
520                 map.boss[i]->setActionFinished(120);
521                 map.boss[i]->think = &galdovMiniAttack;
522                 map.boss[i]->react = &galdovFinalMiniReact;
523                 map.boss[i]->die = &galdovMiniDie;
524                 Math::addBit(&map.boss[i]->flags, ENT_AIMS);
525                 Math::addBit(&map.boss[i]->flags, ENT_FLIES);
526                 Math::addBit(&map.boss[i]->flags, ENT_FIRETRAIL);
527                 
528                 addTeleportParticles(map.boss[i]->x + 10 + map.boss[i]->dx, map.boss[i]->y + 10 + map.boss[i]->dy, 75, -1);
529         }
530         
531         audio.playSound(SND_BOSSCUSTOM1, CH_AMBIANCE, map.boss[0]->x);
532
533         map.boss[0]->place(9999, 9999);
534         map.boss[0]->setThinkTime(2);
535         map.boss[0]->setActionFinished(Math::rrand(10, 15) * 60);
536         map.boss[0]->think = &galdovRejoin;
537         map.boss[0]->active = true;
538         
539         map.setMainBossPart(NULL);
540         
541         debug(("galdovFinalSplit: Done\n"));
542 }
543
544 void galdovFinalReact()
545 {
546         map.boss[0]->health = 45 * game.skill;
547         
548         if ((Math::prand() % 5) == 0)
549         {
550                 map.boss[0]->setThinkTime(2);
551                 map.boss[0]->setActionFinished(2);
552                 map.boss[0]->think = &galdovFinalSplit;
553         }
554 }
555
556 void galdovFinalInit()
557 {
558         debug(("galdovFinalInit\n"));
559         
560         map.boss[0] = new Boss();
561         strlcpy(map.boss[0]->name, "Galdov", sizeof map.boss[0]->name);
562         map.boss[0]->health = 45 * game.skill;
563         map.boss[0]->maxHealth = 45 * game.skill;
564         map.boss[0]->setSprites(graphics.getSprite("GaldovRight", true), graphics.getSprite("GaldovLeft", true), graphics.getSprite("GaldovDie", true));
565         map.boss[0]->currentWeapon = &weapon[WP_AIMEDPISTOL];
566         map.boss[0]->face = 0;
567         map.boss[0]->active = true;
568         map.boss[0]->x = 480;
569         map.boss[0]->y = 576;
570         map.boss[0]->immune = 0;
571         map.boss[0]->setThinkTime(2);
572         map.boss[0]->setActionFinished(2);
573         map.boss[0]->think = &galdovMiniAttack;
574         //map.boss[0]->think = &galdovFinalDropCrystal;
575         map.boss[0]->react = &galdovFinalReact;
576         map.boss[0]->die = &galdovFinalDie;
577         Math::addBit(&map.boss[0]->flags, ENT_AIMS);
578         
579         audio.loadSound(SND_BOSSCUSTOM1, "sound/galdovSplit");
580         audio.loadSound(SND_BOSSCUSTOM2, "sound/galdovPain");
581         audio.loadSound(SND_BOSSCUSTOM3, "sound/galdovDie");
582         
583         map.setMainBossPart(map.boss[0]);
584         
585         debug(("galdovFinalInit: Done\n"));
586 }
587
588 // ******************** Second part of Final Battle *********************************
589
590 void galdovFinalReact2()
591 {
592         if (self->health < 1)
593                 return;
594         
595         if ((Math::prand() % 12) == 0)
596         {
597                 addTeleportParticles(self->x + (self->width / 2), self->y + (self->height / 2), 50, SND_TELEPORT3);
598                 map.boss[0]->setThinkTime(2);
599                 map.boss[0]->setActionFinished(2);
600                 map.boss[0]->think = &galdovFinalTeleport;
601         }
602 }
603
604 void galdovFinalStandUp()
605 {
606         map.boss[0]->setSprites(graphics.getSprite("GaldovShieldRight", true), graphics.getSprite("GaldovShieldLeft", true), graphics.getSprite("GaldovShieldLeft", true));
607         self->setThinkTime(2);
608         self->setActionFinished(2);
609         addTeleportParticles(self->x + (self->width / 2), self->y + (self->height / 2), 50, SND_TELEPORT3);
610         self->think = &galdovFinalTeleport;
611         
612         if (map.boss[0]->health <= 15 * game.skill)
613         {
614                 self->setSprites(graphics.getSprite("GaldovRight", true), graphics.getSprite("GaldovLeft", true), graphics.getSprite("GaldovDie", true));
615                 Math::removeBit(&map.boss[0]->flags, ENT_IMMUNE);
616                 map.boss[0]->react = &galdovFinalReact2;
617         }
618 }
619
620 void galdovFinalPainThrow2()
621 {
622         self->dx = -3;
623         self->dy = -12;
624         
625         self->think = &galdovFinalStandUp;
626         self->setThinkTime(2);
627         self->setActionFinished(90);
628 }
629
630 void orbSeekGaldov()
631 {
632         (self->x < player.x) ? self->face = 0 : self->face = 1;
633         
634         float dx, dy;
635         
636         Math::calculateSlope(map.boss[0]->x, map.boss[0]->y, self->x, self->y, &dx, &dy);
637         
638         self->dx = (dx * (1 + game.skill));
639         self->dy = (dy * (1 + game.skill));
640         
641         self->setThinkTime(2);
642         self->setActionFinished(5);
643         self->think = &orbSeekGaldov;
644         
645         int distX = (int)fabs(map.boss[0]->x - self->x);
646         int distY = (int)fabs(map.boss[0]->y - self->y);
647
648         distX *= distX;
649         distY *= distY;
650
651         int distance = (int)sqrt(distX + distY);
652         
653         if (distance <= 10)
654         {
655                 self->active = false;
656                 self->setActionFinished(60);
657                 self->setThinkTime(60);
658                 addExplosion(self->x, self->y, 75, &player);
659                 audio.playSound(SND_BOSSCUSTOM2, CH_AMBIANCE, self->x);
660                 self->place(9999, 9999);
661                 map.boss[0]->setSprites(graphics.getSprite("GaldovPain", true), graphics.getSprite("GaldovPain", true), graphics.getSprite("GaldovPain", true));
662                 map.boss[0]->think = &galdovFinalPainThrow2;
663                 map.boss[0]->health -= (3 * game.skill);
664                 Math::removeBit(&map.boss[0]->flags, ENT_FLIES);
665                 Math::removeBit(&map.boss[0]->flags, ENT_FIRETRAIL);
666         }
667 }
668
669 void galdovFinalShieldInit()
670 {
671         self->setActionFinished(60);
672         self->setThinkTime(60);
673         self->think = &galdovMiniAttack;
674         self->react = NULL;
675         
676         Math::addBit(&map.boss[0]->flags, ENT_IMMUNE);
677         
678         for (int i = 1 ; i < 6 ; i++)
679         {
680                 if (map.boss[i] != NULL)
681                 {
682                         delete map.boss[i];
683                 }
684                 map.boss[i] = new Boss();
685                 strlcpy(map.boss[i]->name, "OrbBomb", sizeof map.boss[i]->name);
686                 map.boss[i]->setSprites(graphics.getSprite("DroidOrb", true), graphics.getSprite("DroidOrb", true), graphics.getSprite("DroidOrb", true));
687                 map.boss[i]->health = 999999;
688                 map.boss[i]->maxHealth = 99999;
689                 map.boss[i]->immune = 0;
690                 Math::addBit(&map.boss[0]->flags, ENT_IMMUNE);
691                 map.boss[i]->active = false;
692                 map.boss[i]->setActionFinished(2);
693                 map.boss[i]->setThinkTime(2);
694                 map.boss[i]->think = &orbSeekGaldov;
695                 map.boss[i]->react = NULL;
696                 Math::addBit(&map.boss[i]->flags, ENT_FLIES);
697         }
698         
699         map.boss[1]->place(864, 1536);
700         map.boss[2]->place(864, 1792);
701         map.boss[3]->place(1856, 1792);
702         map.boss[4]->place(1888, 1440);
703         map.boss[5]->place(1408, 1472);
704         
705         galdovInitBlackDroids();
706 }
707
708 void galdovFinalWaitForObjective()
709 {
710         self->setActionFinished(120);
711         self->setThinkTime(2);
712         
713         Objective *objective = (Objective*)map.objectiveList.getHead();
714
715         while (objective->next != NULL)
716         {
717                 objective = (Objective*)objective->next;
718
719                 if (strstr(objective->target, "Reality"))
720                 {
721                         if (objective->completed)
722                         {
723                                 player.dx = 1000;
724                                 player.dy = 1408;
725                                 Math::addBit(&player.flags, ENT_TELEPORTING);
726                                 self->think = &galdovFinalShieldInit;
727                                 map.boss[0]->setSprites(graphics.getSprite("GaldovShieldRight", true), graphics.getSprite("GaldovShieldLeft", true), graphics.getSprite("GaldovShieldLeft", true));
728                                 self->setActionFinished(2);
729                                 self->setThinkTime(2);
730                                 map.setMainBossPart(map.boss[0]);
731                         }
732                 }
733         }
734 }
735
736 void galdovFinalFlee1()
737 {
738         self->dx = 800;
739         self->dy = 1408;
740         addTeleportParticles(self->x + (self->width / 2), self->y + (self->height / 2), 50, SND_TELEPORT3);
741         Math::addBit(&self->flags, ENT_TELEPORTING);
742         Math::addBit(&self->flags, ENT_FLIES);
743         Math::addBit(&self->flags, ENT_FIRETRAIL);
744         self->think = &galdovFinalWaitForObjective;
745         self->setActionFinished(2);
746         self->setThinkTime(2);
747 }