Pre-release
Adventure.js Docs Downloads
Score: 0 Moves: 0
// jumpOff.js

(function () {
  /*global adventurejs A*/
  "use strict";

  /**
   * @augments {adventurejs.Verb}
   * @class jumpOff
   * @ajsnode game.dictionary.verbs.jumpOff
   * @ajsconstruct MyGame.createVerb({ "name": "jumpOff", [...] });
   * @ajsconstructedby adventurejs.Dictionary#createVerb
   * @hideconstructor
   * @ajsinstanceof Verb
   * @ajsnavheading DeprecatedVerbs
   * @summary Summary.
   * @ajssynonyms hop off, jump from, jump off, leap from, leap off
   * @tutorial Scripting_VerbSubscriptions
   * @tutorial Verbs_VerbAnatomy
   * @tutorial Verbs_VerbProcess
   * @tutorial Verbs_ModifyVerbs
   * @tutorial Verbs_WriteVerbs
   * @classdesc
   * <pre class="display border outline">
   * <span class="input">&gt; jump off bridge</span>
   * You jump off the bridge. Spoosh! You land in the thin
   * creek, which sweeps you under the bridge. The troll swipes
   * at you from the steep embankment but its hairy arms can't
   * quite reach you.
   * </pre>
   * <p>
   * <strong>Jump off</strong> aka <strong>jump from</strong>
   * requires that the player be nested in a
   * {@link adventurejs.Tangible|Tangible}
   * {@link adventurejs.Asset|Asset}.
   * The results are similar to those of {@link go_off}.
   * </p>
   */
  A.Preverbs.jumpOff = {
    name: "jumpOff",
    prettyname: "jump off",
    synonyms: [],
    verb_prep_noun: [
      "hop off",
      "jump from",
      "jump off",
      "leap from",
      "leap off",
    ],

    player_must_be: {
      //not_on_floor: true,
      not_constrained: true,
      //not_under: true,
      //not_behind: true,
      //not_nested_elsewhere: true,
    },

    phrase1: {
      accepts_noun: true,
      noun_must_be: {
        known: true,
        tangible: true,
        present: true,
        visible: true,
        reachable: true,
      },
    },

    /*
     * "jump off" can work with or without a direct object.
     */
    doTry: function () {
      var input = this.game.getInput();
      var player = this.game.getPlayer();
      var nest_preposition = player.getNestPreposition();
      var nest_parent_id = player.getNestId();
      var nest_parent_object = player.getNestAsset();
      var direct_object = input.getAsset(1);

      /**
       * jump off is uncommon in that it requires a noun
       * but can be called without one, in which case we try to
       * assume an implicit noun - anything the player is nested
       * in, or the current room.
       */
      if (!direct_object) {
        // was jumpoff called without noun?
        if (player.isNested()) {
          // if player is nested assume they're trying to leave nest
          direct_object = nest_parent_object;
        } else {
          // otherwise try to exit the room
          direct_object = this.game.world[this.game.world._currentRoom];
        }
        input.setAsset(1, direct_object);
      }

      // if thing can't be gotten off
      if (nest_parent_id === direct_object.id && direct_object.is.unleavable) {
        var msg =
          "$(We) can't leave " + direct_object.articlename + " that way.";
        this.handleFailure(msg);
        return null;
      }

      // player has tried to jump out of room that is not container
      if (
        direct_object.id === this.game.world._currentRoom &&
        false === direct_object.can_go_off
      ) {
        var msg = "How would $(we) do that?";
        this.handleFailure(msg);
        return null;
      }

      // what if player is sitting in a chair in, eq, a submarine?
      if (
        direct_object.id === this.game.world._currentRoom &&
        player.getPlaceAspect().player.can.exit &&
        player.isNested()
      ) {
        var msg =
          "$(We) can't do that from $(our) position " +
          player.getPostureGerund() +
          nest_preposition +
          " " +
          nest_parent_object.articlename +
          ". ";
        this.handleFailure(msg);
        return null;
      }

      // player is on floor in, eg, a submarine?
      if (
        direct_object.id === this.game.world._currentRoom &&
        direct_object.getPlaceAspect().player.can.exit &&
        false === player.isNested() &&
        player.isOnFloor()
      ) {
        var msg =
          "$(We) can't do that from $(our) position " +
          player.getPostureGerund() +
          " on the floor.";
        this.handleFailure(msg);
        return null;
      }

      // nested in some other way
      if (
        false === direct_object instanceof adventurejs.Room &&
        direct_object.id === nest_parent_id &&
        "on" !== nest_preposition &&
        (false === direct_object.quirks.in_means_on ||
          "in" !== nest_preposition)
      ) {
        var msg =
          "$(We're) " +
          nest_preposition +
          " " +
          direct_object.articlename +
          ", not on it.";
        this.handleFailure(msg);
        return null;
      }

      // not even in the thing
      if (
        false === direct_object instanceof adventurejs.Room &&
        direct_object.id !== nest_parent_id
      ) {
        var msg = "$(We're) not even on " + direct_object.articlename + ". ";
        this.handleFailure(msg);
        return null;
      }

      // not something you could be on anyway
      if (
        false === direct_object instanceof adventurejs.Room &&
        false === direct_object.can_go_on
      ) {
        var msg =
          "$(We're) not on, and can't get on, " +
          direct_object.articlename +
          ". ";
        this.handleFailure(msg);
        return null;
      }

      // TODO:
      // what other conditions prevent player from getting out?
      // tied down?

      // TODO: what if player is in body of water?

      // what if player is on, eg, a branch up a tree?
      // redirect to exit verb
      if (
        direct_object.id === this.game.world._currentRoom &&
        direct_object.can_jump_off
      ) {
        this.game.dictionary.doVerb("exit");
        return null;
      }

      return true;
    },

    doSuccess: function () {
      var input = this.game.getInput();
      var direct_object = input.getAsset(1);
      var player = this.game.getPlayer();
      var nest_preposition = player.getNestPreposition();
      var nest_parent_id = player.getNestId();
      var nest_parent_object = player.getNestAsset();
      var results;

      var msg =
        "$(We) jump " +
        player.getPrettyUnnestPreposition() +
        " " +
        direct_object.articlename +
        ". ";

      results = player.onUnnestThisFromThat(nest_parent_object);
      if ("undefined" !== typeof results) return results;

      player.position.y = 0;
      player.posture = "stand";

      this.handleSuccess(msg, direct_object);
      return true;
    },
  };
})(); // jumpOff