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

  /**
   * @ajspath adventurejs.Atom.Asset.Matter.Tangible.Thing.Rideable
   * @augments adventurejs.Thing
   * @class adventurejs.Rideable
   * @classdesc Explanation of the class.
   * @ajsconstruct MyGame.createAsset({ "class":"Rideable", "name":"foo", [...] })
   * @ajsconstructedby adventurejs.Game#createAsset
   * @ajsnavheading MiscAssetClasses
   * @param {String} game_name The name of the top level game object.
   * @param {String} name A name for the object, to be serialized and used as ID.
   * @summary Base class for things like bicycles and skateboards.
   * @tutorial Tangibles_SimpleVehicles
   * @ajstangiblecontainer on
   * @classdesc
   * <p>
   * <strong>Rideable</strong> is the ancestor class for
   * things like {@link adventurejs.Bicycle|Bicycle} and
   * {@link adventurejs.Skateboard|Skateboard}.
   * Rideables are unique among other Asset classes in that
   * {@link adventurejs.Character|Characters} may carry them,
   * while also being nested in/on them.
   * Nesting is a special kind of parent/child relationship that
   * is only used for Characters.
   * This feature is a function of
   * {@link adventurejs.Tangible|Tangible}'s
   * <a href="#property_is_rideable" class="code property">is.rideable</a> property.
   * To learn more, see
   * <a href="/doc/Tangibles_SimpleVehicles.html">Simple Vehicles</a>.
   * </p>
   * <h3 class="examples">Example:</h3>
   * <pre class="display"><code class="language-javascript">MyGame.createAsset({
   *   class: "Rideable",
   *   name: "pogo stick",
   *   place: { in: "Toy Closet" },
   *   descriptions: { look: "It's a pogo stick. ", },
   * });
   * </code></pre>
   **/
  class Rideable extends adventurejs.Thing {
    constructor(name, game_name) {
      super(name, game_name);
      this.class = "Rideable";

      /**
       * Setting a Tangible
       * {@link adventurejs.Asset|Asset}'s
       * <strong>is.rideable</strong>
       * property to true allows players to ride the Tangible Asset
       * while still holding it in inventory.
       * <br><br>
       * Normally, when putting one Tangible
       * in/on/under/behind another, the child asset is
       * added to the parent asset's in/on/under/behind
       * {@link adventurejs.Aspect|Aspect}.
       * <br><br>
       * In the case of {@link adventurejs.Character|Characters},
       * they can only be
       * <strong>in</strong> the {@link adventurejs.Room|Room}
       * they are in. When Characters move in/on/under/behind
       * Tangible subclasses such as {@link adventurejs.Chair|Chairs}
       * or {@link adventurejs.Bed|Beds}, they become
       * <strong>nested</strong>, which is a secondary form of
       * parent/child relationship.
       * <br><br>
       * For example, the player is <strong>IN</strong> a room.
       * A bed is also <strong>IN</strong> the same room.
       * When the player gets <strong>ON</strong> the bed,
       * the player remains <strong>IN</strong> the room
       * and also becomes <strong>NESTED ON</strong> the bed.
       * <br><br>
       * We do this for a couple of reasons. One is to prevent
       * overcomplicating the routines that determine what
       * Tangible Assets are considered to be within scope when
       * parsing player input. Another is to avoid
       * circular child/parent relationships,
       * which overcomplicate save/restore operations.
       * Circular relationships also overcomplicate parsing player input.
       * <br><br>
       * For example, imagine that a player holds a skateboard
       * <strong>IN</strong> their inventory
       * and then stands <strong>ON</strong> the skateboard.
       * If both objects were in each other's Aspects,
       * that would be a circular relationship. By nesting the
       * player to the skateboard, the skateboard can remain
       * in the player's inventory with fewer complications.
       * @var {Boolean} adventurejs.Tangible#is!rideable
       * @default false
       *
       */
      this.is.rideable = true;

      this.setDOVs(["ride", "take", "give", "tie"]);

      this.on_tie_to_this_take_this = false;
      this.on_tie_to_drag_behind_rope = true;

      this.aspects.on = new adventurejs.Aspect("on", this.game_name).set({
        parent_id: this.id,
        list_in_room: false,
        list_in_examine: true,
        maxcount: 1, // presumably a cap
        with_classes: ["Character"],
        player: { can: { enter: true, stand: true, exit: true, ride: true } },
      });
    }
  }

  adventurejs.Rideable = Rideable;
})();