Removed that logo from this bramch aswell..
[dbw.git] / src / aquaBoss.cpp
blobc1c18057585456465fd1a205f6f4d739ee6819f0
1 /*
2 Copyright © 2004 Parallel Realities
3 Copyright © 2007-2008 Kővágó Zoltán <DirtY.iCE.hu@gmail.com>
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 "aquaBoss.h"
23 #include "CAudio.h"
24 #include "CGame.h"
25 #include "CGraphics.h"
26 #include "CMap.h"
27 #include "CMath.h"
28 #include "CWeapon.h"
29 #include "console/console.hpp"
31 void aquaBossAttack();
33 void leachParticles(Entity *enemy)
35 float dx, dy;
37 Sprite *blood = graphics.getSprite("RedBloodParticle", true);
39 Math::calculateSlope(self->x, self->y, enemy->x, enemy->y, &dx, &dy);
41 dx *= Math::rrand(1, 2);
42 dy *= Math::rrand(1, 2);
44 for (int i = 0 ; i < 25 ; i++)
46 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);
49 addBlood(enemy, 0, 0, 1);
52 void aquaBossRecharge()
54 debug("boss", 2) << "aquaBossRecharge" << std::endl;
56 if (self->health == self->maxHealth)
58 self->think = aquaBossAttack;
59 Math::removeBit(&self->flags, ENT_IMMUNE);
60 self->setSprites(graphics.getSprite("AquaBossRight", true), graphics.getSprite("AquaBossLeft", true), graphics.getSprite("AquaBossLeft", true));
61 return;
64 bool leachedEnemy = false;
65 int diffX, diffY;
67 Entity *enemy = (Entity*)map.enemyList.getHead();
69 while (enemy->next != NULL)
71 enemy = (Entity*)enemy->next;
73 // don't leach enemies not in the pool!!
74 if (enemy->x >= 1490)
75 continue;
77 diffX = abs((int)(enemy->x - self->x));
78 diffY = abs((int)(enemy->y - self->y));
80 if ((diffX <= 160) && (diffY <= 120))
82 if (enemy->health > -100)
84 enemy->dx = enemy->dx = 0;
85 enemy->health = -1;
86 if (enemy->health % 10)
88 audio.playSound(SND_DEATH1 + rand() % 3, CH_DEATH);
91 Math::limitInt(&(++self->health), 0, self->maxHealth);
92 self->setActionFinished(25);
93 leachParticles(enemy);
94 leachedEnemy = true;
99 self->setActionFinished(5);
101 if (!leachedEnemy)
103 self->think = aquaBossAttack;
104 Math::removeBit(&self->flags, ENT_IMMUNE);
105 self->setSprites(graphics.getSprite("AquaBossRight", true), graphics.getSprite("AquaBossLeft", true), graphics.getSprite("AquaBossLeft", true));
109 void aquaBossCircleStrafe()
111 debug("boss", 2) << "aquaBossCircleStrafe" << std::endl;
113 self->think = &aquaBossAttack;
116 void aquaBossRapidLaserFire()
118 debug("boss", 2) << "aquaBossRapidLaserFire" << std::endl;
120 (self->x < player.x) ? self->face = 0 : self->face = 1;
122 self->setThinkTime(2);
123 self->setActionFinished(5);
125 addBullet((Entity*)self, self->currentWeapon->getSpeed(self->face), 0);
126 self->think = &aquaBossRapidLaserFire;
128 self->custom--;
130 if (self->custom == 0)
132 self->think = &aquaBossAttack;
133 self->setActionFinished(90);
137 void aquaBossRapidPreLaserFire()
139 (self->x < player.x) ? self->face = 0 : self->face = 1;
141 self->dx = 0;
142 if (self->x < 1150) self->dx = 3;
143 if (self->x > 1170) self->dx = -3;
145 if (self->custom == 0)
147 if (self->y > 490)
148 self->dy = -2;
150 if (self->y <= 490)
152 self->think = &aquaBossRapidLaserFire;
153 self->dy = 3;
154 self->custom = Math::rrand(8, 16);
157 else
159 if (self->y < 940)
160 self->dy = 2;
162 if (self->y >= 940)
164 self->think = &aquaBossRapidLaserFire;
165 self->dy = -3;
166 self->custom = Math::rrand(8, 16);
171 void aquaBossFire()
173 debug("boss", 2) << "aquaBossFire" << std::endl;
175 (self->x < player.x) ? self->face = 0 : self->face = 1;
177 self->setActionFinished(5);
178 self->setThinkTime(2);
179 self->think = &aquaBossFire;
181 addBullet((Entity*)self, 0, 0);
183 self->custom--;
185 if (self->custom == 0)
187 Math::removeBit(&self->flags, ENT_AIMS);
188 self->currentWeapon = &weapon[WP_ALIENLASER];
189 self->think = &aquaBossAttack;
193 void aquaBossUnProtect()
195 debug("boss", 2) << "aquaBossUnProtect" << std::endl;
197 Math::removeBit(&self->flags, ENT_IMMUNE);
198 self->think = &aquaBossAttack;
200 self->setSprites(graphics.getSprite("AquaBossRight", true), graphics.getSprite("AquaBossLeft", true), graphics.getSprite("AquaBossLeft", true));
203 void aquaBossProtect()
205 debug("boss", 2) << "aquaBossProtect" << std::endl;
207 Math::addBit(&self->flags, ENT_IMMUNE);
208 self->think = &aquaBossUnProtect;
209 self->setThinkTime(Math::rrand(90, 120));
211 self->setSprites(graphics.getSprite("AquaBossProtectRight", true), graphics.getSprite("AquaBossProtectLeft", true), graphics.getSprite("AquaBossProtectLeft", true));
214 void aquaBossReact()
216 // They can keep firing as much as they want, but it won't drop its shield now!
217 if (self->flags & ENT_IMMUNE)
219 self->setThinkTime(Math::rrand(90, 120));
220 return;
223 if ((rand() % 12) == 0)
224 aquaBossProtect();
227 void aquaBossDie()
229 self->health -= Math::rrand(1, 2);
230 self->setActionFinished(30);
231 self->setThinkTime(2);
233 self->dx = Math::rrand(-3, 3);
234 self->dy = Math::rrand(-3, 3);
236 addExplosion(self->x, self->y, 50, &player);
237 addSmokeAndFire(self, Math::rrand(-5, 5), Math::rrand(-5, 5), 2);
238 addBlood(self, Math::rrand(-5, 5), Math::rrand(-5, 5), 3);
240 if (self->health <= -100)
242 checkObjectives(self->name, false);
244 map.mainBossPart = NULL;
248 void aquaBossAttack()
250 if (player.health < 1)
252 self->dx = 0;
253 return;
256 debug("boss", 2) << "aquaBossAttack" << std::endl;
258 (self->x < player.x) ? self->face = 0 : self->face = 1;
260 int r = rand() % (15 + game.skill);
262 if (r < 5)
264 self->dx = Math::rrand(-2, 2);
265 self->dy = Math::rrand(-2, 2);
266 self->setThinkTime(Math::rrand(60, 120));
267 self->think = &aquaBossAttack;
269 else if (r < 8)
271 self->dx = self->dy = 0;
272 self->custom = Math::rrand(5, 8);
273 self->currentWeapon = &weapon[WP_AIMEDPISTOL];
274 Math::addBit(&self->flags, ENT_AIMS);
275 self->think = &aquaBossFire;
277 else if (r == 8)
279 self->think = &aquaBossRapidPreLaserFire;
280 self->custom = rand() % 2;
282 else if (r == 9)
284 //self->think = &aquaBossCircleStrafe;
286 else
288 self->think = &aquaBossRecharge;
289 self->custom = Math::rrand(10, 25) * game.skill;
293 void aquaBossMainInit()
295 debug("boss", 2) << "aquaBossMainInit" << std::endl;
297 map.boss[0] = new Boss();
298 strcpy(map.boss[0]->name, "BioMech Aqua Blob");
299 map.boss[0]->health = 45 * game.skill;
300 map.boss[0]->maxHealth = 45 * game.skill;
301 map.boss[0]->setSprites(graphics.getSprite("AquaBossRight", true), graphics.getSprite("AquaBossLeft", true), graphics.getSprite("AquaBossLeft", true));
302 map.boss[0]->currentWeapon = &weapon[WP_ALIENLASER];
303 map.boss[0]->face = 0;
304 map.boss[0]->active = false;
305 map.boss[0]->x = 1072;
306 map.boss[0]->y = 740;
307 map.boss[0]->immune = 0;
308 map.boss[0]->setThinkTime(1);
309 map.boss[0]->setActionFinished(1);
310 map.boss[0]->think = &aquaBossAttack;
311 map.boss[0]->react = &aquaBossReact;
312 map.boss[0]->die = &aquaBossDie;
314 Math::addBit(&map.boss[0]->flags, ENT_SWIMS);
316 map.setMainBossPart(map.boss[0]);
318 debug("boss", 2) << "aquaBossMainInit: Done" << std::endl;
321 void aquaBossInit()
323 aquaBossMainInit();