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

(function () {
  /* global adventurejs A */

  var p = adventurejs.Game.prototype;

  /**
   * Tries to move the subject in the specified direction.
   * @memberOf adventurejs.Game
   * @method adventurejs.Game#doTravel
   * @param {String} direction
   * @param {Object} params
   */
  p.doTravel = function Game_tryTravel() {
    const fx = `doTravel.js`;
    var input = this.game.getInput();
    var subject = input.getSubject();
    var room = this.getRoom();
    var nest_asset = subject.getNestAsset();
    var nest_preposition = subject.getNestPreposition();
    var nest_aspect = subject.getNestAspect();
    var exit_id = room.exits[direction]; // may be no exit
    var aperture = input.travel.aperture;
    var msg = "";
    var results;

    var exit = input.travel.exit;
    var direction = input.travel.direction;
    // if (direction.direction) direction = direction.direction;
    var params = input.travel.params;

    this.game.log(
      "L1588",
      "log",
      "high",
      `[${fx}] doTravel ${direction}`,
      "Travel"
    );

    //

    //

    if (nest_asset && !nest_asset.isDOV("ride")) {
      // if (input.travel.must_unnset) {
      this.game.log(
        "L1590",
        "log",
        "high",
        `[${fx}] ${subject.id} must unnest from ${nest_asset.id}`,
        "Travel"
      );

      // @TODO remove this from tryTravel
      let unnest_preposition = subject.getPrettyUnnestPreposition();
      results = subject.onUnnestThisFromThat(nest_asset);
      if ("undefined" !== typeof results) return results;
      this.game.printInferred(
        `getting ${unnest_preposition} ${nest_asset.article_name} first`
      );
    }

    //

    // direction is valid and destination exists
    if (exit.destinationID) {
      this.game.log(
        "L1591",
        "log",
        "high",
        `[${fx}] doSuccess, travel to ${exit.destinationID}.`,
        "Travel"
      );

      // @TODO add logic for hidden exits
      exit.setIs("used", true);
      var addPeriod = false;
      // console.warn({ aperture });
      if (aperture) {
        if (aperture.is.locked && aperture.canDoVerbAutomatically("unlock")) {
          msg += `{We} unlock ${aperture.article_name}`;
          addPeriod = true;
          aperture.setIs("locked", false);
          aperture.incrementDoVerbCount("unlock", "dov");
        }

        if (
          aperture.is.sealed &&
          aperture.can.canDoVerbAutomatically("unseal")
        ) {
          msg += `{We} unseal ${aperture.article_name}`;
          addPeriod = true;
          aperture.setIs("sealed", false);
          aperture.incrementDoVerbCount("unseal", "dov");
        }

        if (aperture.is.closed && aperture.canDoVerbAutomatically("open")) {
          if (!msg) {
            msg += `{We} open ${aperture.article_name}`;
          } else {
            msg += ", and then open it";
          }
          //+ ". ";
          addPeriod = true;
          aperture.setIs("closed", false);
          aperture.incrementDoVerbCount("open", "dov");
        }

        if (addPeriod) msg += ". ";
        aperture.setIs("used", true);

        if (aperture.linked_asset) {
          this.game.getAsset(aperture.linked_asset).setIs("used", true);
        }
      }

      var newRoomID = exit.destinationID;
      var newRoomObj = this.world[newRoomID];
      for (var exitProp in newRoomObj.exits) {
        var newRoomExitID = newRoomObj.exits[exitProp];
        var newRoomExitObj = this.world[newRoomExitID];
        if (newRoomExitObj.destinationID === room.id) {
          newRoomExitObj.setIs("used", true);
        }
      }

      if (nest_asset && nest_asset.isDOV("ride")) {
        msg += `{We} ${this.game.getVerb("ride").agree()} ${nest_asset.article_name} `;
        if (this.game.dictionary.verbs[direction].is_relative_direction) {
          //msg += "to ";
        } else if (this.game.dictionary.verbs[direction].is_compass_direction) {
          msg += `to the `;
        }
        msg += `${direction}. `;
      } else if (params.with) {
        msg += `{We} ${this.game.getVerb("push").agree()} `;
        msg += this.game.getPrintableObjectList({
          objects: params.with,
          article: "definite",
        });
        msg += ` `;
        if (this.game.dictionary.verbs[direction].is_relative_direction) {
          //msg += "to ";
        } else if (this.game.dictionary.verbs[direction].is_compass_direction) {
          msg += `to the `;
        }
        msg += `${direction}. `;
        if ("string" === typeof params.with) {
          params.with = [params.with];
        }
        for (var i = 0; i < params.with.length; i++) {
          var object = this.game.getAsset(params.with[i]);
          object.moveFrom(object.getPlaceAsset());
          object.moveTo("in", newRoomObj);
        }
      } else if (exit.descriptions && exit.descriptions.travel) {
        msg += A.getSAF.call(this.game, exit.descriptions.travel);
      } else {
        msg +=
          this.game.dictionary.verbs[input.input_verb] &&
          this.game.dictionary.verbs[input.input_verb].type.travel
            ? `{We} ${this.game.getVerb(input.input_verb).agree()} `
            : `{We} ${subject.getPostureVerb()} `;

        if (this.game.dictionary.verbs[direction].is_relative_direction) {
          // relative directions include "port" and "starboard",
          // "left" and "right", etc
          //msg += "to ";
        }
        // else if(this.game.dictionary.verbs[direction].is_compass_direction)
        // {
        //   msg += "to the ";
        // }
        msg +=
          direction +
          " to " +
          (newRoomObj.use_definite_article_in_lists
            ? newRoomObj.definite_article + " "
            : "") +
          newRoomObj.name +
          ". ";
      }

      //
      // @TODO should this print defer to printOutput()?
      //
      this.game.print(msg, input.output_class);

      this.setRoom(this.world[newRoomID], params);

      // END @TODO doTravel - move this to doTravel

      exit.setIs("used", true);
      input.did.doTravel = true;
      return true;
    }
  };
})();