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

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

  var p = adventurejs.Parser.prototype;

  /**
   * Exclude from a list of assets all assets that are not visible to player.
   * @method adventurejs.Parser#selectVisible
   * @memberOf adventurejs.Parser
   * @param {Array} list
   * @returns {Array}
   * @todo consider global darkness
   */
  p.selectVisible = function Parser_selectVisible(list) {
    if ("string" === typeof list) list = [list];
    if (!Array.isArray(list)) {
      this.game.log(
        "warn",
        "critical",
        "selectVisible.js > received non-array",
        "Parser",
      );
      return [];
    }
    // we already know it's present
    var player = this.game.getPlayer();
    var currentRoom = this.game.getCurrentRoom();
    var foundObjects = [];
    var roomObjects = [];

    for (var i = 0; i < list.length; i++) {
      var object;

      // check if input was already parsed by an earlier step
      // as substance:in:tangible in which case verify the tangible
      // var asset_aspect_substance = list[i].split(":");
      // if( 3 === asset_aspect_substance.length )
      // {
      //   object = this.game.getAsset( asset_aspect_substance[2] );
      // }
      // else {
      object = this.game.getAsset(list[i]); // may return substance
      // }

      // abstractions are always visible
      if (object.is.abstract) {
        foundObjects.push(list[i]);
        continue;
      }

      // global objects are always visible, barring darkness
      // @TODO probably some complexities to explore here,
      // like seeing sun, moon, sky from underground
      if (object.is.global) {
        foundObjects.push(list[i]);
        continue;
      }

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

      // check if input is unparsed substance
      // if( object instanceof adventurejs.Substance )
      // {
      //   if( 0 === roomObjects.length )
      // {
      //     roomObjects = currentRoom.getListableContents();
      //   }
      //   for( var j = 0; j < roomObjects.length; j++ )
      // {
      //     var roomObject = this.game.getAsset( roomObjects[j] );
      //     var loc = roomObject.doesContainSubstance( object.id );
      //     if( false !== loc )
      // {
      //       console.warn( " - selectVisible " + roomObject.id + ".doesContainSubstance( "+object.id+" ): " + roomObject.doesContainSubstance( object.id ) );
      //       // becomes for ex: water:in:bowl which can be handled by verbs
      //       foundObjects.push( object.id + ":" + loc + ":" + roomObject.id );
      //     }
      //   }
      //   continue;
      // }

      /*
				TODO

				get ambient light level
				- get light provided by all lightsources?
				get object's min_light_required_to_see

				hidden in a container - visible? or reachable?
				also consider container's opacity

      */

      if (object.is.hidden) {
        continue;
      }

      // if it has no parent, and it's not a room,
      // then it's not present in the world
      if (!object.getPlaceAsset() && !(object instanceof adventurejs.Room)) {
        continue;
      }

      /**
       * If object's anscestor is closed we'll consider it not visible
       * 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 problems in situations like taking
       * objects from NPCs, or inadvertently triggering custom functions.
       */
      //console.warn( 'selectVisible > areAnscestorsClosed()',object.areAnscestorsClosed() );
      if (
        object.areAnscestorsClosed &&
        object.areAnscestorsClosed() &&
        !object.isIn(player)
      ) {
        continue;
      }
      // TODO
      // check if parent is transparent
      // drain with plug
      // bottle with plug

      foundObjects.push(list[i]);
    }

    //console.log( "selectVisible returned " + foundObjects );
    return foundObjects;
  };
})();