2 Copyright (C) 2004 Parallel Realities
3 Copyright (C) 2007 Kővágó Zoltán
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.
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.
14 See the GNU General Public License for more details.
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.
23 #include "console/console.hpp"
26 void galdovCheckSplit();
30 (self
->x
< player
.x
) ? self
->face
= 0 : self
->face
= 1;
43 color
= graphics
.yellow
;
46 color
= graphics
.green
;
49 color
= graphics
.cyan
;
52 color
= graphics
.white
;
56 for (int i
= 0 ; i
< 20 ; i
++)
58 dy
= Math::rrand(-150, -50);
60 map
.addParticle(self
->x
+ (rand() % self
->width
), self
->y
+ (rand() % self
->height
), dx
, dy
, Math::rrand(1, 60), color
, NULL
, PAR_WEIGHTLESS
);
63 self
->setThinkTime(1);
64 self
->setActionFinished(1);
65 self
->think
= &splitParticles
;
68 if (self
->custom
== 0)
70 self
->setThinkTime(2);
71 self
->setActionFinished(2);
72 self
->think
= &galdovAttack
;
74 if (self
== map
.boss
[0])
76 if ((rand() % self
->health
) == 0)
78 self
->think
= &galdovCheckSplit
;
87 self
->setThinkTime(2);
88 self
->setActionFinished(2);
90 int x
= (int)player
.x
>> BRICKSHIFT
;
91 int y
= (int)player
.y
>> BRICKSHIFT
;
92 x
+= Math::rrand(-10, 10);
93 y
+= Math::rrand(-10, 10);
95 Math::limitInt(&x
, 1, 28);
96 Math::limitInt(&y
, 259, 283);
98 if (map
.data
[x
][y
] == MAP_AIR
)
104 addTeleportParticles(self
->x
+ 10, self
->y
+ 10, 50, SND_TELEPORT2
);
105 self
->think
= &galdovAttack
;
111 if (self
->health
< 0)
118 self
->setThinkTime(2);
119 self
->setActionFinished(2);
120 self
->think
= &galdovTeleport
;
126 self
->setThinkTime(2);
127 self
->setActionFinished(2);
128 self
->think
= &galdovCheckSplit
;
133 void galdovSplit(int i
)
135 audio
.playSound(SND_BOSSCUSTOM1
, CH_AMBIANCE
);
137 map
.boss
[i
]->active
= true;
138 map
.boss
[i
]->health
= 4 * game
.skill
;
139 map
.boss
[i
]->maxHealth
= 4 * game
.skill
;
140 map
.boss
[i
]->x
= map
.boss
[0]->x
;
141 map
.boss
[i
]->y
= map
.boss
[0]->y
;
142 map
.boss
[i
]->flags
= map
.boss
[0]->flags
;
143 map
.boss
[i
]->think
= &galdovAttack
;
145 if ((rand() % 2) == 0)
147 map
.boss
[i
]->currentWeapon
= getRandomAimedWeapon();
148 Math::addBit(&map
.boss
[i
]->flags
, ENT_AIMS
);
152 map
.boss
[i
]->currentWeapon
= getRandomStraightWeapon();
153 Math::removeBit(&map
.boss
[i
]->flags
, ENT_AIMS
);
156 if ((rand() % 2) == 0)
158 map
.boss
[0]->dx
= -.5;
160 map
.boss
[i
]->dx
= .5;
165 map
.boss
[0]->dx
= .5;
167 map
.boss
[i
]->dx
= -.5;
171 map
.boss
[0]->think
= &splitParticles
;
172 map
.boss
[0]->setThinkTime(1);
173 map
.boss
[0]->setActionFinished(1);
174 map
.boss
[0]->custom
= 60;
176 map
.boss
[i
]->think
= &splitParticles
;
177 map
.boss
[i
]->setThinkTime(1);
178 map
.boss
[i
]->setActionFinished(1);
179 map
.boss
[i
]->custom
= 60;
182 void galdovCheckSplit()
184 for (int i
= 1 ; i
< 10 ; i
++)
186 if (!map
.boss
[i
]->active
)
196 (self
->x
< player
.x
) ? self
->face
= 0 : self
->face
= 1;
198 self
->setActionFinished(9);
199 self
->setThinkTime(2);
200 self
->think
= &galdovFire
;
202 if (hasClearShot(self
))
204 self
->flags
& ENT_AIMS
? addBullet((Entity
*)self
, 0, 0) : addBullet((Entity
*)self
, self
->currentWeapon
->getSpeed(self
->face
), 0);
206 if (self
->currentWeapon
== &weapon
[WP_ALIENSPREAD
])
208 addBullet(self
, self
->currentWeapon
->getSpeed(self
->face
), 2);
209 addBullet(self
, self
->currentWeapon
->getSpeed(self
->face
), -2);
214 if (self
->custom
== 0)
216 self
->think
= &galdovAttack
;
220 void galdovRocketAttack()
222 (self
->x
< player
.x
) ? self
->face
= 0 : self
->face
= 1;
224 if (!hasClearShot(self
))
227 self
->setActionFinished(5);
228 self
->setThinkTime(2);
229 self
->think
= &galdovRocketAttack
;
231 addBullet((Entity
*)self
, 0, 0);
235 if (self
->custom
== 0)
237 self
->think
= &galdovAttack
;
238 self
->currentWeapon
= getRandomGaldovWeapon();
242 void galdovChasePlayer()
244 (self
->x
< player
.x
) ? self
->face
= 0 : self
->face
= 1;
248 Math::calculateSlope(player
.x
, player
.y
, self
->x
, self
->y
, &dx
, &dy
);
253 self
->setThinkTime(10);
254 self
->setActionFinished(10);
255 self
->think
= &galdovAttack
;
258 void galdovMoveRandom()
260 self
->think
= &galdovAttack
;
262 if (self
->flags
& ENT_FLIES
)
264 self
->dx
= Math::rrand(-200, 200);
265 self
->dy
= Math::rrand(-200, 200);
270 self
->setThinkTime(2);
271 self
->setActionFinished(Math::rrand(60, 90));
275 self
->dy
= Math::rrand(-12, 0);
277 (player
.x
< self
->x
) ? self
->dx
= -3 : self
->dx
= 3;
279 self
->think
= &galdovAttack
;
280 self
->setActionFinished(45);
284 void galdovDoInvisible()
286 if ((rand() % 2) == 0)
288 map
.boss
[0]->setSprites(graphics
.getSprite("GaldovRight", true), graphics
.getSprite("GaldovLeft", true), graphics
.getSprite("GaldovLeft", true));
292 map
.boss
[0]->setSprites(graphics
.getSprite("GaldovInvsRight", true), graphics
.getSprite("GaldovInvsLeft", true), graphics
.getSprite("GaldovInvsLeft", true));
295 self
->setThinkTime(2);
296 self
->setActionFinished(2);
297 self
->think
= &galdovAttack
;
302 if (player
.health
< 1)
304 self
->dx
= self
->dy
= 0;
308 (self
->x
< player
.x
) ? self
->face
= 0 : self
->face
= 1;
310 self
->think
= &galdovAttack
;
311 self
->setThinkTime(2);
312 self
->setActionFinished(2);
314 int r
= rand() % 100;
318 self
->think
= &galdovFire
;
319 self
->custom
= Math::rrand(1, 8);
323 // Make sure only the real Galdov does this!
324 if (self
== map
.boss
[0])
326 addTeleportParticles(self
->x
+ 10, self
->y
+ 10, 50, SND_TELEPORT2
);
329 self
->setActionFinished(120);
330 self
->setThinkTime(2);
331 self
->think
= &galdovTeleport
;
336 self
->think
= &galdovChasePlayer
;
340 self
->think
= &galdovMoveRandom
;
344 if ((self
->flags
& ENT_FLIES
) && (rand() % 5) == 0)
346 Math::removeBit(&self
->flags
, ENT_FLIES
);
347 Math::removeBit(&self
->flags
, ENT_FIRETRAIL
);
351 Math::addBit(&self
->flags
, ENT_FLIES
);
352 Math::addBit(&self
->flags
, ENT_FIRETRAIL
);
357 if (self
== map
.boss
[0])
359 self
->think
= &galdovDoInvisible
;
364 map
.boss
[0]->currentWeapon
= getRandomGaldovWeapon();
368 // Make sure only the real Galdov does this!
369 if (self
== map
.boss
[0])
371 self
->custom
= Math::rrand(4, 8);
372 self
->currentWeapon
= &weapon
[WP_ROCKETS
];
373 self
->think
= &galdovRocketAttack
;
378 // Make sure only the real Galdov does this!
379 if (self
== map
.boss
[0])
381 self
->think
= &galdovCheckSplit
;
390 if (map
.mainBossPart
!= NULL
)
392 map
.mainBossPart
= NULL
;
393 audio
.playSound(SND_BOSSCUSTOM2
, CH_AMBIANCE
);
396 if ((self
->health
% 5) == 0)
398 self
->setActionFinished(5);
399 self
->setThinkTime(2);
401 self
->dx
= Math::rrand(-5, 5);
402 self
->dy
= Math::rrand(-5, 5);
404 addExplosion(self
->x
, self
->y
, 5, &player
);
405 addSmokeAndFire(self
, Math::rrand(-4, 4), Math::rrand(-4, 4), 2);
408 for (int i
= 1 ; i
< 10 ; i
++)
410 if (map
.boss
[i
]->health
> -1)
412 map
.boss
[i
]->health
= -1;
416 if (self
->health
<= -100)
418 checkObjectives(self
->name
, false);
419 map
.mainBossPart
= NULL
;
420 addTeleportParticles(self
->x
, self
->y
, 75, SND_TELEPORT3
);
424 void dropItems(int x
, int y
)
428 for (int i
= 0 ; i
< 2 ; i
++)
430 r
= Math::rrand(ITEM_PISTOL
, ITEM_DOUBLECHERRY
);
432 // Grenades make this battle far too easy(!)
433 if (r
== ITEM_GRENADES
)
436 if ((rand() % 10) == 0)
437 r
= ITEM_TRIPLECHERRY
;
439 addItem(defItem
[r
].id
, defItem
[r
].name
, x
, y
, defItem
[r
].sprite
[0]->name
, 240, defItem
[r
].value
, ENT_DYING
, true);
445 dropItems((int)self
->x
, (int)self
->y
);
447 addExplosion(self
->x
, self
->y
, 50, self
);
448 self
->setThinkTime(2);
449 self
->setActionFinished(2);
450 self
->active
= false;
458 debug
<< "galdovInit" << std::endl
;
460 map
.boss
[0] = new Boss();
461 strcpy(map
.boss
[0]->name
, "Galdov");
462 map
.boss
[0]->health
= 45 * game
.skill
;
463 map
.boss
[0]->maxHealth
= 45 * game
.skill
;
464 map
.boss
[0]->setSprites(graphics
.getSprite("GaldovRight", true), graphics
.getSprite("GaldovLeft", true), graphics
.getSprite("GaldovLeft", true));
465 map
.boss
[0]->currentWeapon
= &weapon
[WP_AIMEDPISTOL
];
466 map
.boss
[0]->face
= 0;
467 map
.boss
[0]->active
= true;
468 map
.boss
[0]->x
= 448;
469 map
.boss
[0]->y
= 9024;
470 map
.boss
[0]->immune
= 0;
471 map
.boss
[0]->setThinkTime(2);
472 map
.boss
[0]->setActionFinished(2);
473 map
.boss
[0]->think
= &galdovCheckSplit
;
474 map
.boss
[0]->react
= &galdovReact
;
475 map
.boss
[0]->die
= &galdovDie
;
477 Math::addBit(&map
.boss
[0]->flags
, ENT_AIMS
);
479 SDL_SetAlpha(graphics
.getSprite("GaldovInvsLeft", true)->image
[0], SDL_SRCALPHA
|SDL_RLEACCEL
, 100);
480 SDL_SetAlpha(graphics
.getSprite("GaldovInvsRight", true)->image
[0], SDL_SRCALPHA
|SDL_RLEACCEL
, 100);
482 for (int i
= 1 ; i
< 10 ; i
++)
484 map
.boss
[i
] = new Boss();
485 strcpy(map
.boss
[i
]->name
, "Fake");
486 map
.boss
[i
]->setSprites(graphics
.getSprite("GaldovRight", true), graphics
.getSprite("GaldovLeft", true), graphics
.getSprite("GaldovLeft", true));
487 map
.boss
[i
]->x
= 9999;
488 map
.boss
[i
]->y
= 9999;
489 map
.boss
[i
]->active
= false;
490 map
.boss
[i
]->think
= &galdovAttack
;
491 map
.boss
[i
]->react
= NULL
;
492 map
.boss
[i
]->die
= &fakeDie
;
495 map
.setMainBossPart(map
.boss
[0]);
497 audio
.loadSound(SND_BOSSCUSTOM1
, "sound/galdovSplit.wav");
498 audio
.loadSound(SND_BOSSCUSTOM2
, "sound/galdovPain.wav");
500 debug
<< "galdovInit: Done" << std::endl
;