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

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

  /**
   * @augments {adventurejs.Verb}
   * @class type
   * @ajsnode game.dictionary.verbs.type
   * @ajsconstruct MyGame.createVerb({ "name": "type", [...] });
   * @ajsconstructedby adventurejs.Dictionary#createVerb
   * @hideconstructor
   * @ajsinstanceof Verb
   * @ajsnavheading CompositionVerbs
   * @summary Verb meaning type, as in "type on keyboard".
   * @tutorial Scripting_VerbSubscriptions
   * @tutorial Verbs_VerbAnatomy
   * @tutorial Verbs_VerbProcess
   * @tutorial Verbs_ModifyVerbs
   * @tutorial Verbs_WriteVerbs
   * @classdesc
   * <pre class="display border outline">
   * <span class="input">&gt; type on keyboard</span>
   * You type on the keyboard. PEFBIJOVAS;DVLKJ ;LAJKSVJVJLS J.
   * Well, walk across it, more like. Your paws aren't very precise.
   * The computer blares a warning: "CAT-LIKE TYPING DETECTED!"
   * </pre>
   * <p>
   * <strong>Type</strong> on a {@link adventurejs.Tangible|Tangible}
   * {@link adventurejs.Asset|Asset}.
   * Requires that the Asset has
   * asset.dov.type.enabled set to true. <strong>Type</strong> takes account
   * of the Asset's parent, so for instance it correctly interprets
   * <code class="property">type on paper</code> if paper is in a
   * typewriter.
   * </p>
   * @ajsverbreactions
   * @ajsverbphases doBeforeTry, doAfterTry, doBeforeSuccess, doAfterSuccess
   */
  A.Preverbs.type = {
    name: "type",
    prettyname: "type on",
    past_tense: "typed",
    synonyms: ["type"],
    // verb_prep_noun: [ "type on" ],

    /**
     * @ajsverbstructures
     * @memberof type
     */
    accepts_structures: [
      "verb noun",
      "verb preposition noun",
      "verb noun preposition noun",
    ],

    /**
     * @memberof type
     * @ajsverbphrase
     * phrase1:
     * {
     *   accepts_noun: true,
     *   requires_noun: true,
     *   noun_must_be:
     *   {
     *     known: true,
     *     present_if_tangible: true,
     *     reachable_if_tangible: true,
     *   },
     *   accepts_preposition: true,
     *   accepts_these_prepositions: ["on"],
     * },
     */
    phrase1: {
      accepts_noun: true,
      requires_noun: true,
      noun_must_be: {
        known: true,
        present_if_tangible: true,
        reachable_if_tangible: true,
      },
      accepts_preposition: true,
      accepts_these_prepositions: ["on"],
    },

    /**
     * @memberof type
     * @ajsverbphrase
     * phrase2:
     * {
     *   accepts_noun: true,
     *   accepts_preposition: true,
     *   requires_preposition: true,
     *   accepts_these_prepositions: ["on"],
     *   noun_must_be:
     *   {
     *     known: true,
     *     present_if_tangible: true,
     *     reachable_if_tangible: true,
     *   },
     * },
     */
    phrase2: {
      accepts_noun: true,
      accepts_preposition: true,
      requires_preposition: true,
      accepts_these_prepositions: ["on"],
      noun_must_be: {
        known: true,
        present_if_tangible: true,
        reachable_if_tangible: true,
      },
    },

    /**
     * @memberof type
     * @ajsverbparams
     * with_params: {},
     */
    with_params: {},

    doTry: function () {
      var input = this.game.getInput();
      var player = this.game.getPlayer();
      var direct_object = input.getAsset(1);
      var direct_preposition = input.getPreposition(1);
      var indirect_object = input.getAsset(2);
      var indirect_preposition = input.getPreposition(2);
      var direct_object_place, indirect_object_place;
      var typing_target;
      var room = this.game.getCurrentRoom();
      var msg = "";

      if (
        input.hasStructure("verb noun") ||
        input.hasStructure("verb noun preposition noun")
      ) {
        // @TODO other information types like password or name
        if (!(direct_object instanceof adventurejs.GlobalString)) {
          this.game.debug(
            `F1663 | ${this.name}.js | ${direct_object.id} can not be typed `,
          );
          msg += `$(We) can't type ${direct_object.articlename}. `;
          this.handleFailure(msg);
          return null;
        }
      }

      // did player input "type foo" ?
      if (input.hasStructure("verb noun")) {
        // see if there's an obvious keyboard
        var room_contents = room.getAllNestedContents();
        var asset = null;
        var typers = [];

        for (var i = 0; i < room_contents.length; i++) {
          var id = room_contents[i];
          var asset = this.game.getAsset(id);
          if (!asset) continue;
          if (asset.isDOV("type")) {
            typers.push(id);
          }
        }

        if (typers.length) {
          typers = this.game.parser.selectKnown(typers);
          typers = this.game.parser.selectReachable(typers);
          typers = this.game.parser.selectVisible(typers);
        }

        switch (typers.length) {
          case 0:
            this.game.debug(
              `F1663 | ${this.name}.js | no assets found with .dov.type.enabled set to true `,
            );
            msg += `$(We) don't see anything to type on. `;
            this.handleFailure(msg);
            return null;

          case 1:
            // set input phrase2 to the keyboard
            input.setPhrase(2, {});
            input.setAsset(2, this.game.getAsset(typers[0]));
            input.setPreposition(2, "on");
            input.setAssumed(2, true);
            indirect_object = input.getAsset(2);
            indirect_preposition = "on";
            input.setStructure("verb noun preposition noun");
            console.warn("typer", typers[0]);
            break;

          default:
            this.game.debug(
              `F1664 | ${this.name}.js | multiple keyboards found, disambiguate `,
            );
            // ask player to choose a keyboard
            input.setParsedNoun(2, new adventurejs.ParsedNoun());
            input.setPreposition(2, "on");
            // save containers back to input for next turn disambiguation
            input.setParsedNounMatchesQualified(2, typers);
            // revise the sentence structure
            input.setStructure("verb noun preposition noun");
            this.game.parser.printNounDisambiguation({
              parsedNoun: input.getParsedNoun(2),
              nounIndex: 2,
            });
            return null;
        } // switch
      } // verb noun

      if (input.hasStructure("verb preposition noun")) {
        // can player type on it?
        if (!direct_object.isDOV("type")) {
          // if not, is it something like a piece of paper in a typewriter?
          direct_object_place = direct_object.getPlaceAsset();
          if (
            direct_object.can.be_typed_on && // ie paper
            direct_object_place.isDOV("type")
          ) {
            // ie typewriter
            typing_target = direct_object;
            input.verb_params.typing_target = typing_target;
            direct_object = direct_object_place;
            input.setAsset(1, direct_object);
            input.setAssumed(1, true);
          }
        }

        if (!direct_object.isDOV("type")) {
          this.game.debug(
            `F1665 | ${this.name}.js | ${direct_object.id} .dov.type.enabled is false `,
          );
          msg += `$(We) can't type on ${direct_object.articlename}. `;
          this.handleFailure(msg);
          return null;
        }
      } // verb preposition noun

      if (input.hasStructure("verb noun preposition noun")) {
        // can player type on it?
        if (!indirect_object.isDOV("type")) {
          // if not, is it something like a piece of paper in a typewriter?
          indirect_object_place = indirect_object.getPlaceAsset();
          if (
            indirect_object.can.be_typed_on && // ie paper
            indirect_object_place.isDOV("type")
          ) {
            // ie typewriter
            typing_target = indirect_object;
            input.verb_params.typing_target = typing_target;
            indirect_object = indirect_object_place;
            input.setAsset(2, indirect_object);
            input.setAssumed(2, true);
          }
        }

        if (!indirect_object.isDOV("type")) {
          this.game.debug(
            `F1666 | ${this.name}.js | ${indirect_object.id} .dov.type.enabled is false `,
          );
          msg += `$(We) can't type on ${indirect_object.articlename}. `;
          this.handleFailure(msg);
          return null;
        }

        // does indirect_object contain something that can.be_typed_on?
        if (!typing_target && indirect_object.hasAspectAt("in")) {
          var contents = indirect_object.getAspectAt("in");
          if (contents) contents = contents.contents;
          for (var i = 0; i < contents.length; i++) {
            var asset = this.game.getAsset(contents[i]);
            if (!asset) continue;
            if (asset.can.be_typed_on) {
              // take the first thing found
              typing_target = asset;
              input.verb_params.typing_target = typing_target;
              break;
            }
          }
        }
      }

      return true;
    },

    doSuccess: function () {
      var input = this.game.getInput();
      var player = this.game.getPlayer();
      var direct_object = input.getAsset(1);
      var direct_preposition = input.getPreposition(1);
      var indirect_object = input.getAsset(2);
      var indirect_preposition = input.getPreposition(2);
      var typing_target;
      var results;
      var msg = "";

      if (input.verb_params.typing_target)
        typing_target = input.verb_params.typing_target;

      this.game.debug(`F1459 | ${this.name}.js | print doSuccess `);

      if (input.hasStructure("verb noun")) {
        msg += "This should not happen. ";
      }

      if (input.hasStructure("verb preposition noun")) {
        msg += `$(We) type on ${direct_object.articlename}. `;
      }

      if (input.hasStructure("verb noun preposition noun")) {
        msg += "$(We) type ";
        if (0 < input.strings.length) {
          if (typing_target)
            typing_target.written_strings.push(input.strings[0]);
          msg += input.strings[0] + " ";
        }
        msg += "on " + indirect_object.articlename + ". ";
      }

      // print output
      this.handleSuccess(msg, direct_object);
      return true;
    },
  };
})(); // type