Пример #1
0
/**
 * \brief Notifies this movement that the object it controls has changed.
 */
void TargetMovement::notify_object_controlled() {

  StraightMovement::notify_object_controlled();

  // Coordinates have changed: compute a new trajectory.
  recompute_movement();
}
Пример #2
0
/**
 * \brief Updates the position.
 */
void PathFindingMovement::update() {

  PathMovement::update();

  if (target != nullptr && target->is_being_removed()) {
    target = nullptr;
  }

  if (is_suspended()) {
    return;
  }

  if (PathMovement::is_finished()) {

    // there was a collision or the path was made
    if (target != nullptr
        && System::now() >= next_recomputation_date
        && get_entity()->is_aligned_to_grid()) {
      recompute_movement();
    }
    else {
      set_path(create_random_path());
    }
  }
}
Пример #3
0
/**
 * @brief Changes the target of this movement.
 * @param target_x x coordinate of the target point
 * @param target_y y coordinate of the target point
 */
void TargetMovement::set_target(int target_x, int target_y) {

  this->target_x = target_x;
  this->target_y = target_y;
  recompute_movement();
  next_recomputation_date = System::now() + recomputation_delay;
}
Пример #4
0
/**
 * @brief Changes the target of this movement.
 * @param target_entity the target entity
 */
void TargetMovement::set_target(MapEntity* target_entity) {

  this->target_entity = target_entity;
  this->target_x = target_x;
  this->target_y = target_y;
  recompute_movement();
  next_recomputation_date = System::now() + recomputation_delay;
}
Пример #5
0
/**
 * \brief Creates a stream action.
 * \param stream The stream applied.
 * \param entity_moved Entity the stream is applied to.
 */
StreamAction::StreamAction(Stream& stream, Entity& entity_moved):
  stream(std::static_pointer_cast<Stream>(stream.shared_from_this())),
  entity_moved(std::static_pointer_cast<Entity>(entity_moved.shared_from_this())),
  active(true),
  suspended(false),
  when_suspended(0),
  target(0, 0),
  next_move_date(0),
  delay(0) {

  recompute_movement();

  next_move_date = System::now() + delay;
}
Пример #6
0
/**
 * @brief Updates the movement.
 */
void TargetMovement::update() {

  if (System::now() >= next_recomputation_date) {
    recompute_movement();
    next_recomputation_date += recomputation_delay;
  }

  // see if the target is reached
  int dx = target_x - get_x();
  int dy = target_y - get_y();
  if (dx * sign_x <= 0 && dy * sign_y <= 0) {
    if (!test_collision_with_obstacles(dx, dy)) {
      set_xy(target_x, target_y); // because the target movement may have not been very precise
      stop();
      finished = true;
    }
  }

  StraightMovement::update();
}
Пример #7
0
/**
 * \brief Changes the target of this movement.
 * \param target_entity The entity to target or NULL.
 * \param x X of the target point, or X offset in the case of an entity.
 * \param y Y of the target point, or Y offset in the case of an entity.
 */
void TargetMovement::set_target(MapEntity* target_entity, int x, int y) {

  if (this->target_entity != NULL) {
    this->target_entity->decrement_refcount();
    if (this->target_entity->get_refcount() == 0) {
      delete this->target_entity;
    }
  }

  this->target_entity = target_entity;

  if (this->target_entity != NULL) {
    this->target_entity->increment_refcount();
    this->entity_offset_x = x;
    this->entity_offset_y = y;
  }
  else {
    this->target_x = x;
    this->target_y = y;
  }

  recompute_movement();
  next_recomputation_date = System::now() + recomputation_delay;
}
Пример #8
0
/**
 * \brief Called repeatedly by the main loop.
 * Updates the effect of the stream on the entity.
 */
void StreamAction::update() {

  // If the action is already disabled, do nothing.
  if (!is_active()) {
    return;
  }

  // First check that the stream and the entity still exist
  // and are enabled.
  if (stream->is_being_removed()) {
    stream = nullptr;
    active = false;
    return;
  }

  if (!stream->is_enabled()) {
    active = false;
    return;
  }

  if (entity_moved->is_being_removed()) {
    entity_moved = nullptr;
    active = false;
    return;
  }

  if (!entity_moved->is_enabled()) {
    active = false;
    return;
  }

  // Stop the stream action if the hero escapes a non-blocking stream.
  const Point& ground_point = entity_moved->get_ground_point();
  if (
      stream->get_allow_movement() &&
      !stream->overlaps(ground_point)  // We are no longer on the stream.
  ) {
    // Blocking streams are more special.
    // The hero cannot escape them so we don't need this.
    // Also, diagonal blocking streams continue
    // to move the entity even when it does not overlap anymore.
    // This is needed to have precise
    // exact diagonal movements of 16 pixels in stream mazes.

    if (entity_moved->get_distance(target) > 8) {
      // This last test is to avoid stopping a stream when being close to the target.
      // Indeed, in the last pixels before the target, the entity's ground
      // point is no longer on the stream. We continue anyway until the target.
      active = false;
      return;
    }
  }

  if (is_suspended()) {
    return;
  }

  // Update the position.
  recompute_movement();
  while (
      System::now() >= next_move_date &&
      is_active()
  ) {
    next_move_date += delay;

    int dx = 0;
    int dy = 0;
    if (target.x > entity_moved->get_x()) {
      dx = 1;
    }
    else if (target.x < entity_moved->get_x()) {
      dx = -1;
    }
    if (target.y > entity_moved->get_y()) {
      dy = 1;
    }
    else if (target.y < entity_moved->get_y()) {
      dy = -1;
    }

    if (test_obstacles(dx, dy)) {
      bool collision = true;
      // Collision with an obstacle: try only X or only Y.
      if (dx != 0 && dy != 0) {
        if (!test_obstacles(dx, 0)) {
          dy = 0;
          collision = false;
        }
        else if (!test_obstacles(0, dy)) {
          dx = 0;
          collision = false;
        }
      }

      if (collision) {
        if (!stream->get_allow_movement()) {
          // Stop the stream if it was a blocking one.
          active = false;
        }
        break;
      }
    }

    entity_moved->set_xy(entity_moved->get_x() + dx, entity_moved->get_y() + dy);
    entity_moved->notify_position_changed();

    // See if the entity has come outside the stream,
    // in other words, if the movement is finished.
    if (has_reached_target()) {
      // The target point is reached: stop the stream.
      active = false;
    }
    recompute_movement();
  }
}
Пример #9
0
/**
 * \brief Sets the speed of this movement when it is not stopped.
 * \param moving_speed the speed when moving, in pixels per second
 */
void TargetMovement::set_moving_speed(int moving_speed) {
  this->moving_speed = moving_speed;
  recompute_movement();
}