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

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

  /**
   * @augments {adventurejs.Verb}
   * @class push
   * @ajsnode game.dictionary.verbs.push
   * @ajsconstruct MyGame.createVerb({ "name": "push", [...] });
   * @ajsconstructedby adventurejs.Dictionary#createVerb
   * @hideconstructor
   * @ajsinstanceof Verb
   * @ajsnavheading ManipulationVerbs
   * @summary Verb meaning push an asset.
   * @ajssynonyms shove, push
   * @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; 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.
   * </p>
   * @ajsverbphases doBeforeTry, doAfterTry, doBeforeSuccess, doAfterSuccess
   */
  A.Preverbs.push = {
    name: "push",
    prettyname: "push",
    past_tense: "pushed",
    synonyms: ["push", "shove"],

    /**
     * @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 direct_object = input.getAsset(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 player = this.game.getPlayer();
      var results;
      var msg = "";

      // parsed sentence structure: verb
      if (input.hasStructure("verb")) {
      }

      // parsed sentence structure: verb noun
      if (input.hasStructure("verb noun")) {
      } // verb noun

      if (!direct_object.isDOV(this.name) && !direct_object.isDOV("take")) {
        // if you can take it, you can push it
        this.game.debug(
          `F1384 | ${this.name}.js | ${direct_object.id}.dov.${this.name}.enabled is false `
        );
        msg += `${direct_object.Articlename} can't be ${this.past_tense}. `;
        this.handleFailure(msg);
        return null;
      }

      if (
        indirect_object &&
        indirect_object.direction &&
        !direct_object.can.push_from_room &&
        !direct_object.isDOV("take")
      ) {
        this.game.debug(
          `F1386 | ${this.name}.js | ${direct_object.id}.can.push_from_room is false `
        );
        msg += `$(We) can't push ${direct_object.articlename} out of the room. `;
        this.handleFailure(msg);
        return null;
      }

      if (input.hasStructure("verb noun noun")) {
        if (!indirect_object.direction) {
          // player input "push asset asset"
          this.game.debug(
            `F1385 | ${this.name}.js | ${indirect_object.id} is not direction `
          );
          msg += this.game.parser.getUnparsedMessage(input.input);
          this.handleFailure(msg);
          return null;
        }
      }

      if (input.hasStructure("verb noun preposition noun preposition noun")) {
        // did player input "push a from b to c"?
        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(
            `F1688 | ${this.name}.js | sentence structure is 'verb noun preposition noun preposition noun' but phrase is not handled`
          );
          msg += this.game.parser.getUnparsedMessage(input.input);
          this.handleFailure(msg);
          return null;
        }

        // is asset at the "from" location?
        if (direct_object.getPlaceAssetId() !== indirect_object2.id) {
          this.game.debug(
            `F1689 | move.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

      if (input.hasStructure("verb noun preposition noun")) {
        if (direct_object === indirect_object) {
          this.game.debug(
            `F1673 | ${this.name}.js | direct_object ${direct_object.id} is indirect_object ${indirect_object.id} `
          );
          msg += `$(We) can't push ${direct_object.articlename} ${indirect_preposition} itself. `;
          this.handleFailure(msg);
          return null;
        }

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

        if (
          [direct_object.getPlacePreposition(), "across", "over"].indexOf(
            indirect_preposition
          ) > -1 &&
          direct_object.getPlaceAsset().id !== indirect_object.id
        ) {
          this.game.debug(
            `F1674 | ${this.name}.js | ${direct_object.id} is not ${indirect_preposition} ${indirect_object.id} `
          );
          msg += `${direct_object.Articlename} is not on ${indirect_object.articlename}. `;
          this.handleFailure(msg);
          return null;
        }

        if (
          [direct_object.getPlacePreposition(), "across", "over"].indexOf(
            indirect_preposition
          ) > -1 &&
          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(
              `F1138 | ${this.name}.js | ${direct_object.id} is not on ${indirect_object.id} `
            );
            msg += `${direct_object.Articlename} isn't on ${indirect_object.articlename}. `;
            this.handleFailure(msg);
            return null;
          }
        } else if (
          ["to", "toward", "near"].indexOf(indirect_preposition) > -1
        ) {
          // @TODO what does it mean to move a thing toward another thing?
          // is direct in same place as indirect?
          if (
            direct_object.getPlaceAssetId() !==
              indirect_object.getPlaceAssetId() ||
            direct_object.getPlacePreposition() !==
              indirect_object.getPlacePreposition()
          ) {
            this.game.debug(
              `F1681 | ${this.name}.js | ${direct_object.id} isn't in same parent as ${indirect_object.id} `
            );
            msg += `$(We) can't push ${direct_object.articlename} ${indirect_preposition} ${indirect_object.articlename}. `;
            this.handleFailure(msg);
            return null;
          }
        } else if (!indirect_object.hasAspectAt(indirect_preposition)) {
          this.game.debug(
            `F1204 | ${this.name}.js | ${indirect_object.id} has no aspect at ${indirect_preposition} `
          );
          msg += `$(We) can't push ${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(
            `F1188 | ${this.name}.js | ${indirect_object.id} has no aspect at ${indirect_preposition} `
          );
          msg += `$(We) can't push 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;
          }
        }
      }

      return true;
    },

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

      this.game.debug(`F1387 | ${this.name}.js | print doSuccess `);

      // parsed sentence structure: verb
      if (input.hasStructure("verb")) {
      }

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

      if (indirect_object && indirect_object.direction) {
        results = this.game.tryTravel(indirect_object.direction, {
          with: [direct_object.id],
        });
        if (A.isFalseOrNull(results)) return results;
        // no msg because tryTravel handled it
      }

      if (input.hasStructure("verb noun noun")) {
      } // verb noun noun

      if (input.hasStructure("verb noun preposition noun")) {
        if (
          [direct_object.getPlacePreposition(), "across", "over"].indexOf(
            indirect_preposition
          ) > -1 &&
          direct_object.getPlaceAsset().id === indirect_object.id
        ) {
          msg += `$(We) nudge ${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 pushing ${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 pushing ${direct_object.articlename} ${indirect_preposition} ${indirect_object.articlename}. `;
          } else {
            msg += `$(We) push ${direct_object.articlename} ${indirect_preposition} ${indirect_object.articlename}. `;
          }
        } // off
        else if (["to", "toward", "near"].indexOf(indirect_preposition) > -1) {
          // @TODO what does it mean to move a thing toward another thing?
          msg += `$(We) push ${direct_object.articlename} ${indirect_preposition} ${indirect_object.articlename}. `;
        } // to toward near
      } // verb noun preposition noun

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