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

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

  var p = adventurejs.Parser.prototype;

  /**
   * Handle single-word input.
   * @memberOf adventurejs.Parser
   * @method adventurejs.Parser#handleWord
   */
  p.handleWord = function Parser_handleWord() {
    this.game.log("log", "high", "handleWord.js > Begin parse.", "Parser");
    var this_turn = this.input_history[0];
    var one_word = this_turn.found_word;
    var parsedNoun1, verb_name;
    var last_turn = this.input_history[1];
    var wordToNumber = Number(one_word);
    var msg = "";
    var foundMatch = false;

    /* *
     * Did the last turn prompt for a preposition?
     * See if this turn's input satisfies that.
     * This ran after the verb check until 3/8/23
     * when I noticed an example that needed this
     * to run before the verb check.
     * Example: "put pen table" where? "in"
     * "in" gets parsed as direction verb but should be preposition
     * @TODO keep an eye on this in case it results in verbs failing to parse
     */
    for (let i = 1; i <= 3; i++) {
      if (
        last_turn.soft_prompt["preposition" + i] &&
        this.game.dictionary.isPreposition(one_word)
      ) {
        this.game.log(
          "log",
          "high",
          "handleWord.js > found soft prompt for preposition" + i,
          "Parser"
        );
        // was sentence structure explicitly set with soft prompt? use that. otherwise use last turn's structure
        this_turn.verified_sentence_structure =
          last_turn.soft_prompt.structure ||
          last_turn.verified_sentence_structure;
        this_turn.soft_prompt.satisfied = true;
        this_turn.setOneWord({ ["preposition" + i]: one_word });
        this.game.debug(
          `F1536 | handleWord.js | last turn soft prompted for preposition${i} and ${one_word} recognized as preposition `
        );
        this.handleSentence();
        return;
      }
    } // preposition

    /**
     * is it a verb that is also a noun that satisfies
     * a travel verb like "go" as in "go east"?
     */
    verb_name = this.parseVerb(one_word);
    this.game.log(
      "log",
      "high",
      "handleWord.js > verb_name " + verb_name,
      "Parser"
    );
    if (
      verb_name &&
      last_turn.soft_prompt.noun1 &&
      this.game.dictionary.verbs[verb_name].type.direction
    ) {
      this.game.debug(
        `F1409 | handleWord.js | soft_prompt received ${one_word} which is direction+noun and satisfies ${this_turn.input_verb}`
      );

      this_turn.setOneWord({ noun1: verb_name });
      if (last_turn.soft_prompt.verb) {
        this_turn.setOneWord({ verb: last_turn.soft_prompt.verb });
        this_turn.input_verb =
          this.game.dictionary.verbs[last_turn.soft_prompt.verb].prettyname;
      }
      this.game.log(
        "log",
        "high",
        "handleWord.js > handle soft prompt for noun1",
        "Parser"
      );
      // was sentence structure explicitly set with soft prompt? use that. otherwise use last turn's structure
      this_turn.verified_sentence_structure =
        last_turn.soft_prompt.structure ||
        last_turn.verified_sentence_structure;
      this_turn.soft_prompt.satisfied = true;
      this.handleSentence();
      return;
    }

    /**
     * Is it a verb?
     * Check our one word input against dictionary verbs.
     * parseVerb returns either the base form of the verb,
     * or false if no matching verb.
     * (Unless last turn was a soft prompt,
     * which is almost always looking for a noun. )
     */
    if (verb_name) {
      //let verb = this.dictionary.verbs[verb_name];

      let verb = this.qualifyParsedVerb({
        parsed_verb_name: verb_name,
      });
      if (!verb) return false;

      if (-1 === verb.accepts_structures.indexOf("verb")) {
        this.game.debug(
          `F1052 | handleWord.js | ${verb_name} doesn't accept structure > verb `
        );
        msg += `${verb.type.travel ? "Where" : "What"} did $(we) want to ${
          verb.prettyname
        }? `;
        msg = msg || verb.msgNoObject;
        this_turn.setSoftPrompt({ noun1: true });
        this.game.print(msg, this_turn.output_class);
        return false;
      }
      this_turn.setVerb(1, verb_name);
      this_turn.setStructure("verb");
      this.game.debug(
        `F1537 | handleWord.js | ${verb_name} recognized as verb`
      );
      this.game.dictionary.doVerb(verb_name);
      return true;
    } // verb_name

    // Is it a number?
    // One way or another, let's find a noun.
    if (Number.isInteger(wordToNumber) && last_turn.disambiguate.index) {
      one_word = last_turn.getParsedNoun(last_turn.disambiguate.index).matches
        .qualified[wordToNumber - 1];
      // this can be asset:aspect:substance
      // if so we want to get the asset
      // and this is an ID so we should be able to get the asset
      // without doing another lookup
      // getAsset returns the container not the substance

      if (!one_word) {
        this.game.debug(
          `F1555 | handleWord.js | ${wordToNumber} is not a valid choice`
        );
        msg += wordToNumber + " doesn't seem to make sense. ";
        if (msg) this.game.print(msg, this_turn.output_class);
        return false;
      }

      // @TODO working here
      parsedNoun1 = new adventurejs.ParsedNoun(this.game.getAsset(one_word));
      console.error("parsedNoun1", parsedNoun1);
    } else {
      parsedNoun1 = this.parseNoun(one_word);
    }

    //No matching key found in world_lookup
    //so we can't do anything with it.
    if (0 === parsedNoun1.matches.all.length) {
      this.game.log(
        "log",
        "high",
        "handleWord.js > no matching key found in world_lookup ",
        "Parser"
      );
      this.game.debug(
        `F1174 | handleWord.js | no matching key found in world_lookup`
      );
      msg += this.getUnparsedMessage(one_word);
      this.game.print(msg, this_turn.output_class);
      return false;
    }

    /**
     * Did the last turn prompt for noun disambiguation?
     * See if this turn's input satisfies that.
     */
    if (last_turn.disambiguate.enabled) {
      this.game.log(
        "log",
        "high",
        "handleWord.js > handle noun disambiguation",
        "Parser"
      );
      foundMatch = this.findMatchIn(
        parsedNoun1.matches.qualified,
        last_turn["parsedNoun" + last_turn.disambiguate.index].matches.qualified
      );
      if (foundMatch) {
        this_turn.verified_sentence_structure =
          last_turn.verified_sentence_structure;
        this_turn.setOneWord({
          ["noun" + last_turn.disambiguate.index]: foundMatch,
        });
        this.game.debug(
          `F1543 | handleWord.js | disambiguate foundMatch ${foundMatch}`
        );
        this.handleSentence();
        return;
      } else {
        // last turn called for disambiguation but no match was found
        this.game.debug(`F1556 | handleWord.js | disambiguation failed`);
        msg += `${wordToNumber} doesn't seem to make sense. `;
        if (msg) this.game.print(msg, this_turn.output_class);
        return false;
      }
    }

    /**
     * Did the last turn soft prompt for anything?
     * See if this turn's input satisfies that.
     */
    if (last_turn.soft_prompt.enabled) {
      this.game.debug(
        `F1544 | handleWord.js | soft_prompt received ${one_word}`
      );

      let p = last_turn.soft_prompt;
      let found = p.noun1
        ? "noun1"
        : p.noun2
        ? "noun2"
        : p.noun3
        ? "noun3"
        : p.preposition1
        ? "preposition1"
        : p.preposition2
        ? "preposition2"
        : p.preposition3
        ? "preposition3"
        : false;

      if (found) this_turn.setOneWord({ [found]: one_word });
      if (last_turn.soft_prompt.verb) {
        this_turn.setOneWord({ verb: last_turn.soft_prompt.verb });
        this_turn.input_verb =
          this.game.dictionary.verbs[last_turn.soft_prompt.verb].prettyname;
      }
      this.game.log(
        "log",
        "high",
        "handleWord.js > handle soft prompt for " + found,
        "Parser"
      );
      // was sentence structure explicitly set with soft prompt? use that. otherwise use last turn's structure
      this_turn.verified_sentence_structure =
        last_turn.soft_prompt.structure ||
        last_turn.verified_sentence_structure;
      this_turn.soft_prompt.satisfied = true;
      this.handleSentence();
      return;
    }

    /**
     * Did we receive a string that hasn't satisfied any prompts?
     */
    if (parsedNoun1.object_id === "global_string") {
      this.game.log("log", "high", "handleWord.js > received string", "Parser");
      this.game.debug(`F1546 | handleWord.js | received string `);
      msg += this_turn.strings.toString() + "...?";
      this.game.print(msg, this_turn.output_class);
      return;
    }

    /**
     * Is settings.if_input_is_an_asset_name_examine_it true?
     *
     * If so, naming a noun with no verb is
     * treated as if player had said "examine x"
     */
    if (this.game.settings.if_input_is_an_asset_name_examine_it) {
      this.game.log(
        "log",
        "high",
        "handleWord.js > if_input_is_an_asset_name_examine_it",
        "Parser"
      );

      this.game.debug(
        `F1547 | handleWord.js | if_input_is_an_asset_name_examine_it `
      );

      parsedNoun1 = this.qualifyParsedNoun({
        parsedNoun: parsedNoun1,
        parsedVerb: "examine",
        nounIndex: "1",
      });

      if (false === parsedNoun1) {
        // if qualifyParsedNoun returned false, it also
        // printed an error message, so we can just...
        return false;
      } else {
        // unambiguous object, print default description
        if (1 === parsedNoun1.matches.qualified.length) {
          this_turn.setParsedNoun(1, parsedNoun1);
          this.game.dictionary.doVerb("examine");
          return;
        }
      }
    } // if( this.game.settings.if_input_is_an_asset_name_examine_it )

    // default
    this.game.debug(
      `F1175 | handleWord.js | reached end of function without resolution`
    );
    msg += this.getUnparsedMessage(one_word);
    this.game.print(msg, this_turn.output_class);
    return false;
  };
})();