/** * \brief Makes the teletransporter move the hero to the destination. * \param hero the hero */ void Teletransporter::transport_hero(Hero& hero) { if (transporting_hero) { // already done return; } std::string name = destination_name; int hero_x = hero.get_x(); int hero_y = hero.get_y(); if (is_on_map_side()) { // special destination point: side of the map // we determine the appropriate side based on the teletransporter's position; // we also place the hero on the old map so that its position corresponds to the new map switch (destination_side) { case 0: name += '0'; // scroll to the west hero_x = 0; break; case 1: name += '1'; // scroll to the south hero_y = get_map().get_height() + 5; break; case 2: name += '2'; // scroll to the east hero_x = get_map().get_width(); break; case 3: name += '3'; // scroll to the north hero_y = 5; break; default: Debug::die(std::string("Bad destination side for teletransporter '") + get_name() + "'"); } } transporting_hero = true; get_lua_context()->teletransporter_on_activated(*this); if (!sound_id.empty()) { Sound::play(sound_id); } get_game().set_current_map(destination_map_id, name, transition_style); hero.set_xy(hero_x, hero_y); }
/** * @brief Returns whether an entity's collides with this entity. * @param entity an entity * @return true if the entity's collides with this entity */ bool Teletransporter::test_collision_custom(MapEntity& entity) { bool collision = false; bool normal_case = true; // specific collision tests for some situations if (entity.is_hero()) { Hero& hero = (Hero&) entity; if (is_on_map_side()) { // scrolling towards an adjacent map Rectangle facing_point = hero.get_facing_point(transition_direction); collision = hero.is_moving_towards(transition_direction) && overlaps(facing_point.get_x(), facing_point.get_y()); normal_case = false; } else if (!get_map().test_collision_with_border(get_center_point()) && hero.get_ground() == GROUND_HOLE) { // falling into a hole collision = overlaps(hero.get_ground_point()); normal_case = false; } } // normal case if (normal_case) { const Rectangle& entity_rectangle = entity.get_bounding_box(); int x1 = entity_rectangle.get_x() + 4; int x2 = x1 + entity_rectangle.get_width() - 9; int y1 = entity_rectangle.get_y() + 4; int y2 = y1 + entity_rectangle.get_height() - 9; collision = overlaps(x1, y1) && overlaps(x2, y1) && overlaps(x1, y2) && overlaps(x2, y2); } if (!collision && !is_on_map_side()) { transporting_hero = false; } return collision; }