2 Copyright (C) 2004-2011 Parallel Realities
3 Copyright (C) 2011-2015 Perpendicular Dimensions
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.
22 #include "droidBoss.h"
24 void droidBossAttack();
26 void droidBossChangeParticles()
28 (self->x < player.x) ? self->face = 0 : self->face = 1;
35 switch (self->shieldFrequency)
41 color = graphics.yellow;
44 color = graphics.green;
47 color = graphics.cyan;
50 color = graphics.white;
54 for (int i = 0 ; i < 20 ; i++)
56 dy = Math::rrand(-150, -50);
58 map.addParticle(self->x + (Math::prand() % self->width), self->y + (Math::prand() % self->height), dx, dy, Math::rrand(1, 60), color, NULL, PAR_WEIGHTLESS);
61 self->setThinkTime(2);
62 self->setActionFinished(10);
63 self->think = &droidBossChangeParticles;
66 if (self->custom == 0)
68 self->setThinkTime(2);
69 self->setActionFinished(10);
70 self->think = &droidBossAttack;
74 void droidBossChasePlayer()
76 (self->x < player.x) ? self->face = 0 : self->face = 1;
80 Math::calculateSlope(player.x, player.y, self->x, self->y, &dx, &dy);
85 self->setThinkTime(10);
86 self->setActionFinished(10);
87 self->think = &droidBossAttack;
90 void droidBossChangeFrequency()
92 (self->x < player.x) ? self->face = 0 : self->face = 1;
94 self->shieldFrequency = Math::rrand(WP_PISTOL, WP_SPREAD);
96 self->think = &droidBossChangeParticles;
97 self->setThinkTime(2);
98 self->setActionFinished(2);
101 Math::removeBit(&self->flags, ENT_AIMS);
102 Math::removeBit(&self->flags, ENT_RAPIDFIRE);
104 switch (self->shieldFrequency)
107 self->currentWeapon = getWeaponByName("Aimed Pistol");
108 Math::addBit(&self->flags, ENT_AIMS);
109 self->setSprites(graphics.getSprite("JetpackBlobRight1", true), graphics.getSprite("JetpackBlobLeft1", true), graphics.getSprite("JetpackBlobLeft1", true));
112 self->currentWeapon = getWeaponByName("Machine Gun");
113 Math::addBit(&self->flags, ENT_RAPIDFIRE);
114 self->setSprites(graphics.getSprite("JetpackBlobRight2", true), graphics.getSprite("JetpackBlobLeft2", true), graphics.getSprite("JetpackBlobLeft2", true));
117 self->currentWeapon = getWeaponByName("Alien Laser Cannon");
118 self->setSprites(graphics.getSprite("JetpackBlobRight3", true), graphics.getSprite("JetpackBlobLeft3", true), graphics.getSprite("JetpackBlobLeft3", true));
121 self->currentWeapon = getWeaponByName("Aimed Pistol");
122 self->shieldFrequency = WP_PISTOL;
123 Math::addBit(&self->flags, ENT_AIMS);
124 self->setSprites(graphics.getSprite("JetpackBlobRight1", true), graphics.getSprite("JetpackBlobLeft1", true), graphics.getSprite("JetpackBlobLeft1", true));
127 self->currentWeapon = &weapon[WP_ALIENSPREAD];
128 Math::addBit(&self->flags, ENT_AIMS);
129 self->setSprites(graphics.getSprite("JetpackBlobRight4", true), graphics.getSprite("JetpackBlobLeft4", true), graphics.getSprite("JetpackBlobLeft4", true));
133 audio.playSound(SND_BOSSCUSTOM1, CH_AMBIANCE, self->x);
138 self->health -= Math::rrand(1, 2);
139 self->setActionFinished(30);
140 self->setThinkTime(2);
142 self->dx = Math::rrand(-3, 3);
143 self->dy = Math::rrand(-3, 3);
145 addExplosion(self->x + Math::prand() % self->width, self->y + Math::prand() % self->height, 50, &player);
146 addSmokeAndFire(self, Math::rrand(-5, 5), Math::rrand(-5, 5), 2);
148 if (self->health <= -100)
150 checkObjectives(self->name, false);
152 map.mainBossPart = NULL;
158 self->dx = Math::rrand(-8, 8);
159 self->dy = Math::rrand(-8, 8);
161 (self->dx > 0) ? self->face = 0 : self->face = 1;
166 self->setThinkTime(2);
167 self->setActionFinished(5);
168 self->think = &droidGoCrazy;
172 if (self->custom == 0)
174 Math::removeBit(&self->flags, ENT_IMMUNE);
175 self->think = &droidBossChangeFrequency;
176 self->setActionFinished(2);
177 self->setThinkTime(2);
181 void droidBossReact()
183 if ((Math::prand() % 10) == 0)
185 Math::addBit(&self->flags, ENT_IMMUNE);
186 audio.playSound(SND_BOSSCUSTOM2, CH_SPAWN, self->x);
188 self->think = &droidGoCrazy;
189 self->setActionFinished(2);
190 self->setThinkTime(2);
196 (self->x < player.x) ? self->face = 0 : self->face = 1;
198 if (hasClearShot((Entity*)self))
200 self->flags & ENT_AIMS ? addBullet((Entity*)self, 0, 0) : addBullet((Entity*)self, self->currentWeapon->getSpeed(self->face), 0);
202 if (self->currentWeapon == &weapon[WP_ALIENSPREAD])
204 addBullet(self, self->currentWeapon->getSpeed(self->face), 2);
205 addBullet(self, self->currentWeapon->getSpeed(self->face), -2);
209 self->setThinkTime(2);
210 self->setActionFinished(self->currentWeapon->reload);
213 if (self->custom == 0)
214 self->think = &droidBossAttack;
219 self->setThinkTime(60);
220 self->setActionFinished(60);
225 addExplosion(self->x, self->y, 50, self);
226 self->setThinkTime(2);
227 self->setActionFinished(2);
228 self->active = false;
230 self->think = &orbWait;
237 (self->x < player.x) ? self->face = 0 : self->face = 1;
241 Math::calculateSlope(player.x, player.y, self->x, self->y, &dx, &dy);
243 self->dx = (dx * (1 + game.skill));
244 self->dy = (dy * (1 + game.skill));
246 self->setThinkTime(2);
247 self->setActionFinished(Math::rrand(10, 90));
248 self->think = &doOrb;
252 int distX = (int)fabs(player.x - self->x);
253 int distY = (int)fabs(player.y - self->y);
258 int distance = (int)sqrt(distX + distY);
264 if ((Math::prand() % 10) == 0)
270 debug(("fireOrb()\n"));
272 map.boss[i]->active = true;
273 map.boss[i]->maxHealth = map.boss[i]->health = 1 * game.skill;
274 map.boss[i]->x = self->x;
275 map.boss[i]->y = self->y + 20;
277 map.boss[i]->think = &doOrb;
278 map.boss[i]->die = &orbExplode;
279 map.boss[i]->setActionFinished(2);
280 map.boss[i]->setThinkTime(2);
283 void droidBossOrbAttack()
285 debug(("droidBossClawAttack\n"));
287 for (int i = 1 ; i < 6 ; i++)
289 if (!map.boss[i]->active)
292 self->setThinkTime(2);
293 self->setActionFinished(90);
294 self->think = &droidBossAttack;
300 self->think = &droidBossAttack;
303 void droidBossMoveRandomly()
305 self->dx = Math::rrand(-200, 200);
306 self->dy = Math::rrand(-200, 200);
311 self->setThinkTime(2);
312 self->setActionFinished(90);
313 self->think = &droidBossAttack;
316 void droidBossAttack()
318 if (player.health < 1)
320 self->dx = self->dy = 0;
324 (self->x < player.x) ? self->face = 0 : self->face = 1;
326 int r = Math::prand() % 110;
330 self->think = &droidBossChasePlayer;
331 self->setThinkTime(2);
332 self->setActionFinished(2);
337 self->think = &droidBossFire;
338 self->setThinkTime(2);
339 self->setActionFinished(2);
340 self->custom = Math::rrand(1, 3);
344 self->think = &droidBossMoveRandomly;
345 self->setThinkTime(2);
346 self->setActionFinished(2);
351 self->think = &droidBossOrbAttack;
352 self->setThinkTime(2);
353 self->setActionFinished(2);
354 self->custom = Math::rrand(1, 3);
358 self->think = &droidBossChangeFrequency;
359 self->setThinkTime(2);
360 self->setActionFinished(2);
366 debug(("droidBossInit\n"));
368 map.boss[0] = new Boss();
369 strlcpy(map.boss[0]->name, "BioMech Jetpack Blob", sizeof map.boss[0]->name);
370 map.boss[0]->health = 30 * game.skill;
371 map.boss[0]->maxHealth = 30 * game.skill;
372 map.boss[0]->setSprites(graphics.getSprite("JetpackBlobRight1", true), graphics.getSprite("JetpackBlobLeft1", true), graphics.getSprite("JetpackBlobLeft1", true));
373 map.boss[0]->currentWeapon = getWeaponByName("Aimed Pistol");
374 map.boss[0]->face = 1;
375 map.boss[0]->active = true;
376 map.boss[0]->x = 3172;
377 map.boss[0]->y = 4646;
378 map.boss[0]->immune = 0;
379 map.boss[0]->setThinkTime(2);
380 map.boss[0]->setActionFinished(2);
381 map.boss[0]->think = &droidBossChangeFrequency;
382 map.boss[0]->react = &droidBossReact;
383 map.boss[0]->die = &droidBossDie;
384 Math::addBit(&map.boss[0]->flags, ENT_FLIES);
386 map.setMainBossPart(map.boss[0]);
388 for (int i = 1 ; i < 6 ; i++)
390 map.boss[i] = new Boss();
391 strlcpy(map.boss[i]->name, "Orb Bomb", sizeof map.boss[i]->name);
392 map.boss[i]->setSprites(graphics.getSprite("DroidOrb", true), graphics.getSprite("DroidOrb", true), graphics.getSprite("DroidOrb", true));
393 map.boss[i]->active = false;
394 map.boss[i]->face = 1;
395 map.boss[i]->think = &orbWait;
396 map.boss[i]->x = 9999;
397 map.boss[i]->y = 9999;
398 Math::addBit(&map.boss[i]->flags, ENT_FLIES);
401 audio.loadSound(SND_BOSSCUSTOM1, "sound/droidChangeFreq");
402 audio.loadSound(SND_BOSSCUSTOM2, "sound/droidFreakOut");
404 debug(("droidBossInit: Done\n"));