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_bsod(bad_guy_type* pbad)
61 /* --- BLUE SCREEN OF DEATH MONSTER: --- */
63 /* Move left/right: */
64 if (pbad->dying == DYING_NOT ||
65 pbad->dying == DYING_FALLING)
67 if (pbad->dir == RIGHT)
68 pbad->base.x = pbad->base.x + pbad->base.xm * frame_ratio;
69 else if (pbad->dir == LEFT)
70 pbad->base.x = pbad->base.x - pbad->base.xm * frame_ratio;
74 /* Move vertically: */
76 pbad->base.y = pbad->base.y + pbad->base.ym * frame_ratio;
78 if (pbad->dying != DYING_FALLING)
79 collision_swept_object_map(&pbad->old_base,&pbad->base);
80 if (pbad->base.y > screen->h)
81 bad_guys.erase(static_cast<std::vector<bad_guy_type>::iterator>(pbad));
83 /* Bump into things horizontally: */
87 if (issolid( pbad->base.x, (int) pbad->base.y + 16))
91 else if (issolid( pbad->base.x + pbad->base.width, (int) pbad->base.y + 16))
97 /* Fall if we get off the ground: */
99 if (pbad->dying != DYING_FALLING)
101 if (!issolid(pbad->base.x+16, pbad->base.y + 32))
103 if(!physic_is_set(&pbad->physic))
105 physic_set_state(&pbad->physic,PH_VT);
106 physic_set_start_vy(&pbad->physic,2.);
109 pbad->base.ym = physic_get_velocity(&pbad->physic);
115 if (pbad->base.ym > 0)
117 pbad->base.y = (int)(pbad->base.y / 32) * 32;
120 physic_init(&pbad->physic);
125 if(!physic_is_set(&pbad->physic))
127 physic_set_state(&pbad->physic,PH_VT);
128 physic_set_start_vy(&pbad->physic,2.);
130 pbad->base.ym = physic_get_velocity(&pbad->physic);
133 if (pbad->base.y > screen->h)
134 bad_guys.erase(static_cast<std::vector<bad_guy_type>::iterator>(pbad));
137 void badguy_action_laptop(bad_guy_type* pbad)
139 /* --- LAPTOP MONSTER: --- */
141 /* Move left/right: */
143 if (pbad->mode == NORMAL || pbad->mode == KICK)
145 if (pbad->dying == DYING_NOT ||
146 pbad->dying == 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 != DYING_FALLING)
195 collision_swept_object_map(&pbad->old_base,&pbad->base);
196 if (pbad->base.y > screen->h)
197 bad_guys.erase(static_cast<std::vector<bad_guy_type>::iterator>(pbad));
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 != 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);
268 void badguy_action_money(bad_guy_type* pbad)
270 /* --- MONEY BAGS: --- */
273 /* Move vertically: */
275 pbad->base.y = pbad->base.y + pbad->base.ym * frame_ratio;
277 if (pbad->dying != DYING_FALLING)
278 collision_swept_object_map(&pbad->old_base,&pbad->base);
280 if (pbad->base.y > screen->h)
281 bad_guys.erase(static_cast<std::vector<bad_guy_type>::iterator>(pbad));
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 != 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);
320 void badguy_action(bad_guy_type* pbad)
327 badguy_action_bsod(pbad);
331 badguy_action_bsod(pbad);
335 badguy_action_money(pbad);
340 /* Handle mode timer: */
341 if (pbad->mode == FLAT && pbad->mode != HELD)
343 if(!timer_check(&pbad->timer))
349 else if (pbad->mode == KICK)
351 timer_check(&pbad->timer);
354 // Handle dying timer:
355 if (pbad->dying == DYING_SQUISHED)
357 /* Remove it if time's up: */
358 if(!timer_check(&pbad->timer))
359 bad_guys.erase(static_cast<std::vector<bad_guy_type>::iterator>(pbad));
362 // Remove if it's far off the screen:
363 if (pbad->base.x < scroll_x - OFFSCREEN_DISTANCE)
365 bad_guys.erase(static_cast<std::vector<bad_guy_type>::iterator>(pbad));
370 // Once it's on screen, it's activated!
371 if (pbad->base.x <= scroll_x + screen->w + OFFSCREEN_DISTANCE)
376 void badguy_draw_bsod(bad_guy_type* pbad)
378 /* --- BLUE SCREEN OF DEATH MONSTER: --- */
379 if (pbad->dying == DYING_NOT)
383 if (pbad->dir == LEFT)
385 texture_draw(&img_bsod_left[(frame / 5) % 4],
386 pbad->base.x - scroll_x,
391 texture_draw(&img_bsod_right[(frame / 5) % 4],
392 pbad->base.x - scroll_x,
396 else if (pbad->dying == DYING_FALLING)
400 if (pbad->dir == LEFT)
402 texture_draw(&img_bsod_falling_left,
403 pbad->base.x - scroll_x,
408 texture_draw(&img_bsod_falling_right,
409 pbad->base.x - scroll_x,
413 else if (pbad->dying == DYING_SQUISHED)
415 /* Dying - Squished: */
417 if (pbad->dir == LEFT)
419 texture_draw(&img_bsod_squished_left,
420 pbad->base.x - scroll_x,
425 texture_draw(&img_bsod_squished_right,
426 pbad->base.x - scroll_x,
432 void badguy_draw_laptop(bad_guy_type* pbad)
434 /* --- LAPTOP MONSTER: --- */
435 if (pbad->dying == DYING_NOT)
439 if (pbad->mode == NORMAL)
443 if (pbad->dir == LEFT)
445 texture_draw(&img_laptop_left[(frame / 5) % 3],
446 pbad->base.x - scroll_x,
451 texture_draw(&img_laptop_right[(frame / 5) % 3],
452 pbad->base.x - scroll_x,
460 if (pbad->dir == LEFT)
462 texture_draw(&img_laptop_flat_left,
463 pbad->base.x - scroll_x,
468 texture_draw(&img_laptop_flat_right,
469 pbad->base.x - scroll_x,
474 else if (pbad->dying == DYING_FALLING)
478 if (pbad->dir == LEFT)
480 texture_draw(&img_laptop_falling_left,
481 pbad->base.x - scroll_x,
486 texture_draw(&img_laptop_falling_right,
487 pbad->base.x - scroll_x,
493 void badguy_draw_money(bad_guy_type* pbad)
495 if (pbad->base.ym != 300 /* > -16*/)
497 if (pbad->dir == LEFT)
499 texture_draw(&img_money_left[0],
500 pbad->base.x - scroll_x,
505 texture_draw(&img_money_right[0],
506 pbad->base.x - scroll_x,
512 if (pbad->dir == LEFT)
514 texture_draw(&img_money_left[1],
515 pbad->base.x - scroll_x,
520 texture_draw(&img_money_right[1],
521 pbad->base.x - scroll_x,
527 void badguy_draw(bad_guy_type* pbad)
529 // Don't try to draw stuff that is outside of the screen
530 if (pbad->base.x > scroll_x - 32 &&
531 pbad->base.x < scroll_x + screen->w)
536 badguy_draw_bsod(pbad);
540 badguy_draw_laptop(pbad);
544 badguy_draw_money(pbad);
548 puts("Unknown badguy type");
554 void badguy_collision(bad_guy_type* pbad, void *p_c_object, int c_object)
556 bad_guy_type* pbad_c = NULL;
557 player_type* pplayer_c = NULL;
562 pbad->dying = DYING_FALLING;
565 /* Gain some points: */
567 if (pbad->kind == BAD_BSOD)
568 add_score(pbad->base.x - scroll_x, pbad->base.y,
569 50 * score_multiplier);
570 else if (pbad->kind == BAD_LAPTOP)
571 add_score(pbad->base.x - scroll_x, pbad->base.y,
572 25 * score_multiplier);
573 else if (pbad->kind == BAD_MONEY)
574 add_score(pbad->base.x - scroll_x, pbad->base.y,
575 50 * score_multiplier);
577 /* Play death sound: */
578 play_sound(sounds[SND_FALL], SOUND_CENTER_SPEAKER);
582 pbad_c = (bad_guy_type*) p_c_object;
583 if (pbad->mode == NORMAL)
587 else if(pbad->mode == KICK)
589 /* We're in kick mode, kill the other guy
590 and yourself(wuahaha) : */
592 pbad_c->dying = DYING_FALLING;
593 pbad_c->base.ym = -8;
594 play_sound(sounds[SND_FALL], SOUND_CENTER_SPEAKER);
596 add_score(pbad->base.x - scroll_x,
598 pbad_c->dying = DYING_FALLING;
600 pbad->dying = DYING_FALLING;
603 add_score(pbad_c->base.x - scroll_x,
604 pbad_c->base.y, 100);
609 pplayer_c = (player_type*) p_c_object;
610 if(pbad->kind != BAD_MONEY)
612 if (pbad->kind == BAD_BSOD)
614 pbad->dying = DYING_SQUISHED;
615 timer_start(&pbad->timer,4000);
616 physic_set_state(&pplayer_c->vphysic,PH_VT);
617 physic_set_start_vy(&pplayer_c->vphysic,2.);
618 pplayer_c->base.y = pbad->base.y - pplayer_c->base.height - 1;
620 add_score(pbad->base.x - scroll_x, pbad->base.y,
621 50 * score_multiplier);
623 play_sound(sounds[SND_SQUISH], SOUND_CENTER_SPEAKER);
625 else if (pbad->kind == BAD_LAPTOP)
628 if (pbad->mode == NORMAL || pbad->mode == KICK)
632 play_sound(sounds[SND_STOMP], SOUND_CENTER_SPEAKER);
636 timer_start(&pbad->timer,10000);
638 physic_set_state(&pplayer_c->vphysic,PH_VT);
639 physic_set_start_vy(&pplayer_c->vphysic,2.);
640 pplayer_c->base.y = pbad->base.y - pplayer_c->base.height - 1;
642 else if (pbad->mode == FLAT)
645 play_sound(sounds[SND_KICK], SOUND_CENTER_SPEAKER);
647 if (pplayer_c->base.x < pbad->base.x + (pbad->base.width/2))
655 timer_start(&pbad->timer,5000);
658 physic_set_state(&pplayer_c->vphysic,PH_VT);
659 physic_set_start_vy(&pplayer_c->vphysic,2.);
660 pplayer_c->base.y = pbad->base.y - pplayer_c->base.height - 1;
662 add_score(pbad->base.x - scroll_x,
664 25 * score_multiplier);
666 /* play_sound(sounds[SND_SQUISH]); */