diff --git a/client/homebrew/editor/snippetbar/snippets/classtable.gen.js b/client/homebrew/editor/snippetbar/snippets/classtable.gen.js index c8a2d051f..c1f6254f9 100644 --- a/client/homebrew/editor/snippetbar/snippets/classtable.gen.js +++ b/client/homebrew/editor/snippetbar/snippets/classtable.gen.js @@ -2,86 +2,77 @@ const _ = require('lodash'); const features = [ 'Astrological Botany', - 'Astrological Chemistry', 'Biochemical Sorcery', - 'Civil Alchemy', - 'Consecrated Biochemistry', + 'Civil Divination', + 'Consecrated Augury', 'Demonic Anthropology', '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', + 'Genetic Banishing', 'Gunpowder Torturer', - 'Orbital Gravedigger', - 'Phased Linguist', - 'Mathematical Pharmacist', - 'Plasma Outlaw', + 'Gunslinger Corruptor', + 'Hermetic Geography', + 'Immunological Cultist', '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', - 'Notary', 'Berserker-Typist', 'Fishmongerer', 'Manicurist', 'Haberdasher', 'Concierge']; +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 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 getFeature = (level)=>{ - let res = []; - if(_.includes([4, 6, 8, 12, 14, 16, 19], level+1)){ - res = ['Ability Score Improvement']; - } - res = _.union(res, _.sampleSize(features, _.sample([0, 1, 1, 1, 1, 1]))); - if(!res.length) return '─'; - return res.join(', '); +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 = { - full : function(){ + full : function(classes){ 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 spells = 1; let slots = 2; - return `{{classTable,wide\n##### The ${classname}\n` + - `| Level | Proficiency | Features | Cantrips | Spells | --- Spell Slots Per Level --- |||||||||\n`+ - `| ^| Bonus ^| ^| Known ^| Known ^| 1st | 2nd | 3rd | 4th | 5th | 6th | 7th | 8th | 9th |\n`+ - `|:-----:|:-----------:|:---------|:--------:|:------:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|\n${ + return `{{${classes}\n##### The ${classname}\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`+ + `|:-----:|:-----------:|:-------------|:--------:|:------:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|\n${ _.map(levels, function(levelName, level){ const res = [ - levelName, - `+${profBonus[level]}`, - getFeature(level), - cantrips, - spells, - drawSlots(slots) + _.pad(levelName, 5), + _.pad(`+${profBonus[level]}`, 2), + _.padEnd(_.sample(features), 21), + _.pad(cantrips.toString(), 8), + _.pad(spells.toString(), 6), + drawSlots(slots, 9, 2), ].join(' | '); cantrips += _.random(0, 1); @@ -92,24 +83,50 @@ module.exports = { }).join('\n')}\n}}\n\n`; }, - half : function(){ + half : function(classes){ const classname = _.sample(classnames); let featureScore = 1; - return `
\n##### The ${classname}\n` + - `| Level | Proficiency Bonus | Features | ${_.sample(features)}|\n` + - `|:---:|:---:|:---|:---:|\n${ + return `{{${classes}\n##### The ${classname}\n` + + `| Level | Proficiency Bonus | Features | ${_.pad(_.sample(features), 21)} |\n` + + `|:-----:|:-----------------:|:---------|:---------------------:|\n${ _.map(levels, function(levelName, level){ const res = [ - levelName, - `+${profBonus[level]}`, - getFeature(level), - `+${featureScore}` + _.pad(levelName, 5), + _.pad(`+${profBonus[level]}`, 2), + _.padEnd(_.sample(features), 23), + _.pad(`+${featureScore}`, 21), ].join(' | '); featureScore += _.random(0, 1); return `| ${res} |`; - }).join('\n')}\n
\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`; } }; diff --git a/client/homebrew/editor/snippetbar/snippets/snippets.js b/client/homebrew/editor/snippetbar/snippets/snippets.js index aab8112ec..4a0e300eb 100644 --- a/client/homebrew/editor/snippetbar/snippets/snippets.js +++ b/client/homebrew/editor/snippetbar/snippets/snippets.js @@ -237,12 +237,32 @@ module.exports = [ { name : 'Class 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', - 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', diff --git a/themes/5ePhb.style.less b/themes/5ePhb.style.less index d767b447c..8b4026867 100644 --- a/themes/5ePhb.style.less +++ b/themes/5ePhb.style.less @@ -560,17 +560,22 @@ body { // * CLASS TABLE // *****************************/ .page .classTable{ - margin-top : 25px; - margin-bottom : 40px; - border-collapse : separate; - background-color : white; - border : initial; - border-style : solid; - border-image-outset : 25px 17px; - border-image-repeat : stretch; - border-image-slice : 150 200 150 200; - border-image-source : @frameBorderImage; - border-image-width : 47px; + th[colspan]:not([rowspan]) { + white-space : nowrap; + } + &.frame { + margin-top : 25px; + margin-bottom : 40px; + border-collapse : separate; + background-color : white; + border : initial; + border-style : solid; + 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{ margin-bottom : 10px; }