4 // Copyright (C) 2000 Bill Kendrick <bill@newbreedsoftware.com>
5 // Copyright (C) 2004 Tobias Glaesser <tobi.web@gmx.de>
6 // Copyright (C) 2004 Matthias Braun <matze@braunis.de>
8 // This program is free software; you can redistribute it and/or
9 // modify it under the terms of the GNU General Public License
10 // as published by the Free Software Foundation; either version 2
11 // of the License, or (at your option) any later version.
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 // GNU General Public License for more details.
18 // You should have received a copy of the GNU General Public License
19 // along with this program; if not, write to the Free Software
20 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
33 #include "resources.h"
34 #include "sprite_manager.h"
36 Sprite* img_bsod_squished_left;
37 Sprite* img_bsod_squished_right;
38 Sprite* img_bsod_falling_left;
39 Sprite* img_bsod_falling_right;
40 Sprite* img_laptop_flat_left;
41 Sprite* img_laptop_flat_right;
42 Sprite* img_laptop_falling_left;
43 Sprite* img_laptop_falling_right;
44 Sprite* img_bsod_left;
45 Sprite* img_bsod_right;
46 Sprite* img_laptop_left;
47 Sprite* img_laptop_right;
48 Sprite* img_jumpy_left_up;
49 Sprite* img_jumpy_left_down;
50 Sprite* img_jumpy_left_middle;
51 Sprite* img_mrbomb_left;
52 Sprite* img_mrbomb_right;
53 Sprite* img_mrbomb_ticking_left;
54 Sprite* img_mrbomb_ticking_right;
55 Sprite* img_mrbomb_explosion;
56 Sprite* img_stalactite;
57 Sprite* img_stalactite_broken;
60 Sprite* img_fish_down;
61 Sprite* img_bouncingsnowball_left;
62 Sprite* img_bouncingsnowball_right;
63 Sprite* img_bouncingsnowball_squished;
64 Sprite* img_flyingsnowball;
65 Sprite* img_flyingsnowball_squished;
66 Sprite* img_spiky_left;
67 Sprite* img_spiky_right;
68 Sprite* img_snowball_left;
69 Sprite* img_snowball_right;
70 Sprite* img_snowball_squished_left;
71 Sprite* img_snowball_squished_right;
73 BadGuyKind badguykind_from_string(const std::string& str)
77 else if (str == "laptop" || str == "mriceblock")
79 else if (str == "bsod")
81 else if (str == "mrbomb")
83 else if (str == "stalactite")
84 return BAD_STALACTITE;
85 else if (str == "flame")
87 else if (str == "fish")
89 else if (str == "bouncingsnowball")
90 return BAD_BOUNCINGSNOWBALL;
91 else if (str == "flyingsnowball")
92 return BAD_FLYINGSNOWBALL;
93 else if (str == "spiky")
95 else if (str == "snowball")
99 printf("Couldn't convert badguy: '%s'\n", str.c_str());
104 std::string badguykind_to_string(BadGuyKind kind)
129 case BAD_BOUNCINGSNOWBALL:
130 return "bouncingsnowball";
132 case BAD_FLYINGSNOWBALL:
133 return "flyingsnowball";
147 BadGuy::init(float x, float y, BadGuyKind kind_)
163 animation_length = 1;
164 animation_offset = 0;
165 sprite_left = sprite_right = 0;
169 if(kind == BAD_BSOD) {
170 physic.set_velocity(-1.3, 0);
171 set_sprite(img_bsod_left, img_bsod_right, 4);
172 } else if(kind == BAD_MRBOMB) {
173 physic.set_velocity(-1.3, 0);
174 set_sprite(img_mrbomb_left, img_mrbomb_right, 4);
175 } else if (kind == BAD_LAPTOP) {
176 physic.set_velocity(-1.3, 0);
177 set_sprite(img_laptop_left, img_laptop_right, 4, 5);
178 } else if(kind == BAD_MONEY) {
179 set_sprite(img_jumpy_left_up, img_jumpy_left_up, 1);
180 } else if(kind == BAD_BOMB) {
181 set_sprite(img_mrbomb_ticking_left, img_mrbomb_ticking_right, 1);
182 // hack so that the bomb doesn't hurt until it expldes...
183 dying = DYING_SQUISHED;
184 } else if(kind == BAD_FLAME) {
185 base.ym = 0; // we misuse base.ym as angle for the flame
186 physic.enable_gravity(false);
187 set_sprite(img_flame, img_flame, 2, 0.5);
188 } else if(kind == BAD_BOUNCINGSNOWBALL) {
189 physic.set_velocity(-1.3, 0);
190 set_sprite(img_bouncingsnowball_left, img_bouncingsnowball_right, 6);
191 } else if(kind == BAD_STALACTITE) {
192 physic.enable_gravity(false);
193 set_sprite(img_stalactite, img_stalactite, 1);
194 } else if(kind == BAD_FISH) {
195 set_sprite(img_fish, img_fish, 2, 1);
196 physic.enable_gravity(true);
197 } else if(kind == BAD_FLYINGSNOWBALL) {
198 set_sprite(img_flyingsnowball, img_flyingsnowball, 2, 5);
199 physic.enable_gravity(false);
200 } else if(kind == BAD_SPIKY) {
201 physic.set_velocity(-1.3, 0);
202 set_sprite(img_spiky_left, img_spiky_right, 3);
203 } else if(kind == BAD_SNOWBALL) {
204 physic.set_velocity(-1.3, 0);
205 set_sprite(img_snowball_left, img_snowball_right, 4, 5);
208 // if we're in a solid tile at start correct that now
209 if(kind != BAD_FLAME && kind != BAD_FISH && collision_object_map(&base)) {
210 printf("Warning: badguy started in wall!.\n");
211 while(collision_object_map(&base))
217 BadGuy::action_bsod(float frame_ratio)
219 static const float BSODJUMP = 2;
221 if (dying == DYING_NOT)
222 check_horizontal_bump();
226 // jump when we're about to fall
227 if (physic.get_velocity_y() == 0 &&
228 !issolid(base.x+base.width/2, base.y + base.height)) {
229 physic.enable_gravity(true);
230 physic.set_velocity(physic.get_velocity_x(), BSODJUMP);
233 // Handle dying timer:
234 if (dying == DYING_SQUISHED && !timer.check())
236 /* Remove it if time's up: */
242 physic.apply(frame_ratio, base.x, base.y);
243 if(dying != DYING_FALLING)
244 collision_swept_object_map(&old_base, &base);
248 BadGuy::action_laptop(float frame_ratio)
250 Player& tux = *World::current()->get_tux();
252 if(dying == DYING_NOT)
255 /* Move left/right: */
256 if (mode == NORMAL || mode == KICK)
259 physic.apply(frame_ratio, base.x, base.y);
260 if (dying != DYING_FALLING)
261 collision_swept_object_map(&old_base,&base);
263 else if (mode == HELD)
264 { /* FIXME: The pbad object shouldn't know about pplayer objects. */
265 /* If we're holding the laptop */
269 base.x = tux.base.x + 16;
270 base.y = tux.base.y + tux.base.height/1.5 - base.height;
272 else /* facing left */
274 base.x = tux.base.x - 16;
275 base.y = tux.base.y + tux.base.height/1.5 - base.height;
277 if(collision_object_map(&base))
280 base.y = tux.base.y + tux.base.height/1.5 - base.height;
283 if(tux.input.fire != DOWN) /* SHOOT! */
292 set_sprite(img_laptop_flat_left, img_laptop_flat_right, 1);
293 physic.set_velocity((dir == LEFT) ? -8 : 8, -8);
294 play_sound(sounds[SND_KICK],SOUND_CENTER_SPEAKER);
301 check_horizontal_bump();
302 if(mode == KICK && changed != dir)
304 /* handle stereo sound (number 10 should be tweaked...)*/
305 if (base.x < scroll_x + screen->w/2 - 10)
306 play_sound(sounds[SND_RICOCHET], SOUND_LEFT_SPEAKER);
307 else if (base.x > scroll_x + screen->w/2 + 10)
308 play_sound(sounds[SND_RICOCHET], SOUND_RIGHT_SPEAKER);
310 play_sound(sounds[SND_RICOCHET], SOUND_CENTER_SPEAKER);
314 /* Handle mode timer: */
320 set_sprite(img_laptop_left, img_laptop_right, 4, 5);
321 physic.set_velocity( (dir == LEFT) ? -1.3 : 1.3, 0);
327 BadGuy::check_horizontal_bump(bool checkcliff)
329 float halfheight = base.height / 2;
330 if (dir == LEFT && issolid( base.x, (int) base.y + halfheight))
333 physic.set_velocity(-physic.get_velocity_x(), physic.get_velocity_y());
336 if (dir == RIGHT && issolid( base.x + base.width, (int)base.y + halfheight))
339 physic.set_velocity(-physic.get_velocity_x(), physic.get_velocity_y());
343 // don't check for cliffs when we're falling
346 if(!issolid(base.x + base.width/2, base.y + base.height))
349 if(dir == LEFT && !issolid(base.x, (int) base.y + base.height + halfheight))
352 physic.set_velocity(-physic.get_velocity_x(), physic.get_velocity_y());
355 if(dir == RIGHT && !issolid(base.x + base.width,
356 (int) base.y + base.height + halfheight))
359 physic.set_velocity(-physic.get_velocity_x(), physic.get_velocity_y());
367 /* Fall if we get off the ground: */
368 if (dying != DYING_FALLING)
370 if (!issolid(base.x+base.width/2, base.y + base.height))
372 // not solid below us? enable gravity
373 physic.enable_gravity(true);
378 if (physic.get_velocity_y() < 0)
380 base.y = int((base.y + base.height)/32) * 32 - base.height;
381 physic.set_velocity(physic.get_velocity_x(), 0);
383 // no gravity anymore please
384 physic.enable_gravity(false);
389 physic.enable_gravity(true);
396 for(std::vector<BadGuy>::iterator i = World::current()->bad_guys.begin();
397 i != World::current()->bad_guys.end(); ++i)
399 if( & (*i) == this) {
400 World::current()->bad_guys.erase(i);
407 BadGuy::action_money(float frame_ratio)
409 if (fabsf(physic.get_velocity_y()) < 2.5f)
410 set_sprite(img_jumpy_left_middle, img_jumpy_left_middle, 1);
411 else if (physic.get_velocity_y() < 0)
412 set_sprite(img_jumpy_left_up, img_jumpy_left_up, 1);
414 set_sprite(img_jumpy_left_down, img_jumpy_left_down, 1);
416 Player& tux = *World::current()->get_tux();
418 static const float JUMPV = 6;
421 // jump when on ground
422 if(dying == DYING_NOT && issolid(base.x, base.y+32))
424 physic.set_velocity(physic.get_velocity_x(), JUMPV);
425 physic.enable_gravity(true);
429 else if(mode == MONEY_JUMP)
434 // set direction based on tux
435 if(tux.base.x > base.x)
441 physic.apply(frame_ratio, base.x, base.y);
442 if(dying == DYING_NOT)
443 collision_swept_object_map(&old_base, &base);
447 BadGuy::action_mrbomb(float frame_ratio)
449 if (dying == DYING_NOT)
450 check_horizontal_bump(true);
454 physic.apply(frame_ratio, base.x, base.y);
455 if (dying != DYING_FALLING)
456 collision_swept_object_map(&old_base,&base);
460 BadGuy::action_bomb(float frame_ratio)
462 static const int TICKINGTIME = 1000;
463 static const int EXPLODETIME = 1000;
469 timer.start(TICKINGTIME);
470 } else if(!timer.check()) {
471 if(mode == BOMB_TICKING) {
473 set_sprite(img_mrbomb_explosion, img_mrbomb_explosion, 1);
474 dying = DYING_NOT; // now the bomb hurts
475 timer.start(EXPLODETIME);
476 } else if(mode == BOMB_EXPLODE) {
483 physic.apply(frame_ratio, base.x, base.y);
484 collision_swept_object_map(&old_base,&base);
488 BadGuy::action_stalactite(float frame_ratio)
490 Player& tux = *World::current()->get_tux();
492 static const int SHAKETIME = 800;
493 static const int RANGE = 40;
496 // start shaking when tux is below the stalactite and at least 40 pixels
498 if(tux.base.x + 32 > base.x - RANGE && tux.base.x < base.x + 32 + RANGE
499 && tux.base.y + tux.base.height > base.y) {
500 timer.start(SHAKETIME);
501 mode = STALACTITE_SHAKING;
503 } if(mode == STALACTITE_SHAKING) {
504 base.x = old_base.x + (rand() % 6) - 3; // TODO this could be done nicer...
506 mode = STALACTITE_FALL;
508 } else if(mode == STALACTITE_FALL) {
510 /* Destroy if we collides with land */
511 if(issolid(base.x+base.width/2, base.y+base.height))
514 dying = DYING_SQUISHED;
516 set_sprite(img_stalactite_broken, img_stalactite_broken, 1);
518 } else if(mode == FLAT) {
523 physic.apply(frame_ratio, base.x, base.y);
525 if(dying == DYING_SQUISHED && !timer.check())
530 BadGuy::action_flame(float frame_ratio)
532 static const float radius = 100;
533 static const float speed = 0.02;
534 base.x = old_base.x + cos(base.ym) * radius;
535 base.y = old_base.y + sin(base.ym) * radius;
537 base.ym = fmodf(base.ym + frame_ratio * speed, 2*M_PI);
541 BadGuy::action_fish(float frame_ratio)
543 static const float JUMPV = 6;
544 static const int WAITTIME = 1000;
546 // go in wait mode when back in water
547 if(dying == DYING_NOT && gettile(base.x, base.y+ base.height)->water
548 && physic.get_velocity_y() <= 0 && mode == NORMAL)
552 physic.set_velocity(0, 0);
553 physic.enable_gravity(false);
554 timer.start(WAITTIME);
556 else if(mode == FISH_WAIT && !timer.check())
559 set_sprite(img_fish, img_fish, 2, 2);
560 animation_offset = global_frame_counter; // restart animation
562 physic.set_velocity(0, JUMPV);
563 physic.enable_gravity(true);
566 physic.apply(frame_ratio, base.x, base.y);
567 if(dying == DYING_NOT)
568 collision_swept_object_map(&old_base, &base);
570 if(physic.get_velocity_y() < 0)
571 set_sprite(img_fish_down, img_fish_down);
575 BadGuy::action_bouncingsnowball(float frame_ratio)
577 static const float JUMPV = 4.5;
581 // jump when on ground
582 if(dying == DYING_NOT && issolid(base.x, base.y+32))
584 physic.set_velocity(physic.get_velocity_x(), JUMPV);
585 physic.enable_gravity(true);
592 // check for right/left collisions
593 check_horizontal_bump();
595 physic.apply(frame_ratio, base.x, base.y);
596 if(dying == DYING_NOT)
597 collision_swept_object_map(&old_base, &base);
599 // Handle dying timer:
600 if (dying == DYING_SQUISHED && !timer.check())
602 /* Remove it if time's up: */
609 BadGuy::action_flyingsnowball(float frame_ratio)
611 static const float FLYINGSPEED = 1;
612 static const int DIRCHANGETIME = 1000;
614 // go into flyup mode if none specified yet
615 if(dying == DYING_NOT && mode == NORMAL) {
617 physic.set_velocity(physic.get_velocity_x(), FLYINGSPEED);
618 timer.start(DIRCHANGETIME/2);
621 if(dying == DYING_NOT && !timer.check()) {
624 physic.set_velocity(physic.get_velocity_x(), -FLYINGSPEED);
625 } else if(mode == FLY_DOWN) {
627 physic.set_velocity(physic.get_velocity_x(), FLYINGSPEED);
629 timer.start(DIRCHANGETIME);
632 if(dying != DYING_NOT)
633 physic.enable_gravity(true);
635 physic.apply(frame_ratio, base.x, base.y);
636 if(dying == DYING_NOT || dying == DYING_SQUISHED)
637 collision_swept_object_map(&old_base, &base);
639 // Handle dying timer:
640 if (dying == DYING_SQUISHED && !timer.check())
642 /* Remove it if time's up: */
649 BadGuy::action_spiky(float frame_ratio)
651 if (dying == DYING_NOT)
652 check_horizontal_bump();
656 // jump when we're about to fall
657 if (physic.get_velocity_y() == 0 &&
658 !issolid(base.x+base.width/2, base.y + base.height)) {
659 physic.enable_gravity(true);
660 physic.set_velocity(physic.get_velocity_x(), 2);
664 physic.apply(frame_ratio, base.x, base.y);
665 if (dying != DYING_FALLING)
666 collision_swept_object_map(&old_base,&base);
670 BadGuy::action_snowball(float frame_ratio)
672 if (dying == DYING_NOT)
673 check_horizontal_bump();
677 physic.apply(frame_ratio, base.x, base.y);
678 if (dying != DYING_FALLING)
679 collision_swept_object_map(&old_base,&base);
683 BadGuy::action(float frame_ratio)
685 // Remove if it's far off the screen:
686 if (base.x < scroll_x - OFFSCREEN_DISTANCE)
692 // BadGuy fall below the ground
693 if (base.y > screen->h) {
698 // Once it's on screen, it's activated!
699 if (base.x <= scroll_x + screen->w + OFFSCREEN_DISTANCE)
708 action_bsod(frame_ratio);
712 action_laptop(frame_ratio);
716 action_money(frame_ratio);
720 action_mrbomb(frame_ratio);
724 action_bomb(frame_ratio);
728 action_stalactite(frame_ratio);
732 action_flame(frame_ratio);
736 action_fish(frame_ratio);
739 case BAD_BOUNCINGSNOWBALL:
740 action_bouncingsnowball(frame_ratio);
743 case BAD_FLYINGSNOWBALL:
744 action_flyingsnowball(frame_ratio);
748 action_spiky(frame_ratio);
752 action_snowball(frame_ratio);
760 // Don't try to draw stuff that is outside of the screen
761 if(base.x <= scroll_x - base.width || base.x >= scroll_x + screen->w)
764 if(sprite_left == 0 || sprite_right == 0)
766 std::cout << "BadGuy: Error no sprite loaded" << std::endl;
770 float global_frame = (float(global_frame_counter - animation_offset) / 10);
771 global_frame *= animation_speed;
772 //size_t frame = size_t(global_frame) % animation_length;
773 Sprite* sprite = (dir == LEFT) ? sprite_left : sprite_right;
774 sprite->draw(base.x - scroll_x, base.y);
777 fillrect(base.x - scroll_x, base.y, base.width, base.height, 75,0,75, 150);
781 BadGuy::set_sprite(Sprite* left, Sprite* right,
782 int nanimlength, float nanimspeed)
791 // FIXME: Using the image size for the physics and collision is
792 // a bad idea, since images should always overlap there physical
795 if(base.width == 0 && base.height == 0) {
796 base.width = left->get_width();
797 base.height = left->get_height();
798 } else if(base.width != left->get_width() || base.height != left->get_height()) {
799 base.x -= (left->get_width() - base.width) / 2;
800 base.y -= left->get_height() - base.height;
801 base.width = left->get_width();
802 base.height = left->get_height();
806 base.width = base.height = 0;
810 animation_length = nanimlength;
811 animation_speed = nanimspeed;
812 animation_offset = 0;
814 sprite_right = right;
820 if(kind == BAD_BSOD || kind == BAD_LAPTOP || kind == BAD_MRBOMB
821 || kind == BAD_BOUNCINGSNOWBALL) {
827 BadGuy::make_player_jump(Player* player)
829 player->physic.set_velocity(player->physic.get_velocity_x(), 2);
830 player->base.y = base.y - player->base.height - 2;
834 BadGuy::squish_me(Player* player)
836 make_player_jump(player);
838 World::current()->add_score(base.x - scroll_x,
839 base.y, 50 * player_status.score_multiplier);
840 play_sound(sounds[SND_SQUISH], SOUND_CENTER_SPEAKER);
841 player_status.score_multiplier++;
843 dying = DYING_SQUISHED;
845 physic.set_velocity(0, 0);
849 BadGuy::squish(Player* player)
851 if(kind == BAD_MRBOMB) {
852 // mrbomb transforms into a bomb now
853 World::current()->add_bad_guy(base.x, base.y, BAD_BOMB);
855 make_player_jump(player);
856 World::current()->add_score(base.x - scroll_x, base.y, 50 * player_status.score_multiplier);
857 play_sound(sounds[SND_SQUISH], SOUND_CENTER_SPEAKER);
858 player_status.score_multiplier++;
863 } else if(kind == BAD_BSOD) {
865 set_sprite(img_bsod_squished_left, img_bsod_squished_right, 1);
866 physic.set_velocity(0, physic.get_velocity_y());
869 } else if (kind == BAD_LAPTOP) {
870 if (mode == NORMAL || mode == KICK)
873 play_sound(sounds[SND_STOMP], SOUND_CENTER_SPEAKER);
875 set_sprite(img_laptop_flat_left, img_laptop_flat_right, 1);
876 physic.set_velocity(0, physic.get_velocity_y());
879 } else if (mode == FLAT) {
881 play_sound(sounds[SND_KICK], SOUND_CENTER_SPEAKER);
883 if (player->base.x < base.x + (base.width/2)) {
884 physic.set_velocity(5, physic.get_velocity_y());
887 physic.set_velocity(-5, physic.get_velocity_y());
892 set_sprite(img_laptop_flat_left, img_laptop_flat_right, 1);
895 make_player_jump(player);
897 World::current()->add_score(base.x - scroll_x, base.y, 25 * player_status.score_multiplier);
898 player_status.score_multiplier++;
900 } else if(kind == BAD_FISH) {
901 // fish can only be killed when falling down
902 if(physic.get_velocity_y() >= 0)
905 make_player_jump(player);
907 World::current()->add_score(base.x - scroll_x, base.y, 25 * player_status.score_multiplier);
908 player_status.score_multiplier++;
910 // simply remove the fish...
913 } else if(kind == BAD_BOUNCINGSNOWBALL) {
915 set_sprite(img_bouncingsnowball_squished,img_bouncingsnowball_squished,1);
917 } else if(kind == BAD_FLYINGSNOWBALL) {
919 set_sprite(img_flyingsnowball_squished,img_flyingsnowball_squished,1);
921 } else if(kind == BAD_SNOWBALL) {
923 set_sprite(img_snowball_squished_left, img_snowball_squished_right, 1);
931 if(kind == BAD_BOMB || kind == BAD_STALACTITE || kind == BAD_FLAME)
934 dying = DYING_FALLING;
935 if(kind == BAD_LAPTOP)
936 set_sprite(img_laptop_falling_left, img_laptop_falling_right, 1);
937 else if(kind == BAD_BSOD)
938 set_sprite(img_bsod_falling_left, img_bsod_falling_right, 1);
940 physic.enable_gravity(true);
941 physic.set_velocity(physic.get_velocity_x(), 0);
943 /* Gain some points: */
944 if (kind == BAD_BSOD)
945 World::current()->add_score(base.x - scroll_x, base.y,
946 50 * player_status.score_multiplier);
948 World::current()->add_score(base.x - scroll_x, base.y,
949 25 * player_status.score_multiplier);
951 /* Play death sound: */
952 play_sound(sounds[SND_FALL], SOUND_CENTER_SPEAKER);
956 BadGuy::collision(void *p_c_object, int c_object, CollisionType type)
958 BadGuy* pbad_c = NULL;
960 if(type == COLLISION_BUMP) {
964 if(type == COLLISION_SQUISH) {
965 Player* player = static_cast<Player*>(p_c_object);
970 /* COLLISION_NORMAL */
978 pbad_c = (BadGuy*) p_c_object;
980 /* If we're a kicked mriceblock, kill any badguys we hit */
981 if(kind == BAD_LAPTOP && mode == KICK &&
982 pbad_c->kind != BAD_FLAME && pbad_c->kind != BAD_BOMB)
987 /* Kill badguys that run into exploding bomb */
988 else if (kind == BAD_BOMB && dying == DYING_NOT)
990 if (pbad_c->kind == BAD_MRBOMB)
992 // FIXME: this is where other MrBombs *should* explode istead of dying
995 else if (pbad_c->kind != BAD_BOMB)
1001 /* Kill any badguys that get hit by stalactite */
1002 else if (kind == BAD_STALACTITE && dying == DYING_NOT)
1007 /* When enemies run into eachother, make them change directions */
1010 // Jumpy is an exception
1011 if (pbad_c->kind == BAD_MONEY)
1015 else if (dir == RIGHT)
1018 physic.inverse_velocity_x();
1024 Player* player = static_cast<Player*>(p_c_object);
1025 /* Get kicked if were flat */
1026 if (mode == FLAT && !dying)
1028 play_sound(sounds[SND_KICK], SOUND_CENTER_SPEAKER);
1030 // Hit from left side
1031 if (player->base.x < base.x) {
1032 physic.set_velocity(5, physic.get_velocity_y());
1035 // Hit from right side
1037 physic.set_velocity(-5, physic.get_velocity_y());
1042 set_sprite(img_laptop_flat_left, img_laptop_flat_right, 1);
1049 //---------------------------------------------------------------------------
1051 void load_badguy_gfx()
1053 img_bsod_squished_left = sprite_manager->load("bsod-squished-left");
1054 img_bsod_squished_right = sprite_manager->load("bsod-squished-right");
1055 img_bsod_falling_left = sprite_manager->load("bsod-falling-left");
1056 img_bsod_falling_right = sprite_manager->load("bsod-falling-right");
1057 img_laptop_flat_left = sprite_manager->load("laptop-flat-left");
1058 img_laptop_flat_right = sprite_manager->load("laptop-flat-right");
1059 img_laptop_falling_left = sprite_manager->load("laptop-falling-left");
1060 img_laptop_falling_right = sprite_manager->load("laptop-falling-right");
1061 img_bsod_left = sprite_manager->load("bsod-left");
1062 img_bsod_right = sprite_manager->load("bsod-right");
1063 img_laptop_left = sprite_manager->load("laptop-left");
1064 img_laptop_right = sprite_manager->load("laptop-right");
1065 img_jumpy_left_up = sprite_manager->load("jumpy-left-up");
1066 img_jumpy_left_down = sprite_manager->load("jumpy-left-down");
1067 img_jumpy_left_middle = sprite_manager->load("jumpy-left-middle");
1068 img_mrbomb_left = sprite_manager->load("mrbomb-left");
1069 img_mrbomb_right = sprite_manager->load("mrbomb-right");
1070 img_mrbomb_ticking_left = sprite_manager->load("mrbomb-ticking-left");
1071 img_mrbomb_ticking_right = sprite_manager->load("mrbomb-ticking-right");
1072 img_mrbomb_explosion = sprite_manager->load("mrbomb-explosion");
1073 img_stalactite = sprite_manager->load("stalactite");
1074 img_stalactite_broken = sprite_manager->load("stalactite-broken");
1075 img_flame = sprite_manager->load("flame");
1076 img_fish = sprite_manager->load("fish");
1077 img_fish_down = sprite_manager->load("fish-down");
1078 img_bouncingsnowball_left = sprite_manager->load("bouncingsnowball-left");
1079 img_bouncingsnowball_right = sprite_manager->load("bouncingsnowball-right");
1080 img_bouncingsnowball_squished = sprite_manager->load("bouncingsnowball-squished");
1081 img_flyingsnowball = sprite_manager->load("flyingsnowball");
1082 img_flyingsnowball_squished = sprite_manager->load("flyingsnowball-squished");
1083 img_spiky_left = sprite_manager->load("spiky-left");
1084 img_spiky_right = sprite_manager->load("spiky-right");
1085 img_snowball_left = sprite_manager->load("snowball-left");
1086 img_snowball_right = sprite_manager->load("snowball-right");
1087 img_snowball_squished_left = sprite_manager->load("snowball-squished-left");
1088 img_snowball_squished_right = sprite_manager->load("snowball-squished-right");
1091 img_bsod_left[0] = new Surface(datadir + "/images/shared/bsod-left-0.png", USE_ALPHA);
1093 img_bsod_left[1] = new Surface(datadir +
1094 "/images/shared/bsod-left-1.png",
1097 img_bsod_left[2] = new Surface(datadir +
1098 "/images/shared/bsod-left-2.png",
1101 img_bsod_left[3] = new Surface(datadir +
1102 "/images/shared/bsod-left-3.png",
1105 img_bsod_right[0] = new Surface(datadir +
1106 "/images/shared/bsod-right-0.png",
1109 img_bsod_right[1] = new Surface(datadir +
1110 "/images/shared/bsod-right-1.png",
1113 img_bsod_right[2] = new Surface(datadir +
1114 "/images/shared/bsod-right-2.png",
1117 img_bsod_right[3] = new Surface(datadir +
1118 "/images/shared/bsod-right-3.png",
1121 img_bsod_squished_left[0] = new Surface(datadir +
1122 "/images/shared/bsod-squished-left.png",
1125 img_bsod_squished_right[0] = new Surface(datadir +
1126 "/images/shared/bsod-squished-right.png",
1129 img_bsod_falling_left[0] = new Surface(datadir +
1130 "/images/shared/bsod-falling-left.png",
1133 img_bsod_falling_right[0] = new Surface(datadir +
1134 "/images/shared/bsod-falling-right.png",
1140 img_laptop_left[0] = new Surface(datadir + "/images/shared/mriceblock-left-0.png", USE_ALPHA);
1141 img_laptop_left[1] = new Surface(datadir + "/images/shared/mriceblock-left-1.png", USE_ALPHA);
1142 img_laptop_left[2] = new Surface(datadir + "/images/shared/mriceblock-left-2.png", USE_ALPHA);
1143 img_laptop_left[3] = new Surface(datadir + "/images/shared/mriceblock-left-1.png", USE_ALPHA);
1145 img_laptop_right[0] = new Surface(datadir + "/images/shared/mriceblock-right-0.png", USE_ALPHA);
1146 img_laptop_right[1] = new Surface(datadir + "/images/shared/mriceblock-right-1.png", USE_ALPHA);
1147 img_laptop_right[2] = new Surface(datadir + "/images/shared/mriceblock-right-2.png", USE_ALPHA);
1148 img_laptop_right[3] = new Surface(datadir + "/images/shared/mriceblock-right-1.png", USE_ALPHA);
1150 img_laptop_flat_left[0] = new Surface(
1151 datadir + "/images/shared/laptop-flat-left.png",
1154 img_laptop_flat_right[0] = new Surface(datadir +
1155 "/images/shared/laptop-flat-right.png",
1158 img_laptop_falling_left[0] = new Surface(datadir +
1159 "/images/shared/laptop-falling-left.png",
1162 img_laptop_falling_right[0] = new Surface(datadir +
1163 "/images/shared/laptop-falling-right.png",
1168 img_jumpy_left_up = new Surface(datadir +
1169 "/images/shared/jumpy-left-up-0.png",
1171 img_jumpy_left_down = new Surface(datadir +
1172 "/images/shared/jumpy-left-down-0.png",
1174 img_jumpy_left_middle = new Surface(datadir +
1175 "/images/shared/jumpy-left-middle-0.png",
1179 for(int i=0; i<4; ++i) {
1181 snprintf(num, 4, "%d", i);
1182 img_mrbomb_left[i] = new Surface(
1183 datadir + "/images/shared/mrbomb-left-" + num + ".png", USE_ALPHA);
1184 img_mrbomb_right[i] = new Surface(
1185 datadir + "/images/shared/mrbomb-right-" + num + ".png", USE_ALPHA);
1187 img_mrbomb_ticking_left[0] = new Surface(
1188 datadir + "/images/shared/mrbombx-left-0.png", USE_ALPHA);
1189 img_mrbomb_ticking_right[0] = new Surface(
1190 datadir + "/images/shared/mrbombx-right-0.png", USE_ALPHA);
1191 img_mrbomb_explosion[0] = new Surface(
1192 datadir + "/images/shared/mrbomb-explosion.png", USE_ALPHA);
1195 img_stalactite[0] = new Surface(
1196 datadir + "/images/shared/stalactite.png", USE_ALPHA);
1197 img_stalactite_broken[0] = new Surface(
1198 datadir + "/images/shared/stalactite-broken.png", USE_ALPHA);
1201 img_flame[0] = new Surface(
1202 datadir + "/images/shared/flame-0.png", USE_ALPHA);
1203 img_flame[1] = new Surface(
1204 datadir + "/images/shared/flame-1.png", USE_ALPHA);
1207 img_fish[0] = new Surface(
1208 datadir + "/images/shared/fish-left-0.png", USE_ALPHA);
1209 img_fish[1] = new Surface(
1210 datadir + "/images/shared/fish-left-1.png", USE_ALPHA);
1211 img_fish_down[0] = new Surface(
1212 datadir + "/images/shared/fish-down-0.png", USE_ALPHA);
1214 /* bouncing snowball */
1215 for(int i=0; i<6; ++i) {
1217 snprintf(num, 4, "%d", i);
1218 img_bouncingsnowball_left[i] = new Surface(
1219 datadir + "/images/shared/bouncingsnowball-left-" + num + ".png",
1221 img_bouncingsnowball_right[i] = new Surface(
1222 datadir + "/images/shared/bouncingsnowball-right-" + num + ".png",
1225 img_bouncingsnowball_squished[0] = new Surface(
1226 datadir + "/images/shared/bsod-squished-left.png", USE_ALPHA);
1228 /* flying snowball */
1229 img_flyingsnowball[0] = new Surface(
1230 datadir + "/images/shared/flyingsnowball-left-0.png", USE_ALPHA);
1231 img_flyingsnowball[1] = new Surface(
1232 datadir + "/images/shared/flyingsnowball-left-1.png", USE_ALPHA);
1233 img_flyingsnowball_squished[0] = new Surface(
1234 datadir + "/images/shared/bsod-squished-left.png", USE_ALPHA);
1237 for(int i = 0; i < 3; ++i) {
1239 snprintf(num, 4, "%d", i);
1240 img_spiky_left[i] = new Surface(
1241 datadir + "/images/shared/spiky-left-" + num + ".png",
1243 img_spiky_right[i] = new Surface(
1244 datadir + "/images/shared/spiky-right-" + num + ".png",
1249 img_snowball_left[0] = new Surface(datadir + "/images/shared/snowball-left-0.png", USE_ALPHA);
1250 img_snowball_left[1] = new Surface(datadir + "/images/shared/snowball-left-1.png", USE_ALPHA);
1251 img_snowball_left[2] = new Surface(datadir + "/images/shared/snowball-left-2.png", USE_ALPHA);
1252 img_snowball_left[3] = new Surface(datadir + "/images/shared/snowball-left-1.png", USE_ALPHA);
1254 img_snowball_right[0] = new Surface(datadir + "/images/shared/snowball-right-0.png", USE_ALPHA);
1255 img_snowball_right[1] = new Surface(datadir + "/images/shared/snowball-right-1.png", USE_ALPHA);
1256 img_snowball_right[2] = new Surface(datadir + "/images/shared/snowball-right-2.png", USE_ALPHA);
1257 img_snowball_right[3] = new Surface(datadir + "/images/shared/snowball-right-1.png", USE_ALPHA);
1259 img_snowball_squished_left[0] = new Surface(
1260 datadir + "/images/shared/bsod-squished-left.png", USE_ALPHA);
1261 img_snowball_squished_right[0] = new Surface(
1262 datadir + "/images/shared/bsod-squished-right.png", USE_ALPHA);
1266 void free_badguy_gfx()