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];
35 BadGuy::init(float x, float y, BadGuyKind kind_)
49 timer_init(&timer, true);
53 void BadGuy::action_bsod()
55 /* --- BLUE SCREEN OF DEATH MONSTER: --- */
57 /* Move left/right: */
58 if (dying == DYING_NOT ||
59 dying == DYING_FALLING)
62 base.x = base.x + base.xm * frame_ratio;
64 base.x = base.x - base.xm * frame_ratio;
67 /* Move vertically: */
68 base.y = base.y + base.ym * frame_ratio;
70 if (dying != DYING_FALLING)
71 collision_swept_object_map(&old_base,&base);
72 if (base.y > screen->h)
73 bad_guys.erase(static_cast<std::vector<BadGuy>::iterator>(this));
75 /* Bump into things horizontally: */
79 if (issolid( base.x, (int) base.y + 16))
83 else if (issolid( base.x + base.width, (int) base.y + 16))
89 /* Fall if we get off the ground: */
90 if (dying != DYING_FALLING)
92 if (!issolid(base.x+16, base.y + 32))
94 if(!physic_is_set(&physic))
96 physic_set_state(&physic,PH_VT);
97 physic_set_start_vy(&physic,2.);
100 base.ym = physic_get_velocity(&physic);
108 base.y = (int)(base.y / 32) * 32;
111 physic_init(&physic);
116 if(!physic_is_set(&physic))
118 physic_set_state(&physic,PH_VT);
119 physic_set_start_vy(&physic,2.);
121 base.ym = physic_get_velocity(&physic);
124 // BadGuy fall below the ground
125 if (base.y > screen->h)
126 bad_guys.erase(static_cast<std::vector<BadGuy>::iterator>(this));
129 void BadGuy::action_laptop()
131 /* Move left/right: */
132 if (mode == NORMAL || mode == KICK)
134 if (dying == DYING_NOT ||
135 dying == DYING_FALLING)
138 base.x = base.x + base.xm * frame_ratio;
139 else if (dir == LEFT)
140 base.x = base.x - base.xm * frame_ratio;
143 else if (mode == HELD)
144 { /* FIXME: The pbad object shouldn't know about pplayer objects. */
145 /* If we're holding the laptop */
149 base.x = tux.base.x + 16;
150 base.y = tux.base.y + tux.base.height/1.5 - base.height;
152 else /* facing left */
154 base.x = tux.base.x - 16;
155 base.y = tux.base.y + tux.base.height/1.5 - base.height;
157 if(collision_object_map(&base))
160 base.y = tux.base.y + tux.base.height/1.5 - base.height;
163 if(tux.input.fire != DOWN) /* SHOOT! */
173 play_sound(sounds[SND_KICK],SOUND_CENTER_SPEAKER);
178 /* Move vertically: */
180 base.y = base.y + base.ym * frame_ratio;
182 if (dying != DYING_FALLING)
183 collision_swept_object_map(&old_base,&base);
184 if (base.y > screen->h)
185 bad_guys.erase(static_cast<std::vector<BadGuy>::iterator>(this));
186 /* Bump into things horizontally: */
188 /* Bump into things horizontally: */
193 if (issolid( base.x, (int) base.y + 16))
197 else if (issolid( base.x + base.width, (int) base.y + 16))
201 if(mode == KICK && changed != dir)
203 /* handle stereo sound */
204 /* FIXME: In theory a badguy object doesn't know anything about player objects */
205 if (tux.base.x > base.x)
206 play_sound(sounds[SND_RICOCHET], SOUND_LEFT_SPEAKER);
207 else if (tux.base.x < base.x)
208 play_sound(sounds[SND_RICOCHET], SOUND_RIGHT_SPEAKER);
210 play_sound(sounds[SND_RICOCHET], SOUND_CENTER_SPEAKER);
215 /* Fall if we get off the ground: */
216 if (dying != DYING_FALLING)
218 if (!issolid(base.x+16, base.y + 32))
220 if(!physic_is_set(&physic))
222 physic_set_state(&physic,PH_VT);
223 physic_set_start_vy(&physic,0.);
228 base.ym = physic_get_velocity(&physic);
237 base.y = (int)(base.y / 32) * 32;
240 physic_init(&physic);
245 if(!physic_is_set(&physic))
247 physic_set_state(&physic,PH_VT);
248 physic_set_start_vy(&physic,0.);
250 base.ym = physic_get_velocity(&physic);
254 void BadGuy::action_money()
256 /* Move vertically: */
257 base.y = base.y + base.ym * frame_ratio;
259 if (dying != DYING_FALLING)
260 collision_swept_object_map(&old_base,&base);
262 if (base.y > screen->h)
263 bad_guys.erase(static_cast<std::vector<BadGuy>::iterator>(this));
265 if(physic_get_state(&physic) == -1)
267 physic_set_state(&physic,PH_VT);
268 physic_set_start_vy(&physic,0.);
271 if (dying != DYING_FALLING)
273 if(issolid(base.x, base.y + 32))
275 physic_set_state(&physic,PH_VT);
276 physic_set_start_vy(&physic,6.);
277 base.ym = physic_get_velocity(&physic);
279 else if(issolid(base.x, base.y))
280 { /* This works, but isn't the best solution imagineable */
281 physic_set_state(&physic,PH_VT);
282 physic_set_start_vy(&physic,0.);
283 base.ym = physic_get_velocity(&physic);
288 base.ym = physic_get_velocity(&physic);
293 if(!physic_is_set(&physic))
295 physic_set_state(&physic,PH_VT);
296 physic_set_start_vy(&physic,0.);
298 base.ym = physic_get_velocity(&physic);
323 /* Handle mode timer: */
324 if (mode == FLAT && mode != HELD)
326 if(!timer_check(&timer))
332 else if (mode == KICK)
337 // Handle dying timer:
338 if (dying == DYING_SQUISHED)
340 /* Remove it if time's up: */
341 if(!timer_check(&timer))
342 bad_guys.erase(static_cast<std::vector<BadGuy>::iterator>(this));
345 // Remove if it's far off the screen:
346 if (base.x < scroll_x - OFFSCREEN_DISTANCE)
348 bad_guys.erase(static_cast<std::vector<BadGuy>::iterator>(this));
353 // Once it's on screen, it's activated!
354 if (base.x <= scroll_x + screen->w + OFFSCREEN_DISTANCE)
362 /* --- BLUE SCREEN OF DEATH MONSTER: --- */
363 if (dying == DYING_NOT)
368 texture_draw(&img_bsod_left[(global_frame_counter / 5) % 4],
374 texture_draw(&img_bsod_right[(global_frame_counter / 5) % 4],
379 else if (dying == DYING_FALLING)
385 texture_draw(&img_bsod_falling_left,
391 texture_draw(&img_bsod_falling_right,
396 else if (dying == DYING_SQUISHED)
398 /* Dying - Squished: */
402 texture_draw(&img_bsod_squished_left,
408 texture_draw(&img_bsod_squished_right,
415 void BadGuy::draw_laptop()
417 /* --- LAPTOP MONSTER: --- */
418 if (dying == DYING_NOT)
427 texture_draw(&img_laptop_left[(global_frame_counter / 5) % 3],
433 texture_draw(&img_laptop_right[(global_frame_counter / 5) % 3],
444 texture_draw(&img_laptop_flat_left,
450 texture_draw(&img_laptop_flat_right,
456 else if (dying == DYING_FALLING)
462 texture_draw(&img_laptop_falling_left,
468 texture_draw(&img_laptop_falling_right,
475 void BadGuy::draw_money()
477 if (base.ym != 300 /* > -16*/)
481 texture_draw(&img_money_left[0],
487 texture_draw(&img_money_right[0],
496 texture_draw(&img_money_left[1],
502 texture_draw(&img_money_right[1],
511 // Don't try to draw stuff that is outside of the screen
512 if (base.x > scroll_x - 32 &&
513 base.x < scroll_x + screen->w)
530 puts("Unknown badguy type");
537 BadGuy::collision(void *p_c_object, int c_object)
539 BadGuy* pbad_c = NULL;
540 Player* pplayer_c = NULL;
545 dying = DYING_FALLING;
548 /* Gain some points: */
549 if (kind == BAD_BSOD)
550 add_score(base.x - scroll_x, base.y,
551 50 * score_multiplier);
552 else if (kind == BAD_LAPTOP)
553 add_score(base.x - scroll_x, base.y,
554 25 * score_multiplier);
555 else if (kind == BAD_MONEY)
556 add_score(base.x - scroll_x, base.y,
557 50 * score_multiplier);
559 /* Play death sound: */
560 play_sound(sounds[SND_FALL], SOUND_CENTER_SPEAKER);
564 pbad_c = (BadGuy*) p_c_object;
569 else if(mode == KICK)
571 /* We're in kick mode, kill the other guy
572 and yourself(wuahaha) : */
574 pbad_c->dying = DYING_FALLING;
575 pbad_c->base.ym = -8;
576 play_sound(sounds[SND_FALL], SOUND_CENTER_SPEAKER);
578 add_score(base.x - scroll_x,
580 pbad_c->dying = DYING_FALLING;
582 dying = DYING_FALLING;
585 add_score(pbad_c->base.x - scroll_x,
586 pbad_c->base.y, 100);
591 pplayer_c = static_cast<Player*>(p_c_object);
592 if(kind != BAD_MONEY)
594 if (kind == BAD_BSOD)
596 dying = DYING_SQUISHED;
597 timer_start(&timer,4000);
598 physic_set_state(&pplayer_c->vphysic,PH_VT);
599 physic_set_start_vy(&pplayer_c->vphysic,2.);
600 pplayer_c->base.y = base.y - pplayer_c->base.height - 1;
602 add_score(base.x - scroll_x, base.y,
603 50 * score_multiplier);
605 play_sound(sounds[SND_SQUISH], SOUND_CENTER_SPEAKER);
607 else if (kind == BAD_LAPTOP)
610 if (mode == NORMAL || mode == KICK)
614 play_sound(sounds[SND_STOMP], SOUND_CENTER_SPEAKER);
618 timer_start(&timer,10000);
620 physic_set_state(&pplayer_c->vphysic,PH_VT);
621 physic_set_start_vy(&pplayer_c->vphysic,2.);
622 pplayer_c->base.y = base.y - pplayer_c->base.height - 1;
624 else if (mode == FLAT)
627 play_sound(sounds[SND_KICK], SOUND_CENTER_SPEAKER);
629 if (pplayer_c->base.x < base.x + (base.width/2))
637 timer_start(&timer,5000);
640 physic_set_state(&pplayer_c->vphysic,PH_VT);
641 physic_set_start_vy(&pplayer_c->vphysic,2.);
642 pplayer_c->base.y = base.y - pplayer_c->base.height - 1;
644 add_score(base.x - scroll_x,
646 25 * score_multiplier);
648 /* play_sound(sounds[SND_SQUISH]); */