// selectAll.js
(function () {
/*global adventurejs A*/
"use strict";
var p = adventurejs.Parser.prototype;
/**
* Get all gettable assets in current room.
* @method adventurejs.Parser#selectAll
* @memberOf adventurejs.Parser
* @param {String} word
* @returns {Array}
*/
p.selectAll = function Parser_selectAll(word) {
this.game.log("log", "high", "selectAll.js > received: " + word, "Parser");
var currentRoom = this.game.getCurrentRoom();
if (typeof word !== "string") {
console.warn("selectAll received non-string", word);
return [];
}
var roomObjects = this.game.getCurrentRoom().getListableContents();
var playerObjects = this.game.getPlayer().getListableContents();
var foundObjects = [];
var exactMatch = false;
/**
* Word must exist in our lookup table.
* Lookup table associates object IDs
* with every word used by the game.
*
* Keywords represent multiple objects and it's possible
* for a keyword to represent an object with the
* exact name AND other objects with that word in their names.
* Example: "desk" represents both "desk" and "desk drawer"
* If there's an exact match, return that, otherwise return all matches.
*/
var keys = Object.keys(this.game.world_lookup);
while (keys.length > 0) {
if (word === keys[0]) {
for (var i = 0; i < this.game.world_lookup[keys[0]].IDs.length; i++) {
var objectID = this.game.world_lookup[keys[0]].IDs[i];
var object = this.game.getAsset(objectID);
// exclude assets with no getRoomId from "all"
// if( "undefined" === typeof object.getRoomId )
// {
// continue;
// }
// exclude assets outside the room from "all"
// if( object.getRoomId() !== currentRoom.id )
// {
// continue;
// }
// no don't do these because selectAll is not for "all"
// it's for getting all game objects
// exclude scenery events
if (object instanceof adventurejs.Zone) {
continue;
}
// exclude all global objects from all
// because there's nothing you can do to all globals
// this cancels out the following global exit check
// but was added at a later date, so leaving both in for now
if (object.is.global) {
//continue;
}
// exclude global exit if there is a local exit with its direction
// selectPresent redundantly does this check
if (
object instanceof adventurejs.Exit &&
object.is.global &&
"undefined" !== typeof currentRoom.exits[object.direction]
) {
continue;
}
// // never return exits from other rooms
// // TODO will this be a problem with "ask about" ?
// selectPresent redundantly does this check
if (
object instanceof adventurejs.Exit &&
false === object.is.global &&
object.getPlaceAssetId() !== currentRoom.id
) {
continue;
}
/**
* Always exclude player.
* TODO: make this an option?
*/
// commented this on 8/3/20 because it was preventing
// using "me" or "myself"
// not sure why I added it except I think it was breaking
// something and player was appearing in "take all"
// but that might have been a symptom of another bug that I fixed
if (objectID === this.game._player) {
//continue
}
// @todo EXAMINE THIS CODE
// check if input is unparsed substance
// if( object instanceof adventurejs.Substance )
// {
// var containers = 0;
// for( var j = 0; j < roomObjects.length; j++ )
// {
// var roomObject = this.game.getAsset( roomObjects[j] );
// var aspect = roomObject.doesContainSubstance( object.id );
// if( false !== aspect )
// {
// console.warn( " - selectAll " + roomObject.id + ".doesContainSubstance( "+object.id+" ): " + roomObject.doesContainSubstance( object.id ) );
// // becomes for ex: bowl:in:water which can be handled by verbs
// // a result of asset:aspect:substance always means player asked for substance
// // and we found a container of that substance
// containers++;
// foundObjects.push( roomObject.id + ":" + aspect + ":" + object.id );
// }
// }
// if( 0 == containers )
// {
// foundObjects.push( object.id );
// }
// continue;
// }
//var objectID = this.game.world_lookup[ keys[0] ].IDs[i];
let context = `selectAll.js > found world_lookup[ ${keys[0]} ].IDs[${objectID}]`;
console.warn(context);
if (!this.game.getInput().replacements[objectID]) {
this.game.getInput().replacements[objectID] = {
source: keys[0],
context: context,
};
}
foundObjects.push(objectID);
}
}
keys.shift();
}
/**
* Ideally, if there's an asset whose id is an exact match to the
* input word, we'd like to return that. Chiefly we'd like this to
* apply to substances, like "water" or "oil" or "milk", which are singular
* in the sense that, while water may exist in multiple substances, there
* is only one water asset. What this does is, if player inputs "take water",
* it prevents the parser from returning something like:
* "did you mean the sink's hot water handle or the sink's cold water handle?"
*
* In theory it seems like this could be applied to things other than
* substances, but in practice, what happens is you run into cases like this:
* there are objects called "plug" and "sink plug", and player inputs
* "take plug" - and since "plug" is an exact match, "sink plug"
* is always omitted from any list of possible matches.
*
* Have removed / reimplemented this a couple of times... still watching to
* see if there are any unexpected side effects.
*/
for (var i = 0; i < foundObjects.length; i++) {
//console.warn( " - selectAll foundObjects[i]: " + foundObjects[i] );
object = this.game.getAsset(foundObjects[i]);
if (object.id === word && object instanceof adventurejs.Substance) {
foundObjects = [word];
break;
}
}
this.game.log(
"log",
"high",
"selectAll.js > return: " + foundObjects,
"Parser"
);
return foundObjects;
};
})();