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.
25 #include "CGraphics.h"
29 #include "console/console.hpp"
31 void aquaBossAttack();
33 void leachParticles(Entity
*enemy
)
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));
64 bool leachedEnemy
= false;
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!!
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;
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
);
99 self
->setActionFinished(5);
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
;
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;
142 if (self
->x
< 1150) self
->dx
= 3;
143 if (self
->x
> 1170) self
->dx
= -3;
145 if (self
->custom
== 0)
152 self
->think
= &aquaBossRapidLaserFire
;
154 self
->custom
= Math::rrand(8, 16);
164 self
->think
= &aquaBossRapidLaserFire
;
166 self
->custom
= Math::rrand(8, 16);
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);
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));
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));
223 if ((rand() % 12) == 0)
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)
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
);
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
;
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
;
279 self
->think
= &aquaBossRapidPreLaserFire
;
280 self
->custom
= rand() % 2;
284 //self->think = &aquaBossCircleStrafe;
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
;