Pre-release
AdventureJS Docs Downloads
Score: 0 Moves: 0
// getPrintableListOfContentsAt.js
(function () {
  /* global AdventureJS A */
  var p = AdventureJS.Assets.Entity.prototype;
  /**
   * Get a printable list of assets within a specified
   * Aspect of this asset, for example
   * to append to asset description when player inputs
   * "look in this". Returns a string.
   * @memberOf AdventureJS.Assets.Entity
   * @method AdventureJS.Assets.Entity#getPrintableListOfContentsAt
   * @param {String|Object} aspect
   * @param {Object} params
   * @return {String}
   * @todo reconsider this logic because it assumes that aspect can be
   * not enabled while substance within it can be enabled
   * and that is not how I see it right now
   */
  p.getPrintableListOfContentsAt = function Entity_getPrintableListOfContentsAt(
    aspect,
    params
  ) {
    if ("string" === typeof aspect) aspect = this.aspects[aspect];
    if (!aspect) return "";

    this.game.log(
      "L1480",
      "log",
      "high",
      `[getPrintableListOfContentsAt.js] ${this.id}.getPrintableListOfContentsAt("${aspect.name}")`,
      "Entity"
    );

    const vessel = aspect.vessel;

    // neither things nor substances enabled
    // @todo reconsider this logic
    if (
      !this.hasAspectAt(aspect.name) &&
      !this.hasVesselAtAspect(aspect.name)
    ) {
      return "";
    }

    // only things enabled but no things to list
    if (
      this.hasAspectAt(aspect.name) &&
      !this.hasVesselAtAspect(aspect.name) &&
      0 === this.getCountOfListableContentsAt(aspect.name)
    ) {
      return "";
    }

    // only substances enabled but empty
    if (
      !this.hasAspectAt(aspect.name) &&
      this.hasVesselAtAspect(aspect.name) &&
      0 >= vessel.getVolume()
    ) {
      return "";
    }

    // some valid contexts call without params
    params = params || {};
    params.caller = params.caller || "examine";

    var output = "";
    var listableObjects = [];
    var contents = A.FX.clone.call(this.game, aspect.contents);
    var empty = true;
    var substance = "";
    var character = this.hasClass("Character");
    var player = this.id === this.game.world._player;

    // does aspect contain substance?
    if (
      this.hasVesselAtAspect(aspect.name) &&
      0 < vessel.getVolume() &&
      vessel.substance_id
    ) {
      // shouldn't be necessary
      empty = false;
      vessel.is.known = true; // ??

      substance = this.game.world[vessel.substance_id]; //.name;

      if (vessel.is.emitting) {
        output += `${substance.Name} spills out of ${this.article_name}. `;
      } else if (!params.exclude_substance) {
        // we have a lookup table for percent values but it rounds down
        // and if percent is between 0 and 0.1 we treat it like 0.1
        const percent =
          vessel.percent_of_maxvolume > 0 && vessel.percent_of_maxvolume < 0.1
            ? "0.1"
            : vessel.percent_of_maxvolume.toFixed(1);

        output += `${
          this.Article_name
        } is ${this.game.dictionary.getStringLookup(
          "substance_percents",
          percent
        )} of ${substance.name}. `;
      }
    }

    for (var i = 0; i < contents.length; i++) {
      var object = this.game.getAsset(contents[i]);

      if (object.is.hidden) {
        continue;
      }

      if (!object.is.listed) {
        continue;
      }

      listableObjects.push(object);
    }

    // if( 0 === listableObjects.length
    // && empty
    // && "examine" === params.caller )
    // {
    //   output += " There isn't anything "
    //   + this.game.dictionary.getStringLookup( "prepositions", aspect.name )
    //   + " "
    //   + this.definite_article
    //   + " "
    //   + this.name
    //   + ". ";
    // }

    if (listableObjects.length > 0) {
      const preposition = this.game.dictionary.getStringLookup(
        "prepositions",
        aspect.name
      );

      // get the raw list
      let raw_list = this.game.getPrintableObjectList({
        objects: listableObjects,
      });

      // get format from settings
      // let asset_list = this.game.settings.asset_list_format.toLowerCase();
      let asset_list =
        this.game.settings[
          character ? "character_list_format" : "asset_list_format"
        ].toLowerCase();

      // console.warn(`asset_list 01`, asset_list);

      // aspect name
      asset_list = asset_list.replace(/{preposition}/g, preposition);

      // console.warn(`asset_list 02`, asset_list);

      // asset name
      if (substance) {
        asset_list = asset_list.replace(/{name}/g, "the " + substance.name);
      } else if (player) {
        asset_list = asset_list.replace(/{name}/g, this.inflect("we're"));
      } else if (character) {
        asset_list = asset_list.replace(
          /{name}/g,
          this.proper_name || this.name
        );
      } else {
        asset_list = asset_list.replace(/{name}/g, this.article_name);
      }

      // console.warn(`asset_list 03`, asset_list);

      // nested assets
      asset_list = asset_list.replace(/{list}/g, raw_list);

      // is / are
      if (player) {
        // we've already handled is/are with the name
        asset_list = asset_list.replace(/{is}/g, "");
      } else if (character) {
        asset_list = asset_list.replace(
          /{is}/g,
          this.inflect("are", this.gender)
        );
      } else {
        asset_list = asset_list.replace(
          /{is}/g,
          raw_list.includes(",") ||
            raw_list.includes(" some ") ||
            raw_list.includes(" and ")
            ? "are"
            : "is"
        );
      }

      // console.warn(`asset_list 04`, asset_list);

      // handlePlaceholders handles pronoun substitution
      asset_list = A.FX.handlePlaceholders.call(this.game, asset_list);

      // console.warn(`asset_list 05`, asset_list);

      asset_list = asset_list.trim();

      // console.warn(`asset_list 06`, asset_list);

      // capitalize the first letter
      output += ` ${A.FX.capitalize(asset_list)} `;
    }

    if (output.length) {
      output = `<span class="${params.caller === "room" ? "ajs-p ajs-aspect" : "ajs-aspect"}">${output}</span>`;
    }

    return output;
  };
})();