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

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

  /**
   * @augments {adventurejs.Verb}
   * @class lasso
   * @ajsnode game.dictionary.verbs.lasso
   * @ajsconstruct MyGame.createVerb({ "name": "lasso", [...] });
   * @ajsconstructedby adventurejs.Dictionary#createVerb
   * @hideconstructor
   * @ajsinstanceof Verb
   * @ajsnavheading ManipulationVerbs
   * @summary Verb meaning lasso asset with rope.
   * @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; lasso crocagator with rope</span>
   * You lasso the crocagator with the woven grass rope. The rope
   * slips over the croc's long mouth. You pull, and the croc's
   * mouth slams shut. The crocagator thrashes angrily and whips
   * its jewel-tipped tail and pulls you off balance. You dig in
   * and pull. Step by step, you drag the bellowing crocagator out
   * of its watering hole. Soon its magic emerald will be yours.
   * </pre>
   * <p>
   * <strong>Lasso</strong> a
   * {@link adventurejs.Tangible|Tangible}
   * {@link adventurejs.Asset|Asset} with a
   * {@link adventurejs.Rope|Rope}.
   * Asset to be lassoed must have
   * <code>asset.dov.lasso.enabled</code> set to true.
   * Lasso has several distinct <a href="#params">params</a>
   * for controlling what happens to the rope after use.
   * </p>
   * @ajsverbreactions doTieThisToThat, doTieThatToThis, doRemoveThisFromThat, doRemoveThatFromThis, doMoveThisToThat, doMoveThatToThis
   * @ajsverbphases doBeforeTry, doAfterTry, doBeforeSuccess, doAfterSuccess
   */
  A.Preverbs.lasso = {
    name: "lasso",
    prettyname: "lasso",
    past_tense: "lassoed",
    synonyms: ["lasso", "rope"],
    gerund: "lassoing",

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

    /**
     * @ajsverbstructures
     * @memberof lasso
     */
    accepts_structures: [
      "verb noun", // lasso steer (with rope)
      "verb noun preposition noun", // lasso steer with rope
    ],

    /**
     * @memberof lasso
     * @ajsverbphrase
     * phrase1:
     * {
     *   accepts_noun:true,
     *   requires_noun: true,
     *   noun_must_be:
     *   {
     *     known: true,
     *     tangible: true,
     *     present: true,
     *     visible: true,
     *   },
     * },
     */
    phrase1: {
      accepts_noun: true,
      requires_noun: true,
      noun_must_be: {
        known: true,
        tangible: true,
        present: true,
        visible: true,
      },
    },

    /**
     * @memberof lasso
     * @ajsverbphrase
     * phrase2:
     * {
     *   accepts_noun:true,
     *   noun_must_be:
     *   {
     *     known: true,
     *     in_inventory: true,
     *   },
     *   accepts_preposition: true,
     *   requires_preposition: true,
     *   accepts_these_prepositions: ["with"],
     * },
     */
    phrase2: {
      accepts_noun: true,
      noun_must_be: {
        known: true,
        in_inventory: true,
      },
      accepts_preposition: true,
      requires_preposition: true,
      accepts_these_prepositions: ["with"],
    },

    /**
     * @memberof lasso
     * @ajsverbparams
     * with_params: {
     *
     *   // If true, using this asset to lasso another will
     *   // result in this asset being tied to the other;
     *   // and calling verb reactions
     *   // rope.doTieThisToThat and target.doTieThatToThis.
     *   on_lasso_set_tied: false,
     *
     *   // If true, using this asset to lasso another will
     *   // result in this asset being attached to the other
     *   // and in calling these verb reactions:
     *   // - player.doRemoveThatFromThis(lasso)
     *   // - lasso.doRemoveThisFromThat(player)
     *   // - target.doMoveThatToThis(lasso)
     *   // - lasso.doMoveThisToThat(target)
     *   on_lasso_set_attached: false,
     *
     *   // If true, using this asset as a lasso will
     *   // remove it from player inventory.
     *   on_lasso_remove_from_player: false,
     *
     *   // If true, using this asset as a lasso will
     *   // leave the player holding it.
     *   on_lasso_set_held: false,
     * },
     */
    with_params: {
      on_lasso_set_tied: false,
      on_lasso_set_attached: false,
      on_lasso_remove_from_player: false,
      on_lasso_set_held: false,
    },

    doTry: function () {
      var input = this.game.getInput();
      var verb_phrase = input.verb_phrase;
      var direct_object = input.getAsset(1);
      var direct_preposition = input.getPreposition(1);
      var indirect_object = input.getAsset(2);
      var indirect_preposition = input.getPreposition(2);
      var player = this.game.getPlayer();
      var results, indirect_inferred;
      var msg = "";

      if (!direct_object.isDOV(this.name)) {
        this.game.debug(
          `D1330 | ${this.name}.js | ${direct_object.id}.dov.lasso is unset `
        );
        msg += `$(We) can't lasso ${direct_object.articlename}. `;
        this.handleFailure(msg);
        return null;
      }

      // single use direct object?
      if (
        direct_object.allowVerbOnce(this.name, "dov") &&
        direct_object.didVerb(this.name, "dov")
      ) {
        this.game.debug(
          `D2171 | ${this.name}.js | ${direct_object.id}.dov.${this.name}.once and ${direct_object.id}.did.${this.name}.directly `
        );
        msg += `${direct_object.Articlename} has already been ${this.past_tense}. `;
        this.handleFailure(msg);
        return false;
      }

      if (input.hasStructure("verb noun")) {
        // indirect object required?
        if (direct_object.allowVerbWithNothing(this.name, "dov")) {
          return true;
        }

        // indirect objects available?
        if (!direct_object.hasIndirectObjects(this.name)) {
          this.game.debug(
            `D2172 | ${this.name}.js | ${direct_object.id}.dov.${this.name}.with_nothing is false `
          );
          msg += `$(We) don't know of anything that can be used to ${this.name} ${direct_object.articlename}. `;
          this.handleFailure(msg);
          return false;
        }

        // infer indirect object?
        results = this.tryToInferIndirectObject({
          direct_object: direct_object,
          context: player,
          handle_input: true,
        });
        if (results.prompt) {
          this.game.debug(`D2173 | ${this.name}.js | soft prompt for noun2 `);
          msg += `What would $(we) like to ${this.name} ${direct_object.articlename} with? `;
          this.handleFailure(msg);
          return false;
        } else if (results.success) {
          indirect_object = results.indirect_object;
          indirect_preposition = "with";
          indirect_inferred = true;
          input.setAsset(2, indirect_object);
          input.setPreposition(2, indirect_preposition);
          input.setStructure("verb noun preposition noun");
          this.game.printInferred(
            `${indirect_preposition} ${indirect_object.articlename}`
          );
        }
      } // verb noun

      // sentence structure: verb noun preposition noun
      if (input.hasStructure("verb noun preposition noun")) {
        // indirect object already tied / attached?
        if (
          indirect_object.isAttached(direct_object) ||
          indirect_object.isConnectedToAsset("tie", direct_object, "iov")
        ) {
          let attached = indirect_object.isAttached(direct_object)
            ? "attached"
            : "tied";
          this.game.debug(
            `D2179 | ${this.name}.js | ${indirect_object.id} is ${attached} to ${direct_object.id}`
          );
          msg += `${indirect_object.Articlename_is} already ${attached} to ${direct_object.articlename}. `;
          this.handleFailure(msg);
          return false;
        }

        // works with any indirect object?
        if (direct_object.allowVerbWithAnything(this.name, "dov")) {
          return true;
        }

        // indirect object not required?
        if (direct_object.allowVerbWithNothing(this.name, "dov")) {
          this.game.debug(
            `D2180 | ${this.name}.js | ${direct_object.id}.dov.${this.name}.with_nothing `
          );
          msg += `$(We) don't need ${indirect_object.articlename} to ${this.name} ${direct_object.articlename}. `;
          this.handleFailure(msg);
          return null;
        }

        // can indirect object be used?
        if (!indirect_object.isIOV(this.name)) {
          this.game.debug(
            `D1331 | ${this.name}.js | ${indirect_object.id}.iov.${this.name}.enabled is false `
          );
          msg += `$(We) can't ${this.name} anything ${indirect_preposition} ${indirect_object.articlename}. `;
          this.handleFailure(msg);
          return null;
        }

        // single use indirect object?
        if (
          indirect_object.allowVerbOnce(this.name, "iov") &&
          indirect_object.iDidVerb(this.name, "iov")
        ) {
          this.game.debug(
            `D2175 | ${this.name}.js | ${indirect_object.id}.iov.${
              this.name
            }.once and ${indirect_object.id}.did.${this.name}.indirectly is ${
              indirect_object.did[this.name].indirectly
            } `
          );
          msg += `${indirect_object.Articlename} has already been used to ${this.name} something. `;
          this.handleFailure(msg);
          return null;
        }

        // indirect object usable with direct object?
        if (
          !direct_object.allowVerbWithAsset(this.name, indirect_object, "dov")
        ) {
          this.game.debug(
            `D2174 | ${this.name}.js | ${direct_object.id}.dov.${this.name}.with_assets/with_classes does not include ${indirect_object.id} `
          );
          msg += `$(We) can't use ${indirect_object.articlename} to ${this.name} ${direct_object.articlename}. `;
          this.handleFailure(msg);
          return null;
        }
      } // verb noun preposition noun

      return true;
    },

    doSuccess: function () {
      var input = this.game.getInput();
      var verb_phrase = input.verb_phrase;
      var direct_object = input.getAsset(1);
      var direct_preposition = input.getPreposition(1);
      var indirect_object = input.getAsset(2);
      var indirect_preposition = input.getPreposition(2);
      var player = this.game.getPlayer();
      var msg = "";
      var results;
      var tied, attached, removed, held;

      // remove from player?
      // @TODO is rope tied to player?
      if (
        true ===
          indirect_object.getVerbParam(
            this.name,
            "iov",
            "on_lasso_remove_from_player"
          ) &&
        player.$has(indirect_object)
      ) {
        // remove thing from player
        results = player.onRemoveThatFromThis(indirect_object);
        if ("undefined" !== typeof results) return results;
        removed = true;
      }

      // set held?
      // @TODO is rope tied to player?
      else if (
        true ===
        indirect_object.getVerbParam(this.name, "iov", "on_lasso_set_held")
      ) {
        if (!indirect_object.isDOV("hold")) {
          this.game.debug(
            `D2178 | ${this.name}.js | ${indirect_object.id}.dov.hold is unset. ${indirect_object.id} won't be held by player. `
          );
        } else {
          if (player.$has(indirect_object)) {
            // remove thing from player
            results = player.onRemoveThatFromThis(indirect_object);
            if ("undefined" !== typeof results) return results;
          }
          let hold = this.game.dictionary.verbs.hold;
          hold.setVerbConnection(indirect_object, player);
          held = true;
        }
      }

      // tie rope to target?
      if (indirect_object.getVerbParam(this.name, "iov", "on_lasso_set_tied")) {
        if (!direct_object.isIOV("tie") || !indirect_object.isDOV("tie")) {
          this.game.debug(
            `D2176 | ${this.name}.js | ${indirect_object.id}.iov.${
              this.name
            }.with_params.on_lasso_set_tied is true but ${
              !direct_object.isIOV("tie")
                ? direct_object.id + ".iov.tie is unset"
                : ""
            } ${
              !indirect_object.isDOV("tie")
                ? indirect_object.id + ".dov.tie is unset"
                : ""
            }. ${direct_object.id} won't be tied to ${direct_object.id}. `
          );
        } else {
          this.game.debug(
            `Fxxx | ${this.name}.js | on_lasso_set_tied > move ${indirect_object.id} in ${direct_object.id}`
          );
          // call tie verb actions
          results = indirect_object.onTieThisToThat(direct_object);
          if ("undefined" !== typeof results) return results;
          indirect_object.moveTo("on", direct_object);
          console.warn("BUH?");

          // direct_object.onMoveThatToThis(indirect_object, "in");

          tied = true;
        }
      }

      // attach rope to target?
      if (
        true ===
        indirect_object.getVerbParam(this.name, "iov", "on_lasso_set_attached")
      ) {
        if (!direct_object.hasAspectAt("attached")) {
          this.game.debug(
            `D2177 | ${this.name}.js | on_lasso_set_attached > ${
              indirect_object.id
            }.iov.${this.name}.with_params.on_lasso_set_attached is true but ${
              direct_object.id + ".aspects.attached is unset"
            }. ${indirect_object.id} won't be attached to ${direct_object.id}. `
          );
        } else {
          this.game.debug(
            `Fxxx | ${this.name}.js | move ${indirect_object.id} attached ${direct_object.id}`
          );
          indirect_object.moveTo("attached", direct_object);
          attached = true;
        }
      }

      // direct_object.can.support_swinging = true;
      // indirect_object.is.supported = true;

      // compose output
      msg +=
        `$(We) ${this.name}` +
        `${direct_preposition ? " " + direct_preposition : ""}` +
        `${direct_object ? " " + direct_object.articlename : ""}` +
        `${indirect_preposition ? " " + indirect_preposition : ""}` +
        `${indirect_object ? " " + indirect_object.articlename : ""}` +
        `. ` +
        `${indirect_object.Articlename} ` +
        `${
          tied || attached
            ? (tied ? "ties " : "attaches ") + "tightly to "
            : "settles over "
        }` +
        `${direct_object.articlename}` +
        `${(tied || attached) && removed ? " and" : ""}` +
        `${removed ? " slips from $(our) hands" : ""}` +
        `${held ? " leaving $(us) holding the other end" : ""}` +
        `. `;

      // print output
      return this.handleSuccess(msg, direct_object);
    },
  }; // END p.preverbs.push
})();