0
0
mirror of https://github.com/naturalcrit/homebrewery.git synced 2026-01-07 16:22:42 +00:00

Merge pull request #1544 from Gazook89/ClassTable-Revisions

Class table revisions - 1/3 Table, minor fixes
This commit is contained in:
Trevor Buckner
2021-08-31 16:42:28 -04:00
committed by GitHub
3 changed files with 122 additions and 80 deletions

View File

@@ -2,86 +2,77 @@ const _ = require('lodash');
const features = [ const features = [
'Astrological Botany', 'Astrological Botany',
'Astrological Chemistry',
'Biochemical Sorcery', 'Biochemical Sorcery',
'Civil Alchemy', 'Civil Divination',
'Consecrated Biochemistry', 'Consecrated Augury',
'Demonic Anthropology', 'Demonic Anthropology',
'Divinatory Mineralogy', 'Divinatory Mineralogy',
'Genetic Banishing',
'Hermetic Geography',
'Immunological Incantations',
'Nuclear Illusionism',
'Ritual Astronomy',
'Seismological Divination',
'Spiritual Biochemistry',
'Statistical Occultism',
'Police Necromancer',
'Sixgun Poisoner',
'Pharmaceutical Gunslinger',
'Infernal Banker',
'Spell Analyst',
'Gunslinger Corruptor',
'Torque Interfacer',
'Exo Interfacer', 'Exo Interfacer',
'Genetic Banishing',
'Gunpowder Torturer', 'Gunpowder Torturer',
'Orbital Gravedigger', 'Gunslinger Corruptor',
'Phased Linguist', 'Hermetic Geography',
'Mathematical Pharmacist', 'Immunological Cultist',
'Plasma Outlaw',
'Malefic Chemist', 'Malefic Chemist',
'Police Cultist' 'Mathematical Pharmacy',
'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 = ['Archivist', 'Fancyman', 'Linguist', 'Fletcher', const classnames = ['Ackerman', 'Berserker-Typist', 'Concierge', 'Fishmonger',
'Notary', 'Berserker-Typist', 'Fishmongerer', 'Manicurist', 'Haberdasher', 'Concierge']; '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 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 profBonus = [2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6];
const getFeature = (level)=>{ const maxes = [4, 3, 3, 3, 3, 2, 2, 1, 1];
let res = [];
if(_.includes([4, 6, 8, 12, 14, 16, 19], level+1)){ const drawSlots = function(Slots, rows, padding){
res = ['Ability Score Improvement']; let slots = Number(Slots);
} return _.times(rows, function(i){
res = _.union(res, _.sampleSize(features, _.sample([0, 1, 1, 1, 1, 1]))); const max = maxes[i];
if(!res.length) return '─'; if(slots < 1) return _.pad('—', padding);
return res.join(', '); const res = _.min([max, slots]);
slots -= res;
return _.pad(res.toString(), padding);
}).join(' | ');
}; };
module.exports = { module.exports = {
full : function(){ full : function(classes){
const classname = _.sample(classnames); const classname = _.sample(classnames);
const maxes = [4, 3, 3, 3, 3, 2, 2, 1, 1];
const drawSlots = function(Slots){
let slots = Number(Slots);
return _.times(9, function(i){
const max = maxes[i];
if(slots < 1) return '—';
const res = _.min([max, slots]);
slots -= res;
return res;
}).join(' | ');
};
let cantrips = 3; let cantrips = 3;
let spells = 1; let spells = 1;
let slots = 2; let slots = 2;
return `{{classTable,wide\n##### The ${classname}\n` + return `{{${classes}\n##### The ${classname}\n` +
`| Level | Proficiency | Features | Cantrips | Spells | --- Spell Slots Per Level --- |||||||||\n`+ `| Level | Proficiency | Features | Cantrips | Spells | --- Spell Slots Per Spell Level ---|||||||||\n`+
`| ^| Bonus ^| ^| Known ^| Known ^| 1st | 2nd | 3rd | 4th | 5th | 6th | 7th | 8th | 9th |\n`+ `| ^| Bonus ^| ^| Known ^| Known ^|1st |2nd |3rd |4th |5th |6th |7th |8th |9th |\n`+
`|:-----:|:-----------:|:---------|:--------:|:------:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|\n${ `|:-----:|:-----------:|:-------------|:--------:|:------:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|\n${
_.map(levels, function(levelName, level){ _.map(levels, function(levelName, level){
const res = [ const res = [
levelName, _.pad(levelName, 5),
`+${profBonus[level]}`, _.pad(`+${profBonus[level]}`, 2),
getFeature(level), _.padEnd(_.sample(features), 21),
cantrips, _.pad(cantrips.toString(), 8),
spells, _.pad(spells.toString(), 6),
drawSlots(slots) drawSlots(slots, 9, 2),
].join(' | '); ].join(' | ');
cantrips += _.random(0, 1); cantrips += _.random(0, 1);
@@ -92,24 +83,50 @@ module.exports = {
}).join('\n')}\n}}\n\n`; }).join('\n')}\n}}\n\n`;
}, },
half : function(){ half : function(classes){
const classname = _.sample(classnames); const classname = _.sample(classnames);
let featureScore = 1; let featureScore = 1;
return `<div class='classTable'>\n##### The ${classname}\n` + return `{{${classes}\n##### The ${classname}\n` +
`| Level | Proficiency Bonus | Features | ${_.sample(features)}|\n` + `| Level | Proficiency Bonus | Features | ${_.pad(_.sample(features), 21)} |\n` +
`|:---:|:---:|:---|:---:|\n${ `|:-----:|:-----------------:|:---------|:---------------------:|\n${
_.map(levels, function(levelName, level){ _.map(levels, function(levelName, level){
const res = [ const res = [
levelName, _.pad(levelName, 5),
`+${profBonus[level]}`, _.pad(`+${profBonus[level]}`, 2),
getFeature(level), _.padEnd(_.sample(features), 23),
`+${featureScore}` _.pad(`+${featureScore}`, 21),
].join(' | '); ].join(' | ');
featureScore += _.random(0, 1); featureScore += _.random(0, 1);
return `| ${res} |`; return `| ${res} |`;
}).join('\n')}\n</div>\n\n`; }).join('\n')}\n}}\n\n`;
},
third : function(classes){
const classname = _.sample(classnames);
let cantrips = 3;
let spells = 1;
let slots = 2;
return `{{${classes}\n##### ${classname} Spellcasting\n` +
`| Class | Cantrips | Spells |--- Spells Slots per Spell Level ---||||\n` +
`| Level ^| Known ^| Known ^| 1st | 2nd | 3rd | 4th |\n` +
`|:------:|:--------:|:-------:|:-------:|:-------:|:-------:|:-------:|\n${
_.map(levels, function(levelName, level){
const res = [
_.pad(levelName, 6),
_.pad(cantrips.toString(), 8),
_.pad(spells.toString(), 7),
drawSlots(slots, 4, 7),
].join(' | ');
cantrips += _.random(0, 1);
spells += _.random(0, 1);
slots += _.random(0, 1);
return `| ${res} |`;
}).join('\n')}\n}}\n\n`;
} }
}; };

View File

@@ -237,12 +237,32 @@ module.exports = [
{ {
name : 'Class Table', name : 'Class Table',
icon : 'fas fa-table', icon : 'fas fa-table',
gen : ClassTableGen.full, gen : ClassTableGen.full('classTable,frame,wide'),
}, },
{ {
name : 'Half Class Table', name : 'Class Table (unframed)',
icon : 'fas fa-border-none',
gen : ClassTableGen.full('classTable,wide'),
},
{
name : '1/2 Class Table',
icon : 'fas fa-list-alt', icon : 'fas fa-list-alt',
gen : ClassTableGen.half, gen : ClassTableGen.half('classTable,frame'),
},
{
name : '1/2 Class Table (unframed)',
icon : 'fas fa-border-none',
gen : ClassTableGen.half('classTable'),
},
{
name : '1/3 Class Table',
icon : 'fas fa-border-all',
gen : ClassTableGen.third('classTable,frame'),
},
{
name : '1/3 Class Table (unframed)',
icon : 'fas fa-border-none',
gen : ClassTableGen.third('classTable'),
}, },
{ {
name : 'Table', name : 'Table',

View File

@@ -560,17 +560,22 @@ body {
// * CLASS TABLE // * CLASS TABLE
// *****************************/ // *****************************/
.page .classTable{ .page .classTable{
margin-top : 25px; th[colspan]:not([rowspan]) {
margin-bottom : 40px; white-space : nowrap;
border-collapse : separate; }
background-color : white; &.frame {
border : initial; margin-top : 25px;
border-style : solid; margin-bottom : 40px;
border-image-outset : 25px 17px; border-collapse : separate;
border-image-repeat : stretch; background-color : white;
border-image-slice : 150 200 150 200; border : initial;
border-image-source : @frameBorderImage; border-style : solid;
border-image-width : 47px; border-image-outset : 25px 17px;
border-image-repeat : stretch;
border-image-slice : 150 200 150 200;
border-image-source : @frameBorderImage;
border-image-width : 47px;
}
h5{ h5{
margin-bottom : 10px; margin-bottom : 10px;
} }