/** * @brief Returns the point located just outside the hookshot's collision box, * in its current direction. */ const Rectangle Hookshot::get_facing_point() { Rectangle facing_point = get_center_point(); switch (get_sprite().get_current_direction()) { // right case 0: facing_point.add_x(8); break; // up case 1: facing_point.add_y(-9); break; // left case 2: facing_point.add_x(-9); break; // down case 3: facing_point.add_y(8); break; default: Debug::die(StringConcat() << "Invalid direction for Hookshot::get_facing_point(): " << get_sprite().get_current_direction()); } return facing_point; }
/** * @brief Updates the entity. */ void Door::update() { Detector::update(); if (!initialized) { update_dynamic_tiles(); initialized = true; } if (is_closed() && get_opening_method() == OPENING_BY_EXPLOSION && get_equipment().has_ability("detect_weak_walls") && Geometry::get_distance(get_center_point(), get_hero().get_center_point()) < 40 && !is_suspended() && System::now() >= next_hint_sound_date) { Sound::play("cane"); next_hint_sound_date = System::now() + 500; } if (is_changing() && get_sprite().is_animation_finished()) { // Toggle door_open when the changing animation finishes. set_open(is_opening()); } if (is_saved() && !is_changing()) { bool open_in_savegame = get_savegame().get_boolean(savegame_variable); if (open_in_savegame && is_closed()) { set_opening(); } else if (!open_in_savegame && is_open()) { set_closing(); } } }
/** * \copydoc Detector::test_collision_custom */ bool Separator::test_collision_custom(Entity& entity) { // Trigger the collision if the center point crosses the middle of the // separator. const Point& separator_center = get_center_point(); const Point& center = entity.get_center_point(); if (!overlaps(center)) { return false; } if (is_horizontal()) { if (center.y < separator_center.y) { // The entity is above the separator. return center.y == separator_center.y - 1; } else { // The entity is below the separator. return center.y == separator_center.y; } } else { if (center.x < separator_center.x) { // The entity is west of the separator. return center.x == separator_center.x - 1; } else { // The entity is east of the separator. return center.x == separator_center.x; } } }
/** * \brief Makes the bomb explode. */ void Bomb::explode() { get_entities().add_entity(std::make_shared<Explosion>( "", get_layer(), get_center_point(), true )); Sound::play("explosion"); remove_from_map(); }
int main() { graph_t * g = graph::read_network<graph_t>(); char c = get_center_point(g); std::cout << "center point: " << c << '\n'; delete g; return 0; }
/** * @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; }
/** * \brief This function is called when a conveyor belt detects a collision with this entity. * \param conveyor_belt a conveyor belt * \param dx direction of the x move in pixels (0, 1 or -1) * \param dy direction of the y move in pixels (0, 1 or -1) */ void Bomb::notify_collision_with_conveyor_belt(ConveyorBelt& conveyor_belt, int dx, int dy) { if (get_movement() == NULL) { // check that a significant part of the bomb is on the conveyor belt Rectangle center = get_center_point(); center.add_xy(-1, -1); center.set_size(2, 2); if (conveyor_belt.overlaps(center)) { set_xy(conveyor_belt.get_xy()); std::string path = " "; path[0] = path[1] = '0' + conveyor_belt.get_direction(); clear_movement(); set_movement(new PathMovement(path, 64, false, false, false)); } } }
/** * \copydoc MapEntity::notify_collision_with_stream */ void Bomb::notify_collision_with_stream(Stream& stream, int /* dx */, int /* dy */) { if (get_movement() == nullptr) { // TODO use a StreamAction, since it now works with any entity and not only the hero. // Check that a significant part of the bomb is on the stream. Rectangle center(get_center_point(), Size(2, 2)); center.add_xy(-1, -1); if (stream.overlaps(center)) { set_xy(stream.get_xy()); std::string path = " "; path[0] = path[1] = '0' + stream.get_direction(); clear_movement(); set_movement(std::make_shared<PathMovement>( path, 64, false, false, false )); } } }
/** * @brief Makes the bomb explode. */ void Bomb::explode() { get_entities().add_entity(new Explosion(get_layer(), get_center_point(), true)); Sound::play("explosion"); remove_from_map(); }