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;
47 timer_init(&pbad->timer,YES);
48 physic_init(&pbad->physic);
51 void badguy_action(bad_guy_type* pbad)
58 if (pbad->kind == BAD_BSOD)
60 /* --- BLUE SCREEN OF DEATH MONSTER: --- */
62 /* Move left/right: */
64 if (pbad->dying == NO ||
65 pbad->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;
79 /* Bump into things horizontally: */
83 if (issolid( pbad->base.x - 1, (int) pbad->base.y + 16))
87 else if (issolid( pbad->base.x + pbad->base.width-1, (int) pbad->base.y + 16))
93 /* Fall if we get off the ground: */
95 if (pbad->dying != FALLING)
97 if (!issolid(pbad->base.x+16, pbad->base.y + 32))
99 if(!physic_is_set(&pbad->physic))
101 physic_set_state(&pbad->physic,PH_VT);
102 physic_set_start_vy(&pbad->physic,2.);
105 pbad->base.ym = physic_get_velocity(&pbad->physic);
111 if (pbad->base.ym > 0)
113 pbad->base.y = (int)(pbad->base.y / 32) * 32;
116 physic_init(&pbad->physic);
121 if(!physic_is_set(&pbad->physic))
123 physic_set_state(&pbad->physic,PH_VT);
124 physic_set_start_vy(&pbad->physic,2.);
126 pbad->base.ym = physic_get_velocity(&pbad->physic);
129 if (pbad->base.y > screen->h)
130 pbad->base.alive = NO;
132 else if (pbad->kind == BAD_LAPTOP)
134 /* --- LAPTOP MONSTER: --- */
136 /* Move left/right: */
138 if (pbad->mode != KICK && pbad->mode != HELD)
140 if (pbad->dying == NO ||
141 pbad->dying == FALLING)
143 if (pbad->dir == RIGHT)
144 pbad->base.x = pbad->base.x + pbad->base.xm * frame_ratio;
145 else if (pbad->dir == LEFT)
146 pbad->base.x = pbad->base.x - pbad->base.xm * frame_ratio;
149 else if (pbad->mode == KICK)
152 if (pbad->dir == RIGHT)
153 pbad->base.x = pbad->base.x + 16;
154 else if (pbad->dir == LEFT)
155 pbad->base.x = pbad->base.x - 16;*/
157 else if (pbad->mode == HELD)
158 { /* FIXME: The pbad object shouldn't know about pplayer objects. */
159 /* If we're holding the laptop */
162 pbad->base.x = tux.base.x - 16;
163 pbad->base.y = tux.base.y - 8 - (tux.size*16);
165 else /* facing left */
167 pbad->base.x = tux.base.x - 16;
168 pbad->base.y = tux.base.y - 8 - (tux.size*16);
171 if(tux.input.fire != DOWN) /* SHOOT! */
176 play_sound(sounds[SND_KICK],SOUND_CENTER_SPEAKER);
181 /* Move vertically: */
183 if(pbad->mode != HELD)
184 pbad->base.y = pbad->base.y + pbad->base.ym * frame_ratio;
186 /* Bump into things horizontally: */
188 /* Bump into things horizontally: */
192 int changed = pbad->dir;
193 if (issolid( pbad->base.x - 1, (int) pbad->base.y + 16))
197 else if (issolid( pbad->base.x + pbad->base.width-1, (int) pbad->base.y + 16))
201 if(pbad->mode == KICK && changed != pbad->dir)
203 /* handle stereo sound */
204 /* FIXME: In theory a badguy object doesn't know anything about player objects */
205 if (tux.base.x > pbad->base.x)
206 play_sound(sounds[SND_RICOCHET], SOUND_LEFT_SPEAKER);
207 else if (tux.base.x < pbad->base.x)
208 play_sound(sounds[SND_RICOCHET], SOUND_RIGHT_SPEAKER);
210 play_sound(sounds[SND_RICOCHET], SOUND_CENTER_SPEAKER);
216 /* Fall if we get off the ground: */
218 if (pbad->dying != FALLING)
220 if (!issolid(pbad->base.x+16, pbad->base.y + 32))
222 if(!physic_is_set(&pbad->physic))
224 physic_set_state(&pbad->physic,PH_VT);
225 physic_set_start_vy(&pbad->physic,0.);
228 if(pbad->mode != HELD)
230 pbad->base.ym = physic_get_velocity(&pbad->physic);
237 if (pbad->base.ym > 0)
239 pbad->base.y = (int)(pbad->base.y / 32) * 32;
242 physic_init(&pbad->physic);
247 if(!physic_is_set(&pbad->physic))
249 physic_set_state(&pbad->physic,PH_VT);
250 physic_set_start_vy(&pbad->physic,0.);
252 pbad->base.ym = physic_get_velocity(&pbad->physic);
255 if (pbad->base.y > screen->h)
256 pbad->base.alive = NO;
258 else if (pbad->kind == BAD_MONEY)
260 /* --- MONEY BAGS: --- */
263 /* Move vertically: */
265 pbad->base.y = pbad->base.y + pbad->base.ym * frame_ratio;
267 if(physic_get_state(&pbad->physic) == -1)
269 physic_set_state(&pbad->physic,PH_VT);
270 physic_set_start_vy(&pbad->physic,0.);
273 if (pbad->dying != FALLING)
275 if(issolid(pbad->base.x, pbad->base.y + 32))
277 physic_set_state(&pbad->physic,PH_VT);
278 physic_set_start_vy(&pbad->physic,6.);
279 pbad->base.ym = physic_get_velocity(&pbad->physic);
281 else if(issolid(pbad->base.x, pbad->base.y - 1))
282 { /* This works, but isn't the best solution imagineable */
283 physic_set_state(&pbad->physic,PH_VT);
284 physic_set_start_vy(&pbad->physic,0.);
285 pbad->base.ym = physic_get_velocity(&pbad->physic);
289 pbad->base.ym = physic_get_velocity(&pbad->physic);
294 if(!physic_is_set(&pbad->physic))
296 physic_set_state(&pbad->physic,PH_VT);
297 physic_set_start_vy(&pbad->physic,0.);
299 pbad->base.ym = physic_get_velocity(&pbad->physic);
302 if (pbad->base.y > screen->h)
303 pbad->base.alive = NO;
305 else if (pbad->kind == -1)
309 else if (pbad->kind == -1)
315 /* Handle mode timer: */
317 if (pbad->mode == FLAT && pbad->mode != HELD)
319 if(!timer_check(&pbad->timer))
322 else if (pbad->mode == KICK)
324 timer_check(&pbad->timer);
328 /* Handle dying timer: */
330 if (pbad->dying == SQUISHED)
332 /* Remove it if time's up: */
333 if(!timer_check(&pbad->timer))
334 pbad->base.alive = NO;
338 /* Remove if it's far off the screen: */
340 if (pbad->base.x < scroll_x - OFFSCREEN_DISTANCE)
341 pbad->base.alive = NO;
344 /* Once it's on screen, it's activated! */
346 if (pbad->base.x <= scroll_x + screen->w + OFFSCREEN_DISTANCE)
352 void badguy_draw(bad_guy_type* pbad)
354 if (pbad->base.alive &&
355 pbad->base.x > scroll_x - 32 &&
356 pbad->base.x < scroll_x + screen->w)
358 if (pbad->kind == BAD_BSOD)
360 /* --- BLUE SCREEN OF DEATH MONSTER: --- */
362 if (pbad->dying == NO)
366 if (pbad->dir == LEFT)
368 texture_draw(&img_bsod_left[(frame / 5) % 4],
369 pbad->base.x - scroll_x,
375 texture_draw(&img_bsod_right[(frame / 5) % 4],
376 pbad->base.x - scroll_x,
381 else if (pbad->dying == FALLING)
385 if (pbad->dir == LEFT)
387 texture_draw(&img_bsod_falling_left,
388 pbad->base.x - scroll_x,
394 texture_draw(&img_bsod_falling_right,
395 pbad->base.x - scroll_x,
400 else if (pbad->dying == SQUISHED)
402 /* Dying - Squished: */
404 if (pbad->dir == LEFT)
406 texture_draw(&img_bsod_squished_left,
407 pbad->base.x - scroll_x,
413 texture_draw(&img_bsod_squished_right,
414 pbad->base.x - scroll_x,
420 else if (pbad->kind == BAD_LAPTOP)
422 /* --- LAPTOP MONSTER: --- */
424 if (pbad->dying == NO)
428 if (pbad->mode == NORMAL)
432 if (pbad->dir == LEFT)
434 texture_draw(&img_laptop_left[(frame / 5) % 3],
435 pbad->base.x - scroll_x,
441 texture_draw(&img_laptop_right[(frame / 5) % 3],
442 pbad->base.x - scroll_x,
451 if (pbad->dir == LEFT)
453 texture_draw(&img_laptop_flat_left,
454 pbad->base.x - scroll_x,
460 texture_draw(&img_laptop_flat_right,
461 pbad->base.x - scroll_x,
467 else if (pbad->dying == FALLING)
471 if (pbad->dir == LEFT)
473 texture_draw(&img_laptop_falling_left,
474 pbad->base.x - scroll_x,
480 texture_draw(&img_laptop_falling_right,
481 pbad->base.x - scroll_x,
487 else if (pbad->kind == BAD_MONEY)
489 if (pbad->base.ym != 300 /* > -16*/)
491 if (pbad->dir == LEFT)
493 texture_draw(&img_money_left[0],
494 pbad->base.x - scroll_x,
500 texture_draw(&img_money_right[0],
501 pbad->base.x - scroll_x,
508 if (pbad->dir == LEFT)
510 texture_draw(&img_money_left[1],
511 pbad->base.x - scroll_x,
517 texture_draw(&img_money_right[1],
518 pbad->base.x - scroll_x,
524 else if (pbad->kind == -1)
529 void badguy_collision(bad_guy_type* pbad, void *p_c_object, int c_object)
531 bad_guy_type* pbad_c = NULL;
532 player_type* pplayer_c = NULL;
537 pbad->dying = FALLING;
540 /* Gain some points: */
542 if (pbad->kind == BAD_BSOD)
543 add_score(pbad->base.x - scroll_x, pbad->base.y,
544 50 * score_multiplier);
545 else if (pbad->kind == BAD_LAPTOP)
546 add_score(pbad->base.x - scroll_x, pbad->base.y,
547 25 * score_multiplier);
548 else if (pbad->kind == BAD_MONEY)
549 add_score(pbad->base.x - scroll_x, pbad->base.y,
550 50 * score_multiplier);
552 /* Play death sound: */
553 play_sound(sounds[SND_FALL], SOUND_CENTER_SPEAKER);
556 pbad_c = (bad_guy_type*) p_c_object;
557 if (pbad->mode != FLAT)
558 pbad->dir = !pbad->dir;
561 /* We're in kick mode, kill the other guy: */
563 pbad_c->dying = FALLING;
564 pbad_c->base.ym = -8;
565 play_sound(sounds[SND_FALL], SOUND_CENTER_SPEAKER);
567 add_score(pbad->base.x - scroll_x,
570 pbad->dir = !pbad->dir;
573 pplayer_c = (player_type*) p_c_object;
574 if (pbad->kind == BAD_BSOD)
576 pbad->dying = SQUISHED;
577 timer_start(&pbad->timer,4000);
578 physic_set_state(&pplayer_c->vphysic,PH_VT);
579 physic_set_start_vy(&pplayer_c->vphysic,2.);
581 add_score(pbad->base.x - scroll_x, pbad->base.y,
582 50 * score_multiplier);
584 play_sound(sounds[SND_SQUISH], SOUND_CENTER_SPEAKER);
586 else if (pbad->kind == BAD_LAPTOP)
588 if (pbad->mode != KICK)
592 play_sound(sounds[SND_STOMP], SOUND_CENTER_SPEAKER);
596 timer_start(&pbad->timer,10000);
598 physic_set_state(&pplayer_c->vphysic,PH_VT);
599 physic_set_start_vy(&pplayer_c->vphysic,2.);
606 play_sound(sounds[SND_KICK], SOUND_CENTER_SPEAKER);
608 if (pplayer_c->base.x <= pbad->base.x)
615 timer_start(&pbad->timer,5000);
618 physic_set_state(&pplayer_c->vphysic,PH_VT);
619 physic_set_start_vy(&pplayer_c->vphysic,2.);
621 add_score(pbad->base.x - scroll_x,
623 25 * score_multiplier);
625 /* play_sound(sounds[SND_SQUISH]); */