Pre-release
Adventure.js Docs Downloads
Score: 0 Moves: 0
// selectTakeable.js

(function () {
  /*global adventurejs A*/
  "use strict";

  var p = adventurejs.Parser.prototype;

  /**
   * Exclude from a list of assets all assets that can't be taken by player.
   * @method adventurejs.Parser#selectTakeable
   * @memberOf adventurejs.Parser
   * @param {Array} list
   * @returns {Array}
   */
  p.selectTakeable = function Parser_selectTakeable(list) {
    // we already know it's present and visible and reachable
    if ("string" === typeof list) list = [list];
    if (!Array.isArray(list)) {
      this.game.log(
        "warn",
        "critical",
        "selectTakeable.js > received non-array",
        "Parser"
      );
      return [];
    }
    var player = this.game.getPlayer();
    var foundObjects = [];
    for (var i = 0; i < list.length; i++) {
      var object = this.game.getAsset(list[i]);

      if (!object.isDOV("take")) {
        if (
          object instanceof adventurejs.Room &&
          list[i].split(":").length === 3
        ) {
          // it's a substance in a room, which is not technically takeable,
          // but we're going to let take verb handle that
          foundObjects.push(list[i]);
        }

        continue;
      }

      // if object is a plug, test against its parent
      if (object.IOVisConnectedToAnything("plug")) {
        object = object.getPlaceAsset();
      }

      // if it has no getParent method then it's not takeable
      // not originally intended but this applies directly to substances
      if (!object.getPlaceAsset) continue;
      var parent = object.getPlaceAsset();
      if (!parent) continue;

      // player's already holding it or wearing it
      //if( parent.id === player.id ) continue;
      // going to let verbs handle this

      /**
       * If any of object's anscestors are closed we'll consider
       * the object not takeable,
       * unless it's nested in player inventory. We'll be nice and
       * let player access their inventory without having to
       * open every damned container.
       *
       * In theory we could do the same for any nested & known objects,
       * but that could raise unpredictable conflicts in situations
       * like taking objects from NPCs, or inadvertently triggering
       * or bypassing custom functions.
       */
      //if( false === object.areAnscestorsClosed()
      if (
        object.areAnscestorsClosed &&
        object.areAnscestorsClosed() &&
        !object.isIn(player)
      ) {
        continue;
      }
      // TODO
      // check if parent is transparent

      /**
       * We don't handle this here because author is likely
       * to want complex interaction on trying to take something
       * from a character. Leaving it commented for later exploration.
       */
      // if( parent instanceof adventurejs.Character
      //   && false === parent.isIOV("take")
      // ) {
      //   continue;
      // }

      foundObjects.push(list[i]);
    }

    return foundObjects;
  };
})();