From: Christoph Sommer Date: Sat, 12 Aug 2006 22:19:42 +0000 (+0000) Subject: Magic Blocks only turn solid when nothing's blocking them. / X-Git-Url: https://git.verplant.org/?a=commitdiff_plain;h=c483080151dcb9de26e884406d3902330fe9fb9d;p=supertux.git Magic Blocks only turn solid when nothing's blocking them. / Split Sector::is_free_space into is_free_of_tiles, ..._statics and ..._movingstatics SVN-Revision: 4173 --- diff --git a/data/levels/test/magicblocks.stl b/data/levels/test/magicblocks.stl index 5df4ef8a3..47dc97df2 100644 --- a/data/levels/test/magicblocks.stl +++ b/data/levels/test/magicblocks.stl @@ -25,7 +25,7 @@ (speed 1) (width 50) (height 20) - (tiles 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0) + (tiles 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0) ) (tilemap (z-pos 100) diff --git a/src/badguy/badguy.cpp b/src/badguy/badguy.cpp index f0d5eacf5..299dece64 100644 --- a/src/badguy/badguy.cpp +++ b/src/badguy/badguy.cpp @@ -397,7 +397,7 @@ BadGuy::might_fall(int height) x1 = bbox.p2.x + 1; x2 = bbox.p2.x + 1; } - return Sector::current()->is_free_space(Rect(x1, y1, x2, y2)); + return Sector::current()->is_free_of_statics(Rect(x1, y1, x2, y2)); } Player* diff --git a/src/badguy/mrtree.cpp b/src/badguy/mrtree.cpp index 775c82102..bf7923466 100644 --- a/src/badguy/mrtree.cpp +++ b/src/badguy/mrtree.cpp @@ -80,7 +80,7 @@ MrTree::collision_squished(Player& player) // spawn PoisonIvy Vector leaf1_pos = Vector(stumpy_pos.x - POISONIVY_WIDTH - 1, stumpy_pos.y - POISONIVY_Y_OFFSET); Rect leaf1_bbox = Rect(leaf1_pos.x, leaf1_pos.y, leaf1_pos.x + POISONIVY_WIDTH, leaf1_pos.y + POISONIVY_HEIGHT); - if (Sector::current()->is_free_space(leaf1_bbox)) { + if (Sector::current()->is_free_of_movingstatics(leaf1_bbox, this)) { PoisonIvy* leaf1 = new PoisonIvy(leaf1_bbox.p1, LEFT); leaf1 = leaf1; Sector::current()->add_object(leaf1); @@ -89,7 +89,7 @@ MrTree::collision_squished(Player& player) // spawn PoisonIvy Vector leaf2_pos = Vector(stumpy_pos.x + sprite->get_current_hitbox_width() + 1, stumpy_pos.y - POISONIVY_Y_OFFSET); Rect leaf2_bbox = Rect(leaf2_pos.x, leaf2_pos.y, leaf2_pos.x + POISONIVY_WIDTH, leaf2_pos.y + POISONIVY_HEIGHT); - if (Sector::current()->is_free_space(leaf2_bbox)) { + if (Sector::current()->is_free_of_movingstatics(leaf2_bbox, this)) { PoisonIvy* leaf2 = new PoisonIvy(leaf2_bbox.p1, RIGHT); leaf2 = leaf2; Sector::current()->add_object(leaf2); diff --git a/src/object/magicblock.cpp b/src/object/magicblock.cpp index 88bd9d935..0e9968724 100644 --- a/src/object/magicblock.cpp +++ b/src/object/magicblock.cpp @@ -80,11 +80,11 @@ MagicBlock::update(float elapsed_time) // lighting suggests going solid if (!is_solid) { - //if (Sector::current()->is_free_space(get_bbox(), this)) { - is_solid = true; - solid_time = 0; - switch_delay = SWITCH_DELAY; - //} + if (Sector::current()->is_free_of_movingstatics(get_bbox(), this)) { + is_solid = true; + solid_time = 0; + switch_delay = SWITCH_DELAY; + } } } else { // lighting suggests going nonsolid diff --git a/src/object/player.cpp b/src/object/player.cpp index 2b0ae7710..5128efa2d 100644 --- a/src/object/player.cpp +++ b/src/object/player.cpp @@ -202,7 +202,7 @@ Player::adjust_height(float new_height) if(new_height > bbox.get_height()) { Rect additional_space = bbox2; additional_space.set_height(new_height - bbox.get_height()); - if(!Sector::current()->is_free_space(additional_space)) + if(!Sector::current()->is_free_of_movingstatics(additional_space, this)) return false; } @@ -645,7 +645,7 @@ Player::handle_input() Vector(dir == LEFT ? -bbox.get_width()-1 : bbox.get_width()+1, bbox.get_height()*0.66666 - 32); Rect dest(pos, pos + Vector(32, 32)); - if(Sector::current()->is_free_space(dest)) { + if(Sector::current()->is_free_of_statics(dest)) { MovingObject* moving_object = dynamic_cast (grabbed_object); if(moving_object) { moving_object->set_pos(pos); diff --git a/src/sector.cpp b/src/sector.cpp index e155abd04..a8ba20913 100644 --- a/src/sector.cpp +++ b/src/sector.cpp @@ -1173,7 +1173,7 @@ Sector::handle_collisions() } bool -Sector::is_free_space(const Rect& rect) const +Sector::is_free_of_tiles(const Rect& rect) const { using namespace collision; @@ -1203,15 +1203,46 @@ Sector::is_free_space(const Rect& rect) const } } + return true; +} + +bool +Sector::is_free_of_statics(const Rect& rect, const MovingObject* ignore_object) const +{ + using namespace collision; + + if (!is_free_of_tiles(rect)) return false; + for(MovingObjects::const_iterator i = moving_objects.begin(); i != moving_objects.end(); ++i) { const MovingObject* moving_object = *i; - if(moving_object->get_group() != COLGROUP_STATIC - || !moving_object->is_valid()) - continue; + if (moving_object == ignore_object) continue; + if (!moving_object->is_valid()) continue; + if (moving_object->get_group() == COLGROUP_STATIC) { + if(intersects(rect, moving_object->get_bbox())) return false; + } + } - if(intersects(rect, moving_object->get_bbox())) - return false; + return true; +} + +bool +Sector::is_free_of_movingstatics(const Rect& rect, const MovingObject* ignore_object) const +{ + using namespace collision; + + if (!is_free_of_tiles(rect)) return false; + + for(MovingObjects::const_iterator i = moving_objects.begin(); + i != moving_objects.end(); ++i) { + const MovingObject* moving_object = *i; + if (moving_object == ignore_object) continue; + if (!moving_object->is_valid()) continue; + if ((moving_object->get_group() == COLGROUP_MOVING) + || (moving_object->get_group() == COLGROUP_MOVING_STATIC) + || (moving_object->get_group() == COLGROUP_STATIC)) { + if(intersects(rect, moving_object->get_bbox())) return false; + } } return true; diff --git a/src/sector.hpp b/src/sector.hpp index 50edf73d8..65e2a0f75 100644 --- a/src/sector.hpp +++ b/src/sector.hpp @@ -132,11 +132,25 @@ public: void collision_tilemap(collision::Constraints* constraints, const Vector& movement, const Rect& dest) const; - /** Checks if at the specified rectangle are gameobjects with STATIC flag set - * (or solid tiles from the tilemap). - * This does not(!) include badguys or players. + /** + * Checks if the specified rectangle is free of (solid) tiles. + * Note that this does not include static objects, e.g. bonus blocks. */ - bool is_free_space(const Rect& rect) const; + bool is_free_of_tiles(const Rect& rect) const; + /** + * Checks if the specified rectangle is free of both + * 1.) solid tiles and + * 2.) MovingObjects in COLGROUP_STATIC. + * Note that this does not include badguys or players. + */ + bool is_free_of_statics(const Rect& rect, const MovingObject* ignore_object = 0) const; + /** + * Checks if the specified rectangle is free of both + * 1.) solid tiles and + * 2.) MovingObjects in COLGROUP_STATIC, COLGROUP_MOVINGSTATIC or COLGROUP_MOVING. + * This includes badguys and players. + */ + bool is_free_of_movingstatics(const Rect& rect, const MovingObject* ignore_object = 0) const; /** * returns a list of players currently in the sector diff --git a/src/title.cpp b/src/title.cpp index 4b4d62ac8..08259e870 100644 --- a/src/title.cpp +++ b/src/title.cpp @@ -233,7 +233,7 @@ TitleScreen::make_tux_jump() // Check if we should press the jump button bool randomJump = !randomWaitTimer.started(); bool notMoving = (fabsf(dx) + fabsf(dy)) < 0.1; - bool pathBlocked = !sector->is_free_space(lookahead); + bool pathBlocked = !sector->is_free_of_statics(lookahead); if (!controller->released(Controller::JUMP) && (notMoving || pathBlocked || randomJump)) { float jumpDuration;