// ParsedNoun.js
(function () {
/* global AdventureJS A */
/**
* @class AdventureJS.Parser.ParsedNoun
* @param {Object|AdventureJS.Assets.Asset} asset
* @ajsinternal
* @ajsnavheading ParserClasses
* @summary Special class used to store metadata about an asset
* and lists of all possible matches for that asset.
* @classdesc
* <p>
* <strong>ParsedNoun</strong> is a special class constructed by
* {@link AdventureJS.Parser#parseNoun|Parser.parseNoun()},
* and used to store metadata about an asset and lists of all
* possible matches for that asset. This is an internal class
* that authors should not need to construct.
* </p>
*/
class ParsedNoun {
constructor(asset) {
if (!asset || !asset.id) asset = null;
/**
*
* @var {String} AdventureJS.Parser.ParsedNoun#
* @default
*/
this.class = "ParsedNoun";
/**
*
* @var {Boolean} AdventureJS.Parser.ParsedNoun#exclude
* @default false
*/
this.exclude = false;
/**
*
* @var {String} AdventureJS.Parser.ParsedNoun#plural
* @default ""
*/
this.plural = "";
/**
*
* @var {Boolean} AdventureJS.Parser.ParsedNoun#is_plural
* @default false
*/
this.is_plural = false;
/**
*
* @var {Boolean} AdventureJS.Parser.ParsedNoun#is_all
* @default false
*/
this.is_all = false;
/**
*
* @var {Boolean} AdventureJS.Parser.ParsedNoun#is_group
* @default false
*/
this.is_group = false;
/**
*
* @var {String} AdventureJS.Parser.ParsedNoun#singular
* @default ""
*/
this.singular = "";
/**
*
* @var {String} AdventureJS.Parser.ParsedNoun#type
* @default ""
*/
this.type = "";
/**
* The asset name found in user input, though that may already have been
* replaced with an asset ID by the time this noun gets parsed.
* @var {String} AdventureJS.Parser.ParsedNoun#input
* @default ""
*/
this.input = asset === null ? "" : asset.name;
/**
* Serializing input changes to lowercase, replaces spaces with underscores.
* @var {String} AdventureJS.Parser.ParsedNoun#normalized_input
* @default ""
*/
this.normalized_input = asset === null ? "" : asset.id;
/**
* During parsing we may replace the original input string with
* the ID of a found asset. Ensure that we keep the original.
* @var {String} AdventureJS.Parser.ParsedNoun#original_input
* @default ""
*/
this.original_input = asset === null ? "" : asset.name;
/**
* If a singular asset was found that matched the input, store its ID here.
* @var {String} AdventureJS.Parser.ParsedNoun#is_qualified
* @default ""
*/
this.is_qualified = asset === null ? "" : asset.id;
/**
* Save a variety of information about assets that matched the input.
* @var {Object} AdventureJS.Parser.ParsedNoun#matches
* @default { all:[], qualified:[], qindex:0 }
*/
this.matches = {
all: [],
qualified: [],
// qindex exists because there is a scenario where
// a verb can act without disambiguation upon one
// qualified asset out of a group returned by the parser
qindex: 0,
// matches.qualified can be set from many places.
// setby is a debug code used to trace where it was set.
setby: "",
};
/**
* matches.qualified can be set from many places.
* matchcode is a code used to debug where it was set.
* @var {Object} AdventureJS.Parser.ParsedNoun#matchcode
* @default ""
*/
this.matchcode = "";
if (asset !== null) {
this.matches.all = [asset.id];
this.matches.qualified = [asset.id];
this.matches.qindex = 0;
}
/**
* If a singular asset was found that matched the input, store its ID here.
* We only use this in support of setting is_qualified, the ultimate arbiter.
*
* we set unambiguous but never really rely on it due to the
* scenario described above - safer to use ParsedNoun.asset_id
* it also causes an issue with substances in handleSentence where
* substance is unambiguous though multiple substance containers are found
*
* @var {String} AdventureJS.Parser.ParsedNoun#is_unambiguous
* @default ""
*/
this.is_unambiguous = asset === null ? "" : asset.id;
/**
*
* @var {String} AdventureJS.Parser.ParsedNoun#preposition
* @default ""
*/
this.preposition = "";
/**
*
* @var {Boolean} AdventureJS.Parser.ParsedNoun#is_assumed
* @default false
*/
this.is_assumed = false;
/**
*
* @var {Boolean} AdventureJS.Parser.ParsedNoun#is_platonic
* @default false
*/
this.is_platonic = false;
/**
*
* @var {String} AdventureJS.Parser.ParsedNoun#is_direction
* @default ""
*/
this.is_direction = false;
/**
*
* @var {String} AdventureJS.Parser.ParsedNoun#is_substance
* @default ""
*/
this.is_substance = false;
/**
*
* @var {Boolean} AdventureJS.Parser.ParsedNoun#is_dispenser
* @default false
*/
this.is_dispenser = false;
/**
*
* @var {Boolean} AdventureJS.Parser.ParsedNoun#is_fungible
* @default false
*/
this.is_fungible = false;
return this;
}
/**
* Getter function looks for a qualified asset id, and if it
* doesn't find one, it returns the first qualified match.
* @var {Getter} AdventureJS.Parser.ParsedNoun#asset_id
* @returns {String}
* @TODO returning this.is_unambiguous breaks with platonics
* because you wind up with this:
*
* is_unambiguous: "platonic_pistachio"
* matches:
* all: ['platonic_pistachio']
* qindex: 0
* qualified:['pistachio_0']
*
*/
get asset_id() {
return (
/* this.is_unambiguous || */
this.is_qualified || this.matches.qualified[this.matches.qindex] || null
);
}
/**
* Provides a chainable shortcut method for setting a number of properties on the instance.
* @method AdventureJS.Atom#set
* @memberOf AdventureJS.Atom
* @param {Object} props A generic object containing properties to copy to the Object instance.
* @returns {Object} Returns the instance the method is called on (useful for chaining calls.)
* @chainable
*/
set(props) {
return A.FX.deepSet.call(this.game, props, this);
}
}
AdventureJS.Parser.ParsedNoun = ParsedNoun;
})();