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;
20 texture_type img_bsod_squished_right;
21 texture_type img_bsod_falling_left;
22 texture_type img_bsod_falling_right;
23 texture_type img_laptop_flat_left;
24 texture_type img_laptop_flat_right;
25 texture_type img_laptop_falling_left;
26 texture_type img_laptop_falling_right;
27 texture_type img_bsod_left[4];
28 texture_type img_bsod_right[4];
29 texture_type img_laptop_left[3];
30 texture_type img_laptop_right[3];
31 texture_type img_money_left[2];
32 texture_type img_money_right[2];
36 void badguy_create_bitmasks()
38 /*bm_bsod = img_bsod_left[0];*/
41 void badguy_init(bad_guy_type* pbad, float x, float y, int kind)
43 pbad->base.width = 32;
44 pbad->base.height = 32;
46 pbad->dying = DYING_NOT;
52 pbad->old_base = pbad->base;
55 timer_init(&pbad->timer, true);
56 physic_init(&pbad->physic);
59 void badguy_action(bad_guy_type* pbad)
64 if (pbad->kind == BAD_BSOD)
66 /* --- BLUE SCREEN OF DEATH MONSTER: --- */
68 /* Move left/right: */
69 if (pbad->dying == DYING_NOT ||
70 pbad->dying == DYING_FALLING)
72 if (pbad->dir == RIGHT)
73 pbad->base.x = pbad->base.x + pbad->base.xm * frame_ratio;
74 else if (pbad->dir == LEFT)
75 pbad->base.x = pbad->base.x - pbad->base.xm * frame_ratio;
79 /* Move vertically: */
81 pbad->base.y = pbad->base.y + pbad->base.ym * frame_ratio;
83 if (pbad->dying != DYING_FALLING)
84 collision_swept_object_map(&pbad->old_base,&pbad->base);
85 if (pbad->base.y > screen->h)
86 bad_guys.erase(static_cast<std::vector<bad_guy_type>::iterator>(pbad));
88 /* Bump into things horizontally: */
92 if (issolid( pbad->base.x, (int) pbad->base.y + 16))
96 else if (issolid( pbad->base.x + pbad->base.width, (int) pbad->base.y + 16))
102 /* Fall if we get off the ground: */
104 if (pbad->dying != DYING_FALLING)
106 if (!issolid(pbad->base.x+16, pbad->base.y + 32))
108 if(!physic_is_set(&pbad->physic))
110 physic_set_state(&pbad->physic,PH_VT);
111 physic_set_start_vy(&pbad->physic,2.);
114 pbad->base.ym = physic_get_velocity(&pbad->physic);
120 if (pbad->base.ym > 0)
122 pbad->base.y = (int)(pbad->base.y / 32) * 32;
125 physic_init(&pbad->physic);
130 if(!physic_is_set(&pbad->physic))
132 physic_set_state(&pbad->physic,PH_VT);
133 physic_set_start_vy(&pbad->physic,2.);
135 pbad->base.ym = physic_get_velocity(&pbad->physic);
138 if (pbad->base.y > screen->h)
139 bad_guys.erase(static_cast<std::vector<bad_guy_type>::iterator>(pbad));
141 else if (pbad->kind == BAD_LAPTOP)
143 /* --- LAPTOP MONSTER: --- */
145 /* Move left/right: */
147 if (pbad->mode == NORMAL || pbad->mode == KICK)
149 if (pbad->dying == DYING_NOT ||
150 pbad->dying == DYING_FALLING)
152 if (pbad->dir == RIGHT)
153 pbad->base.x = pbad->base.x + pbad->base.xm * frame_ratio;
154 else if (pbad->dir == LEFT)
155 pbad->base.x = pbad->base.x - pbad->base.xm * frame_ratio;
158 else if (pbad->mode == HELD)
159 { /* FIXME: The pbad object shouldn't know about pplayer objects. */
160 /* If we're holding the laptop */
164 pbad->base.x = tux.base.x + 16;
165 pbad->base.y = tux.base.y + tux.base.height/1.5 - pbad->base.height;
167 else /* facing left */
169 pbad->base.x = tux.base.x - 16;
170 pbad->base.y = tux.base.y + tux.base.height/1.5 - pbad->base.height;
172 if(collision_object_map(&pbad->base))
174 pbad->base.x = tux.base.x;
175 pbad->base.y = tux.base.y + tux.base.height/1.5 - pbad->base.height;
178 if(tux.input.fire != DOWN) /* SHOOT! */
180 if(pbad->dir == LEFT)
188 play_sound(sounds[SND_KICK],SOUND_CENTER_SPEAKER);
193 /* Move vertically: */
195 if(pbad->mode != HELD)
196 pbad->base.y = pbad->base.y + pbad->base.ym * frame_ratio;
198 if (pbad->dying != DYING_FALLING)
199 collision_swept_object_map(&pbad->old_base,&pbad->base);
200 if (pbad->base.y > screen->h)
201 bad_guys.erase(static_cast<std::vector<bad_guy_type>::iterator>(pbad));
202 /* Bump into things horizontally: */
204 /* Bump into things horizontally: */
208 int changed = pbad->dir;
209 if (issolid( pbad->base.x, (int) pbad->base.y + 16))
213 else if (issolid( pbad->base.x + pbad->base.width, (int) pbad->base.y + 16))
217 if(pbad->mode == KICK && changed != pbad->dir)
219 /* handle stereo sound */
220 /* FIXME: In theory a badguy object doesn't know anything about player objects */
221 if (tux.base.x > pbad->base.x)
222 play_sound(sounds[SND_RICOCHET], SOUND_LEFT_SPEAKER);
223 else if (tux.base.x < pbad->base.x)
224 play_sound(sounds[SND_RICOCHET], SOUND_RIGHT_SPEAKER);
226 play_sound(sounds[SND_RICOCHET], SOUND_CENTER_SPEAKER);
232 /* Fall if we get off the ground: */
234 if (pbad->dying != DYING_FALLING)
236 if (!issolid(pbad->base.x+16, pbad->base.y + 32))
238 if(!physic_is_set(&pbad->physic))
240 physic_set_state(&pbad->physic,PH_VT);
241 physic_set_start_vy(&pbad->physic,0.);
244 if(pbad->mode != HELD)
246 pbad->base.ym = physic_get_velocity(&pbad->physic);
253 if (pbad->base.ym > 0)
255 pbad->base.y = (int)(pbad->base.y / 32) * 32;
258 physic_init(&pbad->physic);
263 if(!physic_is_set(&pbad->physic))
265 physic_set_state(&pbad->physic,PH_VT);
266 physic_set_start_vy(&pbad->physic,0.);
268 pbad->base.ym = physic_get_velocity(&pbad->physic);
273 else if (pbad->kind == BAD_MONEY)
275 /* --- MONEY BAGS: --- */
278 /* Move vertically: */
280 pbad->base.y = pbad->base.y + pbad->base.ym * frame_ratio;
282 if (pbad->dying != DYING_FALLING)
283 collision_swept_object_map(&pbad->old_base,&pbad->base);
285 if (pbad->base.y > screen->h)
286 bad_guys.erase(static_cast<std::vector<bad_guy_type>::iterator>(pbad));
288 if(physic_get_state(&pbad->physic) == -1)
290 physic_set_state(&pbad->physic,PH_VT);
291 physic_set_start_vy(&pbad->physic,0.);
294 if (pbad->dying != DYING_FALLING)
296 if(issolid(pbad->base.x, pbad->base.y + 32))
298 physic_set_state(&pbad->physic,PH_VT);
299 physic_set_start_vy(&pbad->physic,6.);
300 pbad->base.ym = physic_get_velocity(&pbad->physic);
302 else if(issolid(pbad->base.x, pbad->base.y))
303 { /* This works, but isn't the best solution imagineable */
304 physic_set_state(&pbad->physic,PH_VT);
305 physic_set_start_vy(&pbad->physic,0.);
306 pbad->base.ym = physic_get_velocity(&pbad->physic);
311 pbad->base.ym = physic_get_velocity(&pbad->physic);
316 if(!physic_is_set(&pbad->physic))
318 physic_set_state(&pbad->physic,PH_VT);
319 physic_set_start_vy(&pbad->physic,0.);
321 pbad->base.ym = physic_get_velocity(&pbad->physic);
324 else if (pbad->kind == -1)
328 else if (pbad->kind == -1)
331 /* Handle mode timer: */
333 if (pbad->mode == FLAT && pbad->mode != HELD)
335 if(!timer_check(&pbad->timer))
341 else if (pbad->mode == KICK)
343 timer_check(&pbad->timer);
347 /* Handle dying timer: */
349 if (pbad->dying == DYING_SQUISHED)
351 /* Remove it if time's up: */
352 if(!timer_check(&pbad->timer))
353 bad_guys.erase(static_cast<std::vector<bad_guy_type>::iterator>(pbad));
357 /* Remove if it's far off the screen: */
359 if (pbad->base.x < scroll_x - OFFSCREEN_DISTANCE)
360 bad_guys.erase(static_cast<std::vector<bad_guy_type>::iterator>(pbad));
363 /* Once it's on screen, it's activated! */
365 if (pbad->base.x <= scroll_x + screen->w + OFFSCREEN_DISTANCE)
371 void badguy_draw_bsod(bad_guy_type* pbad)
373 /* --- BLUE SCREEN OF DEATH MONSTER: --- */
374 if (pbad->dying == DYING_NOT)
378 if (pbad->dir == LEFT)
380 texture_draw(&img_bsod_left[(frame / 5) % 4],
381 pbad->base.x - scroll_x,
386 texture_draw(&img_bsod_right[(frame / 5) % 4],
387 pbad->base.x - scroll_x,
391 else if (pbad->dying == DYING_FALLING)
395 if (pbad->dir == LEFT)
397 texture_draw(&img_bsod_falling_left,
398 pbad->base.x - scroll_x,
403 texture_draw(&img_bsod_falling_right,
404 pbad->base.x - scroll_x,
408 else if (pbad->dying == DYING_SQUISHED)
410 /* Dying - Squished: */
412 if (pbad->dir == LEFT)
414 texture_draw(&img_bsod_squished_left,
415 pbad->base.x - scroll_x,
420 texture_draw(&img_bsod_squished_right,
421 pbad->base.x - scroll_x,
427 void badguy_draw_laptop(bad_guy_type* pbad)
429 /* --- LAPTOP MONSTER: --- */
430 if (pbad->dying == DYING_NOT)
434 if (pbad->mode == NORMAL)
438 if (pbad->dir == LEFT)
440 texture_draw(&img_laptop_left[(frame / 5) % 3],
441 pbad->base.x - scroll_x,
446 texture_draw(&img_laptop_right[(frame / 5) % 3],
447 pbad->base.x - scroll_x,
455 if (pbad->dir == LEFT)
457 texture_draw(&img_laptop_flat_left,
458 pbad->base.x - scroll_x,
463 texture_draw(&img_laptop_flat_right,
464 pbad->base.x - scroll_x,
469 else if (pbad->dying == DYING_FALLING)
473 if (pbad->dir == LEFT)
475 texture_draw(&img_laptop_falling_left,
476 pbad->base.x - scroll_x,
481 texture_draw(&img_laptop_falling_right,
482 pbad->base.x - scroll_x,
488 void badguy_draw_money(bad_guy_type* pbad)
490 if (pbad->base.ym != 300 /* > -16*/)
492 if (pbad->dir == LEFT)
494 texture_draw(&img_money_left[0],
495 pbad->base.x - scroll_x,
500 texture_draw(&img_money_right[0],
501 pbad->base.x - scroll_x,
507 if (pbad->dir == LEFT)
509 texture_draw(&img_money_left[1],
510 pbad->base.x - scroll_x,
515 texture_draw(&img_money_right[1],
516 pbad->base.x - scroll_x,
522 void badguy_draw(bad_guy_type* pbad)
524 // Don't try to draw stuff that is outside of the screen
525 if (pbad->base.x > scroll_x - 32 &&
526 pbad->base.x < scroll_x + screen->w)
531 badguy_draw_bsod(pbad);
535 badguy_draw_laptop(pbad);
539 badguy_draw_money(pbad);
543 puts("Unknown badguy type");
549 void badguy_collision(bad_guy_type* pbad, void *p_c_object, int c_object)
551 bad_guy_type* pbad_c = NULL;
552 player_type* pplayer_c = NULL;
557 pbad->dying = DYING_FALLING;
560 /* Gain some points: */
562 if (pbad->kind == BAD_BSOD)
563 add_score(pbad->base.x - scroll_x, pbad->base.y,
564 50 * score_multiplier);
565 else if (pbad->kind == BAD_LAPTOP)
566 add_score(pbad->base.x - scroll_x, pbad->base.y,
567 25 * score_multiplier);
568 else if (pbad->kind == BAD_MONEY)
569 add_score(pbad->base.x - scroll_x, pbad->base.y,
570 50 * score_multiplier);
572 /* Play death sound: */
573 play_sound(sounds[SND_FALL], SOUND_CENTER_SPEAKER);
577 pbad_c = (bad_guy_type*) p_c_object;
578 if (pbad->mode == NORMAL)
582 else if(pbad->mode == KICK)
584 /* We're in kick mode, kill the other guy
585 and yourself(wuahaha) : */
587 pbad_c->dying = DYING_FALLING;
588 pbad_c->base.ym = -8;
589 play_sound(sounds[SND_FALL], SOUND_CENTER_SPEAKER);
591 add_score(pbad->base.x - scroll_x,
593 pbad_c->dying = DYING_FALLING;
595 pbad->dying = DYING_FALLING;
598 add_score(pbad_c->base.x - scroll_x,
599 pbad_c->base.y, 100);
604 pplayer_c = (player_type*) p_c_object;
605 if(pbad->kind != BAD_MONEY)
607 if (pbad->kind == BAD_BSOD)
609 pbad->dying = DYING_SQUISHED;
610 timer_start(&pbad->timer,4000);
611 physic_set_state(&pplayer_c->vphysic,PH_VT);
612 physic_set_start_vy(&pplayer_c->vphysic,2.);
613 pplayer_c->base.y = pbad->base.y - pplayer_c->base.height - 1;
615 add_score(pbad->base.x - scroll_x, pbad->base.y,
616 50 * score_multiplier);
618 play_sound(sounds[SND_SQUISH], SOUND_CENTER_SPEAKER);
620 else if (pbad->kind == BAD_LAPTOP)
623 if (pbad->mode == NORMAL || pbad->mode == KICK)
627 play_sound(sounds[SND_STOMP], SOUND_CENTER_SPEAKER);
631 timer_start(&pbad->timer,10000);
633 physic_set_state(&pplayer_c->vphysic,PH_VT);
634 physic_set_start_vy(&pplayer_c->vphysic,2.);
635 pplayer_c->base.y = pbad->base.y - pplayer_c->base.height - 1;
637 else if (pbad->mode == FLAT)
640 play_sound(sounds[SND_KICK], SOUND_CENTER_SPEAKER);
642 if (pplayer_c->base.x < pbad->base.x + (pbad->base.width/2))
650 timer_start(&pbad->timer,5000);
653 physic_set_state(&pplayer_c->vphysic,PH_VT);
654 physic_set_start_vy(&pplayer_c->vphysic,2.);
655 pplayer_c->base.y = pbad->base.y - pplayer_c->base.height - 1;
657 add_score(pbad->base.x - scroll_x,
659 25 * score_multiplier);
661 /* play_sound(sounds[SND_SQUISH]); */