Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
9566 turbocat 1
#include "crab.h"
2
#include "../PHL.h"
3
#include "../enemy.h"
4
#include "../game.h"
5
#include "../hero.h"
6
#include 
7
#include 
8
 
9
int boss3flag = 13;
10
 
11
void crabStep(Crab* c);
12
void crabDraw(Crab* c);
13
void updateCrabMask(Crab* c);
14
void crabDestroy(Crab* c);
15
 
16
void electricityStep(Electricity* e);
17
void electricityDraw(Electricity* e);
18
 
19
void createCrab(int x, int y)
20
{
21
	if (flags[boss3flag] == 0) { //have not beaten boss 3
22
		PHL_FreeSurface(images[imgBoss]);
23
		images[imgBoss] = PHL_LoadQDA("boss06.bmp");
24
 
25
		int i;
26
		for (i = 0; i < MAX_ENEMIES; i++) {
27
			if (enemies[i] == NULL) {
28
				//Boss start
29
				setBossRoom();
30
 
31
				Enemy* e = /*(Enemy*)*/malloc(sizeof(Enemy));
32
				Crab* c = /*(Crab*)*/malloc(sizeof(Crab));
33
				c->id = i;
34
 
35
				//c->hp = 1;
36
				c->hp = 35;
37
				c->invincible = 0;
38
 
39
				c->x = x;
40
				c->y = y;
41
 
42
				c->vsp = 0;
43
				c->hsp = 0;
44
 
45
				c->imageIndex = 0;
46
 
47
				c->state = 0;
48
				c->timer = 0;
49
				c->counter = 0;
50
 
51
				c->mask.unused = 0;
52
				c->mask.circle = 1;
53
				c->mask.w = 33;
54
				c->mask.h = 33;
55
				updateCrabMask(c);
56
 
57
				//Setup phase
58
				c->timer = 60;
59
 
60
				e->data = c;
61
				e->enemyStep = crabStep;
62
				e->enemyDraw = crabDraw;
63
				e->type = 42;
64
 
65
				enemies[i] = e;
66
				i = MAX_ENEMIES;
67
			}
68
		}
69
	}
70
}
71
 
