From 34c5787d09b5d56664c13173dbafb6242a3d4e65 Mon Sep 17 00:00:00 2001 From: Christoph Sommer Date: Mon, 10 Jul 2006 00:48:50 +0000 Subject: [PATCH] Stay-on-platform Badguys no longer go crazy when falling down SVN-Revision: 3975 --- src/badguy/badguy.cpp | 24 ++++++++++++++++++++---- src/badguy/badguy.hpp | 13 +++++++++++++ src/badguy/igel.cpp | 4 +++- src/badguy/mrbomb.cpp | 4 +++- src/badguy/mriceblock.cpp | 10 +++++++--- src/badguy/mrtree.cpp | 4 +++- src/badguy/snail.cpp | 10 ++++++---- src/badguy/spiky.cpp | 4 +++- src/badguy/totem.cpp | 4 +++- 9 files changed, 61 insertions(+), 16 deletions(-) diff --git a/src/badguy/badguy.cpp b/src/badguy/badguy.cpp index 26db65d46..533a6aeab 100644 --- a/src/badguy/badguy.cpp +++ b/src/badguy/badguy.cpp @@ -34,7 +34,7 @@ static const float X_OFFSCREEN_DISTANCE = 1600; static const float Y_OFFSCREEN_DISTANCE = 1200; BadGuy::BadGuy(const Vector& pos, const std::string& sprite_name, int layer) - : MovingSprite(pos, sprite_name, layer, COLGROUP_DISABLED), countMe(true), dir(LEFT), start_dir(AUTO), state(STATE_INIT) + : MovingSprite(pos, sprite_name, layer, COLGROUP_DISABLED), countMe(true), dir(LEFT), start_dir(AUTO), state(STATE_INIT), on_ground_flag(false) { start_position = bbox.p1; @@ -43,7 +43,7 @@ BadGuy::BadGuy(const Vector& pos, const std::string& sprite_name, int layer) } BadGuy::BadGuy(const Vector& pos, Direction direction, const std::string& sprite_name, int layer) - : MovingSprite(pos, sprite_name, layer, COLGROUP_DISABLED), countMe(true), dir(direction), start_dir(direction), state(STATE_INIT) + : MovingSprite(pos, sprite_name, layer, COLGROUP_DISABLED), countMe(true), dir(direction), start_dir(direction), state(STATE_INIT), on_ground_flag(false) { start_position = bbox.p1; @@ -52,7 +52,7 @@ BadGuy::BadGuy(const Vector& pos, Direction direction, const std::string& sprite } BadGuy::BadGuy(const lisp::Lisp& reader, const std::string& sprite_name, int layer) - : MovingSprite(reader, sprite_name, layer, COLGROUP_DISABLED), countMe(true), dir(LEFT), start_dir(AUTO), state(STATE_INIT) + : MovingSprite(reader, sprite_name, layer, COLGROUP_DISABLED), countMe(true), dir(LEFT), start_dir(AUTO), state(STATE_INIT), on_ground_flag(false) { start_position = bbox.p1; @@ -114,6 +114,8 @@ BadGuy::update(float elapsed_time) movement = physic.get_movement(elapsed_time); break; } + + on_ground_flag = false; } Direction @@ -197,8 +199,9 @@ BadGuy::collision(GameObject& other, const CollisionHit& hit) } void -BadGuy::collision_solid(const CollisionHit& ) +BadGuy::collision_solid(const CollisionHit& hit) { + update_on_ground_flag(hit); } HitResponse @@ -407,3 +410,16 @@ BadGuy::get_nearest_player() return 0; } + +void +BadGuy::update_on_ground_flag(const CollisionHit& hit) +{ + if (hit.bottom) on_ground_flag = true; +} + +bool +BadGuy::on_ground() +{ + return on_ground_flag; +} + diff --git a/src/badguy/badguy.hpp b/src/badguy/badguy.hpp index 797cd44bf..44613e47f 100644 --- a/src/badguy/badguy.hpp +++ b/src/badguy/badguy.hpp @@ -165,11 +165,24 @@ protected: */ Direction str2dir( std::string dir_str ); + /** + * Update on_ground_flag judging by solid collision @c hit. + * This gets called from the base implementation of collision_solid, so call this when overriding collision_solid's default behaviour. + */ + void update_on_ground_flag(const CollisionHit& hit); + + /** + * Returns true if we touched ground in the past frame + * This only works if update_on_ground_flag() gets called in collision_solid. + */ + bool on_ground(); + private: void try_activate(); State state; Timer state_timer; + bool on_ground_flag; }; #endif diff --git a/src/badguy/igel.cpp b/src/badguy/igel.cpp index 02b716342..0d305e502 100644 --- a/src/badguy/igel.cpp +++ b/src/badguy/igel.cpp @@ -94,7 +94,7 @@ Igel::active_update(float elapsed_time) switch (state) { case STATE_NORMAL: - if (might_fall()) { + if (on_ground() && might_fall()) { // turn around when we are at a ledge turn_around(); } @@ -118,6 +118,8 @@ Igel::active_update(float elapsed_time) void Igel::collision_solid(const CollisionHit& hit) { + update_on_ground_flag(hit); + if(hit.top || hit.bottom) { // floor or roof physic.set_velocity_y(0); return; diff --git a/src/badguy/mrbomb.cpp b/src/badguy/mrbomb.cpp index d59b9582a..78cb5b726 100644 --- a/src/badguy/mrbomb.cpp +++ b/src/badguy/mrbomb.cpp @@ -68,7 +68,7 @@ MrBomb::activate() void MrBomb::active_update(float elapsed_time) { - if (might_fall()) + if (on_ground() && might_fall()) { dir = (dir == LEFT ? RIGHT : LEFT); sprite->set_action(dir == LEFT ? "left" : "right"); @@ -90,6 +90,8 @@ MrBomb::collision_squished(Player& player) void MrBomb::collision_solid(const CollisionHit& hit) { + update_on_ground_flag(hit); + if(hit.bottom || hit.top) { physic.set_velocity_y(0); } diff --git a/src/badguy/mriceblock.cpp b/src/badguy/mriceblock.cpp index aa91c5aae..09f2bb096 100644 --- a/src/badguy/mriceblock.cpp +++ b/src/badguy/mriceblock.cpp @@ -73,7 +73,7 @@ MrIceBlock::active_update(float elapsed_time) set_state(ICESTATE_NORMAL); } - if (ice_state == ICESTATE_NORMAL && might_fall(601)) + if (ice_state == ICESTATE_NORMAL && on_ground() && might_fall(601)) { dir = (dir == LEFT ? RIGHT : LEFT); sprite->set_action(dir == LEFT ? "left" : "right"); @@ -86,6 +86,8 @@ MrIceBlock::active_update(float elapsed_time) void MrIceBlock::collision_solid(const CollisionHit& hit) { + update_on_ground_flag(hit); + if(hit.top || hit.bottom) { // floor or roof physic.set_velocity_y(0); return; @@ -96,11 +98,13 @@ MrIceBlock::collision_solid(const CollisionHit& hit) case ICESTATE_NORMAL: if(hit.right && dir == RIGHT) { dir = LEFT; + sprite->set_action(dir == LEFT ? "left" : "right"); + physic.set_velocity_x(-physic.get_velocity_x()); } else if(hit.left && dir == LEFT) { dir = RIGHT; + sprite->set_action(dir == LEFT ? "left" : "right"); + physic.set_velocity_x(-physic.get_velocity_x()); } - sprite->set_action(dir == LEFT ? "left" : "right"); - physic.set_velocity_x(-physic.get_velocity_x()); break; case ICESTATE_KICKED: { #if 0 diff --git a/src/badguy/mrtree.cpp b/src/badguy/mrtree.cpp index 0e7970b9c..ed0d6d495 100644 --- a/src/badguy/mrtree.cpp +++ b/src/badguy/mrtree.cpp @@ -82,7 +82,7 @@ MrTree::active_update(float elapsed_time) activate(); } - if (might_fall() && !recently_changed_direction ) + if (on_ground() && might_fall() && !recently_changed_direction ) { recently_changed_direction = true; dir = (dir == LEFT ? RIGHT : LEFT); @@ -177,6 +177,8 @@ MrTree::collision_squished(Player& player) void MrTree::collision_solid(const CollisionHit& hit) { + update_on_ground_flag(hit); + if(hit.top || hit.bottom) { physic.set_velocity_y(0); } else { diff --git a/src/badguy/snail.cpp b/src/badguy/snail.cpp index bc00a4f40..0de7bfaab 100644 --- a/src/badguy/snail.cpp +++ b/src/badguy/snail.cpp @@ -108,12 +108,12 @@ Snail::active_update(float elapsed_time) switch (state) { case STATE_NORMAL: - if (might_fall(601)) { + if (on_ground() && might_fall(601)) { if( recently_changed_direction ) break; recently_changed_direction = true; - dir = (dir == LEFT ? RIGHT : LEFT); - sprite->set_action(dir == LEFT ? "left" : "right"); - physic.set_velocity_x(-physic.get_velocity_x()); + dir = (dir == LEFT ? RIGHT : LEFT); + sprite->set_action(dir == LEFT ? "left" : "right"); + physic.set_velocity_x(-physic.get_velocity_x()); } break; @@ -146,6 +146,8 @@ Snail::active_update(float elapsed_time) void Snail::collision_solid(const CollisionHit& hit) { + update_on_ground_flag(hit); + if(hit.top || hit.bottom) { // floor or roof physic.set_velocity_y(0); diff --git a/src/badguy/spiky.cpp b/src/badguy/spiky.cpp index befbd0531..44ef749c9 100644 --- a/src/badguy/spiky.cpp +++ b/src/badguy/spiky.cpp @@ -51,7 +51,7 @@ Spiky::active_update(float elapsed_time) { BadGuy::active_update(elapsed_time); - if (might_fall(601)) + if (on_ground() && might_fall(601)) { dir = (dir == LEFT ? RIGHT : LEFT); sprite->set_action(dir == LEFT ? "left" : "right"); @@ -62,6 +62,8 @@ Spiky::active_update(float elapsed_time) void Spiky::collision_solid(const CollisionHit& hit) { + update_on_ground_flag(hit); + if(hit.top || hit.bottom) { // hit floor or roof? physic.set_velocity_y(0); } else { // hit right or left diff --git a/src/badguy/totem.cpp b/src/badguy/totem.cpp index 2ee60f16a..2f1327d11 100644 --- a/src/badguy/totem.cpp +++ b/src/badguy/totem.cpp @@ -90,7 +90,7 @@ Totem::active_update(float elapsed_time) BadGuy::active_update(elapsed_time); if (!carried_by) { - if (might_fall()) + if (on_ground() && might_fall()) { dir = (dir == LEFT ? RIGHT : LEFT); activate(); @@ -154,6 +154,8 @@ Totem::collision_squished(Player& player) void Totem::collision_solid(const CollisionHit& hit) { + update_on_ground_flag(hit); + // if we are being carried around, pass event to bottom of stack and ignore it if (carried_by) { carried_by->collision_solid(hit); -- 2.11.0