Pre-release
AdventureJS Docs Downloads
Score: 0 Moves: 0
// getStringOrArrayOrFunction.js

/*global adventurejs A*/

/**
 * This is an important and flexible tool in the author's quiver.
 * Because Javascript is untyped, we can pass any kind of value in a
 * variable. We take advantage of that to set properties that
 * print a string back to the player using a string or an array
 * or a function. For more information and examples, see
 * <a href="/doc/Scripting_StringArrayFunction.html">How to Use String|Array|Function</a>.
 * @method adventurejs#getStringOrArrayOrFunction
 * @memberOf adventurejs
 * @param {*} 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 = {}) {
    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, convert to object
    if (Array.isArray(obj)) {
      obj = {
        use_saf: true,
        randomize: false,
        frequency: 1,
        index: 0,
        array: obj,
      };
    }

    // object with array
    if (obj && obj.array) {
      // ensure that we have use_saf setting
      if ("undefined" === typeof obj.use_saf) {
        obj.use_saf = true;
      }

      // ensure that we have randomize setting
      if ("undefined" === typeof obj.randomize) {
        obj.randomize =
          this.game.settings.randomize_arrays_in_getStringOrArrayOrFunction;
      }

      // ensure that we have reset setting
      if ("undefined" === typeof obj.reset) {
        obj.reset =
          this.game.settings.reset_arrays_in_getStringOrArrayOrFunction;
      }

      // ensure that we have index object
      if ("undefined" === typeof obj.index) {
        obj.index = 0;
      }

      // ensure that we have frequency setting
      if ("undefined" === typeof obj.frequency) {
        obj.frequency = 1;
      }

      // does frequency permit printing?
      if (obj.frequency < Math.random() * 1) {
        return "";
      }

      // are we randomizing?
      if (obj.randomize) {
        // this version left over from when we added a property
        // object to the first position of the array
        // var rand = Math.floor(Math.random() * (obj.array.length - 2) + 1);

        // this version handles obj.array
        var rand = Math.floor(Math.random() * obj.array.length);

        msg = obj.array[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

      // get it
      msg = obj.array[obj.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");
      }

      // if we're not randomizing then we're sequencing,
      // so increment the counter
      obj.index++;

      // reset if needed
      if (obj.index >= obj.array.length) {
        obj.index = obj.reset ? 0 : obj.array.length - 1;
      }

      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
  };