create_horse.js

import { format, sentenceCase } from "./string_utils.js";
import { logger } from "./utils.js";
import { mapLoader } from "./data_loaders.js";
import { random, test } from "./random_utils.js";
import RarityTable from "./tables/rarity_table.js";
import Horse from "./models/horse.js";

const map = await mapLoader("horses.data");

const MALE_HORSE_NAMES = map.get("male.names");
const FEMALE_HORSE_NAMES = map.get("female.names");
const BOTH_HORSE_NAMES = map.get("unisex.names");
const BEHAVIOR = map.get("behavior");
const PATTERNS = map.get("patterns");
const EFFECTS = map.get("effects");

const FEMALE_NAMES = new RarityTable({ useStrict: false, outFunction: (a) => random(a) });
FEMALE_NAMES.add("common", FEMALE_HORSE_NAMES);
FEMALE_NAMES.add("common", BOTH_HORSE_NAMES);

const MALE_NAMES = new RarityTable({ useStrict: false, outFunction: (a) => random(a) });
MALE_NAMES.add("common", MALE_HORSE_NAMES);
MALE_NAMES.add("common", BOTH_HORSE_NAMES);

const NAMES_BY_GENDER = {
  male: MALE_NAMES,
  female: FEMALE_NAMES,
};

const FEMALE_TYPES = new RarityTable({ useStrict: false });
FEMALE_TYPES.add("rare", "filly");
FEMALE_TYPES.add("common", "mare");

const MALE_TYPES = new RarityTable({ useStrict: false });
MALE_TYPES.add("rare", "colt");
MALE_TYPES.add("uncommon", "stallion");
MALE_TYPES.add("common", "gelding");

const TYPES_BY_GENDER = {
  male: MALE_TYPES,
  female: FEMALE_TYPES,
};

/**
 * Generates a descriptive string for a horse, including its type, optional behavior,
 * coat pattern, and name.
 *
 * @param {Object} [options={}] - Horse description options
 * @param {string} [options.gender] - Gender of the horse ("male" or "female"). Male horses may be
 *    stallions, geldings, or colts; female horses may be mares or fillies. If not provided,
 *    randomly selected.
 * @returns {string} A descriptive phrase for the horse (e.g. "a nervous spotted mare named Clover")
 */
export function createHorse({ gender = random(["male", "female"]) } = {}) {
  logger.start("createHorse", { gender });

  let pattern = random(PATTERNS).trim();
  let type = random(TYPES_BY_GENDER[gender].get()).trim();
  let behavior = test(50) ? random(BEHAVIOR).trim() : undefined;
  let name = random(NAMES_BY_GENDER[gender].get()).trim();
  let effect;
  if (test(40)) {
    effect = format(random(EFFECTS), {
      possessive: gender === "male" ? "his" : "her",
      personal: gender === "male" ? "he" : "she",
    });
  }
  return logger.end(
    new Horse({
      name,
      behavior,
      pattern,
      gender,
      type,
      effect,
    }),
  );
}