mirror of
https://github.com/stolksdorf/homebrewery.git
synced 2025-12-15 17:35:58 +00:00
Added a bunch of random generators
This commit is contained in:
@@ -6,6 +6,8 @@ var Statusbar = require('../statusbar/statusbar.jsx');
|
|||||||
var PHB = require('../phb/phb.jsx');
|
var PHB = require('../phb/phb.jsx');
|
||||||
var Editor = require('../editor/editor.jsx');
|
var Editor = require('../editor/editor.jsx');
|
||||||
|
|
||||||
|
var FullClassGen = require('../editor/snippets/fullclass.gen.js');
|
||||||
|
|
||||||
var request = require("superagent");
|
var request = require("superagent");
|
||||||
|
|
||||||
var EditPage = React.createClass({
|
var EditPage = React.createClass({
|
||||||
@@ -36,6 +38,12 @@ var EditPage = React.createClass({
|
|||||||
if(!self.state.pending) return;
|
if(!self.state.pending) return;
|
||||||
return "You have unsaved changes!";
|
return "You have unsaved changes!";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(this.state.text === ""){
|
||||||
|
this.setState({
|
||||||
|
text : FullClassGen()
|
||||||
|
})
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
handleTextChange : function(text){
|
handleTextChange : function(text){
|
||||||
|
|||||||
@@ -1,69 +1,8 @@
|
|||||||
var React = require('react');
|
var React = require('react');
|
||||||
var _ = require('lodash');
|
var _ = require('lodash');
|
||||||
var cx = require('classnames');
|
var cx = require('classnames');
|
||||||
|
var SnippetIcons = require('./snippets/snippets.js');
|
||||||
|
|
||||||
var Snippets = require('./snippets.js');
|
|
||||||
|
|
||||||
|
|
||||||
var Icons = [
|
|
||||||
{
|
|
||||||
icon : 'fa-book',
|
|
||||||
snippet : Snippets.intro,
|
|
||||||
tooltip : 'Intro'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
icon : 'fa-magic',
|
|
||||||
snippet : Snippets.spell,
|
|
||||||
tooltip : 'Spell'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
icon : 'fa-bookmark',
|
|
||||||
snippet : Snippets.classFeatures,
|
|
||||||
tooltip : 'Class Intro'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
icon : 'fa-trophy',
|
|
||||||
snippet : Snippets.destroyUndead,
|
|
||||||
tooltip : 'Class Feature'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
icon : 'fa-sticky-note',
|
|
||||||
snippet : Snippets.note,
|
|
||||||
tooltip : 'Note'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
icon : 'fa-bug',
|
|
||||||
snippet : Snippets.statBlock,
|
|
||||||
tooltip : 'Monster Stat Block'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
icon : 'fa-table',
|
|
||||||
snippet : Snippets.classTable,
|
|
||||||
tooltip : "Class Table"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
icon : 'fa-columns',
|
|
||||||
snippet : "```\n```\n\n",
|
|
||||||
tooltip : "Column Break"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
icon : 'fa-file-text',
|
|
||||||
snippet : "\\pagen\n\n",
|
|
||||||
tooltip : "New Page"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
icon : 'fa-arrows-v',
|
|
||||||
snippet : "<div style='margin-top:140px'></div>\n\n",
|
|
||||||
tooltip : "Vertical Spacing"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
icon : 'fa-image',
|
|
||||||
snippet : "<img />",
|
|
||||||
tooltip : "Insert Image"
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
var Editor = React.createClass({
|
var Editor = React.createClass({
|
||||||
getDefaultProps: function() {
|
getDefaultProps: function() {
|
||||||
@@ -81,15 +20,15 @@ var Editor = React.createClass({
|
|||||||
this.props.onChange(e.target.value);
|
this.props.onChange(e.target.value);
|
||||||
},
|
},
|
||||||
|
|
||||||
iconClick : function(snippet){
|
iconClick : function(snippetFn){
|
||||||
var curPos = this.refs.textarea.selectionStart;
|
var curPos = this.refs.textarea.selectionStart;
|
||||||
this.props.onChange(this.props.text.slice(0, curPos) +
|
this.props.onChange(this.props.text.slice(0, curPos) +
|
||||||
snippet +
|
snippetFn() +
|
||||||
this.props.text.slice(curPos + 1));
|
this.props.text.slice(curPos + 1));
|
||||||
},
|
},
|
||||||
|
|
||||||
renderTemplateIcons : function(){
|
renderTemplateIcons : function(){
|
||||||
return _.map(Icons, (t) => {
|
return _.map(SnippetIcons, (t) => {
|
||||||
return <div className='icon' key={t.icon}
|
return <div className='icon' key={t.icon}
|
||||||
onClick={this.iconClick.bind(this, t.snippet)}
|
onClick={this.iconClick.bind(this, t.snippet)}
|
||||||
data-tooltip={t.tooltip}>
|
data-tooltip={t.tooltip}>
|
||||||
@@ -104,7 +43,6 @@ var Editor = React.createClass({
|
|||||||
<div className='editor'>
|
<div className='editor'>
|
||||||
<div className='textIcons'>
|
<div className='textIcons'>
|
||||||
{this.renderTemplateIcons()}
|
{this.renderTemplateIcons()}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<textarea
|
<textarea
|
||||||
ref='textarea'
|
ref='textarea'
|
||||||
|
|||||||
42
client/homebrew/editor/snippets/classfeature.gen.js
Normal file
42
client/homebrew/editor/snippets/classfeature.gen.js
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
var _ = require('lodash');
|
||||||
|
|
||||||
|
module.exports = function(classname){
|
||||||
|
|
||||||
|
classname = classname || _.sample(['archivist', 'fancyman', 'linguist', 'fletcher',
|
||||||
|
'notary', 'berserker-typist', 'fishmongerer', 'manicurist', 'haberdasher', 'concierge'])
|
||||||
|
|
||||||
|
classname = classname.toLowerCase();
|
||||||
|
|
||||||
|
var hitDie = _.sample([4, 6, 8, 10, 12]);
|
||||||
|
|
||||||
|
var abilityList = ["Strength", "Dexerity", "Constitution", "Wisdom", "Charisma", "Intelligence"];
|
||||||
|
var skillList = ["Acrobatics ", "Animal Handling", "Arcana", "Athletics", "Deception", "History", "Insight", "Intimidation", "Investigation", "Medicine", "Nature", "Perception", "Performance", "Persuasion", "Religion", "Sleight of Hand", "Stealth", "Survival"];
|
||||||
|
|
||||||
|
|
||||||
|
return [
|
||||||
|
"## Class Features",
|
||||||
|
"As a " + classname + ", you gain the following class features",
|
||||||
|
"#### Hit Points",
|
||||||
|
"___",
|
||||||
|
"- **Hit Dice:** 1d" + hitDie + " per " + classname + " level",
|
||||||
|
"- **Hit Points at 1st Level:** " + hitDie + " + your Constituion modifier",
|
||||||
|
"- **Hit Points at Higher Levels:** 1d" + hitDie + " (or " + (hitDie/2 + 1) + ") + your Constituion modifier per " + classname + " level after 1st",
|
||||||
|
"",
|
||||||
|
"#### Proficiencies",
|
||||||
|
"___",
|
||||||
|
"- **Armor:** " + (_.sample(["Light armor", "Medium armor", "Heavy armor", "Shields"], _.random(0,3)).join(', ') || "None"),
|
||||||
|
"- **Weapons:** " + (_.sample(["Squeegee", "Rubber Chicken", "Simple weapons", "Martial weapons"], _.random(0,2)).join(', ') || "None"),
|
||||||
|
"- **Tools:** " + (_.sample(["Artian's tools", "one musical instrument", "Thieve's tools"], _.random(0,2)).join(', ') || "None"),
|
||||||
|
"",
|
||||||
|
"___",
|
||||||
|
"- **Saving Throws:** " + (_.sample(abilityList, 2).join(', ')),
|
||||||
|
"- **Skills:** Choose two from " + (_.sample(skillList, _.random(4, 6)).join(', ')),
|
||||||
|
"",
|
||||||
|
"#### Equipment",
|
||||||
|
"You start with the following equipment, in addition to the equipment granted by your background:",
|
||||||
|
"- *(a)* a martial weapon and a shield or *(b)* two martial weapons",
|
||||||
|
"- *(a)* five javelins or *(b)* any simple melee weapon",
|
||||||
|
"- " + (_.sample(["10 lint fluffs", "1 button", "a cherished lost sock"])),
|
||||||
|
"\n\n\n"
|
||||||
|
].join('\n');
|
||||||
|
}
|
||||||
78
client/homebrew/editor/snippets/classtable.gen.js
Normal file
78
client/homebrew/editor/snippets/classtable.gen.js
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
var _ = require('lodash');
|
||||||
|
|
||||||
|
module.exports = function(classname){
|
||||||
|
|
||||||
|
classname = classname || _.sample(['Archivist', 'Fancyman', 'Linguist', 'Fletcher',
|
||||||
|
'Notary', 'Berserker-Typist', 'Fishmongerer', 'Manicurist', 'Haberdasher', 'Concierge'])
|
||||||
|
|
||||||
|
var features = [
|
||||||
|
"Astrological Botany",
|
||||||
|
"Astrological Chemistry",
|
||||||
|
"Biochemical Sorcery",
|
||||||
|
"Civil Alchemy",
|
||||||
|
"Consecrated Biochemistry",
|
||||||
|
"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",
|
||||||
|
"Gunpowder Torturer",
|
||||||
|
"Orbital Gravedigger",
|
||||||
|
"Phased Linguist",
|
||||||
|
"Mathematical Pharmacist",
|
||||||
|
"Plasma Outlaw",
|
||||||
|
"Malefic Chemist",
|
||||||
|
"Police Cultist"
|
||||||
|
];
|
||||||
|
|
||||||
|
var maxes = [4,3,3,3,3,2,2,1,1]
|
||||||
|
var drawSlots = function(Slots){
|
||||||
|
var slots = Number(Slots);
|
||||||
|
return _.times(9, function(i){
|
||||||
|
var max = maxes[i];
|
||||||
|
if(slots < 1) return "—";
|
||||||
|
var res = _.min([max, slots]);
|
||||||
|
slots -= res;
|
||||||
|
return res;
|
||||||
|
}).join(' | ')
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
var cantrips = 3;
|
||||||
|
var spells = 1;
|
||||||
|
var slots = 2;
|
||||||
|
return "##### The " + classname + "\n" +
|
||||||
|
"___\n" +
|
||||||
|
"| Level | Proficiency Bonus | Features | Cantrips Known | Spells Known | 1st | 2nd | 3 rd | 4th | 5th | 6th | 7th | 8th | 9th |\n"+
|
||||||
|
"|:---:|:---:|:---|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|\n" +
|
||||||
|
_.map(["1st", "2nd", "3rd", "4th", "5th", "6th", "7th", "8th", "9th", "10th", "11th", "12th", "13th", "14th", "15th", "16th", "17th", "18th", "19th", "20th"],function(levelName, level){
|
||||||
|
var res = [
|
||||||
|
levelName,
|
||||||
|
"+" + Math.ceil(level/5 + 1),
|
||||||
|
_.sample(features, _.sample([0,1,1])).join(', ') || "Ability Score Improvement",
|
||||||
|
cantrips,
|
||||||
|
spells,
|
||||||
|
drawSlots(slots)
|
||||||
|
].join(' | ');
|
||||||
|
|
||||||
|
cantrips += _.random(0,1);
|
||||||
|
spells += _.random(0,1);
|
||||||
|
slots += _.random(0,2);
|
||||||
|
|
||||||
|
return "| " + res + " |";
|
||||||
|
}).join('\n') +'\n\n';
|
||||||
|
|
||||||
|
};
|
||||||
43
client/homebrew/editor/snippets/fullclass.gen.js
Normal file
43
client/homebrew/editor/snippets/fullclass.gen.js
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
var _ = require('lodash');
|
||||||
|
|
||||||
|
var ClassFeatureGen = require('./classfeature.gen.js');
|
||||||
|
|
||||||
|
var ClassTableGen = require('./classtable.gen.js');
|
||||||
|
|
||||||
|
module.exports = function(){
|
||||||
|
|
||||||
|
var classname = _.sample(['Archivist', 'Fancyman', 'Linguist', 'Fletcher',
|
||||||
|
'Notary', 'Berserker-Typist', 'Fishmongerer', 'Manicurist', 'Haberdasher', 'Concierge'])
|
||||||
|
|
||||||
|
|
||||||
|
var image = _.sample(_.map([
|
||||||
|
"http://orig01.deviantart.net/4682/f/2007/099/f/c/bard_stick_figure_by_wrpigeek.png",
|
||||||
|
"http://img07.deviantart.net/a3c9/i/2007/099/3/a/archer_stick_figure_by_wrpigeek.png",
|
||||||
|
"http://pre04.deviantart.net/d596/th/pre/f/2007/099/5/2/adventurer_stick_figure_by_wrpigeek.png",
|
||||||
|
"http://img13.deviantart.net/d501/i/2007/099/d/4/black_mage_stick_figure_by_wrpigeek.png",
|
||||||
|
"http://img09.deviantart.net/5cf3/i/2007/099/d/d/dark_knight_stick_figure_by_wrpigeek.png",
|
||||||
|
"http://pre01.deviantart.net/7a34/th/pre/f/2007/099/6/3/monk_stick_figure_by_wrpigeek.png",
|
||||||
|
"http://img11.deviantart.net/5dcc/i/2007/099/d/1/mystic_knight_stick_figure_by_wrpigeek.png",
|
||||||
|
"http://pre08.deviantart.net/ad45/th/pre/f/2007/099/a/0/thief_stick_figure_by_wrpigeek.png",
|
||||||
|
], function(url){
|
||||||
|
return "<img src = '" + url + "' style='max-width:8cm;max-height:25cm' />"
|
||||||
|
}))
|
||||||
|
|
||||||
|
|
||||||
|
return [
|
||||||
|
image,
|
||||||
|
"",
|
||||||
|
"```",
|
||||||
|
"```",
|
||||||
|
"<div style='margin-top:240px'></div>\n\n",
|
||||||
|
"## " + classname,
|
||||||
|
"Cool intro stuff will go here",
|
||||||
|
|
||||||
|
"\\page",
|
||||||
|
ClassTableGen(classname),
|
||||||
|
ClassFeatureGen(classname),
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
].join('\n') + '\n\n\n';
|
||||||
|
};
|
||||||
168
client/homebrew/editor/snippets/monsterblock.gen.js
Normal file
168
client/homebrew/editor/snippets/monsterblock.gen.js
Normal file
@@ -0,0 +1,168 @@
|
|||||||
|
var _ = require('lodash');
|
||||||
|
|
||||||
|
var genList = function(list, max){
|
||||||
|
return _.sample(list, _.random(0,max)).join(', ') || "None";
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = function(){
|
||||||
|
|
||||||
|
var monsterName = _.sample([
|
||||||
|
"All-devouring Baseball Imp",
|
||||||
|
"All-devouring Gumdrop Wraith",
|
||||||
|
"Chocolate Hydra",
|
||||||
|
"Devouring Peacock",
|
||||||
|
"Economy-sized Colossus of the Lemonade Stand",
|
||||||
|
"Ghost Pigeon",
|
||||||
|
"Gibbering Duck",
|
||||||
|
"Sparklemuffin Peacock Spider",
|
||||||
|
"Gum Elemental",
|
||||||
|
"Illiterate Construct of the Candy Store",
|
||||||
|
"Ineffable Chihuahua",
|
||||||
|
"Irritating Death Hamster",
|
||||||
|
"Irritating Gold Mouse",
|
||||||
|
"Juggernaut Snail",
|
||||||
|
"Juggernaut of the Sock Drawer",
|
||||||
|
"Koala of the Cosmos",
|
||||||
|
"Mad Koala of the West",
|
||||||
|
"Milk Djinni of the Lemonade Stand",
|
||||||
|
"Mind Ferret",
|
||||||
|
"Mystic Salt Spider",
|
||||||
|
"Necrotic Halitosis Angel",
|
||||||
|
"Pinstriped Famine Sheep",
|
||||||
|
"Ritalin Leech",
|
||||||
|
"Shocker Kangaroo",
|
||||||
|
"Stellar Tennis Juggernaut",
|
||||||
|
"Wailing Quail of the Sun",
|
||||||
|
"Angel Pigeon",
|
||||||
|
"Anime Sphinx",
|
||||||
|
"Bored Avalanche Sheep of the Wasteland",
|
||||||
|
"Devouring Nougat Sphinx of the Sock Drawer",
|
||||||
|
"Djinni of the Footlocker",
|
||||||
|
"Ectoplasmic Jazz Devil",
|
||||||
|
"Flatuent Angel",
|
||||||
|
"Gelatinous Duck of the Dream-Lands",
|
||||||
|
"Gelatinous Mouse",
|
||||||
|
"Golem of the Footlocker",
|
||||||
|
"Lich Wombat",
|
||||||
|
"Mechanical Sloth of the Past",
|
||||||
|
"Milkshake Succubus",
|
||||||
|
"Puffy Bone Peacock of the East",
|
||||||
|
"Rainbow Manatee",
|
||||||
|
"Rune Parrot",
|
||||||
|
"Sand Cow",
|
||||||
|
"Sinister Vanilla Dragon",
|
||||||
|
"Snail of the North",
|
||||||
|
"Spider of the Sewer",
|
||||||
|
"Stellar Sawdust Leech",
|
||||||
|
"Storm Anteater of Hell",
|
||||||
|
"Stupid Spirit of the Brewery",
|
||||||
|
"Time Kangaroo",
|
||||||
|
"Tomb Poodle",
|
||||||
|
]);
|
||||||
|
|
||||||
|
var type = _.sample(['Tiny', 'Small', 'Medium', 'Large', 'Gargantuan', 'Stupidly vast']) + " " + _.sample(['beast', 'fiend', 'annoyance', 'guy', 'cutie'])
|
||||||
|
|
||||||
|
var alignment =_.sample([
|
||||||
|
"annoying evil",
|
||||||
|
"chaotic gossipy",
|
||||||
|
"chaotic sloppy",
|
||||||
|
"depressed neutral",
|
||||||
|
"lawful bogus",
|
||||||
|
"lawful coy",
|
||||||
|
"manic-depressive evil",
|
||||||
|
"narrow-minded neutral",
|
||||||
|
"neutral annoying",
|
||||||
|
"neutral ignorant",
|
||||||
|
"oedpipal neutral",
|
||||||
|
"silly neutral",
|
||||||
|
"unoriginal neutral",
|
||||||
|
"weird neutral",
|
||||||
|
"wordy evil",
|
||||||
|
"unaligned"
|
||||||
|
]);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
var stats = '>|' + _.times(6, function(){
|
||||||
|
var num = _.random(1,20);
|
||||||
|
var mod = Math.ceil(num/2 - 5)
|
||||||
|
return num + " (" + (mod >= 0 ? '+'+mod : mod ) + ")"
|
||||||
|
}).join('|') + '|';
|
||||||
|
|
||||||
|
|
||||||
|
var genAbilities = function(){
|
||||||
|
return _.sample([
|
||||||
|
"> ***Pack Tactics.*** These guys work together. Like super well, you don't even know.",
|
||||||
|
"> ***False Appearance. *** While the armor reamin motionless, it is indistinguishable from a normal suit of armor.",
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
var genAction = function(){
|
||||||
|
var name = _.sample([
|
||||||
|
"Abdominal Drop",
|
||||||
|
"Airplane Hammer",
|
||||||
|
"Atomic Death Throw",
|
||||||
|
"Bulldog Rake",
|
||||||
|
"Corkscrew Strike",
|
||||||
|
"Crossed Splash",
|
||||||
|
"Crossface Suplex",
|
||||||
|
"DDT Powerbomb",
|
||||||
|
"Dual Cobra Wristlock",
|
||||||
|
"Dual Throw",
|
||||||
|
"Elbow Hold",
|
||||||
|
"Gory Body Sweep",
|
||||||
|
"Heel Jawbreaker",
|
||||||
|
"Jumping Driver",
|
||||||
|
"Open Chin Choke",
|
||||||
|
"Scorpion Flurry",
|
||||||
|
"Somersault Stump Fists",
|
||||||
|
"Suffering Wringer",
|
||||||
|
"Super Hip Submission",
|
||||||
|
"Super Spin",
|
||||||
|
"Team Elbow",
|
||||||
|
"Team Foot",
|
||||||
|
"Tilt-a-whirl Chin Sleeper",
|
||||||
|
"Tilt-a-whirl Eye Takedown",
|
||||||
|
"Turnbuckle Roll"
|
||||||
|
])
|
||||||
|
|
||||||
|
return "> ***" + name + ".*** *Melee Weapon Attack:* +4 to hit, reach 5ft., one target. *Hit* 5 (1d6 + 2) ";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return [
|
||||||
|
"___",
|
||||||
|
"> ## " + monsterName,
|
||||||
|
">*" + type + ", " + alignment+ "*",
|
||||||
|
"> ___",
|
||||||
|
"> - **Armor Class** " + _.random(10,20),
|
||||||
|
"> - **Hit Points** " + _.random(1, 150) + "(1d4 + 5)",
|
||||||
|
"> - **Speed** " + _.random(0,50) + "ft.",
|
||||||
|
">___",
|
||||||
|
">|STR|DEX|CON|INT|WIS|CHA|",
|
||||||
|
">|:---:|:---:|:---:|:---:|:---:|:---:|:---:|",
|
||||||
|
stats,
|
||||||
|
">___",
|
||||||
|
"> - **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(0,2), function(){
|
||||||
|
return genAbilities()
|
||||||
|
}).join('\n>\n'),
|
||||||
|
"> ### Actions",
|
||||||
|
_.times(_.random(1,2), function(){
|
||||||
|
return genAction()
|
||||||
|
}).join('\n>\n'),
|
||||||
|
].join('\n') + '\n\n\n';
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
*/
|
||||||
@@ -1,4 +1,125 @@
|
|||||||
module.exports = {
|
var SpellGen = require('./spell.gen.js');
|
||||||
|
var ClassTableGen = require('./classtable.gen.js');
|
||||||
|
var MonsterBlockGen = require('./monsterblock.gen.js');
|
||||||
|
var ClassFeatureGen = require('./classfeature.gen.js');
|
||||||
|
var FullClassGen = require('./fullclass.gen.js');
|
||||||
|
|
||||||
|
module.exports = [
|
||||||
|
{
|
||||||
|
tooltip : 'Full Class',
|
||||||
|
icon : 'fa-user',
|
||||||
|
snippet : FullClassGen,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
tooltip : 'Spell',
|
||||||
|
icon : 'fa-magic',
|
||||||
|
snippet : SpellGen,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
tooltip : 'Class Feature',
|
||||||
|
icon : 'fa-trophy',
|
||||||
|
snippet : ClassFeatureGen,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
tooltip : 'Note',
|
||||||
|
icon : 'fa-sticky-note',
|
||||||
|
snippet : function(){
|
||||||
|
return ""
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
tooltip : 'Table',
|
||||||
|
icon : 'fa-list',
|
||||||
|
snippet : function(){
|
||||||
|
return [
|
||||||
|
"##### Cookie Tastiness",
|
||||||
|
"| Tasty Level | Cookie Type |",
|
||||||
|
"|:----:|:-------------|",
|
||||||
|
"| -5 | Raisin |",
|
||||||
|
"| 8th | 1 or lower |",
|
||||||
|
"| 11th | 2 or lower |",
|
||||||
|
"| 14th | 3 or lower |",
|
||||||
|
"| 17th | 4 or lower |\n\n",
|
||||||
|
].join('\n');
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
tooltip : 'Monster Stat Block',
|
||||||
|
icon : 'fa-bug',
|
||||||
|
snippet : MonsterBlockGen,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
tooltip : "Class Table",
|
||||||
|
icon : 'fa-table',
|
||||||
|
snippet : ClassTableGen,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
tooltip : "Column Break",
|
||||||
|
icon : 'fa-columns',
|
||||||
|
snippet : function(){
|
||||||
|
return "```\n```\n\n";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
tooltip : "New Page",
|
||||||
|
icon : 'fa-file-text',
|
||||||
|
snippet : function(){
|
||||||
|
return "\\page\n\n";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
tooltip : "Vertical Spacing",
|
||||||
|
icon : 'fa-arrows-v',
|
||||||
|
snippet : function(){
|
||||||
|
return "<div style='margin-top:140px'></div>\n\n";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
tooltip : "Insert Image",
|
||||||
|
icon : 'fa-image',
|
||||||
|
snippet : function(){
|
||||||
|
return "<img />";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
var temp = {
|
||||||
|
|
||||||
intro : [
|
intro : [
|
||||||
'# Welcome to HomeBrew',
|
'# Welcome to HomeBrew',
|
||||||
@@ -13,33 +134,6 @@ module.exports = {
|
|||||||
].join('\n'),
|
].join('\n'),
|
||||||
|
|
||||||
|
|
||||||
classFeatures : [
|
|
||||||
"## Class Features",
|
|
||||||
"As a paladin, you gain the following class features.",
|
|
||||||
"",
|
|
||||||
"#### Hit Points",
|
|
||||||
"___",
|
|
||||||
"- **Hit Dice:** 1d10 per paladin level",
|
|
||||||
"- **Hit Points at 1st Level:** 10 + your Constitution modifier",
|
|
||||||
"- **Hit Points at Higher Levels:** 1d10 (or 6) + your Constituion modifier per paladin level after 1st",
|
|
||||||
"",
|
|
||||||
"#### Proficiencies",
|
|
||||||
"___",
|
|
||||||
"- **Armor:** All armor, Shields",
|
|
||||||
"- **Weapons:** Simple Weapons, martial weapons",
|
|
||||||
"- **Tools:** None <br>",
|
|
||||||
"___",
|
|
||||||
"- **Saving Throws:** Wisdom, Charisma",
|
|
||||||
"- **Skills:** Choose two from Athletics, Insight, Intimidation, Medicine, Persuasion, and Religion",
|
|
||||||
"",
|
|
||||||
"#### Equipment",
|
|
||||||
"You start with the following equipment, in addition to the equipment granted by your background:",
|
|
||||||
"",
|
|
||||||
"- *(a)* a martial weapon and a shield or *(b)* two martial weapons",
|
|
||||||
"- *(a)* five javelins or *(b)* any simple melee weapon",
|
|
||||||
"- Chain mail and a holy symbol",
|
|
||||||
].join('\n'),
|
|
||||||
|
|
||||||
spell : [
|
spell : [
|
||||||
"#### Continual Flame",
|
"#### Continual Flame",
|
||||||
"*2nd-level evocation*",
|
"*2nd-level evocation*",
|
||||||
78
client/homebrew/editor/snippets/spell.gen.js
Normal file
78
client/homebrew/editor/snippets/spell.gen.js
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
var _ = require('lodash');
|
||||||
|
|
||||||
|
module.exports = function(){
|
||||||
|
|
||||||
|
|
||||||
|
var spellNames = [
|
||||||
|
"Astral Rite of Acne",
|
||||||
|
"Create Acne",
|
||||||
|
"Cursed Ramen Erruption",
|
||||||
|
"Dark Chant of the Dentists",
|
||||||
|
"Erruption of Immaturity",
|
||||||
|
"Flaming Disc of Inconvenience",
|
||||||
|
"Heal Bad Hygene",
|
||||||
|
"Heavenly Transfiguration of the Cream Devil",
|
||||||
|
"Hellish Cage of Mucus",
|
||||||
|
"Irritate Peanut Butter Fairy",
|
||||||
|
"Luminous Erruption of Tea",
|
||||||
|
"Mystic Spell of the Poser",
|
||||||
|
"Sorcerous Enchantment of the Chimneysweep",
|
||||||
|
"Steak Sauce Ray",
|
||||||
|
"Talk to Groupie",
|
||||||
|
"Astonishing Chant of Chocolate",
|
||||||
|
"Astounding Pasta Puddle",
|
||||||
|
"Ball of Annoyance",
|
||||||
|
"Cage of Yarn",
|
||||||
|
"Control Noodles Elemental",
|
||||||
|
"Create Nervousness",
|
||||||
|
"Cure Baldness",
|
||||||
|
"Cursed Ritual of Bad Hair",
|
||||||
|
"Dispell Piles in Dentist",
|
||||||
|
"Eliminate Florists",
|
||||||
|
"Illusionary Transfiguration of the Babysitter",
|
||||||
|
"Necromantic Armor of Salad Dressing",
|
||||||
|
"Occult Transfiguration of Foot Fetish",
|
||||||
|
"Protection from Mucus Giant",
|
||||||
|
"Tinsel Blast",
|
||||||
|
"Alchemical Evocation of the Goths",
|
||||||
|
"Call Fangirl",
|
||||||
|
"Divine Spell of Crossdressing",
|
||||||
|
"Dominate Ramen Giant",
|
||||||
|
"Eliminate Vindictiveness in Gym Teacher",
|
||||||
|
"Extra-Planar Spell of Irritation",
|
||||||
|
"Induce Whining in Babysitter",
|
||||||
|
"Invoke Complaining",
|
||||||
|
"Magical Enchantment of Arrogance",
|
||||||
|
"Occult Globe of Salad Dressing",
|
||||||
|
"Overwhelming Enchantment of the Chocolate Fairy",
|
||||||
|
"Sorcerous Dandruff Globe",
|
||||||
|
"Spiritual Invocation of the Costumers",
|
||||||
|
"Ultimate Rite of the Confetti Angel",
|
||||||
|
"Ultimate Ritual of Mouthwash",
|
||||||
|
];
|
||||||
|
|
||||||
|
|
||||||
|
var level = ["1st", "2nd", "3rd", "4th", "5th", "6th", "7th", "8th", "9th"];
|
||||||
|
var spellSchools = ["abjuration", "conjuration", "divination", "enchantment", "evocation", "illusion", "necromancy", "transmutation"];
|
||||||
|
|
||||||
|
|
||||||
|
var components = _.sample(["V", "S", "M"], _.random(1,3)).join(', ');
|
||||||
|
if(components.indexOf("M") !== -1){
|
||||||
|
components += " (" + _.sample(['a small doll', 'a crushed button worth at least 1cp', 'discarded gum wrapper'], _.random(1,3)).join(', ') + ")"
|
||||||
|
}
|
||||||
|
|
||||||
|
return [
|
||||||
|
"#### " + _.sample(spellNames),
|
||||||
|
"*" + _.sample(level) + "-level " + _.sample(spellSchools) + "*",
|
||||||
|
"___",
|
||||||
|
"- **Casting Time:** 1 action",
|
||||||
|
"- **Range:** " + _.sample(["Self", "Touch", "30 feet", "60 feet"]),
|
||||||
|
"- **Components:** " + components,
|
||||||
|
"- **Duration:** " + _.sample(["Until dispelled", "1 round", "Instantaneous", "Concentration, up to 10 minutes", "1 hour"]),
|
||||||
|
"",
|
||||||
|
"A flame, equivalent in brightness to a torch, springs from from an object that you touch. ",
|
||||||
|
"The effect look like a regular flame, but it creates no heat and doesn't use oxygen. ",
|
||||||
|
"A *continual flame* can be covered or hidden but not smothered or quenched.",
|
||||||
|
"\n\n\n"
|
||||||
|
].join('\n');
|
||||||
|
}
|
||||||
@@ -12,7 +12,7 @@ var HomePage = React.createClass({
|
|||||||
|
|
||||||
getInitialState: function() {
|
getInitialState: function() {
|
||||||
return {
|
return {
|
||||||
text: "# Welcome \n Katie help me decide what should go here."
|
text: "# Welcome \n Oh god, what to put here. *Instructions* I guess?."
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -107,7 +107,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
p {
|
p {
|
||||||
padding-bottom : 1em;
|
padding-bottom : 0.8em;
|
||||||
font-family : BookInsanity;
|
font-family : BookInsanity;
|
||||||
font-size : 9pt;
|
font-size : 9pt;
|
||||||
line-height : 1.3em;
|
line-height : 1.3em;
|
||||||
@@ -117,7 +117,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
ul{
|
ul{
|
||||||
margin-bottom : 1em;
|
margin-bottom : 0.8em;
|
||||||
font-family : BookInsanity;
|
font-family : BookInsanity;
|
||||||
font-size : 9pt;
|
font-size : 9pt;
|
||||||
line-height : 1.3em;
|
line-height : 1.3em;
|
||||||
@@ -127,7 +127,7 @@
|
|||||||
|
|
||||||
|
|
||||||
//Full Spell casting table
|
//Full Spell casting table
|
||||||
hr+table{
|
h5+hr+table{
|
||||||
-webkit-column-span : all;
|
-webkit-column-span : all;
|
||||||
column-span : all;
|
column-span : all;
|
||||||
background-color: white;
|
background-color: white;
|
||||||
@@ -136,10 +136,15 @@
|
|||||||
border-image-width: 47px;
|
border-image-width: 47px;
|
||||||
border-image-outset: 37px 17px;
|
border-image-outset: 37px 17px;
|
||||||
border-image-repeat: round;
|
border-image-repeat: round;
|
||||||
margin: 40px 0px;
|
margin-bottom: 50px;
|
||||||
border-collapse: separate;
|
border-collapse: separate;
|
||||||
border: initial;
|
border: initial;
|
||||||
|
padding-top: 10px;
|
||||||
|
margin-top: -5px;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
table{
|
table{
|
||||||
width : 100%;
|
width : 100%;
|
||||||
margin-bottom : 1em;
|
margin-bottom : 1em;
|
||||||
@@ -150,10 +155,6 @@
|
|||||||
th{
|
th{
|
||||||
padding-bottom : 0.3em;
|
padding-bottom : 0.3em;
|
||||||
}
|
}
|
||||||
tr{
|
|
||||||
//background-color : white;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
tbody{
|
tbody{
|
||||||
tr{
|
tr{
|
||||||
@@ -219,6 +220,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Monster Ability table
|
||||||
hr+table{
|
hr+table{
|
||||||
-webkit-column-span : 1;
|
-webkit-column-span : 1;
|
||||||
column-span : 1;
|
column-span : 1;
|
||||||
|
|||||||
@@ -5,26 +5,32 @@ var Moment = require('moment');
|
|||||||
|
|
||||||
var Logo = require('naturalCrit/logo/logo.jsx');
|
var Logo = require('naturalCrit/logo/logo.jsx');
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var Statusbar = React.createClass({
|
var Statusbar = React.createClass({
|
||||||
|
|
||||||
getDefaultProps: function() {
|
getDefaultProps: function() {
|
||||||
return {
|
return {
|
||||||
editId: null,
|
//editId: null,
|
||||||
shareId : null,
|
shareId : null,
|
||||||
isPending : false,
|
isPending : false,
|
||||||
|
|
||||||
lastUpdated : null,
|
lastUpdated : null,
|
||||||
|
|
||||||
info : null
|
info : null
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
selectInputText : function(refName){
|
componentDidMount: function() {
|
||||||
this.refs[refName].select();
|
//Updates the last updated text every 10 seconds
|
||||||
|
if(this.props.lastUpdated){
|
||||||
|
this.refreshTimer = setInterval(()=>{
|
||||||
|
this.forceUpdate();
|
||||||
|
}, 10000)
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
componentWillUnmount: function() {
|
||||||
|
clearInterval(this.refreshTimer);
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
renderInfo : function(){
|
renderInfo : function(){
|
||||||
if(!this.props.lastUpdated) return null;
|
if(!this.props.lastUpdated) return null;
|
||||||
|
|
||||||
@@ -41,17 +47,6 @@ var Statusbar = React.createClass({
|
|||||||
</a>
|
</a>
|
||||||
},
|
},
|
||||||
|
|
||||||
renderEdit : function(){
|
|
||||||
return null;
|
|
||||||
|
|
||||||
if(!this.props.editId) return null;
|
|
||||||
|
|
||||||
return <div className='editField' key='edit' onClick={this.selectInputText.bind(this, 'edit')}>
|
|
||||||
<span>Edit Link</span>
|
|
||||||
<input type='text' readOnly value={'/homebrew/edit/' + this.props.editId} ref='edit' />
|
|
||||||
</div>
|
|
||||||
},
|
|
||||||
|
|
||||||
renderShare : function(){
|
renderShare : function(){
|
||||||
if(!this.props.shareId) return null;
|
if(!this.props.shareId) return null;
|
||||||
|
|
||||||
@@ -74,16 +69,12 @@ var Statusbar = React.createClass({
|
|||||||
|
|
||||||
render : function(){
|
render : function(){
|
||||||
return <div className='statusbar'>
|
return <div className='statusbar'>
|
||||||
|
|
||||||
<Logo />
|
<Logo />
|
||||||
|
|
||||||
<div className='left'>
|
<div className='left'>
|
||||||
<a href='/homebrew' className='toolName'>
|
<a href='/homebrew' className='toolName'>
|
||||||
The Home<i className='fa fa-beer fa-flip-horizontal' /><small>rewery</small>
|
The Home<i className='fa fa-beer fa-flip-horizontal' /><small>rewery</small>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className='controls right'>
|
<div className='controls right'>
|
||||||
{this.renderStatus()}
|
{this.renderStatus()}
|
||||||
{this.renderInfo()}
|
{this.renderInfo()}
|
||||||
|
|||||||
25
todo.txt
25
todo.txt
@@ -1,2 +1,23 @@
|
|||||||
- Merge homebrew back into natural crit (maybe?)
|
___
|
||||||
-
|
| Level | Proficiency Bonus | Sorcery Points | Features | Cantrips Known | Spells Known | 1st | 2nd | 3rd | 4th | 5th | 6th | 7th | 8th | 9th |
|
||||||
|
| :---: | :---------------: | :------------: | :------- |:---:|:---: |:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|
|
||||||
|
| 1st | +2 | <20> | Spellcasting, Sorcerous Origin | 4 | 2 | 2 | <20> | <20> | <20> | <20> | <20> | <20> | <20> | <20> |
|
||||||
|
| 2nd | +2 | 2 | Font of Magic | 4 | 3 | 3 | <20> | <20> | <20> | <20> | <20> | <20> | <20> | <20> |
|
||||||
|
| 3rd | +2 | 3 | Katie Magic| 4 | 4 | 4 | 2 | <20> | <20> | <20> | <20> | <20> | <20> | <20> |
|
||||||
|
| 4th | +2 | 4 | Metamagic | 5 | 5 | 4 | 2 | <20> | <20> | <20> | <20> | <20> | <20> | <20> |
|
||||||
|
| 5th | +3 | 5 | Metamagic | 5 | 6 | 4 | 2 | <20> | <20> | <20> | <20> | <20> | <20> | <20> |
|
||||||
|
| 6th | +3 | 6 | Metamagic | 5 | 7 | 4 | 2 | <20> | <20> | <20> | <20> | <20> | <20> | <20> |
|
||||||
|
| 7th | +3 | 7 | Metamagic | 5 | 8 | 4 | 2 | <20> | <20> | <20> | <20> | <20> | <20> | <20> |
|
||||||
|
| 8th | +3 | 8 | Metamagic | 6 | 9 | 4 | 2 | <20> | <20> | <20> | <20> | <20> | <20> | <20> |
|
||||||
|
| 9th | +4 | 9 | Metamagic | 6 | 10 | 4 | 2 | <20> | <20> | <20> | <20> | <20> | <20> | <20> |
|
||||||
|
| 10th| +4 | 10 | Metamagic | 6 | 11 | 4 | 2 | <20> | <20> | <20> | <20> | <20> | <20> | <20> |
|
||||||
|
| 11th| +4 | 11 | Metamagic | 6 | 12 | 4 | 2 | <20> | <20> | <20> | <20> | <20> | <20> | <20> |
|
||||||
|
| 12th| +4 | 12 | Metamagic | 6 | 12 | 4 | 2 | <20> | <20> | <20> | <20> | <20> | <20> | <20> |
|
||||||
|
| 13th| +5 | 13 | Metamagic | 6 | 13 | 4 | 2 | <20> | <20> | <20> | <20> | 1 | <20> | <20> |
|
||||||
|
| 14th| +5 | 14 | Metamagic | 6 | 13 | 4 | 2 | <20> | <20> | <20> | <20> | 1 | <20> | <20> |
|
||||||
|
| 15th| +5 | 15 | Metamagic | 6 | 14 | 4 | 2 | <20> | <20> | <20> | <20> | 1 | 1 | <20> |
|
||||||
|
| 16th| +5 | 16 | Metamagic | 6 | 14 | 4 | 2 | <20> | <20> | <20> | <20> | 1 | 1 | <20> |
|
||||||
|
| 17th| +6 | 17 | Metamagic | 6 | 15 | 4 | 2 | <20> | <20> | <20> | <20> | 1 | 1 | 1 |
|
||||||
|
| 18th| +6 | 18 | Metamagic | 6 | 15 | 4 | 2 | <20> | <20> | <20> | <20> | 1 | 1 | 1 |
|
||||||
|
| 19th| +6 | 19 | Metamagic | 6 | 15 | 4 | 2 | <20> | <20> | <20> | <20> | 1 | 1 | 1 |
|
||||||
|
| 20th| +6 | 20 | Metamagic | 6 | 15 | 4 | 2 | <20> | <20> | <20> | <20> | 2 | 1 | 1 |
|
||||||
Reference in New Issue
Block a user