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);
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))
87 else if (issolid( pbad->base.x + pbad->base.width-1, (int) pbad->base.y))
93 /* Fall if we get off the ground: */
95 if (pbad->dying != FALLING)
97 if (!issolid(pbad->base.x, pbad->base.y + 32) &&
98 pbad->base.ym < MAX_YM)
100 pbad->base.ym = pbad->base.ym + GRAVITY;
106 if (pbad->base.ym > 0)
108 pbad->base.y = (int)(pbad->base.y / 32) * 32;
114 pbad->base.ym = pbad->base.ym + GRAVITY;
116 if (pbad->base.y > screen->h)
117 pbad->base.alive = NO;
119 else if (pbad->kind == BAD_LAPTOP)
121 /* --- LAPTOP MONSTER: --- */
123 /* Move left/right: */
125 if (pbad->mode != KICK && pbad->mode != HELD)
127 if (pbad->dying == NO ||
128 pbad->dying == FALLING)
130 if (pbad->dir == RIGHT)
131 pbad->base.x = pbad->base.x + pbad->base.xm * frame_ratio;
132 else if (pbad->dir == LEFT)
133 pbad->base.x = pbad->base.x - pbad->base.xm * frame_ratio;
136 else if (pbad->mode == KICK)
139 if (pbad->dir == RIGHT)
140 pbad->base.x = pbad->base.x + 16;
141 else if (pbad->dir == LEFT)
142 pbad->base.x = pbad->base.x - 16;*/
144 else if (pbad->mode == HELD)
145 { /* FIXME: The pbad object shouldn't know about pplayer objects. */
146 /* If we're holding the laptop */
149 pbad->base.x = tux.base.x - 16;
150 pbad->base.y = tux.base.y - 8 - (tux.size*16);
152 else /* facing left */
154 pbad->base.x = tux.base.x - 16;
155 pbad->base.y = tux.base.y - 8 - (tux.size*16);
158 if(tux.input.fire != DOWN) /* SHOOT! */
163 play_sound(sounds[SND_KICK],SOUND_CENTER_SPEAKER);
168 /* Move vertically: */
170 if(pbad->mode != HELD)
171 pbad->base.y = pbad->base.y + pbad->base.ym * frame_ratio;
173 /* Bump into things horizontally: */
177 if (issolid(pbad->base.x, pbad->base.y))
179 pbad->dir = !pbad->dir;
181 if (pbad->mode == KICK)
183 /* handle stereo sound */
184 /* FIXME: In theory a badguy object doesn't know anything about player objects */
185 if (tux.base.x > pbad->base.x)
186 play_sound(sounds[SND_RICOCHET], SOUND_LEFT_SPEAKER);
187 else if (tux.base.x < pbad->base.x)
188 play_sound(sounds[SND_RICOCHET], SOUND_RIGHT_SPEAKER);
190 play_sound(sounds[SND_RICOCHET], SOUND_CENTER_SPEAKER);
196 /* Fall if we get off the ground: */
198 if (pbad->dying != FALLING)
200 if (!issolid(pbad->base.x, pbad->base.y + 32) &&
201 pbad->base.ym < MAX_YM)
203 if(pbad->mode != HELD)
204 pbad->base.ym = pbad->base.ym + GRAVITY;
210 if (pbad->base.ym > 0)
212 pbad->base.y = (int)(pbad->base.y / 32) * 32;
218 pbad->base.ym = pbad->base.ym + GRAVITY;
220 if (pbad->base.y > screen->h)
221 pbad->base.alive = NO;
223 else if (pbad->kind == BAD_MONEY)
225 /* --- MONEY BAGS: --- */
228 /* Move vertically: */
230 pbad->base.y = pbad->base.y + pbad->base.ym * frame_ratio;
232 if(physic_get_state(&pbad->physic) == -1)
233 physic_set_state(&pbad->physic,PH_VTU);
235 if(issolid(pbad->base.x, pbad->base.y + 32))
237 physic_set_state(&pbad->physic,PH_VTU);
238 pbad->base.ym = -0.6;
240 else if(issolid(pbad->base.x, pbad->base.y - 1))
241 { /* This works, but isn't the best solution imagineable */
242 pbad->base.ym = physic_get_velocity(&pbad->physic,-6.);
246 pbad->base.ym = physic_get_velocity(&pbad->physic,6.);
249 if (pbad->base.y > screen->h)
250 pbad->base.alive = NO;
252 else if (pbad->kind == -1)
256 else if (pbad->kind == -1)
262 /* Handle mode timer: */
264 if (pbad->mode == FLAT /* && bad_guys[1].mode != HELD*/)
266 if(!timer_check(&pbad->timer))
269 /* else if (pbad->mode == KICK)
276 /* Handle dying timer: */
278 if (pbad->dying == SQUISHED)
280 /* Remove it if time's up: */
281 if(!timer_check(&pbad->timer))
282 pbad->base.alive = NO;
286 /* Remove if it's far off the screen: */
288 if (pbad->base.x < scroll_x - OFFSCREEN_DISTANCE)
289 pbad->base.alive = NO;
292 /* Once it's on screen, it's activated! */
294 if (pbad->base.x <= scroll_x + screen->w + OFFSCREEN_DISTANCE)
300 void badguy_draw(bad_guy_type* pbad)
302 if (pbad->base.alive &&
303 pbad->base.x > scroll_x - 32 &&
304 pbad->base.x < scroll_x + screen->w)
306 if (pbad->kind == BAD_BSOD)
308 /* --- BLUE SCREEN OF DEATH MONSTER: --- */
310 if (pbad->dying == NO)
314 if (pbad->dir == LEFT)
316 texture_draw(&img_bsod_left[(frame / 5) % 4],
317 pbad->base.x - scroll_x,
323 texture_draw(&img_bsod_right[(frame / 5) % 4],
324 pbad->base.x - scroll_x,
329 else if (pbad->dying == FALLING)
333 if (pbad->dir == LEFT)
335 texture_draw(&img_bsod_falling_left,
336 pbad->base.x - scroll_x,
342 texture_draw(&img_bsod_falling_right,
343 pbad->base.x - scroll_x,
348 else if (pbad->dying == SQUISHED)
350 /* Dying - Squished: */
352 if (pbad->dir == LEFT)
354 texture_draw(&img_bsod_squished_left,
355 pbad->base.x - scroll_x,
361 texture_draw(&img_bsod_squished_right,
362 pbad->base.x - scroll_x,
368 else if (pbad->kind == BAD_LAPTOP)
370 /* --- LAPTOP MONSTER: --- */
372 if (pbad->dying == NO)
376 if (pbad->mode == NORMAL)
380 if (pbad->dir == LEFT)
382 texture_draw(&img_laptop_left[(frame / 5) % 3],
383 pbad->base.x - scroll_x,
389 texture_draw(&img_laptop_right[(frame / 5) % 3],
390 pbad->base.x - scroll_x,
399 if (pbad->dir == LEFT)
401 texture_draw(&img_laptop_flat_left,
402 pbad->base.x - scroll_x,
408 texture_draw(&img_laptop_flat_right,
409 pbad->base.x - scroll_x,
415 else if (pbad->dying == FALLING)
419 if (pbad->dir == LEFT)
421 texture_draw(&img_laptop_falling_left,
422 pbad->base.x - scroll_x,
428 texture_draw(&img_laptop_falling_right,
429 pbad->base.x - scroll_x,
435 else if (pbad->kind == BAD_MONEY)
437 if (pbad->base.ym != 300 /* > -16*/)
439 if (pbad->dir == LEFT)
441 texture_draw(&img_money_left[0],
442 pbad->base.x - scroll_x,
448 texture_draw(&img_money_right[0],
449 pbad->base.x - scroll_x,
456 if (pbad->dir == LEFT)
458 texture_draw(&img_money_left[1],
459 pbad->base.x - scroll_x,
465 texture_draw(&img_money_right[1],
466 pbad->base.x - scroll_x,
472 else if (pbad->kind == -1)
477 void badguy_collision(bad_guy_type* pbad, void *p_c_object, int c_object)
479 bad_guy_type* pbad_c = NULL;
480 player_type* pplayer_c = NULL;
485 pbad->dying = FALLING;
488 /* Gain some points: */
490 if (pbad->kind == BAD_BSOD)
491 add_score(pbad->base.x - scroll_x, pbad->base.y,
492 50 * score_multiplier);
493 else if (pbad->kind == BAD_LAPTOP)
494 add_score(pbad->base.x - scroll_x, pbad->base.y,
495 25 * score_multiplier);
497 /* Play death sound: */
498 play_sound(sounds[SND_FALL], SOUND_CENTER_SPEAKER);
501 pbad_c = (bad_guy_type*) p_c_object;
502 if (pbad->mode != FLAT)
503 pbad->dir = !pbad->dir;
506 /* We're in kick mode, kill the other guy: */
508 pbad_c->dying = FALLING;
509 pbad_c->base.ym = -8;
510 play_sound(sounds[SND_FALL], SOUND_CENTER_SPEAKER);
512 add_score(pbad->base.x - scroll_x,
515 pbad->dir = !pbad->dir;
518 pplayer_c = (player_type*) p_c_object;
519 if (pbad->kind == BAD_BSOD)
521 pbad->dying = SQUISHED;
522 timer_start(&pbad->timer,4000);
523 pplayer_c->base.ym = -KILL_BOUNCE_YM;
525 add_score(pbad->base.x - scroll_x, pbad->base.y,
526 50 * score_multiplier);
528 play_sound(sounds[SND_SQUISH], SOUND_CENTER_SPEAKER);
530 else if (pbad->kind == BAD_LAPTOP)
532 if (pbad->mode != KICK)
536 play_sound(sounds[SND_STOMP], SOUND_CENTER_SPEAKER);
540 timer_start(&pbad->timer,10000);
542 pplayer_c->base.y = pplayer_c->base.y - 32;
549 play_sound(sounds[SND_KICK], SOUND_CENTER_SPEAKER);
551 if (pplayer_c->base.x <= pbad->base.x)
556 timer_start(&pbad->timer,5000);
559 pplayer_c->base.ym = -KILL_BOUNCE_YM;
561 add_score(pbad->base.x - scroll_x,
563 25 * score_multiplier);
565 /* play_sound(sounds[SND_SQUISH]); */