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

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

  /**
   * @augments {adventurejs.Verb}
   * @class push
   * @ajsnode game.dictionary.verbs.push
   * @ajsredirectverb press, toggle
   * @ajsconstruct MyGame.createVerb({ "name": "push", [...] });
   * @ajsconstructedby adventurejs.Dictionary#createVerb
   * @hideconstructor
   * @ajsinstanceof Verb
   * @ajsnavheading ManipulationVerbs
   * @summary Verb meaning push an asset.
   * @ajssynonyms shove, push
   * @tutorial Verbs_Subscriptions
   * @tutorial AdvancedVerbs_VerbAnatomy
   * @tutorial AdvancedVerbs_VerbProcess
   * @tutorial AdvancedVerbs_ModifyVerbs
   * @tutorial AdvancedVerbs_ModifyVerbs
   * @classdesc
   * <pre class="display border outline">
   * <span class="ajs-player-input">&gt; push builder</span>
   * You push the builder up the hill. He complains loudly. "Hey! Whatsamatta you?!? Is you a'crazy?" He rolls back down the hill and resumes the very important building project that you interrupted. Meanwhile, a deformed buzzard has landed on you. It begins plucking out your intestines. "You don't mind, do ya chum? My momma don'tol' me, bring something for dinner." Gruesome, isn't it? Really makes you wish you had spellcheck.
   * </pre>
   * <p>
   * <strong>Push</strong> a
   * {@link adventurejs.Tangible|Tangible}
   * {@link adventurejs.Asset|Asset}.
   * Requires that the Asset has
   * asset.dov.push.enabled set to true.
   * By default, no special results will occur.
   * Authors wanting to make use of it may need to use a method such
   * as verb hooks. See
   * <a href="/doc/Verbs_PhaseHooks.html">Verb Phases</a>
   * to learn more.
   * </p>
   * @ajsverbreactions
   * @ajsverbphases doBeforeTry, doAfterTry, doBeforeSuccess, doAfterSuccess
   */
  A.Preverbs.push = {
    name: "push",
    prettyname: "push",
    past_tense: "pushed",
    synonyms: ["push", "shove"],
    gerund: "pushing",

    /**
     * @ajsverbstructures
     * @memberof push
     */
    accepts_structures: [
      "verb noun", // ie 'push boulder'
      "verb noun noun", // ie 'push boulder north'
      "verb noun preposition noun", // ie 'push boulder over hill'
      "verb noun preposition noun preposition noun", // ie 'push boulder from dingle to hill'
    ],

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

    /**
     * @memberof push
     * @ajsverbphrase
     * phrase2:
     * {
     *   accepts_noun:true,
     *   noun_must_be:
     *   {
     *     known: true,
     *     tangible: true,
     *     present: true,
     *     visible: true,
     *     reachable: true,
     *   },
     *   accepts_preposition: true,
     * },
     */
    phrase2: {
      accepts_noun: true,
      noun_must_be: {
        known: true,
        tangible: true,
        present: true,
        visible: true,
        reachable: true,
      },
      accepts_preposition: true,
    },

    /**
     * @memberof push
     * @ajsverbphrase
     * phrase3:
     * {
     *   // only supports form: push asset from asset to asset
     *   accepts_noun:true,
     *   noun_must_be:
     *   {
     *     known: true,
     *     tangible: true,
     *     present: true,
     *     visible: true,
     *     reachable: true,
     *   },
     *   accepts_preposition: true,
     *   requires_preposition: true,
     * },
     */
    phrase3: {
      accepts_noun: true,
      noun_must_be: {
        known: true,
        tangible: true,
        present: true,
        visible: true,
        reachable: true,
      },
      accepts_preposition: true,
      requires_preposition: true,
    },

    /**
     * @memberof push
     * @ajsverbparams
     * with_params: {},
     */
    with_params: {},

    doTry: function () {
      var input = this.game.getInput();
      var subject = input.getSubject();
      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 indirect_object2 = input.getAsset(3);
      var indirect_preposition2 = input.getPreposition(3);
      var results;
      var msg = "";

      if (
        direct_object.hasQuirk("push_means_press") &&
        direct_object.isDOV("press")
      ) {
        this.game.debug(
          `D2029 | ${this.name}.js | ${direct_object.id}.quirks.push_means_press is true, doVerb press `
        );
        return this.game.dictionary.doVerb("press");
      }

      if (
        direct_object.hasQuirk("push_means_toggle") &&
        direct_object.isDOV("toggle")
      ) {
        this.game.debug(
          `D2043 | ${this.name}.js | ${direct_object.id}.quirks.push_means_toggle is true, doVerb toggle `
        );
        return this.game.dictionary.doVerb("toggle");
      }

      if (!direct_object.isDOV(this.name)) {
        this.game.debug(
          `D1384 | ${this.name}.js | ${direct_object.id}.dov.${this.name} is unset `
        );
        msg += `${direct_object.Articlename} can't be ${this.past_tense}. `;
        this.handleFailure(msg);
        return null;
      }

      if (
        indirect_object &&
        indirect_object.direction &&
        !direct_object.can.drag_between_rooms &&
        !direct_object.isDOV("take")
      ) {
        this.game.debug(
          `D1386 | ${this.name}.js | ${direct_object.id}.can.drag_between_rooms is false `
        );
        msg += `{We} try to ${this.name} ${direct_object.articlename} ${
          indirect_object.direction
        }, but ${direct_object.getPronoun("we're")} not going anywhere. `;
        this.handleFailure(msg);
        return null;
      }

      // sentence structure: verb noun noun
      // ex: push chair north
      if (input.hasStructure("verb noun noun")) {
        if (!indirect_object.direction) {
          this.game.debug(
            `D1385 | ${this.name}.js | ${indirect_object.id} is not direction `
          );
          msg += this.game.settings.getUnparsedMessage(input.getInput());
          this.handleFailure(msg);
          return null;
        }
      } // verb noun noun

      // sentence structure: verb noun preposition noun preposition noun
      // ex: push a from b to c
      if (input.hasStructure("verb noun preposition noun preposition noun")) {
        if (indirect_preposition === "from" && indirect_preposition2 === "to") {
          // if so swap to/from because we're going to drop from at a later step
          input.swapPhrases(2, 3);
          indirect_preposition = "to";
          indirect_preposition2 = "from";
          indirect_object = input.getAsset(2);
          indirect_object2 = input.getAsset(3);
        }

        if (indirect_preposition !== "to" || indirect_preposition2 !== "from") {
          // we don't handle any other phrases in this structure
          this.game.debug(
            `D1688 | ${this.name}.js | sentence structure is 'verb noun preposition noun preposition noun' but phrase is not handled`
          );
          msg += this.game.settings.getUnparsedMessage(input.getInput());
          this.handleFailure(msg);
          return null;
        }

        // is asset at the "from" location?
        if (direct_object.getPlaceAssetId() !== indirect_object2.id) {
          this.game.debug(
            `D1689 | ${this.name}.js | ${direct_object.id} is not ${indirect_object2.default_aspect} ${indirect_object2.id} `
          );
          msg += `${direct_object.Articlename_is} not ${indirect_object2.default_aspect} ${indirect_object2.articlename}. `;
          this.handleFailure(msg);
          return null;
        }

        // simplify this down to 'verb noun preposition noun'
        input.setStructure("verb noun preposition noun");
      } // verb noun preposition noun preposition noun

      // sentence structure: verb noun preposition noun
      // ex: push pram across lawn
      if (input.hasStructure("verb noun preposition noun")) {
        if (direct_object === indirect_object) {
          this.game.debug(
            `D1673 | ${this.name}.js | direct_object ${direct_object.id} is indirect_object ${indirect_object.id} `
          );
          msg += `{We} can't ${this.name} ${direct_object.articlename} ${indirect_preposition} itself. `;
          this.handleFailure(msg);
          return null;
        }

        // if( [direct_object.getPlacePreposition(), "across", "over"].includes( indirect_preposition )
        // && direct_object.getPlaceAsset().id === indirect_object.id )
        // {
        //   this.game.debug(` | ${this.name}.js | ${direct_object.id} is ${indirect_preposition} ${indirect_object.id} `);
        //   msg += `{We} ${this.agree()} ${direct_object.articlename} ${indirect_preposition} ${indirect_object.articlename}. `;
        //   this.handleFailure(msg);
        //   return null;
        // }

        if (
          [direct_object.getPlacePreposition(), "across", "over"].includes(
            indirect_preposition
          ) &&
          direct_object.getPlaceAsset().id !== indirect_object.id
        ) {
          this.game.debug(
            `D1674 | ${this.name}.js | ${direct_object.id} is not ${indirect_preposition} ${indirect_object.id} `
          );
          msg += `{We} can't ${this.name} ${direct_object.articlename} ${indirect_preposition} ${indirect_object.articlename}. `;
          this.handleFailure(msg);
          return null;
        }

        if (
          [direct_object.getPlacePreposition(), "across", "over"].includes(
            indirect_preposition
          ) &&
          direct_object.getPlaceAsset().id === indirect_object.id
        ) {
          // ok
        } else if ("off" === indirect_preposition) {
          if (
            "on" !== direct_object.getPlacePreposition() ||
            direct_object.getPlaceAssetId() !== indirect_object.id
          ) {
            this.game.debug(
              `D1138 | ${this.name}.js | ${direct_object.id} is not on ${indirect_object.id} `
            );
            msg += `${direct_object.Articlename_isnt}  on ${indirect_object.articlename}. `;
            this.handleFailure(msg);
            return null;
          }
        } else if (["to", "toward", "near"].includes(indirect_preposition)) {
          // is direct in same place as indirect?
          if (
            direct_object.getPlaceAssetId() !==
              indirect_object.getPlaceAssetId() ||
            direct_object.getPlacePreposition() !==
              indirect_object.getPlacePreposition()
          ) {
            this.game.debug(
              `D1681 | ${this.name}.js | ${direct_object.id} isn't in same parent as ${indirect_object.id} `
            );
            msg += `{We} can't ${this.name} ${direct_object.articlename} ${indirect_preposition} ${indirect_object.articlename}. `;
            this.handleFailure(msg);
            return null;
          }
        } else if (!indirect_object.hasAspectAt(indirect_preposition)) {
          this.game.debug(
            `D1204 | ${this.name}.js | ${indirect_object.id} has no aspect at ${indirect_preposition} `
          );
          msg += `{We} can't ${this.name} ${direct_object.articlename} ${indirect_preposition} ${indirect_object.articlename}. `;
          this.handleFailure(msg);
          return null;
        }

        if (
          -1 !== "in on under behind".indexOf(indirect_preposition) &&
          !indirect_object.hasAspectAt(indirect_preposition)
        ) {
          this.game.debug(
            `D1188 | ${this.name}.js | ${indirect_object.id} has no aspect at ${indirect_preposition} `
          );
          msg += `{We} can't ${this.name} anything ${indirect_preposition} ${indirect_object.articlename}. `;
          this.handleFailure(msg);
          return null;
        }

        if (indirect_object.hasAspectAt(indirect_preposition)) {
          results = this.tryToPutThisInThatAspect(
            direct_object,
            indirect_preposition,
            indirect_object
          );
          if (results.fail) {
            msg = results.msg;
            this.handleFailure(msg);
            if (results.end_turn) return false;
            return null;
          }
        }
      } // verb noun preposition noun

      return true;
    },

    doSuccess: function () {
      var input = this.game.getInput();
      var subject = input.getSubject();
      var direct_object = input.getAsset(1);
      var indirect_object = input.getAsset(2);
      var indirect_preposition = input.getPreposition(2);
      var msg = "";
      var results;
      var results1, results2;

      // sentence structure: verb noun
      if (input.hasStructure("verb noun")) {
        msg += `{We} ${this.agree()} ${direct_object.articlename}. `;
      } // verb noun

      // sentence structure: push noun direction
      if (indirect_object && indirect_object.direction) {
        if (direct_object.can.drag_between_rooms) {
          // applies to things like heavy objects and vehicles
          results = this.game.tryTravel(indirect_object.direction, {
            with: [direct_object.id],
          });
          if (A.isFalseOrNull(results)) return results;
          // no msg because tryTravel handled it
        } else {
          msg += `{We} ${this.agree()} ${direct_object.articlename} a bit to the ${indirect_object.direction}. `;
        }
      }

      // sentence structure: verb noun preposition noun
      if (input.hasStructure("verb noun preposition noun")) {
        if (
          [direct_object.getPlacePreposition(), "across", "over"].includes(
            indirect_preposition
          ) &&
          direct_object.getPlaceAsset().id === indirect_object.id
        ) {
          msg += `{We} ${this.agree()} ${direct_object.articlename} ${indirect_preposition} ${indirect_object.articlename}. `;
        } // across over
        else if (
          -1 < "in on under behind".indexOf(indirect_preposition) &&
          indirect_object.hasAspectAt(indirect_preposition)
        ) {
          results1 = direct_object
            .getPlaceAsset()
            .onRemoveThatFromThis(direct_object);
          if (!A.isFalseOrNull(results1)) {
            results2 = indirect_object.onMoveThatToThis(
              direct_object,
              "behind"
            );
          }
          if (A.isFalseOrNull(results1) || A.isFalseOrNull(results2)) {
            msg += `{We're} prevented from ${this.gerund} ${direct_object.articlename} ${indirect_preposition} ${indirect_object.articlename}. `;
          }
        } // in on under behind
        else if ("off" === indirect_preposition) {
          results1 = indirect_object.onRemoveThatFromThis(direct_object);
          if (!A.isFalseOrNull(results1)) {
            results2 = indirect_object
              .getPlaceAsset()
              .onMoveThatToThis(
                direct_object,
                indirect_object.getPlacePreposition()
              );
          }
          if (A.isFalseOrNull(results1) || A.isFalseOrNull(results2)) {
            msg += `{We're} prevented from ${this.gerund} ${direct_object.articlename} ${indirect_preposition} ${indirect_object.articlename}. `;
          } else {
            msg += `{We} ${this.agree()} ${direct_object.articlename} ${indirect_preposition} ${indirect_object.articlename}. `;
          }
        } // off
        else if (["to", "toward", "near"].includes(indirect_preposition)) {
          msg += `{We} ${this.agree()} ${direct_object.articlename} ${indirect_preposition} ${indirect_object.articlename}. `;
        } // to toward near
      } // verb noun preposition noun

      // --------------------------------------------------
      // print output
      // --------------------------------------------------
      return this.handleSuccess(msg);
    }, // push
  };
})();