This commit is contained in:
TheGiddyLimit
2024-06-23 22:13:57 +01:00
parent ed9833eefc
commit e5844f8a3f
279 changed files with 38254 additions and 7675 deletions

View File

@@ -0,0 +1,53 @@
class _HtmlGenerator {
static _getAttrClass (str, {classListAdditional = null} = {}) {
const pts = [
str,
classListAdditional?.length ? classListAdditional.join(" ") : "",
]
.filter(Boolean)
.join(" ");
if (!pts) return null;
return `class="${pts}"`;
}
}
export class HtmlGeneratorListButtons extends _HtmlGenerator {
static getBtnPreviewToggle () {
return `<button type="button" class="ve-col-0-3 btn btn-default btn-xs p-0 lst__btn-collapse-all-previews" name="list-toggle-all-previews">[+]</button>`;
}
static getBtnSource () {
return `<button type="button" class="sort btn btn-default btn-xs ve-grow" data-sort="source">Source</button>`;
}
/**
* @param {?string} width
* @param {?string} sortIdent
* @param {string} text
* @param {?string} title
* @param {?boolean} isDisabled
* @param {?Array<string>} classListAdditional
* @return {string}
*/
static getBtn (
{
width = null,
sortIdent = null,
text,
title = null,
isDisabled = false,
classListAdditional = null,
},
) {
const attrs = [
this._getAttrClass(`${width ? `ve-col-${width}` : `ve-grow`} sort btn btn-default btn-xs`, {classListAdditional}),
sortIdent ? `data-sort="${sortIdent}"` : null,
title ? `title="${title}"` : null,
isDisabled ? `disabled` : null,
]
.filter(Boolean)
.join(" ");
return `<button type="button" ${attrs}>${text}</button>`;
}
}

View File

@@ -0,0 +1,75 @@
import {PageGeneratorAdventureBookBase, PageGeneratorAdventuresBooksBase} from "./generate-pages-page-generator.js";
import {HtmlGeneratorListButtons} from "./generate-pages-html-generator.js";
class _PageGeneratorAdventure extends PageGeneratorAdventureBookBase {
_page = UrlUtil.PG_ADVENTURE;
_pageTitle = "Adventure";
_navbarTitle = "Adventure Details";
_navbarDescription = "Loading...";
_scriptIdentAdvBook = "adventure";
_advBookPlaceholder = `Did you ever hear the tragedy of Darth Plagueis The Wise? I thought not. It's not a story the Jedi would tell you. It's a Sith legend. Darth Plagueis was a Dark Lord of the Sith, so powerful and so wise he could use the Force to influence the midichlorians to create life… He had such a knowledge of the dark side that he could even keep the ones he cared about from dying. The dark side of the Force is a pathway to many abilities some consider to be unnatural. He became so powerful… the only thing he was afraid of was losing his power, which eventually, of course, he did. Unfortunately, he taught his apprentice everything he knew, then his apprentice killed him in his sleep. Ironic. He could save others from death, but not himself.`;
}
class _PageGeneratorBook extends PageGeneratorAdventureBookBase {
_page = UrlUtil.PG_BOOK;
_pageTitle = "Book";
_navbarTitle = "Book Details";
_navbarDescription = "Loading...";
_scriptIdentAdvBook = "book";
_advBookPlaceholder = `What the fuck did you just fucking say about me, you little bitch? I'll have you know I graduated top of my class in the Navy Seals, and I've been involved in numerous secret raids on Al-Quaeda, and I have over 300 confirmed kills. I am trained in gorilla warfare and I'm the top sniper in the entire US armed forces. You are nothing to me but just another target. I will wipe you the fuck out with precision the likes of which has never been seen before on this Earth, mark my fucking words. You think you can get away with saying that shit to me over the Internet? Think again, fucker. As we speak I am contacting my secret network of spies across the USA and your IP is being traced right now so you better prepare for the storm, maggot. The storm that wipes out the pathetic little thing you call your life. You're fucking dead, kid. I can be anywhere, anytime, and I can kill you in over seven hundred ways, and that's just with my bare hands. Not only am I extensively trained in unarmed combat, but I have access to the entire arsenal of the United States Marine Corps and I will use it to its full extent to wipe your miserable ass off the face of the continent, you little shit. If only you could have known what unholy retribution your little "clever" comment was about to bring down upon you, maybe you would have held your fucking tongue. But you couldn't, you didn't, and now you're paying the price, you goddamn idiot. I will shit fury all over you and you will drown in it. You're fucking dead, kiddo.`;
}
class _PageGeneratorQuickref extends PageGeneratorAdventureBookBase {
_page = UrlUtil.PG_QUICKREF;
_pageTitle = "Quick Reference";
_navbarTitle = "Quick Reference";
_navbarDescription = "Browse content. Press F to find, and G to go to page.";
_scriptIdentAdvBook = "quickreference";
_advBookPlaceholder = `Trans rights are human rights.`;
}
class _PageGeneratorAdventures extends PageGeneratorAdventuresBooksBase {
_page = UrlUtil.PG_ADVENTURES;
_pageTitle = "Adventures";
_navbarTitle = "Adventures";
_navbarDescription = "Browse adventures by name and contents";
_scriptIdentAdvsBooks = "adventures";
_searchName = "adventure";
_btnsList = [
HtmlGeneratorListButtons.getBtn({width: "1-3", sortIdent: "group", text: "Type"}),
HtmlGeneratorListButtons.getBtn({width: "5-5", sortIdent: "name", text: "Name"}),
HtmlGeneratorListButtons.getBtn({width: "2-5", sortIdent: "storyline", text: "Storyline"}),
HtmlGeneratorListButtons.getBtn({width: "1", sortIdent: "level", text: "Levels"}),
HtmlGeneratorListButtons.getBtn({width: "1-7", sortIdent: "published", text: "Published"}),
];
}
class _PageGeneratorBooks extends PageGeneratorAdventuresBooksBase {
_page = UrlUtil.PG_BOOKS;
_pageTitle = "Books";
_navbarTitle = "Books";
_navbarDescription = "Browse books by name and contents";
_scriptIdentAdvsBooks = "books";
_searchName = "book";
_btnsList = [
HtmlGeneratorListButtons.getBtn({width: "1-3", sortIdent: "group", text: "Type"}),
HtmlGeneratorListButtons.getBtn({width: "8-5", sortIdent: "name", text: "Name"}),
HtmlGeneratorListButtons.getBtn({sortIdent: "published", text: "Published"}),
];
}
export const PAGE_GENERATORS_ADVENTURE_BOOK = [
new _PageGeneratorAdventure(),
new _PageGeneratorBook(),
new _PageGeneratorQuickref(),
new _PageGeneratorAdventures(),
new _PageGeneratorBooks(),
];

View File

