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;
68 /* Move vertically: */
70 base.y = base.y + base.ym * frame_ratio;
72 if (dying != DYING_FALLING)
73 collision_swept_object_map(&old_base,&base);
74 if (base.y > screen->h)
75 bad_guys.erase(static_cast<std::vector<BadGuy>::iterator>(this));
77 /* Bump into things horizontally: */
81 if (issolid( base.x, (int) base.y + 16))
85 else if (issolid( base.x + base.width, (int) base.y + 16))
91 /* Fall if we get off the ground: */
93 if (dying != DYING_FALLING)
95 if (!issolid(base.x+16, base.y + 32))
97 if(!physic_is_set(&physic))
99 physic_set_state(&physic,PH_VT);
100 physic_set_start_vy(&physic,2.);
103 base.ym = physic_get_velocity(&physic);
111 base.y = (int)(base.y / 32) * 32;
114 physic_init(&physic);
119 if(!physic_is_set(&physic))
121 physic_set_state(&physic,PH_VT);
122 physic_set_start_vy(&physic,2.);
124 base.ym = physic_get_velocity(&physic);
127 if (base.y > screen->h)
128 bad_guys.erase(static_cast<std::vector<BadGuy>::iterator>(this));
131 void BadGuy::action_laptop()
133 /* --- LAPTOP MONSTER: --- */
135 /* Move left/right: */
137 if (mode == NORMAL || mode == KICK)
139 if (dying == DYING_NOT ||
140 dying == DYING_FALLING)
143 base.x = base.x + base.xm * frame_ratio;
144 else if (dir == LEFT)
145 base.x = base.x - base.xm * frame_ratio;
148 else if (mode == HELD)
149 { /* FIXME: The pbad object shouldn't know about pplayer objects. */
150 /* If we're holding the laptop */
154 base.x = tux.base.x + 16;
155 base.y = tux.base.y + tux.base.height/1.5 - base.height;
157 else /* facing left */
159 base.x = tux.base.x - 16;
160 base.y = tux.base.y + tux.base.height/1.5 - base.height;
162 if(collision_object_map(&base))
165 base.y = tux.base.y + tux.base.height/1.5 - base.height;
168 if(tux.input_.fire != DOWN) /* SHOOT! */
178 play_sound(sounds[SND_KICK],SOUND_CENTER_SPEAKER);
183 /* Move vertically: */
186 base.y = base.y + base.ym * frame_ratio;
188 if (dying != DYING_FALLING)
189 collision_swept_object_map(&old_base,&base);
190 if (base.y > screen->h)
191 bad_guys.erase(static_cast<std::vector<BadGuy>::iterator>(this));
192 /* Bump into things horizontally: */
194 /* Bump into things horizontally: */
199 if (issolid( base.x, (int) base.y + 16))
203 else if (issolid( base.x + base.width, (int) base.y + 16))
207 if(mode == KICK && changed != dir)
209 /* handle stereo sound */
210 /* FIXME: In theory a badguy object doesn't know anything about player objects */
211 if (tux.base.x > base.x)
212 play_sound(sounds[SND_RICOCHET], SOUND_LEFT_SPEAKER);
213 else if (tux.base.x < base.x)
214 play_sound(sounds[SND_RICOCHET], SOUND_RIGHT_SPEAKER);
216 play_sound(sounds[SND_RICOCHET], SOUND_CENTER_SPEAKER);
222 /* Fall if we get off the ground: */
224 if (dying != DYING_FALLING)
226 if (!issolid(base.x+16, base.y + 32))
228 if(!physic_is_set(&physic))
230 physic_set_state(&physic,PH_VT);
231 physic_set_start_vy(&physic,0.);
236 base.ym = physic_get_velocity(&physic);
245 base.y = (int)(base.y / 32) * 32;
248 physic_init(&physic);
253 if(!physic_is_set(&physic))
255 physic_set_state(&physic,PH_VT);
256 physic_set_start_vy(&physic,0.);
258 base.ym = physic_get_velocity(&physic);
262 void BadGuy::action_money()
264 /* --- MONEY BAGS: --- */
267 /* Move vertically: */
269 base.y = base.y + base.ym * frame_ratio;
271 if (dying != DYING_FALLING)
272 collision_swept_object_map(&old_base,&base);
274 if (base.y > screen->h)
275 bad_guys.erase(static_cast<std::vector<BadGuy>::iterator>(this));
277 if(physic_get_state(&physic) == -1)
279 physic_set_state(&physic,PH_VT);
280 physic_set_start_vy(&physic,0.);
283 if (dying != DYING_FALLING)
285 if(issolid(base.x, base.y + 32))
287 physic_set_state(&physic,PH_VT);
288 physic_set_start_vy(&physic,6.);
289 base.ym = physic_get_velocity(&physic);
291 else if(issolid(base.x, base.y))
292 { /* This works, but isn't the best solution imagineable */
293 physic_set_state(&physic,PH_VT);
294 physic_set_start_vy(&physic,0.);
295 base.ym = physic_get_velocity(&physic);
300 base.ym = physic_get_velocity(&physic);
305 if(!physic_is_set(&physic))
307 physic_set_state(&physic,PH_VT);
308 physic_set_start_vy(&physic,0.);
310 base.ym = physic_get_velocity(&physic);
335 /* Handle mode timer: */
336 if (mode == FLAT && mode != HELD)
338 if(!timer_check(&timer))
344 else if (mode == KICK)
349 // Handle dying timer:
350 if (dying == DYING_SQUISHED)
352 /* Remove it if time's up: */
353 if(!timer_check(&timer))
354 bad_guys.erase(static_cast<std::vector<BadGuy>::iterator>(this));
357 // Remove if it's far off the screen:
358 if (base.x < scroll_x - OFFSCREEN_DISTANCE)
360 bad_guys.erase(static_cast<std::vector<BadGuy>::iterator>(this));
365 // Once it's on screen, it's activated!
366 if (base.x <= scroll_x + screen->w + OFFSCREEN_DISTANCE)
374 /* --- BLUE SCREEN OF DEATH MONSTER: --- */
375 if (dying == DYING_NOT)
380 texture_draw(&img_bsod_left[(global_frame_counter / 5) % 4],
386 texture_draw(&img_bsod_right[(global_frame_counter / 5) % 4],
391 else if (dying == DYING_FALLING)
397 texture_draw(&img_bsod_falling_left,
403 texture_draw(&img_bsod_falling_right,
408 else if (dying == DYING_SQUISHED)
410 /* Dying - Squished: */
414 texture_draw(&img_bsod_squished_left,
420 texture_draw(&img_bsod_squished_right,
427 void BadGuy::draw_laptop()
429 /* --- LAPTOP MONSTER: --- */
430 if (dying == DYING_NOT)
439 texture_draw(&img_laptop_left[(global_frame_counter / 5) % 3],
445 texture_draw(&img_laptop_right[(global_frame_counter / 5) % 3],
456 texture_draw(&img_laptop_flat_left,
462 texture_draw(&img_laptop_flat_right,
468 else if (dying == DYING_FALLING)
474 texture_draw(&img_laptop_falling_left,
480 texture_draw(&img_laptop_falling_right,
487 void BadGuy::draw_money()
489 if (base.ym != 300 /* > -16*/)
493 texture_draw(&img_money_left[0],
499 texture_draw(&img_money_right[0],
508 texture_draw(&img_money_left[1],
514 texture_draw(&img_money_right[1],
523 // Don't try to draw stuff that is outside of the screen
524 if (base.x > scroll_x - 32 &&
525 base.x < scroll_x + screen->w)
542 puts("Unknown badguy type");
549 BadGuy::collision(void *p_c_object, int c_object)
551 BadGuy* pbad_c = NULL;
552 Player* pplayer_c = NULL;
557 dying = DYING_FALLING;
560 /* Gain some points: */
561 if (kind == BAD_BSOD)
562 add_score(base.x - scroll_x, base.y,
563 50 * score_multiplier);
564 else if (kind == BAD_LAPTOP)
565 add_score(base.x - scroll_x, base.y,
566 25 * score_multiplier);
567 else if (kind == BAD_MONEY)
568 add_score(base.x - scroll_x, base.y,
569 50 * score_multiplier);
571 /* Play death sound: */
572 play_sound(sounds[SND_FALL], SOUND_CENTER_SPEAKER);
576 pbad_c = (BadGuy*) p_c_object;
581 else if(mode == KICK)
583 /* We're in kick mode, kill the other guy
584 and yourself(wuahaha) : */
586 pbad_c->dying = DYING_FALLING;
587 pbad_c->base.ym = -8;
588 play_sound(sounds[SND_FALL], SOUND_CENTER_SPEAKER);
590 add_score(base.x - scroll_x,
592 pbad_c->dying = DYING_FALLING;
594 dying = DYING_FALLING;
597 add_score(pbad_c->base.x - scroll_x,
598 pbad_c->base.y, 100);
603 pplayer_c = static_cast<Player*>(p_c_object);
604 if(kind != BAD_MONEY)
606 if (kind == BAD_BSOD)
608 dying = DYING_SQUISHED;
609 timer_start(&timer,4000);
610 physic_set_state(&pplayer_c->vphysic,PH_VT);
611 physic_set_start_vy(&pplayer_c->vphysic,2.);
612 pplayer_c->base.y = base.y - pplayer_c->base.height - 1;
614 add_score(base.x - scroll_x, base.y,
615 50 * score_multiplier);
617 play_sound(sounds[SND_SQUISH], SOUND_CENTER_SPEAKER);
619 else if (kind == BAD_LAPTOP)
622 if (mode == NORMAL || mode == KICK)
626 play_sound(sounds[SND_STOMP], SOUND_CENTER_SPEAKER);
630 timer_start(&timer,10000);
632 physic_set_state(&pplayer_c->vphysic,PH_VT);
633 physic_set_start_vy(&pplayer_c->vphysic,2.);
634 pplayer_c->base.y = base.y - pplayer_c->base.height - 1;
636 else if (mode == FLAT)
639 play_sound(sounds[SND_KICK], SOUND_CENTER_SPEAKER);
641 if (pplayer_c->base.x < base.x + (base.width/2))
649 timer_start(&timer,5000);
652 physic_set_state(&pplayer_c->vphysic,PH_VT);
653 physic_set_start_vy(&pplayer_c->vphysic,2.);
654 pplayer_c->base.y = base.y - pplayer_c->base.height - 1;
656 add_score(base.x - scroll_x,
658 25 * score_multiplier);
660 /* play_sound(sounds[SND_SQUISH]); */