Beispiel #1
0
/**
 * @brief Creates a new destructible item with the specified subtype.
 * @param name Unique name identifying the entity on the map or an empty string.
 * @param layer layer of the destructible item to create on the map
 * @param x x coordinate of the destructible item to create
 * @param y y coordinate of the destructible item to create
 * @param subtype subtype of destructible item to create
 * @param treasure the pickable item that appears when the destructible
 * item is lifted or cut
 */
Destructible::Destructible(const std::string& name, Layer layer, int x, int y,
    Subtype subtype, const Treasure &treasure):

  Detector(COLLISION_NONE, name, layer, x, y, 16, 16),
  subtype(subtype),
  treasure(treasure),
  is_being_cut(false),
  regeneration_date(0),
  is_regenerating(false),
  destruction_callback_ref(LUA_REFNIL) {

  set_origin(8, 13);
  create_sprite(get_animation_set_id());

  // set the collision mode
  if (features[subtype].can_be_lifted) {
    add_collision_mode(COLLISION_FACING_POINT);
  }

  if (features[subtype].can_be_cut
      || features[subtype].can_explode) {
    add_collision_mode(COLLISION_SPRITE);
  }

  if (has_special_ground()) { // display a special ground under the hero
    add_collision_mode(COLLISION_CUSTOM);
  }
}
Beispiel #2
0
/**
 * \brief Notifies this detector that the player is interacting with it by
 * pressing the action command.
 *
 * This function is called when the player presses the action command
 * while the hero is facing this detector, and the action command effect lets
 * him do this.
 */
void Destructible::notify_action_command_pressed() {

  KeysEffect::ActionKeyEffect effect = get_keys_effect().get_action_key_effect();

  if ((effect == KeysEffect::ACTION_KEY_LIFT || effect == KeysEffect::ACTION_KEY_LOOK)
      && features[subtype].can_be_lifted
      && !is_being_cut
      && !is_disabled()
      && !is_regenerating) {

    int weight = features[subtype].weight;

    if (get_equipment().has_ability("lift", weight)) {

      uint32_t explosion_date = can_explode() ? System::now() + 6000 : 0;
      get_hero().start_lifting(new CarriedItem(
          get_hero(),
          *this,
          get_animation_set_id(),
          get_destruction_sound_id(),
          get_damage_on_enemies(),
          explosion_date)
      );

      // play the sound
      Sound::play("lift");

      // create the pickable item
      create_pickable();

      // remove the item from the map
      if (!features[subtype].can_regenerate) {
        destruction_callback();
        remove_from_map();
      }
      else {
        // the item can actually regenerate
        play_destroy_animation();
      }
    }
    else {
      if (features[subtype].can_be_cut
          && !features[subtype].can_explode
          && !get_equipment().has_ability("sword", 1)) {
        get_game().start_dialog("_cannot_lift_should_cut", LUA_REFNIL);
      }
      else if (!get_equipment().has_ability("lift", 1)) {
        get_game().start_dialog("_cannot_lift_too_heavy", LUA_REFNIL);
      }
      else {
        get_game().start_dialog("_cannot_lift_still_too_heavy", LUA_REFNIL);
      }
    }
  }
}
Beispiel #3
0
/**
 * \copydoc Detector::notify_action_command_pressed
 */
bool Destructible::notify_action_command_pressed() {

  KeysEffect::ActionKeyEffect effect = get_keys_effect().get_action_key_effect();

  if ((effect == KeysEffect::ACTION_KEY_LIFT || effect == KeysEffect::ACTION_KEY_LOOK)
      && get_weight() != -1
      && !is_being_cut
      && !is_waiting_for_regeneration()
      && !is_regenerating) {

    if (get_equipment().has_ability(Ability::LIFT, get_weight())) {

      uint32_t explosion_date = get_can_explode() ? System::now() + 6000 : 0;
      get_hero().start_lifting(std::make_shared<CarriedItem>(
          get_hero(),
          *this,
          get_animation_set_id(),
          get_destruction_sound(),
          get_damage_on_enemies(),
          explosion_date)
      );

      // Play the sound.
      Sound::play("lift");

      // Create the pickable treasure.
      create_treasure();

      if (!get_can_regenerate()) {
        // Remove this destructible from the map.
        remove_from_map();
      }
      else {
        // The item can actually regenerate.
        play_destroy_animation();
      }

      // Notify Lua.
      get_lua_context().destructible_on_lifting(*this);
    }
    else {
      // Cannot lift the object.
      get_hero().start_grabbing();
      get_lua_context().destructible_on_looked(*this);
    }

    return true;
  }

  return false;
}
Beispiel #4
0
/**
 * \brief Sets the current direction of the sprite's animation and restarts the animation.
 *
 * If the specified direction is the current direction, nothing is done.
 *
 * \param current_direction the current direction
 */
void Sprite::set_current_direction(int current_direction) {

  if (current_direction != this->current_direction) {

    Debug::check_assertion(current_direction >= 0
        && current_direction < get_nb_directions(),
        StringConcat() << "Invalid direction " << current_direction
        << " for sprite '" << get_animation_set_id()
        << "' in animation '" << current_animation_name << "'");

    this->current_direction = current_direction;

    set_current_frame(0, false);

    if (lua_context != NULL) {
      lua_context->sprite_on_direction_changed(*this, current_animation_name, current_direction);
      lua_context->sprite_on_frame_changed(*this, current_animation_name, 0);
    }
  }
}