0
0
mirror of https://github.com/naturalcrit/homebrewery.git synced 2026-01-04 14:42:40 +00:00
Update class table generators
This commit is contained in:
Trevor Buckner
2023-08-04 01:41:02 -04:00
committed by GitHub
2 changed files with 170 additions and 147 deletions

View File

@@ -220,34 +220,51 @@ module.exports = [
view : 'text', view : 'text',
snippets : [ snippets : [
{ {
name : 'Class Table', name : 'Class Tables',
icon : 'fas fa-table', icon : 'fas fa-table',
gen : ClassTableGen.full('classTable,frame,decoration,wide'), gen : ClassTableGen.full('classTable,frame,decoration,wide'),
}, subsnippets : [
{ {
name : 'Class Table (unframed)', name : 'Martial Class Table',
icon : 'fas fa-border-none', icon : 'fas fa-table',
gen : ClassTableGen.full('classTable,wide'), gen : ClassTableGen.non('classTable,frame,decoration'),
}, },
{ {
name : '1/2 Class Table', name : 'Martial Class Table (unframed)',
icon : 'fas fa-list-alt', icon : 'fas fa-border-none',
gen : ClassTableGen.half('classTable,decoration,frame'), gen : ClassTableGen.non('classTable'),
}, },
{ {
name : '1/2 Class Table (unframed)', name : 'Full Caster Class Table',
icon : 'fas fa-border-none', icon : 'fas fa-table',
gen : ClassTableGen.half('classTable'), gen : ClassTableGen.full('classTable,frame,decoration,wide'),
}, },
{ {
name : '1/3 Class Table', name : 'Full Caster Class Table (unframed)',
icon : 'fas fa-border-all', icon : 'fas fa-border-none',
gen : ClassTableGen.third('classTable,frame'), gen : ClassTableGen.full('classTable,wide'),
}, },
{ {
name : '1/3 Class Table (unframed)', name : 'Half Caster Class Table',
icon : 'fas fa-border-none', icon : 'fas fa-list-alt',
gen : ClassTableGen.third('classTable'), gen : ClassTableGen.half('classTable,frame,decoration,wide'),
},
{
name : 'Half Caster Class Table (unframed)',
icon : 'fas fa-border-none',
gen : ClassTableGen.half('classTable,wide'),
},
{
name : 'Third Caster Spell Table',
icon : 'fas fa-border-all',
gen : ClassTableGen.third('classTable,frame,decoration'),
},
{
name : 'Third Caster Spell Table (unframed)',
icon : 'fas fa-border-none',
gen : ClassTableGen.third('classTable'),
}
]
}, },
{ {
name : 'Rune Table', name : 'Rune Table',

View File

@@ -1,132 +1,138 @@
const _ = require('lodash'); const _ = require('lodash');
const dedent = require('dedent-tabs').default;
const features = [ const features = [
'Astrological Botany', 'Astrological Botany', 'Biochemical Sorcery', 'Civil Divination',
'Biochemical Sorcery', 'Consecrated Augury', 'Demonic Anthropology', 'Divinatory Mineralogy',
'Civil Divination', 'Exo Interfacer', 'Genetic Banishing', 'Gunpowder Torturer',
'Consecrated Augury', 'Gunslinger Corruptor', 'Hermetic Geography', 'Immunological Cultist',
'Demonic Anthropology', 'Malefic Chemist', 'Mathematical Pharmacy', 'Nuclear Biochemistry',
'Divinatory Mineralogy', 'Orbital Gravedigger', 'Pharmaceutical Outlaw', 'Phased Linguist',
'Exo Interfacer', 'Plasma Gunslinger', 'Police Necromancer', 'Ritual Astronomy',
'Genetic Banishing', 'Sixgun Poisoner', 'Seismological Alchemy', 'Spiritual Illusionism',
'Gunpowder Torturer', 'Statistical Occultism', 'Spell Analyst', 'Torque Interfacer'
'Gunslinger Corruptor', ].map((f)=>_.padEnd(f, 21)); // Pad to equal length of 21 chars long
'Hermetic Geography',
'Immunological Cultist', const classnames = [
'Malefic Chemist', 'Ackerman', 'Berserker-Typist', 'Concierge', 'Fishmonger',
'Mathematical Pharmacy', 'Haberdasher', 'Manicurist', 'Netrunner', 'Weirkeeper'
'Nuclear Biochemistry',
'Orbital Gravedigger',
'Pharmaceutical Outlaw',
'Phased Linguist',
'Plasma Gunslinger',
'Police Necromancer',
'Ritual Astronomy',
'Sixgun Poisoner',
'Seismological Alchemy',
'Spiritual Illusionism',
'Statistical Occultism',
'Spell Analyst',
'Torque Interfacer'
]; ];
const classnames = ['Ackerman', 'Berserker-Typist', 'Concierge', 'Fishmonger',
'Haberdasher', 'Manicurist', 'Netrunner', 'Weirkeeper'];
const levels = ['1st', '2nd', '3rd', '4th', '5th',
'6th', '7th', '8th', '9th', '10th',
'11th', '12th', '13th', '14th', '15th',
'16th', '17th', '18th', '19th', '20th'];
const profBonus = [2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6];
const maxes = [4, 3, 3, 3, 3, 2, 2, 1, 1];
const drawSlots = function(Slots, rows, padding){
let slots = Number(Slots);
return _.times(rows, function(i){
const max = maxes[i];
if(slots < 1) return _.pad('—', padding);
const res = _.min([max, slots]);
slots -= res;
return _.pad(res.toString(), padding);
}).join(' | ');
};
module.exports = { module.exports = {
full : function(classes){ non : function(snippetClasses){
const classname = _.sample(classnames); return dedent`
{{${snippetClasses}
##### The ${_.sample(classnames)}
let cantrips = 3; | Level | Proficiency Bonus | Features | ${_.sample(features)} |
let spells = 1; |:-----:|:-----------------:|:---------|:---------------------:|
let slots = 2; | 1st | +2 | ${_.sample(features)} | 2 |
return `{{${classes}\n##### The ${classname}\n` + | 2nd | +2 | ${_.sample(features)} | 2 |
`| Level | Proficiency | Features | Cantrips | Spells | --- Spell Slots Per Spell Level ---|||||||||\n`+ | 3rd | +2 | ${_.sample(features)} | 3 |
`| ^| Bonus ^| ^| Known ^| Known ^|1st |2nd |3rd |4th |5th |6th |7th |8th |9th |\n`+ | 4th | +2 | ${_.sample(features)} | 3 |
`|:-----:|:-----------:|:-------------|:--------:|:------:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|\n${ | 5th | +3 | ${_.sample(features)} | 3 |
_.map(levels, function(levelName, level){ | 6th | +3 | ${_.sample(features)} | 4 |
const res = [ | 7th | +3 | ${_.sample(features)} | 4 |
_.pad(levelName, 5), | 8th | +3 | ${_.sample(features)} | 4 |
_.pad(`+${profBonus[level]}`, 2), | 9th | +4 | ${_.sample(features)} | 4 |
_.padEnd(_.sample(features), 21), | 10th | +4 | ${_.sample(features)} | 4 |
_.pad(cantrips.toString(), 8), | 11th | +4 | ${_.sample(features)} | 4 |
_.pad(spells.toString(), 6), | 12th | +4 | ${_.sample(features)} | 5 |
drawSlots(slots, 9, 2), | 13th | +5 | ${_.sample(features)} | 5 |
].join(' | '); | 14th | +5 | ${_.sample(features)} | 5 |
| 15th | +5 | ${_.sample(features)} | 5 |
cantrips += _.random(0, 1); | 16th | +5 | ${_.sample(features)} | 5 |
spells += _.random(0, 1); | 17th | +6 | ${_.sample(features)} | 6 |
slots += _.random(0, 2); | 18th | +6 | ${_.sample(features)} | 6 |
| 19th | +6 | ${_.sample(features)} | 6 |
return `| ${res} |`; | 20th | +6 | ${_.sample(features)} | unlimited |
}).join('\n')}\n}}\n\n`; }}\n\n`;
}, },
half : function(classes){ full : function(snippetClasses){
const classname = _.sample(classnames); return dedent`
{{${snippetClasses}
let featureScore = 1; ##### The ${_.sample(classnames)}
return `{{${classes}\n##### The ${classname}\n` + | Level | Proficiency | Features | Cantrips | --- Spell Slots Per Spell Level ---|||||||||
`| Level | Proficiency Bonus | Features | ${_.pad(_.sample(features), 21)} |\n` + | ^| Bonus ^| ^| Known ^|1st |2nd |3rd |4th |5th |6th |7th |8th |9th |
`|:-----:|:-----------------:|:---------|:---------------------:|\n${ |:-----:|:-----------:|:-------------|:--------:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|
_.map(levels, function(levelName, level){ | 1st | +2 | ${_.sample(features)} | 2 | 2 | — | — | — | — | — | — | — | — |
const res = [ | 2nd | +2 | ${_.sample(features)} | 2 | 3 | — | — | — | — | — | — | — | — |
_.pad(levelName, 5), | 3rd | +2 | ${_.sample(features)} | 2 | 4 | 2 | — | — | — | — | — | — | — |
_.pad(`+${profBonus[level]}`, 2), | 4th | +2 | ${_.sample(features)} | 3 | 4 | 3 | — | — | — | — | — | — | — |
_.padEnd(_.sample(features), 23), | 5th | +3 | ${_.sample(features)} | 3 | 4 | 3 | 2 | — | — | — | — | — | — |
_.pad(`+${featureScore}`, 21), | 6th | +3 | ${_.sample(features)} | 3 | 4 | 3 | 3 | — | — | — | — | — | — |
].join(' | '); | 7th | +3 | ${_.sample(features)} | 3 | 4 | 3 | 3 | 1 | — | — | — | — | — |
| 8th | +3 | ${_.sample(features)} | 3 | 4 | 3 | 3 | 2 | — | — | — | — | — |
featureScore += _.random(0, 1); | 9th | +4 | ${_.sample(features)} | 3 | 4 | 3 | 3 | 2 | 1 | — | — | — | — |
| 10th | +4 | ${_.sample(features)} | 3 | 4 | 3 | 3 | 2 | 1 | — | — | — | — |
return `| ${res} |`; | 11th | +4 | ${_.sample(features)} | 4 | 4 | 3 | 3 | 2 | 1 | 1 | — | — | — |
}).join('\n')}\n}}\n\n`; | 12th | +4 | ${_.sample(features)} | 4 | 4 | 3 | 3 | 2 | 1 | 1 | — | — | — |
| 13th | +5 | ${_.sample(features)} | 4 | 4 | 3 | 3 | 2 | 1 | 1 | 1 | — | — |
| 14th | +5 | ${_.sample(features)} | 4 | 4 | 3 | 3 | 2 | 1 | 1 | 1 | — | — |
| 15th | +5 | ${_.sample(features)} | 4 | 4 | 3 | 3 | 2 | 1 | 1 | 1 | 1 | — |
| 16th | +5 | ${_.sample(features)} | 4 | 4 | 3 | 3 | 2 | 1 | 1 | 1 | 1 | — |
| 17th | +6 | ${_.sample(features)} | 4 | 4 | 3 | 3 | 2 | 1 | 1 | 1 | 1 | 1 |
| 18th | +6 | ${_.sample(features)} | 4 | 4 | 3 | 3 | 3 | 1 | 1 | 1 | 1 | 1 |
| 19th | +6 | ${_.sample(features)} | 4 | 4 | 3 | 3 | 3 | 2 | 2 | 1 | 1 | 1 |
| 20th | +6 | ${_.sample(features)} | 4 | 4 | 3 | 3 | 3 | 2 | 2 | 2 | 1 | 1 |
}}\n\n`;
}, },
third : function(classes){ half : function(snippetClasses){
const classname = _.sample(classnames); return dedent`
{{${snippetClasses}
##### The ${_.sample(classnames)}
| Level | Proficiency | Features | Spells |--- Spell Slots Per Spell Level ---|||||
| ^| Bonus ^| ^| Known ^| 1st | 2nd | 3rd | 4th | 5th |
|:-----:|:-----------:|:-------------|:------:|:-----:|:-----:|:-----:|:-----:|:-----:|
| 1st | +2 | ${_.sample(features)} | — | — | — | — | — | — |
| 2nd | +2 | ${_.sample(features)} | 2 | 2 | — | — | — | — |
| 3rd | +2 | ${_.sample(features)} | 3 | 3 | — | — | — | — |
| 4th | +2 | ${_.sample(features)} | 3 | 3 | — | — | — | — |
| 5th | +3 | ${_.sample(features)} | 4 | 4 | 2 | — | — | — |
| 6th | +3 | ${_.sample(features)} | 4 | 4 | 2 | — | — | — |
| 7th | +3 | ${_.sample(features)} | 5 | 4 | 3 | — | — | — |
| 8th | +3 | ${_.sample(features)} | 5 | 4 | 3 | — | — | — |
| 9th | +4 | ${_.sample(features)} | 6 | 4 | 3 | 2 | — | — |
| 10th | +4 | ${_.sample(features)} | 6 | 4 | 3 | 2 | — | — |
| 11th | +4 | ${_.sample(features)} | 7 | 4 | 3 | 3 | — | — |
| 12th | +4 | ${_.sample(features)} | 7 | 4 | 3 | 3 | — | — |
| 13th | +5 | ${_.sample(features)} | 8 | 4 | 3 | 3 | 1 | — |
| 14th | +5 | ${_.sample(features)} | 8 | 4 | 3 | 3 | 1 | — |
| 15th | +5 | ${_.sample(features)} | 9 | 4 | 3 | 3 | 2 | — |
| 16th | +5 | ${_.sample(features)} | 9 | 4 | 3 | 3 | 2 | — |
| 17th | +6 | ${_.sample(features)} | 10 | 4 | 3 | 3 | 3 | 1 |
| 18th | +6 | ${_.sample(features)} | 10 | 4 | 3 | 3 | 3 | 1 |
| 19th | +6 | ${_.sample(features)} | 11 | 4 | 3 | 3 | 3 | 2 |
| 20th | +6 | ${_.sample(features)} | 11 | 4 | 3 | 3 | 3 | 2 |
}}\n\n`;
},
let cantrips = 3; third : function(snippetClasses){
let spells = 1; return dedent`
let slots = 2; {{${snippetClasses}
return `{{${classes}\n##### ${classname} Spellcasting\n` + ##### ${_.sample(classnames)} Spellcasting
`| Class | Cantrips | Spells |--- Spells Slots per Spell Level ---||||\n` + | Level | Cantrips | Spells |--- Spells Slots per Spell Level ---||||
`| Level ^| Known ^| Known ^| 1st | 2nd | 3rd | 4th |\n` + | ^| Known ^| Known ^| 1st | 2nd | 3rd | 4th |
`|:------:|:--------:|:-------:|:-------:|:-------:|:-------:|:-------:|\n${ |:-----:|:--------:|:------:|:-------:|:-------:|:-------:|:-------:|
_.map(levels, function(levelName, level){ | 3rd | 2 | 3 | 2 | — | — | — |
const res = [ | 4th | 2 | 4 | 3 | — | — | — |
_.pad(levelName, 6), | 5th | 2 | 4 | 3 | — | — | — |
_.pad(cantrips.toString(), 8), | 6th | 2 | 4 | 3 | — | — | — |
_.pad(spells.toString(), 7), | 7th | 2 | 5 | 4 | 2 | — | — |
drawSlots(slots, 4, 7), | 8th | 2 | 6 | 4 | 2 | — | — |
].join(' | '); | 9th | 2 | 6 | 4 | 2 | — | — |
| 10th | 3 | 7 | 4 | 3 | — | — |
cantrips += _.random(0, 1); | 11th | 3 | 8 | 4 | 3 | — | — |
spells += _.random(0, 1); | 12th | 3 | 8 | 4 | 3 | — | — |
slots += _.random(0, 1); | 13th | 3 | 9 | 4 | 3 | 2 | — |
| 14th | 3 | 10 | 4 | 3 | 2 | — |
return `| ${res} |`; | 15th | 3 | 10 | 4 | 3 | 2 | — |
}).join('\n')}\n}}\n\n`; | 16th | 3 | 11 | 4 | 3 | 3 | — |
| 17th | 3 | 11 | 4 | 3 | 3 | — |
| 18th | 3 | 11 | 4 | 3 | 3 | — |
| 19th | 3 | 12 | 4 | 3 | 3 | 1 |
| 20th | 3 | 13 | 4 | 3 | 3 | 1 |
}}\n\n`;
} }
}; };