// parseNoun.js
(function () {
/*global adventurejs A*/
"use strict";
var p = adventurejs.Parser.prototype;
/**
* Handle noun input.
* @memberOf adventurejs.Parser
* @method adventurejs.Parser#parseNoun
* @param {String} word
* @returns {adventurejs.parsedNoun}
*/
p.parseNoun = function Parser_parseNoun(word) {
this.game.log("log", "high", "parseNoun.js > BEGIN", "Parser");
this.game.log("log", "high", "parseNoun.js received > " + word, "Parser");
var currentRoom = this.game.getCurrentRoom();
var lastTurn = this.input_history[1];
/**
* We're using the input word to create a parsedNoun
* with properties needed by logic down the road.
*/
var parsedNoun = new adventurejs.ParsedNoun();
parsedNoun.input = word;
parsedNoun.serialized_input = A.serialize(word);
parsedNoun.deserialized_input = A.deserialize(word);
// player can enter "it" to refer to last turn's direct object
if (
"it" === word &&
lastTurn &&
lastTurn.parsedNoun1 &&
lastTurn.parsedNoun1.qualified_object_id
) {
word = lastTurn.parsedNoun1.qualified_object_id;
}
/*
* Does the input word match a direction?
* getDirection converts shortcuts to full name,
* eg ne to northeast
* and returns the full name as a string.
*/
var direction = this.dictionary.getDirection(word);
if (direction) {
// save the direction string to matches object
parsedNoun.matches.direction = direction;
}
var asset = this.game.getAsset(word);
if (asset && asset instanceof adventurejs.Substance) {
// save the substance id to matches object
parsedNoun.matches.substance = asset.id;
}
/**
* Noun is direction and room has an exit in that direction.
*/
if (direction && "undefined" !== typeof currentRoom.exits[direction]) {
// save the room's direction object id to matches object
// TODO have we confirmed the room has a direction there?
// console.log("*** currentRoom.exits", currentRoom.exits);
var exitID = currentRoom.exits[direction];
parsedNoun.matches.all.push(exitID);
parsedNoun.matches.qualified.push(exitID);
//parsedNoun.matches.direction = direction;
parsedNoun.qualified_object_id = exitID;
} else if (
/**
* Noun is direction and room does not have an exit in that direction.
* Get global direction object.
*/
direction &&
"undefined" === typeof currentRoom.exits[direction]
) {
// global direction
parsedNoun.matches.all.push("global_" + direction);
parsedNoun.matches.qualified.push("global_" + direction);
} // direction
// if player entered "all" as a noun, we're only looking at
// the current room's contents
else if ("all" === word) {
parsedNoun.matches.all = currentRoom.getAllNestedContents();
} else if (1 === word.split("&").length && 1 === word.split("=").length) {
/**
* User did not ask for "this AND that"
* and world_lookup search returned single ID string
*/
parsedNoun.matches.all = this.game.parser.selectAll(word);
} else if (1 < word.split("&").length || 1 < word.split("=").length) {
/**
* User asked for "this AND that"
* or world_lookup search returned multiple IDs
*/
/**
* Multiple inputs come from player input such as:
* "get brass key and silver key"
*/
// console.log("=======================");
// console.log("MULTIPLE INPUTS!!!");
var multipleInput = word.split("&");
for (var mI = 0; mI < multipleInput.length; mI++) {
console.log(multipleInput);
/**
* Ambiguous inputs come from combineCompoundPhrases,
* which searches world_lookup trying to match
* player input with world objects.
* It doesn't do disambiguation but just passes
* along multiple values.
*
* Example:
* brass_key=old_brass_key,new_brass_key,small_brass_key
*
* The item before the = is the original input.
*/
var ambiguousInput = multipleInput[mI].split("=");
if (1 === ambiguousInput.length) {
parsedNoun.matches.all = parsedNoun.matches.all.concat(
this.game.parser.selectAll(ambiguousInput[0]),
);
this.game.log(
"log",
"low",
"parseNoun.js > Unambiguous match: " + ambiguousInput[0],
"Parser",
);
} else {
this.game.log(
"log",
"low",
"parseNoun.js > Ambiguous matches:",
"Parser",
);
var ambiguousMatches = ambiguousInput[1].split(",");
parsedNoun.input = ambiguousInput[0];
parsedNoun.serialized_input = ambiguousInput[0];
parsedNoun.deserialized_input = A.deserialize(ambiguousInput[0]);
for (var aM = 0; aM < ambiguousMatches.length; aM++) {
var tempParsedNoun = this.game.parser.selectAll(
ambiguousMatches[aM],
);
this.game.log(
"log",
"low",
"parseNoun.js > tempParsedNoun: " + tempParsedNoun,
"Parser",
);
for (var tPN = 0; tPN < tempParsedNoun.length; tPN++) {
parsedNoun.matches.all.push(tempParsedNoun[tPN]);
}
this.game.log(
"log",
"low",
"parseNoun.js > ambiguousMatches: " + ambiguousMatches[aM],
"Parser",
);
} // for loop
} // if( 1 === ambiguousInput.length )
} // for loop
} // else if
// get an array of objects
// we clone all -> qualified so that we can delete
// unqualified objects but still keep a record of all found
parsedNoun.matches.qualified = Object.assign([], parsedNoun.matches.all);
if (0 === parsedNoun.matches.all.length) {
// no objects this word, but it might be a direction
return parsedNoun;
}
//console.error( 'parsedNoun.matches.all',parsedNoun.matches.all );
// for( var i = 0; i < parsedNoun.matches.all.length; i++)
// {
// if( word === parsedNoun.matches.all[i] )
// {
// parsedNoun.matches.all = [word];
// parsedNoun.matches.qualified = [word];
// }
// }
// console.error( 'parsedNoun.matches.all',parsedNoun.matches.all );
if (1 === parsedNoun.matches.all.length) {
// exact match! whoo hoo!
// we still need to know if it's present/visible/reachable
parsedNoun.matches.unambiguous = parsedNoun.matches.all[0];
}
//this.game.log( "log", "high", [ "parseNoun.js > matches.all > " + parsedNoun.matches.all ] , 'Parser' );
/**
* Is the input word plural?
* Bearing in mind that we might have received
* for example, the word "keys" which would simply mean "all keys"
* or we might've received a compound string like
* "grass_keys=red_grass_key,green_grass_key,blue_grass_key"
*/
var lookup = this.game.world_lookup[parsedNoun.deserialized_input];
if ("undefined" !== typeof lookup) {
parsedNoun.type = lookup.type;
if ("singular" === parsedNoun.type) {
parsedNoun.plural = lookup.plural;
}
if ("plural" === lookup.type) {
parsedNoun.isPlural = true;
parsedNoun.singular = lookup.singular;
}
if ("group" === lookup.type) {
parsedNoun.isGroup = true;
parsedNoun.singular = lookup.singular;
}
}
//if( -1 < word.indexOf( "=" ) ) {
// parsedNoun.plural = true;
//}
this.game.log(
"log",
"high",
"parseNoun.js > returns matches.qualified: " +
parsedNoun.matches.qualified,
"Parser",
);
this.game.log("log", "high", "parseNoun.js > END", "Parser");
//console.warn( parsedNoun );
return parsedNoun;
};
})();