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

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

  var p = adventurejs.Parser.prototype;

  /**
   * Exclude from a list of assets all assets that are not present in current room.
   * @method adventurejs.Parser#selectPresent
   * @memberOf adventurejs.Parser
   * @param {Array} list
   * @returns {Array}
   */
  p.selectPresent = function Parser_selectPresent(list) {
    if ("string" === typeof list) list = [list];
    if (!Array.isArray(list)) {
      this.game.log(
        "warn",
        "critical",
        "selectPresent.js > received non-array",
        "Parser"
      );
      return [];
    }
    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 asset:aspect:substance 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]);
      // }

      /**
       * check if input is unparsed substance
       * I've commented and uncommented this a couple of times.
       * Latest uncomment on 2023.04.08
       * Needed in order to handle "water" as a substance
       * specifically in the case of "pour water" while player
       * is holding a bowl full of water.
       */
      if (object instanceof adventurejs.Substance) {
        // this version automatically returns substances as present
        // foundObjects.push( list[i] );
        // continue;

        // this version looks for substance containers
        //console.warn( " - selectPresent " + object.id + " is substance" );
        if (0 === roomObjects.length) {
          //roomObjects = currentRoom.getListableContents();
          roomObjects = currentRoom.getAllNestedContents();
        }
        roomObjects.push(currentRoom.id);
        //console.warn( "roomObjects", roomObjects );
        for (var j = 0; j < roomObjects.length; j++) {
          var roomObject = this.game.getAsset(roomObjects[j]);
          if (!roomObject.is.known) continue;
          var aspect = roomObject.doesContainSubstance(object.id);
          if (aspect) {
            console.warn(
              " - selectPresent " +
                roomObject.id +
                ".doesContainSubstance( " +
                object.id +
                " ): " +
                roomObject.doesContainSubstance(object.id)
            );
            // becomes for ex: bowl:in:water which can be handled by verbs
            foundObjects.push(roomObject.id + ":" + aspect + ":" + object.id);
          }
        }
      }

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

      // walls, floor, ceiling, scenery
      // all prefixed with "global_"
      if (object.is.global) {
        console.warn("global object", object);
        if (object instanceof adventurejs.GlobalString) {
          foundObjects.push(list[i]);
          continue;
        }

        if (object instanceof adventurejs.Floor) {
          if (this.game.getCurrentRoom().findClassInThis("Floor").length)
            continue;
        }

        // room says yes
        if (
          "undefined" !== typeof currentRoom.room_scenery[object.id] &&
          true === currentRoom.room_scenery[object.id].enabled
        ) {
          foundObjects.push(list[i]);
          console.warn(
            "selectPresent > true === currentRoom.room_scenery[ object.id ].enabled"
          );
          continue;
        }

        // room says no
        if (
          "undefined" !== typeof currentRoom.room_scenery[object.id] &&
          false === currentRoom.room_scenery[object.id].enabled
        ) {
          console.warn(
            "selectPresent > false === currentRoom.room_scenery[ object.id ].enabled"
          );
          continue;
        }

        // room says neither true nor false

        // if room has no true / false setting, check for zone

        // zone says yes
        if (
          "undefined" !== typeof this.game.world[currentRoom.zone] &&
          "undefined" !==
            typeof this.game.world[currentRoom.zone].zone_scenery[object.id] &&
          true ===
            this.game.world[currentRoom.zone].zone_scenery[object.id].enabled
        ) {
          foundObjects.push(list[i]);
          console.warn(
            "selectPresent > true === this.game.world[ currentRoom.zone ].zone_scenery[ object.id ].enabled"
          );
          continue;
        }

        // zone says no
        if (
          "undefined" !== typeof this.game.world[currentRoom.zone] &&
          "undefined" !==
            typeof this.game.world[currentRoom.zone].zone_scenery[object.id] &&
          false ===
            this.game.world[currentRoom.zone].zone_scenery[object.id].enabled
        ) {
          console.warn(
            "selectPresent > false === currentRoom.zone.zone_scenery[ object.id ].enabled"
          );
          continue;
        }

        // zone says neither true nor false

        if (object.enabled) {
          console.warn("selectPresent > true === object.enabled");
          foundObjects.push(list[i]);
        }

        continue;
      }

      // exclude global exit if there is a local exit with its direction
      if (
        object instanceof adventurejs.Exit &&
        object.is.global &&
        "undefined" !== typeof currentRoom.exits[object.direction]
      ) {
        continue;
      }

      // include global exit if there is no local exit with its direction
      if (
        object instanceof adventurejs.Exit &&
        object.is.global &&
        "undefined" === typeof currentRoom.exits[object.direction]
      ) {
        foundObjects.push(list[i]);
        continue;
      }

      // never return exits from other rooms
      // TODO will this be a problem with "ask about" ?
      if (
        object instanceof adventurejs.Exit &&
        !object.is.global &&
        object.getPlaceAssetId() !== this.game.world._currentRoom
      ) {
        continue;
      }

      if (object.id === this.game.world._currentRoom) {
        foundObjects.push(list[i]);
        continue;
      }

      if (object.isIn && object.isIn(this.game.getCurrentRoom())) {
        foundObjects.push(list[i]);
        continue;
      }

      // for substances
      // examine every item in the room for substance container
      //if( object.contains_substance)

      // if there's a global object, list that
      // if( -1 < object.id.indexOf( "global_" ) ) {
      //   //console.log( "selectPresent found " + object.name );
      //   foundObjects.push( list[i] );
      //   continue;
      // }
    }
    //console.log( "selectPresent returned " + foundObjects );
    return foundObjects;
  };
})();