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 void aquaBossAttack();
25 void leachParticles(Entity *enemy)
29 Sprite *blood = graphics.getSprite("RedBloodParticle", true);
31 Math::calculateSlope(self->x, self->y, enemy->x, enemy->y, &dx, &dy);
33 dx *= Math::rrand(1, 2);
34 dy *= Math::rrand(1, 2);
36 for (int i = 0 ; i < 25 ; i++)
38 map.addParticle(enemy->x + 10 + Math::rrand(-2, 2), enemy->y + 10 + Math::rrand(-2, 2), dx, dy, Math::rrand(1, 60), graphics.red, blood, PAR_WEIGHTLESS);
41 addBlood(enemy, 0, 0, 1);
44 void aquaBossRecharge()
46 debug(("aquaBossRecharge\n"));
48 if (self->health == self->maxHealth)
50 self->think = aquaBossAttack;
51 Math::removeBit(&self->flags, ENT_IMMUNE);
52 self->setSprites(graphics.getSprite("AquaBossRight", true), graphics.getSprite("AquaBossLeft", true), graphics.getSprite("AquaBossLeft", true));
56 bool leachedEnemy = false;
59 Entity *enemy = (Entity*)map.enemyList.getHead();
61 while (enemy->next != NULL)
63 enemy = (Entity*)enemy->next;
65 // don't leach enemies not in the pool!!
69 diffX = abs((int)(enemy->x - self->x));
70 diffY = abs((int)(enemy->y - self->y));
72 if ((diffX <= 160) && (diffY <= 120))
74 if (enemy->health > -100)
76 enemy->dx = enemy->dx = 0;
78 if (enemy->health % 10)
80 audio.playSound(SND_DEATH1 + Math::prand() % 3, CH_DEATH);
83 Math::limitInt(&(++self->health), 0, self->maxHealth);
84 self->setActionFinished(25);
85 leachParticles(enemy);
91 self->setActionFinished(5);
95 self->think = aquaBossAttack;
96 Math::removeBit(&self->flags, ENT_IMMUNE);
97 self->setSprites(graphics.getSprite("AquaBossRight", true), graphics.getSprite("AquaBossLeft", true), graphics.getSprite("AquaBossLeft", true));
101 void aquaBossCircleStrafe()
103 debug(("aquaBossCircleStrafe\n"));
105 self->think = &aquaBossAttack;
108 void aquaBossRapidLaserFire()
110 debug(("aquaBossRapidLaserFire\n"));
112 (self->x < player.x) ? self->face = 0 : self->face = 1;
114 self->setThinkTime(2);
115 self->setActionFinished(5);
117 addBullet((Entity*)self, self->currentWeapon->getSpeed(self->face), 0);
118 self->think = &aquaBossRapidLaserFire;
122 if (self->custom == 0)
124 self->think = &aquaBossAttack;
125 self->setActionFinished(90);
129 void aquaBossRapidPreLaserFire()
131 (self->x < player.x) ? self->face = 0 : self->face = 1;
134 if (self->x < 1150) self->dx = 3;
135 if (self->x > 1170) self->dx = -3;
137 if (self->custom == 0)
144 self->think = &aquaBossRapidLaserFire;
146 self->custom = Math::rrand(8, 16);
156 self->think = &aquaBossRapidLaserFire;
158 self->custom = Math::rrand(8, 16);
165 debug(("aquaBossFire\n"));
167 (self->x < player.x) ? self->face = 0 : self->face = 1;
169 self->setActionFinished(5);
170 self->setThinkTime(2);
171 self->think = &aquaBossFire;
173 addBullet((Entity*)self, 0, 0);
177 if (self->custom == 0)
179 Math::removeBit(&self->flags, ENT_AIMS);
180 self->currentWeapon = &weapon[WP_ALIENLASER];
181 self->think = &aquaBossAttack;
185 void aquaBossUnProtect()
187 debug(("aquaBossUnProtect\n"));
189 Math::removeBit(&self->flags, ENT_IMMUNE);
190 self->think = &aquaBossAttack;
192 self->setSprites(graphics.getSprite("AquaBossRight", true), graphics.getSprite("AquaBossLeft", true), graphics.getSprite("AquaBossLeft", true));
195 void aquaBossProtect()
197 debug(("aquaBossProtect\n"));
199 Math::addBit(&self->flags, ENT_IMMUNE);
200 self->think = &aquaBossUnProtect;
201 self->setThinkTime(Math::rrand(90, 120));
203 self->setSprites(graphics.getSprite("AquaBossProtectRight", true), graphics.getSprite("AquaBossProtectLeft", true), graphics.getSprite("AquaBossProtectLeft", true));
208 // They can keep firing as much as they want, but it won't drop its shield now!
209 if (self->flags & ENT_IMMUNE)
211 self->setThinkTime(Math::rrand(90, 120));
215 if ((Math::prand() % 12) == 0)
221 self->health -= Math::rrand(1, 2);
222 self->setActionFinished(30);
223 self->setThinkTime(2);
225 self->dx = Math::rrand(-3, 3);
226 self->dy = Math::rrand(-3, 3);
228 addExplosion(self->x, self->y, 50, &player);
229 addSmokeAndFire(self, Math::rrand(-5, 5), Math::rrand(-5, 5), 2);
230 addBlood(self, Math::rrand(-5, 5), Math::rrand(-5, 5), 3);
232 if (self->health <= -100)
234 checkObjectives(self->name, false);
236 map.mainBossPart = NULL;
240 void aquaBossAttack()
242 if (player.health < 1)
248 debug(("aquaBossAttack\n"));
250 (self->x < player.x) ? self->face = 0 : self->face = 1;
252 int r = Math::prand() % (15 + game.skill);
256 self->dx = Math::rrand(-2, 2);
257 self->dy = Math::rrand(-2, 2);
258 self->setThinkTime(Math::rrand(60, 120));
259 self->think = &aquaBossAttack;
263 self->dx = self->dy = 0;
264 self->custom = Math::rrand(5, 8);
265 self->currentWeapon = &weapon[WP_AIMEDPISTOL];
266 Math::addBit(&self->flags, ENT_AIMS);
267 self->think = &aquaBossFire;
271 self->think = &aquaBossRapidPreLaserFire;
272 self->custom = Math::prand() % 2;
276 //self->think = &aquaBossCircleStrafe;
280 self->think = &aquaBossRecharge;
281 self->custom = Math::rrand(10, 25) * game.skill;
285 void aquaBossMainInit()
287 debug(("aquaBossMainInit\n"));
289 map.boss[0] = new Boss();
290 strcpy(map.boss[0]->name, "BioMech Aqua Blob");
291 map.boss[0]->health = 45 * game.skill;
292 map.boss[0]->maxHealth = 45 * game.skill;
293 map.boss[0]->setSprites(graphics.getSprite("AquaBossRight", true), graphics.getSprite("AquaBossLeft", true), graphics.getSprite("AquaBossLeft", true));
294 map.boss[0]->currentWeapon = &weapon[WP_ALIENLASER];
295 map.boss[0]->face = 0;
296 map.boss[0]->active = false;
297 map.boss[0]->x = 1072;
298 map.boss[0]->y = 740;
299 map.boss[0]->immune = 0;
300 map.boss[0]->setThinkTime(1);
301 map.boss[0]->setActionFinished(1);
302 map.boss[0]->think = &aquaBossAttack;
303 map.boss[0]->react = &aquaBossReact;
304 map.boss[0]->die = &aquaBossDie;
306 Math::addBit(&map.boss[0]->flags, ENT_SWIMS);
308 map.setMainBossPart(map.boss[0]);
310 debug(("aquaBossMainInit: Done\n"));