Пример #1
0
/**
 * \brief Notifies this state that the hero is activating a jumper.
 * \param jumper The jumper activated.
 */
void Hero::RunningState::notify_jumper_activated(Jumper& jumper) {

  // Jump immediately.
  get_hero().start_jumping(
      jumper.get_direction(),
      jumper.get_jump_length(),
      true,
      true,
      0);
}
Пример #2
0
/**
 * \brief Returns whether a jumper is considered as an obstacle in this state
 * for the hero at the specified position.
 * \param jumper A jumper.
 * \param candidate_position Position of the hero to test.
 * \return \c true if the jumper is an obstacle in this state with this
 * hero position.
 */
bool Hero::BaseState::is_jumper_obstacle(
    const Jumper& jumper, const Rectangle& candidate_position) const {
  const Hero& hero = get_entity();

  if (jumper.overlaps_jumping_region(hero.get_bounding_box(), false)) {
    // The hero already overlaps the active part of the jumper.
    // This is authorized if he arrived from another direction
    // and thus did not activate it.
    // This can be used to leave water pools for example.
    return false;
  }

  if (!jumper.overlaps_jumping_region(candidate_position, false)) {
    // The candidate position is in the inactive region: always accept that.
    return false;
  }

  if (!can_take_jumper()) {
    // If jumpers cannot be used in this state, consider their active region
    // as obstacles and their inactive region as traversable.
    // The active region should be an obstacle.
    return true;
  }

  // At this point, we know that the jumper can be activated.

  const bool hero_in_jump_position =
      jumper.is_in_jump_position(hero, hero.get_bounding_box(), false);
  const bool candidate_in_jump_position =
      jumper.is_in_jump_position(hero, candidate_position, false);

  if (candidate_in_jump_position) {
    // Wants to move to a valid jump position: accept.
    return false;
  }

  if (hero_in_jump_position) {
    // If the hero is already correctly placed (ready to jump),
    // make the jumper obstacle so that the player has to move in the
    // jumper's direction during a small delay before jumping.
    // This also prevents the hero to get inside the jumper's active region.
    return true;
  }

  const bool candidate_in_extended_jump_position =
      jumper.is_in_jump_position(hero, candidate_position, true);

  if (candidate_in_extended_jump_position) {
    // Wants to get inside the active region from an end of the jumper:
    // don't accept this.
    return true;
  }

  if (!jumper.is_jump_diagonal() &&
      hero.is_moving_towards(jumper.get_direction() / 2)) {
    // Special case: make the jumper traversable so
    // that the smooth movement can slide to it.
    return false;
  }

  if (!jumper.is_jump_diagonal() &&
      get_name() == "swimming" &&  // TODO use inheritance instead
      hero.is_moving_towards(((jumper.get_direction() / 2) + 2) % 4)
  ) {
    // Other special case: trying to enter the jumper the reverse way while
    // swimming: we accept this to allow the hero to leave water pools.
    // TODO I'm not sure this behavior is really a good idea.
    // This may change in a future version.
    return false;
  }

  return true;
}