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

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

  /**
   * @augments {adventurejs.Verb}
   * @class plugIn
   * @ajsnode game.dictionary.verbs.plugIn
   * @ajsconstruct MyGame.createVerb({ "name": "plugIn", [...] });
   * @ajsconstructedby adventurejs.Dictionary#createVerb
   * @hideconstructor
   * @ajsinstanceof Verb
   * @ajsnavheading ManipulationVerbs
   * @ajsstate pluggedIn
   * @summary Verb meaning plug in, as in "plug in computer".
   * @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; plug computer into socket</span>
   * You plug the ancient computer into the dusty socket. Nothing happens.
   * But wait! Was that a flicker of light? It was! A small red light blinks on.
   * And then another, and another as the ancient computer begins to wake.
   * You hear a deep thrumming sound that rises in pitch until it becomes a
   * painful screeching whine. And then silence. Until. The computer speaks!
   * "THIS WORLD IS MINE!" Uh oh.
   * </pre>
   * <p>
   * <strong>PlugIn</strong> applies to the physical act of attaching one
   * asset to another, such as plugging in a computer. If
   * <code>asset.dov.plugIn.with_nothing</code>
   * is true, players can input "plug in computer" without specifying a
   * particular asset to plug the computer into, and it will just be
   * implied that the computer is plugged into a wall outlet.
   * Conversely, in order to specify an asset such as an outlet to plug
   * the computer into, enter asset IDs into the computer's
   * <code>asset.dov.plugIn.with_assets</code>.
   * This distinction exists so that authors can choose how fiddly
   * they want to get.
   * Note that plugIn is distinct from
   * <a href="/doc/plug.html">Plug</a>, which pertains to plugging things like
   * drains.
   * </p>
   * @ajsverbphases doBeforeTry, doAfterTry, doBeforeSuccess, doAfterSuccess
   * @ajsdemo PlugGame, PlugSomethingIntoSomething, PlugSomethingIntoNothing, PlugSomethingWithSomething, PlugSomethingWithNothing
   */
  A.Preverbs.plugIn = {
    name: "plugIn",
    prettyname: "plug in",
    past_tense: "plugged in",
    verb_noun_prep: ["plug in"], // plug computer in
    verb_prep_noun: ["plug in"], // plug in computer
    verb_noun_prep_noun: ["plug into", "plug in"], // plug computer into outlet
    state: "pluggedIn",
    state_string: "plugged in",
    unstate_string: "not plugged in",

    /**
     * @ajsverbstructures
     * plugIn is parsed as a compound word which means that we
     * don't parse 'in' as a separate word and therefore don't
     * accept 'verb noun preposition noun' as with many other verbs.
     * @memberof plugIn
     */
    accepts_structures: ["verb noun", "verb noun noun"],

    /**
     * @memberof plugIn
     * @ajsverbphrase
     * phrase1:
     * {
     *   accepts_noun: true,
     *   requires_noun: true,
     *   //accepts_preposition: true,
     *   //accepts_these_prepositions: ["in"],
     *   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 plugIn
     * @ajsverbphrase
     * phrase2:
     * {
     *   accepts_noun: true,
     *   //requires_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" ],
     * },
     */
    phrase2: {
      accepts_noun: true,
      noun_must_be: {
        known: true,
        tangible: true,
        present: true,
        visible: true,
        reachable: true,
      },
      //requires_preposition: true,
      //accepts_these_prepositions: [ "to" ],
    },

    /**
     * @memberof plugIn
     * @ajsverbparams
     * with_params: {
     *   connections: [],
     *   max_connections: 1,
     *   take_breaks_connections: true,
     *   take_takes_connections: false,
     * },
     */
    with_params: {
      connections: [],
      max_connections: 1,
      take_breaks_connections: true,
      take_takes_connections: false,
    },

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

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

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

      // can be direct object of verb?
      if (!direct_object.isDOV(this.name)) {
        this.game.debug(
          `F1765 | ${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;
      }

      // already plugged into nothing? // takes place of state check
      if (
        direct_object.DOVallowWithNothing(this.name) &&
        direct_object.DOVisConnectedToNothing(this.name)
      ) {
        this.game.debug(
          `F1358 | ${this.name}.js | ${direct_object.id}.dov.plugIn.with_params.connections contains null `,
        );
        msg += `${direct_object.Articlename} is already plugged in. `;
        this.handleFailure(msg);
        return false;
      }

      // sentence structure: verb noun // ie plugIn computer
      if (input.hasStructure("verb noun")) {
        // indirect object required?
        if (direct_object.DOVallowWithNothing(this.name)) {
          return true;
        }

        // indirect objects available?
        if (!direct_object.DOVhasIndirectObjects(this.name)) {
          this.game.debug(
            `F1690 | ${this.name}.js | ${direct_object.id}.dov.${this.name}.with_nothing is false `,
          );
          msg += `$(We) don't know of a way to ${this.prettyname} ${direct_object.articlename}. `;
          this.handleFailure(msg);
          return false;
        }

        // infer indirect object?
        results = this.tryToInferIndirectObject(direct_object);
        if (results.prompt) {
          // restructure sentence for next turn
          //input.setPreposition(2,'with');
          input.setSoftPrompt({
            noun2: true,
            structure: "verb noun noun",
          });
          this.game.debug(`F1692 | ${this.name}.js | soft prompt for noun2 `);
          msg += `What would $(we) like to plug ${direct_object.articlename} into? `;
          this.handleFailure(msg);
          return false;
        } else if (results.success) {
          indirect_object = results.indirect_object;
          indirect_preposition = "to";
          input.setNewPhrase({
            asset: indirect_object,
            preposition: indirect_preposition,
          });
          input.setStructure("verb noun noun");
        }
      } // verb noun

      // parsed sentence structure: verb noun noun
      // ie plugIn computer outlet
      if (input.hasStructure("verb noun noun")) {
        // works with any indirect object?
        if (direct_object.DOVallowWithAnything(this.name)) {
          return true;
        }

        // indirect object not required?
        if (direct_object.DOVallowWithNothing(this.name)) {
          this.game.debug(
            `F1762 | ${this.name}.js | ${direct_object.id}.dov.${this.name}.with_nothing `,
          );
          msg += `$(We) can't plug ${direct_object.articlename} into ${indirect_object.articlename}. `;
          this.handleFailure(msg);
          return null;
        }

        // indirect object usable with direct object?
        if (!direct_object.DOVallowWithAsset(this.name, indirect_object)) {
          this.game.debug(
            `F1763 | ${this.name}.js | ${direct_object.id}.dov.${this.name}.with_assets/with_classes does not include ${indirect_object.id} `,
          );
          msg += `$(We) can't plug ${direct_object.articlename} into ${indirect_object.articlename}. `;
          this.handleFailure(msg);
          return null;
        }

        // can indirect object be used?
        if (!indirect_object.isIOV(this.name)) {
          this.game.debug(
            `F1907 | ${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 false;
        }

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

        // is direct object already plugged in?
        if (
          direct_object.dov.plugIn.with_params.connections.length >=
          direct_object.dov.plugIn.with_params.max_connections
        ) {
          this.game.debug(
            `F1752 | ${this.name}.js | ${direct_object.id}.dov.plugIn.with_params.max_connections reached `,
          );
          msg += direct_object.DOVisConnectedToAsset(this.name, indirect_object)
            ? `${direct_object.Articlename} is already plugged into ${indirect_object.articlename}. `
            : `${direct_object.Articlename} can't be plugged into any more things. `;
          this.handleFailure(msg);
          return null;
        }

        // does indirect object already have max plugged into it?
        if (
          indirect_object.iov.plugIn.with_params.connections.length >=
          indirect_object.iov.plugIn.with_params.max_connections
        ) {
          this.game.debug(
            `F1760 | ${this.name}.js | ${indirect_object.id}.iov.plugIn.with_params.max_connections reached `,
          );
          msg += `${indirect_object.Articlename} can't have any more things plugged into it. `;
          this.handleFailure(msg);
          return null;
        }
      } // verb noun noun

      return true;
    },

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

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

      // parsed sentence structure: verb noun
      if (input.hasStructure("verb noun")) {
        // connect direct object to null
        this.setVerbSubscriptionConnection(direct_object, null);
      } // verb noun

      // sentence structure: verb noun noun
      if (input.hasStructure("verb noun noun")) {
        // connect direct object to indirect object
        this.setVerbSubscriptionConnection(direct_object, indirect_object);

        // @TODO reconsider plug as one type of attachment
        // what to do if player moves between nests or tries travel?
        // if( direct_object.isIn(player) )
        // {
        //   // remove direct_object from player?
        //   results = indirect_object.moveFrom( player );
        //   if( "undefined" !== typeof results ) return results;
        // }
        // // move indirect_object to direct_object
        // results = indirect_object.moveTo( "in", direct_object );
        // if( "undefined" !== typeof results ) return results;
      } // verb noun noun

      // apply state changes
      this.setState(direct_object, true);

      // compose output
      msg += `$(We) plug`;
      msg += `${indirect_object ? "" : " in"}`;
      msg += `${direct_object ? " " + direct_object.articlename : ""}`;
      msg += `${indirect_object ? " into " + indirect_object.articlename : ""}`;
      msg += `. `;

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