// getStringOrArrayOrFunction.js
/*global adventurejs A*/
"use strict";
/**
* <p>
* Get string or array or function.
* Because Javascript is untyped, we can pass any kind of value in a
* variable. We take advantage of that here to provide flexibility
* to authors in properties that print a string back to the player.
* </p>
* <ul>
* <li><strong>Strings</strong> will be printed as is.</li>
* <li><strong>Arrays</strong> can be set to provide a string from
* a randomized index, or a sequential index that increments each time
* it's called.</li>
* <li><strong>Functions</strong> can use their
* own internal logic to return a string, allowing for dynamic
* state-based descriptions, such as whether an Asset is open or closed.
* </ul>
* <h3 class="examples">Example:</h3>
* <pre class="display"><code class="language-javascript">MyGame.createAsset({
* class: "Desk",
* name: "desk",
* descriptions: { look: "An old school wooden desk. ", },
* });
* MyGame.createAsset({
* class: "Drawer",
* name: "drawer",
* descriptions: {
* look: function(){
* return "The drawer is $( drawer is| open or| closed ). ";
* },
* },
* });
* MyGame.createAsset({
* class: "Blotter",
* name: "blotter",
* descriptions: {
* look: [
* {randomize: true},
* "The words 'live and let die' are scrawled on the blotter. ",
* "The desk blotter has 'born to bleed' carved into it. ",
* "You see 'zep rulez!' scratched in to the desk blotter. ",
* ],
* },
* });
* </code></pre>
* <p>
* For more information, see
* <a href="/doc/Scripting_StringArrayFunction.html">How to Use String|Array|Function</a>.
* </p>
* <h3 class="examples">Properties that call getStringOrArrayOrFunction</h3>
* <ul>
* <li>verb subscription on_success: asset.[i|d]ov[verb].on_success</li>
* <li>verb subscription then_destroy: asset.[i|d]ov[verb].then_destroy</li>
* <li>all descriptions: asset.description and asset.descriptions[any]</li>
* <li>room events: room.room_events</li>
* <li>zone events: room.zone.zone_events</li>
* <li>custom vars: MyGame.world._vars[ property ]</li>
* <li>constraint message: character.constrained_msg</li>
* </ul>
*
* @method adventurejs#getStringOrArrayOrFunction
* @memberOf adventurejs
* @param {String|Array|Function|Boolean|null} obj Can be string or array or function.
* @param {Object} scope Optional reference to set scope to an object.
* @param {Object} params Optional params to pass to a function.
* @returns {String}
* @ajsalias A.getSAF()
*/
adventurejs.getStringOrArrayOrFunction = adventurejs.getSAF =
function Adventurejs_getStringOrArrayOrFunction(obj, scope, params = {}) {
// console.warn( 'getSAF', obj );
var msg = "";
var err = "";
// if it's string or bool or null just pass it on
if ("string" === typeof obj || "boolean" === typeof obj || null === obj) {
return obj;
} // string / bool / null
// if it's an array, check for meta data in first position
if (Array.isArray(obj)) {
if ("object" !== typeof obj[0]) {
obj.unshift({
randomize: false,
frequency: 1,
index: 0,
});
} // object in first slot?
// ensure that we have randomize setting
if ("undefined" === typeof obj[0].randomize) {
obj[0].randomize =
this.game.settings.randomize_arrays_in_getStringOrArrayOrFunction;
}
// ensure that we have index object
if ("undefined" === typeof obj[0].index) {
obj[0].index = 0;
}
// ensure that we have frequency setting
if ("undefined" === typeof obj[0].frequency) {
obj[0].frequency = 1;
}
// are we randomizing?
if (true === obj[0].randomize) {
var rand = Math.floor(Math.random() * (obj.length - 2) + 1);
msg = obj[rand];
// we might be calling an arbitrary function set by an author
// that isn't returning a string
if ("string" !== typeof msg) {
msg = "";
err =
"getStringOrArrayOrFunction found an array item that is something other than a string.";
this.log("warn", 0, err, "Game");
}
return msg;
} // random
// if we're not randomizing then we're sequencing, so increment
// we increment here instead of at the end because we may have
// just changed the length by adding the meta object
obj[0].index++;
// if at end, reset to beginning
if (obj[0].index === obj.length) {
obj[0].index = 1;
}
// get it
msg = obj[obj[0].index];
// check it
if ("string" !== typeof msg) {
msg = "";
err =
"getStringOrArrayOrFunction found an array item that is something other than a string.";
this.log("warn", 0, err, "Game");
//console.warn( msg, obj[rand] );
}
return msg;
} // isArray
if (typeof obj === "function") {
// it's a function so call it
// passing this because there's some scope weirdness
msg = scope ? obj.call(scope) : obj(this);
// we might be calling an arbitrary function set by an author
// that isn't returning a string
if ("string" !== typeof msg) {
msg = "";
err =
"getStringOrArrayOrFunction called a function that returned something other than a string.";
this.log("warn", 0, err, "Game");
}
return msg;
} // function
};