Ejemplo n.º 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");

  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);
    }
  }
}
Ejemplo n.º 2
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();
  }
}
Ejemplo n.º 3
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::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()) {

      Hero& hero = get_hero();
      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);
    }
  }
}
Ejemplo n.º 4
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) {

  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);
    }
  }
}