import { createCharacter } from "./create_character.js";
import { assignNickName } from "./create_character_name.js";
import { logger } from "./utils.js";
import { mapLoader } from "./data_loaders.js";
import { random, roll, test } from "./random_utils.js";
import { TRAITS as T } from "./constants.js";
import Gang from "./models/gang.js";
const map = await mapLoader("names.data");
/*
* TODO: All girl gangs/all boy gangs mostly, with sometimes a connection between the two.
patrols: no communications or medics in group.
*
* TODO: Non-criminal gangs? Like the "Eastside Motorcycle Club" or the "Southside Paladins", etc.?
"nomadic": [
"Raiding Parties (Banditry or Plundering)",
"Scavenging",
"Ambushes/Highway Robbery (Brigandry)"
],
"street": [
"Protection Rackets",
"Burglery & Larceny",
"Pickpocketing",
"Scavenging",
"Extracting tolls for passage or entry"
]
Names for military patrols
*/
const TYPES = {
"Biker Gang": {
prof: "Raider",
nicks: 100,
traits: { [T.MOTORCYCLING]: 1 },
count: "3d4-2",
names: map.get("names.biker.gang"),
},
"Street Gang": {
prof: "Thief",
nicks: 100,
count: "1d4+1",
names: map.get("names.street.gang"),
},
"Raiding Gang": {
prof: "Raider",
count: "3d4-1",
nicks: 90,
},
"Scavenger Party": {
prof: "Scavenger",
count: "1d4+1",
nicks: 50,
},
// TODO: Which isn't a group of working buckeroos. Those guys might have a chuck wagon and the like
"Cowboy Posse": {
prof: "Rancher",
count: "1d5+1",
nicks: 20,
},
"Cattle Rustler Gang": {
prof: ["Rancher", "Rancher", "Scavenger", "Thief"],
count: "1d3+1",
nicks: 50,
},
"Ex-Army Gang": {
prof: "Raider",
count: "1d3*4",
military: "Army",
nicks: 5,
},
"Ex-Marine Gang": {
prof: "Raider",
count: "1d3*4",
military: "Marine",
nicks: 15,
},
};
const TYPE_KEYS = Object.keys(TYPES);
export function getGangTypes() {
return TYPE_KEYS.sort();
}
/**
* Creates a gang of characters with a shared type, name, and profession-appropriate traits.
* Each member is a generated Character. Members may be assigned nicknames depending on gang type.
*
* @param {Object} [options={}] - Gang creation options
* @param {string} [options.type] - Type of gang to create, selected from the values returned by
* `getGangTypes()` (e.g. "Biker Gang", "Street Gang", "Raiding Gang", "Cowboy Posse"). If not
* provided, randomly selected.
* @param {number} [options.count=null] - Number of gang members to generate. If not provided, a count
* is rolled based on the gang type's configuration.
* @returns {Gang} A new Gang instance containing the generated member characters
*/
export function createGang({ type = random(TYPE_KEYS), count = null } = {}) {
logger.start("createGang", { type, count });
const gangType = type;
const gangSpec = TYPES[gangType];
if (typeof gangSpec === "undefined") {
throw new Error("Invalid gang type: " + gangType);
}
const opts = {
kind: gangType,
name: random(gangSpec.names),
};
const gang = new Gang({ name: opts.name, kind: gangType });
let newCount = count ? count : roll(gangSpec.count);
for (let i = 0; i < newCount; i++) {
const c = createCharacter({
preProfession: gangSpec.military,
postProfession: random(gangSpec.prof),
});
if (test(gangSpec.nicks)) {
assignNickName(c);
}
gang.add(c);
}
return logger.end(gang);
}