Pre-release
Adventure.js Docs Downloads
Score: 0 Moves: 0
// StateManager.js
(function () {
  /*global adventurejs A*/
  "use strict";

  /**
   * @ajspath adventurejs.Atom.StateManager
   * @augments adventurejs.Atom
   * @class adventurejs.StateManager
   * @ajsnavheading FrameworkReference
   * @param {String} game_name Name of top level game instance that is scoped to window.
   * @param {String} name Instance name.
   * @param {String} parent_id The ID of the containing asset instance.
   * @summary A container for state variables.
   * @classdesc
   * <p>
   * <strong>StateManager</strong> is a special class used
   * for storing general state variables. For example,
   * <a href="/doc/adventurejs.Tangible.html#property_is">tangible.is</a>
   * is used to store states such as
   * <a href="/doc/adventurejs.Tangible.html#property_is_closed">tangible.is.closed</a>,
   * <a href="/doc/adventurejs.Tangible.html#property_is_locked">tangible.is.locked</a>,
   * <a href="/doc/adventurejs.Tangible.html#property_is_global">tangible.is.global</a>,
   * etc.
   * This is done chiefly for organizational purposes. With hundreds of
   * properties per asset, it seemed cleaner
   * to group similar types of properties into clusters and access them
   * through dot notation, rather than leave hundreds of properties
   * floating around the top level of each object. The reason to make it a
   * classed object rather than a generic object (as we do for some collections)
   * is so we can add prototype methods and properties that have access to scope
   * of <code>this</code> (meaning the parent asset) and <code>game</code>
   * (the top level game object).
   * <br><br>
   * State containers and their values are passed down the inheritance chain.
   * For example: {@link adventurejs.Tangible|Tangible} inherits from
   * {@link adventurejs.Asset|Asset}, and
   * <a href="/doc/adventurejs.Asset.html#property_is_global">asset.is.global</a>
   * is available on
   * <a href="/doc/adventurejs.Tangible.html#property_is_global">tangible.is.global</a>.
   * It's also possible to override
   * inherited nested properties. For example:
   * {@link adventurejs.Exit|Exit} inherits
   * <a href="/doc/adventurejs.Tangible.html#property_is_closed">tangible.is.closed</a>
   * and
   * <a href="/doc/adventurejs.Tangible.html#property_is_locked">tangible.is.locked</a>,
   * but overrides them with new definitions in order to account
   * for Exit's relationship to the linked class
   * {@link adventurejs.Aperture|Aperture}.
   **/

  class StateManager extends adventurejs.Atom {
    constructor(name = "is", game_name, parent_id) {
      super(name, game_name);
      this.class = "StateManager";
      if ("string" === typeof parent_id && parent_id) {
        this.parent_id = parent_id;
      } else this.parent_id = "";

      return this;
    }

    get parent() {
      return this.game.getAsset(this.parent_id);
    }

    /**
     * See if there is a linked asset, such as an other side of a door,
     * and set this value for it. Intended primarily for open/closed,
     * locked/unlocked, sealed/unsealed, and known / seen / used.
     * @param {*} value
     * @param {String} property
     */
    setLinkedAssetState(property, value) {
      var parent = this.parent;
      if (parent && parent.linked_asset) {
        var linked_asset = this.game.getAsset(parent.linked_asset);
        if (linked_asset && linked_asset[this.name])
          linked_asset[this.name][property] = value;
      }
    }

    /**
     * Set linked values such as open/close. Also see if there is a linked asset,
     * such as an other side of door, and set the same values for it.
     * @param {Boolean} value
     * @param {String} posprep
     * @param {String} negprep
     */
    setUnstate(value, posprop, negprop) {
      this[posprop] = value;
      this[negprop] = "boolean" === typeof value ? !value : value;
      var parent = this.parent;
      if (parent && parent.linked_asset) {
        var linked_asset = this.game.getAsset(parent.linked_asset);
        if (linked_asset && linked_asset[this.name]) {
          linked_asset[this.name][posprop] = this[posprop];
          linked_asset[this.name][negprop] = this[negprop];
        }
      }
    }
  } // class State

  adventurejs.StateManager = StateManager;
})();