models/gang.js

import Model from "./model.js";
import { Builder } from "../string_utils.js";
import { COMBAT_TRAITS } from "../constants.js";

function gangName(b, gang) {
  b.if(
    !!gang.name,
    `The ${gang.name} (${gang.kind}): `,
    `${gang.members.length} member ${gang.kind}: `
  );
  return b;
}

function combatantString(character) {
  var traits = {};
  Object.values(COMBAT_TRAITS).forEach(function (traitName) {
    if (character.trait(traitName) > 0) {
      traits[traitName] = character.trait(traitName);
    }
  });
  // This is destructive, which is not great
  character.traits = traits;
  character.description = [];
  return character.toString();
}

/**
 * Represents a Gang, which is a set of characters of a specific kind or purpose. Could
 * also be called a “party”.
 *
 * @class
 * @extends Model
 *
 * @property {Array<Character>} members - The members of the gang.
 * @property {String} kind - The kind or type of the gang.
 * @property {String} [name] - The name of the gang.
 *
 * @example
 * const gang = new Gang({
 *   name: 'Oakley Boys',
 *   kind: 'Cowboy Posse',
 *   members: [pa, littleJohn, billy]
 * });
 */
class Gang extends Model {
  /**
   * Create a Gang.
   * @param [params] {Object}
   * @param {String} params.kind - The kind/type of the gang.
   * @param {String} [params.name] - The name of the gang.
   * @param {Array} [params.members=[]] - The members of the gang.
   * @param {Array} [params.tags=[]] - Tags associated with the gang.
   */
  constructor({ kind, name, members = [], tags = [] } = {}) {
    super({ tags });
    this.members = members;
    this.kind = kind;
    this.name = name;
  }
  add(character) {
    this.members.push(character);
  }
  toString() {
    var b = new Builder();
    gangName(b, this);
    b.append("\n\n");
    b.append(this.members.map((m) => combatantString(m)).join("\n\n"));
    return b.toString();
  }
}

export default Gang;