import { createGender, getProfessions } from "./create_character.js";
import { createItem } from "./create_item.js";
import { database as professionDb } from "./professions.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";
// TODOs:
// remove radiation suit and chaps from "clothes" and make them profession-specific
// update the profession tags so you can do profession-specific weapons, clothing,
// tools.
function addAmmo(bag, firearm) {
var ammoType = firearm.typeOf("ammo");
var bundledAmmo = createItem({ tags: `ammo ${ammoType} bundled` });
if (test(20) && bundledAmmo) {
bag.add(bundledAmmo, roll("2d3"));
} else {
var ammo = createItem({ tags: `ammo ${ammoType} -bundled` });
switch (ammo.frequency) {
case "common":
bag.add(ammo, roll("8d8"));
break;
case "uncommon":
bag.add(ammo, roll("4d8"));
break;
case "rare":
bag.add(ammo, roll("3d6"));
break;
}
}
if (firearm.is("pistol") && test("60")) {
var holster = createItem({ tags: `holster` });
bag.add(holster);
}
}
function addUntil(...args) {
let bag = args.shift();
shuffle(args);
for (let i = 0; i < args.length; i++) {
let item = createItem({ tags: args[i] });
if (item) {
bag.add(item);
return;
}
}
console.warn("No item matches any of these tag sets: " + args.join("; "));
}
/**
* 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.gender] {String} gender of character (male or female)
* @param [params.traveling] {boolean} should this bag include extended equipment
* for exploring, and not just walk-abouts?
*
* @return {Object} An object of two bags, one under the property "clothing" and another
* under the bag of "possessions".
*/
export function createKit({
profession = random(getProfessions()),
gender = createGender(),
traveling = false,
} = {}) {
logger.start("createKit", { profession, gender, traveling });
var clothing = new Bag();
var possessions = new Bag();
var selGender = gender.toLowerCase();
var profConfig = professionDb.findOne({ name: profession });
var profKit = profConfig.kit;
// clothes. stuff isn't tagged by profession
if (test(20)) {
addUntil(
clothing,
`clothing body -armor (${profKit})`,
`clothing body -armor (${selGender} | unisex)`
);
} else {
addUntil(
clothing,
`clothing torso -armor -coat (${profKit})`,
`clothing torso -armor -coat (${selGender} | unisex)`
);
addUntil(
clothing,
`clothing legs -armor (${profKit})`,
`clothing legs -armor (${selGender} | unisex)`
);
}
// shoes
addUntil(clothing, `clothing feet (${profKit})`, `clothing feet (${selGender} | unisex)`);
// hat
if (test(60)) {
addUntil(clothing, `clothing head (${profKit})`, `clothing head (${selGender} | unisex)`);
} else if (test(20)) {
addUntil(possessions, `armor head`);
}
if (test(20)) {
addUntil(possessions, `armor body`, `armor torso`);
}
// weapons and ammo
var firearm = createItem({ tags: `firearm` });
var melee = createItem({ tags: `melee` });
var result = roll("1d10");
if (result < 4) {
possessions.add(firearm);
addAmmo(possessions, firearm);
} else if (result < 8) {
possessions.add(melee);
possessions.add(firearm);
addAmmo(possessions, firearm);
} else {
possessions.add(melee);
}
if (traveling) {
var carry = createItem({ tags: `useful travel container` });
if (carry) {
possessions.add(carry);
}
// exploration: wayfinding
// exploration: communication
// personal effects
for (var i = 0; i < roll("1d4-2"); i++) {
var item = createItem({ tags: `(kit:* tiny) | accessory` });
possessions.add(item);
}
// exploration: food
for (var i = 0; i < roll("2d4"); i++) {
var food = createItem({ tags: `food -candy (preserved | ration | fruit)` });
possessions.add(food);
}
// Not entirely happy with the horse as a possession. The horse can carry stuff and probably
// would be carrying some stuff like feed, there’s no way to describe this, nor the relationship
// to the character. What if they have two horses, or six?
createTransport({ bag: possessions, profConfig });
}
return logger.end({ clothing, possessions });
}
function hasTrait(prof, trait) {
return prof.seeds.includes(trait) || prof.traits.includes(trait);
}
function createTransport({ bag, profConfig } = {}) {
let chanceHorse = hasTrait(profConfig, T.HORSEBACK_RIDING) ? 60 : 20;
let chanceMotorcycle = hasTrait(profConfig, T.MOTORCYCLING) ? 20 : 5;
console.debug(`chanceHorse = ${chanceHorse}, chanceMotorcycle = ${chanceMotorcycle}`);
// TODO: If they have a motorcycle, they have some amount of gas and gas in tanks.
// If they have a horse, the horse probably has saddlebags and may be carrying feed
let hasHorse = test(chanceHorse);
let hasMotorcycle = test(chanceHorse);
if (chanceHorse > chanceMotorcycle && hasHorse) {
bag.add(createItem({ tags: "horse" }), 1);
} else if (hasMotorcycle) {
bag.add(createItem({ tags: "motorcycle" }), 1);
}
}