72
void crabStep(Crab* c)
73
{
74
	char dead = 0;
75
	double grav = 0.15;
76
 
77
	if (c->invincible > 0) {
78
		c->invincible -= 1;
79
	}
80
 
81
	//Wait
82
	if (c->state == 0)
83
	{
84
		c->imageIndex = 0;
85
 
86
		if (c->timer <= 0) {
87
			c->timer = 0;
88
			if (c->counter == 2 || c->counter == 5) { //Goto roll
89
				c->state = 3;
90
				if (c->counter == 5) {
91
					c->counter = 0;
92
				}else{
93
					c->counter = 3;
94
				}
95
			}else if (c->counter == 3) {
96
				c->state = 2;
97
			}else{
98
				c->state = 1; //Goto shoot
99
			}
100
		}else{
101
			c->timer -= 1;
102
		}
103
	}
104
	//Shoot Electric orbs
105
	else if (c->state == 1)
106
	{
107
		//Create orbs
108
		if (c->timer == 0) {
109
			PHL_PlaySound(sounds[sndPi05], CHN_ENEMIES);
110
 
111
			double angle = (atan2(heroy + 20 - (c->y + 60), c->x - (herox - 20)) * 180 / 3.14159) + 270;
112
			createElectricity(c->x, c->y + 60, angle - 45, c->id);
113
			createElectricity(c->x, c->y + 60, angle - 22.5, c->id);
114
			createElectricity(c->x, c->y + 60, angle, c->id);
115
			createElectricity(c->x, c->y + 60, angle + 22.5, c->id);
116
			createElectricity(c->x, c->y + 60, angle + 45, c->id);
117
		}
118
 
119
		if (c->timer >= 20) {
120
			c->state = 2;
121
			c->timer = 0;
122
		}else{
123
			c->timer += 1;
124
		}
125
	}
126
	//Leap
127
	else if (c->state == 2)
128
	{
129
		c->imageIndex = 1;
130
 
131
		//Hopping down or hopping up
132
		int hopup = 1;
133
		if (c->counter > 2) {
134
			hopup = 0;
135
		}
136
 
137
		//Jump
138
		if (c->timer == 0) {
139
			PHL_PlaySound(sounds[sndJump02], CHN_ENEMIES);
140
 
141
			c->vsp = -6.5;
142
			if (hopup == 0) {
143
				c->vsp = -1.5;
144
			}
145
			c->timer = 1;
146
		}
147
 
148
		//Vertical velocity
149
		c->y += c->vsp;
150
		c->vsp += grav;
151
 
152
		if (c->vsp >= 6) {
153
			c->vsp = 6;
154
		}
155
 
156
		//Check if onground
157
		if ((hopup == 1 && c->vsp > 0) || (hopup == 0 && c->vsp >= 6)) {
158
			Mask area;
159
			area.unused = area.circle = 0;
160
			area.w = 40;
161
			area.h = 10;
162
			area.x = c->x - (area.w / 2);
163
			area.y = c->y + (80 - area.h);
164
 
165
			PHL_Rect collide = getTileCollision(1, area);
166
			if (collide.x != -1) {
167
				c->y = collide.y - 80;
168
				c->state = 0;
169
				c->counter += 1;
170
				c->timer = 25;
171
				if (c->counter == 2 || c->counter == 5) {
172
					c->timer = 3;
173
				}
174
			}
175
		}
176
	}
177
	//Roll hop
178
	else if (c->state == 3)
179
	{
180
		//Animate
181
		if (c->hsp > 0) {
182
			c->imageIndex += 0.25;
183
		}
184
		if (c->hsp < 0) {
185
			c->imageIndex -= 0.25;
186
		}
187
		if (c->imageIndex < 2) { c->imageIndex += 4; }
188
		if (c->imageIndex >= 6) { c->imageIndex -= 4; }
189
 
190
 
191
		if (c->timer == 0) {
192
			PHL_PlaySound(sounds[sndHit04], CHN_ENEMIES);
193
 
194
			c->timer = 1;
195
			c->vsp = -1.5;
196
			c->imageIndex = 2;
197
			if (c->x > 320) {
198
				c->hsp = -8;
199
			}else{
200
				c->hsp = 8;
201
			}
202
		}
203
 
204
		//Movement
205
		c->y += c->vsp;
206
		c->vsp += grav;
207
 
208
		//Check if onground
209
		if (c->vsp > 0) {
210
			Mask area;
211
			area.unused = area.circle = 0;
212
			area.w = 40;
213
			area.h = 10;
214
			area.x = c->x - (area.w / 2);
215
			area.y = c->y + (80 - area.h);
216
 
217
			PHL_Rect collide = getTileCollision(1, area);
218
			if (collide.x != -1) {
219
				c->y = collide.y - 80;
220
				c->state = 4;
221
			}
222
		}
223
	}
224
	//Roll
225
	if (c->state == 4)
226
	{
227
		//Animate
228
		if (c->hsp > 0) {
229
			c->imageIndex += 0.25;
230
		}
231
		if (c->hsp < 0) {
232
			c->imageIndex -= 0.25;
233
		}
234
		if (c->imageIndex < 2) { c->imageIndex += 4; }
235
		if (c->imageIndex >= 6) { c->imageIndex -= 4; }
236
 
237
		//Movement
238
		c->x += c->hsp;
239
 
240
		//Collide with wall
241
		Mask area;
242
		area.unused = area.circle = 0;
243
		area.w = area.h = c->mask.w * 2;
244
		area.x = c->x - c->mask.w;
245
		area.y = c->y + (40 - c->mask.h);
246
 
247
		if (checkTileCollision(1, area) == 1) {
248
			c->state = 5;
249
			c->timer = 0;
250
		}
251
	}
252
	//Bounce off wall
253
	if (c->state == 5)
254
	{
255
		if (c->timer == 0) {
256
			PHL_PlaySound(sounds[sndHit04], CHN_ENEMIES);
257
 
258
			c->timer = 1;
259
			c->vsp = -2;
260
			c->hsp = 2;
261
			if (c->x > 320) {
262
				c->hsp *= -1;
263
			}
264
		}
265
 
266
		c->imageIndex = 1;
267
 
268
		c->x += c->hsp;
269
 
270
		c->y += c->vsp;
271
		c->vsp += grav;
272
 
273
		//Check if onground
274
		if (c->vsp > 0) {
275
			Mask area;
276
			area.unused = area.circle = 0;
277
			area.w = 40;
278
			area.h = 10;
279
			area.x = c->x - (area.w / 2);
280
			area.y = c->y + (80 - area.h);
281
 
282
			PHL_Rect collide = getTileCollision(1, area);
283
			if (collide.x != -1) {
284
				c->y = collide.y - 80;
285
				c->state = 0;
286
				c->timer = 65;
287
			}
288
		}
289
	}
290
	//Death
291
	else if (c->state == 6)
292
	{
293
		c->imageIndex = 1;
294
 
295
		c->y += 0.2;
296
 
297
		c->timer -= 1;
298
 
299
		if (c->timer % 12 == 0) {
300
			createEffect(2, c->x - 64 + (rand() % 100), c->y + (rand() % 80));
301
		}
302
 
303
		if (c->timer <= 0) {
304
			crabDestroy(c);
305
			dead = 1;
306
		}
307
	}
308
 
309
	if (dead == 0) {
310
		if (c->state != 6) {
311
			//Update Mask
312
			c->mask.x = c->x;
313
			c->mask.y = c->y + 40;
314
 
315
			//Weapon collision
316
			int i;
317
			for (i = 0; i < MAX_WEAPONS; i++) {
318
				if (weapons[i] != NULL) {
319
					if (weapons[i]->cooldown == 0) {
320
						if (checkCollision(c->mask, weapons[i]->weaponMask)) {
321
							weaponHit(weapons[i]);
322
							c->invincible = 15;
323
							c->hp -= 1;
324
							i = MAX_WEAPONS;
325
						}
326
					}
327
				}
328
			}
329
 
330
			//Hit Player
331
			if (checkCollision(c->mask, getHeroMask())) {
332
				heroHit(30, c->x);
333
			}
334
 
335
			//Die
336
			if (c->hp <= 0) {
337
				c->state = 6;
338
				c->timer = 180;
339
				c->invincible = 200;
340
			}
341
		}
342
	}
343
}
344
 
