Pre-release
Adventure.js Docs Downloads
Score: 0 Moves: 0
// getIOVkeys.js
(function () {
  /*global adventurejs A*/
  "use strict";
  var p = adventurejs.Character.prototype;
  /**
   * Returns a list of assets carried by the player, if any, that can perform
   * the specified verb upon the specified asset as defined in the
   * target asset.dov[verb].with_assets/with_classes
   * property. Works with verbs including open & close, pick,
   * lock & unlock, and seal & unseal.
   * @memberOf adventurejs.Character
   * @method adventurejs.Character#getIOVkeys
   * @param {String} verb The name of a verb.
   * @param {Object|String} direct_object An asset or asset ID of a direct object that the player has tried to perform an indirect verb on.
   * @returns {Array} An array of Key assets, if player has any.
   */
  p.getIOVkeys = function Character_getIOVkeys(verb, direct_object) {
    //console.warn('getIOVkeys',verb, direct_object, this.game.dictionary.verbs[verb] );
    // we might've received a string
    if ("string" === typeof direct_object)
      direct_object = this.game.getAsset(direct_object);
    if (
      !verb ||
      !this.game.dictionary.verbs[verb] ||
      !direct_object ||
      !direct_object.isDOV(verb)
    )
      return [];

    this.game.log(
      "log",
      "high",
      "getIOVkeys.js >  " + verb + " " + direct_object.name,
      "Game"
    );

    var indirect_objects = [];
    // classes_that_can_verb_this
    var direct_object_classes = direct_object.dov[verb].with_classes;
    var direct_object_assets = direct_object.dov[verb].with_assets;

    // get class instances in player
    // findClassInThis calls getAllNestedContents
    if (direct_object_classes) {
      for (var i = 0; i < direct_object_classes.length; i++) {
        var classed_ids = this.findClassInThis(direct_object_classes[i]);
        for (var id = 0; id < classed_ids.length; id++) {
          // findClassInThis returns ids so we gotta get assets
          var classet = this.game.getAsset(classed_ids[id]);
          if (classet) indirect_objects.push(classet);
        }
      }
    }

    // find direct_object_assets in character
    if (direct_object_assets) {
      for (var i = 0; i < direct_object_assets.length; i++) {
        var indirect_object = this.game.getAsset(direct_object_assets[i]);
        if (indirect_object.isIn(this)) indirect_objects.push(indirect_object);
      }
    }

    // classes_this_can_verb
    var inventory = this.getAllNestedContents();
    for (var i = 0; i < inventory.length; i++) {
      var inventory_item = this.game.getAsset(inventory[i]);
      if (
        inventory_item.iov[verb]?.with_classes &&
        -1 !== inventory_item.iov[verb]?.with_classes.indexOf(direct_object.id)
      ) {
        var dupe = false;
        for (var asset in indirect_objects) {
          if (indirect_objects[asset].id === inventory_item.id) dupe = true;
        }
        if (!dupe) indirect_objects.push(indirect_object);
      }
    }

    // subtract unknown / unreachable items
    for (var i = indirect_objects.length - 1; i > -1; i--) {
      // it's possible for player to not know about items in inventory
      var asset = indirect_objects[i];
      if (!asset.is.known) indirect_objects.splice(i);
      if (!asset.areAnscestorsKnown()) indirect_objects.splice(i);
    }

    return indirect_objects;
  };
})();