Beispiel #1
0
/**
 * \brief Starts this state.
 * \param previous_state the previous state
 */
void Hero::HurtState::start(const State* previous_state) {

  State::start(previous_state);

  Equipment& equipment = get_equipment();

  Sound::play("hero_hurt");

  if (life_points != 0) {
    // the level of the tunic reduces the damage, but we remove at least 1 life point
    life_points = std::max(1, life_points / (equipment.get_ability("tunic")));

    equipment.remove_life(life_points);
    if (equipment.has_ability("tunic")) {
      equipment.notify_ability_used("tunic");
    }
  }

  if (magic_points > 0 && equipment.get_magic() > 0) {
    equipment.remove_magic(magic_points);
    Sound::play("magic_bar");
  }
  get_sprites().set_animation_hurt();
  get_sprites().blink();

  Hero& hero = get_hero();
  double angle = Geometry::get_angle(source_xy.get_x(), source_xy.get_y(),
      hero.get_x(), hero.get_y());
  StraightMovement* movement = new StraightMovement(false, true);
  movement->set_max_distance(24);
  movement->set_speed(120);
  movement->set_angle(angle);
  hero.set_movement(movement);
  end_hurt_date = System::now() + 200;
}
Beispiel #2
0
/**
 * \brief Notifies this state that the hero has just attacked an enemy.
 * \param attack the attack
 * \param victim the enemy just hurt
 * \param result indicates how the enemy has reacted to the attack (see Enemy.h)
 * \param killed indicates that the attack has just killed the enemy
 */
void Hero::SpinAttackState::notify_attacked_enemy(
    EnemyAttack attack,
    Enemy& victim,
    EnemyReaction::Reaction& result,
    bool killed) {

  Hero& hero = get_hero();
  if (result.type != EnemyReaction::IGNORED && attack == ATTACK_SWORD) {

    if (victim.get_push_hero_on_sword()) {

      if (hero.get_movement() != NULL) {
        // interrupting a super spin attack: finish with a normal one
        hero.clear_movement();
        get_sprites().set_animation_spin_attack();
      }

      being_pushed = true;
      double angle = Geometry::get_angle(victim.get_x(), victim.get_y(),
          hero.get_x(), hero.get_y());
      StraightMovement* movement = new StraightMovement(false, true);
      movement->set_max_distance(24);
      movement->set_speed(120);
      movement->set_angle(angle);
      hero.set_movement(movement);
    }
  }
}
Beispiel #3
0
/**
 * \brief Hurts the enemy.
 *
 * Updates its state, its sprite and plays the sound.
 *
 * \param source the entity attacking the enemy (often the hero)
 */
void Enemy::hurt(MapEntity& source) {

  uint32_t now = System::now();

  // update the enemy state
  being_hurt = true;
  set_movement_events_enabled(false);

  can_attack = false;
  can_attack_again_date = now + 300;

  // graphics and sounds
  set_animation("hurt");
  play_hurt_sound();

  // stop any movement
  clear_movement();

  // push the enemy back
  if (pushed_back_when_hurt) {
    double angle = source.get_angle(*this);
    StraightMovement* movement = new StraightMovement(false, true);
    movement->set_max_distance(24);
    movement->set_speed(120);
    movement->set_angle(angle);
    set_movement(movement);
  }

  stop_hurt_date = now + 300;
}
Beispiel #4
0
/**
 * \brief Creates a boomerang.
 * \param hero the hero
 * \param max_distance maximum distance of the movement in pixels
 * \param speed speed of the movement in pixels per second
 * \param angle the angle of the boomerang trajectory in radians
 * \param sprite_name animation set id representing the boomerang
 */
