]> git.mxchange.org Git - quix0rs-blobwars.git/blob - src/aquaBoss.cpp
Updated PNG icon files.
[quix0rs-blobwars.git] / src / aquaBoss.cpp
1 /*
2 Copyright (C) 2004-2011 Parallel Realities
3
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.
8
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.
12
13 See the GNU General Public License for more details.
14
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.
18
19 */
20
21 #include "aquaBoss.h"
22
23 void aquaBossAttack();
24
25 void leachParticles(Entity *enemy)
26 {
27         float dx, dy;
28         
29         Sprite *blood = graphics.getSprite("RedBloodParticle", true);
30         
31         Math::calculateSlope(self->x, self->y, enemy->x, enemy->y, &dx, &dy);
32         
33         dx *= Math::rrand(1, 2);
34         dy *= Math::rrand(1, 2);
35
36         for (int i = 0 ; i < 25 ; i++)
37         {
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);
39         }
40         
41         addBlood(enemy, 0, 0, 1);
42 }
43
44 void aquaBossRecharge()
45 {
46         debug(("aquaBossRecharge\n"));
47         
48         if (self->health == self->maxHealth)
49         {
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));
53                 return;
54         }
55         
56         bool leachedEnemy = false;
57         int diffX, diffY;
58         
59         Entity *enemy = (Entity*)map.enemyList.getHead();
60         
61         while (enemy->next != NULL)
62         {
63                 enemy = (Entity*)enemy->next;
64                 
65                 // don't leach enemies not in the pool!!
66                 if (enemy->x >= 1490)
67                         continue;
68                 
69                 diffX = abs((int)(enemy->x - self->x));
70                 diffY = abs((int)(enemy->y - self->y));
71                 
72                 if ((diffX <= 160) && (diffY <= 120))
73                 {
74                         if (enemy->health > -100)
75                         {
76                                 enemy->dx = enemy->dy = 0;
77                                 enemy->health = -1;
78                                 if (enemy->health % 10)
79                                 {
80                                         audio.playSound(SND_DEATH1 + Math::prand() % 3, CH_DEATH);
81                                 }
82                                 
83                                 Math::limitInt(&(++self->health), 0, self->maxHealth);
84                                 self->setActionFinished(25);
85                                 leachParticles(enemy);
86                                 leachedEnemy = true;
87                         }
88                 }
89         }
90         
91         self->setActionFinished(5);
92         
93         if (!leachedEnemy)
94         {
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));
98         }
99 }
100
101 void aquaBossCircleStrafe()
102 {
103         debug(("aquaBossCircleStrafe\n"));
104         
105         self->think = &aquaBossAttack;
106 }
107
108 void aquaBossRapidLaserFire()
109 {
110         debug(("aquaBossRapidLaserFire\n"));
111         
112         (self->x < player.x) ? self->face = 0 : self->face = 1;
113         
114         self->setThinkTime(2);
115         self->setActionFinished(5);
116         
117         addBullet((Entity*)self, self->currentWeapon->getSpeed(self->face), 0);
118         self->think = &aquaBossRapidLaserFire;
119         
120         self->custom--;
121         
122         if (self->custom == 0)
123         {
124                 self->think = &aquaBossAttack;
125                 self->setActionFinished(90);
126         }
127 }
128
129 void aquaBossRapidPreLaserFire()
130 {
131         (self->x < player.x) ? self->face = 0 : self->face = 1;
132         
133         self->dx = 0;
134         if (self->x < 1150) self->dx = 3;
135         if (self->x > 1170) self->dx = -3;
136         
137         if (self->custom == 0)
138         {
139                 if (self->y > 490)
140                         self->dy = -2;
141                 
142                 if (self->y <= 490)
143                 {
144                         self->think = &aquaBossRapidLaserFire;
145                         self->dy = 3;
146                         self->custom = Math::rrand(8, 16);
147                 }
148         }
149         else
150         {
151                 if (self->y < 940)
152                         self->dy = 2;
153                 
154                 if (self->y >= 940)
155                 {
156                         self->think = &aquaBossRapidLaserFire;
157                         self->dy = -3;
158                         self->custom = Math::rrand(8, 16);
159                 }
160         }
161 }
162
163 void aquaBossFire()
164 {
165         debug(("aquaBossFire\n"));
166         
167         (self->x < player.x) ? self->face = 0 : self->face = 1;
168         
169         self->setActionFinished(5);
170         self->setThinkTime(2);
171         self->think = &aquaBossFire;
172         
173         addBullet((Entity*)self, 0, 0);
174         
175         self->custom--;
176         
177         if (self->custom == 0)
178         {
179                 Math::removeBit(&self->flags, ENT_AIMS);
180                 self->currentWeapon = &weapon[WP_ALIENLASER];
181                 self->think = &aquaBossAttack;
182         }
183 }
184
185 void aquaBossUnProtect()
186 {
187         debug(("aquaBossUnProtect\n"));
188         
189         Math::removeBit(&self->flags, ENT_IMMUNE);
190         self->think = &aquaBossAttack;
191         
192         self->setSprites(graphics.getSprite("AquaBossRight", true), graphics.getSprite("AquaBossLeft", true), graphics.getSprite("AquaBossLeft", true));
193 }
194
195 void aquaBossProtect()
196 {
197         debug(("aquaBossProtect\n"));
198         
199         Math::addBit(&self->flags, ENT_IMMUNE);
200         self->think = &aquaBossUnProtect;
201         self->setThinkTime(Math::rrand(90, 120));
202         
203         self->setSprites(graphics.getSprite("AquaBossProtectRight", true), graphics.getSprite("AquaBossProtectLeft", true), graphics.getSprite("AquaBossProtectLeft", true));
204 }
205
206 void aquaBossReact()
207 {
208         // They can keep firing as much as they want, but it won't drop its shield now!
209         if (self->flags & ENT_IMMUNE)
210         {
211                 self->setThinkTime(Math::rrand(90, 120));
212                 return;
213         }
214         
215         if ((Math::prand() % 12) == 0)
216                 aquaBossProtect();
217 }
218
219 void aquaBossDie()
220 {
221         self->health -= Math::rrand(1, 2);
222         self->setActionFinished(30);
223         self->setThinkTime(2);
224         
225         self->dx = Math::rrand(-3, 3);
226         self->dy = Math::rrand(-3, 3);
227         
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);
231         
232         if (self->health <= -100)
233         {
234                 checkObjectives(self->name, false);
235                 
236                 map.mainBossPart = NULL;
237         }
238 }
239
240 void aquaBossAttack()
241 {
242         if (player.health < 1)
243         {
244                 self->dx = 0;
245                 return;
246         }
247         
248         debug(("aquaBossAttack\n"));
249         
250         (self->x < player.x) ? self->face = 0 : self->face = 1;
251         
252         int r = Math::prand() % (15 + game.skill);
253         
254         if (r < 5)
255         {
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;
260         }
261         else if (r < 8)
262         {
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;
268         }
269         else if (r == 8)
270         {
271                 self->think = &aquaBossRapidPreLaserFire;
272                 self->custom = Math::prand() % 2;
273         }
274         else if (r == 9)
275         {
276                 //self->think = &aquaBossCircleStrafe;
277         }
278         else
279         {
280                 self->think = &aquaBossRecharge;
281                 self->custom = Math::rrand(10, 25) * game.skill;
282         }
283 }
284
285 void aquaBossMainInit()
286 {
287         debug(("aquaBossMainInit\n"));
288         
289         map.boss[0] = new Boss();
290         strlcpy(map.boss[0]->name, "BioMech Aqua Blob", sizeof map.boss[0]->name);
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;
305         
306         Math::addBit(&map.boss[0]->flags, ENT_SWIMS);
307         
308         map.setMainBossPart(map.boss[0]);
309         
310         debug(("aquaBossMainInit: Done\n"));
311 }
312
313 void aquaBossInit()
314 {
315         aquaBossMainInit();
316 }