Pre-release
AdventureJS Docs Downloads Bundler Devlog Score: 0 Moves: 0
// getStringArrayFunction.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/BasicScripting_StringArrayFunction.html">How to Use String Array Function</a>.
 * @method AdventureJS#getStringArrayFunction
 * @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.FX.getSAF()
 */
AdventureJS.FX.getStringArrayFunction = AdventureJS.FX.getSAF =
  function AdventureJS_getStringArrayFunction(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 ("boolean" === typeof obj || null === obj) {
      return obj;
    } // bool / null

    if ("string" === typeof obj) {
      if (obj.startsWith("[append]")) {
        obj = obj.replace("[append]", "");
        this.game.appendOutput(obj);
        return; // "" ?
      } else if (obj.startsWith("[prepend]")) {
        obj = obj.replace("[prepend]", "");
        this.game.prependOutput(obj);
        return; // "" ?
      } else if (obj.startsWith("[override]")) {
        obj = obj.replace("[override]", "");
        this.game.overrideOutput(obj);
        return; // "" ?
      } else {
        // this.game.appendOutput(obj);
        return obj;
      }
      // return obj;
    }

    // if it's an array, convert to object
    if (Array.isArray(obj)) {
      obj = {
        use_saf: true,
        randomize: false,
        reset: false,
        chance: 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_SAF;
      }

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

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

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

      // does chance permit printing?
      if (obj.chance < 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 =
            "getStringArrayFunction found an array item that is something other than a string.";
          this.log("L1540", "warn", 0, err, "Game");
        }
        return msg;
      } // random

      // get it
      msg = obj.array[obj.index];

      // check it
      if ("string" !== typeof msg) {
        msg = "";
        err =
          "getStringArrayFunction found an array item that is something other than a string.";
        this.log("L1541", "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 ("undefined" === typeof msg) {
        msg = "";
        err =
          "getStringArrayFunction called a function that returned undefined.";
        this.log("L1542", "log", 0, err, "Game");
      }
      return msg;
    } // function
  };