From: Tobias Gläßer Date: Fri, 26 Mar 2004 23:53:31 +0000 (+0000) Subject: merged bad_guy patch from Matze Braun. (recycling Ricardo's stalactite patch and... X-Git-Url: https://git.verplant.org/?a=commitdiff_plain;h=34145c1911171da557faac38278c1ba56bb5e201;p=supertux.git merged bad_guy patch from Matze Braun. (recycling Ricardo's stalactite patch and added mrbomb). SVN-Revision: 382 --- diff --git a/src/Makefile.am b/src/Makefile.am index 56d458a16..19e60fe17 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,6 +1,6 @@ bin_PROGRAMS = supertux -supertux_SOURCES = badguy.cpp badguy.h bitmask.cpp bitmask.h button.cpp button.h collision.cpp collision.h configfile.cpp configfile.h defines.h gameloop.cpp gameloop.h globals.cpp globals.h high_scores.cpp high_scores.h intro.cpp intro.h level.cpp level.h leveleditor.cpp leveleditor.h lispreader.cpp lispreader.h menu.cpp menu.h particlesystem.cpp particlesystem.h physic.cpp physic.h player.cpp player.h scene.cpp scene.h screen.cpp screen.h setup.cpp setup.h sound.cpp sound.h special.cpp special.h supertux.cpp supertux.h text.cpp text.h texture.cpp texture.h timer.cpp timer.h title.cpp title.h type.cpp type.h world.cpp world.h worldmap.cpp worldmap.h tile.h tile.cpp +supertux_SOURCES = badguy.cpp badguy.h bitmask.cpp bitmask.h button.cpp button.h collision.cpp collision.h configfile.cpp configfile.h defines.h gameloop.cpp gameloop.h globals.cpp globals.h high_scores.cpp high_scores.h intro.cpp intro.h level.cpp level.h leveleditor.cpp leveleditor.h lispreader.cpp lispreader.h menu.cpp menu.h particlesystem.cpp particlesystem.h physic.cpp physic.h player.cpp player.h scene.cpp scene.h screen.cpp screen.h setup.cpp setup.h sound.cpp sound.h special.cpp special.h supertux.cpp supertux.h text.cpp text.h texture.cpp texture.h timer.cpp timer.h title.cpp title.h type.cpp type.h world.cpp world.h worldmap.cpp worldmap.h tile.h tile.cpp mousecursor.cpp mousecursor.h # EOF # noinst_HEADERS = diff --git a/src/badguy.cpp b/src/badguy.cpp index 2b603a469..611ddcfd0 100644 --- a/src/badguy.cpp +++ b/src/badguy.cpp @@ -30,6 +30,10 @@ texture_type img_laptop_left[3]; texture_type img_laptop_right[3]; texture_type img_money_left[2]; texture_type img_money_right[2]; +texture_type img_mrbomb_left[4]; +texture_type img_mrbomb_right[4]; +texture_type img_stalactite; +texture_type img_stalactite_broken; BadGuyKind badguykind_from_string(const std::string& str) { @@ -39,6 +43,10 @@ BadGuyKind badguykind_from_string(const std::string& str) return BAD_LAPTOP; else if (str == "bsod") return BAD_BSOD; + else if (str == "mrbomb") + return BAD_MRBOMB; + else if (str == "stalactite") + return BAD_STALACTITE; else { printf("Couldn't convert badguy: %s\n", str.c_str()); @@ -59,6 +67,12 @@ std::string badguykind_to_string(BadGuyKind kind) case BAD_BSOD: return "bsod"; break; + case BAD_MRBOMB: + return "mrbomb"; + break; + case BAD_STALACTITE: + return "stalactite"; + break; default: return "bsod"; } @@ -74,13 +88,20 @@ BadGuy::init(float x, float y, BadGuyKind kind_) kind = kind_; base.x = x; base.y = y; - base.xm = 1.3; + base.xm = -1.3; base.ym = 4.8; old_base = base; dir = LEFT; seen = false; timer_init(&timer, true); physic_init(&physic); + + if(kind == BAD_BOMB) { + timer_start(&timer, 1000); + mode = BOMB_TICKING; + // hack so that the bomb doesn't hurt until it expldes... + dying = DYING_SQUISHED; + } } void BadGuy::action_bsod() @@ -91,10 +112,7 @@ void BadGuy::action_bsod() if (dying == DYING_NOT || dying == DYING_FALLING) { - if (dir == RIGHT) - base.x = base.x + base.xm * frame_ratio; - else if (dir == LEFT) - base.x = base.x - base.xm * frame_ratio; + base.x += base.xm * frame_ratio; } /* Move vertically: */ @@ -102,61 +120,21 @@ void BadGuy::action_bsod() if (dying != DYING_FALLING) collision_swept_object_map(&old_base,&base); - if (base.y > screen->h) - bad_guys.erase(static_cast::iterator>(this)); - /* Bump into things horizontally: */ - if (!dying) - { - if (issolid( base.x, (int) base.y + 16)) - { - dir = RIGHT; - } - else if (issolid( base.x + base.width, (int) base.y + 16)) - { - dir = LEFT; - } - } - - /* Fall if we get off the ground: */ - if (dying != DYING_FALLING) - { - if (!issolid(base.x+16, base.y + 32)) - { - if(!physic_is_set(&physic)) - { - physic_set_state(&physic,PH_VT); - physic_set_start_vy(&physic,2.); - } + check_horizontal_bump(); - base.ym = physic_get_velocity(&physic); - } - else - { - /* Land: */ + fall(); - if (base.ym > 0) - { - base.y = (int)(base.y / 32) * 32; - base.ym = 0; - } - physic_init(&physic); - } - } - else + // Handle dying timer: + if (dying == DYING_SQUISHED) { - if(!physic_is_set(&physic)) - { - physic_set_state(&physic,PH_VT); - physic_set_start_vy(&physic,2.); - } - base.ym = physic_get_velocity(&physic); + /* Remove it if time's up: */ + if(!timer_check(&timer)) { + remove_me(); + return; + } } - - // BadGuy fall below the ground - if (base.y > screen->h) - bad_guys.erase(static_cast::iterator>(this)); } void BadGuy::action_laptop() @@ -167,10 +145,7 @@ void BadGuy::action_laptop() if (dying == DYING_NOT || dying == DYING_FALLING) { - if (dir == RIGHT) - base.x = base.x + base.xm * frame_ratio; - else if (dir == LEFT) - base.x = base.x - base.xm * frame_ratio; + base.x += base.xm * frame_ratio; } } else if (mode == HELD) @@ -214,37 +189,79 @@ void BadGuy::action_laptop() if (dying != DYING_FALLING) collision_swept_object_map(&old_base,&base); - if (base.y > screen->h) - bad_guys.erase(static_cast::iterator>(this)); - /* Bump into things horizontally: */ - /* Bump into things horizontally: */ if (!dying) { int changed = dir; - if (issolid( base.x, (int) base.y + 16)) - { - dir = RIGHT; - } - else if (issolid( base.x + base.width, (int) base.y + 16)) - { - dir = LEFT; - } + check_horizontal_bump(); if(mode == KICK && changed != dir) { - /* handle stereo sound */ - /* FIXME: In theory a badguy object doesn't know anything about player objects */ - if (tux.base.x > base.x) + /* handle stereo sound (number 10 should be tweaked...)*/ + if (base.x < scroll_x - 10) play_sound(sounds[SND_RICOCHET], SOUND_LEFT_SPEAKER); - else if (tux.base.x < base.x) + else if (base.x > scroll_x + 10) play_sound(sounds[SND_RICOCHET], SOUND_RIGHT_SPEAKER); else play_sound(sounds[SND_RICOCHET], SOUND_CENTER_SPEAKER); } + } + + fall(); + /* Handle mode timer: */ + if (mode == FLAT && mode != HELD) + { + if(!timer_check(&timer)) + { + mode = NORMAL; + base.xm = 4; + } + } + else if (mode == KICK) + { + timer_check(&timer); } +} +void BadGuy::check_horizontal_bump(bool checkcliff) +{ + if (dir == LEFT && issolid( base.x, (int) base.y + 16)) + { + dir = RIGHT; + base.xm = -base.xm; + return; + } + if (dir == RIGHT && issolid( base.x + base.width, (int) base.y + 16)) + { + dir = LEFT; + base.xm = -base.xm; + return; + } + + // don't check for cliffs when we're falling + if(!checkcliff) + return; + + if(dir == LEFT && !issolid(base.x, (int) base.y + base.height + 16)) + { + printf("Cliffcol left\n"); + dir = RIGHT; + base.xm = -base.xm; + return; + } + if(dir == RIGHT && !issolid(base.x + base.width, + (int) base.y + base.height + 16)) + { + printf("Cliffcol right\n"); + dir = LEFT; + base.xm = -base.xm; + return; + } +} + +void BadGuy::fall() +{ /* Fall if we get off the ground: */ if (dying != DYING_FALLING) { @@ -276,12 +293,29 @@ void BadGuy::action_laptop() else { if(!physic_is_set(&physic)) - { + { physic_set_state(&physic,PH_VT); physic_set_start_vy(&physic,0.); } base.ym = physic_get_velocity(&physic); } + + // BadGuy fall below the ground + if (base.y > screen->h) { + remove_me(); + return; + } +} + +void BadGuy::remove_me() +{ + std::vector::iterator i; + for(i = bad_guys.begin(); i != bad_guys.end(); ++i) { + if( & (*i) == this) { + bad_guys.erase(i); + return; + } + } } void BadGuy::action_money() @@ -292,8 +326,10 @@ void BadGuy::action_money() if (dying != DYING_FALLING) collision_swept_object_map(&old_base,&base); - if (base.y > screen->h) - bad_guys.erase(static_cast::iterator>(this)); + if (base.y > screen->h) { + remove_me(); + return; + } if(physic_get_state(&physic) == -1) { @@ -303,19 +339,21 @@ void BadGuy::action_money() if (dying != DYING_FALLING) { + if(issolid(base.x, base.y + 32)) { physic_set_state(&physic,PH_VT); physic_set_start_vy(&physic,6.); base.ym = physic_get_velocity(&physic); } + /* // matze: is this code needed? else if(issolid(base.x, base.y)) - { /* This works, but isn't the best solution imagineable */ + { // This works, but isn't the best solution imagineable physic_set_state(&physic,PH_VT); physic_set_start_vy(&physic,0.); base.ym = physic_get_velocity(&physic); ++base.y; - } + }*/ else { base.ym = physic_get_velocity(&physic); @@ -332,6 +370,65 @@ void BadGuy::action_money() } } +void BadGuy::action_mrbomb() +{ + if(mode == NORMAL) { + base.x += base.xm * frame_ratio; + } + + /* Move vertically: */ + base.y += base.ym * frame_ratio; + + if (dying != DYING_FALLING) + collision_swept_object_map(&old_base,&base); + + check_horizontal_bump(true); + fall(); +} + +void BadGuy::action_bomb() +{ + // eventually fall down + base.y += base.ym * frame_ratio; + collision_swept_object_map(&old_base,&base); + fall(); + + if(!timer_check(&timer)) { + if(mode == BOMB_TICKING) { + mode = BOMB_EXPLODE; + dying = DYING_NOT; // now the bomb hurts + timer_start(&timer, 1000); + } else if(mode == BOMB_EXPLODE) { + remove_me(); + return; + } + } +} + +void BadGuy::action_stalactite() +{ + if(mode == NORMAL) { + if(tux.base.x + 32 > base.x - 40 && tux.base.x < base.x + 32 + 40) { + timer_start(&timer, 800); + mode = STALACTITE_SHAKING; + } + } if(mode == STALACTITE_SHAKING) { + base.x = old_base.x + (rand() % 6) - 3; // TODO this could be done nicer... + if(!timer_check(&timer)) { + mode = STALACTITE_FALL; + } + } else if(mode == STALACTITE_FALL) { + base.y += base.ym * frame_ratio; + /* Destroy if collides land */ + if(issolid(base.x+16, base.y+32)) + { + timer_start(&timer, 3000); + dying = DYING_SQUISHED; + mode = FLAT; + } + } +} + void BadGuy::action() { @@ -344,41 +441,32 @@ BadGuy::action() break; case BAD_LAPTOP: - action_bsod(); + action_laptop(); break; case BAD_MONEY: action_money(); break; - } - } - /* Handle mode timer: */ - if (mode == FLAT && mode != HELD) - { - if(!timer_check(&timer)) - { - mode = NORMAL; - base.xm = 4; - } - } - else if (mode == KICK) - { - timer_check(&timer); - } + case BAD_MRBOMB: + action_mrbomb(); + break; + + case BAD_BOMB: + action_bomb(); + break; - // Handle dying timer: - if (dying == DYING_SQUISHED) - { - /* Remove it if time's up: */ - if(!timer_check(&timer)) - bad_guys.erase(static_cast::iterator>(this)); + case BAD_STALACTITE: + action_stalactite(); + break; + + } } // Remove if it's far off the screen: if (base.x < scroll_x - OFFSCREEN_DISTANCE) { - bad_guys.erase(static_cast::iterator>(this)); + remove_me(); return; } else /* !seen */ @@ -392,154 +480,103 @@ BadGuy::action() void BadGuy::draw_bsod() { - /* --- BLUE SCREEN OF DEATH MONSTER: --- */ - if (dying == DYING_NOT) - { - /* Alive: */ - if (dir == LEFT) - { - texture_draw(&img_bsod_left[(global_frame_counter / 5) % 4], - base.x - scroll_x, - base.y); - } - else - { - texture_draw(&img_bsod_right[(global_frame_counter / 5) % 4], - base.x - scroll_x, - base.y); - } - } - else if (dying == DYING_FALLING) - { - /* Falling: */ + texture_type* texture = 0; + float y = base.y; + if(dying == DYING_NOT) { + size_t frame = (global_frame_counter / 5) % 4; + texture = (dir == LEFT) ? &img_bsod_left[frame] : &img_bsod_right[frame]; + } else if(dying == DYING_FALLING) { + texture = (dir == LEFT) ? &img_bsod_falling_left : &img_bsod_falling_right; + } else if(dying == DYING_SQUISHED) { + texture = (dir == LEFT) + ? &img_bsod_squished_left : &img_bsod_squished_right; + y += 24; + } + + texture_draw(texture, base.x - scroll_x, y); +} - if (dir == LEFT) - { - texture_draw(&img_bsod_falling_left, - base.x - scroll_x, - base.y); - } +void +BadGuy::draw_laptop() +{ + texture_type* texture; + size_t frame = (global_frame_counter / 5) % 3; + + if(dying == DYING_NOT) { + if(mode == NORMAL) { + if(dir == LEFT) + texture = &img_laptop_left[frame]; else - { - texture_draw(&img_bsod_falling_right, - base.x - scroll_x, - base.y); - } + texture = &img_laptop_right[frame]; + } else { + texture = (dir == LEFT) ? &img_laptop_flat_left : &img_laptop_flat_right; } - else if (dying == DYING_SQUISHED) - { - /* Dying - Squished: */ + } else { + texture = (dir == LEFT) + ? &img_laptop_falling_left : &img_laptop_falling_right; + } - if (dir == LEFT) - { - texture_draw(&img_bsod_squished_left, - base.x - scroll_x, - base.y + 24); - } - else - { - texture_draw(&img_bsod_squished_right, - base.x - scroll_x, - base.y + 24); - } - } + texture_draw(texture, base.x - scroll_x, base.y); } -void BadGuy::draw_laptop() +void +BadGuy::draw_money() { - /* --- LAPTOP MONSTER: --- */ - if (dying == DYING_NOT) - { - /* Alive: */ + texture_type* texture; + size_t frame = (base.ym != 300) ? 0 : 1; - if (mode == NORMAL) - { - /* Not flat: */ - if (dir == LEFT) - { - texture_draw(&img_laptop_left[(global_frame_counter / 5) % 3], - base.x - scroll_x, - base.y); - } - else - { - texture_draw(&img_laptop_right[(global_frame_counter / 5) % 3], - base.x - scroll_x, - base.y); - } - } - else - { - /* Flat: */ + if(tux.base.x + tux.base.width < base.x) { + texture = &img_money_left[frame]; + } else { + texture = &img_money_right[frame]; + } - if (dir == LEFT) - { - texture_draw(&img_laptop_flat_left, - base.x - scroll_x, - base.y); - } - else - { - texture_draw(&img_laptop_flat_right, - base.x - scroll_x, - base.y); - } - } - } - else if (dying == DYING_FALLING) - { - /* Falling: */ + texture_draw(texture, base.x - scroll_x, base.y); +} + +void +BadGuy::draw_mrbomb() +{ + texture_type* texture; + size_t frame = (global_frame_counter/5) % 4; - if (dir == LEFT) - { - texture_draw(&img_laptop_falling_left, - base.x - scroll_x, - base.y); - } - else - { - texture_draw(&img_laptop_falling_right, - base.x - scroll_x, - base.y); - } - } + if(dir == LEFT) + texture = &img_mrbomb_left[frame]; + else + texture = &img_mrbomb_right[frame]; + + texture_draw(texture, base.x - scroll_x, base.y); } -void BadGuy::draw_money() +void +BadGuy::draw_bomb() { - if (base.ym != 300 /* > -16*/) - { - if (dir == LEFT) - { - texture_draw(&img_money_left[0], - base.x - scroll_x, - base.y); - } - else - { - texture_draw(&img_money_right[0], - base.x - scroll_x, - base.y); - } - } + texture_type* texture; + + // TODO add real bomb graphics + if(mode == BOMB_TICKING) { + texture = &img_bsod_squished_right; + } else { + texture = &img_bsod_squished_left; + } + + texture_draw(texture, base.x - scroll_x, base.y); +} + +void +BadGuy::draw_stalactite() +{ + texture_type* texture; + if(mode != FLAT) + texture = &img_stalactite; else - { - if (dir == LEFT) - { - texture_draw(&img_money_left[1], - base.x - scroll_x, - base.y); - } - else - { - texture_draw(&img_money_right[1], - base.x - scroll_x, - base.y); - } - } + texture = &img_stalactite_broken; + + texture_draw(texture, base.x - scroll_x, base.y); } -void BadGuy::draw() +void +BadGuy::draw() { // Don't try to draw stuff that is outside of the screen if (base.x > scroll_x - 32 && @@ -559,22 +596,120 @@ void BadGuy::draw() draw_money(); break; - default: - puts("Unknown badguy type"); + case BAD_MRBOMB: + draw_mrbomb(); + break; + + case BAD_BOMB: + draw_bomb(); + break; + + case BAD_STALACTITE: + draw_stalactite(); break; } } } void -BadGuy::collision(void *p_c_object, int c_object) +BadGuy::bump() +{ + if(kind == BAD_BSOD || kind == BAD_LAPTOP || kind == BAD_BOMB) { + dying = DYING_FALLING; + base.ym = -8; + play_sound(sounds[SND_FALL], SOUND_CENTER_SPEAKER); + } +} + +void +BadGuy::make_player_jump(Player* player) +{ + physic_set_state(&player->vphysic,PH_VT); + physic_set_start_vy(&player->vphysic,2.); + player->base.y = base.y - player->base.height - 1; +} + +void +BadGuy::squich(Player* player) +{ + if(kind == BAD_MRBOMB) { + // mrbomb transforms into a bomb now + add_bad_guy(base.x, base.y, BAD_BOMB); + + make_player_jump(player); + add_score(base.x - scroll_x, base.y, 50 * score_multiplier); + play_sound(sounds[SND_SQUISH], SOUND_CENTER_SPEAKER); + score_multiplier++; + + remove_me(); + return; + + } else if(kind == BAD_BSOD) { + dying = DYING_SQUISHED; + timer_start(&timer,4000); + + make_player_jump(player); + + add_score(base.x - scroll_x, base.y, 50 * score_multiplier); + play_sound(sounds[SND_SQUISH], SOUND_CENTER_SPEAKER); + score_multiplier++; + return; + + } else if (kind == BAD_LAPTOP) { + if (mode == NORMAL || mode == KICK) + { + /* Flatten! */ + play_sound(sounds[SND_STOMP], SOUND_CENTER_SPEAKER); + mode = FLAT; + base.xm = 4; + + timer_start(&timer, 4000); + } else if (mode == FLAT) { + /* Kick! */ + play_sound(sounds[SND_KICK], SOUND_CENTER_SPEAKER); + + if (player->base.x < base.x + (base.width/2)) + dir = RIGHT; + else + dir = LEFT; + + base.xm = 5; + mode = KICK; + + timer_start(&timer,5000); + } + + make_player_jump(player); + + add_score(base.x - scroll_x, + base.y, + 25 * score_multiplier); + score_multiplier++; + return; + } +} + +void +BadGuy::collision(void *p_c_object, int c_object, CollisionType type) { BadGuy* pbad_c = NULL; - Player* pplayer_c = NULL; + + if(type == COLLISION_BUMP) { + bump(); + return; + } + if(type == COLLISION_SQUICH) { + Player* player = static_cast(p_c_object); + squich(player); + return; + } switch (c_object) { case CO_BULLET: + if(kind == BAD_BOMB || kind == BAD_STALACTITE) + return; + dying = DYING_FALLING; base.ym = -8; @@ -619,72 +754,7 @@ BadGuy::collision(void *p_c_object, int c_object) pbad_c->base.y, 100); } break; - - case CO_PLAYER: - pplayer_c = static_cast(p_c_object); - if(kind != BAD_MONEY) - { - if (kind == BAD_BSOD) - { - dying = DYING_SQUISHED; - timer_start(&timer,4000); - physic_set_state(&pplayer_c->vphysic,PH_VT); - physic_set_start_vy(&pplayer_c->vphysic,2.); - pplayer_c->base.y = base.y - pplayer_c->base.height - 1; - - add_score(base.x - scroll_x, base.y, - 50 * score_multiplier); - - play_sound(sounds[SND_SQUISH], SOUND_CENTER_SPEAKER); - } - else if (kind == BAD_LAPTOP) - { - - if (mode == NORMAL || mode == KICK) - { - /* Flatten! */ - - play_sound(sounds[SND_STOMP], SOUND_CENTER_SPEAKER); - mode = FLAT; - base.xm = 4; - - timer_start(&timer,10000); - - physic_set_state(&pplayer_c->vphysic,PH_VT); - physic_set_start_vy(&pplayer_c->vphysic,2.); - pplayer_c->base.y = base.y - pplayer_c->base.height - 1; - } - else if (mode == FLAT) - { - /* Kick! */ - play_sound(sounds[SND_KICK], SOUND_CENTER_SPEAKER); - - if (pplayer_c->base.x < base.x + (base.width/2)) - dir = RIGHT; - else - dir = LEFT; - - base.xm = 5; - mode = KICK; - - timer_start(&timer,5000); - } - - physic_set_state(&pplayer_c->vphysic,PH_VT); - physic_set_start_vy(&pplayer_c->vphysic,2.); - pplayer_c->base.y = base.y - pplayer_c->base.height - 1; - - add_score(base.x - scroll_x, - base.y, - 25 * score_multiplier); - - /* play_sound(sounds[SND_SQUISH]); */ - } - score_multiplier++; - } - break; } - } // EOF // diff --git a/src/badguy.h b/src/badguy.h index 6590fa654..ca4e16cca 100644 --- a/src/badguy.h +++ b/src/badguy.h @@ -22,10 +22,18 @@ #include "collision.h" /* Enemy modes: */ -#define NORMAL 0 -#define FLAT 1 -#define KICK 2 -#define HELD 3 +enum { + NORMAL=0, + FLAT, + KICK, + HELD, + + BOMB_TICKING, + BOMB_EXPLODE, + + STALACTITE_SHAKING, + STALACTITE_FALL +}; extern texture_type img_bsod_squished_left; extern texture_type img_bsod_squished_right; @@ -41,12 +49,19 @@ extern texture_type img_laptop_left[3]; extern texture_type img_laptop_right[3]; extern texture_type img_money_left[2]; extern texture_type img_money_right[2]; +extern texture_type img_mrbomb_left[4]; +extern texture_type img_mrbomb_right[4]; +extern texture_type img_stalactite; +extern texture_type img_stalactite_broken; /* Bad guy kinds: */ enum BadGuyKind { BAD_BSOD, BAD_LAPTOP, - BAD_MONEY + BAD_MONEY, + BAD_MRBOMB, + BAD_BOMB, + BAD_STALACTITE }; BadGuyKind badguykind_from_string(const std::string& str); @@ -65,6 +80,8 @@ struct BadGuyData : kind(BAD_BSOD), x(0), y(0) {} }; +class Player; + /* Badguy type: */ class BadGuy { @@ -85,6 +102,13 @@ class BadGuy void action(); void draw(); + void collision(void* p_c_object, int c_object, + CollisionType type = COLLISION_NORMAL); + + private: + void fall(); + void remove_me(); + void action_bsod(); void draw_bsod(); @@ -94,7 +118,19 @@ class BadGuy void action_money(); void draw_money(); - void collision(void* p_c_object, int c_object); + void action_bomb(); + void draw_bomb(); + + void action_mrbomb(); + void draw_mrbomb(); + + void action_stalactite(); + void draw_stalactite(); + + void make_player_jump(Player* player); + void check_horizontal_bump(bool checkcliff = false); + void bump(); + void squich(Player* player); }; #endif /*SUPERTUX_BADGUY_H*/ diff --git a/src/collision.cpp b/src/collision.cpp index afb4a921b..117d6c76e 100644 --- a/src/collision.cpp +++ b/src/collision.cpp @@ -250,10 +250,9 @@ void collision_handler() // We have detected a collision and now call the collision // functions of the collided objects. if (tux.previous_base.y < tux.base.y && - tux.previous_base.y + tux.previous_base.height < bad_guys[i].base.y + bad_guys[i].base.height/2 && - bad_guys[i].kind != BAD_MONEY && bad_guys[i].mode != HELD) + tux.previous_base.y + tux.previous_base.height < bad_guys[i].base.y + bad_guys[i].base.height/2) { - bad_guys[i].collision(&tux, CO_PLAYER); + bad_guys[i].collision(&tux, CO_PLAYER, COLLISION_SQUICH); } else { diff --git a/src/collision.h b/src/collision.h index 210559412..410e2e87e 100644 --- a/src/collision.h +++ b/src/collision.h @@ -19,10 +19,15 @@ enum { CO_BULLET, CO_BADGUY, - CO_BSOD, CO_PLAYER }; +enum CollisionType { + COLLISION_NORMAL, + COLLISION_BUMP, + COLLISION_SQUICH +}; + bool rectcollision(base_type* one, base_type* two); bool rectcollision_offset(base_type* one, base_type* two, float off_x, float off_y); void collision_swept_object_map(base_type* old, base_type* current); diff --git a/src/gameloop.cpp b/src/gameloop.cpp index 03e8f6e2d..4a8d7f299 100644 --- a/src/gameloop.cpp +++ b/src/gameloop.cpp @@ -110,7 +110,6 @@ void activate_bad_guys(void) void activate_particle_systems(void) { - printf("PSys: %s\n", current_level.particle_system.c_str()); if(current_level.particle_system == "clouds") { particle_systems.push_back(new CloudParticleSystem); @@ -1145,7 +1144,21 @@ void loadshared(void) "/images/shared/bag-right-1.png", USE_ALPHA); + /* Mr. Bomb */ + for(int i=0; i<4; ++i) { + char num[4]; + snprintf(num, 4, "%d", i); + texture_load(&img_mrbomb_left[i], + datadir + "/images/shared/mrbomb-left-" + num + ".png", USE_ALPHA); + texture_load(&img_mrbomb_right[i], + datadir + "/images/shared/mrbomb-right-" + num + ".png", USE_ALPHA); + } + /* stalactite */ + texture_load(&img_stalactite, + datadir + "/images/shared/stalactite.png", USE_ALPHA); + texture_load(&img_stalactite_broken, + datadir + "/images/shared/stalactite-broken.png", USE_ALPHA); /* Upgrades: */ @@ -1272,6 +1285,14 @@ void unloadshared(void) texture_free(&img_money_right[i]); } + for(i = 0; i < 4; i++) { + texture_free(&img_mrbomb_left[i]); + texture_free(&img_mrbomb_right[i]); + } + + texture_free(&img_stalactite); + texture_free(&img_stalactite_broken); + texture_free(&img_box_full); texture_free(&img_box_empty); @@ -1625,13 +1646,7 @@ void trybumpbadguy(float x, float y) if (bad_guys[i].base.x >= x - 32 && bad_guys[i].base.x <= x + 32 && bad_guys[i].base.y >= y - 16 && bad_guys[i].base.y <= y + 16) { - if (bad_guys[i].kind == BAD_BSOD || - bad_guys[i].kind == BAD_LAPTOP) - { - bad_guys[i].dying = DYING_FALLING; - bad_guys[i].base.ym = -8; - play_sound(sounds[SND_FALL], SOUND_CENTER_SPEAKER); - } + bad_guys[i].collision(&tux, CO_PLAYER, COLLISION_BUMP); } } diff --git a/src/leveleditor.cpp b/src/leveleditor.cpp index 0cb0282a8..a7fc46f3c 100644 --- a/src/leveleditor.cpp +++ b/src/leveleditor.cpp @@ -90,7 +90,7 @@ static int le_show_grid; static int le_frame; static texture_type le_selection; static int done; -static char le_current_tile; +static unsigned int le_current_tile; static bool le_mouse_pressed[2]; static button_type le_save_level_bt; static button_type le_test_level_bt; @@ -382,7 +382,7 @@ int le_init() le_level_changed = false; le_current_level = NULL; - le_current_tile = '.'; + le_current_tile = 0; le_mouse_pressed[LEFT] = false; le_mouse_pressed[RIGHT] = false; @@ -1086,7 +1086,7 @@ void le_checkevents() } button_event(&le_rubber_bt,&event); if(button_get_state(&le_rubber_bt) == BUTTON_CLICKED) - le_current_tile = '.'; + le_current_tile = 0; button_event(&le_select_mode_one_bt,&event); if(button_get_state(&le_select_mode_one_bt) == BUTTON_CLICKED) le_selection_mode = CURSOR; diff --git a/src/particlesystem.cpp b/src/particlesystem.cpp index db1ca26c3..2003024ec 100644 --- a/src/particlesystem.cpp +++ b/src/particlesystem.cpp @@ -82,7 +82,10 @@ SnowParticleSystem::SnowParticleSystem() particle->layer = i % 2; int snowsize = rand() % 3; particle->texture = &snowimages[snowsize]; - particle->speed = 0.01 + snowsize/50.0 + (rand()%(int)gravity/15.0); + do { + particle->speed = snowsize/60.0 + (float(rand()%10)/300.0); + } while(particle->speed < 0.01); + particle->speed *= gravity; particles.push_back(particle); } @@ -111,13 +114,13 @@ CloudParticleSystem::CloudParticleSystem() { texture_load(&cloudimage, datadir + "/images/shared/cloud.png", USE_ALPHA); - virtual_width = 5000.0; + virtual_width = 2000.0; // create some random clouds for(size_t i=0; i<15; ++i) { CloudParticle* particle = new CloudParticle; particle->x = rand() % int(virtual_width); - particle->y = rand() % int((float) screen->h * 0.3333); + particle->y = rand() % int(virtual_height); particle->layer = 0; particle->texture = &cloudimage; particle->speed = -float(250 + rand() % 200) / 1000.0; diff --git a/src/player.cpp b/src/player.cpp index 9f04006f3..f20884403 100644 --- a/src/player.cpp +++ b/src/player.cpp @@ -164,7 +164,7 @@ Player::action() base.x += base.xm * frame_ratio; base.y += base.ym * frame_ratio; - + collision_swept_object_map(&old_base,&base); keep_in_bounds(); @@ -190,11 +190,9 @@ Player::action() } } base.ym = physic_get_velocity(&vphysic); - } else { - /* Land: */ if (base.ym > 0) diff --git a/src/type.h b/src/type.h index e450ecd99..454e0826c 100644 --- a/src/type.h +++ b/src/type.h @@ -27,6 +27,7 @@ struct base_type float height; }; + struct string_list_type { int num_items;