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

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

  /**
   * @augments {adventurejs.Verb}
   * @class screw
   * @ajsnode game.dictionary.verbs.screw
   * @ajsconstruct MyGame.createVerb({ "name": "screw", [...] });
   * @ajsconstructedby adventurejs.Dictionary#createVerb
   * @hideconstructor
   * @ajsinstanceof Verb
   * @ajsnavheading LocomotionVerbs
   * @summary Verb meaning screw, as in "screw rod into socket".
   * @todo replace canScrewToThing with Aspect methods for limiting attachment
   * @todo attachment type?
   * @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; screw suppressor to pistol</span>
   * You screw the suppressor to the barrel of the pistol, carefully
   * guiding the threads into place. The seam closes tightly, squeezing
   * out a bit of grease. You wipe it away with a bit of chamois from
   * your pocket. As you refold the chamois, greasy side in, you consider
   * the chain of events that brought you here. A late phone call, a
   * veiled threat, an untrustworthy promise. You certainly have no
   * loyalties to betray here, but neither do you care to be manipulated.
   * </pre>
   * <p>
   * <strong>Screw</strong> one {@link adventurejs.Tangible|Tangible}
   * {@link adventurejs.Asset|Asset} to another.
   * Requires that the receiving Asset has an <code>attach</code>
   * {@link adventurejs.Aspect|Aspect}.
   * To learn about Aspects, see
   * <a href="/doc/Tangibles_Aspects.html">How to Use Aspects</a>.
   * </p>
   * @ajsverbreactions
   * @ajsverbphases doBeforeTry, doAfterTry, doBeforeSuccess, doAfterSuccess
   */
  A.Preverbs.screw = {
    name: "screw",
    prettyname: "screw",
    past_tense: "screwed",
    synonyms: ["screw"],
    verb_noun_prep_noun: ["screw to", "screw onto"],
    verb_noun_prep_prep_noun: ["screw on to"],
    state: "screwed",
    //unstate: "unscrewed",

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

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

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

    doTry: function () {
      var input = this.game.getInput();
      var player = this.game.getPlayer();
      var direct_object = input.getAsset(1);
      var msg = "";

      // no indirect object given
      if ("undefined" === typeof input.parsedNoun2) {
        input.setSoftPrompt({ noun2: true, verb: "screw" });
        this.game.debug(
          `F1396 | ${this.name}.js | no indirect object received or inferred, soft prompt noun2 `,
        );
        msg += `Screw ${direct_object.articlename} to what? `;
        this.handleFailure(msg);
        return null;
      }

      var indirect_object = input.getAsset(2);

      // can't screw
      if (
        !direct_object.isDOV("screw") ||
        !indirect_object.hasAspectAt("attached")
      ) {
        this.game.debug(
          `F1395 | ${this.name}.js | ${direct_object.id}.dov.screw.enabled is false or ${indirect_object.id} has no attached aspect `,
        );
        msg += `$(We) can't screw ${direct_object.articlename} into ${indirect_object.articlename}. `;
        this.handleFailure(msg);
        return null;
      }

      // can we attach this particular thing to that particular thing?
      var can_be_screwed = false;
      /** @TODO these functions don't exist yet */
      if (
        direct_object.canScrewToClassOf(indirect_object) ||
        direct_object.canScrewToThing(indirect_object)
      ) {
        can_be_screwed = true;
      }

      if (!can_be_screwed) {
        this.game.debug(
          `F1394 | ${this.name}.js | ${indirect_object.id} can't accept ${direct_object.id} `,
        );
        msg += `$(We) can't screw ${direct_object.articlename} into ${indirect_object.articlename}. `;
        this.handleFailure(msg);
        return null;
      }

      // already screwed
      if (direct_object.isPlacedAtAspect("attached")) {
        this.game.debug(
          `F1397 | ${this.name}.js | ${
            direct_object.id
          } is already attached to ${direct_object.getPlaceAssetId()}`,
        );
        msg += `${direct_object.Articlename} is ${
          direct_object.isDOV("screw") ? "screwed" : "attached"
        } to ${indirect_object.articlename}. `;
        this.handleFailure(msg);
        return null;
      }

      return true;
    },

    doSuccess: function () {
      var input = this.game.getInput();
      var player = this.game.getPlayer();
      var direct_object = input.getAsset(1);
      var doParent = direct_object.getPlaceAsset();
      var indirect_object = input.getAsset(2);
      var msg = "";
      var results;

      this.game.debug(`F1398 | ${this.name}.js | print doSuccess `);
      if (doParent.id !== indirect_object.id) {
        // remove thing from current parent
        //results = parent.onRemoveThatFromThis( direct_object );
        results = direct_object.moveFrom(doParent);
        if ("undefined" !== typeof results) return results;

        // add thing to new parent
        //results = indirect_object.onMoveThatToThis( direct_object, "attached" );
        results = direct_object.moveTo("attached", indirect_object);
        if ("undefined" !== typeof results) return results;
      }

      msg += `$(We) screw ${direct_object.articlename} into ${indirect_object.articlename}. `;

      direct_object.is.screwed = true;

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