From 22ebbf03379aad8d3fc704e47e6cfa7acca8651d Mon Sep 17 00:00:00 2001 From: Christoph Sommer Date: Sat, 4 Nov 2006 14:13:27 +0000 Subject: [PATCH] Badguys squish badguys. Badguys keep track of floor normal they are standing on. SVN-Revision: 4435 --- src/badguy/badguy.cpp | 54 ++++++++++++++++++++++++++++------------ src/badguy/badguy.hpp | 13 +++++++--- src/badguy/bouncing_snowball.cpp | 4 +-- src/badguy/bouncing_snowball.hpp | 2 +- src/badguy/dispenser.cpp | 7 +++--- src/badguy/dispenser.hpp | 2 +- src/badguy/flyingsnowball.cpp | 4 +-- src/badguy/flyingsnowball.hpp | 2 +- src/badguy/igel.cpp | 6 ++--- src/badguy/igel.hpp | 2 +- src/badguy/mole.cpp | 2 +- src/badguy/mole.hpp | 2 +- src/badguy/mrbomb.cpp | 8 +++--- src/badguy/mrbomb.hpp | 2 +- src/badguy/mriceblock.cpp | 16 +++++++----- src/badguy/mriceblock.hpp | 2 +- src/badguy/mrrocket.cpp | 4 +-- src/badguy/mrrocket.hpp | 2 +- src/badguy/mrtree.cpp | 7 +++--- src/badguy/mrtree.hpp | 2 +- src/badguy/poisonivy.cpp | 4 +-- src/badguy/poisonivy.hpp | 2 +- src/badguy/skullyhop.cpp | 4 +-- src/badguy/skullyhop.hpp | 2 +- src/badguy/snail.cpp | 17 +++++++------ src/badguy/snail.hpp | 2 +- src/badguy/snowball.cpp | 4 +-- src/badguy/snowball.hpp | 2 +- src/badguy/spidermite.cpp | 4 +-- src/badguy/spidermite.hpp | 2 +- src/badguy/stumpy.cpp | 11 ++++---- src/badguy/stumpy.hpp | 2 +- src/badguy/toad.cpp | 4 +-- src/badguy/toad.hpp | 2 +- src/badguy/totem.cpp | 7 +++--- src/badguy/totem.hpp | 2 +- src/badguy/walking_badguy.cpp | 9 ++++--- src/badguy/walkingleaf.cpp | 8 +++--- src/badguy/walkingleaf.hpp | 2 +- src/badguy/yeti.cpp | 13 ++++++---- src/badguy/yeti.hpp | 4 +-- src/badguy/zeekling.cpp | 4 +-- src/badguy/zeekling.hpp | 2 +- 43 files changed, 151 insertions(+), 105 deletions(-) diff --git a/src/badguy/badguy.cpp b/src/badguy/badguy.cpp index 8d9ae8cc4..75e59d348 100644 --- a/src/badguy/badguy.cpp +++ b/src/badguy/badguy.cpp @@ -185,12 +185,30 @@ BadGuy::collision(GameObject& other, const CollisionHit& hit) return ABORT_MOVE; case STATE_ACTIVE: { BadGuy* badguy = dynamic_cast (&other); - if(badguy && badguy->state == STATE_ACTIVE && badguy->get_group() == COLGROUP_MOVING) - return collision_badguy(*badguy, hit); + if(badguy && badguy->state == STATE_ACTIVE && badguy->get_group() == COLGROUP_MOVING) { + + // hit from above? + if (badguy->get_bbox().p2.y < (bbox.p1.y + 16)) { + if(collision_squished(*badguy)) { + return ABORT_MOVE; + } + } + + return collision_badguy(*badguy, hit); + } Player* player = dynamic_cast (&other); - if(player) + if(player) { + + // hit from above? + if (player->get_bbox().p2.y < (bbox.p1.y + 16)) { + if(collision_squished(*player)) { + return ABORT_MOVE; + } + } + return collision_player(*player, hit); + } Bullet* bullet = dynamic_cast (&other); if(bullet) @@ -218,14 +236,6 @@ BadGuy::collision_solid(const CollisionHit& hit) HitResponse BadGuy::collision_player(Player& player, const CollisionHit& ) { - // hit from above? - if(player.get_bbox().p2.y < (bbox.p1.y + 16)) { - // if it's not possible to squish us, then this will hurt - if(collision_squished(player)) { - return ABORT_MOVE; - } - } - if(player.is_invincible()) { kill_fall(); return ABORT_MOVE; @@ -244,7 +254,7 @@ BadGuy::collision_badguy(BadGuy& , const CollisionHit& ) } bool -BadGuy::collision_squished(Player& ) +BadGuy::collision_squished(GameObject& ) { return false; } @@ -296,7 +306,7 @@ BadGuy::collision_bullet(Bullet& bullet, const CollisionHit& hit) } void -BadGuy::kill_squished(Player& player) +BadGuy::kill_squished(GameObject& object) { sound_manager->play("sounds/squish.wav", get_pos()); physic.enable_gravity(true); @@ -304,8 +314,11 @@ BadGuy::kill_squished(Player& player) physic.set_velocity_y(0); set_state(STATE_SQUISHED); set_group(COLGROUP_MOVING_ONLY_STATIC); - if (countMe) Sector::current()->get_level()->stats.badguys++; - player.bounce(*this); + Player* player = dynamic_cast(&object); + if (player) { + if (countMe) Sector::current()->get_level()->stats.badguys++; + player->bounce(*this); + } } void @@ -466,7 +479,10 @@ BadGuy::get_nearest_player() void BadGuy::update_on_ground_flag(const CollisionHit& hit) { - if (hit.bottom) on_ground_flag = true; + if (hit.bottom) { + on_ground_flag = true; + floor_normal = hit.slope_normal; + } } bool @@ -475,6 +491,12 @@ BadGuy::on_ground() return on_ground_flag; } +Vector +BadGuy::get_floor_normal() +{ + return floor_normal; +} + void BadGuy::freeze() { diff --git a/src/badguy/badguy.hpp b/src/badguy/badguy.hpp index cf0adc22b..7853f8b6b 100644 --- a/src/badguy/badguy.hpp +++ b/src/badguy/badguy.hpp @@ -146,7 +146,7 @@ protected: /** Called when the player hit the badguy from above. You should return true * if the badguy was squished, false if squishing wasn't possible */ - virtual bool collision_squished(Player& player); + virtual bool collision_squished(GameObject& object); /** Called when the badguy collided with a bullet */ virtual HitResponse collision_bullet(Bullet& bullet, const CollisionHit& hit); @@ -164,7 +164,7 @@ protected: /** called when the badguy has been deactivated */ virtual void deactivate(); - void kill_squished(Player& player); + void kill_squished(GameObject& object); void set_state(State state); State get_state() const @@ -219,6 +219,11 @@ protected: */ bool on_ground(); + /** + * Returns floor normal stored the last time when update_on_ground_flag was called and we touched something solid from above. + */ + Vector get_floor_normal(); + bool frozen; bool ignited; /**< true if this badguy is currently on fire */ @@ -227,7 +232,9 @@ private: State state; Timer state_timer; - bool on_ground_flag; + bool on_ground_flag; /**< true if we touched something solid from above and update_on_ground_flag was called last frame */ + Vector floor_normal; /**< floor normal stored the last time when update_on_ground_flag was called and we touched something solid from above */ + }; #endif diff --git a/src/badguy/bouncing_snowball.cpp b/src/badguy/bouncing_snowball.cpp index 72d1acffc..f84561b74 100644 --- a/src/badguy/bouncing_snowball.cpp +++ b/src/badguy/bouncing_snowball.cpp @@ -53,10 +53,10 @@ BouncingSnowball::activate() } bool -BouncingSnowball::collision_squished(Player& player) +BouncingSnowball::collision_squished(GameObject& object) { sprite->set_action("squished"); - kill_squished(player); + kill_squished(object); return true; } diff --git a/src/badguy/bouncing_snowball.hpp b/src/badguy/bouncing_snowball.hpp index 371d60abc..ed2c5cb16 100644 --- a/src/badguy/bouncing_snowball.hpp +++ b/src/badguy/bouncing_snowball.hpp @@ -36,7 +36,7 @@ public: virtual BouncingSnowball* clone() const { return new BouncingSnowball(*this); } protected: - bool collision_squished(Player& player); + bool collision_squished(GameObject& object); }; #endif diff --git a/src/badguy/dispenser.cpp b/src/badguy/dispenser.cpp index 2f3dce533..123e4aa74 100644 --- a/src/badguy/dispenser.cpp +++ b/src/badguy/dispenser.cpp @@ -74,13 +74,14 @@ Dispenser::deactivate() //TODO: Add launching velocity to certain badguys bool -Dispenser::collision_squished(Player& player) +Dispenser::collision_squished(GameObject& object) { //TODO: Should it act like a normal tile when killed? sprite->set_action(dir == LEFT ? "broken-left" : "broken-right"); dispense_timer.start(0); - player.bounce(*this); - kill_squished(player); + Player* player = dynamic_cast(&object); + if (player) player->bounce(*this); + kill_squished(object); return true; } diff --git a/src/badguy/dispenser.hpp b/src/badguy/dispenser.hpp index 5313b4f53..e553d545d 100644 --- a/src/badguy/dispenser.hpp +++ b/src/badguy/dispenser.hpp @@ -40,7 +40,7 @@ public: virtual Dispenser* clone() const { return new Dispenser(*this); } protected: - bool collision_squished(Player& player); + bool collision_squished(GameObject& object); void launch_badguy(); float cycle; std::string badguy; diff --git a/src/badguy/flyingsnowball.cpp b/src/badguy/flyingsnowball.cpp index 517f6b90a..fd684304f 100644 --- a/src/badguy/flyingsnowball.cpp +++ b/src/badguy/flyingsnowball.cpp @@ -68,10 +68,10 @@ FlyingSnowBall::activate() } bool -FlyingSnowBall::collision_squished(Player& player) +FlyingSnowBall::collision_squished(GameObject& object) { sprite->set_action(dir == LEFT ? "squished-left" : "squished-right"); - kill_squished(player); + kill_squished(object); return true; } diff --git a/src/badguy/flyingsnowball.hpp b/src/badguy/flyingsnowball.hpp index 9b244347c..43e932494 100644 --- a/src/badguy/flyingsnowball.hpp +++ b/src/badguy/flyingsnowball.hpp @@ -41,7 +41,7 @@ protected: FLY_DOWN }; FlyingSnowballMode mode; - bool collision_squished(Player& player); + bool collision_squished(GameObject& object); private: Timer timer; Timer puff_timer; /**< time until the next smoke puff is spawned */ diff --git a/src/badguy/igel.cpp b/src/badguy/igel.cpp index 6a4e47772..b8450d226 100644 --- a/src/badguy/igel.cpp +++ b/src/badguy/igel.cpp @@ -34,14 +34,14 @@ Igel::Igel(const lisp::Lisp& reader) : WalkingBadguy(reader, "images/creatures/igel/igel.sprite", "walking-left", "walking-right") { walk_speed = WALKSPEED; - max_drop_height = 0; + max_drop_height = 16; } Igel::Igel(const Vector& pos, Direction d) : WalkingBadguy(pos, d, "images/creatures/igel/igel.sprite", "walking-left", "walking-right") { walk_speed = WALKSPEED; - max_drop_height = 0; + max_drop_height = 16; } void @@ -118,7 +118,7 @@ Igel::collision_bullet(Bullet& bullet, const CollisionHit& hit) } bool -Igel::collision_squished(Player& ) +Igel::collision_squished(GameObject& ) { // this will hurt return false; diff --git a/src/badguy/igel.hpp b/src/badguy/igel.hpp index 0c83cef38..4d2b82f79 100644 --- a/src/badguy/igel.hpp +++ b/src/badguy/igel.hpp @@ -40,7 +40,7 @@ public: virtual Igel* clone() const { return new Igel(*this); } protected: - bool collision_squished(Player& player); + bool collision_squished(GameObject& object); void be_normal(); /**< switch to state STATE_NORMAL */ void turn_around(); /**< reverse direction, assumes we are in STATE_NORMAL */ bool can_see(const MovingObject& o); /**< check if we can see o */ diff --git a/src/badguy/mole.cpp b/src/badguy/mole.cpp index 765319d83..d3e4e4687 100644 --- a/src/badguy/mole.cpp +++ b/src/badguy/mole.cpp @@ -74,7 +74,7 @@ Mole::collision_badguy(BadGuy& , const CollisionHit& ) } bool -Mole::collision_squished(Player& ) +Mole::collision_squished(GameObject& ) { set_state(DEAD); sound_manager->play("sounds/squish.wav", get_pos()); diff --git a/src/badguy/mole.hpp b/src/badguy/mole.hpp index 378a21e56..2a1fa0f39 100644 --- a/src/badguy/mole.hpp +++ b/src/badguy/mole.hpp @@ -30,7 +30,7 @@ public: void kill_fall(); HitResponse collision_badguy(BadGuy& , const CollisionHit& ); - bool collision_squished(Player& player); + bool collision_squished(GameObject& object); void activate(); void write(lisp::Writer& ); diff --git a/src/badguy/mrbomb.cpp b/src/badguy/mrbomb.cpp index 0526c9514..dcd71987d 100644 --- a/src/badguy/mrbomb.cpp +++ b/src/badguy/mrbomb.cpp @@ -27,7 +27,7 @@ MrBomb::MrBomb(const lisp::Lisp& reader) : WalkingBadguy(reader, "images/creatures/mr_bomb/mr_bomb.sprite", "left", "right") { walk_speed = 80; - max_drop_height = 0; + max_drop_height = 16; grabbed = false; //Check if we need another sprite @@ -47,7 +47,7 @@ MrBomb::MrBomb(const Vector& pos, Direction d) : WalkingBadguy(pos, d, "images/creatures/mr_bomb/mr_bomb.sprite", "left", "right") { walk_speed = 80; - max_drop_height = 0; + max_drop_height = 16; grabbed = false; } @@ -76,11 +76,11 @@ MrBomb::collision_player(Player& player, const CollisionHit& hit) } bool -MrBomb::collision_squished(Player& player) +MrBomb::collision_squished(GameObject& object) { remove_me(); Sector::current()->add_object(new Bomb(get_pos(), dir, sprite_name )); - kill_squished(player); + kill_squished(object); return true; } diff --git a/src/badguy/mrbomb.hpp b/src/badguy/mrbomb.hpp index 3a0adaf65..14f326dec 100644 --- a/src/badguy/mrbomb.hpp +++ b/src/badguy/mrbomb.hpp @@ -46,7 +46,7 @@ public: virtual MrBomb* clone() const { return new MrBomb(*this); } protected: - bool collision_squished(Player& player); + bool collision_squished(GameObject& object); private: bool grabbed; diff --git a/src/badguy/mriceblock.cpp b/src/badguy/mriceblock.cpp index 7b954bfc5..697fed9d7 100644 --- a/src/badguy/mriceblock.cpp +++ b/src/badguy/mriceblock.cpp @@ -174,7 +174,7 @@ MrIceBlock::collision_badguy(BadGuy& badguy, const CollisionHit& hit) } bool -MrIceBlock::collision_squished(Player& player) +MrIceBlock::collision_squished(GameObject& object) { switch(ice_state) { case ICESTATE_KICKED: @@ -188,10 +188,13 @@ MrIceBlock::collision_squished(Player& player) set_state(ICESTATE_FLAT); break; case ICESTATE_FLAT: - if(player.get_pos().x < get_pos().x) { - dir = RIGHT; - } else { - dir = LEFT; + { + MovingObject* movingobject = dynamic_cast(&object); + if (movingobject && (movingobject->get_pos().x < get_pos().x)) { + dir = RIGHT; + } else { + dir = LEFT; + } } set_state(ICESTATE_KICKED); break; @@ -200,7 +203,8 @@ MrIceBlock::collision_squished(Player& player) break; } - player.bounce(*this); + Player* player = dynamic_cast(&object); + if (player) player->bounce(*this); return true; } diff --git a/src/badguy/mriceblock.hpp b/src/badguy/mriceblock.hpp index 93aba4e13..a00c5e734 100644 --- a/src/badguy/mriceblock.hpp +++ b/src/badguy/mriceblock.hpp @@ -47,7 +47,7 @@ public: virtual MrIceBlock* clone() const { return new MrIceBlock(*this); } protected: - bool collision_squished(Player& player); + bool collision_squished(GameObject& object); private: enum IceState { diff --git a/src/badguy/mrrocket.cpp b/src/badguy/mrrocket.cpp index cbf5d3126..3f6cc3b7a 100644 --- a/src/badguy/mrrocket.cpp +++ b/src/badguy/mrrocket.cpp @@ -66,10 +66,10 @@ MrRocket::active_update(float elapsed_time) } bool -MrRocket::collision_squished(Player& player) +MrRocket::collision_squished(GameObject& object) { sprite->set_action(dir == LEFT ? "squished-left" : "squished-right"); - kill_squished(player); + kill_squished(object); kill_fall(); return true; } diff --git a/src/badguy/mrrocket.hpp b/src/badguy/mrrocket.hpp index 11ae037a5..bb95805ba 100644 --- a/src/badguy/mrrocket.hpp +++ b/src/badguy/mrrocket.hpp @@ -38,7 +38,7 @@ public: virtual MrRocket* clone() const { return new MrRocket(*this); } protected: - bool collision_squished(Player& player); + bool collision_squished(GameObject& object); Timer collision_timer; }; diff --git a/src/badguy/mrtree.cpp b/src/badguy/mrtree.cpp index bf7923466..ddcc43aa3 100644 --- a/src/badguy/mrtree.cpp +++ b/src/badguy/mrtree.cpp @@ -37,7 +37,7 @@ MrTree::MrTree(const lisp::Lisp& reader) : WalkingBadguy(reader, "images/creatures/mr_tree/mr_tree.sprite","left","right") { walk_speed = WALKSPEED; - max_drop_height = 0; + max_drop_height = 16; sound_manager->preload("sounds/mr_tree.ogg"); } @@ -50,7 +50,7 @@ MrTree::write(lisp::Writer& writer) } bool -MrTree::collision_squished(Player& player) +MrTree::collision_squished(GameObject& object) { // replace with Stumpy Vector stumpy_pos = get_pos(); @@ -62,7 +62,8 @@ MrTree::collision_squished(Player& player) // give Feedback sound_manager->play("sounds/mr_tree.ogg", get_pos()); - player.bounce(*this); + Player* player = dynamic_cast(&object); + if (player) player->bounce(*this); // spawn some particles // TODO: provide convenience function in MovingSprite or MovingObject? diff --git a/src/badguy/mrtree.hpp b/src/badguy/mrtree.hpp index 4eae54948..0b884a1ce 100644 --- a/src/badguy/mrtree.hpp +++ b/src/badguy/mrtree.hpp @@ -30,7 +30,7 @@ public: virtual MrTree* clone() const { return new MrTree(*this); } protected: - bool collision_squished(Player& player); + bool collision_squished(GameObject& object); }; diff --git a/src/badguy/poisonivy.cpp b/src/badguy/poisonivy.cpp index e881933dc..67b4c7f06 100644 --- a/src/badguy/poisonivy.cpp +++ b/src/badguy/poisonivy.cpp @@ -44,7 +44,7 @@ PoisonIvy::write(lisp::Writer& writer) } bool -PoisonIvy::collision_squished(Player& player) +PoisonIvy::collision_squished(GameObject& object) { sprite->set_action(dir == LEFT ? "squished-left" : "squished-right"); // spawn some particles @@ -59,7 +59,7 @@ PoisonIvy::collision_squished(Player& player) Vector paccel = Vector(0, 100); Sector::current()->add_object(new SpriteParticle("images/objects/particles/poisonivy.sprite", "default", ppos, ANCHOR_MIDDLE, pspeed, paccel, LAYER_OBJECTS-1)); } - kill_squished(player); + kill_squished(object); return true; } diff --git a/src/badguy/poisonivy.hpp b/src/badguy/poisonivy.hpp index 908a788e4..783f23254 100644 --- a/src/badguy/poisonivy.hpp +++ b/src/badguy/poisonivy.hpp @@ -32,7 +32,7 @@ public: virtual PoisonIvy* clone() const { return new PoisonIvy(*this); } protected: - bool collision_squished(Player& player); + bool collision_squished(GameObject& object); }; diff --git a/src/badguy/skullyhop.cpp b/src/badguy/skullyhop.cpp index 8d2dbca60..8bf61d7da 100644 --- a/src/badguy/skullyhop.cpp +++ b/src/badguy/skullyhop.cpp @@ -84,10 +84,10 @@ SkullyHop::set_state(SkullyHopState newState) } bool -SkullyHop::collision_squished(Player& player) +SkullyHop::collision_squished(GameObject& object) { sprite->set_action(dir == LEFT ? "squished-left" : "squished-right"); - kill_squished(player); + kill_squished(object); return true; } diff --git a/src/badguy/skullyhop.hpp b/src/badguy/skullyhop.hpp index 1ceab05b0..0569722dc 100644 --- a/src/badguy/skullyhop.hpp +++ b/src/badguy/skullyhop.hpp @@ -36,7 +36,7 @@ public: void write(lisp::Writer& writer); void collision_solid(const CollisionHit& hit); HitResponse collision_badguy(BadGuy& badguy, const CollisionHit& hit); - bool collision_squished(Player& player); + bool collision_squished(GameObject& object); void active_update(float elapsed_time); virtual SkullyHop* clone() const { return new SkullyHop(*this); } diff --git a/src/badguy/snail.cpp b/src/badguy/snail.cpp index e40a24dae..1f21922af 100644 --- a/src/badguy/snail.cpp +++ b/src/badguy/snail.cpp @@ -206,7 +206,7 @@ Snail::collision_badguy(BadGuy& badguy, const CollisionHit& hit) } bool -Snail::collision_squished(Player& player) +Snail::collision_squished(GameObject& object) { switch(state) { @@ -224,11 +224,13 @@ Snail::collision_squished(Player& player) case STATE_FLAT: sound_manager->play("sounds/kick.wav", get_pos()); - - if(player.get_pos().x < get_pos().x) { - dir = RIGHT; - } else { - dir = LEFT; + { + MovingObject* movingobject = dynamic_cast(&object); + if (movingobject && (movingobject->get_pos().x < get_pos().x)) { + dir = RIGHT; + } else { + dir = LEFT; + } } be_kicked(); break; @@ -238,7 +240,8 @@ Snail::collision_squished(Player& player) } - player.bounce(*this); + Player* player = dynamic_cast(&object); + if (player) player->bounce(*this); return true; } diff --git a/src/badguy/snail.hpp b/src/badguy/snail.hpp index 0e804090e..642df55b2 100644 --- a/src/badguy/snail.hpp +++ b/src/badguy/snail.hpp @@ -42,7 +42,7 @@ public: virtual Snail* clone() const { return new Snail(*this); } protected: - bool collision_squished(Player& player); + bool collision_squished(GameObject& object); void be_normal(); /**< switch to state STATE_NORMAL */ void be_flat(); /**< switch to state STATE_FLAT */ void be_kicked(); /**< switch to state STATE_KICKED_DELAY */ diff --git a/src/badguy/snowball.cpp b/src/badguy/snowball.cpp index 2876357a4..8e690cbed 100644 --- a/src/badguy/snowball.cpp +++ b/src/badguy/snowball.cpp @@ -42,10 +42,10 @@ SnowBall::write(lisp::Writer& writer) } bool -SnowBall::collision_squished(Player& player) +SnowBall::collision_squished(GameObject& object) { sprite->set_action(dir == LEFT ? "squished-left" : "squished-right"); - kill_squished(player); + kill_squished(object); return true; } diff --git a/src/badguy/snowball.hpp b/src/badguy/snowball.hpp index a68bc3eec..ef32818c3 100644 --- a/src/badguy/snowball.hpp +++ b/src/badguy/snowball.hpp @@ -32,7 +32,7 @@ public: virtual SnowBall* clone() const { return new SnowBall(*this); } protected: - bool collision_squished(Player& player); + bool collision_squished(GameObject& object); }; diff --git a/src/badguy/spidermite.cpp b/src/badguy/spidermite.cpp index 42210d2b2..ee9eac956 100644 --- a/src/badguy/spidermite.cpp +++ b/src/badguy/spidermite.cpp @@ -58,10 +58,10 @@ SpiderMite::activate() } bool -SpiderMite::collision_squished(Player& player) +SpiderMite::collision_squished(GameObject& object) { sprite->set_action(dir == LEFT ? "squished-left" : "squished-right"); - kill_squished(player); + kill_squished(object); return true; } diff --git a/src/badguy/spidermite.hpp b/src/badguy/spidermite.hpp index 91333aa87..ee36b5b20 100644 --- a/src/badguy/spidermite.hpp +++ b/src/badguy/spidermite.hpp @@ -41,7 +41,7 @@ protected: FLY_DOWN }; SpiderMiteMode mode; - bool collision_squished(Player& player); + bool collision_squished(GameObject& object); private: Timer timer; }; diff --git a/src/badguy/stumpy.cpp b/src/badguy/stumpy.cpp index 282b3a635..f4515461f 100644 --- a/src/badguy/stumpy.cpp +++ b/src/badguy/stumpy.cpp @@ -31,7 +31,7 @@ Stumpy::Stumpy(const lisp::Lisp& reader) : WalkingBadguy(reader, "images/creatures/mr_tree/stumpy.sprite","left","right"), mystate(STATE_NORMAL) { walk_speed = WALKSPEED; - max_drop_height = 0; + max_drop_height = 16; sound_manager->preload("sounds/mr_tree.ogg"); sound_manager->preload("sounds/mr_treehit.ogg"); } @@ -40,7 +40,7 @@ Stumpy::Stumpy(const Vector& pos, Direction d) : WalkingBadguy(pos, d, "images/creatures/mr_tree/stumpy.sprite","left","right"), mystate(STATE_INVINCIBLE) { walk_speed = WALKSPEED; - max_drop_height = 0; + max_drop_height = 16; sound_manager->preload("sounds/mr_treehit.ogg"); invincible_timer.start(INVINCIBLE_TIME); } @@ -87,13 +87,14 @@ Stumpy::active_update(float elapsed_time) } bool -Stumpy::collision_squished(Player& player) +Stumpy::collision_squished(GameObject& object) { // if we're still invincible, we ignore the hit if (mystate == STATE_INVINCIBLE) { sound_manager->play("sounds/mr_treehit.ogg", get_pos()); - player.bounce(*this); + Player* player = dynamic_cast(&object); + if (player) player->bounce(*this); return true; } @@ -101,7 +102,7 @@ Stumpy::collision_squished(Player& player) if (mystate == STATE_NORMAL) { sprite->set_action(dir == LEFT ? "squished-left" : "squished-right"); set_size(sprite->get_current_hitbox_width(), sprite->get_current_hitbox_height()); - kill_squished(player); + kill_squished(object); // spawn some particles // TODO: provide convenience function in MovingSprite or MovingObject? for (int i = 0; i < 25; i++) { diff --git a/src/badguy/stumpy.hpp b/src/badguy/stumpy.hpp index 25ca246da..212e8c7f7 100644 --- a/src/badguy/stumpy.hpp +++ b/src/badguy/stumpy.hpp @@ -44,7 +44,7 @@ protected: Timer invincible_timer; - bool collision_squished(Player& player); + bool collision_squished(GameObject& object); }; #endif diff --git a/src/badguy/toad.cpp b/src/badguy/toad.cpp index 9115e338f..1657a9b26 100644 --- a/src/badguy/toad.cpp +++ b/src/badguy/toad.cpp @@ -86,10 +86,10 @@ Toad::set_state(ToadState newState) } bool -Toad::collision_squished(Player& player) +Toad::collision_squished(GameObject& object) { sprite->set_action(dir == LEFT ? "squished-left" : "squished-right"); - kill_squished(player); + kill_squished(object); return true; } diff --git a/src/badguy/toad.hpp b/src/badguy/toad.hpp index 7460757e0..b7c674632 100644 --- a/src/badguy/toad.hpp +++ b/src/badguy/toad.hpp @@ -36,7 +36,7 @@ public: void write(lisp::Writer& writer); void collision_solid(const CollisionHit& hit); HitResponse collision_badguy(BadGuy& badguy, const CollisionHit& hit); - bool collision_squished(Player& player); + bool collision_squished(GameObject& object); void active_update(float elapsed_time); virtual Toad* clone() const { return new Toad(*this); } diff --git a/src/badguy/totem.cpp b/src/badguy/totem.cpp index 279038ba7..139aa14df 100644 --- a/src/badguy/totem.cpp +++ b/src/badguy/totem.cpp @@ -139,18 +139,19 @@ Totem::active_update(float elapsed_time) } bool -Totem::collision_squished(Player& player) +Totem::collision_squished(GameObject& object) { if (carrying) carrying->jump_off(); if (carried_by) { - player.bounce(*this); + Player* player = dynamic_cast(&object); + if (player) player->bounce(*this); jump_off(); } sprite->set_action(dir == LEFT ? "squished-left" : "squished-right"); bbox.set_size(sprite->get_current_hitbox_width(), sprite->get_current_hitbox_height()); - kill_squished(player); + kill_squished(object); return true; } diff --git a/src/badguy/totem.hpp b/src/badguy/totem.hpp index 89ef732aa..682fe456c 100644 --- a/src/badguy/totem.hpp +++ b/src/badguy/totem.hpp @@ -46,7 +46,7 @@ protected: Totem* carrying; /**< Totem we are currently carrying (or 0) */ Totem* carried_by; /**< Totem by which we are currently carried (or 0) */ - bool collision_squished(Player& player); + bool collision_squished(GameObject& object); void kill_fall(); void jump_on(Totem* target); /**< jump on target */ diff --git a/src/badguy/walking_badguy.cpp b/src/badguy/walking_badguy.cpp index e57a9b7cd..37816dc68 100644 --- a/src/badguy/walking_badguy.cpp +++ b/src/badguy/walking_badguy.cpp @@ -75,11 +75,14 @@ WalkingBadguy::collision_solid(const CollisionHit& hit) update_on_ground_flag(hit); - if (hit.top || hit.bottom) { - physic.set_velocity_y(0); + if (hit.top) { + if (physic.get_velocity_y() < 0) physic.set_velocity_y(0); + } + if (hit.bottom) { + if (physic.get_velocity_y() > 0) physic.set_velocity_y(0); } - if ((hit.left && dir == LEFT) || (hit.right && dir == RIGHT)) { + if ((hit.left && (hit.slope_normal.y == 0) && (dir == LEFT)) || (hit.right && (hit.slope_normal.y == 0) && (dir == RIGHT))) { turn_around(); } diff --git a/src/badguy/walkingleaf.cpp b/src/badguy/walkingleaf.cpp index 9f9778aeb..a05744111 100644 --- a/src/badguy/walkingleaf.cpp +++ b/src/badguy/walkingleaf.cpp @@ -27,21 +27,21 @@ WalkingLeaf::WalkingLeaf(const lisp::Lisp& reader) : WalkingBadguy(reader, "images/creatures/walkingleaf/walkingleaf.sprite", "left", "right") { walk_speed = 60; - max_drop_height = 0; + max_drop_height = 16; } WalkingLeaf::WalkingLeaf(const Vector& pos, Direction d) : WalkingBadguy(pos, d, "images/creatures/walkingleaf/walkingleaf.sprite", "left", "right") { walk_speed = 60; - max_drop_height = 0; + max_drop_height = 16; } bool -WalkingLeaf::collision_squished(Player& player) +WalkingLeaf::collision_squished(GameObject& object) { sprite->set_action(dir == LEFT ? "squished-left" : "squished-right"); - kill_squished(player); + kill_squished(object); return true; } diff --git a/src/badguy/walkingleaf.hpp b/src/badguy/walkingleaf.hpp index a221865e8..e2b84b1e8 100644 --- a/src/badguy/walkingleaf.hpp +++ b/src/badguy/walkingleaf.hpp @@ -34,7 +34,7 @@ public: virtual WalkingLeaf* clone() const { return new WalkingLeaf(*this); } protected: - bool collision_squished(Player& player); + bool collision_squished(GameObject& object); }; diff --git a/src/badguy/yeti.cpp b/src/badguy/yeti.cpp index 2b18b98ba..51f9c13ce 100644 --- a/src/badguy/yeti.cpp +++ b/src/badguy/yeti.cpp @@ -164,18 +164,21 @@ Yeti::summon_snowball() } bool -Yeti::collision_squished(Player& player) +Yeti::collision_squished(GameObject& object) { - kill_squished(player); + kill_squished(object); return true; } void -Yeti::kill_squished(Player& player) +Yeti::kill_squished(GameObject& object) { - player.bounce(*this); - take_hit(player); + Player* player = dynamic_cast(&object); + if (player) { + player->bounce(*this); + take_hit(*player); + } } void Yeti::take_hit(Player& ) diff --git a/src/badguy/yeti.hpp b/src/badguy/yeti.hpp index d7e16ce39..62e090974 100644 --- a/src/badguy/yeti.hpp +++ b/src/badguy/yeti.hpp @@ -34,8 +34,8 @@ public: void activate(); void active_update(float elapsed_time); void collision_solid(const CollisionHit& hit); - bool collision_squished(Player& player); - void kill_squished(Player& player); + bool collision_squished(GameObject& object); + void kill_squished(GameObject& object); void kill_fall(); virtual Yeti* clone() const { return new Yeti(*this); } diff --git a/src/badguy/zeekling.cpp b/src/badguy/zeekling.cpp index 85b2d471c..8a17c4de8 100644 --- a/src/badguy/zeekling.cpp +++ b/src/badguy/zeekling.cpp @@ -58,10 +58,10 @@ Zeekling::activate() } bool -Zeekling::collision_squished(Player& player) +Zeekling::collision_squished(GameObject& object) { sprite->set_action(dir == LEFT ? "squished-left" : "squished-right"); - kill_squished(player); + kill_squished(object); kill_fall(); return true; } diff --git a/src/badguy/zeekling.hpp b/src/badguy/zeekling.hpp index fd0f2871b..b85136851 100644 --- a/src/badguy/zeekling.hpp +++ b/src/badguy/zeekling.hpp @@ -38,7 +38,7 @@ public: virtual Zeekling* clone() const { return new Zeekling(*this); } protected: - bool collision_squished(Player& player); + bool collision_squished(GameObject& object); float speed; Timer diveRecoverTimer; -- 2.11.0