0
0
mirror of https://github.com/naturalcrit/homebrewery.git synced 2026-01-06 18:42:40 +00:00

Merge pull request #1307 from naturalcrit/V3MonsterBlockSnippets

V3 monster block snippets
This commit is contained in:
Trevor Buckner
2021-04-04 17:07:40 -04:00
committed by GitHub
16 changed files with 9364 additions and 169 deletions

View File

@@ -1,4 +1,5 @@
const _ = require('lodash'); const _ = require('lodash');
const dedent = require('dedent-tabs').default;
const genList = function(list, max){ const genList = function(list, max){
return _.sampleSize(list, _.random(0, max)).join(', ') || 'None'; return _.sampleSize(list, _.random(0, max)).join(', ') || 'None';
@@ -86,7 +87,7 @@ const getAlignment = function(){
}; };
const getStats = function(){ const getStats = function(){
return `>|${_.times(6, function(){ return `|${_.times(6, function(){
const num = _.random(1, 20); const num = _.random(1, 20);
const mod = Math.ceil(num/2 - 5); const mod = Math.ceil(num/2 - 5);
return `${num} (${mod >= 0 ? `+${mod}` : mod})`; return `${num} (${mod >= 0 ? `+${mod}` : mod})`;
@@ -95,12 +96,12 @@ const getStats = function(){
const genAbilities = function(){ const genAbilities = function(){
return _.sample([ return _.sample([
'> ***Pack Tactics.*** These guys work together. Like super well, you don\'t even know.', '***Pack Tactics.*** These guys work together like peanut butter and jelly.',
'> ***Fowl Appearance.*** While the creature remains motionless, it is indistinguishable from a normal chicken.', '***Fowl Appearance.*** While the creature remains motionless, it is indistinguishable from a normal chicken.',
'> ***Onion Stench.*** Any creatures within 5 feet of this thing develops an irrational craving for onion rings.', '***Onion Stench.*** Any creatures within 5 feet of this thing develops an irrational craving for onion rings.',
'> ***Enormous Nose.*** This creature gains advantage on any check involving putting things in its nose.', '***Enormous Nose.*** This creature gains advantage on any check involving putting things in its nose.',
'> ***Sassiness.*** When questioned, this creature will talk back instead of answering.', '***Sassiness.*** When questioned, this creature will talk back instead of answering.',
'> ***Big Jerk.*** Thinks he is just *waaaay* better than you.', '***Big Jerk.*** Whenever this creature makes an attack, it starts telling you how much cooler it is than you.',
]); ]);
}; };
@@ -133,68 +134,36 @@ const genAction = function(){
'Turnbuckle Roll' 'Turnbuckle Roll'
]); ]);
return `> ***${name}.*** *Melee Weapon Attack:* +4 to hit, reach 5ft., one target. *Hit* 5 (1d6 + 2) `; return `***${name}.*** *Melee Weapon Attack:* +4 to hit, reach 5ft., one target. *Hit* 5 (1d6 + 2) `;
}; };
module.exports = { module.exports = {
full : function(){ monster : function(classes, genLines){
return `${[ return dedent`
'___', {{${classes}
'___', ## ${getMonsterName()}
`> ## ${getMonsterName()}`, *${getType()}, ${getAlignment()}*
`>*${getType()}, ${getAlignment()}*`, ___
'> ___', : **Armor Class** : ${_.random(10, 20)} (chain mail, shield)
`> - **Armor Class** ${_.random(10, 20)}`, : **Hit Points** : ${_.random(1, 150)}(1d4 + 5)
`> - **Hit Points** ${_.random(1, 150)}(1d4 + 5)`, : **Speed** : ${_.random(0, 50)}ft.
`> - **Speed** ${_.random(0, 50)}ft.`, ___
'>___', | STR | DEX | CON | INT | WIS | CHA |
'>|STR|DEX|CON|INT|WIS|CHA|', |:-----:|:-----:|:-----:|:-----:|:-----:|:-----:|
'>|:---:|:---:|:---:|:---:|:---:|:---:|', ${getStats()}
getStats(), ___
'>___', : **Condition Immunities** : ${genList(['groggy', 'swagged', 'weak-kneed', 'buzzed', 'groovy', 'melancholy', 'drunk'], 3)}
`> - **Condition Immunities** ${genList(['groggy', 'swagged', 'weak-kneed', 'buzzed', 'groovy', 'melancholy', 'drunk'], 3)}`, : **Senses** : darkvision 60 ft., passive Perception ${_.random(3, 20)}
`> - **Senses** passive Perception ${_.random(3, 20)}`, : **Languages** : ${genList(['Common', 'Pottymouth', 'Gibberish', 'Latin', 'Jive'], 2)}
`> - **Languages** ${genList(['Common', 'Pottymouth', 'Gibberish', 'Latin', 'Jive'], 2)}`, : **Challenge** : ${_.random(0, 15)} (${_.random(10, 10000)} XP)
`> - **Challenge** ${_.random(0, 15)} (${_.random(10, 10000)} XP)`, ___
'> ___', :
_.times(_.random(3, 6), function(){ ${_.times(_.random(genLines, genLines + 2), function(){return genAbilities();}).join('\n\t\t\t\n\t\t\t')}
return genAbilities(); :
}).join('\n>\n'), ### Actions
'> ### Actions', ${_.times(_.random(genLines, genLines + 2), function(){return genAction();}).join('\n\t\t\t\n\t\t\t')}
_.times(_.random(4, 6), function(){ }}`;
return genAction();
}).join('\n>\n'),
].join('\n')}\n\n\n`;
},
half : function(){
return `${[
'___',
`> ## ${getMonsterName()}`,
`>*${getType()}, ${getAlignment()}*`,
'> ___',
`> - **Armor Class** ${_.random(10, 20)}`,
`> - **Hit Points** ${_.random(1, 150)}(1d4 + 5)`,
`> - **Speed** ${_.random(0, 50)}ft.`,
'>___',
'>|STR|DEX|CON|INT|WIS|CHA|',
'>|:---:|:---:|:---:|:---:|:---:|:---:|',
getStats(),
'>___',
`> - **Condition Immunities** ${genList(['groggy', 'swagged', 'weak-kneed', 'buzzed', 'groovy', 'melancholy', 'drunk'], 3)}`,
`> - **Senses** passive Perception ${_.random(3, 20)}`,
`> - **Languages** ${genList(['Common', 'Pottymouth', 'Gibberish', 'Latin', 'Jive'], 2)}`,
`> - **Challenge** ${_.random(0, 15)} (${_.random(10, 10000)} XP)`,
'> ___',
_.times(_.random(2, 3), function(){
return genAbilities();
}).join('\n>\n'),
'> ### Actions',
_.times(_.random(1, 2), function(){
return genAction();
}).join('\n>\n'),
].join('\n')}\n\n\n`;
} }
}; };

View File

@@ -151,15 +151,20 @@ module.exports = [
].join('\n'); ].join('\n');
}, },
}, },
{
name : 'Monster Stat Block (unframed)',
icon : 'fas fa-paw',
gen : MonsterBlockGen.monster('monster', 2),
},
{ {
name : 'Monster Stat Block', name : 'Monster Stat Block',
icon : 'fas fa-spider', icon : 'fas fa-spider',
gen : MonsterBlockGen.half, gen : MonsterBlockGen.monster('monster,frame', 2),
}, },
{ {
name : 'Wide Monster Stat Block', name : 'Wide Monster Stat Block',
icon : 'fas fa-dragon', icon : 'fas fa-dragon',
gen : MonsterBlockGen.full, gen : MonsterBlockGen.monster('monster,frame,wide', 4),
}, },
{ {
name : 'Cover Page', name : 'Cover Page',

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 930 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

File diff suppressed because one or more lines are too long

View File

@@ -7,7 +7,7 @@
@headerUnderline : #c9ad6a; @headerUnderline : #c9ad6a;
@horizontalRule : #9c2b1b; @horizontalRule : #9c2b1b;
@headerText : #58180D; @headerText : #58180D;
@monsterStatBackground : #FDF1DC; @monsterStatBackground : #EEDBAB;
@page { margin: 0; } @page { margin: 0; }
body { body {
counter-reset : phb-page-numbers; counter-reset : phb-page-numbers;
@@ -17,7 +17,11 @@ body {
} }
.useSansSerif(){ .useSansSerif(){
font-family : ScalySansRemake; font-family : ScalySansRemake;
font-size : 10pt; font-size : 0.325cm;
line-height : 1.2em;
p,dl,ul {
line-height : 1.2em;
}
em{ em{
font-style : italic; font-style : italic;
} }
@@ -29,14 +33,14 @@ body {
.useColumns(@multiplier : 1){ .useColumns(@multiplier : 1){
column-count : 2; column-count : 2;
column-fill : auto; column-fill : auto;
column-gap : 1cm; column-gap : 0.9cm;
column-width : 8cm * @multiplier; column-width : 8cm * @multiplier;
-webkit-column-count : 2; -webkit-column-count : 2;
-moz-column-count : 2; -moz-column-count : 2;
-webkit-column-width : 8cm * @multiplier; -webkit-column-width : 8cm * @multiplier;
-moz-column-width : 8cm * @multiplier; -moz-column-width : 8cm * @multiplier;
-webkit-column-gap : 1cm; -webkit-column-gap : 0.9cm;
-moz-column-gap : 1cm; -moz-column-gap : 0.9cm;
} }
.phb3{ .phb3{
.useColumns(); .useColumns();
@@ -47,11 +51,11 @@ body {
overflow : hidden; overflow : hidden;
height : 279.4mm; height : 279.4mm;
width : 215.9mm; width : 215.9mm;
padding : 1.0cm 1.7cm 1.5cm; padding : 1.4cm 1.9cm 1.7cm;
background-color : @background; background-color : @background;
background-image : @backgroundImage; background-image : @backgroundImage;
font-family : BookInsanityRemake; font-family : BookInsanityRemake;
font-size : 0.317cm; font-size : 0.34cm;
text-rendering : optimizeLegibility; text-rendering : optimizeLegibility;
page-break-before : always; page-break-before : always;
page-break-after : always; page-break-after : always;
@@ -60,10 +64,10 @@ body {
// *****************************/ // *****************************/
p{ p{
overflow-wrap : break-word; overflow-wrap : break-word;
padding-top : 0em; margin-bottom : 1em;
line-height : 1.3em; line-height : 1.3em;
&+p{ &+p{
padding-top : 0em; margin-top : -1em;
} }
} }
ul{ ul{
@@ -116,7 +120,7 @@ body {
} }
h1{ h1{
column-span : all; column-span : all;
font-size : 0.987cm; font-size : 0.89cm;
-webkit-column-span : all; -webkit-column-span : all;
-moz-column-span : all; -moz-column-span : all;
&+p::first-letter{ &+p::first-letter{
@@ -136,12 +140,11 @@ body {
color: rgba(0, 0, 0, 0); color: rgba(0, 0, 0, 0);
} }
&+p::first-line{ &+p::first-line{
font-size : .385cm;
font-variant : small-caps; font-variant : small-caps;
} }
} }
h2{ h2{
font-size : 0.705cm; font-size : 0.75cm;
} }
h3{ h3{
font-size : 0.529cm; font-size : 0.529cm;
@@ -164,7 +167,6 @@ body {
.useSansSerif(); .useSansSerif();
width : 100%; width : 100%;
margin-bottom : 1em; margin-bottom : 1em;
font-size : 10pt;
thead{ thead{
display: table-row-group; display: table-row-group;
font-weight : 800; font-weight : 800;
@@ -213,66 +215,97 @@ body {
//***************************** //*****************************
// * MONSTER STAT BLOCK // * MONSTER STAT BLOCK
// *****************************/ // *****************************/
hr+blockquote{
position : relative; .monster {
padding-top : 15px; &.frame {
background-color : @monsterStatBackground; border-style : solid;
border-style : solid; border-width : 7px 6px;
border-width : 10px; background-color : @monsterStatBackground;
border-image : @monsterBorderImage 10; background-image : @monsterBlockBackground;
border-image : @monsterBorderImage 14 round;
border-image-outset : 0px 2px;
background-blend-mode : overlay;
background-attachment : fixed;
box-shadow : 1px 4px 14px #888;
padding : 4px 2px;
margin : 0px -6px 1em;
}
.useSansSerif();
-webkit-transform : translateZ(0); //Prevents shadows from breaking across columns
position : relative;
padding : 0px;
margin-bottom : 1em;
p{
margin-bottom : 0;
}
p+p {
margin-top : 0.3cm;
text-indent : 0;
}
//Headers
h2{ h2{
margin-top : -8px; font-size : 0.62cm;
margin-bottom : 0px; line-height : 1em;
&+p{ margin : 0;
padding-bottom : 0px; &+p {
font-size : 0.304cm; //Monster size and type subtext
} }
} }
h3{ h3{
font-family : ScalySansRemake; font-family : ScalySansRemake;
font-weight : 400; font-weight : 800;
border-bottom : 1px solid @headerText; font-variant : small-caps;
} border-bottom : 2px solid @headerText;
hr+ul{ margin-top : 0.05cm;
color : @headerText; padding-bottom : 0.05cm;
}
ul{
.useSansSerif();
padding-left : 1em;
font-size : 0.352cm;
}
// Monster Ability table
hr+table{
margin : 0;
column-span : 1;
background-color : transparent;
border-style : none;
border-image : none;
-webkit-column-span : 1;
tbody{
tr:nth-child(odd), tr:nth-child(even){
background-color : transparent;
}
}
}
table{
color : @headerText;
}
p+p{
margin-top : 0em;
padding-bottom : 0.5em;
text-indent : 0em;
} }
//Triangle dividers //Triangle dividers
hr{ hr{
visibility : visible; visibility : visible;
height : 6px; height : 6px;
margin : 4px 0px; margin : 0.12cm 0cm;
background-image : @redTriangleImage; background-image : @redTriangleImage;
background-size : 100% 100%; background-size : 100% 100%;
border : none; border : none;
} }
//Attribute Lists
dl {
.useSansSerif();
color : @headerText;
padding-left :1.3em;
text-indent :-1.3em;
}
dd {
text-indent : 0px;
}
// Monster Ability table
hr + table:first-of-type{
margin : 0;
column-span : 1;
color : @headerText;
background-color : transparent;
border-style : none;
border-image : none;
-webkit-column-span : 1;
tr {
background-color : transparent;
}
td,th {
padding: 0px;
}
}
} }
//Full Width //Full Width
.monster.wide{
.useColumns(0.96);
}
hr+hr+blockquote{ hr+hr+blockquote{
.useColumns(0.96); .useColumns(0.96);
} }
@@ -485,6 +518,9 @@ body {
// * MUSTACHE DIVS/SPANS // * MUSTACHE DIVS/SPANS
// *****************************/ // *****************************/
.phb3 { .phb3 {
.block {
break-inside: avoid;
}
.inline-block { .inline-block {
display : block; display : block;
} }
@@ -512,6 +548,6 @@ body {
// *****************************/ // *****************************/
.phb3 { .phb3 {
.blank { .blank {
height: 0.8em; height: 0.75em;
} }
} }

9262
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -48,6 +48,7 @@
"codemirror": "^5.59.4", "codemirror": "^5.59.4",
"cookie-parser": "^1.4.5", "cookie-parser": "^1.4.5",
"create-react-class": "^15.7.0", "create-react-class": "^15.7.0",
"dedent-tabs": "^0.9.0",
"express": "^4.17.1", "express": "^4.17.1",
"express-async-handler": "^1.1.4", "express-async-handler": "^1.1.4",
"express-static-gzip": "2.1.1", "express-static-gzip": "2.1.1",