X-Git-Url: https://git.verplant.org/?a=blobdiff_plain;f=src%2Fbadguy.cpp;h=ac0e59b0eac3557597b0a38be8405186ee8a6091;hb=03bc45b5d64e7295cb64a30116c9dbf90c0a0c7a;hp=b3ef65d1fb6f7e0567513d11606d8a720208831f;hpb=c5cbd36c2e01d8c807c8c931ca44fb7c1b48ad18;p=supertux.git diff --git a/src/badguy.cpp b/src/badguy.cpp index b3ef65d1f..ac0e59b0e 100644 --- a/src/badguy.cpp +++ b/src/badguy.cpp @@ -24,7 +24,7 @@ #include #include "app/globals.h" -#include "app/defines.h" +#include "defines.h" #include "special/sprite_manager.h" #include "utils/lispwriter.h" #include "badguy.h" @@ -34,6 +34,7 @@ #include "level.h" #include "sector.h" #include "tilemap.h" +#include "statistics.h" Sprite* img_mriceblock_flat_left; Sprite* img_mriceblock_flat_right; @@ -59,6 +60,8 @@ Sprite* img_fish; Sprite* img_fish_down; Sprite* img_fish_iced; Sprite* img_fish_iced_down; +Sprite* img_flamefish; +Sprite* img_flamefish_down; Sprite* img_bouncingsnowball_left; Sprite* img_bouncingsnowball_right; Sprite* img_bouncingsnowball_squished; @@ -93,6 +96,8 @@ BadGuyKind badguykind_from_string(const std::string& str) return BAD_FLAME; else if (str == "fish") return BAD_FISH; + else if (str == "flamefish") + return BAD_FLAMEFISH; else if (str == "bouncingsnowball") return BAD_BOUNCINGSNOWBALL; else if (str == "flyingsnowball") @@ -133,6 +138,9 @@ std::string badguykind_to_string(BadGuyKind kind) case BAD_FISH: return "fish"; break; + case BAD_FLAMEFISH: + return "flamefish"; + break; case BAD_BOUNCINGSNOWBALL: return "bouncingsnowball"; break; @@ -207,7 +215,7 @@ BadGuy::init() // if we're in a solid tile at start correct that now if(Sector::current()) { - if(kind != BAD_FLAME && kind != BAD_FISH && collision_object_map(base)) + if(kind != BAD_FLAME && kind != BAD_FISH && kind != BAD_FLAMEFISH && collision_object_map(base)) { std::cout << "Warning: badguy started in wall: kind: " << badguykind_to_string(kind) << " pos: (" << base.x << ", " << base.y << ")" << std::endl; @@ -281,6 +289,9 @@ BadGuy::activate(Direction activation_dir) } else if(kind == BAD_FISH) { set_sprite(img_fish, img_fish); physic.enable_gravity(true); + } else if(kind == BAD_FLAMEFISH) { + set_sprite(img_flamefish, img_flamefish); + physic.enable_gravity(true); } else if(kind == BAD_FLYINGSNOWBALL) { set_sprite(img_flyingsnowball, img_flyingsnowball); physic.enable_gravity(false); @@ -329,16 +340,23 @@ BadGuy::action_mriceblock(double elapsed_time) { /* FIXME: The pbad object shouldn't know about pplayer objects. */ /* If we're holding the iceblock */ dir = tux.dir; - if(dir==RIGHT) + if(tux.size == SMALL) { - base.x = tux.base.x + 16; - base.y = tux.base.y + tux.base.height/1.5 - base.height; + if(dir == RIGHT) + base.x = tux.base.x + 24; + else // dir == LEFT + base.x = tux.base.x - 12; + base.y = tux.base.y + tux.base.height/1.5 - base.height; } - else /* facing left */ + else // TUX == BIG { - base.x = tux.base.x - 16; - base.y = tux.base.y + tux.base.height/1.5 - base.height; + if(dir == RIGHT) + base.x = tux.base.x + 24; + else // dir == LEFT + base.x = tux.base.x - 4; + base.y = tux.base.y + tux.base.height/1.5 - base.height; } + if(collision_object_map(base)) { base.x = tux.base.x; @@ -348,9 +366,9 @@ BadGuy::action_mriceblock(double elapsed_time) if(tux.input.fire != DOWN) /* SHOOT! */ { if(dir == LEFT) - base.x -= 24; + base.x = tux.base.x - base.width; else - base.x += 24; + base.x = tux.base.x + tux.base.width; old_base = base; mode=KICK; @@ -387,20 +405,27 @@ void BadGuy::check_horizontal_bump(bool checkcliff) { float halfheight = base.height / 2; - if (dir == LEFT && issolid( base.x, (int) base.y + halfheight)) + if (dir == LEFT && issolid( base.x, base.y + halfheight)) { if (kind == BAD_MRICEBLOCK && mode == KICK) + { Sector::current()->trybreakbrick(Vector(base.x, base.y + halfheight), false); + Sector::current()->tryemptybox(Vector(base.x, base.y + halfheight), dir); + } dir = RIGHT; physic.set_velocity(-physic.get_velocity_x(), physic.get_velocity_y()); return; } - if (dir == RIGHT && issolid( base.x + base.width, (int)base.y + halfheight)) + if (dir == RIGHT && issolid( base.x + base.width, base.y + halfheight)) { if (kind == BAD_MRICEBLOCK && mode == KICK) + { Sector::current()->trybreakbrick( - Vector(base.x + base.width, (int) base.y + halfheight), false); + Vector(base.x + base.width, base.y + halfheight), false); + Sector::current()->tryemptybox( + Vector(base.x + base.width, base.y + halfheight), dir); + } dir = LEFT; physic.set_velocity(-physic.get_velocity_x(), physic.get_velocity_y()); @@ -658,7 +683,10 @@ BadGuy::action_fish(double elapsed_time) else if(mode == FISH_WAIT && !timer.check()) { // jump again - set_sprite(img_fish, img_fish); + if(kind == BAD_FISH) + set_sprite(img_fish, img_fish); + else // BAD_FLAMEFISH + set_sprite(img_flamefish, img_flamefish); mode = NORMAL; physic.set_velocity(0, JUMPV); physic.enable_gravity(true); @@ -669,7 +697,12 @@ BadGuy::action_fish(double elapsed_time) collision_swept_object_map(&old_base, &base); if(physic.get_velocity_y() < 0) - set_sprite(img_fish_down, img_fish_down); + { + if(kind == BAD_FISH) + set_sprite(img_fish_down, img_fish_down); + else // BAD_FLAMEFISH + set_sprite(img_flamefish_down, img_flamefish_down); + } } void @@ -818,29 +851,11 @@ BadGuy::action_wingling(double elapsed_time) void BadGuy::action_walkingtree(double elapsed_time) { - Player& tux = *Sector::current()->player; - Direction v_dir = physic.get_velocity_x() < 0 ? LEFT : RIGHT; - if (dying == DYING_NOT) check_horizontal_bump(); fall(); - if (mode == BGM_BIG && tux.dying == DYING_NOT) - { - if ((tux.base.x + tux.base.width/2 > base.x + base.width/2) && v_dir == LEFT) - { - dir = RIGHT; - physic.set_velocity_x(-physic.get_velocity_x()); - } - else if ((tux.base.x + tux.base.width/2 < base.x + base.width/2) && v_dir == RIGHT) - { - dir = LEFT; - physic.set_velocity_x(-physic.get_velocity_x()); - } - } - - physic.apply(elapsed_time, base.x, base.y, Sector::current()->gravity); if (dying != DYING_FALLING) collision_swept_object_map(&old_base,&base); @@ -931,6 +946,7 @@ BadGuy::action(float elapsed_time) break; case BAD_FISH: + case BAD_FLAMEFISH: action_fish(elapsed_time); break; @@ -1019,7 +1035,7 @@ BadGuy::bump() { // these can't be bumped if(kind == BAD_FLAME || kind == BAD_BOMB || kind == BAD_FISH - || kind == BAD_FLYINGSNOWBALL) + || kind == BAD_FLAMEFISH || kind == BAD_FLYINGSNOWBALL) return; physic.set_velocity_y(3); @@ -1032,7 +1048,7 @@ BadGuy::squish_me(Player* player) player->bounce(this); Sector::current()->add_score(Vector(base.x, base.y), - 50 * player_status.score_multiplier); + 25 * player_status.score_multiplier); SoundManager::get()->play_sound(IDToSound(SND_SQUISH), get_pos(), Sector::current()->player->get_pos()); player_status.score_multiplier++; @@ -1053,8 +1069,10 @@ BadGuy::squish(Player* player) player->bounce(this); Sector::current()->add_score(Vector(base.x, base.y), - 50 * player_status.score_multiplier); + 25 * player_status.score_multiplier); SoundManager::get()->play_sound(IDToSound(SND_SQUISH), get_pos(), Sector::current()->player->get_pos()); + + global_stats.add_points(BADGUYS_SQUISHED_STAT, 1); player_status.score_multiplier++; return; @@ -1097,7 +1115,7 @@ BadGuy::squish(Player* player) } return; - } else if(kind == BAD_FISH) { + } else if(kind == BAD_FISH || kind == BAD_FLAMEFISH) { // fish can only be killed when falling down if(physic.get_velocity_y() >= 0) return; @@ -1106,6 +1124,8 @@ BadGuy::squish(Player* player) Sector::current()->add_score(Vector(base.x, base.y), 25 * player_status.score_multiplier); + + global_stats.add_points(BADGUYS_SQUISHED_STAT, 1); player_status.score_multiplier++; // simply remove the fish... @@ -1131,11 +1151,18 @@ BadGuy::squish(Player* player) { set_sprite(img_walkingtree_left_small, img_walkingtree_left_small); physic.set_velocity_x(physic.get_velocity_x() * 2.0f); + + /* Move to the player's direction */ + if(dir != Sector::current()->player->dir) + physic.set_velocity_x(-physic.get_velocity_x()); + dir = Sector::current()->player->dir; + // XXX magic number: 66 is BGM_BIG height player->bounce(this); base.y += 66 - base.height; - + + global_stats.add_points(BADGUYS_SQUISHED_STAT, 1); Sector::current()->add_score(Vector(base.x, base.y), 25 * player_status.score_multiplier); player_status.score_multiplier++; @@ -1218,14 +1245,15 @@ BadGuy::collision(void *p_c_object, int c_object, CollisionType type) if(pbullet_c->kind == FIRE_BULLET) { - if (kind != BAD_BOMB && kind != BAD_STALACTITE && kind != BAD_FLAME) + if (kind != BAD_BOMB && kind != BAD_STALACTITE && kind != BAD_FLAME + && kind != BAD_FLAMEFISH) kill_me(10); } else if(pbullet_c->kind == ICE_BULLET) { - //if(kind == BAD_FLAME) - // kill_me(10); - //else + if(kind == BAD_FLAME || kind == BAD_FLAMEFISH) + kill_me(10); + else frozen_timer.start(FROZEN_TIME); } break; @@ -1257,7 +1285,7 @@ BadGuy::collision(void *p_c_object, int c_object, CollisionType type) pbad_c->explode(true); return; } - else if (pbad_c->kind != BAD_MRBOMB) + else { pbad_c->kill_me(50); } @@ -1285,7 +1313,8 @@ BadGuy::collision(void *p_c_object, int c_object, CollisionType type) // Jumpy, fish, flame, stalactites, wingling are exceptions if (pbad_c->kind == BAD_JUMPY || pbad_c->kind == BAD_FLAME - || pbad_c->kind == BAD_STALACTITE || pbad_c->kind == BAD_FISH) + || pbad_c->kind == BAD_STALACTITE || pbad_c->kind == BAD_FISH + || pbad_c->kind == BAD_FLAMEFISH) break; // Bounce off of other badguy if we land on top of him @@ -1314,9 +1343,10 @@ BadGuy::collision(void *p_c_object, int c_object, CollisionType type) dir = RIGHT; physic.set_velocity_x(fabsf(physic.get_velocity_x())); - // in case badguys get "jammed" + // Put bad guys a part (or they get jammed) + // only needed to do to one of them if (physic.get_velocity_x() != 0) - base.x = pbad_c->base.x + pbad_c->base.width; + base.x = pbad_c->base.x + pbad_c->base.width + 1; } else if (dir == RIGHT) { @@ -1385,6 +1415,8 @@ void load_badguy_gfx() img_fish_down = sprite_manager->load("fish-down"); img_fish_iced = sprite_manager->load("fish-iced"); img_fish_iced_down = sprite_manager->load("fish-iced-down"); + img_flamefish = sprite_manager->load("flamefish"); + img_flamefish_down = sprite_manager->load("flamefish-down"); img_bouncingsnowball_left = sprite_manager->load("bouncingsnowball-left"); img_bouncingsnowball_right = sprite_manager->load("bouncingsnowball-right"); img_bouncingsnowball_squished = sprite_manager->load("bouncingsnowball-squished");