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;
20 texture_type img_bsod_squished_right;
21 texture_type img_bsod_falling_left;
22 texture_type img_bsod_falling_right;
23 texture_type img_laptop_flat_left;
24 texture_type img_laptop_flat_right;
25 texture_type img_laptop_falling_left;
26 texture_type img_laptop_falling_right;
27 texture_type img_bsod_left[4];
28 texture_type img_bsod_right[4];
29 texture_type img_laptop_left[3];
30 texture_type img_laptop_right[3];
31 texture_type img_money_left[2];
32 texture_type img_money_right[2];
34 BadGuyKind badguykind_from_string(const std::string& str)
38 else if (str == "laptop")
40 else if (str == "bsod")
44 printf("Couldn't convert badguy: %s\n", str.c_str());
49 std::string badguykind_to_string(BadGuyKind kind)
68 BadGuy::init(float x, float y, BadGuyKind kind_)
82 timer_init(&timer, true);
86 void BadGuy::action_bsod()
88 /* --- BLUE SCREEN OF DEATH MONSTER: --- */
90 /* Move left/right: */
91 if (dying == DYING_NOT ||
92 dying == DYING_FALLING)
95 base.x = base.x + base.xm * frame_ratio;
97 base.x = base.x - base.xm * frame_ratio;
100 /* Move vertically: */
101 base.y = base.y + base.ym * frame_ratio;
103 if (dying != DYING_FALLING)
104 collision_swept_object_map(&old_base,&base);
105 if (base.y > screen->h)
106 bad_guys.erase(static_cast<std::vector<BadGuy>::iterator>(this));
108 /* Bump into things horizontally: */
112 if (issolid( base.x, (int) base.y + 16))
116 else if (issolid( base.x + base.width, (int) base.y + 16))
122 /* Fall if we get off the ground: */
123 if (dying != DYING_FALLING)
125 if (!issolid(base.x+16, base.y + 32))
127 if(!physic_is_set(&physic))
129 physic_set_state(&physic,PH_VT);
130 physic_set_start_vy(&physic,2.);
133 base.ym = physic_get_velocity(&physic);
141 base.y = (int)(base.y / 32) * 32;
144 physic_init(&physic);
149 if(!physic_is_set(&physic))
151 physic_set_state(&physic,PH_VT);
152 physic_set_start_vy(&physic,2.);
154 base.ym = physic_get_velocity(&physic);
157 // BadGuy fall below the ground
158 if (base.y > screen->h)
159 bad_guys.erase(static_cast<std::vector<BadGuy>::iterator>(this));
162 void BadGuy::action_laptop()
164 /* Move left/right: */
165 if (mode == NORMAL || mode == KICK)
167 if (dying == DYING_NOT ||
168 dying == DYING_FALLING)
171 base.x = base.x + base.xm * frame_ratio;
172 else if (dir == LEFT)
173 base.x = base.x - base.xm * frame_ratio;
176 else if (mode == HELD)
177 { /* FIXME: The pbad object shouldn't know about pplayer objects. */
178 /* If we're holding the laptop */
182 base.x = tux.base.x + 16;
183 base.y = tux.base.y + tux.base.height/1.5 - base.height;
185 else /* facing left */
187 base.x = tux.base.x - 16;
188 base.y = tux.base.y + tux.base.height/1.5 - base.height;
190 if(collision_object_map(&base))
193 base.y = tux.base.y + tux.base.height/1.5 - base.height;
196 if(tux.input.fire != DOWN) /* SHOOT! */
206 play_sound(sounds[SND_KICK],SOUND_CENTER_SPEAKER);
211 /* Move vertically: */
213 base.y = base.y + base.ym * frame_ratio;
215 if (dying != DYING_FALLING)
216 collision_swept_object_map(&old_base,&base);
217 if (base.y > screen->h)
218 bad_guys.erase(static_cast<std::vector<BadGuy>::iterator>(this));
219 /* Bump into things horizontally: */
221 /* Bump into things horizontally: */
226 if (issolid( base.x, (int) base.y + 16))
230 else if (issolid( base.x + base.width, (int) base.y + 16))
234 if(mode == KICK && changed != dir)
236 /* handle stereo sound */
237 /* FIXME: In theory a badguy object doesn't know anything about player objects */
238 if (tux.base.x > base.x)
239 play_sound(sounds[SND_RICOCHET], SOUND_LEFT_SPEAKER);
240 else if (tux.base.x < base.x)
241 play_sound(sounds[SND_RICOCHET], SOUND_RIGHT_SPEAKER);
243 play_sound(sounds[SND_RICOCHET], SOUND_CENTER_SPEAKER);
248 /* Fall if we get off the ground: */
249 if (dying != DYING_FALLING)
251 if (!issolid(base.x+16, base.y + 32))
253 if(!physic_is_set(&physic))
255 physic_set_state(&physic,PH_VT);
256 physic_set_start_vy(&physic,0.);
261 base.ym = physic_get_velocity(&physic);
270 base.y = (int)(base.y / 32) * 32;
273 physic_init(&physic);
278 if(!physic_is_set(&physic))
280 physic_set_state(&physic,PH_VT);
281 physic_set_start_vy(&physic,0.);
283 base.ym = physic_get_velocity(&physic);
287 void BadGuy::action_money()
289 /* Move vertically: */
290 base.y = base.y + base.ym * frame_ratio;
292 if (dying != DYING_FALLING)
293 collision_swept_object_map(&old_base,&base);
295 if (base.y > screen->h)
296 bad_guys.erase(static_cast<std::vector<BadGuy>::iterator>(this));
298 if(physic_get_state(&physic) == -1)
300 physic_set_state(&physic,PH_VT);
301 physic_set_start_vy(&physic,0.);
304 if (dying != DYING_FALLING)
306 if(issolid(base.x, base.y + 32))
308 physic_set_state(&physic,PH_VT);
309 physic_set_start_vy(&physic,6.);
310 base.ym = physic_get_velocity(&physic);
312 else if(issolid(base.x, base.y))
313 { /* This works, but isn't the best solution imagineable */
314 physic_set_state(&physic,PH_VT);
315 physic_set_start_vy(&physic,0.);
316 base.ym = physic_get_velocity(&physic);
321 base.ym = physic_get_velocity(&physic);
326 if(!physic_is_set(&physic))
328 physic_set_state(&physic,PH_VT);
329 physic_set_start_vy(&physic,0.);
331 base.ym = physic_get_velocity(&physic);
356 /* Handle mode timer: */
357 if (mode == FLAT && mode != HELD)
359 if(!timer_check(&timer))
365 else if (mode == KICK)
370 // Handle dying timer:
371 if (dying == DYING_SQUISHED)
373 /* Remove it if time's up: */
374 if(!timer_check(&timer))
375 bad_guys.erase(static_cast<std::vector<BadGuy>::iterator>(this));
378 // Remove if it's far off the screen:
379 if (base.x < scroll_x - OFFSCREEN_DISTANCE)
381 bad_guys.erase(static_cast<std::vector<BadGuy>::iterator>(this));
386 // Once it's on screen, it's activated!
387 if (base.x <= scroll_x + screen->w + OFFSCREEN_DISTANCE)
395 /* --- BLUE SCREEN OF DEATH MONSTER: --- */
396 if (dying == DYING_NOT)
401 texture_draw(&img_bsod_left[(global_frame_counter / 5) % 4],
407 texture_draw(&img_bsod_right[(global_frame_counter / 5) % 4],
412 else if (dying == DYING_FALLING)
418 texture_draw(&img_bsod_falling_left,
424 texture_draw(&img_bsod_falling_right,
429 else if (dying == DYING_SQUISHED)
431 /* Dying - Squished: */
435 texture_draw(&img_bsod_squished_left,
441 texture_draw(&img_bsod_squished_right,
448 void BadGuy::draw_laptop()
450 /* --- LAPTOP MONSTER: --- */
451 if (dying == DYING_NOT)
460 texture_draw(&img_laptop_left[(global_frame_counter / 5) % 3],
466 texture_draw(&img_laptop_right[(global_frame_counter / 5) % 3],
477 texture_draw(&img_laptop_flat_left,
483 texture_draw(&img_laptop_flat_right,
489 else if (dying == DYING_FALLING)
495 texture_draw(&img_laptop_falling_left,
501 texture_draw(&img_laptop_falling_right,
508 void BadGuy::draw_money()
510 if (base.ym != 300 /* > -16*/)
514 texture_draw(&img_money_left[0],
520 texture_draw(&img_money_right[0],
529 texture_draw(&img_money_left[1],
535 texture_draw(&img_money_right[1],
544 // Don't try to draw stuff that is outside of the screen
545 if (base.x > scroll_x - 32 &&
546 base.x < scroll_x + screen->w)
563 puts("Unknown badguy type");
570 BadGuy::collision(void *p_c_object, int c_object)
572 BadGuy* pbad_c = NULL;
573 Player* pplayer_c = NULL;
578 dying = DYING_FALLING;
581 /* Gain some points: */
582 if (kind == BAD_BSOD)
583 add_score(base.x - scroll_x, base.y,
584 50 * score_multiplier);
585 else if (kind == BAD_LAPTOP)
586 add_score(base.x - scroll_x, base.y,
587 25 * score_multiplier);
588 else if (kind == BAD_MONEY)
589 add_score(base.x - scroll_x, base.y,
590 50 * score_multiplier);
592 /* Play death sound: */
593 play_sound(sounds[SND_FALL], SOUND_CENTER_SPEAKER);
597 pbad_c = (BadGuy*) p_c_object;
602 else if(mode == KICK)
604 /* We're in kick mode, kill the other guy
605 and yourself(wuahaha) : */
607 pbad_c->dying = DYING_FALLING;
608 pbad_c->base.ym = -8;
609 play_sound(sounds[SND_FALL], SOUND_CENTER_SPEAKER);
611 add_score(base.x - scroll_x,
613 pbad_c->dying = DYING_FALLING;
615 dying = DYING_FALLING;
618 add_score(pbad_c->base.x - scroll_x,
619 pbad_c->base.y, 100);
624 pplayer_c = static_cast<Player*>(p_c_object);
625 if(kind != BAD_MONEY)
627 if (kind == BAD_BSOD)
629 dying = DYING_SQUISHED;
630 timer_start(&timer,4000);
631 physic_set_state(&pplayer_c->vphysic,PH_VT);
632 physic_set_start_vy(&pplayer_c->vphysic,2.);
633 pplayer_c->base.y = base.y - pplayer_c->base.height - 1;
635 add_score(base.x - scroll_x, base.y,
636 50 * score_multiplier);
638 play_sound(sounds[SND_SQUISH], SOUND_CENTER_SPEAKER);
640 else if (kind == BAD_LAPTOP)
643 if (mode == NORMAL || mode == KICK)
647 play_sound(sounds[SND_STOMP], SOUND_CENTER_SPEAKER);
651 timer_start(&timer,10000);
653 physic_set_state(&pplayer_c->vphysic,PH_VT);
654 physic_set_start_vy(&pplayer_c->vphysic,2.);
655 pplayer_c->base.y = base.y - pplayer_c->base.height - 1;
657 else if (mode == FLAT)
660 play_sound(sounds[SND_KICK], SOUND_CENTER_SPEAKER);
662 if (pplayer_c->base.x < base.x + (base.width/2))
670 timer_start(&timer,5000);
673 physic_set_state(&pplayer_c->vphysic,PH_VT);
674 physic_set_start_vy(&pplayer_c->vphysic,2.);
675 pplayer_c->base.y = base.y - pplayer_c->base.height - 1;
677 add_score(base.x - scroll_x,
679 25 * score_multiplier);
681 /* play_sound(sounds[SND_SQUISH]); */