import { createItem } from "./create_item.js";
import { format, sentenceCase } from "./string_utils.js";
import { logger } from "./utils.js";
import { mapLoader } from "./data_loaders.js";
import { random, roll, test } from "./random_utils.js";
import Bag from "./models/bag.js";
import Dog from "./models/dog.js";
import Horse from "./models/horse.js";
import Model from "./models/model.js";
import RarityTable from "./tables/rarity_table.js";
const map = await mapLoader("animals.data");
const HORSES_MALE_NAMES = map.get("horses.male.names");
const HORSES_FEMALE_NAMES = map.get("horses.female.names");
const HORSES_BOTH_NAMES = map.get("horses.unisex.names");
const HORSES_BEHAVIOR = map.get("horses.behavior");
const HORSES_PATTERNS = map.get("horses.patterns");
const HORSES_EFFECTS = map.get("horses.effects");
const HORSE_FEMALE_NAME_TABLE = new RarityTable({
useStrict: false,
outFunction: (a) => random(a),
})
.add("common", HORSES_FEMALE_NAMES)
.add("common", HORSES_BOTH_NAMES);
const HORSE_MALE_NAME_TABLE = new RarityTable({ useStrict: false, outFunction: (a) => random(a) })
.add("common", HORSES_MALE_NAMES)
.add("common", HORSES_BOTH_NAMES);
const HORSE_NAMES_BY_GENDER = {
male: HORSE_MALE_NAME_TABLE,
female: HORSE_FEMALE_NAME_TABLE,
};
const HORSE_FEMALE_TYPES = new RarityTable({ useStrict: false })
.add("rare", "filly")
.add("common", "mare");
const HORSE_MALE_TYPES = new RarityTable({ useStrict: false })
.add("rare", "colt")
.add("uncommon", "stallion")
.add("common", "gelding");
const HORSE_TYPES_BY_GENDER = {
male: HORSE_MALE_TYPES,
female: HORSE_FEMALE_TYPES,
};
const DOGS_MALE_NAMES = map.get("dog.male.names");
const DOGS_FEMALE_NAMES = map.get("dog.female.names");
/**
* 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(HORSES_PATTERNS).trim();
let type = random(HORSE_TYPES_BY_GENDER[gender].get()).trim();
let behavior = test(50) ? random(HORSES_BEHAVIOR).trim() : undefined;
let name = random(HORSE_NAMES_BY_GENDER[gender].get()).trim();
let effect;
if (test(40)) {
effect = format(random(HORSES_EFFECTS), {
possessive: gender === "male" ? "his" : "her",
personal: gender === "male" ? "he" : "she",
});
}
let bag = new Bag();
if (test(80)) {
bag.add(createItem({ tags: "horse-tack" }));
bag.add(createItem({ tags: "saddle" }));
if (test(80)) {
for (let i = 1; i < roll("1d2"); i++) {
bag.add(createItem({ tags: "saddlebag" }));
}
}
}
return logger.end(
new Horse({
name,
behavior,
pattern,
gender,
type,
bag,
effect,
}),
);
}
export function createDog({} = {}) {
logger.start("createDog");
const gender = random(["male", "female"]);
const name = gender === "male" ? random(DOGS_MALE_NAMES) : random(DOGS_FEMALE_NAMES);
const dog = new Dog({
name,
gender,
coloring: "spotted",
breed: "mutt",
});
return logger.end(dog);
}
export function getAnimalTypes() {
return ["Dog", "Horse"];
}
export function createAnimal({ type = random(getAnimalTypes()) } = {}) {
logger.start("createAnimal", { type });
switch (type) {
case "Dog":
return logger.end(createDog());
break;
case "Horse":
return logger.end(createHorse());
break;
}
}