diff --git a/lib/npc-generation/familyRaces.ts b/lib/npc-generation/familyRaces.ts index f153372f9..e88de16e5 100644 --- a/lib/npc-generation/familyRaces.ts +++ b/lib/npc-generation/familyRaces.ts @@ -20,7 +20,9 @@ export const marriagePools: Record = { 'half-elf': ['human', 'elf', 'half-elf', 'half-orc'], 'half-orc': ['human', 'orc', 'half-elf', 'half-orc'], 'tiefling': ['human', 'tiefling'], - 'lizardfolk': ['lizardfolk'] + 'lizardfolk': ['lizardfolk'], + 'ratfolk': ['ratfolk', 'goblin', 'halfling', 'gnome'], + 'kitsune': ['human', 'kitsune', 'elf', 'tiefling', 'dragonborn', 'lizardfolk', 'dwarf', 'gnome', 'halfling', 'ratfolk'] } export function findParentRaces (npc: NPC) { diff --git a/lib/npc-generation/getAgeInYears.test.ts b/lib/npc-generation/getAgeInYears.test.ts index f5124bf04..8447419e0 100644 --- a/lib/npc-generation/getAgeInYears.test.ts +++ b/lib/npc-generation/getAgeInYears.test.ts @@ -10,5 +10,7 @@ describe(getAgeInYears.name, () => { expect(typeof getAgeInYears('half-elf', 'elderly')).toBe('number') expect(typeof getAgeInYears('human', 'settled adult')).toBe('number') expect(typeof getAgeInYears('tiefling', 'young adult')).toBe('number') + expect(typeof getAgeInYears('ratfolk', 'child')).toBe('number') + expect(typeof getAgeInYears('kitsune', 'settled adult')).toBe('number') }) }) diff --git a/lib/npc-generation/raceTraits.ts b/lib/npc-generation/raceTraits.ts index bfdc4231c..c4cb2704f 100644 --- a/lib/npc-generation/raceTraits.ts +++ b/lib/npc-generation/raceTraits.ts @@ -12,8 +12,10 @@ import { tiefling } from './races/tiefling' import { orc } from './races/orc' import { lizardfolk } from './races/lizardfolk' import { goblin } from './races/goblin' +import { ratfolk } from './races/ratfolk' +import { kitsune } from './races/kitsune' -export type RaceName = 'dragonborn' | 'dwarf' | 'elf' | 'gnome' | 'half-elf' | 'halfling' | 'half-orc' | 'human' | 'tiefling' | 'goblin' | 'orc' | 'lizardfolk' +export type RaceName = 'dragonborn' | 'dwarf' | 'elf' | 'gnome' | 'half-elf' | 'halfling' | 'half-orc' | 'human' | 'tiefling' | 'goblin' | 'orc' | 'lizardfolk' | 'ratfolk' | 'kitsune' export interface RaceTrait { muscleMass: number @@ -66,5 +68,7 @@ export const raceTraits: Record = { human, tiefling, orc, - lizardfolk + lizardfolk, + ratfolk, + kitsune } diff --git a/lib/npc-generation/races/kitsune.ts b/lib/npc-generation/races/kitsune.ts new file mode 100644 index 000000000..2f2959cc6 --- /dev/null +++ b/lib/npc-generation/races/kitsune.ts @@ -0,0 +1,304 @@ +import { dice } from '../../src/dice' +import { RaceTrait } from '../raceTraits' + +// race source: Pathfinder 2e +// for details, see https://2e.aonprd.com/Ancestries.aspx?ID=38 + +export const kitsune: RaceTrait = { + muscleMass: 9, + bmiModifier: 703, + ageTraits: { + 'ageDescriptors': [ + [110, 'ancient'], + [90, 'incredibly elderly'], + [80, 'vulnerably elderly'], + [75, 'withered'], + [70, 'elderly'], + [65, 'weathered'], + [60, 'aged'], + [55, 'old'], + [50, 'middle aged'], + [45, 'middle aged'], + [40, 'early middle aged'], + [37, 'adult'], + [35, 'mid thirties'], + [32, 'earlyish thirties'], + [30, 'prime adult aged'], + [26, 'young adult'], + [24, 'youthful adult'], + [22, 'relatively young'], + [20, 'surprisingly young'], + [19, 'nineteen year old'], + [18, 'barely adult aged'], + [17, 'late teenager'], + [16, 'teenager'], + [15, 'young teenager'], + [14, 'adolescent'], + [12, 'prepubescent'], + [10, 'child'], + [8, 'young child'], + [6, 'toddler'], + [0, 'newborn'] + ], + 'elderly': { + baseAge: 65, + ageModifier: () => dice(3, 4) + }, + 'settled adult': { + baseAge: 30, + ageModifier: () => dice(3, 10) + }, + 'young adult': { + baseAge: 15, + ageModifier: () => dice(4, 5) + }, + 'child': { + baseAge: 5, + ageModifier: () => dice(3, 4) + } + }, + genderTraits: { + entity: {}, + nonbinary: { + firstName: [ + 'Aisiri', + 'Akemi', + 'Ashinsen', + 'Chinatsu', + 'Dawn', + 'Domino', + 'Gina', + 'Haruhi', + 'Ikumi', + 'Kaeya', + 'Katsumi', + 'Kimiko', + 'Kiyoshi', + 'Minoru', + 'Nariyama', + 'Tadao', + 'Takumi', + 'Zenkichi', + 'Blossom', + 'Ichiyo', + 'Kamai', + 'Mitsami', + 'Sayoko', + 'Noriko', + 'Sachi', + 'Inoue', + 'Kazuko', + 'Katsue', + 'Yutsuko', + 'Natsuki', + 'Ai', + 'Taro', + 'Akira', + 'Boko', + 'Rimoru', + 'Naokuzo', + 'Sosamu', + 'Rin', + 'Seijuro', + 'Rotaru', + 'Nobuyuki', + 'Harumi', + 'Mekichi', + 'Munuko', + 'Juroshi', + 'Wayuko', + 'Yunu', + 'Tagoro' + ], + beardProbability: 0, + baseHeight: 61, + baseWeight: 90, + heightModifier: () => dice(2, 4), + weightModifier: () => dice(2, 6) + }, + woman: { + firstName: [ + 'Akela', + 'Akira', + 'Azula', + 'Chimera', + 'Haruhi', + 'Himani', + 'Kai', + 'Kirin', + 'Kotori', + 'Lynx', + 'Megumi', + 'Mia', + 'Michelle', + 'Naoki', + 'Primrose', + 'Suki', + 'Usagi', + 'Ushi', + 'Victoria', + 'Yoko', + 'Atsuko', + 'Hisako', + 'Kurize', + 'Raino', + 'Tasaji', + 'Yaro', + 'Miyeko', + 'Etsuko', + 'Kohaku', + 'Junko', + 'Nochiha', + 'Wazuki', + 'Hamika', + 'Esami', + 'Kirumi', + 'Mika', + 'Riko', + 'Chinatsu', + 'Momo', + 'Rifumi', + 'Eiju', + 'Keimoto', + 'Masanori', + 'Minoru', + 'Kafumi', + 'Muhiko', + 'Tenae' + ], + beardProbability: 0, + baseHeight: 62, + baseWeight: 100, + heightModifier: () => dice(2, 4), + weightModifier: () => dice(2, 6) + }, + man: { + firstName: [ + 'Asako', + 'Ayako', + 'Chane', + 'Chiko', + 'Chili', + 'Chrom', + 'Chuang', + 'Kalinda', + 'Kiyoshi', + 'Mario', + 'Michiko', + 'Mikel', + 'Mizuchi', + 'Nadi', + 'Namba', + 'Natsume', + 'Nittaya', + 'Nozomi', + 'Orochi', + 'Yayoi', + 'Tomio', + 'Noboru', + 'Teruo', + 'Boko', + 'Satsuna', + 'Damichi', + 'Atada', + 'Tetaru', + 'Yuki', + 'Sadao', + 'Yasuhiro', + 'Shigeru', + 'Seitane', + 'Kokoto', + 'Hotsune', + 'Hyotora', + 'Ganshiro', + 'Takeo', + 'Yoshiro', + 'Ryuu', + 'Reiho', + 'Senori', + 'Chirui', + 'Ichirou', + 'Sohira', + 'Surumi', + 'Kuchemon', + 'Kaede', + 'Gosaku', + 'Daru', + 'Iehira', + 'Maiko', + 'Rifumi' + ], + beardProbability: 25, + baseHeight: 62, + baseWeight: 100, + heightModifier: () => dice(2, 4), + weightModifier: () => dice(3, 6) + } + }, + lastName: [ + 'Bemei', + 'Dai', + 'Fumio', + 'Hisashi', + 'Hyosuki', + 'Jun', + 'Kin', + 'Kou', + 'Makato', + 'Masanori', + 'Masayoshi', + 'Michi', + 'Mokei', + 'Nimiaki', + 'Nonabu', + 'Ryuu', + 'Toshiaki', + 'Tsuneo', + 'Tsuyoshi', + 'Yuki', + 'Eternity', + 'Starspark', + 'Blueeyes', + 'Springstep', + 'Redfur', + 'Moonshine', + 'Sunhair', + 'Rincewind', + 'Softpaw', + 'Whitetail', + 'Wildfur', + 'Keeneye', + 'Stormsage', + 'Nightstep', + 'Mistdweller', + 'Bushbrow', + 'Akio', + 'Satoru', + 'Kazuhiro', + 'Masasada', + 'Kunimochi', + 'Sadamitsu', + 'Takaari', + 'Sueie', + 'Uchimasa', + 'Takachika', + 'Tsunenobu', + 'Hiraaki', + 'Tadahide', + 'Tsune' + ], + eyes: ['green', 'blue', 'gray', 'aqua', 'purple', 'gold', 'yellow', 'amber', 'brown', 'dark brown', 'hazel', 'red', 'blood red', 'dark red', 'black'], + raceWords: { + raceName: 'kitsune', + racePlural: 'kitsune', + raceSingular: 'kitsune', + raceAdjective: 'kitsunein', + raceLanguage: 'Common' + }, + knownLanguages: ['Common'], + beard: ['scraggly beard', 'long, flowing beard', 'goatee', 'goatee that seems to be trying to level up into a beard', 'rather wild, unkempt beard', 'dreadful beard'], + abilities: { + 'Low-Light Vision': 'Accustomed to life underground, you have superior vision in dim conditions. You can see in dim light as though it were bright light, so you ignore the concealed condition due to dim light.', + 'Change Shape': "You transform into a specific alternate form determined by your heritage. If your heritage doesn't list a form, your alternate form is a tailless form, which is a common Medium humanoid ancestry prevalent where you grew up (typically human). This form is the same age and body type as your true form and has roughly analogous physical traits, such as hair color. Using Change Shape counts as creating a disguise for the Impersonate use of Deception. You lose any unarmed Strikes you gained from a kitsune heritage or ancestry feat in this form. You can remain in your alternate form indefinitely, and you can shift back to your true kitsune form by using this action again." + } +} diff --git a/lib/npc-generation/races/ratfolk.ts b/lib/npc-generation/races/ratfolk.ts new file mode 100644 index 000000000..49a472043 --- /dev/null +++ b/lib/npc-generation/races/ratfolk.ts @@ -0,0 +1,289 @@ +import { dice } from '../../src/dice' +import { RaceTrait } from '../raceTraits' + +// source: Pathfinder 2e +// for details, see https://2e.aonprd.com/Ancestries.aspx?ID=20 + +export const ratfolk: RaceTrait = { + muscleMass: 9, + bmiModifier: 703, + ageTraits: { + 'ageDescriptors': [ + [65, 'ancient'], + [60, 'incredibly elderly'], + [58, 'vulnerably elderly'], + [55, 'withered'], + [53, 'elderly'], + [50, 'weathered'], + [48, 'aged'], + [45, 'old'], + [43, 'middle aged'], + [40, 'middle aged'], + [35, 'early middle aged'], + [20, 'adult'], + [18, 'prime adult aged'], + [16, 'young adult'], + [15, 'youthful adult'], + [14, 'relatively young'], + [13, 'surprisingly young'], + [12, 'barely adult aged'], + [11, 'youngster'], + [8, 'adolescent'], + [7, 'prepubescent'], + [3, 'child'], + [2, 'young child'], + [1, 'toddler'], + [0, 'newborn'] + ], + 'elderly': { + baseAge: 50, + ageModifier: () => dice(3, 4) + }, + 'settled adult': { + baseAge: 30, + ageModifier: () => dice(3, 10) + }, + 'young adult': { + baseAge: 20, + ageModifier: () => dice(4, 5) + }, + 'child': { + baseAge: 5, + ageModifier: () => dice(3, 4) + } + }, + genderTraits: { + entity: {}, + nonbinary: { + firstName: [ + 'Chagdin', + 'Creccot', + 'Dreg', + 'Drez', + 'Glannat', + 'Gnin', + 'Irkac', + 'Jercohk', + 'Knicdahk', + 'Kot', + 'Krat', + 'Mec', + 'Sarcon', + 'Scrak', + 'Skerdihl', + 'Skrec', + 'Trenihl', + 'Zar', + 'Zerrir', + 'Zris', + 'Zuppef', + 'Jir', + 'Pir', + 'Knegdaq', + 'Screnkis', + 'Neg', + 'Vizehm', + 'Noggix', + 'Dhehm', + 'Skes', + 'Kravom', + 'Ces', + 'Cras', + 'Sholir', + 'Frille', + 'Beset', + 'Gner', + 'Nhete', + 'Eggac', + 'Knimmam', + 'Pigdehz', + 'Teth', + 'Zer', + 'Kricdin', + 'Nini', + 'Sirith' + ], + beardProbability: 0, + baseHeight: 43, + baseWeight: 55, + heightModifier: () => dice(2, 4), + weightModifier: () => dice(2, 6) + }, + woman: { + firstName: [ + 'Apple', + 'Ben', + 'Bessel', + 'Cloudy', + 'Ember', + 'Fhar', + 'Fres', + 'Frost', + 'Ghegge', + 'Jasper', + 'Jix', + 'Kitch', + 'Kubi', + 'Mifihm', + 'Nana', + 'Nech', + 'Nehm', + 'Rissi', + 'Russet', + 'Sif', + 'Telli', + 'Thikka', + 'Urchin', + 'Veil', + 'Vhezzem', + 'Yarn', + 'Ziruhm', + 'Zitch', + 'Vharre', + 'Cahl', + 'Nhete', + 'Nhom', + 'Pir', + 'Muf', + 'Riks', + 'Sire', + 'Jippeks', + 'Dhikem', + 'Fherrech', + 'Nhuccith', + 'Bhech', + 'Fer', + 'Ricci', + 'Vher', + 'Fich', + 'Cekohm', + 'Berresh', + 'Miffes' + ], + beardProbability: 0, + baseHeight: 43, + baseWeight: 50, + heightModifier: () => dice(2, 4), + weightModifier: () => dice(2, 6) + }, + man: { + firstName: [ + 'Chigveg', + 'Djir', + 'Dolf', + 'Drer', + 'Grim', + 'Jan', + 'Knoz', + 'Lefty', + 'Moon', + 'Ninnec', + 'Ondam', + 'Pearl', + 'Rerdahl', + 'Rikkan', + 'Scengeq', + 'Sehl', + 'Shadow', + 'Skavvag', + 'Skivven', + 'Tamoq', + 'Timoc', + 'Twister', + 'Wax', + 'Staq', + 'Zroc', + 'Giggac', + 'Knimmam', + 'Scandos', + 'Kravom', + 'Skravkem', + 'Gnat', + 'Gner', + 'Brik', + 'Scros', + 'Vres', + 'Vrevan', + 'Ikzir', + 'Kricdin', + 'Crokkem', + 'Vris', + 'Stat', + 'Piz', + 'Promkehk', + 'Tremves', + 'Jiffi', + 'Mir', + 'Ikvek' + ], + beardProbability: 0, + baseHeight: 45, + baseWeight: 55, + heightModifier: () => dice(2, 4), + weightModifier: () => dice(3, 6) + } + }, + lastName: [ + 'Caskstride', + 'Deadstar', + 'Fogsky', + 'Fordreamer', + 'Havenbraid', + 'Mourntrack', + 'Oatsnarl', + 'Solidhorn', + 'Sternlance', + 'Warbreath', + 'Bestfood', + 'Manymother', + 'Manyeyes', + 'Foemuncher', + 'Manypocket', + 'Breadcrumb', + 'Burrowmore', + 'Highsqueek', + 'Treeclimber', + 'Chewy', + 'Furskin', + 'Blackmane', + 'Neverrun', + 'Sleepmuch', + 'Sclean', + 'Risky', + 'Dob', + 'Urchin', + 'Cheesar', + 'Wax', + 'Gigg', + 'Bet', + 'Bags', + 'Bagi', + 'Cefe', + 'Moldmuffin', + 'Bathed', + 'Readoo', + 'Longreach', + 'Shortsight', + 'Dewmind', + 'Brined', + 'Chipped', + 'Losttime', + 'Foundtime', + 'Emptytankard', + 'Lastname', + 'Sirnamed' + ], + eyes: ['green', 'blue', 'gray', 'aqua', 'purple', 'gold', 'yellow', 'amber', 'brown', 'dark brown', 'hazel', 'red', 'blood red', 'dark red', 'black'], + raceWords: { + raceName: 'ratfolk', + racePlural: 'ratfolk', + raceSingular: 'ratfolk', + raceAdjective: 'ratfolkin', + raceLanguage: 'Ysoki' + }, + knownLanguages: ['Common', 'Ratfolk'], + beard: ['scraggly beard', 'long, flowing beard', 'goatee', 'goatee that seems to be trying to level up into a beard', 'rather wild, unkempt beard', 'dreadful beard'], + abilities: { + 'Low-Light Vision': 'Accustomed to life underground, you have superior vision in dim conditions. You can see in dim light as though it were bright light, so you ignore the concealed condition due to dim light.' + } +} diff --git a/lib/src/createRing.ts b/lib/src/createRing.ts index 266925286..6999bd7de 100644 --- a/lib/src/createRing.ts +++ b/lib/src/createRing.ts @@ -144,7 +144,7 @@ export function createRing (base?: Partial): MagicRing { intendedowner: random([ 'no one in particular', `the ringmaker's ${random(['true love', 'best friend', 'favorite patron', 'ruler who he cared deeply for', 'family member', 'wife', 'husband', 'good friend'])}, but ${random(['they perished long ago', 'they are no longer on this plane', 'it was never delivered', 'the ringmaker perished before it was gifted away', 'they pawned it during times of trouble', "they pawned it after the ringmaker's death", 'it was stolen during the original delivery'])}`, - `${random(['a Dwarvish', 'an Elvish', 'a Gnomish', 'a Human', 'a Dragonborn', 'a Half-Orc', 'a Drow', 'a Tiefling', 'a Halfling', 'a Half-Elf', 'a Goblin', 'a Lizardfolk'])} ${random(['king', 'queen', 'princess', 'prince', 'prince', 'noble', 'duke', 'baron', 'lord', 'lady', 'merchant', 'witch of terrible power', 'gemcutter', 'hero from ancient times', 'knight'])} who ${random(['used it to gain power', 'used it to gain fame', 'used it to gain wealth', 'used it against their enemies', 'used it to better their town while they were alive', 'wore it until they died', 'wore it until it was lost during a long journey', 'wore it until it was stolen from them', 'never actually wore the ring', 'gifted it away after a few years'])}`, + `${random(['a Dwarvish', 'an Elvish', 'a Gnomish', 'a Human', 'a Dragonborn', 'a Half-Orc', 'a Drow', 'a Tiefling', 'a Halfling', 'a Half-Elf', 'a Goblin', 'a Lizardfolk', 'a Ratfolk', 'a Kitsune'])} ${random(['king', 'queen', 'princess', 'prince', 'prince', 'noble', 'duke', 'baron', 'lord', 'lady', 'merchant', 'witch of terrible power', 'gemcutter', 'hero from ancient times', 'knight'])} who ${random(['used it to gain power', 'used it to gain fame', 'used it to gain wealth', 'used it against their enemies', 'used it to better their town while they were alive', 'wore it until they died', 'wore it until it was lost during a long journey', 'wore it until it was stolen from them', 'never actually wore the ring', 'gifted it away after a few years'])}`, `${random(['a dark', 'a notorious', 'a legendary', 'a mysterious', 'an ancient', 'a sinister', 'a forgotten', 'a devious', 'an eccentric', 'a powerful', 'a wealthy', 'a conniving', 'an infamous', 'a renowned', 'a famous', 'a heralded', 'a strong-willed', 'a well known', 'a barely known', 'a weak-willed', 'an extremely wealthy'])} ${random(['sorceress', 'sorcerer', 'wizard', 'mage', 'witch', 'high priest', 'lich', 'rogue', 'fiend', 'warlord', 'explorer', 'bard', 'performer', 'druid', 'warlock', 'monk', 'warrior', 'knight', 'fighter', 'fortune teller', 'gladiator', 'king', 'queen', 'prince', 'princess', 'lord', 'lady', 'duke', 'monarch', 'prophet', 'spellcaster', 'hag'])} who ${random(['used it to gain power', 'used it to gain fame', 'used it to gain wealth', 'used it against their enemies', 'used it to better their town in their time', 'wore it until they died', 'wore it until it was lost during a long journey', 'wore it until it was stolen from them', 'never actually wore the ring', 'gifted it away after a few years'])}` ]), importance: random([ diff --git a/lib/town/townData.ts b/lib/town/townData.ts index 42f74e54b..58351fc74 100644 --- a/lib/town/townData.ts +++ b/lib/town/townData.ts @@ -286,7 +286,9 @@ export const townData: TownData = { 'halfling': randomFloat(5, 10), 'human': randomFloat(85, 95), 'lizardfolk': randomFloat(1, 2), - 'tiefling': randomFloat(1, 2) + 'tiefling': randomFloat(1, 2), + 'ratfolk': randomFloat(1, 2), + 'kitsune': randomFloat(1, 5) } }, { @@ -302,7 +304,9 @@ export const townData: TownData = { 'halfling': randomFloat(5, 10), 'human': randomFloat(5, 15), 'lizardfolk': randomFloat(1, 2), - 'tiefling': randomFloat(1, 2) + 'tiefling': randomFloat(1, 2), + 'ratfolk': randomFloat(1, 2), + 'kitsune': randomFloat(1, 5) } }, { @@ -318,7 +322,9 @@ export const townData: TownData = { 'halfling': randomFloat(5, 10), 'human': randomFloat(5, 15), 'lizardfolk': randomFloat(1, 2), - 'tiefling': randomFloat(3, 10) + 'tiefling': randomFloat(3, 10), + 'ratfolk': randomFloat(1, 5), + 'kitsune': randomFloat(1, 5) } }, { @@ -334,7 +340,9 @@ export const townData: TownData = { 'halfling': randomFloat(70, 90), 'human': randomFloat(5, 15), 'lizardfolk': randomFloat(1, 2), - 'tiefling': randomFloat(1, 2) + 'tiefling': randomFloat(1, 2), + 'ratfolk': randomFloat(1, 2), + 'kitsune': randomFloat(1, 5) } }, { @@ -350,7 +358,9 @@ export const townData: TownData = { 'halfling': randomFloat(5, 15), 'human': randomFloat(5, 15), 'lizardfolk': randomFloat(1, 2), - 'tiefling': randomFloat(1, 2) + 'tiefling': randomFloat(1, 2), + 'ratfolk': randomFloat(1, 2), + 'kitsune': randomFloat(70, 80) } }, { @@ -366,7 +376,9 @@ export const townData: TownData = { 'halfling': randomFloat(5, 10), 'human': randomFloat(5, 15), 'lizardfolk': randomFloat(1, 2), - 'tiefling': randomFloat(1, 2) + 'tiefling': randomFloat(1, 2), + 'ratfolk': randomFloat(1, 2), + 'kitsune': randomFloat(1, 5) } } ], @@ -421,7 +433,9 @@ export const townData: TownData = { 'halfling': randomFloat(5, 10), 'human': randomFloat(85, 95), 'lizardfolk': randomFloat(1, 2), - 'tiefling': randomFloat(1, 2) + 'tiefling': randomFloat(1, 2), + 'ratfolk': randomFloat(1, 2), + 'kitsune': randomFloat(1, 10) } }, { @@ -437,7 +451,9 @@ export const townData: TownData = { 'halfling': randomFloat(5, 7), 'human': randomFloat(8, 15), 'lizardfolk': randomFloat(1, 2), - 'tiefling': randomFloat(1, 5) + 'tiefling': randomFloat(1, 5), + 'ratfolk': randomFloat(1, 5), + 'kitsune': randomFloat(1, 3) } }, { @@ -453,7 +469,9 @@ export const townData: TownData = { 'halfling': randomFloat(5, 10), 'human': randomFloat(5, 20), 'lizardfolk': randomFloat(1, 2), - 'tiefling': randomFloat(3, 10) + 'tiefling': randomFloat(3, 10), + 'ratfolk': randomFloat(1, 5), + 'kitsune': randomFloat(1, 5) } }, { @@ -469,7 +487,9 @@ export const townData: TownData = { 'halfling': randomFloat(70, 90), 'human': randomFloat(5, 15), 'lizardfolk': randomFloat(1, 2), - 'tiefling': randomFloat(1, 4) + 'tiefling': randomFloat(1, 4), + 'ratfolk': randomFloat(1, 2), + 'kitsune': randomFloat(1, 5) } }, { @@ -485,7 +505,9 @@ export const townData: TownData = { 'halfling': randomFloat(5, 15), 'human': randomFloat(5, 15), 'lizardfolk': randomFloat(1, 2), - 'tiefling': randomFloat(1, 3) + 'tiefling': randomFloat(1, 3), + 'ratfolk': randomFloat(1, 4), + 'kitsune': randomFloat(70, 80) } }, { @@ -501,7 +523,9 @@ export const townData: TownData = { 'halfling': randomFloat(5, 10), 'human': randomFloat(10, 15), 'lizardfolk': randomFloat(1, 2), - 'tiefling': randomFloat(1, 3) + 'tiefling': randomFloat(1, 3), + 'ratfolk': randomFloat(1, 2), + 'kitsune': randomFloat(80, 90) } } ], @@ -555,7 +579,9 @@ export const townData: TownData = { 'halfling': randomFloat(5, 10), 'human': randomFloat(75, 95), 'lizardfolk': randomFloat(1, 2), - 'tiefling': randomFloat(1, 2) + 'tiefling': randomFloat(1, 2), + 'ratfolk': randomFloat(1, 2), + 'kitsune': randomFloat(1, 10) } }, { @@ -571,7 +597,9 @@ export const townData: TownData = { 'halfling': randomFloat(5, 7), 'human': randomFloat(8, 25), 'lizardfolk': randomFloat(1, 2), - 'tiefling': randomFloat(4, 10) + 'tiefling': randomFloat(4, 10), + 'ratfolk': randomFloat(1, 7), + 'kitsune': randomFloat(1, 3) } }, { @@ -587,7 +615,9 @@ export const townData: TownData = { 'halfling': randomFloat(5, 10), 'human': randomFloat(5, 20), 'lizardfolk': randomFloat(1, 2), - 'tiefling': randomFloat(3, 10) + 'tiefling': randomFloat(3, 10), + 'ratfolk': randomFloat(1, 5), + 'kitsune': randomFloat(1, 5) } }, { @@ -603,7 +633,9 @@ export const townData: TownData = { 'halfling': randomFloat(50, 80), 'human': randomFloat(25, 40), 'lizardfolk': randomFloat(1, 2), - 'tiefling': randomFloat(1, 7) + 'tiefling': randomFloat(1, 7), + 'ratfolk': randomFloat(1, 2), + 'kitsune': randomFloat(5, 20) } }, { @@ -619,7 +651,9 @@ export const townData: TownData = { 'halfling': randomFloat(5, 20), 'human': randomFloat(5, 15), 'lizardfolk': randomFloat(1, 2), - 'tiefling': randomFloat(1, 3) + 'tiefling': randomFloat(1, 3), + 'ratfolk': randomFloat(1, 4), + 'kitsune': randomFloat(70, 80) } }, { @@ -635,7 +669,9 @@ export const townData: TownData = { 'halfling': randomFloat(3, 7), 'human': randomFloat(10, 20), 'lizardfolk': randomFloat(1, 2), - 'tiefling': randomFloat(1, 3) + 'tiefling': randomFloat(1, 3), + 'ratfolk': randomFloat(1, 2), + 'kitsune': randomFloat(1, 7) } } ], @@ -690,7 +726,9 @@ export const townData: TownData = { 'halfling': randomFloat(5, 15), 'human': randomFloat(70, 95), 'lizardfolk': randomFloat(1, 2), - 'tiefling': randomFloat(1, 2) + 'tiefling': randomFloat(1, 2), + 'ratfolk': randomFloat(1, 4), + 'kitsune': randomFloat(1, 15) } }, { @@ -706,7 +744,9 @@ export const townData: TownData = { 'halfling': randomFloat(5, 7), 'human': randomFloat(8, 25), 'lizardfolk': randomFloat(1, 2), - 'tiefling': randomFloat(4, 10) + 'tiefling': randomFloat(4, 10), + 'ratfolk': randomFloat(1, 7), + 'kitsune': randomFloat(1, 3) } }, { @@ -722,7 +762,9 @@ export const townData: TownData = { 'halfling': randomFloat(5, 10), 'human': randomFloat(5, 20), 'lizardfolk': randomFloat(1, 2), - 'tiefling': randomFloat(3, 10) + 'tiefling': randomFloat(3, 10), + 'ratfolk': randomFloat(1, 5), + 'kitsune': randomFloat(1, 5) } }, { @@ -738,7 +780,9 @@ export const townData: TownData = { 'halfling': randomFloat(50, 60), 'human': randomFloat(25, 40), 'lizardfolk': randomFloat(1, 2), - 'tiefling': randomFloat(1, 10) + 'tiefling': randomFloat(1, 10), + 'ratfolk': randomFloat(1, 2), + 'kitsune': randomFloat(5, 30) } }, { @@ -754,7 +798,9 @@ export const townData: TownData = { 'halfling': randomFloat(5, 15), 'human': randomFloat(5, 25), 'lizardfolk': randomFloat(1, 2), - 'tiefling': randomFloat(1, 5) + 'tiefling': randomFloat(1, 5), + 'ratfolk': randomFloat(1, 5), + 'kitsune': randomFloat(70, 95) } }, { @@ -770,7 +816,9 @@ export const townData: TownData = { 'halfling': randomFloat(3, 7), 'human': randomFloat(10, 25), 'lizardfolk': randomFloat(1, 2), - 'tiefling': randomFloat(1, 3) + 'tiefling': randomFloat(1, 3), + 'ratfolk': randomFloat(1, 3), + 'kitsune': randomFloat(1, 4) } } ], diff --git a/src/NPCGeneration/npcData.js b/src/NPCGeneration/npcData.js index 456f6b0c3..993564062 100644 --- a/src/NPCGeneration/npcData.js +++ b/src/NPCGeneration/npcData.js @@ -1236,7 +1236,7 @@ setup.initNpcData = () => { value: ['experience', 'family', 'progeny', 'learning', 'wealth', 'masterwork', 'revenge', 'intelligence', 'discovery', 'pilgrimage', 'invention', 'miracle', 'secret', 'martyrdom', 'collection', 'patronage', 'fame'], drive: ['health', 'beauty', 'thrills', 'knowledge', 'power', 'partnership', 'networking', 'glory', 'entertainment', 'helpfulness', 'bravery', 'compassion', 'piety', 'solitude', 'relationships', 'hedonism', 'privacy'], belief: ['piety', 'pragmatism', 'cleverness', 'stoicism', 'reason', 'self-deserving', 'dogma', 'forgiveness', 'learning', 'tough love', 'honor', 'loyalty', 'optimism', 'respect', 'self-discipline', 'integrity'], - race: ['human', 'half-elf', 'elf', 'dwarf', 'gnome', 'halfling', 'half-orc', 'dragonborn', 'tiefling', 'lizardfolk'], + race: ['human', 'half-elf', 'elf', 'dwarf', 'gnome', 'halfling', 'half-orc', 'dragonborn', 'tiefling', 'lizardfolk', 'ratfolk', 'kitsune'], standardLanguages: ['Common', 'Dwarvish', 'Elvish', 'Gnomish', 'Giant', 'Goblin', 'Halfling', 'Orc'], exoticLanguages: ['Abyssal', 'Celestial', 'Draconic', 'Deep Speech', 'Infernal', 'Primordial', 'Sylvan', 'Undercommon'] } diff --git a/src/Tavern/js/tavernData.js b/src/Tavern/js/tavernData.js index 4d4a31864..f6cfe9ebd 100644 --- a/src/Tavern/js/tavernData.js +++ b/src/Tavern/js/tavernData.js @@ -160,7 +160,7 @@ setup.initTavernData = () => { `A palm reader has set up a booth in the corner of the tavern. He is currently reading the palm of ${['a grumpy looking dwarf', 'a frail old woman', 'an enormous man', 'a tough looking half-orc', 'a slender elf'].random()}.`, `${['An eldery dwarf', 'A snobby looking elf', 'A clever looking half-orc', 'An angular looking woman', 'A colorful gnome'].random()} is currently up on the ${tavern.stageDescriptor} stage reading their poetry to a drunken crowd.`, `There is ${lib.articles.output(tavern.stageDescriptor)}stage in this tavern, but it is currently empty.`, - `There is ${['a large human', 'an elf', 'a half-orc', 'a gnome', 'a dwarf', 'a dragonborn'].random()} in a puffy white hat up on ${lib.articles.output(tavern.stageDescriptor)} stage, giving some sort of cooking demonstration to the patrons.`, + `There is ${['a large human', 'an elf', 'a half-orc', 'a gnome', 'a dwarf', 'a dragonborn', 'a ratfolk', 'a kitsune'].random()} in a puffy white hat up on ${lib.articles.output(tavern.stageDescriptor)} stage, giving some sort of cooking demonstration to the patrons.`, `There is a play happening on the tavern's ${tavern.stageDescriptor} stage with ${['a single actor', 'a few actors', 'a fair few actors', 'a great many actors', 'a couple actors'].random()} in it. The play seems to be about ${['star crossed lovers', 'a great battle', 'the history of the region', 'the history of an old noble', 'a local folk tale', "a local children's story", 'the tragedy of man', 'the folly of the gods'].random()}.` ] return entertainment.random()