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))
336 else if (pbad->mode == KICK)
338 timer_check(&pbad->timer);
342 /* Handle dying timer: */
344 if (pbad->dying == SQUISHED)
346 /* Remove it if time's up: */
347 if(!timer_check(&pbad->timer))
348 pbad->base.alive = NO;
352 /* Remove if it's far off the screen: */
354 if (pbad->base.x < scroll_x - OFFSCREEN_DISTANCE)
355 pbad->base.alive = NO;
358 /* Once it's on screen, it's activated! */
360 if (pbad->base.x <= scroll_x + screen->w + OFFSCREEN_DISTANCE)
366 void badguy_draw(bad_guy_type* pbad)
368 if (pbad->base.alive &&
369 pbad->base.x > scroll_x - 32 &&
370 pbad->base.x < scroll_x + screen->w)
372 if (pbad->kind == BAD_BSOD)
374 /* --- BLUE SCREEN OF DEATH MONSTER: --- */
376 if (pbad->dying == NO)
380 if (pbad->dir == LEFT)
382 texture_draw(&img_bsod_left[(frame / 5) % 4],
383 pbad->base.x - scroll_x,
389 texture_draw(&img_bsod_right[(frame / 5) % 4],
390 pbad->base.x - scroll_x,
395 else if (pbad->dying == FALLING)
399 if (pbad->dir == LEFT)
401 texture_draw(&img_bsod_falling_left,
402 pbad->base.x - scroll_x,
408 texture_draw(&img_bsod_falling_right,
409 pbad->base.x - scroll_x,
414 else if (pbad->dying == SQUISHED)
416 /* Dying - Squished: */
418 if (pbad->dir == LEFT)
420 texture_draw(&img_bsod_squished_left,
421 pbad->base.x - scroll_x,
427 texture_draw(&img_bsod_squished_right,
428 pbad->base.x - scroll_x,
434 else if (pbad->kind == BAD_LAPTOP)
436 /* --- LAPTOP MONSTER: --- */
438 if (pbad->dying == NO)
442 if (pbad->mode == NORMAL)
446 if (pbad->dir == LEFT)
448 texture_draw(&img_laptop_left[(frame / 5) % 3],
449 pbad->base.x - scroll_x,
455 texture_draw(&img_laptop_right[(frame / 5) % 3],
456 pbad->base.x - scroll_x,
465 if (pbad->dir == LEFT)
467 texture_draw(&img_laptop_flat_left,
468 pbad->base.x - scroll_x,
474 texture_draw(&img_laptop_flat_right,
475 pbad->base.x - scroll_x,
481 else if (pbad->dying == FALLING)
485 if (pbad->dir == LEFT)
487 texture_draw(&img_laptop_falling_left,
488 pbad->base.x - scroll_x,
494 texture_draw(&img_laptop_falling_right,
495 pbad->base.x - scroll_x,
501 else if (pbad->kind == BAD_MONEY)
503 if (pbad->base.ym != 300 /* > -16*/)
505 if (pbad->dir == LEFT)
507 texture_draw(&img_money_left[0],
508 pbad->base.x - scroll_x,
514 texture_draw(&img_money_right[0],
515 pbad->base.x - scroll_x,
522 if (pbad->dir == LEFT)
524 texture_draw(&img_money_left[1],
525 pbad->base.x - scroll_x,
531 texture_draw(&img_money_right[1],
532 pbad->base.x - scroll_x,
538 else if (pbad->kind == -1)
543 void badguy_collision(bad_guy_type* pbad, void *p_c_object, int c_object)
545 bad_guy_type* pbad_c = NULL;
546 player_type* pplayer_c = NULL;
551 pbad->dying = FALLING;
554 /* Gain some points: */
556 if (pbad->kind == BAD_BSOD)
557 add_score(pbad->base.x - scroll_x, pbad->base.y,
558 50 * score_multiplier);
559 else if (pbad->kind == BAD_LAPTOP)
560 add_score(pbad->base.x - scroll_x, pbad->base.y,
561 25 * score_multiplier);
562 else if (pbad->kind == BAD_MONEY)
563 add_score(pbad->base.x - scroll_x, pbad->base.y,
564 50 * score_multiplier);
566 /* Play death sound: */
567 play_sound(sounds[SND_FALL], SOUND_CENTER_SPEAKER);
570 pbad_c = (bad_guy_type*) p_c_object;
571 if (pbad->mode == NORMAL)
572 pbad->dir = !pbad->dir;
575 /* We're in kick mode, kill the other guy: */
577 pbad_c->dying = FALLING;
578 pbad_c->base.ym = -8;
579 play_sound(sounds[SND_FALL], SOUND_CENTER_SPEAKER);
581 add_score(pbad->base.x - scroll_x,
586 pplayer_c = (player_type*) p_c_object;
587 if(pbad->kind != BAD_MONEY)
589 if (pbad->kind == BAD_BSOD)
591 pbad->dying = SQUISHED;
592 timer_start(&pbad->timer,4000);
593 physic_set_state(&pplayer_c->vphysic,PH_VT);
594 physic_set_start_vy(&pplayer_c->vphysic,2.);
596 add_score(pbad->base.x - scroll_x, pbad->base.y,
597 50 * score_multiplier);
599 play_sound(sounds[SND_SQUISH], SOUND_CENTER_SPEAKER);
601 else if (pbad->kind == BAD_LAPTOP)
604 if (pbad->mode == NORMAL || pbad->mode == KICK)
608 play_sound(sounds[SND_STOMP], SOUND_CENTER_SPEAKER);
612 timer_start(&pbad->timer,10000);
614 physic_set_state(&pplayer_c->vphysic,PH_VT);
615 physic_set_start_vy(&pplayer_c->vphysic,2.);
617 else if (pbad->mode == FLAT)
621 play_sound(sounds[SND_KICK], SOUND_CENTER_SPEAKER);
623 if (pplayer_c->base.x <= pbad->base.x)
630 timer_start(&pbad->timer,5000);
633 physic_set_state(&pplayer_c->vphysic,PH_VT);
634 physic_set_start_vy(&pplayer_c->vphysic,2.);
636 add_score(pbad->base.x - scroll_x,
638 25 * score_multiplier);
640 /* play_sound(sounds[SND_SQUISH]); */