@@ -0,0 +1,649 @@
import {PageGeneratorListBase} from "./generate-pages-page-generator.js";
import {HtmlGeneratorListButtons} from "./generate-pages-html-generator.js";
class _PageGeneratorListActions extends PageGeneratorListBase {
_page = UrlUtil.PG_ACTIONS;
_pageTitle = "Actions";
_scriptIdentList = "actions";
_btnsList = [
HtmlGeneratorListButtons.getBtnPreviewToggle(),
HtmlGeneratorListButtons.getBtn({width: "5-7", sortIdent: "name", text: "Name"}),
HtmlGeneratorListButtons.getBtn({width: "4", sortIdent: "time", text: "Time"}),
HtmlGeneratorListButtons.getBtnSource(),
];
_btnsSublist = [
HtmlGeneratorListButtons.getBtn({width: "8", sortIdent: "name", text: "Name"}),
HtmlGeneratorListButtons.getBtn({width: "4", sortIdent: "time", text: "Time"}),
];
}
class _PageGeneratorListBackgrounds extends PageGeneratorListBase {
_page = UrlUtil.PG_BACKGROUNDS;
_pageTitle = "Backgrounds";
_scriptIdentList = "backgrounds";
_btnsList = [
HtmlGeneratorListButtons.getBtn({width: "4", sortIdent: "name", text: "Name"}),
HtmlGeneratorListButtons.getBtn({width: "6", sortIdent: "skills", text: "Skill Proficiencies"}),
HtmlGeneratorListButtons.getBtnSource(),
];
_btnsSublist = [
HtmlGeneratorListButtons.getBtn({width: "4", sortIdent: "name", text: "Name"}),
HtmlGeneratorListButtons.getBtn({width: "8", sortIdent: "skills", text: "Skills"}),
];
_isPrinterView = true;
}
class _PageGeneratorListBestiary extends PageGeneratorListBase {
_page = UrlUtil.PG_BESTIARY;
_pageTitle = "Bestiary";
_stylesheets = [
"bestiary",
"encounterbuilder-bundle",
];
_scriptIdentList = "bestiary";
_scriptsUtilsAdditional = [
"utils-tableview.js",
];
_isModule = true;
_isMultisource = true;
_btnsList = [
HtmlGeneratorListButtons.getBtn({width: "4-2", sortIdent: "name", text: "Name"}),
HtmlGeneratorListButtons.getBtn({width: "4-1", sortIdent: "type", text: "Type"}),
HtmlGeneratorListButtons.getBtn({width: "1-7", sortIdent: "cr", text: "CR"}),
HtmlGeneratorListButtons.getBtnSource(),
];
_btnsSublist = [
HtmlGeneratorListButtons.getBtn({width: "5", sortIdent: "name", text: "Name"}),
HtmlGeneratorListButtons.getBtn({width: "3-8", classListAdditional: ["best-ecgen__hidden"], sortIdent: "type", text: "Type"}),
HtmlGeneratorListButtons.getBtn({width: "3-8", classListAdditional: ["best-ecgen__visible"], isDisabled: true, text: "&nbsp;"}),
HtmlGeneratorListButtons.getBtn({width: "1-2", sortIdent: "cr", text: "CR"}),
HtmlGeneratorListButtons.getBtn({width: "2", sortIdent: "count", text: "Number"}),
];
_registerPartials () {
super._registerPartials();
this._registerPartial({
ident: "listContentwrapperBestiary",
filename: "list/template-list-contentwrapper--bestiary.hbs",
});
this._registerPartial({
ident: "listSublistContainerBestiary",
filename: "list/template-list-sublist-container--bestiary.hbs",
});
}
_getData () {
return {
...super._getData(),
identPartialListContentwrapper: "listContentwrapperBestiary",
};
}
_isPrinterView = true;
}
class _PageGeneratorListCharCreationOptions extends PageGeneratorListBase {
_page = UrlUtil.PG_CHAR_CREATION_OPTIONS;
_pageTitle = "Other Character Creation Options";
_scriptIdentList = "charcreationoptions";
_btnsList = [
HtmlGeneratorListButtons.getBtn({width: "5", sortIdent: "type", text: "Type"}),
HtmlGeneratorListButtons.getBtn({width: "5", sortIdent: "name", text: "Name"}),
HtmlGeneratorListButtons.getBtnSource(),
];
_btnsSublist = [
HtmlGeneratorListButtons.getBtn({width: "5", sortIdent: "type", text: "Type"}),
HtmlGeneratorListButtons.getBtn({width: "7", sortIdent: "name", text: "Name"}),
];
}
class _PageGeneratorListConditionsDiseases extends PageGeneratorListBase {
_page = UrlUtil.PG_CONDITIONS_DISEASES;
_pageTitle = "Conditions & Diseases";
_scriptIdentList = "conditionsdiseases";
_btnsList = [
HtmlGeneratorListButtons.getBtnPreviewToggle(),
HtmlGeneratorListButtons.getBtn({width: "3", sortIdent: "type", text: "Type"}),
HtmlGeneratorListButtons.getBtn({width: "6-7", sortIdent: "name", text: "Name"}),
HtmlGeneratorListButtons.getBtnSource(),
];
_btnsSublist = [
HtmlGeneratorListButtons.getBtn({width: "2", sortIdent: "type", text: "Type"}),
HtmlGeneratorListButtons.getBtn({width: "10", sortIdent: "name", text: "Name"}),
];
}
class _PageGeneratorListCultsBoons extends PageGeneratorListBase {
_page = UrlUtil.PG_CULTS_BOONS;
_pageTitle = "Cults & Supernatural Boons";
_scriptIdentList = "cultsboons";
_btnsList = [
HtmlGeneratorListButtons.getBtn({width: "2", sortIdent: "type", text: "Type"}),
HtmlGeneratorListButtons.getBtn({width: "2", sortIdent: "subType", text: "Subtype"}),
HtmlGeneratorListButtons.getBtn({width: "6", sortIdent: "name", text: "Name"}),
HtmlGeneratorListButtons.getBtnSource(),
];
_btnsSublist = [
HtmlGeneratorListButtons.getBtn({width: "2", sortIdent: "type", text: "Type"}),
HtmlGeneratorListButtons.getBtn({width: "2", sortIdent: "subType", text: "Subtype"}),
HtmlGeneratorListButtons.getBtn({width: "8", sortIdent: "name", text: "Name"}),
];
}
class _PageGeneratorListDecks extends PageGeneratorListBase {
_page = UrlUtil.PG_DECKS;
_pageTitle = "Decks";
_isFontAwesome = true;
_stylesheets = [
"decks",
];
_isStyleBook = true;
_scriptIdentList = "decks";
_styleListContainerAdditional = "ve-flex-4";
_styleContentWrapperAdditional = "ve-flex-7";
_btnsList = [
HtmlGeneratorListButtons.getBtn({width: "10", sortIdent: "name", text: "Name"}),
HtmlGeneratorListButtons.getBtnSource(),
];
_btnsSublist = [
HtmlGeneratorListButtons.getBtn({width: "12", sortIdent: "name", text: "Name"}),
];
}
class _PageGeneratorListDeities extends PageGeneratorListBase {
_page = UrlUtil.PG_DEITIES;
_pageTitle = "Deities";
_scriptIdentList = "deities";
_styleListContainerAdditional = "ve-flex-6";
_styleContentWrapperAdditional = "ve-flex-4";
_btnsList = [
HtmlGeneratorListButtons.getBtn({width: "3", sortIdent: "name", text: "Name"}),
HtmlGeneratorListButtons.getBtn({width: "2", sortIdent: "pantheon", text: "Pantheon"}),
HtmlGeneratorListButtons.getBtn({width: "2", sortIdent: "alignment", text: "Alignment"}),
HtmlGeneratorListButtons.getBtn({width: "3", sortIdent: "domains", text: "Domains"}),
HtmlGeneratorListButtons.getBtnSource(),
];
_btnsSublist = [
HtmlGeneratorListButtons.getBtn({width: "4", sortIdent: "name", text: "Name"}),
HtmlGeneratorListButtons.getBtn({width: "2", sortIdent: "pantheon", text: "Pantheon"}),
HtmlGeneratorListButtons.getBtn({width: "2", sortIdent: "alignment", text: "Alignment"}),
HtmlGeneratorListButtons.getBtn({width: "4", sortIdent: "domains", text: "Domains"}),
];
}
class _PageGeneratorListFeats extends PageGeneratorListBase {
_page = UrlUtil.PG_FEATS;
_pageTitle = "Feats";
_scriptIdentList = "feats";
_btnsList = [
HtmlGeneratorListButtons.getBtnPreviewToggle(),
HtmlGeneratorListButtons.getBtn({width: "3-5", sortIdent: "name", text: "Name"}),
HtmlGeneratorListButtons.getBtn({width: "3-5", sortIdent: "ability", text: "Ability"}),
HtmlGeneratorListButtons.getBtn({width: "3", sortIdent: "prerequisite", text: "Prerequisite"}),
HtmlGeneratorListButtons.getBtnSource(),
];
_btnsSublist = [
HtmlGeneratorListButtons.getBtn({width: "4", sortIdent: "name", text: "Name"}),
HtmlGeneratorListButtons.getBtn({width: "4", sortIdent: "ability", text: "Ability"}),
HtmlGeneratorListButtons.getBtn({width: "4", sortIdent: "prerequisite", text: "Prerequisite"}),
];
_isPrinterView = true;
}
class _PageGeneratorListItems extends PageGeneratorListBase {
_page = UrlUtil.PG_ITEMS;
_pageTitle = "Items";
_stylesheets = [
"items",
];
_scriptIdentList = "items";
_scriptsUtilsAdditional = [
"utils-tableview.js",
];
_styleContentWrapperAdditional = "itm__wrp-stats";
_btnsSublist = [
HtmlGeneratorListButtons.getBtn({width: "6", sortIdent: "name", text: "Name"}),
HtmlGeneratorListButtons.getBtn({width: "2", sortIdent: "weight", text: "Weight"}),
HtmlGeneratorListButtons.getBtn({width: "2", sortIdent: "cost", text: "Cost"}),
HtmlGeneratorListButtons.getBtn({width: "2", sortIdent: "count", text: "Number"}),
];
_registerPartials () {
super._registerPartials();
this._registerPartial({
ident: "listListcontainerItems",
filename: "list/template-list-listcontainer--items.hbs",
});
this._registerPartial({
ident: "listContentwrapperItems",
filename: "list/template-list-contentwrapper--items.hbs",
});
this._registerPartial({
ident: "listSublistContainerItems",
filename: "list/template-list-sublist-container--items.hbs",
});
}
_getData () {
return {
...super._getData(),
identPartialListListcontainer: "listListcontainerItems",
identPartialListContentwrapper: "listContentwrapperItems",
};
}
_isPrinterView = true;
}
class _PageGeneratorListTrapsHazards extends PageGeneratorListBase {
_page = UrlUtil.PG_TRAPS_HAZARDS;
_pageTitle = "Traps & Hazards";
_scriptIdentList = "trapshazards";
_btnsList = [
HtmlGeneratorListButtons.getBtn({width: "3", sortIdent: "trapType", text: "Type"}),
HtmlGeneratorListButtons.getBtn({width: "7", sortIdent: "name", text: "Name"}),
HtmlGeneratorListButtons.getBtnSource(),
];
_btnsSublist = [
HtmlGeneratorListButtons.getBtn({width: "4", sortIdent: "trapType", text: "Type"}),
HtmlGeneratorListButtons.getBtn({width: "8", sortIdent: "name", text: "Name"}),
];
}
class _PageGeneratorListRewards extends PageGeneratorListBase {
_page = UrlUtil.PG_REWARDS;
_pageTitle = "Supernatural Gifts & Rewards";
_scriptIdentList = "rewards";
_btnsList = [
HtmlGeneratorListButtons.getBtnPreviewToggle(),
HtmlGeneratorListButtons.getBtn({width: "2", sortIdent: "type", text: "Type"}),
HtmlGeneratorListButtons.getBtn({width: "7-7", sortIdent: "name", text: "Name"}),
HtmlGeneratorListButtons.getBtnSource(),
];
_btnsSublist = [
HtmlGeneratorListButtons.getBtn({width: "2", sortIdent: "type", text: "Type"}),
HtmlGeneratorListButtons.getBtn({width: "10", sortIdent: "name", text: "Name"}),
];
}
class _PageGeneratorListLanguages extends PageGeneratorListBase {
_page = UrlUtil.PG_LANGUAGES;
_pageTitle = "Languages";
_scriptIdentList = "languages";
_stylesheets = [
"languages",
];
_btnsList = [
HtmlGeneratorListButtons.getBtn({width: "6", sortIdent: "name", text: "Name"}),
HtmlGeneratorListButtons.getBtn({width: "2", sortIdent: "type", text: "Type"}),
HtmlGeneratorListButtons.getBtn({width: "2", sortIdent: "script", text: "Script"}),
HtmlGeneratorListButtons.getBtnSource(),
];
_btnsSublist = [
HtmlGeneratorListButtons.getBtn({width: "8", sortIdent: "name", text: "Name"}),
HtmlGeneratorListButtons.getBtn({width: "2", sortIdent: "type", text: "Type"}),
HtmlGeneratorListButtons.getBtn({width: "2", sortIdent: "script", text: "Script"}),
];
}
class _PageGeneratorListObjects extends PageGeneratorListBase {
_page = UrlUtil.PG_OBJECTS;
_pageTitle = "Objects";
_scriptIdentList = "objects";
_stylesheets = [
"objects",
];
_btnsList = [
HtmlGeneratorListButtons.getBtn({width: "8", sortIdent: "name", text: "Name"}),
HtmlGeneratorListButtons.getBtn({width: "2", sortIdent: "size", text: "Size"}),
HtmlGeneratorListButtons.getBtnSource(),
];
_btnsSublist = [
HtmlGeneratorListButtons.getBtn({width: "9", sortIdent: "name", text: "Name"}),
HtmlGeneratorListButtons.getBtn({width: "3", sortIdent: "size", text: "Size"}),
];
_isWrpToken = true;
_onscrollPageContent = `TokenUtil.handleStatblockScroll(event, this)`;
}
class _PageGeneratorListOptionalFeatures extends PageGeneratorListBase {
_page = UrlUtil.PG_OPT_FEATURES;
_pageTitle = "Other Options and Features";
_scriptIdentList = "optionalfeatures";
_isPrinterView = true;
_stylesheets = [
"optionalfeatures",
];
_styleListContainerAdditional = "ve-flex-6";
_styleContentWrapperAdditional = "ve-flex-4";
_btnsList = [
HtmlGeneratorListButtons.getBtnPreviewToggle(),
HtmlGeneratorListButtons.getBtn({width: "3", sortIdent: "name", text: "Name"}),
HtmlGeneratorListButtons.getBtn({width: "1-5", sortIdent: "type", text: "Type"}),
HtmlGeneratorListButtons.getBtn({width: "4-7", sortIdent: "prerequisite", text: "Prerequisite"}),
HtmlGeneratorListButtons.getBtn({width: "1", sortIdent: "level", text: "Level"}),
HtmlGeneratorListButtons.getBtnSource(),
];
_btnsSublist = [
HtmlGeneratorListButtons.getBtn({width: "4", sortIdent: "name", text: "Name"}),
HtmlGeneratorListButtons.getBtn({width: "2", sortIdent: "type", text: "Type"}),
HtmlGeneratorListButtons.getBtn({width: "4-5", sortIdent: "prerequisite", text: "Prerequisite"}),
HtmlGeneratorListButtons.getBtn({width: "1-5", sortIdent: "level", text: "Level"}),
];
}
class _PageGeneratorListPsionics extends PageGeneratorListBase {
_page = UrlUtil.PG_PSIONICS;
_pageTitle = "Psionics";
_scriptIdentList = "psionics";
_scriptsUtilsAdditional = [
"utils-tableview.js",
];
_btnsList = [
HtmlGeneratorListButtons.getBtn({width: "6", sortIdent: "name", text: "Name"}),
HtmlGeneratorListButtons.getBtn({width: "2", sortIdent: "type", text: "Type"}),
HtmlGeneratorListButtons.getBtn({width: "2", sortIdent: "order", text: "Order"}),
HtmlGeneratorListButtons.getBtnSource(),
];
_btnsSublist = [
HtmlGeneratorListButtons.getBtn({width: "6", sortIdent: "name", text: "Name"}),
HtmlGeneratorListButtons.getBtn({width: "3", sortIdent: "type", text: "Type"}),
HtmlGeneratorListButtons.getBtn({width: "3", sortIdent: "order", text: "Order"}),
];
_registerPartials () {
super._registerPartials();
this._registerPartial({
ident: "listContentwrapperPsionics",
filename: "list/template-list-contentwrapper--psionics.hbs",
});
}
_getData () {
return {
...super._getData(),
identPartialListContentwrapper: "listContentwrapperPsionics",
};
}
}
class _PageGeneratorListRaces extends PageGeneratorListBase {
_page = UrlUtil.PG_RACES;
_pageTitle = "Races";
_scriptIdentList = "races";
_btnsList = [
HtmlGeneratorListButtons.getBtn({width: "4", sortIdent: "name", text: "Name"}),
HtmlGeneratorListButtons.getBtn({width: "4", sortIdent: "ability", text: "Ability"}),
HtmlGeneratorListButtons.getBtn({width: "2", sortIdent: "size", text: "Size"}),
HtmlGeneratorListButtons.getBtnSource(),
];
_btnsSublist = [
HtmlGeneratorListButtons.getBtn({width: "5", sortIdent: "name", text: "Name"}),
HtmlGeneratorListButtons.getBtn({width: "5", sortIdent: "ability", text: "Ability"}),
HtmlGeneratorListButtons.getBtn({width: "2", sortIdent: "size", text: "Size"}),
];
_isPrinterView = true;
}
class _PageGeneratorListRecipes extends PageGeneratorListBase {
_page = UrlUtil.PG_RECIPES;
_pageTitle = "Recipes";
_scriptIdentList = "recipes";
_stylesheets = [
"recipes",
];
_isStyleBook = true;
_styleListContainerAdditional = "ve-flex-4";
_styleContentWrapperAdditional = "ve-flex-7";
_stylePageContentAdditional = "recipes__tbl-recipes";
_btnsList = [
HtmlGeneratorListButtons.getBtn({width: "6", sortIdent: "name", text: "Name"}),
HtmlGeneratorListButtons.getBtn({width: "4", sortIdent: "type", text: "Category"}),
HtmlGeneratorListButtons.getBtnSource(),
];
_btnsSublist = [
HtmlGeneratorListButtons.getBtn({width: "9", sortIdent: "name", text: "Name"}),
HtmlGeneratorListButtons.getBtn({width: "3", sortIdent: "type", text: "Category"}),
];
_registerPartials () {
super._registerPartials();
this._registerPartial({
ident: "listContentwrapperRecipes",
filename: "list/template-list-contentwrapper--recipes.hbs",
});
}
_getData () {
return {
...super._getData(),
identPartialListContentwrapper: "listContentwrapperRecipes",
};
}
}
class _PageGeneratorListSpells extends PageGeneratorListBase {
_page = UrlUtil.PG_SPELLS;
_pageTitle = "Spells";
_scriptIdentList = "spells";
_stylesheets = [
"spells",
];
_styleListContainerAdditional = "ve-flex-7";
_styleContentWrapperAdditional = "ve-flex-5";
_isMultisource = true;
_scriptsUtilsAdditional = [
"utils-tableview.js",
];
_btnsList = [
HtmlGeneratorListButtons.getBtn({width: "2-9", sortIdent: "name", text: "Name"}),
HtmlGeneratorListButtons.getBtn({width: "1-5", sortIdent: "level", text: "Level"}),
HtmlGeneratorListButtons.getBtn({width: "1-7", sortIdent: "time", text: "Time"}),
HtmlGeneratorListButtons.getBtn({width: "1-2", sortIdent: "school", text: "School"}),
HtmlGeneratorListButtons.getBtn({width: "0-6", sortIdent: "concentration", title: "Concentration", text: "C."}),
HtmlGeneratorListButtons.getBtn({width: "2-4", sortIdent: "range", text: "Range"}),
HtmlGeneratorListButtons.getBtnSource(),
];
_btnsSublist = [
HtmlGeneratorListButtons.getBtn({width: "3-2", sortIdent: "name", text: "Name"}),
HtmlGeneratorListButtons.getBtn({width: "1-5", sortIdent: "level", text: "Level"}),
HtmlGeneratorListButtons.getBtn({width: "1-8", sortIdent: "time", text: "Time"}),
HtmlGeneratorListButtons.getBtn({width: "1-6", sortIdent: "school", text: "School"}),
HtmlGeneratorListButtons.getBtn({width: "0-7", sortIdent: "concentration", title: "Concentration", text: "C."}),
HtmlGeneratorListButtons.getBtn({width: "3-2", sortIdent: "range", text: "Range"}),
];
_registerPartials () {
super._registerPartials();
this._registerPartial({
ident: "listContentwrapperSpells",
filename: "list/template-list-contentwrapper--spells.hbs",
});
}
_getData () {
return {
...super._getData(),
identPartialListContentwrapper: "listContentwrapperSpells",
};
}
}
class _PageGeneratorListTables extends PageGeneratorListBase {
_page = UrlUtil.PG_TABLES;
_pageTitle = "Tables";
_scriptIdentList = "tables";
_styleListContainerAdditional = "ve-flex-4";
_styleContentWrapperAdditional = "ve-flex-6";
_btnsList = [
HtmlGeneratorListButtons.getBtn({width: "10", sortIdent: "sortName", text: "Name"}),
HtmlGeneratorListButtons.getBtnSource(),
];
_btnsSublist = [
HtmlGeneratorListButtons.getBtn({width: "12", sortIdent: "sortName", text: "Name"}),
];
}
class _PageGeneratorListVariantRules extends PageGeneratorListBase {
_page = UrlUtil.PG_VARIANTRULES;
_pageTitle = "Optional, Variant, and Expanded Rules";
_navbarTitle = "Optional/etc. Rules";
_scriptIdentList = "variantrules";
_btnsList = [
HtmlGeneratorListButtons.getBtn({width: "7", sortIdent: "name", text: "Name"}),
HtmlGeneratorListButtons.getBtn({width: "3", sortIdent: "ruleType", text: "Type"}),
HtmlGeneratorListButtons.getBtnSource(),
];
_btnsSublist = [
HtmlGeneratorListButtons.getBtn({width: "9", sortIdent: "name", text: "Name"}),
HtmlGeneratorListButtons.getBtn({width: "3", sortIdent: "ruleType", text: "Type"}),
];
}
class _PageGeneratorListVehicles extends PageGeneratorListBase {
_page = UrlUtil.PG_VEHICLES;
_pageTitle = "Vehicles";
_scriptIdentList = "vehicles";
_stylesheets = [
"vehicles",
];
_btnsList = [
HtmlGeneratorListButtons.getBtn({width: "6", sortIdent: "type", text: "Type"}),
HtmlGeneratorListButtons.getBtn({width: "4", sortIdent: "name", text: "Name"}),
HtmlGeneratorListButtons.getBtnSource(),
];
_btnsSublist = [
HtmlGeneratorListButtons.getBtn({width: "8", sortIdent: "type", text: "Type"}),
HtmlGeneratorListButtons.getBtn({width: "4", sortIdent: "name", text: "Name"}),
];
_isWrpToken = true;
_onscrollPageContent = `TokenUtil.handleStatblockScroll(event, this)`;
}
class _PageGeneratorListClasses extends PageGeneratorListBase {
_filename = "list/template-list--classes.hbs";
_page = UrlUtil.PG_CLASSES;
_pageTitle = "Classes";
_scriptIdentList = "classes";
_isHasRenderer = false;
_stylesheets = [
"classes",
];
}
export const PAGE_GENERATORS_LISTPAGE = [
new _PageGeneratorListActions(),
new _PageGeneratorListBackgrounds(),
new _PageGeneratorListBestiary(),
new _PageGeneratorListCharCreationOptions(),
new _PageGeneratorListConditionsDiseases(),
new _PageGeneratorListCultsBoons(),
new _PageGeneratorListDecks(),
new _PageGeneratorListDeities(),
new _PageGeneratorListFeats(),
new _PageGeneratorListItems(),
new _PageGeneratorListTrapsHazards(),
new _PageGeneratorListRewards(),
new _PageGeneratorListLanguages(),
new _PageGeneratorListObjects(),
new _PageGeneratorListOptionalFeatures(),
new _PageGeneratorListPsionics(),
new _PageGeneratorListRaces(),
new _PageGeneratorListRecipes(),
new _PageGeneratorListSpells(),
new _PageGeneratorListTables(),
new _PageGeneratorListVariantRules(),
new _PageGeneratorListVehicles(),
new _PageGeneratorListClasses(),
];

