diff --git a/gulpfile.js b/gulpfile.js new file mode 100644 index 00000000..93c23404 --- /dev/null +++ b/gulpfile.js @@ -0,0 +1,32 @@ +const gulp = require('gulp'); +const less = require('gulp-less'); + +/* ----------------------------------------- */ +/* Compile LESS +/* ----------------------------------------- */ + +const SW5E_LESS = ["less/*.less"]; +function compileLESS() { + return gulp.src("less/sw5e.less") + .pipe(less()) + .pipe(gulp.dest("./")) +} +const css = gulp.series(compileLESS); + +/* ----------------------------------------- */ +/* Watch Updates +/* ----------------------------------------- */ + +function watchUpdates() { + gulp.watch(SW5E_LESS, css); +} + +/* ----------------------------------------- */ +/* Export Tasks +/* ----------------------------------------- */ + +exports.default = gulp.series( + gulp.parallel(css), + watchUpdates +); +exports.css = css; diff --git a/sw5e.css b/sw5e.css new file mode 100644 index 00000000..01491268 --- /dev/null +++ b/sw5e.css @@ -0,0 +1,1369 @@ +/* Deprecated vars */ +/* ----------------------------------------- */ +/* Fonts */ +/* ----------------------------------------- */ +@font-face { + font-family: "Nodesto"; + src: url("fonts/NodestoCapsCondensed.otf"); +} +.nodesto { + font-family: "Nodesto", "Signika", "Palatino Linotype", serif; + font-size: 20px; +} +/* ----------------------------------------- */ +/* Sheet Styles */ +/* ----------------------------------------- */ +/* ----------------------------------------- */ +/* Flexbox */ +/* ----------------------------------------- */ +.flexrow { + display: flex; + flex-direction: row; + flex-wrap: wrap; + justify-content: flex-start; +} +.flexrow > * { + flex: 1; +} +.flexrow .flex1 { + flex: 1; +} +.flexrow .flex2 { + flex: 2; +} +.flexrow .flex3 { + flex: 3; +} +.flexrow .flex4 { + flex: 4; +} +.flexcol { + display: flex; + flex-direction: column; + flex-wrap: nowrap; +} +.flexcol > * { + flex: 1; +} +.flexcol .flex1 { + flex: 1; +} +.flexcol .flex2 { + flex: 2; +} +.flexcol .flex3 { + flex: 3; +} +.flexcol .flex4 { + flex: 4; +} +/* ----------------------------------------- */ +/* All SW5e Apps */ +/* ----------------------------------------- */ +.sw5e { + /* ----------------------------------------- */ + /* Element Styles */ + /* ----------------------------------------- */ + /* Form Groups */ + /* Tags */ +} +.sw5e .window-content { + background: url("ui/parchment.jpg") repeat; + font-size: 13px; + color: #191813; +} +.sw5e input[type="text"], +.sw5e select { + height: calc(100% - 2px); + border: 1px solid #7a7971; + background: rgba(0, 0, 0, 0.05); + color: #191813; +} +.sw5e input[type="text"]:hover, +.sw5e input[type="text"]:focus { + border: 1px solid #111; + box-shadow: 0 0 8px red; +} +.sw5e input:disabled, +.sw5e select:disabled, +.sw5e textarea:disabled { + color: #4b4a44; +} +.sw5e input:disabled:hover, +.sw5e select:disabled:hover, +.sw5e textarea:disabled:hover, +.sw5e input:disabled:focus, +.sw5e select:disabled:focus, +.sw5e textarea:disabled:focus { + box-shadow: none !important; + border: 1px solid transparent !important; + outline: none !important; +} +.sw5e button { + background: rgba(0, 0, 0, 0.1); + border: 2px groove #eeede0; +} +.sw5e label.checkbox { + flex: auto; + margin: 0; + line-height: 20px; + font-size: 11px; + text-align: right; +} +.sw5e label.checkbox input[type="checkbox"] { + height: auto; + margin: 0 5px 0; + position: relative; + top: 3px; +} +.sw5e .form-group label { + flex: 2; + color: #4b4a44; + font-weight: bold; +} +.sw5e .form-group .form-fields { + display: flex; + flex-direction: row; + flex-wrap: wrap; + justify-content: flex-start; +} +.sw5e .form-group .form-fields > * { + flex: 1; +} +.sw5e .form-group .form-fields .flex1 { + flex: 1; +} +.sw5e .form-group .form-fields .flex2 { + flex: 2; +} +.sw5e .form-group .form-fields .flex3 { + flex: 3; +} +.sw5e .form-group .form-fields .flex4 { + flex: 4; +} +.sw5e .form-group .form-fields > * { + margin: 0 3px 0 0; +} +.sw5e .form-group .form-fields > *:last-child { + margin-right: 0; +} +.sw5e .form-group.stacked label { + flex: 0 0 100%; + margin: 0; +} +.sw5e .form-group.stacked label.checkbox { + flex: auto; + text-align: left; +} +.sw5e .form-header { + margin: 0 0 0.25em 0; + padding: 0 2px; + font-family: "Nodesto", "Signika", "Palatino Linotype", serif; + font-size: 20px; + font-size: 24px; + border-top: 2px groove #eeede0; + border-bottom: 2px groove #eeede0; +} +.sw5e .tag { + display: inline-block; + margin: 0 2px 0 0; + padding: 0 3px; + font-size: 10px; + line-height: 16px; + border: 1px solid #999; + border-radius: 3px; + background: rgba(0, 0, 0, 0.05); +} +/* ----------------------------------------- */ +/* Entity Sheets Specifically */ +/* ----------------------------------------- */ +.sw5e.sheet { + /* ----------------------------------------- */ + /* Element Styles */ + /* ----------------------------------------- */ + /* ----------------------------------------- */ + /* TinyMCE */ + /* ----------------------------------------- */ + /* ----------------------------------------- */ + /* Sheet Header */ + /* ----------------------------------------- */ + /* ----------------------------------------- */ + /* Sheet Navigation */ + /* ----------------------------------------- */ + /* ----------------------------------------- */ + /* Sheet Body */ + /* ----------------------------------------- */ + /* ----------------------------------------- */ + /* List Filters */ + /* ----------------------------------------- */ + /* ----------------------------------------- */ + /* Trait Lists */ + /* ----------------------------------------- */ +} +.sw5e.sheet .window-content { + overflow-y: hidden; + padding: 5px; + background: url("ui/parchment.jpg") repeat; + font-size: 13px; + color: #191813; +} +.sw5e.sheet .window-content form { + height: 100%; + overflow: hidden; +} +.sw5e.sheet .window-content .tab { + height: 100%; + overflow-y: auto; + align-content: flex-start; +} +.sw5e.sheet input[type="text"] { + background: none; + border: 1px solid transparent; +} +.sw5e.sheet input[type="text"]:hover, +.sw5e.sheet input[type="text"]:focus { + border: 1px solid #111; +} +.sw5e.sheet select { + flex: 1; + font-size: 12px; + height: 22px; + background: transparent; +} +.sw5e.sheet .editable .rollable:hover { + color: #000; + text-shadow: 0 0 10px red; + cursor: pointer; +} +.sw5e.sheet .editor { + height: 100%; +} +.sw5e.sheet .editor .tox-toolbar-overlord, +.sw5e.sheet .editor .tox-toolbar__primary { + background: none; +} +.sw5e.sheet .sheet-header { + flex: 0 0 100px; + border-bottom: 2px groove #eeede0; + font-family: "Nodesto", "Signika", "Palatino Linotype", serif; + font-size: 20px; + /* Character Name */ + /* Profile Image */ + /* Header Summary Details */ +} +.sw5e.sheet .sheet-header h1 { + flex: 1; + border-bottom: none; + height: 60px; + margin: 0; + padding: 5px; +} +.sw5e.sheet .sheet-header h1 input { + height: 50px; + font-size: 36px; +} +.sw5e.sheet .sheet-header img.profile { + flex: 0 0 100px; + max-width: 100px; + height: 100px; + object-fit: cover; + border: none; + border-right: 2px groove #eeede0; +} +.sw5e.sheet .sheet-header .summary { + flex: 0 0 100%; + height: 40px; + margin: 0; + padding: 0; + list-style: none; + border-top: 2px groove #eeede0; + border-bottom: none; +} +.sw5e.sheet .sheet-header .summary li { + width: 33.33%; + float: left; + height: 34px; + margin: 2px 0; + padding: 0 3px; + border-right: 2px groove #eeede0; + line-height: 34px; + color: #4b4a44; +} +.sw5e.sheet .sheet-header .summary li:last-child { + border-right: none; +} +.sw5e.sheet .sheet-navigation { + flex: 0 0 30px; + margin-bottom: 5px; + font-family: "Nodesto", "Signika", "Palatino Linotype", serif; + font-size: 20px; +} +.sw5e.sheet .sheet-navigation .item { + height: 30px; + line-height: 32px; + margin: 0 24px; + border-bottom: 3px solid #b5b3a4; +} +.sw5e.sheet .sheet-navigation .item.active { + border-bottom: 3px solid #44191A; +} +.sw5e.sheet .sheet-body { + flex: 1; + overflow: hidden; +} +.sw5e.sheet .filter-list { + list-style: none; + margin: 0; + padding: 0; + line-height: 16px; +} +.sw5e.sheet .filter-list .filter-title { + flex: 3; +} +.sw5e.sheet .filter-list .filter-item { + text-align: center; + font-size: 12px; + margin: 0 6px; + border-bottom: 3px solid #b5b3a4; + white-space: nowrap; +} +.sw5e.sheet .filter-list .filter-item:hover { + text-shadow: 0 0 4px red; + border-bottom: 3px solid #7a7971; +} +.sw5e.sheet .filter-list .filter-item.active { + border-bottom: 3px solid #44191A; +} +.sw5e.sheet .trait-selector { + flex: 0 0 16px; + padding: 2px 0; + color: #999; + font-size: 10px; +} +.sw5e.sheet .traits-list { + line-height: 20px; + list-style: none; + margin: 0; + padding: 0; + text-align: right; +} +/* ----------------------------------------- */ +/* Trait Selector +/* ----------------------------------------- */ +#trait-selector .trait-list { + list-style: none; + margin: 0; + padding: 0; +} +#trait-selector input[type="text"] { + height: 24px; + margin: 2px; +} +.sw5e.sheet.actor { + /* ----------------------------------------- */ + /* Sheet Header */ + /* ----------------------------------------- */ + /* ----------------------------------------- */ + /* General Styles */ + /* ----------------------------------------- */ + /* ----------------------------------------- */ + /* Attributes */ + /* ----------------------------------------- */ + /* ----------------------------------------- */ + /* Ability Scores */ + /* ----------------------------------------- */ + /* ----------------------------------------- */ + /* Skills */ + /* ----------------------------------------- */ + /* ----------------------------------------- */ + /* Statuses */ + /* ----------------------------------------- */ + /* ----------------------------------------- */ + /* Traits */ + /* ----------------------------------------- */ + /* ----------------------------------------- */ + /* Inventory Lists */ + /* ----------------------------------------- */ + /* Inventory List Filters */ + /* ----------------------------------------- */ + /* Powerbook */ + /* ----------------------------------------- */ + /* ----------------------------------------- */ + /* TinyMCE */ + /* ----------------------------------------- */ +} +.sw5e.sheet.actor .sheet-header .charlevel { + flex: 0 0 160px; + height: 60px; + margin: 0; + padding: 5px; + text-align: right; +} +.sw5e.sheet.actor .sheet-header .charlevel .level { + width: 100%; + height: 30px; + font-size: 20px; + line-height: 30px; +} +.sw5e.sheet.actor .sheet-header .charlevel .level label { + display: inline; + font-size: 24px; + text-align: right; +} +.sw5e.sheet.actor .sheet-header .charlevel .level input { + display: inline; + width: 36px; + font-size: 24px; + text-align: center; +} +.sw5e.sheet.actor .sheet-header .charlevel .level.noxp { + margin-top: 10px; +} +.sw5e.sheet.actor .sheet-header .charlevel .level.noxp > label { + font-size: 32px; +} +.sw5e.sheet.actor .sheet-header .charlevel .level.noxp > input { + font-size: 32px; + flex: 0 0 40px; + height: 44px; +} +.sw5e.sheet.actor .sheet-header .charlevel .experience { + width: 100%; + height: 20px; + padding-right: 5px; + font-size: 16px; + color: #4b4a44; +} +.sw5e.sheet.actor .attributes input.temphp { + width: 48%; +} +.sw5e.sheet.actor h4.box-title { + line-height: 16px; + margin: 4px 8px 2px; + font-size: 18px; + border-bottom: 1px solid #b5b3a4; +} +.sw5e.sheet.actor ul.attributes { + list-style: none; + margin: 5px 0 0; + padding: 0; +} +.sw5e.sheet.actor ul.attributes li.attribute { + height: 70px; + margin: 0 5px; + border: 2px groove #eeede0; + border-radius: 4px; + font-family: "Nodesto", "Signika", "Palatino Linotype", serif; + font-size: 20px; + text-align: center; +} +.sw5e.sheet.actor ul.attributes li.attribute .attribute-name { + flex: 0 0 18px; +} +.sw5e.sheet.actor ul.attributes li.attribute .attribute-value { + height: 28px; + line-height: 28px; +} +.sw5e.sheet.actor ul.attributes li.attribute .attribute-value input { + display: inline; + max-width: 80%; + height: 28px; + margin: 0; + font-size: 24px; +} +.sw5e.sheet.actor ul.attributes li.attribute .attribute-value span.sep { + display: inline; + position: relative; + top: 2px; + font-size: 28px; + color: #7a7971; +} +.sw5e.sheet.actor ul.attributes li.attribute .attribute-value.multiple input { + max-width: 33%; +} +.sw5e.sheet.actor ul.attributes li.attribute .attribute-footer { + flex: 0 0 18px; + margin-top: -1px; + line-height: 18px; + font-family: "Signika", "Palatino Linotype", serif; + font-size: 12px; +} +.sw5e.sheet.actor .ability-scores { + flex: 0 0 100%; + list-style: none; + margin: 0; + padding: 0; + font-family: "Nodesto", "Signika", "Palatino Linotype", serif; + font-size: 20px; +} +.sw5e.sheet.actor .ability-scores .ability { + height: 70px; + margin: 0 5px; + text-align: center; + border: 2px groove #eeede0; + border-radius: 3px; + /* Hide modifier box on hover */ +} +.sw5e.sheet.actor .ability-scores .ability input.ability-score { + height: 30px; + width: 50px; + margin: 0 auto; + line-height: 32px; + font-size: 24px; +} +.sw5e.sheet.actor .ability-scores .ability .ability-modifiers { + height: 24px; + margin: -10px 0 0; +} +.sw5e.sheet.actor .ability-scores .ability .ability-modifiers span.ability-mod, +.sw5e.sheet.actor .ability-scores .ability .ability-modifiers span.ability-save { + flex: 0 0 24px; + height: 24px; + border-top: 2px groove #eeede0; +} +.sw5e.sheet.actor .ability-scores .ability .ability-modifiers span.ability-mod { + border-right: 2px groove #eeede0; +} +.sw5e.sheet.actor .ability-scores .ability .ability-modifiers .ability-proficiency { + line-height: 30px; +} +.sw5e.sheet.actor .ability-scores .ability .ability-modifiers span.ability-save { + border-left: 2px groove #eeede0; +} +.sw5e.sheet.actor .ability-scores .ability input.ability-score:hover + .ability-modifiers { + visibility: hidden; +} +.sw5e.sheet.actor .proficiency-toggle { + color: #b5b3a4; + font-size: 12px; +} +.sw5e.sheet.actor .proficient .proficiency-toggle { + color: #4b4a44; +} +.sw5e.sheet.actor .locked .proficiency-toggle { + color: #b5b3a4; + text-shadow: none; + cursor: default; +} +.sw5e.sheet.actor ul.skills-list { + flex: 0 0 192px; + list-style: none; + margin: 5px 5px 0; + padding: 2px 2px 0; + border: 2px groove #eeede0; + border-radius: 3px; +} +.sw5e.sheet.actor ul.skills-list li.skill { + height: 22px; + padding: 3px 0; +} +.sw5e.sheet.actor ul.skills-list li.skill h4 { + flex: 1px; + margin: 0; + font-size: 11px; + line-height: 18px; +} +.sw5e.sheet.actor ul.skills-list li.skill .skill-proficiency { + flex: 0 0 16px; + line-height: 18px; +} +.sw5e.sheet.actor ul.skills-list li.skill .skill-ability { + flex: 0 0 26px; +} +.sw5e.sheet.actor ul.skills-list li.skill .skill-mod { + flex: 0 0 20px; +} +.sw5e.sheet.actor ul.skills-list li.skill .skill-passive { + flex: 0 0 26px; + text-align: center; + color: #7a7971; +} +.sw5e.sheet.actor .counters { + flex: 0 0 100%; + border-bottom: 2px groove #eeede0; + margin-bottom: 5px; +} +.sw5e.sheet.actor .counters .counter { + padding: 0 3px; + line-height: 32px; +} +.sw5e.sheet.actor .counters .counter h4 { + flex: auto; + margin: 0; + font-family: "Nodesto", "Signika", "Palatino Linotype", serif; + font-size: 20px; + font-size: 14px; +} +.sw5e.sheet.actor .counters .counter .counter-value { + flex: 0 0 50px; + text-align: right; +} +.sw5e.sheet.actor .counters .counter .counter-value > * { + display: inline; +} +.sw5e.sheet.actor .counters .counter input[type="text"] { + height: 20px; + max-width: 20px; + margin: 0; + padding: 0; + text-align: center; +} +.sw5e.sheet.actor .counters .counter input[type="checkbox"] { + position: relative; + margin: 0; + top: 6px; +} +.sw5e.sheet.actor .counters .counter span.sep { + margin: 0 -2px; + font-size: 12px; +} +.sw5e.sheet.actor .traits { + margin: 0 5px; +} +.sw5e.sheet.actor .traits .form-group, +.sw5e.sheet.actor .traits .form-group-stacked { + margin: 0 0 4px 0; + justify-content: space-between; +} +.sw5e.sheet.actor .traits .configure-flags { + flex: 1; +} +.sw5e.sheet.actor .traits .actor-size { + flex: 0 0 150px; +} +.sw5e.sheet.actor .traits label { + flex: 0 0 150px; + line-height: 20px; + font-weight: bold; + margin: 0; +} +.sw5e.sheet.actor .traits input { + text-align: right; +} +.sw5e.sheet.actor .traits i.fas { + float: right; + margin-right: 3px; + text-align: right; + color: #999; +} +.sw5e.sheet.actor .traits i.fas:hover { + color: #111; + text-shadow: 0 0 10px red; +} +.sw5e.sheet.actor .traits .inactive { + color: #7a7971; +} +.sw5e.sheet.actor .tab.features, +.sw5e.sheet.actor .tab.inventory, +.sw5e.sheet.actor .tab.powerbook { + overflow-y: hidden; +} +.sw5e.sheet.actor .inventory-filters { + margin: 0 8px; + flex: 0 0 20px; +} +.sw5e.sheet.actor .inventory-filters h3, +.sw5e.sheet.actor .inventory-filters .filter-title { + font-family: "Nodesto", "Signika", "Palatino Linotype", serif; + font-size: 20px; + color: #4b4a44; + font-size: 18px; + margin: 0; +} +.sw5e.sheet.actor .inventory-filters.powerbook-filters { + flex: 0 0 40px; +} +.sw5e.sheet.actor .inventory-filters .currency { + list-style: none; + margin: 4px 0 8px; + padding: 0; + font-size: 12px; +} +.sw5e.sheet.actor .inventory-filters .currency label { + flex: 0; + margin-left: 8px; + text-align: right; + line-height: 20px; + color: #7a7971; +} +.sw5e.sheet.actor .inventory-filters .currency input[type="text"] { + flex: 0 0 48px; + text-align: center; + margin-left: 8px; + border-bottom: 2px groove #eeede0; +} +.sw5e.sheet.actor .inventory-list { + list-style: none; + margin: 0; + padding: 0 5px; + overflow-y: auto; +} +.sw5e.sheet.actor .inventory-list .item { + line-height: 30px; + padding: 0 2px; + border-bottom: 1px solid #c9c7b8; +} +.sw5e.sheet.actor .inventory-list .item:last-child { + border-bottom: none; +} +.sw5e.sheet.actor .inventory-list .item .item-name { + cursor: pointer; + max-height: 30px; + overflow: hidden; +} +.sw5e.sheet.actor .inventory-list .item .item-name .item-image { + flex: 0 0 30px; + background-size: 30px; + margin-right: 5px; +} +.sw5e.sheet.actor .inventory-list .item .item-name h4 { + margin: 0; + white-space: nowrap; + overflow-x: hidden; +} +.sw5e.sheet.actor .inventory-list .item .item-name.rollable .item-image:hover { + background-image: url("/icons/svg/d20-black.svg") !important; +} +.sw5e.sheet.actor .inventory-list .item .item-name.rollable:hover .item-image { + background-image: url("/icons/svg/d20-grey.svg") !important; +} +.sw5e.sheet.actor .inventory-list .item .item-name i.attuned { + color: #7a7971; +} +.sw5e.sheet.actor .inventory-list .item .item-uses input { + width: 24px; + text-align: center; +} +.sw5e.sheet.actor .inventory-list .item .item-properties { + margin-top: 3px; +} +.sw5e.sheet.actor .inventory-list .item .item-recharge { + flex: 0 0 80px; + text-align: right; + font-size: 11px; + color: #7a7971; +} +.sw5e.sheet.actor .inventory-list .inventory-header { + margin: 2px 0; + padding: 0; + background: rgba(0, 0, 0, 0.05); + border: 2px groove #eeede0; + font-weight: bold; + line-height: 24px; +} +.sw5e.sheet.actor .inventory-list .inventory-header h3 { + margin: 0 -5px 0 0; + padding-left: 5px; + font-size: 13px; + font-weight: bold; +} +.sw5e.sheet.actor .inventory-list .inventory-header .item-controls a.item-create { + flex: 0 0 100%; +} +.sw5e.sheet.actor .inventory-list .item-detail { + flex: 0 0 70px; + font-size: 12px; + color: #7a7971; + text-align: center; + border-right: 1px solid #c9c7b8; +} +.sw5e.sheet.actor .inventory-list .item-detail:last-child { + border-right: none; +} +.sw5e.sheet.actor .inventory-list .item-detail.item-action { + flex: 0 0 100px; +} +.sw5e.sheet.actor .inventory-list .item-weight { + flex: 0 0 60px; + border-left: 1px solid #c9c7b8; + border-right: 1px solid #c9c7b8; +} +.sw5e.sheet.actor .inventory-list .item-list { + list-style: none; + margin: 0; + padding: 0; +} +.sw5e.sheet.actor .inventory-list .item-controls { + flex: 0 0 44px; + display: flex; + flex-direction: row; + flex-wrap: wrap; + justify-content: flex-start; + justify-content: flex-end; +} +.sw5e.sheet.actor .inventory-list .item-controls > * { + flex: 1; +} +.sw5e.sheet.actor .inventory-list .item-controls .flex1 { + flex: 1; +} +.sw5e.sheet.actor .inventory-list .item-controls .flex2 { + flex: 2; +} +.sw5e.sheet.actor .inventory-list .item-controls .flex3 { + flex: 3; +} +.sw5e.sheet.actor .inventory-list .item-controls .flex4 { + flex: 4; +} +.sw5e.sheet.actor .inventory-list .item-controls a { + flex: 0 0 22px; + font-size: 12px; + text-align: center; + color: #7a7971; +} +.sw5e.sheet.actor .inventory-list .item-summary { + flex: 0 0 100%; + font-size: 12px; + line-height: 16px; + padding: 0.25em 0.5em; + border-top: 1px solid #c9c7b8; +} +.sw5e.sheet.actor .powercasting-ability h3, +.sw5e.sheet.actor .pact-slots h3 { + flex: none; + margin-right: 5px; +} +.sw5e.sheet.actor .powercasting-ability input, +.sw5e.sheet.actor .pact-slots input, +.sw5e.sheet.actor .powercasting-ability span, +.sw5e.sheet.actor .pact-slots span { + flex: 0 0 32px; + text-align: center; +} +.sw5e.sheet.actor .powercasting-ability select, +.sw5e.sheet.actor .pact-slots select { + margin: 0 5px; + flex: 0 0 150px; +} +.sw5e.sheet.actor .powercasting-ability h3.power-dc, +.sw5e.sheet.actor .pact-slots h3.power-dc { + flex: 1; + text-align: right; +} +.sw5e.sheet.actor .pact-slots { + align-items: center; +} +.sw5e.sheet.actor .power-slots, +.sw5e.sheet.actor .power-comps { + flex: 0 0 72px; + padding-right: 5px; + text-align: right; + font-size: 12px; + color: #7a7971; + border-right: 1px solid #c9c7b8; +} +.sw5e.sheet.actor .power-slots input, +.sw5e.sheet.actor .power-slots span.sep { + display: inline; + max-width: 20px; + text-align: center; +} +.sw5e.sheet.actor .power-uses { + padding-right: 8px; + text-align: right !important; +} +.sw5e.sheet.actor .power-school, +.sw5e.sheet.actor .power-action, +.sw5e.sheet.actor .power-target { + flex: 0 0 100px; + font-size: 12px; + color: #7a7971; + text-align: center; + border-right: 1px solid #c9c7b8; +} +.sw5e.sheet.actor .power-component { + line-height: 14px; +} +.sw5e.sheet.actor .power-component.C, +.sw5e.sheet.actor .power-component.R { + display: inline-block; + text-align: center; + padding-top: 1px; + width: 16px; + color: #c9c7b8; + background: rgba(0, 0, 0, 0.4); + border: 1px solid transparent; + border-radius: 8px; +} +.sw5e.sheet.actor .powerbook-empty .item-controls { + flex: 1; +} +.sw5e.sheet.actor .editor { + padding: 0 8px; +} +.sw5e.sheet.item { + min-height: 420px; + /* ----------------------------------------- */ + /* Sheet Header */ + /* ----------------------------------------- */ + /* ----------------------------------------- */ + /* Item Details Form */ + /* ----------------------------------------- */ + /* ----------------------------------------- */ + /* Item Actions */ + /* ----------------------------------------- */ + /* ----------------------------------------- */ + /* Item Actions */ + /* ----------------------------------------- */ + /* ----------------------------------------- */ + /* Loot Sheet (No Tabs) */ + /* ----------------------------------------- */ +} +.sw5e.sheet.item .sheet-header img.profile { + border: 2px solid #000; +} +.sw5e.sheet.item .sheet-header .item-subtitle { + flex: 0 0 80px; + height: 60px; + margin: 0; + padding: 5px; + text-align: right; + color: #7a7971; +} +.sw5e.sheet.item .sheet-header .item-subtitle .item-type { + font-size: 24px; + line-height: 26px; + margin: 0; +} +.sw5e.sheet.item .sheet-header .item-subtitle .item-status { + font-size: 16px; + line-height: 24px; +} +.sw5e.sheet.item .sheet-navigation { + margin-bottom: 5px; +} +.sw5e.sheet.item .sheet-navigation .item { + font-size: 18px; +} +.sw5e.sheet.item .sheet-body { + overflow: hidden; +} +.sw5e.sheet.item .sheet-body .tab { + padding: 0 5px; + overflow: hidden auto; +} +.sw5e.sheet.item .sheet-body .item-properties { + flex: 0 0 120px; + margin: 5px 5px 5px 0; + padding-right: 5px; + border-right: 2px groove #eeede0; +} +.sw5e.sheet.item .sheet-body .item-properties .form-group { + margin: 0; +} +.sw5e.sheet.item .sheet-body .item-properties .form-group label { + line-height: 20px; +} +.sw5e.sheet.item .sheet-body .item-properties .form-group input { + text-align: right; +} +.sw5e.sheet.item .sheet-body .item-properties .properties-list { + list-style: none; + margin: 0; + padding: 0; +} +.sw5e.sheet.item .sheet-body .item-properties .properties-list li { + margin: 3px 0; + padding: 0 2px; + background: rgba(0, 0, 0, 0.05); + border: 2px groove #eeede0; + text-align: center; + font-size: 12px; + line-height: 18px; +} +.sw5e.sheet.item .details input[type="text"], +.sw5e.sheet.item .details select { + height: 24px; + border: 1px solid #7a7971; + background: rgba(0, 0, 0, 0.05); +} +.sw5e.sheet.item .details .form-group span { + text-align: center; + line-height: 24px; +} +.sw5e.sheet.item .details .form-group.input-select select { + flex: 1.8; +} +.sw5e.sheet.item .details .form-group.input-select-select select { + flex: 1.5; +} +.sw5e.sheet.item .details .form-group.uses-per input { + flex: 1; +} +.sw5e.sheet.item .details .form-group.uses-per span { + flex: 0 0 16px; +} +.sw5e.sheet.item .details .form-group.uses-per select { + flex: 3; +} +.sw5e.sheet.item .details span.sep { + flex: 0 0 8px; +} +.sw5e.sheet.item .details .prepared { + flex: 1.3 !important; + text-align: right; + padding-right: 10px; +} +.sw5e.sheet.item .details .power-materials { + flex: 0 0 100%; + margin: 0.25em 0; + justify-content: flex-end; +} +.sw5e.sheet.item .details .power-materials label { + flex: 0 0 64px; + text-align: right; + margin-right: 5px; + font-size: 12px; + line-height: 24px; +} +.sw5e.sheet.item .details .power-materials input[type="text"] { + flex: 0 0 48px; + margin-right: 10px; +} +.sw5e.sheet.item h4.damage-header { + margin: 0; + padding: 0; + font-weight: bold; + line-height: 24px; + color: #4b4a44; +} +.sw5e.sheet.item .damage-parts { + list-style: none; + margin: 0; + padding: 0; +} +.sw5e.sheet.item .damage-parts .damage-part { + flex: 0 0 100%; + padding: 0; +} +.sw5e.sheet.item .damage-parts .damage-part input { + flex: 3; +} +.sw5e.sheet.item .damage-parts .damage-part select { + margin-left: 5px; + flex: 1; +} +.sw5e.sheet.item .damage-control { + width: 18px; + flex: 0 0 18px; + line-height: 24px; + float: right; + text-align: right; + color: #7a7971; +} +.sw5e.sheet.item .recharge span { + flex: 0 0 80px; +} +.sw5e.sheet.item .recharge label.checkbox { + flex: 0 0 80px; + text-align: right; +} +.sw5e.sheet.item .weapon-properties label.checkbox { + flex: 0 0 98px; +} +.sw5e.sheet.item .loot-header { + margin-bottom: 10px; +} +/* ----------------------------------------- */ +/* Chat Cards +/* ----------------------------------------- */ +.sw5e.chat-card { + font-style: normal; + font-size: 12px; +} +.sw5e.chat-card .card-header { + padding: 3px 0; + border-top: 2px groove #FFF; + border-bottom: 2px groove #FFF; +} +.sw5e.chat-card .card-header img { + flex: 0 0 36px; + margin-right: 5px; +} +.sw5e.chat-card .card-header h3 { + flex: 1; + margin: 0; + line-height: 36px; + font-family: "Nodesto", "Signika", "Palatino Linotype", serif; + font-size: 20px; + color: #4b4a44; +} +.sw5e.chat-card .card-header h3:hover { + color: #111; + text-shadow: 0 0 10px red; +} +.sw5e.chat-card .card-content { + margin: 5px 0; +} +.sw5e.chat-card .card-content h3 { + font-size: 12px; + margin: 0; + font-weight: bold; +} +.sw5e.chat-card .card-content > * { + -webkit-user-select: text; + -moz-user-select: text; + -ms-user-select: text; + user-select: text; +} +.sw5e.chat-card .card-buttons { + margin: 5px 0; +} +.sw5e.chat-card .card-buttons span { + display: block; + line-height: 28px; + text-align: center; + border: 1px solid #CCC; +} +.sw5e.chat-card .card-buttons button { + font-size: 12px; + height: 24px; + line-height: 20px; + margin: 2px 0; +} +.sw5e.chat-card .card-footer { + padding: 3px 0 0; + border-top: 2px groove #FFF; +} +.sw5e.chat-card .card-footer span { + border-right: 2px groove #FFF; + padding: 0 5px 0 0; + font-size: 10px; +} +.sw5e.chat-card .card-footer span:last-child { + border-right: none; + padding-right: 0; +} +.dice-roll .dice-total.success { + color: inherit; + background: #c7d0c0; + border: 1px solid #006c00; +} +.dice-roll .dice-total.failure { + color: inherit; + background: #ffdddd; + border: 1px solid #6e0000; +} +.dice-roll .dice-total.critical { + color: green; +} +.dice-roll .dice-total.fumble { + color: red; +} +/* ----------------------------------------- */ +/* Basic Structure */ +/* ----------------------------------------- */ +.sw5e.sheet.actor.character { + min-width: 672px; + min-height: 736px; + /* ----------------------------------------- */ + /* Sheet Header */ + /* ----------------------------------------- */ + /* ----------------------------------------- */ + /* Sheet Body */ + /* ----------------------------------------- */ + /* ----------------------------------------- */ + /* Inventory */ + /* ----------------------------------------- */ + /* Encumbrance Bar */ + /* ----------------------------------------- */ + /* Item Controls */ + /* ----------------------------------------- */ +} +.sw5e.sheet.actor.character .sheet-header img.profile { + flex: 0 0 180px; + max-width: 180px; + height: 180px; +} +.sw5e.sheet.actor.character .sheet-header .charlevel { + flex: 0 0 180px; + padding: 0 5px 2px; +} +.sw5e.sheet.actor.character .sheet-header .charlevel .level { + height: 28px; +} +.sw5e.sheet.actor.character .sheet-header .charlevel .experience input[type="text"] { + width: 100px; +} +.sw5e.sheet.actor.character .sheet-header .charlevel .xpbar { + width: 100%; + flex: 0 0 8px; + background: #666; + border: 1px solid #000; + border-radius: 3px; +} +.sw5e.sheet.actor.character .sheet-header .charlevel .xpbar .bar { + height: 4px; + margin: 1px; + display: block; + background: #afebff; + border: 1px solid #000; + border-radius: 2px; +} +.sw5e.sheet.actor.character .sheet-header .summary { + border-bottom: 2px groove #eeede0; +} +.sw5e.sheet.actor.character .sheet-header .attributes { + height: 80px; + margin: 0; +} +.sw5e.sheet.actor.character .sheet-header .attributes .attribute { + height: 80px; + margin: 0; + border: none; + border-right: 2px groove #eeede0; + border-radius: 0; +} +.sw5e.sheet.actor.character .sheet-header .attributes .attribute:last-child { + border-right: none; +} +.sw5e.sheet.actor.character .sheet-header .attributes .attribute .attribute-value { + margin: 5px 0 0; + height: 32px; + line-height: 32px; +} +.sw5e.sheet.actor.character .sheet-header .attributes .attribute .attribute-name { + margin-top: 6px; +} +.sw5e.sheet.actor.character .sheet-header .attributes .attribute .attribute-footer { + margin-bottom: 2px; +} +.sw5e.sheet.actor.character .sheet-header .attributes a.rest { + border: 1px solid #b5b3a4; + border-radius: 2px; + background: rgba(0, 0, 0, 0.05); + padding: 1px 3px; + margin: 0 6px; +} +.sw5e.sheet.actor.character .sheet-header .attributes .hit-dice { + font-size: 24px; +} +.sw5e.sheet.actor.character .attributes .resource .attribute-name { + margin: 0 8px; +} +.sw5e.sheet.actor.character .attributes .resource .attribute-name input[type="text"] { + height: 20px; + margin: 2px 0 -2px; + line-height: 24px; +} +.sw5e.sheet.actor.character .attributes .resource label.checkbox { + margin: 0 3px; +} +.sw5e.sheet.actor.character .attributes .resource label.checkbox input[type="checkbox"] { + transform: scale(1.2); +} +.sw5e.sheet.actor.character .attributes .initiative .attribute-footer input { + width: 32px; +} +.sw5e.sheet.actor.character ul.skills-list { + flex: 0 0 212px; +} +.sw5e.sheet.actor.character ul.skills-list li.skill { + padding: 3px; +} +.sw5e.sheet.actor.character ul.skills-list li.skill h4 { + flex: 1px; + margin: 0; + font-size: 13px; +} +.sw5e.sheet.actor.character .counters .death-saves { + flex: 2; +} +.sw5e.sheet.actor.character .counters .death-saves .counter-value { + flex: 0 0 90px; +} +.sw5e.sheet.actor.character .item-detail.player-class { + flex: 0 0 180px; + text-align: right; + padding-right: 10px; +} +.sw5e.sheet.actor.character .encumbrance { + flex: 0 0 12px; + background: #7a7971; + margin: 1px 15px 0 1px; + border: 1px solid #191813; + border-radius: 3px; + position: relative; +} +.sw5e.sheet.actor.character .encumbrance .encumbrance-bar { + position: absolute; + top: 1px; + left: 1px; + background: #6c8aa5; + height: 8px; + border: 1px solid #cde4ff; + border-radius: 2px; +} +.sw5e.sheet.actor.character .encumbrance .encumbrance-label { + height: 10px; + padding: 0 5px; + position: absolute; + top: 0; + right: 0; + font-size: 13px; + line-height: 12px; + text-align: right; + color: #EEE; + text-shadow: 0 0 5px #000; +} +.sw5e.sheet.actor.character .encumbrance .encumbrance-breakpoint { + display: block; + position: absolute; +} +.sw5e.sheet.actor.character .encumbrance .encumbrance-breakpoint.encumbrance-33 { + left: 33%; +} +.sw5e.sheet.actor.character .encumbrance .encumbrance-breakpoint.encumbrance-66 { + left: 66%; +} +.sw5e.sheet.actor.character .encumbrance .arrow-up { + bottom: 0; + width: 0; + height: 0; + border-left: 4px solid transparent; + border-right: 4px solid transparent; + border-bottom: 4px solid #666; +} +.sw5e.sheet.actor.character .encumbrance .arrow-down { + top: 0; + width: 0; + height: 0; + border-left: 4px solid transparent; + border-right: 4px solid transparent; + border-top: 4px solid #666; +} +.sw5e.sheet.actor.character .encumbrance.encumbered .arrow-up { + border-bottom: 4px solid #000; +} +.sw5e.sheet.actor.character .encumbrance.encumbered .arrow-down { + border-top: 4px solid #000; +} +.sw5e.sheet.actor.character .inventory .item-controls, +.sw5e.sheet.actor.character .powerbook .item-controls { + flex: 0 0 68px; +} +.sw5e.sheet.actor.character .inventory .item-controls .item-toggle, +.sw5e.sheet.actor.character .powerbook .item-controls .item-toggle { + color: #b5b3a4; +} +.sw5e.sheet.actor.character .inventory .item-controls .item-toggle.active, +.sw5e.sheet.actor.character .powerbook .item-controls .item-toggle.active { + color: #4b4a44; +} +.sw5e.sheet.actor.character .inventory .item-controls .item-toggle.fixed, +.sw5e.sheet.actor.character .powerbook .item-controls .item-toggle.fixed { + color: #44191A; +} +.sw5e.sheet.actor.character .inventory .item-controls .item-toggle.fixed:hover, +.sw5e.sheet.actor.character .powerbook .item-controls .item-toggle.fixed:hover { + text-shadow: none; +} +/* ----------------------------------------- */ +/* Basic Structure */ +/* ----------------------------------------- */ +.sw5e.sheet.actor.npc { + min-width: 600px; + min-height: 658px; +} diff --git a/sw5e.js b/sw5e.js new file mode 100644 index 00000000..f37ec6c6 --- /dev/null +++ b/sw5e.js @@ -0,0 +1,206 @@ +/** + * The Star Wars 5th Edition game system for Foundry Virtual Tabletop + * Author: Kakeman89 + * Software License: GNU GPLv3 + * Content License: https://media.wizards.com/2016/downloads/SW5ERD-OGL_V5.1.pdf + * Repository: https://gitlab.com/foundrynet/sw5e + * Issue Tracker: https://gitlab.com/foundrynet/sw5e/issues + */ + +// Import Modules +import { SW5E } from "./module/config.js"; +import { registerSystemSettings } from "./module/settings.js"; +import { preloadHandlebarsTemplates } from "./module/templates.js"; +import { _getInitiativeFormula } from "./module/combat.js"; +import { measureDistance, getBarAttribute } from "./module/canvas.js"; +import { Actor5e } from "./module/actor/entity.js"; +import { ActorSheet5eCharacter } from "./module/actor/sheets/character.js"; +import { Item5e } from "./module/item/entity.js"; +import { ItemSheet5e } from "./module/item/sheet.js"; +import { ActorSheet5eNPC } from "./module/actor/sheets/npc.js"; +import { Dice5e } from "./module/dice.js"; +import * as chat from "./module/chat.js"; +import * as migrations from "./module/migration.js"; + +/* -------------------------------------------- */ +/* Foundry VTT Initialization */ +/* -------------------------------------------- */ + +Hooks.once("init", function() { + console.log(`SW5e | Initializing Star Wars 5th Edition System\n${SW5E.ASCII}`); + + // Create a SW5E namespace within the game global + game.sw5e = { + Actor5e, + Dice5e, + Item5e, + migrations, + rollItemMacro + }; + + // Record Configuration Values + CONFIG.SW5E = SW5E; + CONFIG.Actor.entityClass = Actor5e; + CONFIG.Item.entityClass = Item5e; + + // Register System Settings + registerSystemSettings(); + + // Patch Core Functions + Combat.prototype._getInitiativeFormula = _getInitiativeFormula; + + // Register sheet application classes + Actors.unregisterSheet("core", ActorSheet); + Actors.registerSheet("sw5e", ActorSheet5eCharacter, { types: ["character"], makeDefault: true }); + Actors.registerSheet("sw5e", ActorSheet5eNPC, { types: ["npc"], makeDefault: true }); + Items.unregisterSheet("core", ItemSheet); + Items.registerSheet("sw5e", ItemSheet5e, {makeDefault: true}); + + // Preload Handlebars Templates + preloadHandlebarsTemplates(); +}); + + +/* -------------------------------------------- */ +/* Foundry VTT Setup */ +/* -------------------------------------------- */ + +/** + * This function runs after game data has been requested and loaded from the servers, so entities exist + */ +Hooks.once("setup", function() { + + // Localize CONFIG objects once up-front + const toLocalize = [ + "abilities", "alignments", "conditionTypes", "consumableTypes", "currencies", "damageTypes", "distanceUnits", "equipmentTypes", + "healingTypes", "itemActionTypes", "limitedUsePeriods", "senses", "skills", "powerComponents", "powerLevels", "powerPreparationModes", + "powerSchools", "powerScalingModes", "targetTypes", "timePeriods", "weaponProperties", "weaponTypes", "languages", "polymorphSettings", + "armorProficiencies", "weaponProficiencies", "toolProficiencies", "abilityActivationTypes", "actorSizes", "proficiencyLevels" + ]; + for ( let o of toLocalize ) { + CONFIG.SW5E[o] = Object.entries(CONFIG.SW5E[o]).reduce((obj, e) => { + obj[e[0]] = game.i18n.localize(e[1]); + return obj; + }, {}); + } +}); + +/* -------------------------------------------- */ + +/** + * Once the entire VTT framework is initialized, check to see if we should perform a data migration + */ +Hooks.once("ready", function() { + + // Determine whether a system migration is required and feasible + const currentVersion = game.settings.get("sw5e", "systemMigrationVersion"); + const NEEDS_MIGRATION_VERSION = 0.84; + const COMPATIBLE_MIGRATION_VERSION = 0.80; + let needMigration = (currentVersion < NEEDS_MIGRATION_VERSION) || (currentVersion === null); + const canMigrate = currentVersion >= COMPATIBLE_MIGRATION_VERSION; + + // Perform the migration + if ( needMigration && game.user.isGM ) { + if ( currentVersion && (currentVersion < COMPATIBLE_MIGRATION_VERSION) ) { + ui.notifications.error(`Your SW5E system data is from too old a Foundry version and cannot be reliably migrated to the latest version. The process will be attempted, but errors may occur.`, {permanent: true}); + } + migrations.migrateWorld(); + } + + // Wait to register hotbar drop hook on ready so that modules could register earlier if they want to + Hooks.on("hotbarDrop", (bar, data, slot) => create5eMacro(data, slot)); +}); + +/* -------------------------------------------- */ +/* Canvas Initialization */ +/* -------------------------------------------- */ + +Hooks.on("canvasInit", function() { + + // Extend Diagonal Measurement + canvas.grid.diagonalRule = game.settings.get("sw5e", "diagonalMovement"); + SquareGrid.prototype.measureDistance = measureDistance; + + // Extend Token Resource Bars + Token.prototype.getBarAttribute = getBarAttribute; +}); + + +/* -------------------------------------------- */ +/* Other Hooks */ +/* -------------------------------------------- */ + +Hooks.on("renderChatMessage", (app, html, data) => { + + // Display action buttons + chat.displayChatActionButtons(app, html, data); + + // Highlight critical success or failure die + chat.highlightCriticalSuccessFailure(app, html, data); + + // Optionally collapse the content + if (game.settings.get("sw5e", "autoCollapseItemCards")) html.find(".card-content").hide(); +}); +Hooks.on("getChatLogEntryContext", chat.addChatMessageContextOptions); +Hooks.on("renderChatLog", (app, html, data) => Item5e.chatListeners(html)); +Hooks.on('getActorDirectoryEntryContext', Actor5e.addDirectoryContextOptions); + +/* -------------------------------------------- */ +/* Hotbar Macros */ +/* -------------------------------------------- */ + +/** + * Create a Macro from an Item drop. + * Get an existing item macro if one exists, otherwise create a new one. + * @param {Object} data The dropped data + * @param {number} slot The hotbar slot to use + * @returns {Promise} + */ +async function create5eMacro(data, slot) { + if ( data.type !== "Item" ) return; + if (!( "data" in data ) ) return ui.notifications.warn("You can only create macro buttons for owned Items"); + const item = data.data; + + // Create the macro command + const command = `game.sw5e.rollItemMacro("${item.name}");`; + let macro = game.macros.entities.find(m => (m.name === item.name) && (m.command === command)); + if ( !macro ) { + macro = await Macro.create({ + name: item.name, + type: "script", + img: item.img, + command: command, + flags: {"sw5e.itemMacro": true} + }); + } + game.user.assignHotbarMacro(macro, slot); + return false; +} + +/* -------------------------------------------- */ + +/** + * Create a Macro from an Item drop. + * Get an existing item macro if one exists, otherwise create a new one. + * @param {string} itemName + * @return {Promise} + */ +function rollItemMacro(itemName) { + const speaker = ChatMessage.getSpeaker(); + let actor; + if ( speaker.token ) actor = game.actors.tokens[speaker.token]; + if ( !actor ) actor = game.actors.get(speaker.actor); + + // Get matching items + const items = actor ? actor.items.filter(i => i.name === itemName) : []; + if ( items.length > 1 ) { + ui.notifications.warn(`Your controlled Actor ${actor.name} has more than one Item with name ${itemName}. The first matched item will be chosen.`); + } else if ( items.length === 0 ) { + return ui.notifications.warn(`Your controlled Actor does not have an item named ${itemName}`); + } + const item = items[0]; + + // Trigger the item roll + if ( item.data.type === "power" ) return actor.usePower(item); + return item.roll(); +} diff --git a/system.json b/system.json new file mode 100644 index 00000000..a92067a8 --- /dev/null +++ b/system.json @@ -0,0 +1,76 @@ +{ + "name": "sw5e", + "title": "Star Wars 5th Edition", + "description": "A comprehensive game system for running games of Star wars 5th Edition in the Foundry VTT environment.", + "version": 0.88, + "author": "Kakeman89", + "scripts": [], + "esmodules": ["sw5e.js"], + "styles": ["sw5e.css"], + "packs": [ + { + "name": "heroes", + "label": "Starter Heroes", + "system": "dnd5e", + "path": "./packs/heroes.db", + "entity": "Actor" + }, + { + "name": "beasts", + "label": "Beasts", + "system": "sw5e", + "path": "./packs/beasts.db", + "entity": "Actor" + }, + { + "name": "items", + "label": "Items", + "system": "sw5e", + "path": "./packs/items.db", + "entity": "Item" + }, + { + "name": "tradegoods", + "label": "Trade Goods (SRD)", + "system": "sw5e", + "path": "./packs/tradegoods.db", + "entity": "Item" + }, + { + "name": "powers", + "label": "Casting", + "system": "sw5e", + "path": "./packs/powers.db", + "entity": "Item" + }, + { + "name": "classes", + "label": "Classes", + "system": "sw5e", + "path": "./packs/classes.db", + "entity": "Item" + }, + { + "name": "classfeatures", + "label": "Class Features (SRD)", + "system": "sw5e", + "path": "./packs/classfeatures.db", + "entity": "Item" + } + ], + "languages": [ + { + "lang": "en", + "name": "English", + "path": "lang/en.json" + } + ], + "socket": true, + "initiative": "1d20 + @abilities.dex.mod + @attributes.init.value + (@abilities.dex.value / 100)", + "gridDistance": 5, + "gridUnits": "ft", + "primaryTokenAttribute": "attributes.hp", + "secondaryTokenAttribute": null, + "minimumCoreVersion": "0.5.2", + "compatibleCoreVersion": "0.6.4" +} diff --git a/template.json b/template.json new file mode 100644 index 00000000..16c84644 --- /dev/null +++ b/template.json @@ -0,0 +1,488 @@ +{ + "Actor": { + "types": ["character", "npc"], + "templates": { + "common": { + "abilities": { + "str": { + "value": 10, + "proficient": 0 + }, + "dex": { + "value": 10, + "proficient": 0 + }, + "con": { + "value": 10, + "proficient": 0 + }, + "int": { + "value": 10, + "proficient": 0 + }, + "wis": { + "value": 10, + "proficient": 0 + }, + "cha": { + "value": 10, + "proficient": 0 + } + }, + "attributes": { + "ac": { + "min": 0 + }, + "hp": { + "value": 10, + "min": 0, + "max": 10, + "temp": 0, + "tempmax": 0 + }, + "init": { + "value": 0, + "bonus": 0 + }, + "speed": { + "value": "30 ft", + "special": "" + }, + "powercasting": "int" + }, + "details": { + "alignment": "", + "biography": { + "value": "", + "public": "" + }, + "race": "" + }, + "skills": { + "acr": { + "value": 0, + "ability": "dex" + }, + "ani": { + "value": 0, + "ability": "wis" + }, + "ath": { + "value": 0, + "ability": "str" + }, + "dec": { + "value": 0, + "ability": "cha" + }, + "ins": { + "value": 0, + "ability": "wis" + }, + "itm": { + "value": 0, + "ability": "cha" + }, + "inv": { + "value": 0, + "ability": "int" + }, + "lor": { + "value": 0, + "ability": "int" + }, + "med": { + "value": 0, + "ability": "wis" + }, + "nat": { + "value": 0, + "ability": "int" + }, + "pil": { + "value": 0, + "ability": "int" + }, + "prc": { + "value": 0, + "ability": "wis" + }, + "prf": { + "value": 0, + "ability": "cha" + }, + "per": { + "value": 0, + "ability": "cha" + }, + "slt": { + "value": 0, + "ability": "dex" + }, + "ste": { + "value": 0, + "ability": "dex" + }, + "sur": { + "value": 0, + "ability": "wis" + }, + "tec": { + "value": 0, + "ability": "int" + } + }, + "traits": { + "size": "med", + "senses": "", + "languages": { + "value": [], + "custom": "" + }, + "di": { + "value": [], + "custom": "" + }, + "dr": { + "value": [], + "custom": "" + }, + "dv": { + "value": [], + "custom": "" + }, + "ci": { + "value": [], + "custom": "" + } + }, + "currency": { + "gc": 0 + }, + "powers": { + "power1": { + "value": 0, + "max": 0, + "override": null + }, + "power2": { + "value": 0, + "max": 0, + "override": null + }, + "power3": { + "value": 0, + "max": 0, + "override": null + }, + "power4": { + "value": 0, + "max": 0, + "override": null + }, + "power5": { + "value": 0, + "max": 0, + "override": null + }, + "power6": { + "value": 0, + "max": 0, + "override": null + }, + "power7": { + "value": 0, + "max": 0, + "override": null + }, + "power8": { + "value": 0, + "max": 0, + "override": null + }, + "power9": { + "value": 0, + "max": 0, + "override": null + }, + "pact": { + "value": 0, + "max": 0, + "override": null + } + }, + "bonuses": { + "mwak": { + "attack": "", + "damage": "" + }, + "rwak": { + "attack": "", + "damage": "" + }, + "mpak": { + "attack": "", + "damage": "" + }, + "rpak": { + "attack": "", + "damage": "" + }, + "abilities": { + "check": "", + "save": "", + "skill": "" + }, + "power": { + "dc": "" + } + } + } + }, + "character": { + "templates": ["common"], + "attributes": { + "death": { + "success": 0, + "failure": 0 + }, + "exhaustion": 0, + "inspiration": 0 + }, + "details": { + "background": "", + "xp": { + "value": 0, + "min": 0, + "max": 300 + }, + "trait": "", + "ideal": "", + "bond": "", + "flaw": "" + }, + "resources": { + "primary": { + "value": 0, + "max": 0, + "sr": 0, + "lr": 0 + }, + "secondary": { + "value": 0, + "max": 0, + "sr": 0, + "lr": 0 + }, + "tertiary": { + "value": 0, + "max": 0, + "sr": 0, + "lr": 0 + } + }, + "traits": { + "weaponProf": { + "value": [], + "custom": "" + }, + "armorProf": { + "value": [], + "custom": "" + }, + "toolProf": { + "value": [], + "custom": "" + } + } + }, + "npc": { + "templates": ["common"], + "details": { + "type": "", + "environment": "", + "cr": 1, + "powerLevel": 0, + "xp": { + "value": 10 + }, + "source": "" + }, + "resources": { + "legact": { + "value": 0, + "max": 0 + }, + "legres": { + "value": 0, + "max": 0 + }, + "lair": { + "value": 0, + "initiative": 0 + } + } + } + }, + "Item": { + "types": ["weapon", "equipment", "consumable", "tool", "loot", "class", "power", "feat", "backpack"], + "templates": { + "itemDescription": { + "description": { + "value": "", + "chat": "", + "unidentified": "" + }, + "source": "" + }, + "physicalItem": { + "quantity": 1, + "weight": 0, + "price": 0, + "attuned": false, + "equipped": false, + "rarity": "", + "identified": true + }, + "activatedEffect": { + "activation": { + "type": "", + "cost": 0, + "condition": "" + }, + "duration": { + "value": null, + "units": "" + }, + "target": { + "value": null, + "units": "", + "type": "" + }, + "range": { + "value": null, + "long": null, + "units": "" + }, + "uses": { + "value": 0, + "max": 0, + "per": null + } + }, + "action": { + "ability": null, + "actionType": null, + "attackBonus": 0, + "chatFlavor": "", + "critical": null, + "damage": { + "parts": [], + "versatile": "" + }, + "formula": "", + "save": { + "ability": "", + "dc": null, + "scaling": "power" + } + } + }, + "backpack": { + "templates": ["itemDescription", "physicalItem"], + "capacity": { + "type": "weight", + "value": 0, + "weightless": false + }, + "currency": { + "gc": 0 + } + }, + "class": { + "templates": ["itemDescription"], + "levels": 1, + "subclass": "", + "hitDice": "d6", + "hitDiceUsed": 0, + "skills": { + "number": 2, + "choices": [], + "value": [] + }, + "powercasting": "none" + }, + "consumable": { + "templates": ["itemDescription", "physicalItem", "activatedEffect", "action"], + "consumableType": "potion", + "uses": { + "value": 0, + "max": 0, + "per": null, + "autoUse": true, + "autoDestroy": true + } + }, + "equipment": { + "templates": ["itemDescription", "physicalItem", "activatedEffect", "action"], + "armor": { + "type": "light", + "value": 10, + "dex": null + }, + "strength": 0, + "stealth": false, + "proficient": true + }, + "feat": { + "templates": ["itemDescription", "activatedEffect", "action"], + "requirements": "", + "recharge": { + "value": null, + "charged": false + } + }, + "loot": { + "templates": ["itemDescription", "physicalItem"] + }, + "tool": { + "templates": ["itemDescription", "physicalItem"], + "ability": "int", + "chatFlavor": "", + "proficient": 0 + }, + "power": { + "templates": ["itemDescription", "activatedEffect", "action"], + "level": 1, + "school": "", + "components": { + "value": "", + "vocal": false, + "somatic": false, + "material": false, + "ritual": false, + "concentration": false + }, + "materials": { + "value": "", + "consumed": false, + "cost": 0, + "supply": 0 + }, + "preparation": { + "mode": null, + "prepared": false + }, + "scaling": { + "mode": null, + "formula": null + } + }, + "weapon": { + "templates": ["itemDescription", "physicalItem" ,"activatedEffect", "action"], + "weaponType": "simpleM", + "properties": {}, + "proficient": true + } + } +}