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