2 Copyright (C) 2004 Parallel Realities
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.
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.
13 See the GNU General Public License for more details.
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.
23 // **************** Machine Gun Boss ***********************
25 void tankBossMGFight();
26 void tankBossGLFight();
27 void activateGLBoss();
30 * Adds a load of particles within an area of the specified location
31 * @param x The x location
32 * @param y The y location
34 void plasmaBurstTraceParticles(int x, int y)
38 for (int i = 0 ; i < 7 ; i++)
40 color[i] = SDL_MapRGB(graphics.screen->format, 0, 100 + (i * 20), 0);
45 for (int i = 0 ; i < 25 ; i++)
47 dx = Math::rrand(0, 5);
54 map.addParticle(x + Math::rrand(-6, 6), y + Math::rrand(-2, 2), dx, 0, Math::rrand(1, 90), color[Math::rrand(0, 6)], NULL, PAR_WEIGHTLESS);
59 * Adds particles to the front of the MG Tank Boss's gun
61 void plasmaChargeParticles()
64 int y = (int)self->y + 10;
68 x += self->getFaceImage()->w;
73 for (int i = 0 ; i < 2 ; i++)
75 dx = Math::rrand(-30, 30); dx /= 90;
76 dy = Math::rrand(-30, 30); dy /= 90;
77 map.addParticle(x, y, dx, dy, Math::rrand(30, 60), graphics.green, NULL, PAR_WEIGHTLESS);
82 * Traces a line from the MG Tank Boss to 800 pixel in the
83 * direction it is facing. Anything in the path is killed immediately.
85 void traceTankBossMGFireLine()
95 int y = (int)self->y + 10;
99 for (int i = 0 ; i < 800 ; i++)
105 x += self->getFaceImage()->w;
110 plasmaBurstTraceParticles(x, y);
112 if (Collision::collision(player.x, player.y, 20, 20, x - 1, y - 1, 2, 2))
114 throwAndDamageEntity(&player, 100, dx * 10, dx * 10, 0);
116 for (int i = 0 ; i < 10 ; i++)
118 addExplosion(player.x + Math::rrand(-25, 25), player.y + Math::rrand(-25, 25), 10, self);
122 enemy = (Entity*)map.enemyList.getHead();
124 while (enemy->next != NULL)
126 enemy = (Entity*)enemy->next;
128 if (Collision::collision(enemy->x, enemy->y, enemy->getFaceImage()->w, enemy->getFaceImage()->h, x - 1, y - 1, 2, 2))
130 throwAndDamageEntity(enemy, 100, dx * 10, dx * 10, 0);
134 for (int i = 0 ; i < 10 ; i++)
136 addExplosion(enemy->x + Math::rrand(-25, 25), enemy->y + Math::rrand(-25, 25), 10, self);
142 self->setThinkTime(2);
143 self->setActionFinished(90);
144 Math::removeBit(&self->flags, ENT_IMMUNE);
145 self->think = &tankBossMGFight;
149 * Tells the Machine Gun Tank to fire it's beam laser
151 void tankBossMGCannonFire()
153 self->setThinkTime(2);
154 self->setActionFinished(2);
155 self->think = &tankBossMGCannonFire;
157 traceTankBossMGFireLine();
161 * Tells the Machine Gun boss to begin charging it's
162 * cannon and play the appropriate sound
164 void tankBossMGCannonChargeFire()
166 plasmaChargeParticles();
168 self->setActionFinished(2);
172 if (self->custom == 0)
174 self->think = tankBossMGCannonFire;
175 audio.playSound(SND_BOSSCUSTOM2, CH_AMBIANCE);
179 void tankBossMGRapidFire()
181 (self->x < player.x) ? self->face = 0 : self->face = 1;
183 addBullet((Entity*)self, 0, 0);
185 self->think = &tankBossMGRapidFire;
186 self->setActionFinished(4);
189 if (self->custom <= 0)
191 self->think = &tankBossMGFight;
192 self->setThinkTime(2);
193 self->setActionFinished(90);
197 void tankBossMGFire()
199 (self->x < player.x) ? self->face = 0 : self->face = 1;
201 addBullet((Entity*)self, 0, 0);
203 self->think = &tankBossMGFire;
204 self->setActionFinished(15);
207 if (self->custom <= 0)
209 self->think = &tankBossMGFight;
210 self->setThinkTime(2);
211 self->setActionFinished(60);
215 void tankBossMGJump()
219 (player.x < self->x) ? self->dx = -6 : self->dx = 6;
221 self->think = &tankBossMGFight;
222 self->setActionFinished(45);
227 self->setThinkTime(60);
228 self->setActionFinished(60);
229 self->health -= Math::rrand(1, 2);
231 // don't hurt the player(!)
232 addExplosion(self->x, self->y, 50, &player);
233 addSmokeAndFire(self, Math::rrand(-5, 5), Math::rrand(-5, 5), 2);
234 addBlood(self, Math::rrand(-5, 5), Math::rrand(-5, 5), 3);
236 if ((Math::prand() % 5) == 0)
238 self->dx = Math::rrand(-15, 15);
239 self->dy = Math::rrand(-8, 0);
242 if (self->health <= -100)
244 checkObjectives(self->name, false);
250 void tankBossMGAttack()
252 (player.x > self->x) ? self->face = 0 : self->face = 1;
254 int r = Math::prand() % 12;
258 self->custom = Math::rrand(1, 6);
259 self->think = &tankBossMGFire;
260 self->setThinkTime(0);
261 self->setActionFinished(2);
265 self->custom = Math::rrand(35, 80);
266 self->think = &tankBossMGCannonChargeFire;
267 self->setThinkTime(0);
268 self->setActionFinished(2);
269 audio.playSound(SND_BOSSCUSTOM1, CH_AMBIANCE);
270 Math::addBit(&self->flags, ENT_IMMUNE);
275 self->think = &tankBossMGRapidFire;
276 self->setThinkTime(0);
277 self->setActionFinished(2);
281 void tankBossMGFight()
283 if (player.health < 1)
289 int r = Math::prand() % 10;
293 if (player.x - 320 < self->x)
295 else if (player.x + 320 > self->x)
298 self->dx = Math::rrand(-2, 2);
300 (self->x < player.x) ? self->face = 0 : self->face = 1;
301 self->setActionFinished(60);
302 self->setThinkTime(1);
306 self->think = &tankBossMGJump;
307 self->setActionFinished(2);
308 self->setThinkTime(2);
313 self->setThinkTime(2);
314 self->think = &tankBossMGAttack;
318 void activateGLBoss()
320 if (map.boss[1] == NULL)
322 map.mainBossPart = NULL;
326 map.boss[1]->active = true;
327 map.boss[1]->dx = Math::rrand(416, 928);
328 map.boss[1]->dy = 8576;
329 map.boss[1]->setThinkTime(2);
330 map.boss[1]->setActionFinished(2);
331 map.boss[1]->think = &tankBossGLFight;
332 Math::addBit(&map.boss[1]->flags, ENT_TELEPORTING);
334 map.setMainBossPart(map.boss[1]);
337 void tankBossMGSwap()
339 // Machine Gun Boss wait state
340 self->active = false;
343 // Grenade launcher boss active state
347 void tankBossMGReact()
349 if (map.boss[1] == NULL)
354 if (self->flags & ENT_IMMUNE)
359 if ((Math::prand() % 25) > 0)
366 self->think = &tankBossMGSwap;
367 self->setThinkTime(2);
368 self->setActionFinished(2);
369 Math::addBit(&self->flags, ENT_TELEPORTING);
372 void tankBossMGStart()
374 self->dx = Math::rrand(416, 928);
376 Math::addBit(&self->flags, ENT_TELEPORTING);
377 self->think = &tankBossMGFight;
380 void tankBossMGInit()
382 debug(("tankBossMGInit\n"));
384 map.boss[0] = new Boss();
385 strcpy(map.boss[0]->name, "BioMech Tank V1.1");
386 map.boss[0]->health = 65 * game.skill;
387 map.boss[0]->maxHealth = 65 * game.skill;
388 map.boss[0]->setSprites(graphics.getSprite("BlobTankCannonRight", true), graphics.getSprite("BlobTankCannonLeft", true), graphics.getSprite("BlobTankCannonLeft", true));
389 map.boss[0]->currentWeapon = &weapon[WP_PLASMARIFLE];
390 map.boss[0]->face = 0;
391 map.boss[0]->active = false;
392 map.boss[0]->x = 900;
393 map.boss[0]->y = 8256;
394 map.boss[0]->immune = 0;
395 map.boss[0]->setThinkTime(1);
396 map.boss[0]->setActionFinished(1);
397 map.boss[0]->think = &tankBossMGStart;
398 map.boss[0]->react = &tankBossMGReact;
399 map.boss[0]->die = &tankBossMGDie;
400 Math::addBit(&map.boss[0]->flags, ENT_AIMS);
402 audio.loadSound(SND_BOSSCUSTOM1, "sound/tankBeam.wav");
403 audio.loadSound(SND_BOSSCUSTOM2, "sound/tankBeamFire.wav");
405 map.setMainBossPart(map.boss[0]);
407 debug(("tankBossMGInit: Done\n"));
410 // **************** Grenade Launcher Boss ***********************
412 void tankBossGLJump()
416 (player.x < self->x) ? self->dx = -6 : self->dx = 6;
418 self->think = &tankBossGLFight;
419 self->setActionFinished(45);
422 void tankBossGLRapidFire()
424 (self->x < player.x) ? self->face = 0 : self->face = 1;
426 addBullet((Entity*)self, 0, 0);
428 self->think = &tankBossGLRapidFire;
429 self->setActionFinished(4);
432 if (self->custom <= 0)
434 self->think = &tankBossGLFight;
435 self->setThinkTime(2);
436 self->setActionFinished(90);
440 void tankBossGLMortor()
442 (self->x < player.x) ? self->face = 0 : self->face = 1;
444 int speed = Math::rrand(3, 5);
448 addBullet((Entity*)self, speed, 0);
450 self->think = &tankBossGLMortor;
451 self->setActionFinished(20);
454 if (self->custom <= 0)
456 self->think = &tankBossGLFight;
457 self->setThinkTime(2);
458 self->setActionFinished(60);
462 void tankBossGLAttack()
464 (player.x > self->x) ? self->face = 0 : self->face = 1;
466 int r = Math::prand() % 10;
470 Math::removeBit(&self->flags, ENT_AIMS);
471 self->currentWeapon = getWeaponByName("Mortor Shells");
472 self->think = &tankBossGLMortor;
473 self->setThinkTime(0);
474 self->setActionFinished(2);
475 self->custom = Math::rrand(2, 5);
479 Math::addBit(&self->flags, ENT_AIMS);
480 self->currentWeapon = getWeaponByName("Aimed Pistol");
482 self->think = &tankBossGLRapidFire;
483 self->setThinkTime(0);
484 self->setActionFinished(2);
488 self->custom = Math::rrand(45, 60);
489 //self->think = &tankBossGLCannonChargeFire;
490 self->setThinkTime(0);
491 self->setActionFinished(2);
495 void tankBossGLFight()
497 if (player.health < 1)
503 int r = Math::prand() % 10;
507 if (player.x - 320 < self->x)
509 else if (player.x + 320 > self->x)
512 self->dx = Math::rrand(-2, 2);
514 (self->x < player.x) ? self->face = 0 : self->face = 1;
515 self->setActionFinished(60);
516 self->setThinkTime(1);
520 self->think = &tankBossGLJump;
521 self->setActionFinished(2);
522 self->setThinkTime(2);
527 self->setThinkTime(2);
528 self->think = &tankBossGLAttack;
532 void activateMGBoss()
534 if (map.boss[0] == NULL)
536 map.mainBossPart = NULL;
540 map.boss[0]->active = true;
541 map.boss[0]->dx = Math::rrand(416, 928);
542 map.boss[0]->dy = 8576;
543 map.boss[0]->setThinkTime(2);
544 map.boss[0]->setActionFinished(2);
545 map.boss[0]->think = &tankBossMGFight;
546 Math::addBit(&map.boss[0]->flags, ENT_TELEPORTING);
548 map.setMainBossPart(map.boss[0]);
551 void tankBossGLSwap()
553 // Grenade launcher Boss wait state
554 self->active = false;
557 // Machine Gun boss active state
561 void tankBossGLReact()
563 if (map.boss[0] == NULL)
566 if ((Math::prand() % 25) > 0)
571 self->think = &tankBossGLSwap;
572 self->setThinkTime(2);
573 self->setActionFinished(2);
574 Math::addBit(&self->flags, ENT_TELEPORTING);
579 self->setThinkTime(60);
580 self->setActionFinished(60);
581 self->health -= Math::rrand(1, 2);
583 // don't hurt the player(!)
584 addExplosion(self->x, self->y, 50, &player);
585 addSmokeAndFire(self, Math::rrand(-5, 5), Math::rrand(-5, 5), 2);
586 addBlood(self, Math::rrand(-5, 5), Math::rrand(-5, 5), 3);
588 if ((Math::prand() % 5) == 0)
590 self->dx = Math::rrand(-15, 15);
591 self->dy = Math::rrand(-8, 0);
594 if (self->health <= -100)
596 checkObjectives(self->name, false);
602 void tankBossGLInit()
604 debug(("tankBossGLInit\n"));
606 map.boss[1] = new Boss();
607 strcpy(map.boss[1]->name, "BioMech Tank V2.6");
608 map.boss[1]->health = 65 * game.skill;
609 map.boss[1]->maxHealth = 65 * game.skill;
610 map.boss[1]->setSprites(graphics.getSprite("BlobTankGrenadeRight", true), graphics.getSprite("BlobTankGrenadeLeft", true), graphics.getSprite("BlobTankGrenadeLeft", true));
611 map.boss[1]->currentWeapon = getWeaponByName("Mortor Shells");
612 map.boss[1]->face = 1;
613 map.boss[1]->active = false;
614 map.boss[1]->x = 420;
615 map.boss[1]->y = 8256;
616 map.boss[1]->immune = 0;
617 map.boss[1]->setThinkTime(1);
618 map.boss[1]->setActionFinished(1);
619 map.boss[1]->think = &tankBossGLFight;
620 map.boss[1]->react = &tankBossGLReact;
621 map.boss[1]->die = &tankBossGLDie;
623 debug(("tankBossMGInit: Done\n"));