View File

@@ -0,0 +1,28 @@
import {PageGeneratorManagerBase} from "./generate-pages-page-generator.js";
class _PageGeneratorManagebrew extends PageGeneratorManagerBase {
_page = "managebrew.html";
_pageTitle = "Manage Homebrew";
_navbarDescription = "View, Add, and Delete Homebrew.";
_scripts = [
"managebrew.js",
];
}
class _PageGeneratorManageprerelease extends PageGeneratorManagerBase {
_page = "manageprerelease.html";
_pageTitle = "Manage Prerelease Content";
_navbarDescription = "View, Add, and Delete Prerelease Content.";
_scripts = [
"manageprerelease.js",
];
}
export const PAGE_GENERATORS_MANAGER = [
new _PageGeneratorManagebrew(),
new _PageGeneratorManageprerelease(),
];

View File

@@ -0,0 +1,14 @@
import {PageGeneratorRedirectBase} from "./generate-pages-page-generator.js";
class _PageGenerator5etools extends PageGeneratorRedirectBase {
_page = "5etools.html";
_pageDescription = "A suite of browser-based tools for 5th Edition Dungeons & Dragons players and Dungeon Masters.";
_redirectHref = "index.html";
_redirectMessage = "the homepage";
}
export const PAGE_GENERATORS_REDIRECT = [
new _PageGenerator5etools(),
];

View File

@@ -0,0 +1,29 @@
import {PageGeneratorTablepageBase} from "./generate-pages-page-generator.js";
class _PageGeneratorEncountergen extends PageGeneratorTablepageBase {
_page = "encountergen.html";
_pageTitle = "Encounters";
_navbarTitle = "Encounter Generator";
_navbarDescription = "Choose a setting and level range, then roll the dice!";
_scripts = [
"encountergen.js",
];
}
class _PageGeneratorNames extends PageGeneratorTablepageBase {
_page = "names.html";
_pageTitle = "Names";
_navbarDescription = "Choose a race and a type, then roll the dice!";
_scripts = [
"names.js",
];
}
export const PAGE_GENERATORS_TABLEPAGE = [
new _PageGeneratorEncountergen(),
new _PageGeneratorNames(),
];

View File

@@ -0,0 +1,464 @@
import {PAGE_GENERATORS_LISTPAGE} from "./generate-pages-page-generator-config-list.js";
import {PAGE_GENERATORS_REDIRECT} from "./generate-pages-page-generator-config-redirect.js";
import {PAGE_GENERATORS_ADVENTURE_BOOK} from "./generate-pages-page-generator-config-advbook.js";
import {PageGeneratorGeneric} from "./generate-pages-page-generator.js";
import {PAGE_GENERATORS_TABLEPAGE} from "./generate-pages-page-generator-config-tablepage.js";
import {PAGE_GENERATORS_MANAGER} from "./generate-pages-page-generator-config-manager.js";
class _PageGeneratorMaps extends PageGeneratorGeneric {
_filename = "page/template-page-maps.hbs";
_page = UrlUtil.PG_MAPS;
_pageTitle = "Maps";
_navbarDescription = "Browse maps from adventures and books.";
_stylesheets = [
"maps",
];
_scriptsRenderAdditional = [
"render-map.js",
];
_scripts = [
"maps-util.js",
"maps.js",
];
}
class _PageGeneratorDmscreen extends PageGeneratorGeneric {
_filename = "page/template-page-dmscreen.hbs";
_page = UrlUtil.PG_DM_SCREEN;
_pageTitle = "DM Screen";
_navbarDescription = "Build a personalised DM screen.";
_isFontAwesome = true;
_stylesheets = [
"dmscreen",
];
_scriptsLibAdditional = [
"peerjs.js",
"jquery.panzoom.js",
"lzma.js",
];
_scriptsUtilsAdditional = [
"utils-list.js",
"utils-p2p.js",
];
_scriptsRenderAdditional = [
"render-map.js",
];
_scriptsModules = [
"dmscreen.js",
];
}
class _PageGeneratorBlocklist extends PageGeneratorGeneric {
_filename = "page/template-page-blocklist.hbs";
_page = "blocklist.html";
_pageTitle = "Content Blocklist";
_navbarDescription = "Exclude content and export configurations.";
_scripts = [
"blocklist-ui.js",
"blocklist.js",
];
}
class _PageGeneratorChangelog extends PageGeneratorGeneric {
_filename = "page/template-page-changelog.hbs";
_page = "changelog.html";
_pageTitle = "Changelog";
_navbarDescription = "See what changed.";
_stylesheets = [
"changelog",
];
_scriptsUtilsAdditional = [
"utils-changelog.js",
];
_scripts = [
"changelog.js",
];
}
class _PageGeneratorConverter extends PageGeneratorGeneric {
_filename = "page/template-page-converter.hbs";
_page = "converter.html";
_pageTitle = "Text Converter";
_navbarDescription = "Input text on left, hit parse, copy JSON from right.";
_stylesheets = [
"converter",
];
_scriptsLibAdditional = [
"ace.js",
];
_scriptsRenderAdditional = [
"render-markdown.js",
];
_scriptsUtilsAdditional = [
"utils-proporder.js",
];
_scripts = [
"converterutils.js",
"converterutils-entries.js",
"converterutils-markdown.js",
"converterutils-creature.js",
"converterutils-spell.js",
"converterutils-item.js",
"converterutils-race.js",
"converterutils-background.js",
"converter.js",
"converter-feature.js",
"converter-creature.js",
"converter-spell.js",
"converter-item.js",
"converter-table.js",
"converter-feat.js",
"converter-race.js",
"converter-background.js",
];
}
class _PageGeneratorCrcalculator extends PageGeneratorGeneric {
_filename = "page/template-page-crcalculator.hbs";
_page = "crcalculator.html";
_pageTitle = "CR Calculator";
_navbarDescription = "Easily build custom creatures.";
_stylesheets = [
"crcalculator",
];
_scripts = [
"crcalculator.js",
];
}
class _PageGeneratorIndex extends PageGeneratorGeneric {
_filename = "page/template-page-index.hbs";
_page = "index.html";
_pageDescription = "A suite of tools for 5th Edition Dungeons & Dragons players and Dungeon Masters.";
_navbarTitleHtml = `5e<span>tools</span>`;
_navbarDescription = "A suite of tools for 5th Edition Dungeons & Dragons players and Dungeon Masters.";
_navbarPageTitleStyleAdditional = "my-0--home";
_isFontAwesome = true;
_stylesheets = [
"index",
];
_scriptsModules = [
"index.js",
];
}
class _PageGeneratorInittrackerplayerview extends PageGeneratorGeneric {
_filename = "page/template-page-inittrackerplayerview.hbs";
_page = "inittrackerplayerview.html";
_pageTitle = "Initiative Tracker Player View";
_navbarDescription = "Press F to toggle fullscreen. Good luck.";
_stylesheets = [
"inittrackerplayerview",
];
_scriptsLibAdditional = [
"peerjs.js",
"lzma.js",
];
_scriptsUtilsAdditional = [
"utils-p2p.js",
];
_scriptsModules = [
"inittrackerplayerview.js",
];
}
class _PageGeneratorLangdemo extends PageGeneratorGeneric {
_filename = "page/template-page-langdemo.hbs";
_page = "langdemo.html";
_pageTitle = "RoLang Demo";
_navbarDescription = "Edit the input and context, and hit Run";
_stylesheets = [
"langdemo",
];
_scriptsRenderAdditional = [
"render-markdown.js",
"render-card.js",
];
_scriptsLibAdditional = [
"ace.js",
];
_scriptsModules = [
"langdemo.js",
"rolang.js",
];
}
class _PageGeneratorLifegen extends PageGeneratorGeneric {
_filename = "page/template-page-lifegen.hbs";
_page = "lifegen.html";
_pageTitle = "This Is Your Life";
_navbarDescription = "Select options, and hit generate.";
_stylesheets = [
"lifegen",
];
_scriptsUtilsAdditional = [
"utils-generate.js",
];
_scripts = [
"lifegen.js",
];
}
class _PageGeneratorLootgen extends PageGeneratorGeneric {
_filename = "page/template-page-lootgen.hbs";
_page = "lootgen.html";
_pageTitle = "Loot Generator";
_navbarDescription = "Configure the generator, then Roll Loot!";
_stylesheets = [
"lootgen-bundle",
];
_scriptsUtilsAdditional = [
"utils-generate.js",
"filter-items.js",
"filter-spells.js",
];
_scripts = [
"lootgen.js",
"lootgen-ui.js",
];
}
class _PageGeneratorMakebrew extends PageGeneratorGeneric {
_filename = "page/template-page-makebrew.hbs";
_page = "makebrew.html";
_pageTitle = "Homebrew Builder";
_navbarDescription = "Input values on left, view the results on the right.";
_stylesheets = [
"makebrew",
];
_scriptsLibAdditional = [
"bootstrap-typeahead.js",
];
_scriptsRenderAdditional = [
"render-markdown.js",
"render-bestiary.js",
"render-spells.js",
];
_scriptsUtilsAdditional = [
"utils-proporder.js",
"filter-spells.js",
"converterutils.js",
"converterutils-creature.js",
];
_scripts = [
"makebrew.js",
"makebrew-creature.js",
"makebrew-legendarygroup.js",
];
_scriptsModules = [
"makebrew-spell.js",
];
}
class _PageGeneratorMakecards extends PageGeneratorGeneric {
_filename = "page/template-page-makecards.hbs";
_page = "makecards.html";
_pageTitle = "RPG Cards JSON Builder";
_navbarDescription = "Build and export card JSON data.";
_stylesheets = [
"makecards",
];
_scriptsLibAdditional = [
"bootstrap-typeahead.js",
];
_scriptsLibAdditionalRemote = [
"https://rpg-cards.vercel.app/js/icons.js",
];
_scriptsRenderAdditional = [
"render-card.js",
];
_scriptsUtilsAdditional = [
"filter-common.js",
"filter-bestiary.js",
"filter-items.js",
"filter-spells.js",
"filter-races.js",
"filter-backgrounds.js",
"filter-feats.js",
"filter-optionalfeatures.js",
];
_scripts = [
"makecards.js",
];
}
class _PageGeneratorPlutonium extends PageGeneratorGeneric {
_filename = "page/template-page-plutonium.hbs";
_page = "plutonium.html";
_pageTitle = "Plutonium Features";
_navbarDescription = "An overview of the 5etools integration for Foundry VTT.";
_stylesheets = [
"plutonium",
];
_scriptsModules = [
"plutonium.js",
];
}
class _PageGeneratorPrivacyPolicy extends PageGeneratorGeneric {
_filename = "page/template-page-privacy-policy.hbs";
_page = "privacy-policy.html";
_pageTitle = "Privacy Policy";
_navbarDescription = `Just click "Accept."`;
_scripts = [
"privacy-policy.js",
];
}
class _PageGeneratorRenderdemo extends PageGeneratorGeneric {
_filename = "page/template-page-renderdemo.hbs";
_page = "renderdemo.html";
_pageTitle = "Renderer Demo";
_navbarDescription = "Edit the JSON on the left, and see the results on the right.";
_stylesheets = [
"renderdemo",
];
_scriptsRenderAdditional = [
"render-markdown.js",
"render-card.js",
];
_scriptsLibAdditional = [
"ace.js",
];
_scripts = [
"renderdemo.js",
];
}
class _PageGeneratorSearch extends PageGeneratorGeneric {
_filename = "page/template-page-search.hbs";
_page = "search.html";
_pageTitle = "Search";
_navbarDescription = "A search engine to add to your browser.";
_stylesheets = [
"search",
];
_scripts = [
"search.js",
];
}
class _PageGeneratorStatgen extends PageGeneratorGeneric {
_filename = "page/template-page-statgen.hbs";
_page = "statgen.html";
_pageTitle = "Statgen";
_navbarDescription = "Change method on the left, refer to method that appears on the right.";
_isFontAwesome = true;
_stylesheets = [
"statgen-bundle",
];
_scriptsUtilsAdditional = [
"filter-common.js",
"filter-races.js",
"filter-backgrounds.js",
"filter-feats.js",
];
_scripts = [
"statgen.js",
"statgen-ui.js",
];
}
export const PAGE_GENERATORS = [
...PAGE_GENERATORS_LISTPAGE,
...PAGE_GENERATORS_REDIRECT,
...PAGE_GENERATORS_ADVENTURE_BOOK,
...PAGE_GENERATORS_TABLEPAGE,
...PAGE_GENERATORS_MANAGER,
new _PageGeneratorMaps(),
new _PageGeneratorDmscreen(),
new _PageGeneratorBlocklist(),
new _PageGeneratorChangelog(),
new _PageGeneratorConverter(),
new _PageGeneratorCrcalculator(),
new _PageGeneratorIndex(),
new _PageGeneratorInittrackerplayerview(),
new _PageGeneratorLangdemo(),
new _PageGeneratorLifegen(),
new _PageGeneratorLootgen(),
new _PageGeneratorMakebrew(),
new _PageGeneratorMakecards(),
new _PageGeneratorPlutonium(),
new _PageGeneratorPrivacyPolicy(),
new _PageGeneratorRenderdemo(),
new _PageGeneratorSearch(),
new _PageGeneratorStatgen(),
];