345
void crabDraw(Crab* c)
346
{
347
	if (c->invincible % 2 == 0) {
348
		PHL_DrawSurfacePart(c->x - 40, c->y, (int)c->imageIndex * 80, 0, 80, 80, images[imgBoss]);
349
	}
350
}
351
 
352
void updateCrabMask(Crab* c)
353
{
354
	c->mask.x = c->x;
355
	c->mask.y = c->y + 40;
356
}
357
 
358
void crabDestroy(Crab* c)
359
{
360
	enemyDestroy(c->id);
361
	bossDefeatedFlag = 1;
362
	roomSecret = 1;
363
 
364
	flags[boss3flag] = 1;
365
	PHL_StopMusic();
366
}
367
 
368
 
369
void createElectricity(int x, int y, double angle, int minid)
370
{
371
	int i;
372
	for (i = minid; i < MAX_ENEMIES; i++) {
373
		if (enemies[i] == NULL) {
374
			Enemy* e = /*(Enemy*)*/malloc(sizeof *e);
375
			Electricity* el = /*(Electricity*)*/malloc(sizeof *el);
376
			el->id = i;
377
 
378
			el->x = x;
379
			el->y = y;
380
 
381
			//Fix angle
382
			if (angle < 0) {
383
				angle += 360;
384
			}
385
			if (angle >= 360) {
386
				angle -= 360;
387
			}
388
 
389
			el->angle = angle;
390
			el->imageIndex = 0;
391
 
392
			el->mask.unused = 0;
393
			el->mask.circle = 1;
394
			el->mask.w = 16;
395
			el->mask.h = 16;
396
			el->mask.x = x;
397
			el->mask.y = y;
398
 
399
			e->data = el;
400
			e->enemyStep = electricityStep;
401
			e->enemyDraw = electricityDraw;
402
			e->type = -1;
403
 
404
			enemies[i] = e;
405
			i = MAX_ENEMIES;
406
		}
407
	}
408
	/*
409
	int thisid = -1;
410
	int i;
411
	for (i = 0; i < MAX_ENEMIES; i++) {
412
		if (enemies[i] == NULL) {
413
			if (i <= minid) {
414
				thisid = i;
415
				i = MAX_ENEMIES;
416
			}else{
417
				i = MAX_ENEMIES;
418
			}
419
		}
420
	}
421
 
422
	if (thisid == -1) {
423
		for (i = minid + 1; i < MAX_ENEMIES; i++) {
424
			if (enemies[i] == NULL) {
425
				enemies[i] = enemies[minid];
426
				Crab* c = enemies[i]->data;
427
				c->id = i;
428
				thisid = minid;
429
				i = MAX_ENEMIES;
430
			}
431
		}
432
	}
433
 
434
	if (thisid != -1) {
435
		Enemy* e = (Enemy*)malloc(sizeof(Enemy));
436
		Electricity* el = (Electricity*)malloc(sizeof(Electricity));
437
		el->id = thisid;
438
 
439
		el->x = x;
440
		el->y = y;
441
 
442
		//Fix angle
443
		if (angle < 0) {
444
			angle += 360;
445
		}
446
		if (angle >= 360) {
447
			angle -= 360;
448
		}
449
 
450
		el->angle = angle;
451
		el->imageIndex = 0;
452
 
453
		el->mask.unused = 0;
454
		el->mask.circle = 1;
455
		el->mask.w = 16;
456
		el->mask.h = 16;
457
		el->mask.x = x;
458
		el->mask.y = y;
459
 
460
		e->data = el;
461
		e->enemyStep = electricityStep;
462
		e->enemyDraw = electricityDraw;
463
		e->type = -1;
464
 
465
		enemies[thisid] = e;
466
	}
467
	*/
468
}
469
 
