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 /* && bad_guys[1].mode != HELD*/)
319 if(!timer_check(&pbad->timer))
322 /* else if (pbad->mode == KICK)
329 /* Handle dying timer: */
331 if (pbad->dying == SQUISHED)
333 /* Remove it if time's up: */
334 if(!timer_check(&pbad->timer))
335 pbad->base.alive = NO;
339 /* Remove if it's far off the screen: */
341 if (pbad->base.x < scroll_x - OFFSCREEN_DISTANCE)
342 pbad->base.alive = NO;
345 /* Once it's on screen, it's activated! */
347 if (pbad->base.x <= scroll_x + screen->w + OFFSCREEN_DISTANCE)
353 void badguy_draw(bad_guy_type* pbad)
355 if (pbad->base.alive &&
356 pbad->base.x > scroll_x - 32 &&
357 pbad->base.x < scroll_x + screen->w)
359 if (pbad->kind == BAD_BSOD)
361 /* --- BLUE SCREEN OF DEATH MONSTER: --- */
363 if (pbad->dying == NO)
367 if (pbad->dir == LEFT)
369 texture_draw(&img_bsod_left[(frame / 5) % 4],
370 pbad->base.x - scroll_x,
376 texture_draw(&img_bsod_right[(frame / 5) % 4],
377 pbad->base.x - scroll_x,
382 else if (pbad->dying == FALLING)
386 if (pbad->dir == LEFT)
388 texture_draw(&img_bsod_falling_left,
389 pbad->base.x - scroll_x,
395 texture_draw(&img_bsod_falling_right,
396 pbad->base.x - scroll_x,
401 else if (pbad->dying == SQUISHED)
403 /* Dying - Squished: */
405 if (pbad->dir == LEFT)
407 texture_draw(&img_bsod_squished_left,
408 pbad->base.x - scroll_x,
414 texture_draw(&img_bsod_squished_right,
415 pbad->base.x - scroll_x,
421 else if (pbad->kind == BAD_LAPTOP)
423 /* --- LAPTOP MONSTER: --- */
425 if (pbad->dying == NO)
429 if (pbad->mode == NORMAL)
433 if (pbad->dir == LEFT)
435 texture_draw(&img_laptop_left[(frame / 5) % 3],
436 pbad->base.x - scroll_x,
442 texture_draw(&img_laptop_right[(frame / 5) % 3],
443 pbad->base.x - scroll_x,
452 if (pbad->dir == LEFT)
454 texture_draw(&img_laptop_flat_left,
455 pbad->base.x - scroll_x,
461 texture_draw(&img_laptop_flat_right,
462 pbad->base.x - scroll_x,
468 else if (pbad->dying == FALLING)
472 if (pbad->dir == LEFT)
474 texture_draw(&img_laptop_falling_left,
475 pbad->base.x - scroll_x,
481 texture_draw(&img_laptop_falling_right,
482 pbad->base.x - scroll_x,
488 else if (pbad->kind == BAD_MONEY)
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,
501 texture_draw(&img_money_right[0],
502 pbad->base.x - scroll_x,
509 if (pbad->dir == LEFT)
511 texture_draw(&img_money_left[1],
512 pbad->base.x - scroll_x,
518 texture_draw(&img_money_right[1],
519 pbad->base.x - scroll_x,
525 else if (pbad->kind == -1)
530 void badguy_collision(bad_guy_type* pbad, void *p_c_object, int c_object)
532 bad_guy_type* pbad_c = NULL;
533 player_type* pplayer_c = NULL;
538 pbad->dying = FALLING;
541 /* Gain some points: */
543 if (pbad->kind == BAD_BSOD)
544 add_score(pbad->base.x - scroll_x, pbad->base.y,
545 50 * score_multiplier);
546 else if (pbad->kind == BAD_LAPTOP)
547 add_score(pbad->base.x - scroll_x, pbad->base.y,
548 25 * score_multiplier);
549 else if (pbad->kind == BAD_MONEY)
550 add_score(pbad->base.x - scroll_x, pbad->base.y,
551 50 * score_multiplier);
553 /* Play death sound: */
554 play_sound(sounds[SND_FALL], SOUND_CENTER_SPEAKER);
557 pbad_c = (bad_guy_type*) p_c_object;
558 if (pbad->mode != FLAT)
559 pbad->dir = !pbad->dir;
562 /* We're in kick mode, kill the other guy: */
564 pbad_c->dying = FALLING;
565 pbad_c->base.ym = -8;
566 play_sound(sounds[SND_FALL], SOUND_CENTER_SPEAKER);
568 add_score(pbad->base.x - scroll_x,
571 pbad->dir = !pbad->dir;
574 pplayer_c = (player_type*) p_c_object;
575 if (pbad->kind == BAD_BSOD)
577 pbad->dying = SQUISHED;
578 timer_start(&pbad->timer,4000);
579 pplayer_c->base.ym = -KILL_BOUNCE_YM;
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 pplayer_c->base.y = pplayer_c->base.y - 32;
605 play_sound(sounds[SND_KICK], SOUND_CENTER_SPEAKER);
607 if (pplayer_c->base.x <= pbad->base.x)
612 timer_start(&pbad->timer,5000);
615 pplayer_c->base.ym = -KILL_BOUNCE_YM;
617 add_score(pbad->base.x - scroll_x,
619 25 * score_multiplier);
621 /* play_sound(sounds[SND_SQUISH]); */