Пример #1
0
/**
 * @brief Updates this state.
 */
void Hero::PushingState::update() {

  State::update();

  if (is_moving_grabbed_entity()) { // the hero is pushing an entity and is currently moving it (typically a block)

    // detect when the hero movement is finished
    // because the hero has covered 16 pixels, has reached an obstacle or has aligned the entity on the grid

    PathMovement *movement = (PathMovement*) hero.get_movement();

    bool horizontal = pushing_direction4 % 2 == 0;
    bool has_reached_grid = movement->get_total_distance_covered() > 8
      && ((horizontal && hero.is_aligned_to_grid_x()) || (!horizontal && hero.is_aligned_to_grid_y()));

    if (movement->is_finished() || has_reached_grid) {
      stop_moving_pushed_entity();
    }
  }
  else { // the hero is pushing a fixed obstacle

    // stop pushing if there is no more obstacle
    if (!hero.is_facing_obstacle()) {
      hero.set_state(new FreeState(hero));
    }

    // stop pushing if the player changes his direction
    else if (get_controls().get_wanted_direction8() != pushing_direction4 * 2) {

      if (get_controls().is_key_pressed(GameControls::ACTION)) {
	hero.set_state(new GrabbingState(hero));
      }
      else {
	hero.set_state(new FreeState(hero));
      }
    }

    // see if the obstacle pushed is an entity that the hero can move
    else {
 
      Detector *facing_entity = hero.get_facing_entity();
      if (facing_entity != NULL) { // the obstacle pushed is an entity

	if (facing_entity->get_type() == BLOCK) { // it can be moved by the hero (TODO dynamic binding)
	  hero.try_snap_to_facing_entity();
	}

	if (facing_entity->moved_by_hero()) {

	  std::string path = "  ";
	  path[0] = path[1] = '0' + pushing_direction4 * 2;

	  hero.set_movement(new PathMovement(path, 40, false, false, false));
	  pushed_entity = facing_entity;
	}
      }
    }
  }
}
Пример #2
0
/**
 * @brief Stops this state.
 */
void Hero::PushingState::stop(State *next_state) {

  State::stop(next_state);

  if (is_moving_grabbed_entity()) {
    hero.clear_movement();
  }
}
Пример #3
0
/**
 * @brief Notifies this state that the hero has just failed to change its
 * position because of obstacles.
 */
void Hero::PushingState::notify_obstacle_reached() {

  if (is_moving_grabbed_entity()) {
    // an obstacle is reached before the 16 pixels are completed
    //std::cout << "stop moving block: the hero has reached an obstacle\n";
    stop_moving_pushed_entity();
  }
}
Пример #4
0
/**
 * \brief Notifies this state that the hero has just failed to change its
 * position because of obstacles.
 */
void Hero::PullingState::notify_obstacle_reached() {

  if (is_moving_grabbed_entity()) {
    // an obstacle is reached before the 16 pixels are completed
    pulled_entity->update();
    stop_moving_pulled_entity();
  }
}
Пример #5
0
/**
 * @brief Notifies this state that the movement if finished.
 */
void Hero::PushingState::notify_movement_finished() {

  if (is_moving_grabbed_entity()) {
    // the 16 pixels of the path are completed
    //std::cout << "stop moving block: 16 pixels were completed\n";
    stop_moving_pushed_entity();
  }
}
Пример #6
0
/**
 * \brief Notifies this state that the movement if finished.
 */
void Hero::PullingState::notify_movement_finished() {

  if (is_moving_grabbed_entity()) {
    // the 16 pixels of the path are completed
    pulled_entity->update();
    stop_moving_pulled_entity();
  }
}
Пример #7
0
/**
 * \brief Stops this state.
 */
void Hero::PullingState::stop(const State* next_state) {

  State::stop(next_state);

  if (is_moving_grabbed_entity()) {
    get_hero().clear_movement();
    pulled_entity->update();
    stop_moving_pulled_entity();
  }
}
Пример #8
0
/**
 * \brief Notifies this state that the hero has just changed its
 * position.
 */
void Hero::PullingState::notify_position_changed() {

  if (is_moving_grabbed_entity()) {
    // if the entity has made more than 8 pixels and is aligned on the grid,
    // we stop the movement

    bool horizontal = get_sprites().get_animation_direction() % 2 == 0;
    bool has_reached_grid = pulling_movement->get_total_distance_covered() > 8
      && ((horizontal && pulled_entity->is_aligned_to_grid_x())
          || (!horizontal && pulled_entity->is_aligned_to_grid_y()));

    if (has_reached_grid) {
      stop_moving_pulled_entity();
    }
  }
}
Пример #9
0
/**
 * \brief Updates this state.
 */
