2 // C Implementation: badguy
7 // Author: Tobias Glaesser <tobi.web@gmx.de> & Bill Kendrick, (C) 2004
9 // Copyright: See COPYING file that comes with this distribution
19 texture_type img_bsod_squished_left, img_bsod_squished_right,
20 img_bsod_falling_left, img_bsod_falling_right,
21 img_laptop_flat_left, img_laptop_flat_right,
22 img_laptop_falling_left, img_laptop_falling_right;
23 texture_type img_bsod_left[4], img_bsod_right[4],
24 img_laptop_left[3], img_laptop_right[3],
25 img_money_left[2], img_money_right[2];
28 void badguy_create_bitmasks()
30 /*bm_bsod = img_bsod_left[0];*/
33 void badguy_init(bad_guy_type* pbad, float x, float y, int kind)
35 pbad->base.width = 32;
36 pbad->base.height = 32;
37 pbad->base.alive = YES;
45 pbad->old_base = pbad->base;
48 timer_init(&pbad->timer,YES);
49 physic_init(&pbad->physic);
52 void badguy_action(bad_guy_type* pbad)
59 if (pbad->kind == BAD_BSOD)
61 /* --- BLUE SCREEN OF DEATH MONSTER: --- */
63 /* Move left/right: */
65 if (pbad->dying == NO ||
66 pbad->dying == FALLING)
68 if (pbad->dir == RIGHT)
69 pbad->base.x = pbad->base.x + pbad->base.xm * frame_ratio;
70 else if (pbad->dir == LEFT)
71 pbad->base.x = pbad->base.x - pbad->base.xm * frame_ratio;
75 /* Move vertically: */
77 pbad->base.y = pbad->base.y + pbad->base.ym * frame_ratio;
79 if (pbad->dying != FALLING)
80 collision_swept_object_map(&pbad->old_base,&pbad->base);
81 if (pbad->base.y > screen->h)
82 pbad->base.alive = NO;
84 /* Bump into things horizontally: */
88 if (issolid( pbad->base.x, (int) pbad->base.y + 16))
92 else if (issolid( pbad->base.x + pbad->base.width, (int) pbad->base.y + 16))
98 /* Fall if we get off the ground: */
100 if (pbad->dying != FALLING)
102 if (!issolid(pbad->base.x+16, pbad->base.y + 32))
104 if(!physic_is_set(&pbad->physic))
106 physic_set_state(&pbad->physic,PH_VT);
107 physic_set_start_vy(&pbad->physic,2.);
110 pbad->base.ym = physic_get_velocity(&pbad->physic);
116 if (pbad->base.ym > 0)
118 pbad->base.y = (int)(pbad->base.y / 32) * 32;
121 physic_init(&pbad->physic);
126 if(!physic_is_set(&pbad->physic))
128 physic_set_state(&pbad->physic,PH_VT);
129 physic_set_start_vy(&pbad->physic,2.);
131 pbad->base.ym = physic_get_velocity(&pbad->physic);
134 if (pbad->base.y > screen->h)
135 pbad->base.alive = NO;
137 else if (pbad->kind == BAD_LAPTOP)
139 /* --- LAPTOP MONSTER: --- */
141 /* Move left/right: */
143 if (pbad->mode == NORMAL || pbad->mode == KICK)
145 if (pbad->dying == NO ||
146 pbad->dying == FALLING)
148 if (pbad->dir == RIGHT)
149 pbad->base.x = pbad->base.x + pbad->base.xm * frame_ratio;
150 else if (pbad->dir == LEFT)
151 pbad->base.x = pbad->base.x - pbad->base.xm * frame_ratio;
154 else if (pbad->mode == HELD)
155 { /* FIXME: The pbad object shouldn't know about pplayer objects. */
156 /* If we're holding the laptop */
160 pbad->base.x = tux.base.x + 16;
161 pbad->base.y = tux.base.y + tux.base.height/1.5 - pbad->base.height;
163 else /* facing left */
165 pbad->base.x = tux.base.x - 16;
166 pbad->base.y = tux.base.y + tux.base.height/1.5 - pbad->base.height;
168 if(collision_object_map(&pbad->base))
170 pbad->base.x = tux.base.x;
171 pbad->base.y = tux.base.y + tux.base.height/1.5 - pbad->base.height;
174 if(tux.input.fire != DOWN) /* SHOOT! */
176 if(pbad->dir == LEFT)
184 play_sound(sounds[SND_KICK],SOUND_CENTER_SPEAKER);
189 /* Move vertically: */
191 if(pbad->mode != HELD)
192 pbad->base.y = pbad->base.y + pbad->base.ym * frame_ratio;
194 if (pbad->dying != FALLING)
195 collision_swept_object_map(&pbad->old_base,&pbad->base);
196 if (pbad->base.y > screen->h)
197 pbad->base.alive = NO;
198 /* Bump into things horizontally: */
200 /* Bump into things horizontally: */
204 int changed = pbad->dir;
205 if (issolid( pbad->base.x, (int) pbad->base.y + 16))
209 else if (issolid( pbad->base.x + pbad->base.width, (int) pbad->base.y + 16))
213 if(pbad->mode == KICK && changed != pbad->dir)
215 /* handle stereo sound */
216 /* FIXME: In theory a badguy object doesn't know anything about player objects */
217 if (tux.base.x > pbad->base.x)
218 play_sound(sounds[SND_RICOCHET], SOUND_LEFT_SPEAKER);
219 else if (tux.base.x < pbad->base.x)
220 play_sound(sounds[SND_RICOCHET], SOUND_RIGHT_SPEAKER);
222 play_sound(sounds[SND_RICOCHET], SOUND_CENTER_SPEAKER);
228 /* Fall if we get off the ground: */
230 if (pbad->dying != FALLING)
232 if (!issolid(pbad->base.x+16, pbad->base.y + 32))
234 if(!physic_is_set(&pbad->physic))
236 physic_set_state(&pbad->physic,PH_VT);
237 physic_set_start_vy(&pbad->physic,0.);
240 if(pbad->mode != HELD)
242 pbad->base.ym = physic_get_velocity(&pbad->physic);
249 if (pbad->base.ym > 0)
251 pbad->base.y = (int)(pbad->base.y / 32) * 32;
254 physic_init(&pbad->physic);
259 if(!physic_is_set(&pbad->physic))
261 physic_set_state(&pbad->physic,PH_VT);
262 physic_set_start_vy(&pbad->physic,0.);
264 pbad->base.ym = physic_get_velocity(&pbad->physic);
269 else if (pbad->kind == BAD_MONEY)
271 /* --- MONEY BAGS: --- */
274 /* Move vertically: */
276 pbad->base.y = pbad->base.y + pbad->base.ym * frame_ratio;
278 if (pbad->dying != FALLING)
279 collision_swept_object_map(&pbad->old_base,&pbad->base);
281 if (pbad->base.y > screen->h)
282 pbad->base.alive = NO;
284 if(physic_get_state(&pbad->physic) == -1)
286 physic_set_state(&pbad->physic,PH_VT);
287 physic_set_start_vy(&pbad->physic,0.);
290 if (pbad->dying != FALLING)
292 if(issolid(pbad->base.x, pbad->base.y + 32))
294 physic_set_state(&pbad->physic,PH_VT);
295 physic_set_start_vy(&pbad->physic,6.);
296 pbad->base.ym = physic_get_velocity(&pbad->physic);
298 else if(issolid(pbad->base.x, pbad->base.y))
299 { /* This works, but isn't the best solution imagineable */
300 physic_set_state(&pbad->physic,PH_VT);
301 physic_set_start_vy(&pbad->physic,0.);
302 pbad->base.ym = physic_get_velocity(&pbad->physic);
307 pbad->base.ym = physic_get_velocity(&pbad->physic);
312 if(!physic_is_set(&pbad->physic))
314 physic_set_state(&pbad->physic,PH_VT);
315 physic_set_start_vy(&pbad->physic,0.);
317 pbad->base.ym = physic_get_velocity(&pbad->physic);
320 else if (pbad->kind == -1)
324 else if (pbad->kind == -1)
330 /* Handle mode timer: */
332 if (pbad->mode == FLAT && pbad->mode != HELD)
334 if(!timer_check(&pbad->timer))
340 else if (pbad->mode == KICK)
342 timer_check(&pbad->timer);
346 /* Handle dying timer: */
348 if (pbad->dying == SQUISHED)
350 /* Remove it if time's up: */
351 if(!timer_check(&pbad->timer))
352 pbad->base.alive = NO;
356 /* Remove if it's far off the screen: */
358 if (pbad->base.x < scroll_x - OFFSCREEN_DISTANCE)
359 pbad->base.alive = NO;
362 /* Once it's on screen, it's activated! */
364 if (pbad->base.x <= scroll_x + screen->w + OFFSCREEN_DISTANCE)
370 void badguy_draw(bad_guy_type* pbad)
372 if (pbad->base.alive &&
373 pbad->base.x > scroll_x - 32 &&
374 pbad->base.x < scroll_x + screen->w)
376 if (pbad->kind == BAD_BSOD)
378 /* --- BLUE SCREEN OF DEATH MONSTER: --- */
380 if (pbad->dying == NO)
384 if (pbad->dir == LEFT)
386 texture_draw(&img_bsod_left[(frame / 5) % 4],
387 pbad->base.x - scroll_x,
393 texture_draw(&img_bsod_right[(frame / 5) % 4],
394 pbad->base.x - scroll_x,
399 else if (pbad->dying == FALLING)
403 if (pbad->dir == LEFT)
405 texture_draw(&img_bsod_falling_left,
406 pbad->base.x - scroll_x,
412 texture_draw(&img_bsod_falling_right,
413 pbad->base.x - scroll_x,
418 else if (pbad->dying == SQUISHED)
420 /* Dying - Squished: */
422 if (pbad->dir == LEFT)
424 texture_draw(&img_bsod_squished_left,
425 pbad->base.x - scroll_x,
431 texture_draw(&img_bsod_squished_right,
432 pbad->base.x - scroll_x,
438 else if (pbad->kind == BAD_LAPTOP)
440 /* --- LAPTOP MONSTER: --- */
442 if (pbad->dying == NO)
446 if (pbad->mode == NORMAL)
450 if (pbad->dir == LEFT)
452 texture_draw(&img_laptop_left[(frame / 5) % 3],
453 pbad->base.x - scroll_x,
459 texture_draw(&img_laptop_right[(frame / 5) % 3],
460 pbad->base.x - scroll_x,
469 if (pbad->dir == LEFT)
471 texture_draw(&img_laptop_flat_left,
472 pbad->base.x - scroll_x,
478 texture_draw(&img_laptop_flat_right,
479 pbad->base.x - scroll_x,
485 else if (pbad->dying == FALLING)
489 if (pbad->dir == LEFT)
491 texture_draw(&img_laptop_falling_left,
492 pbad->base.x - scroll_x,
498 texture_draw(&img_laptop_falling_right,
499 pbad->base.x - scroll_x,
505 else if (pbad->kind == BAD_MONEY)
507 if (pbad->base.ym != 300 /* > -16*/)
509 if (pbad->dir == LEFT)
511 texture_draw(&img_money_left[0],
512 pbad->base.x - scroll_x,
518 texture_draw(&img_money_right[0],
519 pbad->base.x - scroll_x,
526 if (pbad->dir == LEFT)
528 texture_draw(&img_money_left[1],
529 pbad->base.x - scroll_x,
535 texture_draw(&img_money_right[1],
536 pbad->base.x - scroll_x,
542 else if (pbad->kind == -1)
547 void badguy_collision(bad_guy_type* pbad, void *p_c_object, int c_object)
549 bad_guy_type* pbad_c = NULL;
550 player_type* pplayer_c = NULL;
555 pbad->dying = FALLING;
558 /* Gain some points: */
560 if (pbad->kind == BAD_BSOD)
561 add_score(pbad->base.x - scroll_x, pbad->base.y,
562 50 * score_multiplier);
563 else if (pbad->kind == BAD_LAPTOP)
564 add_score(pbad->base.x - scroll_x, pbad->base.y,
565 25 * score_multiplier);
566 else if (pbad->kind == BAD_MONEY)
567 add_score(pbad->base.x - scroll_x, pbad->base.y,
568 50 * score_multiplier);
570 /* Play death sound: */
571 play_sound(sounds[SND_FALL], SOUND_CENTER_SPEAKER);
574 pbad_c = (bad_guy_type*) p_c_object;
575 if (pbad->mode == NORMAL)
579 else if(pbad->mode == KICK)
581 /* We're in kick mode, kill the other guy
582 and yourself(wuahaha) : */
584 pbad_c->dying = FALLING;
585 pbad_c->base.ym = -8;
586 play_sound(sounds[SND_FALL], SOUND_CENTER_SPEAKER);
588 add_score(pbad->base.x - scroll_x,
590 pbad_c->dying = FALLING;
592 pbad->dying = FALLING;
595 add_score(pbad_c->base.x - scroll_x,
596 pbad_c->base.y, 100);
600 pplayer_c = (player_type*) p_c_object;
601 if(pbad->kind != BAD_MONEY)
603 if (pbad->kind == BAD_BSOD)
605 pbad->dying = SQUISHED;
606 timer_start(&pbad->timer,4000);
607 physic_set_state(&pplayer_c->vphysic,PH_VT);
608 physic_set_start_vy(&pplayer_c->vphysic,2.);
609 pplayer_c->base.y = pbad->base.y - pplayer_c->base.height - 1;
611 add_score(pbad->base.x - scroll_x, pbad->base.y,
612 50 * score_multiplier);
614 play_sound(sounds[SND_SQUISH], SOUND_CENTER_SPEAKER);
616 else if (pbad->kind == BAD_LAPTOP)
619 if (pbad->mode == NORMAL || pbad->mode == KICK)
623 play_sound(sounds[SND_STOMP], SOUND_CENTER_SPEAKER);
627 timer_start(&pbad->timer,10000);
629 physic_set_state(&pplayer_c->vphysic,PH_VT);
630 physic_set_start_vy(&pplayer_c->vphysic,2.);
631 pplayer_c->base.y = pbad->base.y - pplayer_c->base.height - 1;
633 else if (pbad->mode == FLAT)
636 play_sound(sounds[SND_KICK], SOUND_CENTER_SPEAKER);
638 if (pplayer_c->base.x < pbad->base.x + (pbad->base.width/2))
646 timer_start(&pbad->timer,5000);
649 physic_set_state(&pplayer_c->vphysic,PH_VT);
650 physic_set_start_vy(&pplayer_c->vphysic,2.);
651 pplayer_c->base.y = pbad->base.y - pplayer_c->base.height - 1;
653 add_score(pbad->base.x - scroll_x,
655 25 * score_multiplier);
657 /* play_sound(sounds[SND_SQUISH]); */