View File

@@ -0,0 +1,299 @@
import Handlebars from "handlebars";
import fs from "fs";
/** @abstract */
export class PageGeneratorBase {
_filename;
_page;
_pageTitle;
_pageDescription;
_navbarTitle;
_navbarTitleHtml;
_navbarDescription;
_navbarPageTitleStyleAdditional;
_isFontAwesome = false;
_stylesheets;
init () {
this._registerPartials();
return this;
}
_registerPartial ({ident, filename}) {
Handlebars.registerPartial(ident, this.constructor._getLoadedSource({filename}));
}
_registerPartials () {
this._registerPartial({ident: "overlayNoise", filename: "misc/template-overlay-noise.hbs"});
this._registerPartial({ident: "head", filename: "head/template-head.hbs"});
this._registerPartial({ident: "adRhs", filename: "ad/template-ad-rhs.hbs"});
this._registerPartial({ident: "adRhsScrollingPage", filename: "ad/template-ad-rhs--scrolling-page.hbs"});
this._registerPartial({ident: "adLeaderboard", filename: "ad/template-ad-leaderboard.hbs"});
this._registerPartial({ident: "adMobile1", filename: "ad/template-ad-mobile-1.hbs"});
this._registerPartial({ident: "adFooter", filename: "ad/template-ad-footer.hbs"});
this._registerPartial({ident: "navbar", filename: "navbar/template-navbar.hbs"});
this._registerPartial({ident: "scripts", filename: "scripts/template-scripts.hbs"});
this._registerPartial({ident: "blank", filename: "misc/template-blank.hbs"});
}
getPage () { return this._page; }
/**
* @abstract
* @return {object}
*/
_getData () {
return {
pageTitle: this._pageTitle,
pageDescription: this._pageDescription,
navbarTitle: this._navbarTitle ?? this._pageTitle,
navbarTitleHtml: this._navbarTitleHtml,
navbarDescription: this._navbarDescription,
navbarPageTitleStyleAdditional: this._navbarPageTitleStyleAdditional,
isFontAwesome: this._isFontAwesome,
stylesheets: this._stylesheets,
};
}
generatePage () {
const template = Handlebars.compile(this.constructor._getLoadedSource({filename: this._filename}));
const rendered = template(this._getData())
.split("\n")
.map(l => l.trimEnd())
.join("\n");
fs.writeFileSync(this._page, rendered, "utf-8");
}
static _getLoadedSource ({filename}) {
return fs.readFileSync(`./node/generate-pages/template/${filename}`, "utf-8");
}
}
export class PageGeneratorRedirectBase extends PageGeneratorBase {
_filename = "page/template-page-redirect.hbs";
_redirectHref;
_redirectMessage;
_getData () {
return {
...super._getData(),
redirectHref: this._redirectHref,
redirectMessage: this._redirectMessage,
};
}
}
/** @abstract */
export class PageGeneratorGeneric extends PageGeneratorBase {
_scriptsLibAdditional;
_scriptsLibAdditionalRemote;
_scriptsUtilsAdditional;
_scriptsRenderAdditional;
_scripts;
_scriptsModules;
_getData () {
return {
...super._getData(),
scriptsLibAdditional: this._scriptsLibAdditional,
scriptsLibAdditionalRemote: this._scriptsLibAdditionalRemote,
scriptsUtilsAdditional: this._scriptsUtilsAdditional,
scriptsRenderAdditional: this._scriptsRenderAdditional,
scripts: this._scripts,
scriptsModules: this._scriptsModules,
};
}
}
export class PageGeneratorListBase extends PageGeneratorGeneric {
_filename = "list/template-list.hbs";
_navbarDescription = "Search by name on the left, click a name to display on the right.";
_isStyleBook = false;
_scriptIdentList;
_scriptsPrePageAdditional;
_isHasRenderer = true; // TODO(Future) only used in the Classes page -- refactor class rendering to own file
_isModule = false;
_isMultisource = false;
_btnsList;
_btnsSublist;
_isWrpToken;
_onscrollPageContent;
_styleListContainerAdditional;
_styleContentWrapperAdditional;
_stylePageContentAdditional;
_isPrinterView = false;
_registerPartials () {
super._registerPartials();
this._registerPartial({ident: "listListcontainer", filename: "list/template-list-listcontainer.hbs"});
this._registerPartial({ident: "listFilterSearchGroup", filename: "list/template-list-filter-search-group.hbs"});
this._registerPartial({ident: "listFiltertools", filename: "list/template-list-filtertools.hbs"});
this._registerPartial({ident: "listList", filename: "list/template-list-list.hbs"});
this._registerPartial({ident: "listContentwrapper", filename: "list/template-list-contentwrapper.hbs"});
this._registerPartial({ident: "listSublistContainer", filename: "list/template-list-sublist-container.hbs"});
this._registerPartial({ident: "listSublist", filename: "list/template-list-sublist.hbs"});
this._registerPartial({ident: "listSublistsort", filename: "list/template-list-sublistsort.hbs"});
this._registerPartial({ident: "listStatsTabs", filename: "list/template-list-stats-tabs.hbs"});
this._registerPartial({ident: "listWrpPagecontent", filename: "list/template-list-wrp-pagecontent.hbs"});
this._registerPartial({ident: "listRhsWrpFooterControls", filename: "list/template-list-rhs-wrp-footer-controls.hbs"});
this._registerPartial({ident: "listRhsWrpToken", filename: "list/template-list-rhs-wrp-token.hbs"});
}
/**
* @return {object}
*/
_getData () {
const data = super._getData();
return {
...data,
scripts: [
"listpage.js",
...(this._isMultisource ? ["multisource.js"] : []),
"filter-common.js",
`filter-${this._scriptIdentList}.js`,
...(this._scriptsPrePageAdditional || []),
...(this._isModule ? [] : [`${this._scriptIdentList}.js`]),
...data.scripts || [],
],
scriptsModules: [
...(this._isModule ? [`${this._scriptIdentList}.js`] : []),
...data.scriptsModules || [],
],
scriptsUtilsAdditional: [
"utils-list.js",
...data.scriptsUtilsAdditional || [],
],
scriptsRenderAdditional: [
"render-markdown.js",
...(this._isHasRenderer ? [`render-${this._scriptIdentList}.js`] : []),
...data.scriptsRenderAdditional || [],
],
btnsList: this._btnsList,
btnsSublist: this._btnsSublist,
isWrpToken: this._isWrpToken,
onscrollPageContent: this._onscrollPageContent,
isStyleBook: this._isStyleBook,
styleListContainerAdditional: this._styleListContainerAdditional,
styleContentWrapperAdditional: this._styleContentWrapperAdditional,
stylePageContentAdditional: this._stylePageContentAdditional,
identPartialListListcontainer: "listListcontainer",
identPartialListContentwrapper: "listContentwrapper",
isPrinterView: this._isPrinterView,
};
}
}
export class PageGeneratorAdventureBookBase extends PageGeneratorGeneric {
_filename = "advbook/template-advbook.hbs";
_scriptIdentAdvBook;
_advBookPlaceholder;
_scriptsRenderAdditional = [
"render-markdown.js",
"render-map.js",
];
_getData () {
const data = super._getData();
return {
...data,
advBookPlaceholder: this._advBookPlaceholder,
scripts: [
...data.scripts || [],
"bookutils.js",
`${this._scriptIdentAdvBook}.js`,
],
};
}
}
export class PageGeneratorAdventuresBooksBase extends PageGeneratorGeneric {
_filename = "advbook/template-advsbooks.hbs";
_scriptIdentAdvsBooks;
_searchName;
_btnsList;
_getData () {
const data = super._getData();
return {
...data,
searchName: this._searchName,
btnsList: this._btnsList,
scripts: [
...data.scripts || [],
"bookutils.js",
"bookslist.js",
`${this._scriptIdentAdvsBooks}.js`,
],
};
}
}
export class PageGeneratorTablepageBase extends PageGeneratorGeneric {
_filename = "tablepage/template-tablepage.hbs";
_stylesheets = [
"list-page--grouped",
];
_scriptsRenderAdditional = [
"render-markdown.js",
];
_scriptsUtilsAdditional = [
"utils-list.js",
];
_getData () {
const data = super._getData();
return {
...data,
scripts: [
"listpage.js",
"tablepage.js",
...data.scripts || [],
],
};
}
}
export class PageGeneratorManagerBase extends PageGeneratorGeneric {
_filename = "manager/template-manager.hbs";
_scriptsRenderAdditional = [
"render-markdown.js",
];
_scriptsUtilsAdditional = [
"utils-list.js",
];
_scriptsModules = [
"manageexternal/manageexternal-utils.js",
];
}

View File

@@ -0,0 +1 @@
<div class="cancer__wrp-sidebar-rhs cancer__wrp-sidebar-rhs--scrolling-page cancer__anchor"><div class="cancer__disp-cancer"></div><div class="cancer__sidebar-rhs-inner cancer__sidebar-rhs-inner--top"><!--5ETOOLS_AD_RIGHT_1--></div><div class="cancer__sidebar-rhs-inner cancer__sidebar-rhs-inner--bottom"><!--5ETOOLS_AD_RIGHT_2--></div></div>

View File

@@ -0,0 +1,45 @@
<!DOCTYPE html>
<html lang="en">
{{> "head" }}
<body>
{{> "overlayNoise" }}
{{> "adLeaderboard" }}
{{> "navbar" }}
{{> "adRhsScrollingPage" }}
<div class="container view-col-wrapper">
<div class="view-col book-contents view-col--wrp-book-contents" id="listcontainer">
<div class="list contents ve-flex-col">
<!-- populate with JS -->
</div>
</div>
<div class="view-col linked-titles book-view">
<table id="pagecontent" class="w-100 stats stats--book stats--book-large">
<tr><th class="border" colspan="6"></th></tr>
<tr><td colspan="6" class="initial-message book-loading-message">Loading...</td></tr>
<!-- (Placeholder text until page loads) -->
<tr><td colspan="6" class="text-muted">{{advBookPlaceholder}}</td></tr>
<tr><th class="border" colspan="6"></th></tr>
</table>
<div class="bk__overlay-loading">
<div class="h-100 w-100 ve-flex-vh-center"><span class="initial-message">Loading...</span></div>
</div>
<div class="cancer__footer-pad w-100"></div>
</div>
</div>
{{> "adFooter" }}
{{> "scripts" }}
</body>
</html>

View File

