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

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

  /**
   * @augments {adventurejs.Verb}
   * @class tie_to_and
   * @ajsnode game.dictionary.verbs.tie_to_and
   * @ajsconstruct MyGame.createVerb({ "name": "tie_to_and", [...] });
   * @ajsconstructedby adventurejs.Dictionary#createVerb
   * @hideconstructor
   * @ajsinstanceof Verb
   * @ajsnavheading DeprecatedVerbs
   * @summary Summary.
   * @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; tie rope to boat and bollard</span>
   * You tie the rope to the boat and the bollard.
   * </pre>
   * <p>
   * <strong>Tie</strong> one
   * {@link adventurejs.Tangible|Tangible}
   * {@link adventurejs.Asset|Asset} to two other Tangible Assets.
   * Requires that the tying Asset has its
   * <code class="property">asset.dov.tie.enabled</code>
   * set to true and that the target Assets have their
   * <code class="property">asset.iov.tie.enabled</code>
   * set to true.
   * </p>
   */
  A.Preverbs.tie_to_and = {
    name: "tie_to_and",
    prettyname: "tie",
    synonyms: ["tieto"],
    verb_prep_prep_noun: [],
    verb_noun_prep_noun: ["tie to"],
    verb_noun_prep_noun_prep_noun: ["tie to and"],

    phrase1: {
      accepts_noun: true,
      requires_noun: true,
      noun_must_be: {
        known: true,
        tangible: true,
        present: true,
        visible: true,
        reachable: true,
        //in_inventory: true,
        /**
         * Normally we'd want direct object to be in inventory,
         * but for tie to we might find a case such as a rope
         * that's tied to a bollard and needs to be tied to a boat.
         */
      },
    },

    phrase2: {
      accepts_noun: true,
      requires_noun: true,
      //accepts_preposition: true,
      //requires_preposition: true,
      //accepts_these_prepositions: [ 'to' ], /* @todo */
      noun_must_be: {
        known: true,
        tangible: true,
        present: true,
        visible: true,
        reachable: true,
      },
    },

    phrase3: {
      accepts_noun: true,
      requires_noun: true,
      //accepts_preposition: true,
      //requires_preposition: true,
      //accepts_these_prepositions: [ 'to' ], /* @todo */
      noun_must_be: {
        known: true,
        tangible: true,
        present: true,
        visible: true,
        reachable: true,
      },
    },

    doTry: function () {
      var input = this.game.getInput();
      var direct_object = input.getAsset(1);
      var indirect_object1 = input.getAsset(2);
      var indirect_object2 = input.getAsset(3);
      var player = this.game.getPlayer();

      // example: tie rope to table
      // rope is direct_object
      // table is indirect_object1

      // can't tie if not holding direct_object
      if (
        false === direct_object.can.tie_this_to_things_without_holding &&
        false === player.$has(direct_object)
      ) {
        var msg = "$(We)'re not holding " + direct_object.articlename + ". ";
        this.handleFailure(msg);
        return null;
      }

      // can't tie with direct_object
      if (!direct_object.isDOV("tie")) {
        var msg =
          "$(We) can't tie anything with " + direct_object.articlename + ". ";
        this.handleFailure(msg);
        return null;
      }

      // can't tie to indirect_object1
      if (false === indirect_object1.can_tie_things_to_this) {
        var msg =
          "$(We) can't tie anything to " + indirect_object1.articlename + ". ";
        this.handleFailure(msg);
        return null;
      }

      // can't tie to indirect_object2
      if (indirect_object2 && !indirect_object2.can_tie_things_to_this) {
        var msg =
          "$(We) can't tie anything to " + indirect_object2.articlename + ". ";
        this.handleFailure(msg);
        return null;
      }

      // direct_object already tied to both indirectObjects
      if (
        indirect_object2 &&
        -1 !==
          direct_object.dov.tie?.with_params.connections.indexOf(
            indirect_object1.id
          ) &&
        -1 !==
          direct_object.dov.tie?.with_params.connections.indexOf(
            indirect_object2.id
          )
      ) {
        var msg =
          direct_object.Articlename +
          " is already tied to both " +
          indirect_object1.articlename +
          " and " +
          indirect_object2.articlename +
          ". ";
        this.handleFailure(msg);
        return null;
      }

      // direct_object already tied to indirect_object1
      if (
        -1 !==
        direct_object.dov.tie?.with_params.connections.indexOf(
          indirect_object1.id
        )
      ) {
        var msg =
          direct_object.Articlename +
          " is already tied to " +
          indirect_object1.articlename +
          ". ";
        this.handleFailure(msg);
        return null;
      }

      // direct_object already tied to indirect_object2
      if (
        indirect_object2 &&
        -1 !==
          direct_object.dov.tie?.with_params.connections.indexOf(
            indirect_object2.id
          )
      ) {
        var msg =
          direct_object.Articlename +
          " is already tied to " +
          indirect_object2.articlename +
          ". ";
        this.handleFailure(msg);
        return null;
      }

      // direct_object is maxed out
      if (
        direct_object.dov.tie?.with_params.connections.length >=
        direct_object.dov.tie.with_params.max_connections
      ) {
        var msg =
          direct_object.Articlename + " can't be tied to any more things.";
        this.handleFailure(msg);
        return null;
      }

      // indirect_object1 is maxed out
      if (
        indirect_object1.iov.tie.with_params.connections.length >=
        indirect_object1.iov.tie.with_params.max_connections
      ) {
        var msg =
          indirect_object1.Articlename +
          " can't have any more things tied to it.";
        this.handleFailure(msg);
        return null;
      }

      // indirect_object1 is maxed out
      if (
        indirect_object2 &&
        indirect_object2.iov.tie.with_params.connections.length >=
          indirect_object2.iov.tie.with_params.max_connections
      ) {
        var msg =
          indirect_object2.Articlename +
          " can't have any more things tied to it.";
        this.handleFailure(msg);
        return null;
      }

      return true;
    },

    doSuccess: function () {
      var input = this.game.getInput();
      var direct_object = input.getAsset(1);
      var indirect_object1 = input.getAsset(2);
      var indirect_object2 = input.getAsset(3);
      var player = this.game.getPlayer();
      var results;

      results = direct_object.onTieThisToThat(indirect_object1);
      if ("undefined" !== typeof results) return results;

      if (indirect_object2) {
        results = direct_object.onTieThisToThat(indirect_object2);
        if ("undefined" !== typeof results) return results;
      }

      var msg =
        "$(We) tie " +
        direct_object.articlename +
        " to " +
        indirect_object1.articlename;

      if (indirect_object2) {
        msg += " and to " + indirect_object2.articlename;
      }

      /**
       * If indirect_object1 is takeable, move it into player's
       * inventory. This may lead to undesired side effects.
       * If you find that to be the case, set
       * game.settings.on_tie_rope_to_takeable_object_take_object
       * to false.
       */
      /*if( this.game.settings.on_tie_rope_to_takeable_object_take_object*/
      if (
        false === indirect_object1.isIn(player) &&
        indirect_object1.isDOV("take") &&
        indirect_object1.on_tie_to_this_take_this
      ) {
        results = player.onMoveThatToThis(indirect_object1, "in");
        if ("undefined" !== typeof results) return results;

        msg += ", and take " + indirect_object1.articlename;
      }

      if (
        indirect_object2 &&
        !indirect_object2.isIn(player) &&
        indirect_object2.isDOV("take") &&
        indirect_object1.on_tie_to_this_take_this
      ) {
        /*&& this.game.settings.on_tie_rope_to_takeable_object_take_object*/
        results = player.onMoveThatToThis(indirect_object2, "in");
        if ("undefined" !== typeof results) return results;

        msg += ", and take " + indirect_object2.articlename;
      }

      /**
       * If tying rope to its max number of items, and
       * the items are not in player's inventory, remove
       * rope from inventory. This may lead to undesired side
       * effects. If you find that to be the case, set
       * game.settings.onTieRopeToMaxPointsRemoveFromInventory
       * to false.
       */
      var tiedObjectsNotInInventory = 0;
      var ropeIsTiedToMaxObjects =
        direct_object.dov.tie?.with_params.connections.length ===
        direct_object.dov.tie?.with_params.max_connections;
      if (ropeIsTiedToMaxObjects) {
        for (
          var i = 0;
          i < direct_object.dov.tie?.with_params.connections.length;
          i++
        ) {
          var tiedObject = this.game.getAsset(
            direct_object.dov.tie?.with_params.connections[i]
          );
          if (false === tiedObject.isIn(player)) {
            tiedObjectsNotInInventory++;
          }
        }
      }
      var noTiedObjectsInInventory =
        tiedObjectsNotInInventory ===
        direct_object.dov.tie?.with_params.max_connections;
      if (
        this.game.settings.on_tie_rope_to_max_objects_drop_rope &&
        direct_object.isIn(player) &&
        ropeIsTiedToMaxObjects &&
        noTiedObjectsInInventory
      ) {
        var currentRoom = this.game.getCurrentRoom();

        results = player.onRemoveThatFromThis(direct_object);
        if ("undefined" !== typeof results) return results;

        // set thing's new location to player's location
        results = currentRoom.onMoveThatToThis(direct_object, "in");
        if ("undefined" !== typeof results) return results;

        msg += ", and let go of " + direct_object.articlename;
      }

      msg += ". ";

      this.handleSuccess(msg, direct_object);

      return true;
    },
  };
})(); // tie_to_and