Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
9566 turbocat 1
#include "devil.h"
2
#include "../game.h"
3
#include "../PHL.h"
4
#include "../hero.h"
5
#include 
6
#include 
7
 
8
int boss6flag = 31;
9
 
10
void devilStep(Devil* d);
11
void devilDraw(Devil* d);
12
 
13
void orbStep(Orb* o);
14
void orbDraw(Orb* o);
15
 
16
void createDevil(int x, int y)
17
{
18
	if (flags[boss6flag] == 0) { //have not beaten boss 6
19
		PHL_FreeSurface(images[imgBoss]);
20
		images[imgBoss] = PHL_LoadQDA("boss04.bmp");
21
 
22
		int i;
23
		for (i = 0; i < MAX_ENEMIES; i++) {
24
			if (enemies[i] == NULL) {
25
				setBossRoom();
26
 
27
				Enemy* e = /*(Enemy*)*/malloc(sizeof *e);
28
				Devil* d = /*(Devil*)*/malloc(sizeof *d);
29
				d->id = i;
30
 
31
				d->x = x;
32
				d->y = y;
33
 
34
				d->ystart = d->y;
35
				d->newystart = d->ystart;
36
				d->hsp = -2.5;
37
 
38
				d->hp = 100;
39
				//d->hp = 1;
40
 
41
				d->state = 0;
42
				d->timer = 0;
43
 
44
				d->blink = 0;
45
				d->boblen = 32;
46
				d->bobspd = 3;
47
 
48
				d->tailangle = 90;
49
 
50
				d->rotcounter = 0;
51
				d->bobcounter = 0;
52
 
53
				d->bobspd = 3;
54
				d->rotspd = 1;
55
 
56
				d->imageIndex = 0;
57
 
58
				e->data = d;
59
				e->enemyStep = devilStep;
60
				e->enemyDraw = devilDraw;
61
				e->type = 45;
62
 
63
				enemies[i] = e;
64
				i = MAX_ENEMIES;
65
			}
66
		}
67
	}
68
}
69
 
