import { CONDITION_MULTIPLIER } from "./constants.js";
import { createBookTitle } from "./create_book_title.js";
import { createHorseDescription } from "./create_horse_description.js";
import { createMagazineTitle } from "./create_magazine_title.js";
import { lineLoader } from "./data_loaders.js";
import { logger } from "./utils.js";
import { MEMORABILIA } from "./create_memorabilia.js";
import { test } from "./random_utils.js";
import Item from "./models/item.js";
import ItemDatabase from "./db/item_database.js";
import RarityTable from "./tables/rarity_table.js";
export const CONDITIONS = new RarityTable()
.add("uncommon", "poor")
.add("common", "fair")
.add("common", "good")
.add("uncommon", "excellent")
.add("rare", "mint");
// 10mm, 5.56, 5mm
// Cigarette brands: Chelsea, Chesterfield, Craven, Lucky Strike, Old Gold, Raleigh, and Wings.
const itemDb = new ItemDatabase();
const items = await lineLoader("items.data");
itemDb.add.apply(itemDb, items);
MEMORABILIA.forEach((memo) => itemDb.table.add(memo.frequency, memo));
export { itemDb };
/**
* Creates a random item from the item database, optionally filtered by name, tags, value range,
* or encumbrance range. Automatically generates titles for books, magazines, and horses.
*
* @param {Object} [options={}] - Item creation options
* @param {string} [options.name] - Specific item name to look up. If not provided, an item is selected by tags.
* @param {string} [options.tags="*"] - Tag expression to filter items (e.g. "firearm", "ammo:22",
* "food -luxury"). Supports the full tag expression syntax including `|`, space (AND), and parentheses.
* @param {number} [options.minValue=0] - Minimum item value (in caps).
* @param {number} [options.maxValue=Number.MAX_VALUE] - Maximum item value (in caps).
* @param {number} [options.minEnc=0] - Minimum item encumbrance.
* @param {number} [options.maxEnc=Number.MAX_VALUE] - Maximum item encumbrance.
* @param {string} [options.condition] - Item condition: "poor", "fair", "good", "excellent", or "mint".
* Affects value for items that can break. If not provided, randomly selected by rarity.
* @returns {Item} An Item instance matching the given criteria, or null if no match is found
*/
export function createItem({
name,
tags = "*",
minValue = 0,
maxValue = Number.MAX_VALUE,
minEnc = 0,
maxEnc = Number.MAX_VALUE,
condition = CONDITIONS.get(),
} = {}) {
logger.start("createItem", { name, tags, minValue, maxValue, minEnc, maxEnc, condition });
// items from the database are archetypes, so some qualities are determined per instance,
// such as condition, breakage, and flavor text
let item = itemDb.findOne({ name, tags, minValue, maxValue, minEnc, maxEnc });
if (!item) {
console.warn(
"No item found for terms: " +
JSON.stringify({ name, tags, minValue, maxValue, minEnc, maxEnc }),
);
} else if (item.name === "horse") {
item = new Item({ ...item, title: createHorseDescription() });
} else if (item.has("book") && !item.title && !item.series.title && item.is("titled")) {
item = new Item({ ...item, title: createBookTitle() });
} else if (item.has("magazine") && item.not("collectible") && item.is("titled")) {
item = new Item({ ...item, title: createMagazineTitle() });
} else if (item.has("br")) {
item.tags.delete("br");
item.condition = condition;
item.value = item.value * CONDITION_MULTIPLIER[item.condition];
if (["poor", "fair"].includes(condition) && test(75)) {
item.tags.add("br");
}
}
return logger.end(item);
}