Example #1
0
/**
 * \brief Attacks the hero if possible.
 *
 * This function is called when there is a collision between the enemy and the hero.
 *
 * \param hero the hero
 * \param this_sprite the sprite of this enemy that detected the collision with the hero,
 * or NULL if it was not a pixel-precise collision.
 */
void Enemy::attack_hero(Hero &hero, Sprite *this_sprite) {

  if (!is_immobilized() && can_attack && hero.can_be_hurt(this)) {

    bool hero_protected = false;
    if (minimum_shield_needed != 0
        && get_equipment().has_ability("shield", minimum_shield_needed)) {

      // compute the direction corresponding to the angle between the enemy and the hero
      double angle = hero.get_angle(*this);
      int protected_direction4 = (int) ((angle + Geometry::PI_OVER_2 / 2.0) * 4 / Geometry::TWO_PI);
      protected_direction4 = (protected_direction4 + 4) % 4;

      // also get the direction of the enemy's sprite
      int sprite_opposite_direction4 = -1;
      if (this_sprite != NULL) {
        sprite_opposite_direction4 = (this_sprite->get_current_direction() + 2) % 4;
      }

      // the hero is protected if he is facing the opposite of one of these directions
      hero_protected = hero.is_facing_direction4(protected_direction4) ||
          hero.is_facing_direction4(sprite_opposite_direction4);
    }

    if (hero_protected) {
      attack_stopped_by_hero_shield();
    }
    else {
      hero.hurt(*this, damage_on_hero, magic_damage_on_hero);
    }
  }
}
Example #2
0
/**
 * \brief Attacks the hero if possible.
 *
 * This function is called when there is a collision between the enemy and the hero.
 *
 * \param hero The hero to attack.
 * \param this_sprite The sprite of this enemy that detected the collision with the hero,
 * or NULL if it was not a pixel-precise collision.
 */
void Enemy::attack_hero(Hero& hero, Sprite* this_sprite) {

  if (!is_immobilized()
      && can_attack
      && hero.can_be_hurt(this)) {

    bool hero_protected = false;
    if (minimum_shield_needed != 0
        && get_equipment().has_ability(ABILITY_SHIELD, minimum_shield_needed)
        && hero.can_use_shield()) {

      // Compute the direction corresponding to the angle between the enemy and the hero.
      double angle = hero.get_angle(*this, NULL, this_sprite);
      int protected_direction4 = (int) ((angle + Geometry::PI_OVER_2 / 2.0) * 4 / Geometry::TWO_PI);
      protected_direction4 = (protected_direction4 + 4) % 4;

      // Also get the direction of the enemy's sprite.
      int sprite_opposite_direction4 = -1;
      if (this_sprite != NULL) {
        sprite_opposite_direction4 = (this_sprite->get_current_direction() + 2) % 4;
      }

      // The hero is protected if he is facing the opposite of one of these directions.
      hero_protected = hero.is_facing_direction4(protected_direction4) ||
          hero.is_facing_direction4(sprite_opposite_direction4);
    }

    if (hero_protected) {
      attack_stopped_by_hero_shield();
    }
    else {
      // Let the enemy script handle this if it wants.
      const bool handled = get_lua_context().enemy_on_attacking_hero(
          *this, hero, this_sprite);
      if (!handled) {
        // Scripts did not customize the attack:
        // do the built-in hurt state of the hero.
        hero.hurt(*this, this_sprite, damage_on_hero);
      }
    }
  }
}