70
void devilStep(Devil* d)
71
{
72
	char dead = 0;
73
 
74
	//Animate
75
	{
76
		d->imageIndex += 0.1;
77
		if (d->imageIndex >= 2) {
78
			d->imageIndex -= 2;
79
		}
80
 
81
		if (d->blink > 0) {
82
			d->blink -= 1;
83
		}
84
	}
85
 
86
	//Bob
87
	{
88
		if (d->state != 4) {
89
			d->bobcounter += d->bobspd;
90
			if (d->bobcounter >= 360) {
91
				d->bobcounter -= 360;
92
			}
93
 
94
			d->y = d->ystart + (d->boblen * cos(d->bobcounter * 3.14159 / 180));
95
		}
96
	}
97
 
98
	//Swing tail
99
	{
100
		d->rotcounter += d->rotspd;
101
		if (d->rotcounter >= 360) {
102
			d->rotcounter -= 360;
103
		}
104
 
105
		d->tailangle = 90 + (55 * cos(d->rotcounter * 3.14159 / 180));
106
	}
107
 
108
	//Patterns
109
	{
110
		//movement
111
		if (d->state == 0 || d->state == 2)
112
		{
113
			d->rotspd = 1;
114
			d->boblen = 32;
115
			d->bobspd = 3;
116
 
117
			//Re-align ystart
118
			if (d->ystart > d->newystart) {
119
				d->ystart -= 1;
120
			}
121
			if (d->ystart < d->newystart) {
122
				d->ystart += 1;
123
			}
124
 
125
			d->x += d->hsp;
126
 
127
			//Slow Down
128
			double rate = 0.016;
129
			if (d->hsp < 0) {
130
				d->hsp += rate;
131
				if (d->hsp >= 0) {
132
					d->hsp = 0;
133
				}
134
			}
135
 
136
			if (d->hsp > 0) {
137
				d->hsp -= rate;
138
				if (d->hsp <= 0) {
139
					d->hsp = 0;
140
				}
141
			}
142
 
143
			if (d->hsp == 0) {
144
				d->timer = 0;
145
				if (d->state == 0) {
146
					d->state = 1;
147
				}
148
 
149
				if (d->state == 2) {
150
					if ((d->rotcounter >= 90 && d->rotcounter <= 90 + d->rotspd) || (d->rotcounter >= 270 && d->rotcounter <= 270 + d->rotspd)) {
151
						d->state = 3;
152
					}
153
				}
154
			}
155
		}
156
		//mid room pause
157
		else if (d->state == 1)
158
		{
159
			d->timer += 1;
160
			if (d->timer >= 60) {
161
				if (d->state == 1) {
162
					d->hsp = 2.5;
163
					if (herox < d->x) {
164
						d->hsp *= -1;
165
					}
166
				}
167
				d->state = 2;
168
			}
169
		}
170
		//Shoot
171
		else if (d->state == 3)
172
		{
173
			d->rotspd = 3;
174
			d->boblen = 10;
175
			d->bobspd = 10;
176
 
177
			d->timer += 1;
178
 
179
			//Shoot orbs
180
			if (d->timer == 120 || d->timer == 240 || d->timer == 360) {
181
				int aim = (atan2((heroy + 20) - d->y, d->x - herox) * 180 / 3.14159) + 270;
182
 
183
				int spawnY = d->y + 20;
184
				createOrb(d->x, spawnY, aim + 22);
185
				createOrb(d->x, spawnY, aim + 11);
186
				createOrb(d->x, spawnY, aim);
187
				createOrb(d->x, spawnY, aim - 11);
188
				createOrb(d->x, spawnY, aim - 22);
189
 
190
				PHL_PlaySound(sounds[sndShot03], CHN_ENEMIES);
191
			}
192
 
193
			if (d->timer == 360) {
194
				d->state = 0;
195
				d->hsp = 2.5;
196
 
197
				if (d->x > 320) {
198
					d->hsp *= -1;
199
				}
200
 
201
				int chaseY = heroy - d->ystart;
202
				if (chaseY > 52) { chaseY = 52; }
203
				if (chaseY < -52) { chaseY = -52; }
204
 
205
				d->newystart = d->ystart + chaseY;
206
			}
207
		}
208
 
209
		//Death
210
		if (d->state == 4) {
211
			d->rotspd = 3;
212
			d->y += 0.2;
213
			d->timer -= 1;
214
 
215
			if (d->timer % 12 == 0) {
216
				createEffect(2, d->x - 64 + (rand() % 100), d->y - 64 + (rand() % 80));
217
			}
218
 
219
			if (d->timer <= 0) {
220
				dead = 1;
221
			}
222
		}
223
	}
224
 
225
	//Collisions
226
	if (d->state != 4) {
227
		//Setup masks
228
		Mask masks[6];
229
 
230
		//Head mask
231
		masks[0].unused = masks[0].circle = 0;
232
		masks[0].w = 100;
233
		masks[0].h = 104;
234
		masks[0].x = d->x - (masks[0].w / 2);
235
		masks[0].y = d->y - (masks[0].h / 2);
236
 
237
		//Link masks
238
		for (int i = 1; i < 5; i++) {
239
			int taildis[4] = {54, 80, 108, 134};
240
			int taillag[4] = {10, 15, 10, 5};
241
 
242
			double newtailangle = 90 + (55 * cos((d->rotcounter - taillag[i-1]) * 3.14159 / 180));
243
 
244
			masks[i].unused = 0;
245
			masks[i].circle = 1;
246
			masks[i].w = 16;
247
			masks[i].h = 16;
248
			masks[i].x = d->x + (taildis[i-1] * cos(newtailangle * 3.14159 / 180));
249
			masks[i].y = d->y + (taildis[i-1] * sin(newtailangle * 3.14159 / 180));
250
		}
251
 
252
		//Barb mask
253
		masks[5].unused = masks[5].circle = 0;
254
		masks[5].w = 40;
255
		masks[5].h = 40;
256
		masks[5].x = (d->x + (160 * cos(d->tailangle * 3.14159 / 180))) - (masks[5].w / 2);
257
		masks[5].y = (d->y + (160 * sin(d->tailangle * 3.14159 / 180))) - (masks[5].h / 2);
258
 
259
		//Collisions
260
		int hitHead = 0;
261
		for (int a = 0; a < 6; a++)
262
		{
263
			if (a == 0 || a == 5) {
264
				//Hit Player
265
				if (checkCollision(masks[a], getHeroMask())) {
266
 
267
					int damage = 25;
268
					if (a == 0) {
269
						damage = 50;
270
					}
271
 
272
					if (heroHit(damage, masks[a].x + (masks[a].w / 2)) == 1) {
273
						if (a == 5) { //Barb
274
							heroStun();
275
						}
276
					}
277
				}
278
			}
279
 
280
			//Weapon collision
281
			if (hitHead == 0) {
282
				for (int i = 0; i < MAX_WEAPONS; i++) {
283
					if (weapons[i] != NULL) {
284
						if (weapons[i]->cooldown == 0) {
285
							if (checkCollision(masks[a], weapons[i]->weaponMask)) {
286
								weaponHit(weapons[i]);
287
 
288
								//Head
289
								if (a == 0) {
290
									d->hp -= 1;
291
									d->blink = 15;
292
									hitHead = 1;
293
 
294
									if (d->hp <= 0) {
295
										d->state = 4;
296
										d->timer = 180;
297
										d->blink = 200;
298
									}
299
								}else{
300
									PHL_PlaySound(sounds[sndHit03], CHN_WEAPONS);
301
								}
302
 
303
								i = MAX_WEAPONS;
304
							}
305
						}
306
					}
307
				}
308
			}
309
		}
310
	}
311
 
312
	//Destroy
313
	if (dead == 1) {
314
		enemyDestroy(d->id);
315
		bossDefeatedFlag = 1;
316
		roomSecret = 1;
317
 
318
		flags[boss6flag] = 1;
319
		PHL_StopMusic();
320
	}
321
}
322
 
