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)
183 play_sound(sounds[SND_KICK],SOUND_CENTER_SPEAKER);
188 /* Move vertically: */
190 if(pbad->mode != HELD)
191 pbad->base.y = pbad->base.y + pbad->base.ym * frame_ratio;
193 if (pbad->dying != FALLING)
194 collision_swept_object_map(&pbad->old_base,&pbad->base);
195 if (pbad->base.y > screen->h)
196 pbad->base.alive = NO;
197 /* Bump into things horizontally: */
199 /* Bump into things horizontally: */
203 int changed = pbad->dir;
204 if (issolid( pbad->base.x, (int) pbad->base.y + 16))
208 else if (issolid( pbad->base.x + pbad->base.width, (int) pbad->base.y + 16))
212 if(pbad->mode == KICK && changed != pbad->dir)
214 /* handle stereo sound */
215 /* FIXME: In theory a badguy object doesn't know anything about player objects */
216 if (tux.base.x > pbad->base.x)
217 play_sound(sounds[SND_RICOCHET], SOUND_LEFT_SPEAKER);
218 else if (tux.base.x < pbad->base.x)
219 play_sound(sounds[SND_RICOCHET], SOUND_RIGHT_SPEAKER);
221 play_sound(sounds[SND_RICOCHET], SOUND_CENTER_SPEAKER);
227 /* Fall if we get off the ground: */
229 if (pbad->dying != FALLING)
231 if (!issolid(pbad->base.x+16, pbad->base.y + 32))
233 if(!physic_is_set(&pbad->physic))
235 physic_set_state(&pbad->physic,PH_VT);
236 physic_set_start_vy(&pbad->physic,0.);
239 if(pbad->mode != HELD)
241 pbad->base.ym = physic_get_velocity(&pbad->physic);
248 if (pbad->base.ym > 0)
250 pbad->base.y = (int)(pbad->base.y / 32) * 32;
253 physic_init(&pbad->physic);
258 if(!physic_is_set(&pbad->physic))
260 physic_set_state(&pbad->physic,PH_VT);
261 physic_set_start_vy(&pbad->physic,0.);
263 pbad->base.ym = physic_get_velocity(&pbad->physic);
268 else if (pbad->kind == BAD_MONEY)
270 /* --- MONEY BAGS: --- */
273 /* Move vertically: */
275 pbad->base.y = pbad->base.y + pbad->base.ym * frame_ratio;
277 if (pbad->dying != FALLING)
278 collision_swept_object_map(&pbad->old_base,&pbad->base);
280 if (pbad->base.y > screen->h)
281 pbad->base.alive = NO;
283 if(physic_get_state(&pbad->physic) == -1)
285 physic_set_state(&pbad->physic,PH_VT);
286 physic_set_start_vy(&pbad->physic,0.);
289 if (pbad->dying != FALLING)
291 if(issolid(pbad->base.x, pbad->base.y + 32))
293 physic_set_state(&pbad->physic,PH_VT);
294 physic_set_start_vy(&pbad->physic,6.);
295 pbad->base.ym = physic_get_velocity(&pbad->physic);
297 else if(issolid(pbad->base.x, pbad->base.y))
298 { /* This works, but isn't the best solution imagineable */
299 physic_set_state(&pbad->physic,PH_VT);
300 physic_set_start_vy(&pbad->physic,0.);
301 pbad->base.ym = physic_get_velocity(&pbad->physic);
306 pbad->base.ym = physic_get_velocity(&pbad->physic);
311 if(!physic_is_set(&pbad->physic))
313 physic_set_state(&pbad->physic,PH_VT);
314 physic_set_start_vy(&pbad->physic,0.);
316 pbad->base.ym = physic_get_velocity(&pbad->physic);
319 else if (pbad->kind == -1)
323 else if (pbad->kind == -1)
329 /* Handle mode timer: */
331 if (pbad->mode == FLAT && pbad->mode != HELD)
333 if(!timer_check(&pbad->timer))
339 else if (pbad->mode == KICK)
341 timer_check(&pbad->timer);
345 /* Handle dying timer: */
347 if (pbad->dying == SQUISHED)
349 /* Remove it if time's up: */
350 if(!timer_check(&pbad->timer))
351 pbad->base.alive = NO;
355 /* Remove if it's far off the screen: */
357 if (pbad->base.x < scroll_x - OFFSCREEN_DISTANCE)
358 pbad->base.alive = NO;
361 /* Once it's on screen, it's activated! */
363 if (pbad->base.x <= scroll_x + screen->w + OFFSCREEN_DISTANCE)
369 void badguy_draw(bad_guy_type* pbad)
371 if (pbad->base.alive &&
372 pbad->base.x > scroll_x - 32 &&
373 pbad->base.x < scroll_x + screen->w)
375 if (pbad->kind == BAD_BSOD)
377 /* --- BLUE SCREEN OF DEATH MONSTER: --- */
379 if (pbad->dying == NO)
383 if (pbad->dir == LEFT)
385 texture_draw(&img_bsod_left[(frame / 5) % 4],
386 pbad->base.x - scroll_x,
392 texture_draw(&img_bsod_right[(frame / 5) % 4],
393 pbad->base.x - scroll_x,
398 else if (pbad->dying == FALLING)
402 if (pbad->dir == LEFT)
404 texture_draw(&img_bsod_falling_left,
405 pbad->base.x - scroll_x,
411 texture_draw(&img_bsod_falling_right,
412 pbad->base.x - scroll_x,
417 else if (pbad->dying == SQUISHED)
419 /* Dying - Squished: */
421 if (pbad->dir == LEFT)
423 texture_draw(&img_bsod_squished_left,
424 pbad->base.x - scroll_x,
430 texture_draw(&img_bsod_squished_right,
431 pbad->base.x - scroll_x,
437 else if (pbad->kind == BAD_LAPTOP)
439 /* --- LAPTOP MONSTER: --- */
441 if (pbad->dying == NO)
445 if (pbad->mode == NORMAL)
449 if (pbad->dir == LEFT)
451 texture_draw(&img_laptop_left[(frame / 5) % 3],
452 pbad->base.x - scroll_x,
458 texture_draw(&img_laptop_right[(frame / 5) % 3],
459 pbad->base.x - scroll_x,
468 if (pbad->dir == LEFT)
470 texture_draw(&img_laptop_flat_left,
471 pbad->base.x - scroll_x,
477 texture_draw(&img_laptop_flat_right,
478 pbad->base.x - scroll_x,
484 else if (pbad->dying == FALLING)
488 if (pbad->dir == LEFT)
490 texture_draw(&img_laptop_falling_left,
491 pbad->base.x - scroll_x,
497 texture_draw(&img_laptop_falling_right,
498 pbad->base.x - scroll_x,
504 else if (pbad->kind == BAD_MONEY)
506 if (pbad->base.ym != 300 /* > -16*/)
508 if (pbad->dir == LEFT)
510 texture_draw(&img_money_left[0],
511 pbad->base.x - scroll_x,
517 texture_draw(&img_money_right[0],
518 pbad->base.x - scroll_x,
525 if (pbad->dir == LEFT)
527 texture_draw(&img_money_left[1],
528 pbad->base.x - scroll_x,
534 texture_draw(&img_money_right[1],
535 pbad->base.x - scroll_x,
541 else if (pbad->kind == -1)
546 void badguy_collision(bad_guy_type* pbad, void *p_c_object, int c_object)
548 bad_guy_type* pbad_c = NULL;
549 player_type* pplayer_c = NULL;
554 pbad->dying = FALLING;
557 /* Gain some points: */
559 if (pbad->kind == BAD_BSOD)
560 add_score(pbad->base.x - scroll_x, pbad->base.y,
561 50 * score_multiplier);
562 else if (pbad->kind == BAD_LAPTOP)
563 add_score(pbad->base.x - scroll_x, pbad->base.y,
564 25 * score_multiplier);
565 else if (pbad->kind == BAD_MONEY)
566 add_score(pbad->base.x - scroll_x, pbad->base.y,
567 50 * score_multiplier);
569 /* Play death sound: */
570 play_sound(sounds[SND_FALL], SOUND_CENTER_SPEAKER);
573 pbad_c = (bad_guy_type*) p_c_object;
574 if (pbad->mode == NORMAL)
580 /* We're in kick mode, kill the other guy: */
582 pbad_c->dying = FALLING;
583 pbad_c->base.ym = -8;
584 play_sound(sounds[SND_FALL], SOUND_CENTER_SPEAKER);
586 add_score(pbad->base.x - scroll_x,
591 pplayer_c = (player_type*) p_c_object;
592 if(pbad->kind != BAD_MONEY)
594 if (pbad->kind == BAD_BSOD)
596 pbad->dying = SQUISHED;
597 timer_start(&pbad->timer,4000);
598 physic_set_state(&pplayer_c->vphysic,PH_VT);
599 physic_set_start_vy(&pplayer_c->vphysic,2.);
600 pplayer_c->base.y = pbad->base.y - pplayer_c->base.height;
602 add_score(pbad->base.x - scroll_x, pbad->base.y,
603 50 * score_multiplier);
605 play_sound(sounds[SND_SQUISH], SOUND_CENTER_SPEAKER);
607 else if (pbad->kind == BAD_LAPTOP)
610 if (pbad->mode == NORMAL || pbad->mode == KICK)
614 play_sound(sounds[SND_STOMP], SOUND_CENTER_SPEAKER);
618 timer_start(&pbad->timer,10000);
620 physic_set_state(&pplayer_c->vphysic,PH_VT);
621 physic_set_start_vy(&pplayer_c->vphysic,2.);
622 pplayer_c->base.y = pbad->base.y - pplayer_c->base.height;
624 else if (pbad->mode == FLAT)
628 play_sound(sounds[SND_KICK], SOUND_CENTER_SPEAKER);
630 if (pplayer_c->base.x <= pbad->base.x)
637 timer_start(&pbad->timer,5000);
640 physic_set_state(&pplayer_c->vphysic,PH_VT);
641 physic_set_start_vy(&pplayer_c->vphysic,2.);
642 pplayer_c->base.y = pbad->base.y - pplayer_c->base.height;
644 add_score(pbad->base.x - scroll_x,
646 25 * score_multiplier);
648 /* play_sound(sounds[SND_SQUISH]); */