@@ -0,0 +1,51 @@
<!DOCTYPE html>
<html lang="en">
{{> "head" }}
<body>
{{> "overlayNoise" }}
{{> "adLeaderboard" }}
{{> "navbar" }}
{{> "adRhsScrollingPage" }}
<div class="container view-col-wrapper">
<div class="view-col" id="listcontainer">
<div class="lst__form-top">
<input type="search" id="search" autocomplete="off" autocapitalize="off" spellcheck="false" class="search form-control" placeholder="Find {{searchName}}...">
<button class="btn btn-default" id="reset">Reset</button>
</div>
<div id="filtertools" class="input-group input-group--bottom ve-flex no-shrink">
{{#each btnsList}}
{{{this}}}
{{/each}}
<button class="btn btn-default btn-xs w-30p mobile__hidden" disabled></button>
</div>
<div class="list list--stats books">
<!-- populate with JS -->
</div>
<div class="ve-text-center mt-3 no-print">
<button class="btn btn-xs btn-info" id="manage-brew">Manage Homebrew</button>
</div>
<hr class="hr-3 mt-4">
<div class="books--alt ve-flex-h-center ve-flex-wrap bks__wrp-bookshelf">
<!-- populate with JS -->
</div>
</div>
</div>
{{> "adFooter" }}
{{> "scripts" }}
</body>
</html>

View File

@@ -3,12 +3,12 @@
<!--5ETOOLS_ANALYTICS-->
<!--5ETOOLS_ADCODE-->
<meta charset="utf-8">
<meta name="description" content="">
<meta name="description" content="{{pageDescription}}">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
<meta name="apple-mobile-web-app-capable" content="yes">
<title>{{titlePage}} - 5etools</title>
<title>{{#if pageTitle}}{{pageTitle}} - 5etools{{else}}5etools{{/if}}</title>
<link rel="stylesheet" href="css/bootstrap.css">
{{#if isFontAwesome}} <link rel="stylesheet" href="css/fontawesome.css">
@@ -53,6 +53,11 @@
<script type="text/javascript" src="sw-injector.js"></script>
<script type="text/javascript" src="js/styleswitch.js"></script>
{{#if redirectHref}}
<meta http-equiv="refresh" content="0; URL={{redirectHref}}"/>
{{else}}
<script type="text/javascript" src="js/navigation.js"></script>
<script type="text/javascript" src="js/browsercheck.js"></script>
{{/if}}
</head>

View File

@@ -0,0 +1,78 @@
<!DOCTYPE html>
<html lang="en">
{{> "head" }}
<body>
{{> "overlayNoise" }}
{{> "adLeaderboard" }}
{{> "navbar" }}
{{> "adRhsScrollingPage" }}
<main class="container classes">
<div class="row">
<div class="col-md-3" id="listcontainer">
<div class="night__shadow-big">
<div class="lst__form-top" id="filter-search-group">
<div class="w-100 relative">
<input type="search" id="lst__search" autocomplete="off" autocapitalize="off" spellcheck="false" class="search form-control lst__search lst__search--no-border-h">
<div id="lst__search-glass" class="lst__wrp-search-glass no-events ve-flex-vh-center"><span class="glyphicon glyphicon-search"></span></div>
<div class="lst__wrp-search-visible no-events ve-flex-vh-center"></div>
</div>
<button class="btn btn-default px-2" id="reset"><span class="glyphicon glyphicon-refresh"></span></button>
</div>
<div id="filtertools" class="input-group input-group--bottom ve-flex no-shrink">
<button class="ve-col-8 sort btn btn-default btn-xs" data-sort="name">Name</button>
<button class="sort btn btn-default btn-xs ve-grow" data-sort="source">Source</button>
</div>
<div class="list list--stats classes cls__list"></div>
</div>
<div class="ve-flex-vh-center my-3">
<button class="btn btn-xs btn-info" id="manage-brew">Manage Homebrew</button>
</div>
</div>
<div class="col-md-9" id="classtable"></div>
</div>
<hr class="mt-0">
<div class="row ve-flex mobile-md__ve-flex-col">
<div class="col-md-3">
<div class="ve-flex-vh-center ve-text-center wrp-btn-readmode mb-3">
<button class="btn btn-default btn-xs no-print mr-1" id="btn-comparemode" title="A pop-up table which can be used to compare subclass features.">Subclass Comparison</button>
<button class="btn btn-default btn-xs no-print mr-1" id="btn-readmode" title="A pop-up reading mode with a layout and content order matching that of the books.">Book View</button>
<div class=" ve-flex-v-center btn-group">
<button class="btn btn-default btn-xs" id="btn-link-export"><span class="glyphicon glyphicon-magnet"></span></button>
<button class="btn btn-default btn-xs" id="btn-sidebar-settings" title="Settings"><span class="glyphicon glyphicon-cog"></span></button>
</div>
</div>
<div id="statsprof"></div>
<div id="sticky-nav" class="cls-nav"></div>
</div>
<div class="col-md-9">
<div class="cancer__wrp-mobile-1 cancer__anchor"><div class="cancer__disp-cancer"></div><!--5ETOOLS_AD_MOB_PLAYER_1--></div>
<div id="subclasstabs" class="w-100 ve-flex mb-2 cls-tabs__wrp"></div>
<table id="pagecontent" class="w-100 stats shadow-big">
<tr><th class="border" colspan="6"></th></tr>
<tr><td colspan="6" class="initial-message">Loading...</td></tr>
<tr><th class="border" colspan="6"></th></tr>
</table>
</div>
</div>
</main>
{{> "adFooter" }}
{{> "scripts" }}
</body>
</html>

View File

@@ -5,6 +5,8 @@
<body>
{{> "overlayNoise" }}
{{> "adRhs" }}
<div class="viewport-wrapper">
@@ -25,7 +27,7 @@
{{> "adFooter" }}
{{> "listScripts" }}
{{> "scripts" }}
</body>
</html>

View File

@@ -0,0 +1,25 @@
<!DOCTYPE html>
<html lang="en">
{{> "head" }}
<body>
{{> "overlayNoise" }}
{{> "adLeaderboard" }}
{{> "navbar" }}
{{> "adRhsScrollingPage" }}
<main class="container">
<div id="manager" class="flex-col"><div class="w-100 ve-flex-vh-center"><i class="dnd-font ve-muted">Loading...</i></div></div>
</main>
{{> "adFooter" }}
{{> "scripts" }}
</body>
</html>

View File

@@ -0,0 +1 @@
<div class="overlay-noise"></div>

View File

@@ -1,9 +1,10 @@
<header class="hidden-xs hidden-sm page__header">
<div class="container ve-flex-v-baseline">
<h1 class="page__title no-wrap my-0">{{navbarTitle}}</h1>
<h1 class="page__title no-wrap my-0{{#if navbarPageTitleStyleAdditional}} {{navbarPageTitleStyleAdditional}}{{/if}}" id="page__title">{{#if navbarTitleHtml}}{{{navbarTitleHtml}}}{{else}}{{navbarTitle}}{{/if}}</h1>
<p class="page__subtitle no-wrap my-0" id="page__subtitle">{{navbarDescription}}</p>
</div>
</header>
<nav class="container page__nav" id="navigation">
<ul class="nav nav-pills page__nav-inner" id="navbar"></ul>
</nav>

View File

@@ -0,0 +1,43 @@
<!DOCTYPE html>
<html lang="en">
{{> "head" }}
<body>
{{> "overlayNoise" }}
{{> "adLeaderboard" }}
{{> "navbar" }}
{{> "adRhsScrollingPage" }}
<main class="container">
<div class="px-4 mt-4">
<p>
This page allows you to create configurations which &quot;blocklist&quot; site content, hiding it from list pages.
This can be used, for example, in conjunction with homebrew content, to create a campaign JSON file containing additions to the base game,
as well as the removal of extraneous content.
</p>
<p class="mb-0"><i class="text-muted">
With great power comes great responsibility. If you are a DM intending to use this system to remove parts of the game you
consider broken; inconvenient; or otherwise in need of adjustment, please first consider the needs and expectations of your players,
as well as the extensive playtesting and design iteration backing 5th Edition.
If something is in the game, it is probably there for a reason.
</i></p>
</div>
<hr>
<div class="ve-flex-col" id="blocklist-content">
<div class="py-2 ve-flex-vh-center initial-message">Loading...</div>
</div>
</main>
{{> "adFooter" }}
{{> "scripts" }}
</body>
</html>

View File

@@ -0,0 +1,23 @@
<!DOCTYPE html>
<html lang="en">
{{> "head" }}
<body>
{{> "overlayNoise" }}
{{> "adLeaderboard" }}
{{> "navbar" }}
{{> "adRhsScrollingPage" }}
<main class="container night__shadow-big mt-3" id="pagecontent"><div class="ve-flex-vh-center dnd-font mt-3"><i>Loading...</i></div></main>
{{> "adFooter" }}
{{> "scripts" }}
</body>
</html>

View File

@@ -0,0 +1,66 @@
<!DOCTYPE html>
<html lang="en">
{{> "head" }}
<body>
{{> "overlayNoise" }}
<div class="viewport-wrapper">
<div class="sidemenu__toggle">
<div class="sidemenu__hotzone"></div>
<div class="sidemenu__burger"></div>
<div class="sidemenu__burger"></div>
<div class="sidemenu__burger"></div>
<div class="sidemenu"></div>
</div>
{{> "adLeaderboard" }}
{{> "navbar" }}
<div class="view-col-wrapper">
<div class="view-col">
<h3 class="conv__head">Input</h3>
<pre id="converter_input" class="inputArea ace_editor"></pre>
<div class="split-v-center">
<div id="wrp-footer-lhs" class="ve-flex-v-center"></div>
<div class="ve-flex-v-center btn-group">
<button id="parsestatblock" class="btn btn-sm btn-default">Parse</button>
<button id="parsestatblockadd" class="btn btn-sm btn-default">Parse and Add</button>
</div>
</div>
</div>
<div class="view-col">
<h3 class="conv__head">Output</h3>
<pre id="converter_output" class="outputArea ace_editor"></pre>
<div class="split-v-center conv__out_control__wrp">
<button id="editable" class="btn btn-sm btn-default">Enable Editing</button>
<div class="ve-flex-v-center">
<button id="preview" class="btn btn-sm btn-default mr-2">Preview</button>
<button id="save_local" class="btn btn-sm btn-default hidden mr-2">Save to Homebrew</button>
<div class="btn-group ve-flex-vh-center">
<button id="btn-output-copy" class="btn btn-sm btn-default">Copy</button>
<button id="btn-output-download" class="btn btn-sm btn-default">Download</button>
</div>
</div>
</div>
<div class="code mt-2 p-2 ve-flex-col ve-hidden conv__disp-message conv__disp-message--warning" id="lastWarnings"></div>
<div class="code mt-2 p-2 ve-flex-col ve-hidden conv__disp-message conv__disp-message--error" id="lastError"></div>
</div>
</div>
</div>
{{> "adFooter" }}
{{> "scripts" }}
</body>
</html>

View File

@@ -0,0 +1,257 @@
<!DOCTYPE html>
<html lang="en">
{{> "head" }}
<body>
{{> "overlayNoise" }}
{{> "adLeaderboard" }}
{{> "navbar" }}
{{> "adRhsScrollingPage" }}
<main class="container">
<form id="crcalc" autocomplete="off">
<div class="row">
<div class="col-sm-6">
<div id="croutput">Waiting for calculation...</div>
<button class="btn btn-sm btn-danger crc__reset mt-3" id="crcalc_reset" type="button">Reset</button>
<h4>Instructions</h4>
<ol>
<li>Enter expected CR of the creature.</li>
<li>Fill in the HP, AC, and other defensive attributes of the creature.</li>
<li>Fill in offensives attributes of the creature. DPR is averaged over three rounds!</li>
<li>Add any special Monster Features of creature.</li>
</ol>
<p>
<small>Be sure to read the <em>Dungeon Master's Guide</em> <a href="book.html#dmg,9,creating%20a%20monster,0">section on monster creation</a>, pages 273
through 283. You can click on the table to the right to fill in values for a given and adjust to
taste. You can hover over the individual labels for a short description of how each attribute
contributes to a monster's CR. You can also hover over each feature description to see how that
feature affects the calculations.
</small>
</p>
<hr>
<div class="crc__row">
<label for="expectedcr" class="ui-tip__parent" style="font-size: 1em;">
Expected CR:
<span class="explanation ui-tip__child">
CR calculation begins by determining what you want the final CR of the monster to be.
</span>
</label>
<span class="ve-flex-v-center">
<input type="text" id="expectedcr" value="0" size="2" class="form-control form-control--minimal input-xs">
</span>
</div>
</div>
<div class="col-sm-6 ve-text-center">
<h4>Monster Statistics by Challenge Rating</h4>
<table id="msbcr">
<tr>
<th>CR</th>
<th>XP</th>
<th>Prof.<br>Bonus</th>
<th>Armor<br>Class</th>
<th>Hit<br>Points</th>
<th>Attack<br>Bonus</th>
<th>Damage/<br>Round</th>
<th>Save<br>DC</th>
</tr>
</table>
</div>
</div>
<hr>
<div class="row">
<div class="col-sm-6">
<h4>Defensive</h4>
<div class="crc__row">
<label for="hp" class="ui-tip__parent">
Hit Points:
<span class="explanation ui-tip__child">
A creature's hit points determine its defensive CR before it is adjusted by its AC.
</span>
</label>
<input type="number" id="hp" placeholder="Average HP" value="1" min="0" max="850" class="form-control form-control--minimal input-xs">
</div>
<div class="crc__row">
<label for="ac" class="ui-tip__parent">
Armor Class:
<span class="explanation ui-tip__child">
A creature's AC adjusts its defensive CR.
</span>
</label>
<input type="number" id="ac" placeholder="AC" value="13" min="1" max="40" class="form-control form-control--minimal input-xs">
</div>
</div>
<div class="col-sm-6">
<h4>Offensive</h4>
<div class="crc__row">
<label for="dpr" class="ui-tip__parent">
Damage Per Round:
<span class="explanation ui-tip__child">
A creature's damage per round (DPR) determines its offensive CR, which is offset by its attack bonus or save DC. DPR is determined by averaging its maximum damage output (taking the average of dice rolls, ignoring critics and accuracy) over three rounds. Areas of effect are treated as though they hit two creatures, which fail any involved saving throws.
</span>
</label>
<input type="number" id="dpr" placeholder="Average DPR" value="1" min="0" max="320" class="form-control form-control--minimal input-xs">
</div>
<div class="crc__row">
<label for="attackbonus" class="ui-tip__parent">
Attack Bonus/Save DC:
<span class="explanation ui-tip__child">
A creature's attack bonus or save DC adjusts its offensive CR.
</span>
</label>
<input type="number" id="attackbonus" placeholder="Attack Bonus" value="3" min="-5" max="19" class="form-control form-control--minimal input-xs">
</div>
<div class="crc__row">
<label for="saveinstead" class="ui-tip__parent">
Use Saves?
<span class="explanation ui-tip__child">
If a creature's damage output is more dependent on save-based abilities, its save DC is used for adjusting its offensive CR instead of its attack bonus.
</span>
</label>
<input type="checkbox" id="saveinstead" value="0">
</div>
</div>
</div>
<hr>
<div class="row">
<div class="col-sm-6">
<div class="crc__row">
<label for="size" class="ui-tip__parent">
Size:
<span class="explanation ui-tip__child">
A creature's size determines the size of its individual hit dice.
</span>
</label>
<span class="ve-flex-v-center">
<select id="size" class="form-control input-xs">
<option value="Tiny">Tiny</option>
<option value="Small">Small</option>
<option value="Medium" selected>Medium</option>
<option value="Large">Large</option>
<option value="Huge">Huge</option>
<option value="Gargantuan">Gargantuan</option>
</select>
</span>
</div>
<div class="crc__row">
<label for="hd" class="ui-tip__parent">
Hit Dice:
<span class="explanation ui-tip__child">
Unlike player characters, the number of hit dice an NPC gets is completely arbitrary. Adjust this amount to taste.
</span>
</label>
<div class="ve-flex-v-center">
<input type="number" id="hd" value="1" min="1" max="999" class="form-control form-control--minimal input-xs">
<span id="hdval">d8</span>
</div>
</div>
<div class="crc__row">
<label for="con" class="ui-tip__parent">
Constitution:
<span class="explanation ui-tip__child">
A creature's HP is increases by its Constitution modifier for each hit die it has.
</span>
</label>
<input type="number" id="con" value="10" min="1" max="30" class="form-control form-control--minimal input-xs">
</div>
</div>
<div class="col-sm-6">
<div class="crc__row">
<label for="vulnerabilities" class="ui-tip__parent">
Vulnerabilities:
<span class="explanation ui-tip__child">
If a creature is vulnerable to common damage types (especially bludgeoning, piercing, and slashing damage), its effective hit points are halved.
</span>
</label>
<input type="checkbox" id="vulnerabilities" class="form-control form-control--minimal input-xs">
</div>
<div class="crc__row">
<label for="resistances" class="ui-tip__parent">
Resistances/Immunities:
<span class="explanation ui-tip__child">
A monster's HP is multiplied based on the resistances and immunities has to common damage types (non-magical bludgeoning, piercing, and slashing chief among them).
</span>
</label>
<span class="ve-flex-v-center">
<select id="resistances" class="form-control input-xs">
<option value="0" selected>None</option>
<option value="res">Resistances</option>
<option value="imm">Immunities</option>
</select>
</span>
</div>
<div class="crc__row">
<label for="flying" class="ui-tip__parent">
Flies and can deal damage at range (CR 0-9 only):
<span class="explanation ui-tip__child">
A monster's effective AC is increased by 2 if it can fly and deal damage at range, though only if its expected challenge rating is 10 or lower.
</span>
</label>
<input type="checkbox" id="flying">
</div>
<div class="crc__row">
<label for="saveprofs" class="ui-tip__parent">
Save Proficiencies:
<span class="explanation ui-tip__child">
Increase a creature's effective AC by 2 if it has 3 or 4 saving throw proficiencies, or by 4 if it has 5 or 6.
</span>
</label>
<span class="ve-flex-v-center">
<select id="saveprofs" class="form-control input-xs">
<option value="0" selected>0-2</option>
<option value="2">3-4</option>
<option value="4">5-6</option>
</select>
</span>
</div>
</div>
</div>
</form>
<hr>
<div class="row">
<div class="col-sm-12" id="monsterfeatures">
<h4>Monster Features</h4>
<div class="crc__hdr_mon_features ve-flex-v-center">
<div class="ve-col-1"></div>
<div class="ve-col-2">Name</div>
<div class="ve-col-2">Example Monster</div>
<div class="ve-col-7">Feature Description</div>
</div>
<div class="crc__wrp_mon_features">
<!-- populate with JS -->
</div>
<p>
<small><em>Note: Not all monster features are covered here. The DMG has specific instructions on how to
manage other features.</em></small>
</p>
</div>
</div>
</main>
{{> "adFooter" }}
{{> "scripts" }}
</body>
</html>

View File

@@ -0,0 +1,29 @@
<!DOCTYPE html>
<html lang="en">
{{> "head" }}
<body>
{{> "overlayNoise" }}
<div class="viewport-wrapper">
{{> "navbar" }}
<div class="dm-screen min-h-0">
<div class="sidemenu__toggle">
<div class="sidemenu__hotzone"></div>
<div class="sidemenu__burger"></div>
<div class="sidemenu__burger"></div>
<div class="sidemenu__burger"></div>
<div class="sidemenu"></div>
</div>
</div>
</div>
{{> "adFooter" }}
{{> "scripts" }}
</body>
</html>

View File

@@ -0,0 +1,191 @@
<!DOCTYPE html>
<html lang="en">
{{> "head" }}
<body>
{{> "overlayNoise" }}
{{> "navbar" }}
<div class="container">
<!--GITHUB_DISCLAIMER-->
<!-- <div class="alert alert-warning">-->
<!-- <p><strong>Discord update:</strong> A recent bot-hijack resulted in many accounts being banned from our Discord server, along with a general server reset. Besides bans, no user accounts were affected, and the server has largely been restored to its former state. <a class="alert-link" href="https://discord.gg/5etools" target="_blank" rel="noopener noreferrer">You can rejoin here.</a></p>-->
<!-- </div>-->
</div>
{{> "adRhsScrollingPage" }}
<div class="home__stripe">
<div class="home__split relative">
<div class="home__stripe-header text-right home__h-player"><div class="w-100 text-left mobile__text-center">Players</div></div>
<div class="ve-flex ve-flex-wrap relative home__split-spaced home__split-spaced--gutter home__split-spaced--no-header home__wrp-buttons">
<a class="home__btn-page btn btn-default mr-3 home__btn-player" href="races.html">
<div class="fal fa-users home__icn-page"></div>
<h4 class="ve-text-center home__lbl-page">Races</h4>
</a>
<a class="home__btn-page btn btn-default mr-3 home__btn-player" href="classes.html" title="Quickly browse the official classes, and their associated subclasses.
Unearthed Arcana content can be accessed by cycling the &quot;All Sources&quot; button.">
<div class="fal fa-hat-wizard home__icn-page"></div>
<h4 class="ve-text-center home__lbl-page">Classes</h4>
</a>
<a class="home__btn-page btn btn-default mr-3 home__btn-player" href="feats.html">
<div class="fal fa-award home__icn-page"></div>
<h4 class="ve-text-center home__lbl-page">Feats</h4>
</a>
<a class="home__btn-page btn btn-default home__btn-player" href="optionalfeatures.html" title="A searchable, filterable list of feature choices, including Eldritch Invocations for the Warlock Class, and Maneuvers for the Fighter's Battlemaster subclass.">
<div class="fal fa-drafting-compass home__icn-page"></div>
<h4 class="ve-text-center home__lbl-page">Options<br>&amp; Features</h4>
</a>
<!-- mobile only -->
<a class="home__btn-page btn btn-default home__narrow-visible home__btn-player" href="backgrounds.html">
<div class="fal fa-portrait home__icn-page"></div>
<h4 class="ve-text-center home__lbl-page">Backgrounds</h4>
</a>
<a class="home__btn-page btn btn-default home__narrow-visible home__btn-player" href="items.html">
<div class="fal fa-helmet-battle home__icn-page"></div>
<h4 class="ve-text-center home__lbl-page">Items</h4>
</a>
<a class="home__btn-page btn btn-default home__narrow-visible home__btn-player" href="spells.html">
<div class="fal fa-book-spells home__icn-page"></div>
<h4 class="ve-text-center home__lbl-page">Spells</h4>
</a>
<a class="home__btn-page btn btn-default home__narrow-visible home__btn-player" href="statgen.html">
<div class="fal fa-tally home__icn-page"></div>
<h4 class="ve-text-center home__lbl-page">Stat<br>Generator</h4>
</a>
</div>
<div class="ve-flex ve-flex-wrap home__wrp-buttons home__narrow-hidden">
<a class="home__btn-page btn btn-default mr-3 home__btn-player" href="backgrounds.html">
<div class="fal fa-portrait home__icn-page"></div>
<h4 class="ve-text-center home__lbl-page">Backgrounds</h4>
</a>
<a class="home__btn-page btn btn-default mr-3 home__btn-player" href="items.html">
<div class="fal fa-helmet-battle home__icn-page"></div>
<h4 class="ve-text-center home__lbl-page">Items</h4>
</a>
<a class="home__btn-page btn btn-default mr-3 home__btn-player" href="spells.html">
<div class="fal fa-book-spells home__icn-page"></div>
<h4 class="ve-text-center home__lbl-page">Spells</h4>
</a>
<a class="home__btn-page btn btn-default home__btn-player" href="statgen.html">
<div class="fal fa-tally home__icn-page"></div>
<h4 class="ve-text-center home__lbl-page">Stat<br>Generator</h4>
</a>
</div>
</div>
<div class="my-4 home__mobile-hidden home__narrow-hidden"></div>
<div class="my-4 home__mobile-hidden home__narrow-visible"></div>
<div class="my-4 home__mobile-hidden"></div>
<div class="home__split">
<div class="ve-flex ve-flex-wrap relative home__split-spaced home__split-spaced--gutter home__wrp-buttons">
<div class="home__stripe-header home__h-rule"><div class="w-100 text-left mobile__text-center">Rules</div></div>
<a class="home__btn-page btn btn-default mr-3 home__btn-rule" href="adventures.html" title="All the official adventures published by Wizards of the Coast.">
<div class="fal fa-dungeon home__icn-page"></div>
<h4 class="ve-text-center home__lbl-page">Adventures</h4>
</a>
<a class="home__btn-page btn btn-default mr-3 home__btn-rule" href="books.html" title="All the official sources published by Wizards of the Coast.">
<div class="fal fa-books home__icn-page"></div>
<h4 class="ve-text-center home__lbl-page">Books</h4>
</a>
<a class="home__btn-page btn btn-default mr-3 home__btn-rule" href="quickreference.html" title="A searchable selection of commonly used rules and tables.">
<div class="fal fa-info-square home__icn-page"></div>
<h4 class="ve-text-center home__lbl-page">Quick<br>Reference</h4>
</a>
<a class="home__btn-page btn btn-default home__btn-rule" href="conditionsdiseases.html" title="A searchable, filterable list of the conditions found in the Player's Handbook, and various diseases found in the Dungeon Master's Guide and beyond.">
<div class="fal fa-skull-crossbones home__icn-page"></div>
<h4 class="ve-text-center home__lbl-page">Conditions</h4>
</a>
</div>
<div class="my-4 home__mobile-visible"></div>
<div class="ve-flex ve-flex-wrap relative home__wrp-buttons">
<div class="home__stripe-header home__h-dm"><div class="w-100 text-left mobile__text-center">Dungeon Masters</div></div>
<a class="home__btn-page btn btn-default mr-3 home__btn-dm" href="bestiary.html" title="A searchable, filterable list of the more than 1,000 stat blocks in D&amp;D 5e. An encounter builder is included, and creature Challenge Rating can be scaled according to the &quot;Creating Quick Monster Stats&quot; table in the Dungeon Master's Guide.">
<div class="fal fa-dragon home__icn-page"></div>
<h4 class="ve-text-center home__lbl-page">Bestiary</h4>
</a>
<a class="home__btn-page btn btn-default mr-3 home__btn-dm" href="dmscreen.html" title="A fully-customizable Dungeon Master's screen, featuring an initiative tracker; a unit converter, embedded images, videos, and sites; and the majority of 5etools' content.">
<div class="fal fa-map home__icn-page"></div>
<h4 class="ve-text-center home__lbl-page">DM Screen</h4>
</a>
<a class="home__btn-page btn btn-default mr-3 home__btn-dm" href="lootgen.html" title="A random loot generator for both individual and hoards of treasure.">
<div class="fal fa-treasure-chest home__icn-page"></div>
<h4 class="ve-text-center home__lbl-page">Loot<br>Generator</h4>
</a>
<a class="home__btn-page btn btn-default home__btn-dm" href="crcalculator.html" title="A verbose, in-depth Challenge Rating calculator, for determining the CR of homebrew creatures.">
<div class="fal fa-abacus home__icn-page"></div>
<h4 class="ve-text-center home__lbl-page">CR<br>Calculator</h4>
</a>
</div>
</div>
<div class="my-4"></div>
<hr class="no-shrink w-100 my-0">
</div>
<main class="container">
{{> "adLeaderboard" }}
<div class="w-100">
<div class="mb-2" id="wrp-patreon"></div>
<h3>Use Discord?</h3>
<p>Join the <a href="https://discord.gg/5etools" target="_blank" rel="noopener noreferrer">fan server</a> for announcements, updates, and feature voting.</p>
<h3>Use <a href="https://foundryvtt.com/" rel="noopener">Foundry</a>?</h3>
<p>No? <span class="help" title="Please note that Foundry Gaming, LLC. and The Norr Group Ltd. are in no way affiliated, and that Foundry Gaming, LLC. does not condone the use of their software in violation of your local laws.">Well, you should!</span> Foundry is a modernized, better-than replacement for Roll20, which prioritizes modding support. It is the 5etools platform of choice for VTT integrations.</p>
<p>To install the <a href="plutonium.html">Plutonium</a> module, and start using all of 5etools' content in your game, paste the manifest URL<sup class="ve-small">[<a title="Plutonium manifest URL for most recent supported Foundry version" href="https://raw.githubusercontent.com/TheGiddyLimit/plutonium-next/master/module.json" target="_blank" rel="noopener noreferrer">current</a>/<a title="Plutonium manifest URL for Foundry v11" href="https://raw.githubusercontent.com/TheGiddyLimit/plutonium-next/master/module-foundry11.json" target="_blank" rel="noopener noreferrer">v11</a>/<a title="Plutonium manifest URL for Foundry v10" href="https://raw.githubusercontent.com/TheGiddyLimit/plutonium-next/master/module-foundry10.json" target="_blank" rel="noopener noreferrer">v10</a>]</sup> into your Foundry server's module installer. See the <a href="plutonium.html">Plutonium Features</a> page for an overview of the functionality the module provides.</p>
<p>You can also install the <a href="plutonium.html#rivet-browser-extension">Rivet</a> browser extension (<a rel="noopener noreferrer" href="https://chrome.google.com/webstore/detail/rivet/igmilfmbmkmpkjjgoabaagaoohhhbjde">Chrome</a>/<a rel="noopener noreferrer" href="https://addons.mozilla.org/en-GB/firefox/addon/rivet/">Firefox</a>) to import content from the site with a single click.</p>
<h3>Use Roll20?</h3>
<p>Install <a href="https://ssstormy.github.io/roll20-enhancement-suite/" rel="noopener noreferrer">
Roll20 Enhancement Suite</a> and Tampermonkey (<a
href="https://chrome.google.com/webstore/detail/tampermonkey/dhdgffkkebhmkfjojejmpbldmpobfkfo" rel="noopener noreferrer">Chrome</a>/<a
href="https://addons.mozilla.org/firefox/addon/tampermonkey/" rel="noopener noreferrer">Firefox</a>), and get the betteR20 script using
this <a href="https://github.com/TheGiddyLimit/betterR20/raw/development/dist/betteR20-5etools.user.js" id="betteR20_link" rel="noopener noreferrer">link</a>.</p>
<p>Check the <a href="https://wiki.tercept.net/en/betteR20" rel="noopener noreferrer">wiki</a> for an installation guide, and for information on how to use the script.</p>
<h3>FAQ</h3>
<p><b>Is there a wiki?</b> <a href="https://wiki.tercept.net/" rel="noopener noreferrer">Here.</a> Contributions are welcome.</p>
<p><b>Is it free?</b> Yes! You can even <a href="https://github.com/5etools-mirror-2/5etools-mirror-2.github.io/releases/latest" rel="noopener noreferrer">download the source code</a>. See the <code>README</code> or the <a href="https://wiki.tercept.net/en/5eTools/InstallGuide" rel="noopener noreferrer">wiki</a> for help.</p>
<p><b>Can I contribute?</b> The source is available on <a href="https://github.com/5etools-mirror-2/5etools-mirror-2.github.io" rel="noopener noreferrer">GitHub</a>. See the <a href="https://github.com/5etools-mirror-2/5etools-mirror-2.github.io/blob/main/CONTRIBUTING.md" rel="noopener noreferrer">Contributing</a> guidance.</p>
<p><b>Browser and device support?</b> The latest desktop versions of Chrome and Firefox.</p>
<p><b>Where's my stuff?</b> There's no account system. Everything is stored in cookies. If you wipe those, or close your incognito window, it's gone forever. You can download your data for safekeeping via the Settings menu.</p>
<p><b>Anything else I should know?</b> Hold <kbd>SHIFT</kbd> when hovering to lock a window in place. Everything has tooltips. You will forever be a DM.</p>
<h3>Self-Hosting</h3>
<p>You can host a copy of 5etools on anything that can run a basic webserver&mdash;examples include <a href="https://developer.mozilla.org/en-US/docs/Learn/Common_questions/set_up_a_local_testing_server" rel="noopener noreferrer">your computer</a>, <a href="https://play.google.com/store/apps/details?id=com.sylkat.apache" rel="noopener noreferrer">your phone</a>, a <a href="https://www.raspberrypi.org/products/" rel="noopener noreferrer">Raspberry Pi</a>, or a free <a href="https://aws.amazon.com/free" rel="noopener noreferrer">EC2</a>/<a href="https://cloud.google.com/free" rel="noopener noreferrer">Compute Engine</a> instance. <a href="https://github.com/5etools-mirror-2/5etools-mirror-2.github.io/releases/latest" rel="noopener noreferrer">Download the files</a> and <a href="https://github.com/5etools-mirror-2/5etools-img/releases/latest" rel="noopener noreferrer">images</a>, <a href="https://wiki.tercept.net/en/5eTools/InstallGuide" rel="noopener noreferrer">copy them into your server's root directory</a>, and enjoy!</p>
<h3 title=":^)">Disclaimer</h3>
<p title=":^)">5etools is intended as an easily-accessible digital reference for products you already own. Please ensure you only access content in accordance with your local laws.</p>
</div>
</main>
<footer class="container">
<p class="ve-text-center">
Version
<a id="version_number" href="#">?</a>
| <span style="text-decoration: red line-through">&nbsp;&copy;&nbsp;</span><span id="current_year">2019</span> 5etools
| <a href="privacy-policy.html">Privacy Policy</a>
<a id='unic-gdpr' onclick='__tcfapi("openunic");return false;' style='display:none;cursor:pointer;'>Change Ad Consent</a>
<a id='unic-ccpa' onclick="window.__uspapi('openunic')" style='display:none;cursor:pointer;'>Do not sell my data</a>
<br>
<i>5etools&reg; is a Registered Trademark of The Norr Group Ltd. All rights reserved.</i>
</p>
</footer>
<div class="cancer__footer-pad"></div>
{{> "adFooter" }}
{{> "scripts" }}
</body>
</html>

View File

@@ -0,0 +1,27 @@
<!DOCTYPE html>
<html lang="en">
{{> "head" }}
<body>
{{> "overlayNoise" }}
{{> "adRhs" }}
<div class="viewport-wrapper">
{{> "adLeaderboard" }}
{{> "navbar" }}
<main class="container h-100 min-h-0 pb-0" id="page-content">
<div class="flex-vh-center initial-message">Loading...</div>
</main>
</div>
{{> "adFooter" }}
{{> "scripts" }}
</body>
</html>

View File

@@ -0,0 +1,56 @@
<!DOCTYPE html>
<html lang="en">
{{> "head" }}
<body>
{{> "overlayNoise" }}
{{> "adRhs" }}
<div class="viewport-wrapper">
{{> "adLeaderboard" }}
{{> "navbar" }}
<div class="view-col-wrapper ve-flex-col px-4">
<div class="ve-flex-v-center mb-3">
<button class="btn btn-xs btn-default mr-2" id="btn__run">Run</button>
<button class="btn btn-xs btn-default mr-2" id="btn__validate">Validate</button>
<button class="btn btn-xs btn-default mr-2" id="btn__resolve_dynamics">Resolve Dynamics</button>
<button class="btn btn-xs btn-default mr-2" id="btn__validate_dynamics">Validate Dynamics</button>
<select class="form-control input-xs rlng__sel-sample" id="sel__sample"><option disabled value="-1">Select sample</option></select>
</div>
<div class="ve-flex w-100 h-100">
<div class="ve-flex-col w-33">
<div class="mb-2 small-caps">Input</div>
<div class="ve-flex-col h-100 w-100 ve-flex-1"><textarea id="ipt" class="w-100 h-100 form-control mb-2 code resize-none"></textarea></div>
<div class="mb-2 small-caps">Context</div>
<div class="ve-flex-col h-100 w-100 ve-flex-1" id="wrp_context"></div>
</div>
<div class="ve-flex-col w-33 px-2">
<div class="mb-2 small-caps">Lexed</div>
<div class="ve-flex-col h-100 w-100 ve-flex-1"><pre class="w-100 h-100 m-0 mb-2" id="out_lexed"></pre></div>
<div class="mb-2 small-caps">Parsed</div>
<div class="ve-flex-col h-100 w-100 ve-flex-1"><pre class="w-100 h-100 m-0" id="out_parsed"></pre></div>
</div>
<div class="ve-flex-col w-33 h-100 px-2">
<div class="mb-2 small-caps">Result</div>
<div class="w-100 h-100 ve-flex-vh-center rlng__output" id="out_result"></div>
</div>
</div>
</div>
</div>
{{> "adFooter" }}
{{> "scripts" }}
</body>
</html>

View File

@@ -0,0 +1,91 @@
<!DOCTYPE html>
<html lang="en">
{{> "head" }}
<body>
{{> "overlayNoise" }}
{{> "adLeaderboard" }}
{{> "navbar" }}
{{> "adRhsScrollingPage" }}
<main class="container">
<div class="ve-flex no-print">
<div class="form-group ve-col-2-4 mr-2">
<label for="race">Race</label>
<select class="form-control form-inline" id="race" disabled><option>Loading...</option></select>
</div>
<div class="form-group ve-col-2-4 mr-2">
<label for="cha">Charisma Modifier</label>
<select class="form-control form-inline" id="cha" disabled><option>Loading...</option></select>
</div>
<div class="form-group ve-col-2-4 mr-2">
<label for="race">Background</label>
<select class="form-control form-inline" id="background" disabled><option>Loading...</option></select>
</div>
<div class="form-group ve-col-2-4 mr-2">
<label for="race">Class</label>
<select class="form-control form-inline" id="class" disabled><option>Loading...</option></select>
</div>
<div class="form-group ve-col-2-4">
<label for="age"><i>Age</i></label>
<select class="form-control form-inline" id="age" disabled><option>Loading...</option></select>
</div>
</div>
<div class="ve-flex no-print">
<div class="form-group ve-col-12">
<button class="btn btn-default" onclick="pRoll()">Generate</button>
</div>
</div>
<div class="ve-flex-col no-print py-0 px-5">
<p>Based on the tables and rules in <a href="#" id="xge_link">Xanathar's Guide to Everything</a>, pages 61-73.</p>
<p><i>NOTE: Text displayed in italics is generated for the sake of ease and speed of use, and does not correspond to a table in the original generator. Ignore it as you see fit.</i></p>
</div>
<hr class="life__output" style="display: none; background: transparent">
<div class="ve-flex-col life__output night__shadow-big ve-hidden">
<div class="wrp-sect-head"><h4>Parents</h4><button class="btn btn-xs btn-default btn-reroll" onclick="pSectParents()"></button></div>
<p id="parents"></p>
</div>
<div class="ve-flex-col life__output night__shadow-big ve-hidden">
<div class="wrp-sect-head"><h4>Birthplace</h4><button class="btn btn-xs btn-default btn-reroll" onclick="sectBirthplace()"></button></div>
<p id="birthplace"></p>
</div>
<div class="ve-flex-col life__output night__shadow-big ve-hidden">
<div class="wrp-sect-head"><h4>Siblings</h4><button class="btn btn-xs btn-default btn-reroll" onclick="pSectSiblings()"></button></div>
<p id="siblings"></p>
</div>
<div class="ve-flex-col life__output night__shadow-big ve-hidden">
<div class="wrp-sect-head"><h4>Family and Friends</h4><button class="btn btn-xs btn-default btn-reroll" onclick="sectFamily()"></button></div>
<p id="family"></p>
</div>
<div class="ve-flex-col life__output night__shadow-big ve-hidden">
<div class="wrp-sect-head"><h4>Personal Decisions</h4><button class="btn btn-xs btn-default btn-reroll" onclick="sectPersonalDecisions()"></button></div>
<p id="personal"></p>
</div>
<div class="ve-flex-col life__output night__shadow-big ve-hidden">
<div class="wrp-sect-head"><h4>Class Training</h4><button class="btn btn-xs btn-default btn-reroll" onclick="sectClassTraining()"></button></div>
<p id="clss"></p>
</div>
<div class="ve-flex-col life__output night__shadow-big ve-hidden">
<div class="wrp-sect-head"><h4>Life Events</h4><button class="btn btn-xs btn-default btn-reroll" onclick="sectLifeEvents()"></button></div>
<p id="events"></p>
</div>
</main>
{{> "adFooter" }}
{{> "scripts" }}
</body>
</html>

View File

@@ -0,0 +1,35 @@
<!DOCTYPE html>
<html lang="en">
{{> "head" }}
<body>
{{> "overlayNoise" }}
{{> "adRhs" }}
<div class="viewport-wrapper">
{{> "adLeaderboard" }}
{{> "navbar" }}
<div class="view-col-group--cancer h-100 mh-0">
<div class="py-2 ve-flex-vh-center initial-message initial-message--large h-100" id="wrp-loading">Loading...</div>
<div class="container view-col-wrapper view-col-wrapper--cancer ve-hidden" id="wrp-content">
<div class="view-col ve-flex-4 mb-0" id="lootgen-lhs"></div>
<div class="cancer__wrp-mobile-1 cancer__anchor"><div class="cancer__disp-cancer"></div><!--5ETOOLS_AD_MOB_PLAYER_1--></div>
<div class="view-col ve-flex-6" id="lootgen-rhs"></div>
</div>
</div>
</div>
{{> "adFooter" }}
{{> "scripts" }}
</body>
</html>

View File

@@ -0,0 +1,46 @@
<!DOCTYPE html>
<html lang="en">
{{> "head" }}
<body>
{{> "overlayNoise" }}
{{> "adRhs" }}
<div class="viewport-wrapper">
<div class="sidemenu__toggle" style="display: none;">
<div class="sidemenu__hotzone"></div>
<div class="sidemenu__burger"></div>
<div class="sidemenu__burger"></div>
<div class="sidemenu__burger"></div>
<div class="sidemenu"></div>
</div>
{{> "adLeaderboard" }}
{{> "navbar" }}
<div id="page_loading" class="container view-col-wrapper">
<div class="h-100 w-100 ve-flex-vh-center"><span class="initial-message">Loading...</span></div>
</div>
<div id="page_source" class="container view-col-wrapper" style="display: none"></div>
<div id="page_main" class="container view-col-wrapper" style="display: none">
<div class="view-col">
<div id="content_input"></div>
<div id="content_input_controls" class="ve-text-center"></div>
</div>
<div class="view-col" id="content_output"></div>
</div>
</div>
{{> "adFooter" }}
{{> "scripts" }}
</body>
</html>

View File

@@ -0,0 +1,35 @@
<!DOCTYPE html>
<html lang="en">
{{> "head" }}
<body>
{{> "overlayNoise" }}
{{> "adRhs" }}
<div class="viewport-wrapper">
{{> "adLeaderboard" }}
{{> "navbar" }}
<div class="container view-col-wrapper mt-2">
<div class="view-col ve-overflow-y-auto" style="flex: 3;">
<p>This tool can be used to create data compatible with the <a href="https://rpg-cards.vercel.app" rel="noopener noreferrer">RPG Cards</a> app.</p>
<p>Icons are taken from the open-source <i>RPG Cards</i> code, which is in turn sources icons from <a href="https://game-icons.net/" rel="noopener noreferrer">Game-icons.net</a>. Most of the icons available there should be available here.</p>
<hr class="hr-0">
<h4>Configuration</h4>
<div id="wrp_config"></div>
</div>
<div id="wrp_main" class="view-col ve-flex-col" style="flex: 7;"></div>
</div>
</div>
{{> "adFooter" }}
{{> "scripts" }}
</body>
</html>

View File

@@ -0,0 +1,27 @@
<!DOCTYPE html>
<html lang="en">
{{> "head" }}
<body>
{{> "overlayNoise" }}
<div class="viewport-wrapper ve-flex-col">
{{> "adLeaderboard" }}
{{> "navbar" }}
<div id="content" class="maps ve-flex h-100 mobile__h-initial mobile__ve-flex-col min-h-0">
<div class="ve-flex-vh-center h-100 w-100">
<div class="ve-flex initial-message initial-message--large px-3">Loading...</div>
</div>
</div>
</div>
{{> "adFooter" }}
{{> "scripts" }}
</body>
</html>

View File

@@ -0,0 +1,95 @@
<!DOCTYPE html>
<html lang="en">
{{> "head" }}
<body>
{{> "overlayNoise" }}
{{> "adLeaderboard" }}
{{> "navbar" }}
{{> "adRhsScrollingPage" }}
<main class="container">
<div class="row">
<div class="ve-col-12">
<p>An overview of the features available in Plutonium can be found below. To those familiar with our now-deprecated Roll20 script &quot;betteR20,&quot; we aim to expand on the feature set it provided, while improving user experience.</p>
<p><b>Please note that the videos on this page are updated much less frequently than the module itself.</b> For a (more) complete list of Plutonium's features, see <a href="https://wiki.tercept.net/en/Plutonium" rel="noopener noreferrer">the wiki</a>.</p>
<hr>
<h3>Importing</h3>
<p>The module can import content to the sidebar, to a compendium, or to a character sheet. It can import most content found in 5etools, including:</p>
<ul>
<li>Classes and Subclasses, Backgrounds, Races, Feats, and other character options</li>
<li>Creatures, Spells and Items</li>
<li>Adventures, Books, and Tables</li>
</ul>
<p>By default, the module imports data provided by 5etools, but also includes the option to import from the <a href="https://github.com/TheGiddyLimit/homebrew" rel="noopener noreferrer">homebrew repository</a>, the <a href="https://github.com/TheGiddyLimit/unearthed-arcana" rel="noopener noreferrer">prerelease repository</a>, URLs, and file uploads.</p>
<h4>Importing Creatures</h4>
<a href="img/plutonium/creatures.gif" target="_blank" id="wrp-img-creatures"></a>
<h4>Importing Spells to a Character Sheet</h4>
<a href="img/plutonium/sheet-spells.gif" target="_blank" id="wrp-img-sheet-spells"></a>
<h4>Importing Tables</h4>
<a href="img/plutonium/tables.gif" target="_blank" id="wrp-img-tables"></a>
<hr>
<h3 id="rivet-browser-extension">Rivet Browser Extension</h3>
<p>With Rivet installed, and provided you have 5etools and Foundry open in the same browser, you can send content and rolls from 5etools straight to your Foundry game with the click of a button.</p>
<h4>Send to Foundry</h4>
<a href="img/plutonium/rivet.gif" target="_blank" id="wrp-img-rivet"></a>
<hr>
<h3>Quality of Life Tools</h3>
<p>The module includes a selection of tools to streamline the VTT experience.</p>
<h4>Journal Cleaner</h4>
<a href="img/plutonium/cleaner.gif" target="_blank" title="Sadly incapable of cleaning crappy GIF encoding." id="wrp-img-cleaner"></a>
<h4>Journal Bulk Item Mover</h4>
<a href="img/plutonium/mover.gif" target="_blank" id="wrp-img-mover"></a>
<h4>Mass &quot;Spell Prepared&quot; Toggler</h4>
<a href="img/plutonium/sheet-spell-toggler.gif" target="_blank" id="wrp-img-sheet-spell-toggler"></a>
<hr>
<h3>Customization Options</h3>
<p>Plutonium is designed to be easily configurable, and contains a wide selection of options enable user customization.</p>
<h4>Import Folder Specification</h4>
<a href="img/plutonium/folder.gif" target="_blank" id="wrp-img-folder"></a>
<h4>Configuration Options</h4>
<a href="img/plutonium/config.webp" target="_blank" id="wrp-img-config"></a>
<hr>
<h3>Foundry UI Enhancements</h3>
<p>While overhauling the Foundry user experience is not one of Plutonium's goals, a handful of optional tweaks have been included. These include:</p>
<ul>
<li>Red colorization of &quot;Delete&quot; icons, improving glance value</li>
<li>Faster animations, removing a layer of artificial delay between input and action</li>
<li>Reworked ESC key, to provide an &quot;escape last&quot; function rather than an &quot;escape all&quot; function</li>
</ul>
<div class="ve-flex">
<div class="ve-flex-col px-3">
<h4>Compact Directory Styling</h4>
<a href="img/plutonium/compact-directory.webp" target="_blank" id="wrp-img-compact-directory"></a>
</div>
<div class="ve-flex-col px-3">
<h4>Compact Chat Styling</h4>
<a href="img/plutonium/compact-chat.webp" target="_blank" id="wrp-img-compact-chat"></a>
</div>
</div>
</div>
</div>
</main>
{{> "adFooter" }}
{{> "scripts" }}
</body>
</html>

View File

@@ -0,0 +1,35 @@
<!DOCTYPE html>
<html lang="en">
{{> "head" }}
<body>
{{> "overlayNoise" }}
{{> "adLeaderboard" }}
{{> "navbar" }}
{{> "adRhsScrollingPage" }}
<main class="container">
<div class="row">
<div class="ve-col-12">
<p>The Norr Group Ltd. and its affiliates (collectively &ldquo;Norr Group&rdquo;, &ldquo;we&rdquo; and &ldquo;us&rdquo;) respect your privacy. <br>We do not require that you provide, nor do we collect, any personal information if you are just browsing the Site. We may offer certain functionality and services, such as accessing future services and submitting content (eg product reviews, comments, metadata) that may require you provide certain personal information or may in which in the process of submitting such content inadvertently supply us with personal information. We will not disclose your personal information to any third party unless: 1) it is necessary in order to provide you with a particular Service you have requested; 2) it is required of us in order to comply with a legal process in any applicable jurisdiction (e.g., court order, subpoena, search warrant, law enforcement request); 3) Norr Group determines, in its sole discretion, that disclosure is necessary to protect the rights, property, and safety of Norr Group, its subsidiaries, affiliates, co-brand partners or other parties under contract with Norr Group, our users, or others; or 4) you have provided such data through a partner's site hosted by us, in which case we may provide your personal data to that partner (Norr Group is not responsible for its partners' privacy policies or their use, storage and processing of data collected on their web sites).</p>
<p>In certain instances, we may request that you provide secondary information (e.g., demographic information), which we may use, for example, to learn more about our customers and to develop and improve our services. We may compile your personal information with that collected from other customers to create aggregate data. Aggregate data is information about groups of customers and, once compiled, will in no way identify you as an individual. We may disclose aggregate data to our business affiliates, advertisers, and other parties.</p>
<p>Our web servers collect from Site visitors&rsquo; statistical information regarding what pages are visited, the date and time of the visits, how long it took a user to download a page, and the TCP/IP address of the user. These automated server functions do not collect this information in a manner intended to identify your individual use of the Site. This information is collected to assist us in maintaining a high quality site, provide necessary traffic information to our advertisers and tune our website to provide a better experience for each user. We currently contract with several online partners to help manage and optimize our Internet business and communications. In order to learn more about our users and what services and feature are most attractive to our visitors we utilize cookies to assist us in collecting relevant site usage info by our visitors. We also utilizes the assistance of third party tools to understand how its site is being used (including Google Analytics, Google Adsense, etc.) and these parties may utilize cookie technology to ascertain how the Site is being accessed by visitors.</p>
<p>In conjunction with our in-house advertising, we use third-party advertising companies to place customized advertisements on the pages you view on the Site (eg Google Adsense). Our third-party advertising companies also separately place or recognize a cookie file on your browser in the course of delivering advertisements to the Site. These companies may use non-personal information collected by the cookies about your visits to the Site and other web sites in order to provide you with advertisements about goods and services of interest to you.</p>
<p>The Site contains links to web sites of third parties. Norr Group is not responsible for the actions of these third parties, including their privacy practices and any content posted on their web sites. We encourage you to review their privacy policies to learn more about what, why and how they collect and use personal information. Norr Group adheres to industry recognized standards to secure any personal information in our possession, and to secure it from unauthorized access and tampering. However, as is true with all online actions, it is possible that third parties may unlawfully intercept transmissions of personal information, or other users of the Site may misuse or abuse your personal information that they may collect from the Site.</p>
<p>We uses third-party advertising companies to serve our ads and collect information when users visit the Site. These third-party advertising companies employ cookie and 1x1 pixel .gifs or web beacons to measure and improve the effectiveness of ads for their clients. These companies may use information (not including your name, address, email address or telephone number) about your visits to our website and other websites in order to provide advertisements on our site, other websites and other forms of media about goods and services of interest to you. If you would like more information about this practice and to know your choices about not having this information used by these companies, check out <a href="http://www.networkadvertising.org/managing/opt_out.asp">http://www.networkadvertising.org/managing/opt_out.asp</a>.</p>
</div>
</div>
</main>
{{> "adFooter" }}
{{> "scripts" }}
</body>
</html>

View File

@@ -0,0 +1,16 @@
<!DOCTYPE html>
<html lang="en">
{{> "head" }}
<body>
{{> "overlayNoise" }}
<main class="container ve-flex-vh-center w-100w h-100h">
<h3>
Click <a href="{{redirectHref}}">here</a> to be redirected to {{redirectMessage}}.
</h3>
</main>
</body>
</html>

View File

@@ -0,0 +1,45 @@
<!DOCTYPE html>
<html lang="en">
{{> "head" }}
<body>
{{> "overlayNoise" }}
{{> "adRhs" }}
<div class="viewport-wrapper">
{{> "adLeaderboard" }}
{{> "navbar" }}
<div class="view-col-wrapper">
<div class="view-col no-print" id="wrp-jsoninput">
<pre id="jsoninput" class="inputArea ace_editor"></pre>
<div class="ve-flex-h-right">
<select class="form-control input-sm mr-2" id="demoSelectRenderer">
<option value="html">HTML</option>
<option value="md">Markdown</option>
<option value="cards">RPG Cards</option>
</select>
<button class="btn btn-default btn-sm mr-2" id="demoRender">Render</button>
<button class="btn btn-default btn-sm" id="demoReset">Reset</button>
<span id="message"></span>
</div>
</div>
<div id="wrp-output" class="view-col">
<table id="pagecontent" class="w-100 stats">
<!-- populate with JS -->
</table>
</div>
</div>
</div>
{{> "adFooter" }}
{{> "scripts" }}
</body>
</html>

View File

@@ -0,0 +1,23 @@
<!DOCTYPE html>
<html lang="en">
{{> "head" }}
<body>
{{> "overlayNoise" }}
{{> "adLeaderboard" }}
{{> "navbar" }}
{{> "adRhsScrollingPage" }}
<main class="container" id="main_content"><div class="ve-flex-vh-center initial-message w-100 h-100">Loading...</div></main>
{{> "adFooter" }}
{{> "scripts" }}
</body>
</html>

View File

@@ -0,0 +1,29 @@
<!DOCTYPE html>
<html lang="en">
{{> "head" }}
<body>
{{> "overlayNoise" }}
{{> "adRhs" }}
<div class="viewport-wrapper">
{{> "adLeaderboard" }}
{{> "navbar" }}
<div class="container container--main h-100 min-h-0">
<div class="ve-flex-col w-100 h-100 pt-2" id="statgen-main">
<div class="ve-flex-vh-center initial-message initial-message--large w-100 h-100">Loading...</div>
</div>
</div>
</div>
{{> "adFooter" }}
{{> "scripts" }}
</body>
</html>

View File

@@ -1,31 +1,29 @@
<script type="text/javascript" src="lib/jquery.js"></script>
{{#each scriptsLibAdditional}}<script type="text/javascript" src="lib/{{this}}"></script>
{{/each}}
{{#each scriptsLibAdditionalRemote}}<script type="text/javascript" src="{{this}}"></script>
{{/each}}
<script type="text/javascript" src="js/parser.js"></script>
<script type="text/javascript" src="js/utils.js"></script>
<script type="text/javascript" src="js/utils-ui.js"></script>
<script type="text/javascript" src="js/utils-list.js"></script>
{{#each scriptsUtilsAdditional}}<script type="text/javascript" src="js/{{this}}"></script>
{{/each}}
<script type="text/javascript" src="lib/localforage.js"></script>
<script type="text/javascript" src="js/omnidexer.js"></script>
<script type="text/javascript" src="js/omnisearch.js"></script>
<script type="text/javascript" src="js/filter.js"></script>
<script type="text/javascript" src="js/utils-dataloader.js"></script>
<script type="text/javascript" src="js/utils-brew.js"></script>
<script type="module" src="js/utils-config.js"></script>
{{#each scriptsUtilsAdditional}}<script type="text/javascript" src="js/{{this}}"></script>
{{/each}}
<script type="text/javascript" src="js/render.js"></script>
<script type="text/javascript" src="js/render-dice.js"></script>
<script type="text/javascript" src="js/render-markdown.js"></script>
<script type="text/javascript" src="js/render-{{scriptIdentList}}.js"></script>
{{#each scriptsRenderAdditional}}<script type="text/javascript" src="js/{{this}}"></script>
{{/each}}
<script type="text/javascript" src="js/scalecreature.js"></script>
<script type="text/javascript" src="js/hist.js"></script>
<script type="text/javascript" src="js/listpage.js"></script>
{{#if isMultisource}}<script type="text/javascript" src="js/multisource.js"></script>
{{/if}}
<script type="text/javascript" src="js/filter-common.js"></script>
<script type="text/javascript" src="js/filter-{{scriptIdentList}}.js"></script>
{{#each scriptsPrePageAdditional}}<script type="text/javascript" src="js/{{this}}"></script>
{{#each scripts}}<script type="text/javascript" src="js/{{this}}"></script>
{{/each}}
{{#each scriptsModules}}<script type="module" src="js/{{this}}"></script>
{{/each}}
{{#if isModule}}<script type="module" src="js/{{scriptIdentList}}.js"></script>
{{else}}<script type="text/javascript" src="js/{{scriptIdentList}}.js"></script>
{{/if}}
<script type="text/javascript" src="js/list2.js"></script>
<script type="text/javascript" src="lib/elasticlunr.js"></script>

View File

@@ -0,0 +1,47 @@
<!DOCTYPE html>
<html lang="en">
{{> "head" }}
<body>
{{> "overlayNoise" }}
{{> "adRhs" }}
<div class="viewport-wrapper">
{{> "adLeaderboard" }}
{{> "navbar" }}
<div class="container view-col-wrapper">
<div class="view-col" id="listcontainer">
<div class="input-group btn-group search-box ve-flex">
<div class="w-100 relative">
<input type="search" id="lst__search" autocomplete="off" autocapitalize="off" spellcheck="false" class="search form-control lst__search br-0">
<div id="lst__search-glass" class="lst__wrp-search-glass no-events ve-flex-vh-center"><span class="glyphicon glyphicon-search"></span></div>
</div>
<button class="btn btn-default reset" id="reset" type="button">Reset</button>
</div>
<div class="flex-col ve-overflow-y-scroll min-h-0 pr-2" data-name="tablepage-wrp-list">
<!-- populate with JS -->
</div>
</div>
<div class="view-col" id="tablecontainer">
<div class="rolltable" id="contentwrapper">
<table id="pagecontent" class="w-100 stats stats--book stats--book-large">
<!-- populate with JS -->
</table>
</div>
</div>
</div>
</div>
{{> "adFooter" }}
{{> "scripts" }}
</body>
</html>