void Hero::PullingState::update() {

  State::update();

  Hero& hero = get_hero();
  if (!is_moving_grabbed_entity()) {

    int wanted_direction8 = get_commands().get_wanted_direction8();
    int opposite_direction8 = (get_sprites().get_animation_direction8() + 4) % 8;

    // stop pulling if the action key is released or if there is no more obstacle
    if (!get_commands().is_command_pressed(GameCommand::ACTION)
        || !hero.is_facing_obstacle()) {
      hero.set_state(new FreeState(hero));
    }

    // stop pulling the obstacle if the player changes his direction
    else if (wanted_direction8 != opposite_direction8) {
      hero.set_state(new GrabbingState(hero));
    }

    // see if the obstacle is an entity that the hero can pull
    else {

      Detector* facing_entity = hero.get_facing_entity();
      if (facing_entity != nullptr) {

        if (facing_entity->get_type() == EntityType::BLOCK) { // TODO use dynamic binding
          hero.try_snap_to_facing_entity();
        }

        if (facing_entity->start_movement_by_hero()) {

          std::string path = "  ";
          path[0] = path[1] = '0' + opposite_direction8;

          pulling_movement = std::make_shared<PathMovement>(
              path, 40, false, false, false
          );
          hero.set_movement(pulling_movement);
          pulled_entity = facing_entity;
          pulled_entity->notify_moving_by(hero);
        }
      }
    }
  }
}
Пример #10
0
/**
 * @brief Updates this state.
 */
void Hero::PushingState::update() {

  State::update();

  if (!is_moving_grabbed_entity()) { // the hero is pushing a fixed obstacle

    // stop pushing if there is no more obstacle
    if (!hero.is_facing_obstacle()) {
      hero.set_state(new FreeState(hero));
    }

    // stop pushing if the player changes his direction
    else if (get_controls().get_wanted_direction8() != pushing_direction4 * 2) {

      if (get_controls().is_key_pressed(GameControls::ACTION)) {
        hero.set_state(new GrabbingState(hero));
      }
      else {
        hero.set_state(new FreeState(hero));
      }
    }

    // see if the obstacle pushed is an entity that the hero can move
    else {
 
      Detector *facing_entity = hero.get_facing_entity();
      if (facing_entity != NULL) { // the obstacle pushed is an entity

        if (facing_entity->get_type() == BLOCK) { // it can be moved by the hero (TODO dynamic binding)
          hero.try_snap_to_facing_entity();
        }

        if (facing_entity->start_movement_by_hero()) {

          std::string path = "  ";
          path[0] = path[1] = '0' + pushing_direction4 * 2;

          hero.set_movement(new PathMovement(path, 40, false, false, false));
          pushed_entity = facing_entity;
        }
      }
    }
  }
}
Пример #11
0
/**
 * @brief Notifies this state that the hero has just changed its
 * position.
 */
void Hero::PushingState::notify_position_changed() {

  if (is_moving_grabbed_entity()) {
    // if the entity has made more than 8 pixels and is aligned on the grid,
    // we stop the movement

    PathMovement *movement = (PathMovement*) hero.get_movement();

    bool horizontal = pushing_direction4 % 2 == 0;
    bool has_reached_grid = movement->get_total_distance_covered() > 8
      && ((horizontal && pushed_entity->is_aligned_to_grid_x())
          || (!horizontal && pushed_entity->is_aligned_to_grid_y()));

    if (has_reached_grid) {
      //std::cout << "stop moving block: the entity has reached the grid\n";
      stop_moving_pushed_entity();
    }
  }
}
Пример #12
0
/**
 * @brief Returns whether the hero can be hurt in this state.
 * @return true if the hero can be hurt in this state
 */
bool Hero::PushingState::can_be_hurt() {
  return !is_moving_grabbed_entity();
}
Пример #13
0
/**
 * @brief Returns whether the hero can swing his sword in this state.
 * @return true if the hero can swing his sword in this state
 */
bool Hero::PushingState::can_start_sword() {
  return !is_moving_grabbed_entity();
}
Пример #14
0
/**
 * @brief Returns whether the hero can be hurt in this state.
 * @param attacker an attacker that is trying to hurt the hero
 * (or NULL if the source of the attack is not an enemy)
 * @return true if the hero can be hurt in this state
 */
bool Hero::PushingState::can_be_hurt(Enemy* attacker) {
  return !is_moving_grabbed_entity();
}
Пример #15
0
/**
 * \brief Returns whether the hero can be hurt in this state.
 * \return true if the hero can be hurt in this state
 * \param attacker an attacker that is trying to hurt the hero
 * (or nullptr if the source of the attack is not an enemy)
 */
bool Hero::PullingState::can_be_hurt(MapEntity* /* attacker */) const {
  return !is_moving_grabbed_entity();
}