323
void devilDraw(Devil* d)
324
{
325
	if (d->blink % 2 == 0)
326
	{
327
		int dx, dy;
328
 
329
		//Draw tail
330
		int taildis[4] = {54, 80, 108, 134};
331
		int taillag[4] = {10, 15, 10, 5};
332
		for (int i = 0; i < 4; i++) {
333
			double newtailangle = 90 + (55 * cos((d->rotcounter - taillag[i]) * 3.14159 / 180));
334
 
335
			dx = d->x + (taildis[i] * cos(newtailangle * 3.14159 / 180)) - 32;
336
			dy = d->y + (taildis[i] * sin(newtailangle * 3.14159 / 180)) - 32;
337
			PHL_DrawSurfacePart(dx, dy, 0, 128, 64, 64, images[imgBoss]);
338
		}
339
 
340
		//Draw Head
341
		dx = d->x - 64;
342
		dy = d->y - 64;
343
		PHL_DrawSurfacePart(dx, dy, (int)d->imageIndex * 128, 0, 128, 128, images[imgBoss]);
344
 
345
		//Draw Tail Tip
346
		dx = d->x + (160 * cos(d->tailangle * 3.14159 / 180)) - 32;
347
		dy = d->y + (160 * sin(d->tailangle * 3.14159 / 180)) - 32;
348
		PHL_DrawSurfacePart(dx, dy, 64, 128, 64, 64, images[imgBoss]);
349
 
350
	}
351
}
352
 
353
 
354
//Stone Orbs
355
void createOrb(int x, int y, double dir)
356
{
357
	int i;
358
	for (i = 0; i < MAX_ENEMIES; i++) {
359
		if (enemies[i] == NULL) {
360
			Enemy* e = /*(Enemy*)*/malloc(sizeof *e);
361
			Orb* o = /*(Orb*)*/malloc(sizeof *o);
362
			o->id = i;
363
 
364
			o->x = x;
365
			o->y = y;
366
 
367
			o->dir = dir;
368
 
369
			o->imageIndex = 0;
370
 
371
			e->data = o;
372
			e->enemyStep = orbStep;
373
			e->enemyDraw = orbDraw;
374
			e->type = -1;
375
 
376
			enemies[i] = e;
377
			i = MAX_ENEMIES;
378
		}
379
	}
380
}
381
 
382
void orbStep(Orb* o)
383
{
384
	char dead = 0;
385
 
386
	//Animate
387
	{
388
		o->imageIndex += 0.33;
389
		if (o->imageIndex >= 4) {
390
			o->imageIndex -= 4;
391
		}
392
	}
393
 
394
	//Movement
395
	{
396
		int spd = 4;
397
		o->x += spd * sin(o->dir * 3.14159 / 180);
398
		o->y += spd * cos(o->dir * 3.14159 / 180);
399
	}
400
 
401
	//Collision
402
	{
403
		Mask mask;
404
		mask.unused = 0;
405
		mask.circle = 1;
406
		mask.w = 6;
407
		mask.x = o->x;
408
		mask.y = o->y;
409
 
410
		//Collide with shield
411
		/*if (checkCollision(mask, shieldMask)) {
412
			createEffect(1, o->x - 20, o->y - 20);
413
			PHL_PlaySound(sounds[sndHit07], CHN_EFFECTS);
414
			dead = 1;
415
		}else{*/
416
			//Hit player
417
			if (checkCollision(getHeroMask(), mask)) {
418
				heroStone();
419
				heroHit(25, mask.x);
420
			}
421
		//}
422
 
423
		//Collide with weapon
424
		int i;
425
		for (i = 0; i < MAX_WEAPONS; i++) {
426
			if (weapons[i] != NULL) {
427
				if (checkCollision(mask, weapons[i]->weaponMask)) {
428
					weaponHit(weapons[i]);
429
 
430
					createEffect(2, o->x - 32, o->y - 32);
431
					dead = 1;
432
 
433
					i = MAX_WEAPONS;
434
				}
435
			}
436
		}
437
	}
438
 
439
	//Destroy if outside of room
440
	{
441
		if (o->x < -20 || o->x > 660 || o->y < -20 || o->y > 500) {
442
			dead = 1;
443
		}
444
	}
445
 
446
	//Finally erase object
447
	{
448
		if (dead == 1) {
449
			enemyDestroy(o->id);
450
		}
451
	}
452
}
453
 
454
void orbDraw(Orb* o)
455
{
456
	int animation[4] = {0, 1, 0, 2};
457
	PHL_DrawSurfacePart(o->x - 20, o->y - 20, 440 + (animation[(int)o->imageIndex] * 40), 480, 40, 40, images[imgMisc20]);
458
}