470
void electricityStep(Electricity* e)
471
{
472
	double spd = 3;
473
	e->x += spd * sin(e->angle * 3.14159 / 180);
474
	e->y += spd * cos(e->angle * 3.14159 / 180);
475
 
476
	//Update Mask
477
	e->mask.x = e->x;
478
	e->mask.y = e->y;
479
 
480
	//Collide with Shield
481
	if (checkCollision(shieldMask, e->mask) == 1) {
482
		createEffect(1, e->x - 20, e->y - 20);
483
		PHL_PlaySound(sounds[sndHit07], CHN_EFFECTS);
484
		enemyDestroy(e->id);
485
	}else{
486
		//Collide with Hero
487
		if (checkCollision(getHeroMask(), e->mask) == 1) {
488
			if (heroHit(25, e->x) == 1) {
489
				heroStun();
490
			}
491
		}
492
	}
493
 
494
	//Animate
495
	e->imageIndex += 0.25;
496
	if (e->imageIndex >= 3) {
497
		e->imageIndex -= 3;
498
	}
499
 
500
	//Outside of screen
501
	if (e->x < -20 || e->x > 660 || e->y < -20 || e->y > 500) {
502
		enemyDestroy(e->id);
503
	}
504
}
505
 
506
void electricityDraw(Electricity* e)
507
{
508
	PHL_DrawSurfacePart(e->x - 20, e->y - 20, 40 + ((int)e->imageIndex * 40), 0, 40, 40, images[imgMisc20]);
509
}