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.
24 void aquaBossAttack();
26 void leachParticles(Entity *enemy)
30 Sprite *blood = graphics.getSprite("RedBloodParticle", true);
32 Math::calculateSlope(self->x, self->y, enemy->x, enemy->y, &dx, &dy);
34 dx *= Math::rrand(1, 2);
35 dy *= Math::rrand(1, 2);
37 for (int i = 0 ; i < 25 ; i++)
39 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);
42 addBlood(enemy, 0, 0, 1);
45 void aquaBossRecharge()
47 debug(("aquaBossRecharge\n"));
49 if (self->health == self->maxHealth)
51 self->think = aquaBossAttack;
52 Math::removeBit(&self->flags, ENT_IMMUNE);
53 self->setSprites(graphics.getSprite("AquaBossRight", true), graphics.getSprite("AquaBossLeft", true), graphics.getSprite("AquaBossLeft", true));
57 bool leachedEnemy = false;
60 Entity *enemy = (Entity*)map.enemyList.getHead();
62 while (enemy->next != NULL)
64 enemy = (Entity*)enemy->next;
66 // don't leach enemies not in the pool!!
70 diffX = abs((int)(enemy->x - self->x));
71 diffY = abs((int)(enemy->y - self->y));
73 if ((diffX <= 160) && (diffY <= 120))
75 if (enemy->health > -100)
77 enemy->dx = enemy->dy = 0;
79 if (enemy->health % 10)
81 audio.playSound(SND_DEATH1 + Math::prand() % 3, CH_DEATH, enemy->x);
84 Math::limitInt(&(++self->health), 0, self->maxHealth);
85 self->setActionFinished(25);
86 leachParticles(enemy);
92 self->setActionFinished(5);
96 self->think = aquaBossAttack;
97 Math::removeBit(&self->flags, ENT_IMMUNE);
98 self->setSprites(graphics.getSprite("AquaBossRight", true), graphics.getSprite("AquaBossLeft", true), graphics.getSprite("AquaBossLeft", true));
102 void aquaBossCircleStrafe()
104 debug(("aquaBossCircleStrafe\n"));
106 self->think = &aquaBossAttack;
109 void aquaBossRapidLaserFire()
111 debug(("aquaBossRapidLaserFire\n"));
113 (self->x < player.x) ? self->face = 0 : self->face = 1;
115 self->setThinkTime(2);
116 self->setActionFinished(5);
118 addBullet((Entity*)self, self->currentWeapon->getSpeed(self->face), 0);
119 self->think = &aquaBossRapidLaserFire;
123 if (self->custom == 0)
125 self->think = &aquaBossAttack;
126 self->setActionFinished(90);
130 void aquaBossRapidPreLaserFire()
132 (self->x < player.x) ? self->face = 0 : self->face = 1;
135 if (self->x < 1150) self->dx = 3;
136 if (self->x > 1170) self->dx = -3;
138 if (self->custom == 0)
145 self->think = &aquaBossRapidLaserFire;
147 self->custom = Math::rrand(8, 16);
157 self->think = &aquaBossRapidLaserFire;
159 self->custom = Math::rrand(8, 16);
166 debug(("aquaBossFire\n"));
168 (self->x < player.x) ? self->face = 0 : self->face = 1;
170 self->setActionFinished(5);
171 self->setThinkTime(2);
172 self->think = &aquaBossFire;
174 addBullet((Entity*)self, 0, 0);
178 if (self->custom == 0)
180 Math::removeBit(&self->flags, ENT_AIMS);
181 self->currentWeapon = &weapon[WP_ALIENLASER];
182 self->think = &aquaBossAttack;
186 void aquaBossUnProtect()
188 debug(("aquaBossUnProtect\n"));
190 Math::removeBit(&self->flags, ENT_IMMUNE);
191 self->think = &aquaBossAttack;
193 self->setSprites(graphics.getSprite("AquaBossRight", true), graphics.getSprite("AquaBossLeft", true), graphics.getSprite("AquaBossLeft", true));
196 void aquaBossProtect()
198 debug(("aquaBossProtect\n"));
200 Math::addBit(&self->flags, ENT_IMMUNE);
201 self->think = &aquaBossUnProtect;
202 self->setThinkTime(Math::rrand(90, 120));
204 self->setSprites(graphics.getSprite("AquaBossProtectRight", true), graphics.getSprite("AquaBossProtectLeft", true), graphics.getSprite("AquaBossProtectLeft", true));
209 // They can keep firing as much as they want, but it won't drop its shield now!
210 if (self->flags & ENT_IMMUNE)
212 self->setThinkTime(Math::rrand(90, 120));
216 if ((Math::prand() % 12) == 0)
222 self->health -= Math::rrand(1, 2);
223 self->setActionFinished(30);
224 self->setThinkTime(2);
226 self->dx = Math::rrand(-3, 3);
227 self->dy = Math::rrand(-3, 3);
229 addExplosion(self->x, self->y, 50, &player);
230 addSmokeAndFire(self, Math::rrand(-5, 5), Math::rrand(-5, 5), 2);
231 addBlood(self, Math::rrand(-5, 5), Math::rrand(-5, 5), 3);
233 if (self->health <= -100)
235 checkObjectives(self->name, false);
237 map.mainBossPart = NULL;
241 void aquaBossAttack()
243 if (player.health < 1)
249 debug(("aquaBossAttack\n"));
251 (self->x < player.x) ? self->face = 0 : self->face = 1;
253 int r = Math::prand() % (15 + game.skill);
257 self->dx = Math::rrand(-2, 2);
258 self->dy = Math::rrand(-2, 2);
259 self->setThinkTime(Math::rrand(60, 120));
260 self->think = &aquaBossAttack;
264 self->dx = self->dy = 0;
265 self->custom = Math::rrand(5, 8);
266 self->currentWeapon = &weapon[WP_AIMEDPISTOL];
267 Math::addBit(&self->flags, ENT_AIMS);
268 self->think = &aquaBossFire;
272 self->think = &aquaBossRapidPreLaserFire;
273 self->custom = Math::prand() % 2;
277 //self->think = &aquaBossCircleStrafe;
281 self->think = &aquaBossRecharge;
282 self->custom = Math::rrand(10, 25) * game.skill;
286 void aquaBossMainInit()
288 debug(("aquaBossMainInit\n"));
290 map.boss[0] = new Boss();
291 strlcpy(map.boss[0]->name, "BioMech Aqua Blob", sizeof map.boss[0]->name);
292 map.boss[0]->health = 45 * game.skill;
293 map.boss[0]->maxHealth = 45 * game.skill;
294 map.boss[0]->setSprites(graphics.getSprite("AquaBossRight", true), graphics.getSprite("AquaBossLeft", true), graphics.getSprite("AquaBossLeft", true));
295 map.boss[0]->currentWeapon = &weapon[WP_ALIENLASER];
296 map.boss[0]->face = 0;
297 map.boss[0]->active = false;
298 map.boss[0]->x = 1072;
299 map.boss[0]->y = 740;
300 map.boss[0]->immune = 0;
301 map.boss[0]->setThinkTime(1);
302 map.boss[0]->setActionFinished(1);
303 map.boss[0]->think = &aquaBossAttack;
304 map.boss[0]->react = &aquaBossReact;
305 map.boss[0]->die = &aquaBossDie;
307 Math::addBit(&map.boss[0]->flags, ENT_SWIMS);
309 map.setMainBossPart(map.boss[0]);
311 debug(("aquaBossMainInit: Done\n"));