diff --git a/themes/V3/5eDMG/snippets/classfeature.gen.js b/themes/V3/5eDMG/snippets/classfeature.gen.js deleted file mode 100644 index 7e2e7e858..000000000 --- a/themes/V3/5eDMG/snippets/classfeature.gen.js +++ /dev/null @@ -1,42 +0,0 @@ -const _ = require('lodash'); -const dedent = require('dedent-tabs').default; - -module.exports = function(classname){ - - classname = _.sample(['archivist', 'fancyman', 'linguist', 'fletcher', - 'notary', 'berserker-typist', 'fishmongerer', 'manicurist', 'haberdasher', 'concierge']); - - classname = classname.toLowerCase(); - - const hitDie = _.sample([4, 6, 8, 10, 12]); - - const abilityList = ['Strength', 'Dexerity', 'Constitution', 'Wisdom', 'Charisma', 'Intelligence']; - const skillList = ['Acrobatics', 'Animal Handling', 'Arcana', 'Athletics', 'Deception', 'History', 'Insight', 'Intimidation', 'Investigation', 'Medicine', 'Nature', 'Perception', 'Performance', 'Persuasion', 'Religion', 'Sleight of Hand', 'Stealth', 'Survival']; - - - return dedent` - ## 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 Constitution modifier - **Hit Points at Higher Levels:** :: 1d${hitDie} (or ${hitDie/2 + 1}) + your Constitution modifier per ${classname} level after 1st - - #### Proficiencies - - **Armor:** :: ${_.sampleSize(['Light armor', 'Medium armor', 'Heavy armor', 'Shields'], _.random(0, 3)).join(', ') || 'None'} - **Weapons:** :: ${_.sampleSize(['Squeegee', 'Rubber Chicken', 'Simple weapons', 'Martial weapons'], _.random(0, 2)).join(', ') || 'None'} - **Tools:** :: ${_.sampleSize(['Artian\'s tools', 'one musical instrument', 'Thieve\'s tools'], _.random(0, 2)).join(', ') || 'None'} - - **Saving Throws:** :: ${_.sampleSize(abilityList, 2).join(', ')} - **Skills:** :: Choose two from ${_.sampleSize(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'])} - - `; -}; diff --git a/themes/V3/5eDMG/snippets/classtable.gen.js b/themes/V3/5eDMG/snippets/classtable.gen.js deleted file mode 100644 index c1f6254f9..000000000 --- a/themes/V3/5eDMG/snippets/classtable.gen.js +++ /dev/null @@ -1,132 +0,0 @@ -const _ = require('lodash'); - -const features = [ - 'Astrological Botany', - 'Biochemical Sorcery', - 'Civil Divination', - 'Consecrated Augury', - 'Demonic Anthropology', - 'Divinatory Mineralogy', - 'Exo Interfacer', - 'Genetic Banishing', - 'Gunpowder Torturer', - 'Gunslinger Corruptor', - 'Hermetic Geography', - 'Immunological Cultist', - 'Malefic Chemist', - '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 = ['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 = { - full : function(classes){ - const classname = _.sample(classnames); - - - let cantrips = 3; - let spells = 1; - let slots = 2; - 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 = [ - _.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); - spells += _.random(0, 1); - slots += _.random(0, 2); - - return `| ${res} |`; - }).join('\n')}\n}}\n\n`; - }, - - half : function(classes){ - const classname = _.sample(classnames); - - let featureScore = 1; - return `{{${classes}\n##### The ${classname}\n` + - `| Level | Proficiency Bonus | Features | ${_.pad(_.sample(features), 21)} |\n` + - `|:-----:|:-----------------:|:---------|:---------------------:|\n${ - _.map(levels, function(levelName, level){ - const res = [ - _.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`; - }, - - 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/themes/V3/5eDMG/snippets/coverpage.gen.js b/themes/V3/5eDMG/snippets/coverpage.gen.js deleted file mode 100644 index 0fb8ba7a4..000000000 --- a/themes/V3/5eDMG/snippets/coverpage.gen.js +++ /dev/null @@ -1,124 +0,0 @@ -const _ = require('lodash'); - -const titles = [ - 'The Burning Gallows', - 'The Ring of Nenlast', - 'Below the Blind Tavern', - 'Below the Hungering River', - 'Before Bahamut\'s Land', - 'The Cruel Grave from Within', - 'The Strength of Trade Road', - 'Through The Raven Queen\'s Worlds', - 'Within the Settlement', - 'The Crown from Within', - 'The Merchant Within the Battlefield', - 'Ioun\'s Fading Traveler', - 'The Legion Ingredient', - 'The Explorer Lure', - 'Before the Charming Badlands', - 'The Living Dead Above the Fearful Cage', - 'Vecna\'s Hidden Sage', - 'Bahamut\'s Demonspawn', - 'Across Gruumsh\'s Elemental Chaos', - 'The Blade of Orcus', - 'Beyond Revenge', - 'Brain of Insanity', - 'Breed Battle!, A New Beginning', - 'Evil Lake, A New Beginning', - 'Invasion of the Gigantic Cat, Part II', - 'Kraken War 2020', - 'The Body Whisperers', - 'The Diabolical Tales of the Ape-Women', - 'The Doctor Immortal', - 'The Doctor from Heaven', - 'The Graveyard', - 'Azure Core', - 'Core Battle', - 'Core of Heaven: The Guardian of Amazement', - 'Deadly Amazement III', - 'Dry Chaos IX', - 'Gate Thunder', - 'Guardian: Skies of the Dark Wizard', - 'Lute of Eternity', - 'Mercury\'s Planet: Brave Evolution', - 'Ruby of Atlantis: The Quake of Peace', - 'Sky of Zelda: The Thunder of Force', - 'Vyse\'s Skies', - 'White Greatness III', - 'Yellow Divinity', - 'Zidane\'s Ghost' -]; - -const subtitles = [ - 'In an ominous universe, a botanist opposes terrorism.', - 'In a demon-haunted city, in an age of lies and hate, a physicist tries to find an ancient treasure and battles a mob of aliens.', - 'In a land of corruption, two cyberneticists and a dungeon delver search for freedom.', - 'In an evil empire of horror, two rangers battle the forces of hell.', - 'In a lost city, in an age of sorcery, a librarian quests for revenge.', - 'In a universe of illusions and danger, three time travellers and an adventurer search for justice.', - 'In a forgotten universe of barbarism, in an era of terror and mysticism, a virtual reality programmer and a spy try to find vengance and battle crime.', - 'In a universe of demons, in an era of insanity and ghosts, three bodyguards and a bodyguard try to find vengance.', - 'In a kingdom of corruption and battle, seven artificial intelligences try to save the last living fertile woman.', - 'In a universe of virutal reality and agony, in an age of ghosts and ghosts, a fortune-teller and a wanderer try to avert the apocalypse.', - 'In a crime-infested kingdom, three martial artists quest for the truth and oppose evil.', - 'In a terrifying universe of lost souls, in an era of lost souls, eight dancers fight evil.', - 'In a galaxy of confusion and insanity, three martial artists and a duke battle a mob of psychics.', - 'In an amazing kingdom, a wizard and a secretary hope to prevent the destruction of mankind.', - 'In a kingdom of deception, a reporter searches for fame.', - 'In a hellish empire, a swordswoman and a duke try to find the ultimate weapon and battle a conspiracy.', - 'In an evil galaxy of illusion, in a time of technology and misery, seven psychiatrists battle crime.', - 'In a dark city of confusion, three swordswomen and a singer battle lawlessness.', - 'In an ominous empire, in an age of hate, two philosophers and a student try to find justice and battle a mob of mages intent on stealing the souls of the innocent.', - 'In a kingdom of panic, six adventurers oppose lawlessness.', - 'In a land of dreams and hopelessness, three hackers and a cyborg search for justice.', - 'On a planet of mysticism, three travelers and a fire fighter quest for the ultimate weapon and oppose evil.', - 'In a wicked universe, five seers fight lawlessness.', - 'In a kingdom of death, in an era of illusion and blood, four colonists search for fame.', - 'In an amazing kingdom, in an age of sorcery and lost souls, eight space pirates quest for freedom.', - 'In a cursed empire, five inventors oppose terrorism.', - 'On a crime-ridden planet of conspiracy, a watchman and an artificial intelligence try to find love and oppose lawlessness.', - 'In a forgotten land, a reporter and a spy try to stop the apocalypse.', - 'In a forbidden land of prophecy, a scientist and an archivist oppose a cabal of barbarians intent on stealing the souls of the innocent.', - 'On an infernal world of illusion, a grave robber and a watchman try to find revenge and combat a syndicate of mages intent on stealing the source of all magic.', - 'In a galaxy of dark magic, four fighters seek freedom.', - 'In an empire of deception, six tomb-robbers quest for the ultimate weapon and combat an army of raiders.', - 'In a kingdom of corruption and lost souls, in an age of panic, eight planetologists oppose evil.', - 'In a galaxy of misery and hopelessness, in a time of agony and pain, five planetologists search for vengance.', - 'In a universe of technology and insanity, in a time of sorcery, a computer techician quests for hope.', - 'On a planet of dark magic and barbarism, in an age of horror and blasphemy, seven librarians search for fame.', - 'In an empire of dark magic, in a time of blood and illusions, four monks try to find the ultimate weapon and combat terrorism.', - 'In a forgotten empire of dark magic, six kings try to prevent the destruction of mankind.', - 'In a galaxy of dark magic and horror, in an age of hopelessness, four marines and an outlaw combat evil.', - 'In a mysterious city of illusion, in an age of computerization, a witch-hunter tries to find the ultimate weapon and opposes an evil corporation.', - 'In a damned kingdom of technology, a virtual reality programmer and a fighter seek fame.', - 'In a hellish kingdom, in an age of blasphemy and blasphemy, an astrologer searches for fame.', - 'In a damned world of devils, an alien and a ranger quest for love and oppose a syndicate of demons.', - 'In a cursed galaxy, in a time of pain, seven librarians hope to avert the apocalypse.', - 'In a crime-infested galaxy, in an era of hopelessness and panic, three champions and a grave robber try to solve the ultimate crime.' -]; - - -module.exports = ()=>{ - return ` - -{{margin-top:225px}} - -# ${_.sample(titles)} - -{{margin-top:25px}} - -{{wide -##### ${_.sample(subtitles)} -}} - -\\page`; -}; \ No newline at end of file diff --git a/themes/V3/5eDMG/snippets/fullclass.gen.js b/themes/V3/5eDMG/snippets/fullclass.gen.js deleted file mode 100644 index 5ede9e501..000000000 --- a/themes/V3/5eDMG/snippets/fullclass.gen.js +++ /dev/null @@ -1,43 +0,0 @@ -const _ = require('lodash'); - -const ClassFeatureGen = require('./classfeature.gen.js'); - -const ClassTableGen = require('./classtable.gen.js'); - -module.exports = function(){ - - const classname = _.sample(['Archivist', 'Fancyman', 'Linguist', 'Fletcher', - 'Notary', 'Berserker-Typist', 'Fishmongerer', 'Manicurist', 'Haberdasher', 'Concierge']); - - - const 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 ``; - })); - - - return `${[ - image, - '', - '```', - '```', - '
\n\n', - `## ${classname}`, - 'Cool intro stuff will go here', - - '\\page', - ClassTableGen(classname), - ClassFeatureGen(classname), - - - - ].join('\n')}\n\n\n`; -}; \ No newline at end of file diff --git a/themes/V3/5eDMG/snippets/magic.gen.js b/themes/V3/5eDMG/snippets/magic.gen.js deleted file mode 100644 index 33ce8406d..000000000 --- a/themes/V3/5eDMG/snippets/magic.gen.js +++ /dev/null @@ -1,109 +0,0 @@ -const _ = require('lodash'); - -const 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', -]; -const itemNames = [ - 'Doorknob of Niceness', - 'Paper Armor of Folding', - 'Mixtape of Sadness', - 'Staff of Endless Confetti', -]; - -module.exports = { - - spellList : function(){ - const levels = ['Cantrips (0 Level)', '1st Level', '2nd Level', '3rd Level', '4th Level', '5th Level', '6th Level', '7th Level', '8th Level', '9th Level']; - - const content = _.map(levels, (level)=>{ - const spells = _.map(_.sampleSize(spellNames, _.random(4, 10)), (spell)=>{ - return `- ${spell}`; - }).join('\n'); - return `##### ${level} \n${spells} \n`; - }).join('\n'); - - return `{{spellList,wide\n${content}\n}}`; - }, - - spell : function(){ - const level = ['1st', '2nd', '3rd', '4th', '5th', '6th', '7th', '8th', '9th']; - const spellSchools = ['abjuration', 'conjuration', 'divination', 'enchantment', 'evocation', 'illusion', 'necromancy', 'transmutation']; - - - let components = _.sampleSize(['V', 'S', 'M'], _.random(1, 3)).join(', '); - if(components.indexOf('M') !== -1){ - components += ` (${_.sampleSize(['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 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'); - }, - - item : function() { - return [ - `#### ${_.sample(itemNames)}`, - `*${_.sample(['Wondrous item', 'Armor', 'Weapon'])}, ${_.sample(['Common', 'Uncommon', 'Rare', 'Very Rare', 'Legendary', 'Artifact'])} (requires attunement)*`, - `:`, - `This knob is pretty nice. When attached to a door, it allows a user to`, - `open that door with the strength of the nearest animal. For example, if`, - `there is a cow nearby, the user will have the "strength of a cow" while`, - `opening this door.` - ].join('\n'); - } -}; diff --git a/themes/V3/5eDMG/snippets/monsterblock.gen.js b/themes/V3/5eDMG/snippets/monsterblock.gen.js deleted file mode 100644 index dddf9b78c..000000000 --- a/themes/V3/5eDMG/snippets/monsterblock.gen.js +++ /dev/null @@ -1,184 +0,0 @@ -const _ = require('lodash'); -const dedent = require('dedent-tabs').default; - -const genList = function(list, max){ - return _.sampleSize(list, _.random(0, max)).join(', ') || 'None'; -}; - -const getMonsterName = function(){ - return _.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', - ]); -}; - -const getType = function(){ - return `${_.sample(['Tiny', 'Small', 'Medium', 'Large', 'Gargantuan', 'Stupidly vast'])} ${_.sample(['beast', 'fiend', 'annoyance', 'guy', 'cutie'])}`; -}; - -const getAlignment = function(){ - return _.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' - ]); -}; - -const getStats = function(){ - return `|${_.times(6, function(){ - const num = _.random(1, 20); - const mod = Math.ceil(num/2 - 5); - return `${num} (${mod >= 0 ? `+${mod}` : mod})`; - }).join('|')}|`; -}; - -const genAbilities = function(){ - return _.sample([ - '***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.', - '***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.', - '***Sassiness.*** When questioned, this creature will talk back instead of answering.', - '***Big Jerk.*** Whenever this creature makes an attack, it starts telling you how much cooler it is than you.', - ]); -}; - -const genLongAbilities = function(){ - return _.sample([ - dedent`***Pack Tactics.*** These guys work together like peanut butter and jelly. Jelly and peanut butter. - - When one of these guys attacks, the target is covered with, well, peanut butter and jelly.`, - dedent`***Hangriness.*** This creature is angry, and hungry. It will refuse to do anything with you until its hunger is satisfied. - - When in visual contact with this creature, you must purchase an extra order of fries, even if they say they aren't hungry.`, - dedent`***Full of Detergent.*** This creature has swallowed an entire bottle of dish detergent and is actually having a pretty good time. - - While walking near this creature, you must make a dexterity check or become "a soapy mess" for three hours, after which your skin will get all dry and itchy.` - ]); -}; - -const genAction = function(){ - const 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) `; -}; - - -module.exports = { - - monster : function(classes, genLines){ - return dedent` - {{${classes} - ## ${getMonsterName()} - *${getType()}, ${getAlignment()}* - ___ - **Armor Class** :: ${_.random(10, 20)} (chain mail, shield) - **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** :: darkvision 60 ft., passive Perception ${_.random(3, 20)} - **Languages** :: ${genList(['Common', 'Pottymouth', 'Gibberish', 'Latin', 'Jive'], 2)} - **Challenge** :: ${_.random(0, 15)} (${_.random(10, 10000)} XP) - ___ - ${_.times(_.random(genLines, genLines + 2), function(){return genAbilities();}).join('\n:\n')} - : - ${genLongAbilities()} - ### Actions - ${_.times(_.random(genLines, genLines + 2), function(){return genAction();}).join('\n:\n')} - }} - \n`; - } -}; diff --git a/themes/V3/5eDMG/snippets/tableOfContents.gen.js b/themes/V3/5eDMG/snippets/tableOfContents.gen.js deleted file mode 100644 index 1c52d5cf7..000000000 --- a/themes/V3/5eDMG/snippets/tableOfContents.gen.js +++ /dev/null @@ -1,84 +0,0 @@ -const _ = require('lodash'); -const dedent = require('dedent-tabs').default; - -const getTOC = (pages)=>{ - const add1 = (title, page)=>{ - res.push({ - title : title, - page : page + 1, - children : [] - }); - }; - const add2 = (title, page)=>{ - if(!_.last(res)) add1(null, page); - _.last(res).children.push({ - title : title, - page : page + 1, - children : [] - }); - }; - const add3 = (title, page)=>{ - if(!_.last(res)) add1(null, page); - if(!_.last(_.last(res).children)) add2(null, page); - _.last(_.last(res).children).children.push({ - title : title, - page : page + 1, - children : [] - }); - }; - - const res = []; - _.each(pages, (page, pageNum)=>{ - const lines = page.split('\n'); - _.each(lines, (line)=>{ - if(_.startsWith(line, '# ')){ - const title = line.replace('# ', ''); - add1(title, pageNum); - } - if(_.startsWith(line, '## ')){ - const title = line.replace('## ', ''); - add2(title, pageNum); - } - if(_.startsWith(line, '### ')){ - const title = line.replace('### ', ''); - add3(title, pageNum); - } - }); - }); - return res; -}; - -module.exports = function(brew){ - const pages = brew.text.split('\\page'); - const TOC = getTOC(pages); - const markdown = _.reduce(TOC, (r, g1, idx1)=>{ - if(g1.title !== null) { - r.push(`- ### [{{ ${g1.title}}}{{ ${g1.page}}}](#p${g1.page})`); - } - if(g1.children.length){ - _.each(g1.children, (g2, idx2)=>{ - if(g2.title !== null) { - r.push(` - #### [{{ ${g2.title}}}{{ ${g2.page}}}](#p${g2.page})`); - } - if(g2.children.length){ - _.each(g2.children, (g3, idx3)=>{ - if(g2.title !== null) { - r.push(` - [{{ ${g3.title}}}{{ ${g3.page}}}](#p${g3.page})`); - } else { // Don't over-indent if no level-2 parent entry - r.push(` - [{{ ${g3.title}}}{{ ${g3.page}}}](#p${g3.page})`); - } - }); - } - }); - } - return r; - }, []).join('\n'); - - return dedent` - {{toc,wide - # Table Of Contents - - ${markdown} - }} - \n`; -}; diff --git a/themes/V3/5eDMG/snippets/watercolor.gen.js b/themes/V3/5eDMG/snippets/watercolor.gen.js deleted file mode 100644 index 735a35602..000000000 --- a/themes/V3/5eDMG/snippets/watercolor.gen.js +++ /dev/null @@ -1,5 +0,0 @@ -const _ = require('lodash'); - -module.exports = ()=>{ - return `{{watercolor${_.random(1, 12)},top:20px,left:30px,width:300px,background-color:#BBAD82,opacity:80%}}\n\n`; -};