import { augment } from "./create_bag.js";
import { createGender } from "./create_character.js";
import { createItem } from "./create_item.js";
import { createProfession, getPostProfessions } from "./create_profession.js";
import { getConditionGroup } from "./condition.js";
import { logger } from "./utils.js";
import { roll, random, shuffle, test } from "./random_utils.js";
import { TRAITS as T } from "./constants.js";
import Bag from "./models/bag.js";
import Kit from "./models/kit.js";
// TODO: Use these so they git picked up in the generator configs
const EQUIP_OPTIONS = Object.freeze(["None", "Patrol", "Travel"]);
export const getKitOptions = () => EQUIP_OPTIONS;
function add(bag, tags, count = 1) {
for (let i = 0; i < count; i++) {
let item = createItem({ tags });
if (item) {
bag.add(item, 1);
return true;
}
return false;
}
}
function addUntil(bag, ...allTagArrays) {
shuffle(allTagArrays);
for (let i = 0; i < allTagArrays.length; i++) {
let tagArray = allTagArrays[i];
let haveAdded = false;
for (let j = 0; j < tagArray.length; j++) {
let item = createItem({ tags: tagArray[j] });
if (item) {
bag.add(item, 1);
haveAdded = true;
}
}
if (haveAdded) {
return;
}
}
}
/**
* Generate the possessions that would be on the person of an active NPC (e.g.
* out on patrol, out for a night on the town, out on a raid or in the middle
* of criminal activity).
*
* @param params {Object}
* @param [params.profession] {String|Profession} profession name or instance
* @param [params.preProfession] {String|Profession} profession name or instance
* @param [params.gender] {String} gender of character (male or female)
* @param [params.kit] {String} One of three options, “None” (clothing only);
* “Patrol” (weapons only); and “Travel” (the full amount of equipment a person
* would carry to explore or travel).
*
* @return {Object} An object of two bags, one under the property "clothing" and another
* under the bag of "possessions".
*/
export function createKit({
profession = random(getPostProfessions()),
gender = createGender(),
kit = random(EQUIP_OPTIONS),
} = {}) {
logger.start("createKit", { profession, gender, kit });
const clothing = new Bag();
const possessions = new Bag();
const selGender = gender.toLowerCase();
const profConfig = createProfession({ name: profession });
const kitTag = profConfig.kit;
addUntil(
clothing,
[`post clothing body -armor kit:${kitTag} (${selGender} | unisex)`],
[
`post clothing torso -armor -coat kit:${kitTag} (${selGender} | unisex)`,
`post clothing legs -armor kit:${kitTag} (${selGender} | unisex)`,
],
[`post clothing body -armor -kit (${selGender} | unisex)`],
[
`post clothing torso -armor -coat -kit (${selGender} | unisex)`,
`post clothing legs -armor -coat -kit (${selGender} | unisex)`,
],
);
// shoes
addUntil(
clothing,
[`post clothing feet -kit (${selGender} | unisex)`],
[`post clothing feet kit:${kitTag} (${selGender} | unisex)`],
);
// hat
if (test(80)) {
addUntil(
clothing,
[`post clothing head -armor -kit (${selGender} | unisex)`],
[`post clothing head -armor kit:${kitTag} (${selGender} | unisex)`],
);
}
// weapons and ammo. people don't carry broken weapons
if (kit !== "None") {
const condition = random(getConditionGroup({ group: "U" })).name;
const firearm = createItem({ tags: `firearm`, condition });
firearm.tags.delete("br");
const melee = createItem({ tags: `melee` });
const result = roll("1d10");
if (result < 4) {
augment(possessions, firearm, profession);
} else if (result < 8) {
possessions.add(melee);
augment(possessions, firearm, profession);
} else {
possessions.add(melee);
}
if (!profConfig.tags.has("prestige:high") && test(20)) {
addUntil(possessions, [`armor head -kit`]);
addUntil(possessions, [`armor (body | torso) -kit`]);
}
// criminal, cowboy, science, military, worker, doctor, guard, gang, scavenger
if (kit) {
add(possessions, `kit:${kitTag}`);
}
}
if (kit === "Travel") {
// TODO: separate trinkets and accessories, accessories go under clothing
add(possessions, `accessory`, roll("1d4-2"));
add(possessions, `food -candy (preserved | ration | fruit)`, roll("2d3"));
add(possessions, `travel`, roll("1d4-1"));
// horses, motorcycles, pets are handled under encounters, where the can be more complex
// intersections of people, transport, and animals
}
return logger.end(
new Kit({
clothing,
possessions,
profession: random(profConfig.names),
gender: selGender,
}),
);
}