Boomerang::Boomerang(
    Hero& hero,
    int max_distance,
    int speed,
    double angle,
    const std::string& sprite_name):
  MapEntity("", 0, hero.get_layer(), 0, 0, 0, 0),
  hero(hero),
  has_to_go_back(false),
  going_back(false),
  speed(speed) {

  // initialize the entity
  create_sprite(sprite_name);
  set_size(16, 16);
  set_origin(8, 8);

  int hero_x = hero.get_top_left_x();
  int hero_y = hero.get_top_left_y();
  switch (hero.get_animation_direction()) {

    case 0:
      set_xy(hero_x + 24, hero_y + 8);
      break;

    case 1:
      set_xy(hero_x + 8, hero_y - 8);
      break;

    case 2:
      set_xy(hero_x - 8, hero_y + 8);
      break;

    case 3:
      set_xy(hero_x + 8, hero_y + 24);
      break;

  }

  initial_coords.set_xy(get_xy());

  StraightMovement* movement = new StraightMovement(false, false);
  movement->set_speed(speed);
  movement->set_angle(angle);
  movement->set_max_distance(max_distance);
  set_movement(movement);

  next_sound_date = System::now();
}
/**
 * @brief Notifies this state that the hero has just attacked an enemy.
 * @param attack the attack
 * @param victim the enemy just hurt
 * @param result indicates how the enemy has reacted to the attack (see Enemy.h)
 * @param killed indicates that the attack has just killed the enemy
 */
void Hero::SwordSwingingState::notify_attacked_enemy(EnemyAttack attack, Enemy& victim,
    EnemyReaction::Reaction& result, bool killed) {

  if (result.type != EnemyReaction::IGNORED && attack == ATTACK_SWORD) {
    attacked = true;

    if (victim.get_push_hero_on_sword()) {

      double angle = Geometry::get_angle(victim.get_x(), victim.get_y(),
          hero.get_x(), hero.get_y());
      StraightMovement* movement = new StraightMovement(false, true);
      movement->set_max_distance(24);
      movement->set_speed(120);
      movement->set_angle(angle);
      hero.set_movement(movement);
    }
  }
}
Beispiel #6
0
/**
 * \brief Starts this state.
 * \param previous_state The previous state.
 */
void Hero::HurtState::start(const State* previous_state) {

  State::start(previous_state);

  Equipment& equipment = get_equipment();

  Sound::play("hero_hurt");

  Hero& hero = get_hero();
  const uint32_t invincibility_duration = 2000;
  hero.set_invincible(true, invincibility_duration);
  get_sprites().set_animation_hurt();
  get_sprites().blink(invincibility_duration);

  if (has_source) {
    double angle = Geometry::get_angle(source_xy.get_x(), source_xy.get_y(),
        hero.get_x(), hero.get_y());
    StraightMovement* movement = new StraightMovement(false, true);
    movement->set_max_distance(24);
    movement->set_speed(120);
    movement->set_angle(angle);
    hero.set_movement(movement);
  }
  end_hurt_date = System::now() + 200;

  // See if the script customizes how the hero takes damages.
  bool handled = get_lua_context().hero_on_taking_damage(get_hero(), damage);

  if (!handled && damage != 0) {
    // No customized damage: perform the default calculation.
    // The level of the tunic reduces the damage,
    // but we remove at least 1 life point.
    int life_points = std::max(1, damage / (equipment.get_ability(ABILITY_TUNIC)));

    equipment.remove_life(life_points);
    if (equipment.has_ability(ABILITY_TUNIC)) {
      equipment.notify_ability_used(ABILITY_TUNIC);
    }
  }
}
Beispiel #7
0
/**
 * \brief Updates this state.
 */
void Hero::RunningState::update() {

  State::update();

  if (is_suspended()) {
    return;
  }

  uint32_t now = System::now();

  if (!is_bouncing() && now >= next_sound_date) {
    Sound::play("running");
    next_sound_date = now + 170;
  }

  Hero& hero = get_hero();
  if (phase == 0) {

    if (now >= next_phase_date) {

      double angle = Geometry::degrees_to_radians(get_sprites().get_animation_direction() * 90);
      StraightMovement* movement = new StraightMovement(false, true);
      movement->set_max_distance(3000);
      movement->set_speed(300);
      movement->set_angle(angle);
      hero.clear_movement();
      hero.set_movement(movement);

      get_sprites().set_animation_running();
      phase++;
    }
    else if (!is_pressing_running_key()) {
      hero.set_state(new FreeState(hero));
    }
  }
  else if (hero.get_movement()->is_finished()) {
    hero.start_state_from_ground();
  }
}