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;
38 pbad->dying = DYING_NOT;
44 pbad->old_base = pbad->base;
47 timer_init(&pbad->timer, true);
48 physic_init(&pbad->physic);
51 void badguy_action(bad_guy_type* pbad)
56 if (pbad->kind == BAD_BSOD)
58 /* --- BLUE SCREEN OF DEATH MONSTER: --- */
60 /* Move left/right: */
61 if (pbad->dying == DYING_NOT ||
62 pbad->dying == DYING_FALLING)
64 if (pbad->dir == RIGHT)
65 pbad->base.x = pbad->base.x + pbad->base.xm * frame_ratio;
66 else if (pbad->dir == LEFT)
67 pbad->base.x = pbad->base.x - pbad->base.xm * frame_ratio;
71 /* Move vertically: */
73 pbad->base.y = pbad->base.y + pbad->base.ym * frame_ratio;
75 if (pbad->dying != DYING_FALLING)
76 collision_swept_object_map(&pbad->old_base,&pbad->base);
77 if (pbad->base.y > screen->h)
78 bad_guys.erase(static_cast<std::vector<bad_guy_type>::iterator>(pbad));
80 /* Bump into things horizontally: */
84 if (issolid( pbad->base.x, (int) pbad->base.y + 16))
88 else if (issolid( pbad->base.x + pbad->base.width, (int) pbad->base.y + 16))
94 /* Fall if we get off the ground: */
96 if (pbad->dying != DYING_FALLING)
98 if (!issolid(pbad->base.x+16, pbad->base.y + 32))
100 if(!physic_is_set(&pbad->physic))
102 physic_set_state(&pbad->physic,PH_VT);
103 physic_set_start_vy(&pbad->physic,2.);
106 pbad->base.ym = physic_get_velocity(&pbad->physic);
112 if (pbad->base.ym > 0)
114 pbad->base.y = (int)(pbad->base.y / 32) * 32;
117 physic_init(&pbad->physic);
122 if(!physic_is_set(&pbad->physic))
124 physic_set_state(&pbad->physic,PH_VT);
125 physic_set_start_vy(&pbad->physic,2.);
127 pbad->base.ym = physic_get_velocity(&pbad->physic);
130 if (pbad->base.y > screen->h)
131 bad_guys.erase(static_cast<std::vector<bad_guy_type>::iterator>(pbad));
133 else if (pbad->kind == BAD_LAPTOP)
135 /* --- LAPTOP MONSTER: --- */
137 /* Move left/right: */
139 if (pbad->mode == NORMAL || pbad->mode == KICK)
141 if (pbad->dying == DYING_NOT ||
142 pbad->dying == DYING_FALLING)
144 if (pbad->dir == RIGHT)
145 pbad->base.x = pbad->base.x + pbad->base.xm * frame_ratio;
146 else if (pbad->dir == LEFT)
147 pbad->base.x = pbad->base.x - pbad->base.xm * frame_ratio;
150 else if (pbad->mode == HELD)
151 { /* FIXME: The pbad object shouldn't know about pplayer objects. */
152 /* If we're holding the laptop */
156 pbad->base.x = tux.base.x + 16;
157 pbad->base.y = tux.base.y + tux.base.height/1.5 - pbad->base.height;
159 else /* facing left */
161 pbad->base.x = tux.base.x - 16;
162 pbad->base.y = tux.base.y + tux.base.height/1.5 - pbad->base.height;
164 if(collision_object_map(&pbad->base))
166 pbad->base.x = tux.base.x;
167 pbad->base.y = tux.base.y + tux.base.height/1.5 - pbad->base.height;
170 if(tux.input.fire != DOWN) /* SHOOT! */
172 if(pbad->dir == LEFT)
180 play_sound(sounds[SND_KICK],SOUND_CENTER_SPEAKER);
185 /* Move vertically: */
187 if(pbad->mode != HELD)
188 pbad->base.y = pbad->base.y + pbad->base.ym * frame_ratio;
190 if (pbad->dying != DYING_FALLING)
191 collision_swept_object_map(&pbad->old_base,&pbad->base);
192 if (pbad->base.y > screen->h)
193 bad_guys.erase(static_cast<std::vector<bad_guy_type>::iterator>(pbad));
194 /* Bump into things horizontally: */
196 /* Bump into things horizontally: */
200 int changed = pbad->dir;
201 if (issolid( pbad->base.x, (int) pbad->base.y + 16))
205 else if (issolid( pbad->base.x + pbad->base.width, (int) pbad->base.y + 16))
209 if(pbad->mode == KICK && changed != pbad->dir)
211 /* handle stereo sound */
212 /* FIXME: In theory a badguy object doesn't know anything about player objects */
213 if (tux.base.x > pbad->base.x)
214 play_sound(sounds[SND_RICOCHET], SOUND_LEFT_SPEAKER);
215 else if (tux.base.x < pbad->base.x)
216 play_sound(sounds[SND_RICOCHET], SOUND_RIGHT_SPEAKER);
218 play_sound(sounds[SND_RICOCHET], SOUND_CENTER_SPEAKER);
224 /* Fall if we get off the ground: */
226 if (pbad->dying != DYING_FALLING)
228 if (!issolid(pbad->base.x+16, pbad->base.y + 32))
230 if(!physic_is_set(&pbad->physic))
232 physic_set_state(&pbad->physic,PH_VT);
233 physic_set_start_vy(&pbad->physic,0.);
236 if(pbad->mode != HELD)
238 pbad->base.ym = physic_get_velocity(&pbad->physic);
245 if (pbad->base.ym > 0)
247 pbad->base.y = (int)(pbad->base.y / 32) * 32;
250 physic_init(&pbad->physic);
255 if(!physic_is_set(&pbad->physic))
257 physic_set_state(&pbad->physic,PH_VT);
258 physic_set_start_vy(&pbad->physic,0.);
260 pbad->base.ym = physic_get_velocity(&pbad->physic);
265 else if (pbad->kind == BAD_MONEY)
267 /* --- MONEY BAGS: --- */
270 /* Move vertically: */
272 pbad->base.y = pbad->base.y + pbad->base.ym * frame_ratio;
274 if (pbad->dying != DYING_FALLING)
275 collision_swept_object_map(&pbad->old_base,&pbad->base);
277 if (pbad->base.y > screen->h)
278 bad_guys.erase(static_cast<std::vector<bad_guy_type>::iterator>(pbad));
280 if(physic_get_state(&pbad->physic) == -1)
282 physic_set_state(&pbad->physic,PH_VT);
283 physic_set_start_vy(&pbad->physic,0.);
286 if (pbad->dying != DYING_FALLING)
288 if(issolid(pbad->base.x, pbad->base.y + 32))
290 physic_set_state(&pbad->physic,PH_VT);
291 physic_set_start_vy(&pbad->physic,6.);
292 pbad->base.ym = physic_get_velocity(&pbad->physic);
294 else if(issolid(pbad->base.x, pbad->base.y))
295 { /* This works, but isn't the best solution imagineable */
296 physic_set_state(&pbad->physic,PH_VT);
297 physic_set_start_vy(&pbad->physic,0.);
298 pbad->base.ym = physic_get_velocity(&pbad->physic);
303 pbad->base.ym = physic_get_velocity(&pbad->physic);
308 if(!physic_is_set(&pbad->physic))
310 physic_set_state(&pbad->physic,PH_VT);
311 physic_set_start_vy(&pbad->physic,0.);
313 pbad->base.ym = physic_get_velocity(&pbad->physic);
316 else if (pbad->kind == -1)
320 else if (pbad->kind == -1)
323 /* Handle mode timer: */
325 if (pbad->mode == FLAT && pbad->mode != HELD)
327 if(!timer_check(&pbad->timer))
333 else if (pbad->mode == KICK)
335 timer_check(&pbad->timer);
339 /* Handle dying timer: */
341 if (pbad->dying == DYING_SQUISHED)
343 /* Remove it if time's up: */
344 if(!timer_check(&pbad->timer))
345 bad_guys.erase(static_cast<std::vector<bad_guy_type>::iterator>(pbad));
349 /* Remove if it's far off the screen: */
351 if (pbad->base.x < scroll_x - OFFSCREEN_DISTANCE)
352 bad_guys.erase(static_cast<std::vector<bad_guy_type>::iterator>(pbad));
355 /* Once it's on screen, it's activated! */
357 if (pbad->base.x <= scroll_x + screen->w + OFFSCREEN_DISTANCE)
363 void badguy_draw(bad_guy_type* pbad)
365 if (pbad->base.x > scroll_x - 32 &&
366 pbad->base.x < scroll_x + screen->w)
368 if (pbad->kind == BAD_BSOD)
370 /* --- BLUE SCREEN OF DEATH MONSTER: --- */
372 if (pbad->dying == DYING_NOT)
376 if (pbad->dir == LEFT)
378 texture_draw(&img_bsod_left[(frame / 5) % 4],
379 pbad->base.x - scroll_x,
384 texture_draw(&img_bsod_right[(frame / 5) % 4],
385 pbad->base.x - scroll_x,
389 else if (pbad->dying == DYING_FALLING)
393 if (pbad->dir == LEFT)
395 texture_draw(&img_bsod_falling_left,
396 pbad->base.x - scroll_x,
401 texture_draw(&img_bsod_falling_right,
402 pbad->base.x - scroll_x,
406 else if (pbad->dying == DYING_SQUISHED)
408 /* Dying - Squished: */
410 if (pbad->dir == LEFT)
412 texture_draw(&img_bsod_squished_left,
413 pbad->base.x - scroll_x,
418 texture_draw(&img_bsod_squished_right,
419 pbad->base.x - scroll_x,
424 else if (pbad->kind == BAD_LAPTOP)
426 /* --- LAPTOP MONSTER: --- */
428 if (pbad->dying == DYING_NOT)
432 if (pbad->mode == NORMAL)
436 if (pbad->dir == LEFT)
438 texture_draw(&img_laptop_left[(frame / 5) % 3],
439 pbad->base.x - scroll_x,
444 texture_draw(&img_laptop_right[(frame / 5) % 3],
445 pbad->base.x - scroll_x,
453 if (pbad->dir == LEFT)
455 texture_draw(&img_laptop_flat_left,
456 pbad->base.x - scroll_x,
461 texture_draw(&img_laptop_flat_right,
462 pbad->base.x - scroll_x,
467 else if (pbad->dying == DYING_FALLING)
471 if (pbad->dir == LEFT)
473 texture_draw(&img_laptop_falling_left,
474 pbad->base.x - scroll_x,
479 texture_draw(&img_laptop_falling_right,
480 pbad->base.x - scroll_x,
485 else if (pbad->kind == BAD_MONEY)
487 if (pbad->base.ym != 300 /* > -16*/)
489 if (pbad->dir == LEFT)
491 texture_draw(&img_money_left[0],
492 pbad->base.x - scroll_x,
497 texture_draw(&img_money_right[0],
498 pbad->base.x - scroll_x,
504 if (pbad->dir == LEFT)
506 texture_draw(&img_money_left[1],
507 pbad->base.x - scroll_x,
512 texture_draw(&img_money_right[1],
513 pbad->base.x - scroll_x,
518 else if (pbad->kind == -1)
523 void badguy_collision(bad_guy_type* pbad, void *p_c_object, int c_object)
525 bad_guy_type* pbad_c = NULL;
526 player_type* pplayer_c = NULL;
531 pbad->dying = DYING_FALLING;
534 /* Gain some points: */
536 if (pbad->kind == BAD_BSOD)
537 add_score(pbad->base.x - scroll_x, pbad->base.y,
538 50 * score_multiplier);
539 else if (pbad->kind == BAD_LAPTOP)
540 add_score(pbad->base.x - scroll_x, pbad->base.y,
541 25 * score_multiplier);
542 else if (pbad->kind == BAD_MONEY)
543 add_score(pbad->base.x - scroll_x, pbad->base.y,
544 50 * score_multiplier);
546 /* Play death sound: */
547 play_sound(sounds[SND_FALL], SOUND_CENTER_SPEAKER);
550 pbad_c = (bad_guy_type*) p_c_object;
551 if (pbad->mode == NORMAL)
555 else if(pbad->mode == KICK)
557 /* We're in kick mode, kill the other guy
558 and yourself(wuahaha) : */
560 pbad_c->dying = DYING_FALLING;
561 pbad_c->base.ym = -8;
562 play_sound(sounds[SND_FALL], SOUND_CENTER_SPEAKER);
564 add_score(pbad->base.x - scroll_x,
566 pbad_c->dying = DYING_FALLING;
568 pbad->dying = DYING_FALLING;
571 add_score(pbad_c->base.x - scroll_x,
572 pbad_c->base.y, 100);
576 pplayer_c = (player_type*) p_c_object;
577 if(pbad->kind != BAD_MONEY)
579 if (pbad->kind == BAD_BSOD)
581 pbad->dying = DYING_SQUISHED;
582 timer_start(&pbad->timer,4000);
583 physic_set_state(&pplayer_c->vphysic,PH_VT);
584 physic_set_start_vy(&pplayer_c->vphysic,2.);
585 pplayer_c->base.y = pbad->base.y - pplayer_c->base.height - 1;
587 add_score(pbad->base.x - scroll_x, pbad->base.y,
588 50 * score_multiplier);
590 play_sound(sounds[SND_SQUISH], SOUND_CENTER_SPEAKER);
592 else if (pbad->kind == BAD_LAPTOP)
595 if (pbad->mode == NORMAL || pbad->mode == KICK)
599 play_sound(sounds[SND_STOMP], SOUND_CENTER_SPEAKER);
603 timer_start(&pbad->timer,10000);
605 physic_set_state(&pplayer_c->vphysic,PH_VT);
606 physic_set_start_vy(&pplayer_c->vphysic,2.);
607 pplayer_c->base.y = pbad->base.y - pplayer_c->base.height - 1;
609 else if (pbad->mode == FLAT)
612 play_sound(sounds[SND_KICK], SOUND_CENTER_SPEAKER);
614 if (pplayer_c->base.x < pbad->base.x + (pbad->base.width/2))
622 timer_start(&pbad->timer,5000);
625 physic_set_state(&pplayer_c->vphysic,PH_VT);
626 physic_set_start_vy(&pplayer_c->vphysic,2.);
627 pplayer_c->base.y = pbad->base.y - pplayer_c->base.height - 1;
629 add_score(pbad->base.x - scroll_x,
631 25 * score_multiplier);
633 /* play_sound(sounds[SND_SQUISH]); */