From b113f630bf14bea5ff320e376f7bc91366e28812 Mon Sep 17 00:00:00 2001 From: LeRatierBretonnien Date: Sat, 10 Jan 2026 15:08:28 +0100 Subject: [PATCH] Migration vers DataModels et appv2 --- gulpfile.js | 35 + less/heritiers.less | 4 + less/simple-converted.less | 1637 +++++++++++++++++ .../applications/heritiers-roll-dialog.mjs | 311 ++++ modules/applications/sheets/_module.mjs | 23 + .../applications/sheets/accessoire-sheet.mjs | 19 + modules/applications/sheets/arme-sheet.mjs | 19 + .../sheets/atoutfeerique-sheet.mjs | 19 + .../applications/sheets/avantage-sheet.mjs | 19 + .../applications/sheets/base-actor-sheet.mjs | 618 +++++++ .../applications/sheets/base-item-sheet.mjs | 212 +++ .../sheets/capacitenaturelle-sheet.mjs | 19 + .../applications/sheets/competence-sheet.mjs | 19 + modules/applications/sheets/contact-sheet.mjs | 19 + .../applications/sheets/desavantage-sheet.mjs | 19 + .../applications/sheets/equipement-sheet.mjs | 19 + modules/applications/sheets/fee-sheet.mjs | 19 + .../applications/sheets/personnage-sheet.mjs | 59 + modules/applications/sheets/pnj-sheet.mjs | 59 + modules/applications/sheets/pouvoir-sheet.mjs | 19 + modules/applications/sheets/profil-sheet.mjs | 19 + .../applications/sheets/protection-sheet.mjs | 19 + modules/applications/sheets/sort-sheet.mjs | 19 + modules/heritiers-actor.js | 2 +- modules/heritiers-commands.js | 2 +- modules/heritiers-main.js | 59 +- modules/models/accessoire.mjs | 16 + modules/models/arme.mjs | 30 + modules/models/atoutfeerique.mjs | 11 + modules/models/avantage.mjs | 11 + modules/models/base-item.mjs | 11 + modules/models/capacitenaturelle.mjs | 21 + modules/models/competence.mjs | 43 + modules/models/contact.mjs | 12 + modules/models/desavantage.mjs | 11 + modules/models/equipement.mjs | 15 + modules/models/fee.mjs | 19 + modules/models/index.mjs | 24 + modules/models/personnage.mjs | 234 +++ modules/models/pnj.mjs | 10 + modules/models/pouvoir.mjs | 29 + modules/models/profil.mjs | 12 + modules/models/protection.mjs | 20 + modules/models/sort.mjs | 27 + package.json | 16 + system.json | 2 +- templates/actor-pnj-sheet.hbs | 547 ++++++ templates/actor-pnj-sheet.hbs.backup | 547 ++++++ templates/actor-sheet.hbs | 948 ++++++++++ templates/actor-sheet.hbs.backup | 948 ++++++++++ templates/chat-assommer-result.hbs | 30 + templates/chat-cc-result.hbs | 43 + templates/chat-generic-result.hbs | 145 ++ templates/editor-notes-gm.hbs | 6 + templates/item-accessoire-sheet.hbs | 38 + templates/item-arme-sheet.hbs | 134 ++ templates/item-atoutfeerique-sheet.hbs | 17 + templates/item-avantage-sheet.hbs | 17 + templates/item-capacitenaturelle-sheet.hbs | 79 + templates/item-competence-sheet.hbs | 81 + templates/item-contact-sheet.hbs | 22 + templates/item-desavantage-sheet.hbs | 17 + templates/item-equipement-sheet.hbs | 38 + templates/item-fee-sheet.hbs | 78 + templates/item-pouvoir-sheet.hbs | 157 ++ templates/item-profil-sheet.hbs | 20 + templates/item-protection-sheet.hbs | 65 + templates/item-sort-sheet.hbs | 134 ++ templates/partial-actor-equipment.hbs | 24 + templates/partial-item-description.hbs | 6 + templates/partial-item-header.hbs | 9 + templates/partial-item-nav.hbs | 6 + templates/partial-utile-skills.hbs | 49 + templates/post-item.hbs | 9 + templates/roll-dialog-generic.hbs | 168 ++ 75 files changed, 8232 insertions(+), 11 deletions(-) create mode 100644 gulpfile.js create mode 100644 less/heritiers.less create mode 100644 less/simple-converted.less create mode 100644 modules/applications/heritiers-roll-dialog.mjs create mode 100644 modules/applications/sheets/_module.mjs create mode 100644 modules/applications/sheets/accessoire-sheet.mjs create mode 100644 modules/applications/sheets/arme-sheet.mjs create mode 100644 modules/applications/sheets/atoutfeerique-sheet.mjs create mode 100644 modules/applications/sheets/avantage-sheet.mjs create mode 100644 modules/applications/sheets/base-actor-sheet.mjs create mode 100644 modules/applications/sheets/base-item-sheet.mjs create mode 100644 modules/applications/sheets/capacitenaturelle-sheet.mjs create mode 100644 modules/applications/sheets/competence-sheet.mjs create mode 100644 modules/applications/sheets/contact-sheet.mjs create mode 100644 modules/applications/sheets/desavantage-sheet.mjs create mode 100644 modules/applications/sheets/equipement-sheet.mjs create mode 100644 modules/applications/sheets/fee-sheet.mjs create mode 100644 modules/applications/sheets/personnage-sheet.mjs create mode 100644 modules/applications/sheets/pnj-sheet.mjs create mode 100644 modules/applications/sheets/pouvoir-sheet.mjs create mode 100644 modules/applications/sheets/profil-sheet.mjs create mode 100644 modules/applications/sheets/protection-sheet.mjs create mode 100644 modules/applications/sheets/sort-sheet.mjs create mode 100644 modules/models/accessoire.mjs create mode 100644 modules/models/arme.mjs create mode 100644 modules/models/atoutfeerique.mjs create mode 100644 modules/models/avantage.mjs create mode 100644 modules/models/base-item.mjs create mode 100644 modules/models/capacitenaturelle.mjs create mode 100644 modules/models/competence.mjs create mode 100644 modules/models/contact.mjs create mode 100644 modules/models/desavantage.mjs create mode 100644 modules/models/equipement.mjs create mode 100644 modules/models/fee.mjs create mode 100644 modules/models/index.mjs create mode 100644 modules/models/personnage.mjs create mode 100644 modules/models/pnj.mjs create mode 100644 modules/models/pouvoir.mjs create mode 100644 modules/models/profil.mjs create mode 100644 modules/models/protection.mjs create mode 100644 modules/models/sort.mjs create mode 100644 package.json create mode 100644 templates/actor-pnj-sheet.hbs create mode 100644 templates/actor-pnj-sheet.hbs.backup create mode 100644 templates/actor-sheet.hbs create mode 100644 templates/actor-sheet.hbs.backup create mode 100644 templates/chat-assommer-result.hbs create mode 100644 templates/chat-cc-result.hbs create mode 100644 templates/chat-generic-result.hbs create mode 100644 templates/editor-notes-gm.hbs create mode 100644 templates/item-accessoire-sheet.hbs create mode 100644 templates/item-arme-sheet.hbs create mode 100644 templates/item-atoutfeerique-sheet.hbs create mode 100644 templates/item-avantage-sheet.hbs create mode 100644 templates/item-capacitenaturelle-sheet.hbs create mode 100644 templates/item-competence-sheet.hbs create mode 100644 templates/item-contact-sheet.hbs create mode 100644 templates/item-desavantage-sheet.hbs create mode 100644 templates/item-equipement-sheet.hbs create mode 100644 templates/item-fee-sheet.hbs create mode 100644 templates/item-pouvoir-sheet.hbs create mode 100644 templates/item-profil-sheet.hbs create mode 100644 templates/item-protection-sheet.hbs create mode 100644 templates/item-sort-sheet.hbs create mode 100644 templates/partial-actor-equipment.hbs create mode 100644 templates/partial-item-description.hbs create mode 100644 templates/partial-item-header.hbs create mode 100644 templates/partial-item-nav.hbs create mode 100644 templates/partial-utile-skills.hbs create mode 100644 templates/post-item.hbs create mode 100644 templates/roll-dialog-generic.hbs diff --git a/gulpfile.js b/gulpfile.js new file mode 100644 index 0000000..97b0dd2 --- /dev/null +++ b/gulpfile.js @@ -0,0 +1,35 @@ +const gulp = require('gulp'); +const less = require('gulp-less'); +const sourcemaps = require('gulp-sourcemaps'); + +// Paths +const paths = { + styles: { + src: 'less/**/*.less', + dest: 'styles/' + } +}; + +// Compile LESS to CSS +function styles() { + return gulp.src('less/heritiers.less') + .pipe(sourcemaps.init()) + .pipe(less()) + .pipe(sourcemaps.write('.')) + .pipe(gulp.dest(paths.styles.dest)); +} + +// Watch files +function watchFiles() { + gulp.watch(paths.styles.src, styles); +} + +// Define complex tasks +const build = gulp.series(styles); +const watch = gulp.series(build, watchFiles); + +// Export tasks +exports.styles = styles; +exports.build = build; +exports.watch = watch; +exports.default = build; diff --git a/less/heritiers.less b/less/heritiers.less new file mode 100644 index 0000000..6f97dc3 --- /dev/null +++ b/less/heritiers.less @@ -0,0 +1,4 @@ +// Main LESS file for Les Héritiers system +// Temporarily importing the full converted simple.css while we refactor + +@import "simple-converted"; diff --git a/less/simple-converted.less b/less/simple-converted.less new file mode 100644 index 0000000..81165f3 --- /dev/null +++ b/less/simple-converted.less @@ -0,0 +1,1637 @@ + /* ==================== (A) Fonts ==================== */ + /* ==================== (A) Fonts ==================== */ + @font-face { + font-family: Charlemagne; + src: url('../assets/fonts/CharlemagneStd-Bold.otf') format("otf"); + } + + @font-face { + font-family: GismondaFG; + src: url('../assets/fonts/GismondaFG.woff') format("woff"); + } + + @font-face { + font-family: Garamond; + src: url('../assets/fonts/Garamond.woff') format("woff"); + } + + :root { + /* =================== 1. ACTOR SHEET FONT STYLES =========== */ + --window-header-font-family: GismondaFG; + --window-header-title-font-size: 1.1rem; + --window-header-title-font-weight: normal; + --window-header-title-color: #f5f5f5; + + --major-button-font-family: GismondaFG; + --major-button-font-size: 1.05rem; + --major-button-font-weight: normal; + --major-button-color: #dadada; + + --tab-header-font-family: GismondaFG; + --tab-header-font-size: 1.0rem; + --tab-header-font-weight: 700; + --tab-header-color: #403f3e; + --tab-header-color-active: #4a0404; + + --actor-input-font-size: 0.8rem; + --actor-input-font-weight: 500; + --actor-input-color: black; + + --actor-label-font-size: 0.8rem; + --actor-label-font-weight: 700; + --actor-label-color: #464331c4; + + /* =================== 2. DEBUGGING HIGHLIGHTERS ============ */ + --debug-background-color-red: #ff000054; + --debug-background-color-blue: #1d00ff54; + --debug-background-color-green: #54ff0054; + + --debug-box-shadow-red: inset 0 0 2px red; + --debug-box-shadow-blue: inset 0 0 2px blue; + --debug-box-shadow-green: inset 0 0 2px green; + } + + /*@import url("https://fonts.googleapis.com/css2?family=Martel:wght@400;800&family=Roboto:wght@300;400;500&display=swap");*/ + /* Global styles & Font */ + .window-app { + font-family: GismondaFG; + text-align: justify; + font-size: 12px; + letter-spacing: 1px; + background-image: url("../assets/ui/fiche_background_simple_01.webp"); + background-repeat: repeat; + } + + /* Fonts */ + .window-app .window-header, + #actors .directory-list, + #navigation #scene-list .scene.nav-item { + font-family: GismondaFG; + font-size: 0.8rem; + } + + /* For title, sidebar character and scene */ + .sheet header.sheet-header h1 input { + font-family: GismondaFG; + font-size: 0.8rem; + color: rgb(41, 38, 38); + } + + .sheet nav.sheet-tabs { + font-family: "GismondaFG"; + font-size: 0.8rem; + color: #151c1f; + } + + /* For nav and title */ + + .window-app input, + .fvtt-les-heritiers .item-form, + .sheet header.sheet-header .flex-group-center.flex-compteurs, + .sheet header.sheet-header .flex-group-center.flex-fatigue, + select, + button, + .item-checkbox, + #sidebar, + #players, + #navigation #nav-toggle { + font-size: 0.8rem; + } + + .fvtt-les-heritiers .sheet-header input, + .fvtt-les-heritiers .sheet-header select { + color: rgb(41, 38, 38); + } + + .window-header { + background: rgba(0, 0, 0, 0.75); + } + + .page-heading { + color: #151c1f; + } + + .window-app.sheet .window-content { + margin: 0; + padding: 0; + background-image: url("../assets/ui/fiche_background_simple_01.webp"); + background-repeat: repeat; + } + + .strong-text { + font-weight: bold; + } + + .tabs .item.active, + .blessures-list li ul li:first-child:hover, + a:hover { + text-shadow: 1px 0px 0px #ff6600; + } + + .rollable:hover, + .rollable:focus { + color: #000; + text-shadow: 0 0 10px red; + cursor: pointer; + } + + input:disabled { + color: #1c2058; + } + + select:disabled { + color: #1c2058; + } + + table { + border: 1px solid #7a7971; + } + + .grid, + .grid-2col { + display: grid; + grid-column: span 2 / span 2; + grid-template-columns: repeat(2, minmax(0, 1fr)); + gap: 10px; + margin: 10px 0; + padding: 0; + } + + .grid-3col { + grid-column: span 3 / span 3; + grid-template-columns: repeat(3, minmax(0, 1fr)); + } + + .grid-4col { + grid-column: span 4 / span 4; + grid-template-columns: repeat(4, minmax(0, 1fr)); + } + + .grid-5col { + grid-column: span 5 / span 5; + grid-template-columns: repeat(5, minmax(0, 1fr)); + } + + .grid-6col { + grid-column: span 5 / span 5; + grid-template-columns: repeat(5, minmax(0, 1fr)); + } + + .grid-7col { + grid-column: span 7 / span 7; + grid-template-columns: repeat(7, minmax(0, 1fr)); + } + + .grid-8col { + grid-column: span 8 / span 8; + grid-template-columns: repeat(8, minmax(0, 1fr)); + } + + .grid-9col { + grid-column: span 9 / span 9; + grid-template-columns: repeat(9, minmax(0, 1fr)); + } + + .grid-10col { + grid-column: span 10 / span 10; + grid-template-columns: repeat(10, minmax(0, 1fr)); + } + + .grid-11col { + grid-column: span 11 / span 11; + grid-template-columns: repeat(11, minmax(0, 1fr)); + } + + .grid-12col { + grid-column: span 12 / span 12; + grid-template-columns: repeat(12, minmax(0, 1fr)); + } + + .flex-group-center, + .flex-group-left, + .flex-group-right { + -webkit-box-pack: center; + -ms-flex-pack: center; + justify-content: center; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + text-align: center; + padding: 5px; + } + + .flex-group-left { + -webkit-box-pack: start; + -ms-flex-pack: start; + justify-content: flex-start; + text-align: left; + } + + .flex-group-right { + -webkit-box-pack: end; + -ms-flex-pack: end; + justify-content: flex-end; + text-align: right; + } + + .flex-center { + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + -webkit-box-pack: center; + -ms-flex-pack: center; + justify-content: center; + text-align: center; + } + + .table-create-actor { + font-size: 0.8rem; + } + + .flex-between { + -webkit-box-pack: justify; + -ms-flex-pack: justify; + justify-content: space-between; + } + + .flex-shrink { + flex: 'flex-shrink'; + } + + /* Styles limited to foundryvtt-vadentis sheets */ + + .fvtt-les-heritiers .sheet-header { + -webkit-box-flex: 0; + -ms-flex: 0 0 210px; + flex: 0 0 210px; + overflow: hidden; + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-orient: horizontal; + -webkit-box-direction: normal; + -ms-flex-direction: row; + flex-direction: row; + -ms-flex-wrap: wrap; + flex-wrap: wrap; + -webkit-box-pack: start; + -ms-flex-pack: start; + justify-content: flex-start; + margin-bottom: 10px; + background-image: url("../assets/ui/fiche_background_simple_01.webp"); + } + + .background-sheet-header { + background-image: url("../assets/ui/fiche_background_simple_01.webp"); + background-blend-mode: soft-light; + color: rgb(41, 38, 38); + } + + .fvtt-les-heritiers .sheet-header .profile-img { + -webkit-box-flex: 0; + -ms-flex: 0 0 128px; + flex: 0 0 128px; + height: 128px; + width: 128px; + margin-right: 10px; + object-fit: cover; + object-position: 50% 0; + } + + .button-img { + vertical-align: baseline; + width: 8%; + height: 8%; + max-height: 48px; + border-width: 0; + border: 1px solid rgba(0, 0, 0, 0); + } + + .button-img:hover { + color: rgba(255, 255, 128, 0.7); + border: 1px solid rgba(255, 128, 0, 0.8); + cursor: pointer; + } + + .button-effect-img { + vertical-align: baseline; + width: 16px; + max-height: 16px; + height: 16; + border-width: 0; + } + + .small-button-container { + height: 16px; + width: 16px; + border: 0; + vertical-align: bottom; + } + + .fvtt-les-heritiers .sheet-header .header-fields { + -webkit-box-flex: 1; + -ms-flex: 1; + flex: 1; + } + + .fvtt-les-heritiers .sheet-header h1.charname { + height: 50px; + padding: 0px; + margin: 5px 0; + border-bottom: 0; + font-weight: bold; + font-size: 2rem; + font-family: GismondaFG; + color: rgb(41, 38, 38); + } + + .fvtt-les-heritiers .sheet-header h1.charname input { + width: 100%; + height: 100%; + margin: 0; + font-weight: bold; + font-family: GismondaFG; + font-size: 2rem; + color: rgb(41, 38, 38); + } + + .fvtt-les-heritiers .sheet-tabs { + -webkit-box-flex: 0; + -ms-flex: 0; + flex: 0; + } + + .fvtt-les-heritiers .sheet-body, + .fvtt-les-heritiers .sheet-body .tab, + .fvtt-les-heritiers .sheet-body .tab .editor { + height: 100%; + font-size: 0.9rem; + font-family: Garamond; + color: rgba(0, 0, 0, 0.98) + } + + .fvtt-les-heritiers .sheet-body input, + .fvtt-les-heritiers .sheet-body select { + color: rgba(0, 0, 0, 0.9) + } + + .editor { + border: 2; + height: 300px; + margin-top: 8px; + padding: 0 3px; + } + + .medium-editor { + border: 2; + height: 240px; + padding: 0 3px; + } + + .small-editor { + border: 2; + height: 120px; + padding: 0 3px; + } + + .fvtt-les-heritiers .tox .tox-editor-container { + background: #fff; + } + + .fvtt-les-heritiers .tox .tox-edit-area { + padding: 0 8px; + } + + .fvtt-les-heritiers .resource-label { + font-weight: bold; + text-transform: uppercase; + } + + .fvtt-les-heritiers .tabs { + height: 40px; + border-top: 1px solid #AAA; + border-bottom: 1px solid #AAA; + color: #000000; + } + + .fvtt-les-heritiers .tabs .item { + /*line-height: 40px;*/ + font-weight: bold; + font-family: GismondaFG; + } + + .fvtt-les-heritiers .tabs .item.active { + text-decoration: underline; + text-shadow: none; + } + + .fvtt-les-heritiers .items-list { + list-style: none; + margin: 1px 0; + padding: 0; + overflow-y: auto; + } + + .fvtt-les-heritiers .items-list .item-header { + font-weight: bold; + } + + .fvtt-les-heritiers .items-list .item { + height: 30px; + line-height: 24px; + padding: 1px 0; + border-bottom: 1px solid #BBB; + } + + .fvtt-les-heritiers .items-list .item .item-image { + -webkit-box-flex: 0; + -ms-flex: 0 0 24px; + flex: 0 0 24px; + margin-right: 5px; + } + + .fvtt-les-heritiers .items-list .item img { + display: block; + } + + .fvtt-les-heritiers .items-list .item-name { + margin: 0; + } + + .fvtt-les-heritiers .items-list .item-controls { + -webkit-box-flex: 0; + -ms-flex: 0 0 86px; + flex: 0 0 86px; + text-align: right; + } + + + /* ======================================== */ + /* Sheet */ + .window-app.sheet .window-content .sheet-header { + /*background: #011d33 url("../images/ui/fond1.webp") repeat left top;*/ + background: url("../assets/ui/fiche_background_simple_01.webp"); + background-repeat: repeat; + } + + .window-app.sheet .window-content .sheet-header input[type="text"], + .window-app.sheet .window-content .sheet-header select, + .window-app.sheet .window-content .sheet-header input[type="number"], + .window-app.sheet .window-content .sheet-header input[type="password"], + .window-app.sheet .window-content .sheet-header input[type="date"], + .window-app.sheet .window-content .sheet-header input[type="time"] { + /*color: rgba(36, 37, 37, 0.75);*/ + /*background: rgba(255, 255, 255, 0.05);*/ + /*border: 2px saddlebrown;*/ + /*color: lightgray;*/ + border-width: 1px; + margin-bottom: 0.25rem; + } + + .window-app .window-content, + .window-app.sheet .window-content .sheet-body { + font-size: 0.8rem; + background: url("../assets/ui/fiche_background_simple_01.webp"); + background-repeat: repeat-y; + color: black; + } + + /*section.sheet-body{ + padding: 0.25rem 0.5rem;}*/ + + .sheet header.sheet-header .profile-img { + object-fit: cover; + object-position: 50% 0; + margin: 0.5rem 0 0.5rem 0.5rem; + padding: 0; + border: 0px; + } + + .sheet nav.sheet-tabs { + font-size: 0.70rem; + font-weight: bold; + height: 2.5rem; + flex: 0 0 3rem; + margin: 0; + padding: 0 0 0 0.25rem; + text-align: center; + text-transform: uppercase; + line-height: 1.5rem; + border-top: 0 none; + border-bottom: 0 none; + color: #cbdaa3; + background-image: url("../assets/ui/bandeau_01.webp"); + } + + nav.sheet-tabs a, + nav.sheet-tabs .item { + position: relative; + padding: 0 0.25rem; + color: beige; + } + + nav.sheet-tabs .item:after { + content: ""; + position: absolute; + top: 0; + right: 0; + height: 2rem; + width: 1px; + } + + .sheet .tab[data-tab] { + padding: 0; + } + + section.sheet-body:after { + content: ""; + display: block; + clear: both; + } + + .sheet header.sheet-header .flex-compteurs { + text-align: right; + } + + .sheet header.sheet-header .resource-content { + width: 2rem; + } + + .select-diff { + display: inline-block; + text-align: left; + width: 50px; + } + + .window-app.sheet .window-content .tooltip:hover .tooltiptext { + top: 2rem; + left: 2rem; + margin: 0; + padding: 0.25rem; + } + + .window-app.sheet .window-content .carac-value, + .window-app.sheet .window-content .competence-xp { + margin: 0.05rem; + flex-basis: 3rem; + text-align: center; + } + + /* ======================================== */ + /* Global UI elements */ + + /* ======================================== */ + + h1, + h2, + h3, + h4 { + font-weight: bold; + } + + ul, + ol { + margin: 0; + padding: 0; + } + + ul, + li { + list-style-type: none; + } + + .sheet li { + margin: 0.010rem; + padding: 0.25rem; + } + + .header-fields li { + margin: 0; + padding: 0; + } + + .alterne-list>.list-item:hover { + background: rgba(100, 100, 50, 0.25); + } + + .alterne-list>.list-item:nth-child(even) { + background: rgba(80, 60, 0, 0.10); + } + + .alterne-list>.list-item:nth-child(odd) { + background: rgb(160, 130, 100, 0.05); + } + + .specialisation-label { + font-size: 0.8rem; + font-style: italic; + } + + .carac-label, + .attr-label { + font-weight: bold; + } + + .list-item { + margin: 0.125rem; + box-shadow: inset 0px 0px 1px #00000096; + border-radius: 0.25rem; + padding: 0.125rem; + flex: 1 1 5rem; + } + + .item-display-show { + display: block; + } + + .item-display-hide { + display: none; + } + + .conteneur-type { + background: rgb(200, 10, 100, 0.25); + } + + .item-quantite { + margin-left: 0.5rem; + } + + .list-item-margin1 { + margin-left: 1rem; + } + + .list-item-margin2 { + margin-left: 2rem; + } + + .list-item-margin3 { + margin-left: 3rem; + } + + .list-item-margin4 { + margin-left: 4rem; + } + + .sheet-competence-img { + width: 24px; + height: 24px; + flex-grow: 0; + margin-right: 0.25rem; + } + + .competence-column { + flex-direction: column; + align-content: flex-start; + justify-content: flex-start; + flex-grow: 0; + flex-basis: 1; + } + + .competence-header { + align-content: flex-start; + justify-content: flex-start; + font-weight: bold; + flex-grow: 0; + } + + .secondaire-label, + .arme-label, + .generic-label, + .competence-label, + .devotion-label, + .sort-label, + .technique-label, + .stat-label, + .arme-label, + .armure-label, + .equipement-label, + .description-label { + flex-grow: 2; + margin-left: 4px; + } + + .roll-dialog-label { + margin: 4px 0; + padding-top: 7px; + } + + .roll-style { + background-color: rgba(56, 32, 32, 0.4); + border-radius: 0.25rem; + padding-left: 0.25rem; + margin-right: 0.25rem; + } + + .specialisarion-margin { + margin-left: 1.5rem; + } + + .short-label { + flex-grow: 1; + } + + .keyword-label { + font-size: 0.85rem; + } + + .item-sheet-label { + flex-grow: 1; + } + + .item-text-long-line { + flex-grow: 3; + } + + .score-label { + flex-grow: 2; + align-content: center; + } + + .attribut-value, + .carac-value { + flex-grow: 0; + flex-basis: 64px; + margin-right: 4px; + margin-left: 4px; + } + + .sante-value, + .competence-value { + flex-grow: 0; + flex-basis: 2rem; + margin-right: 0.25rem; + margin-left: 0.25rem; + } + + .description-value { + flex-grow: 0; + flex-basis: 4rem; + margin-right: 0.25rem; + margin-left: 0.25rem; + } + + .competence-xp { + flex-grow: 0; + flex-basis: 2rem; + margin-right: 0.25rem; + margin-left: 0.25rem; + } + + .blessures-title { + font-weight: bold; + } + + .alchimie-title { + font-weight: bold; + } + + .blessure-data { + flex-direction: row; + align-content: flex-start; + justify-content: flex-start; + } + + .blessures-soins { + flex-grow: 0; + flex-basis: 32px; + margin-right: 4px; + margin-left: 4px; + } + + .blessures-loc { + flex-grow: 0; + flex-basis: 96px; + margin-right: 4px; + margin-left: 4px; + } + + .pointsreve-value { + flex-grow: 0; + flex-basis: 64px; + margin-right: 4px; + margin-left: 4px; + } + + .input-sante-header, + .stress-style { + flex-grow: 0; + flex-basis: 64px; + margin-right: 4px; + margin-left: 4px; + } + + .small-label { + margin-top: 5px; + } + + .padd-right { + margin-right: 8px; + } + + .padd-left { + margin-left: 8px; + } + + .stack-left { + align-items: center; + flex-shrink: 1; + flex-grow: 0; + } + + .npc-stat-label { + flex-grow: 2; + } + + .packed-left { + white-space: nowrap; + flex-grow: 0; + } + + .numeric-input { + text-align: right; + direction: rtl; + padding: 5px; + } + + .input-numeric-short { + width: 40px; + max-width: 40px; + flex-grow: 0; + flex-shrink: 0; + flex-basis: 40px; + margin-right: 0.25rem; + margin-left: 0.25rem; + } + + .stats-table { + align-content: flex-start; + } + + /* ======================================== */ + .tokenhudext { + display: flex; + flex: 0 !important; + font-weight: 600; + } + + .tokenhudext.left { + justify-content: flex-start; + flex-direction: column; + position: absolute; + top: 2.75rem; + right: 4rem; + } + + .tokenhudext.right { + justify-content: flex-start; + flex-direction: column; + position: absolute; + top: 2.75rem; + left: 4rem; + } + + .control-icon.tokenhudicon { + width: fit-content; + height: fit-content; + min-width: 6rem; + min-height: 1.2rem; + flex-basis: auto; + padding: 0; + line-height: 1rem; + margin: 0.25rem; + } + + .control-icon.tokenhudicon.right { + margin-left: 8px; + } + + #token-hud .status-effects.active { + z-index: 2; + } + + /* ======================================== */ + .item-checkbox { + height: 25px; + border: 1px solid #736953a6; + border-left: none; + font-weight: 500; + font-size: 1rem; + color: black; + padding-top: 5px; + margin-right: 0px; + width: 45px; + position: relative; + left: 0px; + text-align: center; + } + + + .flex-actions-bar { + flex-grow: 2; + } + + /* ======================================== */ + /* Sidebar CSS */ + #sidebar { + font-size: 1rem; + background-position: 100%; + color: rgba(220, 220, 220, 0.75); + } + + /* background: rgb(105,85,65) url("../images/ui/texture_feuille_perso_onglets.webp") no-repeat right bottom;*/ + + #sidebar.collapsed { + height: 470px !important; + } + + #sidebar-tabs>.collapsed, + #chat-controls .chat-control-icon { + color: rgba(220, 220, 220, 0.75); + text-shadow: 1px 1px 0 rgba(0, 0, 0, 0.75); + } + + .sidebar-tab .directory-list .entity { + border-top: 1px dashed rgba(0, 0, 0, 0.25); + border-bottom: 0 none; + padding: 0.25rem 0; + } + + .sidebar-tab .directory-list .entity:hover { + background: rgba(0, 0, 0, 0.05); + cursor: pointer; + } + + .chat-message-header { + background: rgba(220, 220, 210, 0.5); + font-size: 1.1rem; + height: 48px; + text-align: center; + vertical-align: middle; + display: flex; + align-items: center; + } + + .chat-message .message-header .flavor-text, + .chat-message .message-header .whisper-to { + font-size: 0.9rem; + } + + .chat-actor-name { + padding: 4px; + } + + .chat-img { + width: 64px; + height: 64px; + } + + .roll-dialog-header { + height: 52px; + } + + .adversite-text { + font-weight: bold; + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + } + + .icon-adversite-container { + position: relative; + text-align: center; + color: white; + width: 64px; + min-height: 48px; + } + + .icon-adversite { + width: 48px; + border: 0px; + } + + .hud-adversite-container { + position: relative; + text-align: center; + color: white; + width: 64px; + min-height: 64px; + } + + .hud-adversite-text { + font-weight: bold; + font-size: 0.9rem; + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -85%); + } + + .actor-icon { + float: left; + width: 48px; + height: 48px; + padding: 2px 6px 2px 2px; + } + + .padding-dice { + padding-top: .2rem; + padding-bottom: .2rem; + } + + .dice-image { + box-sizing: border-box; + border: none; + border-radius: 0; + max-width: 100%; + } + + .dice-image-reroll { + background-color: rgba(115, 224, 115, 0.25); + border-color: #011d33; + box-sizing: border-box; + border: 1px; + border-radius: 0%; + max-width: 100%; + } + + .chat-dice { + width: 15%; + height: 15%; + font-size: 15px; + padding: 10px; + padding-bottom: 20px; + padding-top: .2rem; + padding-bottom: .2rem; + } + + .div-river-full { + height: 5rem; + align-items: flex-start; + } + + .div-river { + align-content: center; + margin-left: 8px; + align-content: space-around; + justify-content: space-around; + } + + .div-center { + align-self: center; + } + + .chat-message { + background: rgba(220, 220, 210, 0.5); + font-size: 0.9rem; + } + + .chat-message.whisper { + background: rgba(220, 220, 210, 0.75); + border: 2px solid #545469; + } + + .chat-message .chat-icon { + border: 0; + padding: 2px 6px 2px 2px; + float: left; + width: 64px; + height: 64px; + } + + #sidebar-tabs { + flex: 0 0 32px; + box-sizing: border-box; + margin: 0 0 5px; + border-bottom: 1px solid rgba(0, 0, 0, 0); + box-shadow: inset 0 0 2rem rgba(0, 0, 0, 0.5); + } + + #sidebar-tabs>.item.active { + border: 1px solid rgba(114, 98, 72, 1); + background: rgba(30, 25, 20, 0.75); + box-shadow: 0 0 6px inset rgba(114, 98, 72, 1); + } + + #sidebar #sidebar-tabs i { + display: inline-block; + background-position: center; + background-size: cover; + text-shadow: 1px 1px 0 rgba(0, 0, 0, 0.75); + + } + + /*--------------------------------------------------------------------------*/ + /* Control, Tool, hotbar & navigation */ + + #controls .scene-control, + #controls .control-tool { + box-shadow: 0 0 3px #000; + margin: 0 0 8px; + border-radius: 0; + background: rgba(30, 25, 20, 1); + background-origin: padding-box; + border-image: url(img/ui/footer-button.png) 10 repeat; + border-image-width: 4px; + border-image-outset: 0px; + } + + #controls .scene-control.active, + #controls .control-tool.active, + #controls .scene-control:hover, + #controls .control-tool:hover { + background: rgba(72, 46, 28, 1); + background-origin: padding-box; + border-image: url(img/ui/footer-button.png) 10 repeat; + border-image-width: 4px; + border-image-outset: 0px; + box-shadow: 0 0 3px #ff6400; + } + + #hotbar #action-bar #macro-list { + border: 1px solid rgba(72, 46, 28, 1); + box-shadow: 2px 2px 5px #000000; + } + + #hotbar #action-bar .macro { + border-image: url(img/ui/bg_control.jpg) 21 repeat; + border-image-slice: 6 6 6 6 fill; + border-image-width: 6px 6px 6px 6px; + border-image-outset: 0px 0px 0px 0px; + border-radius: 0px; + } + + #hotbar .bar-controls { + background: rgba(30, 25, 20, 1); + border: 1px solid rgba(72, 46, 28, 1); + } + + #players { + border-image: url(img/ui/footer-button.png) 10 repeat; + border-image-width: 4px; + border-image-outset: 0px; + background: rgba(30, 25, 20, 1); + } + + #navigation #scene-list .scene.nav-item.active { + background: rgba(72, 46, 28, 1); + } + + #navigation #scene-list .scene.nav-item { + background: rgba(30, 25, 20, 1); + background-origin: padding-box; + border-image: url(img/ui/footer-button.png) 10 repeat; + border-image-width: 4px; + border-image-outset: 0px; + } + + #navigation #scene-list .scene.view, + #navigation #scene-list .scene.context { + background: rgba(72, 46, 28, 1); + background-origin: padding-box; + border-image: url(img/ui/footer-button.png) 10 repeat; + border-image-width: 4px; + border-image-outset: 0px; + box-shadow: 0 0 3px #ff6400; + } + + #navigation #nav-toggle { + background: rgba(30, 25, 20, 1); + background-origin: padding-box; + border-image: url(img/ui/footer-button.png) 10 repeat; + border-image-width: 4px; + border-image-outset: 0px; + } + + /* Tooltip container */ + .tooltip { + position: relative; + display: inline-block; + /*border-bottom: 1px dotted black; /* If you want dots under the hoverable text */ + } + + /* Tooltip text */ + .tooltip .tooltiptext { + text-align: left; + background: rgba(231, 229, 226, 0.9); + width: 150px; + padding: 3px 0; + font-size: 0.9rem; + + /* Position the tooltip text */ + top: 1px; + position: absolute; + z-index: 1; + + /* Fade in tooltip */ + visibility: hidden; + opacity: 0; + transition: opacity 0.3s; + } + + .tooltip .ttt-fatigue { + width: 360px; + + background: rgba(30, 25, 20, 0.9); + border-image: url(img/ui/bg_control.jpg) 21 repeat; + border-image-slice: 6 6 6 6 fill; + border-image-width: 6px 6px 6px 6px; + border-image-outset: 0px 0px 0px 0px; + border-radius: 0px; + + font-size: 0.8rem; + padding: 3px 0; + } + + .tooltip .ttt-ajustements { + width: 150px; + background: rgba(220, 220, 210, 0.95); + border-radius: 6px; + font-size: 0.9rem; + padding: 3px 0; + } + + .tooltip-nobottom { + border-bottom: unset; + /* If you want dots under the hoverable text */ + } + + .tooltip .ttt-xp { + width: 250px; + background: rgba(220, 220, 210, 0.95); + border-radius: 6px; + font-size: 0.9rem; + padding: 3px 0; + } + + /* Show the tooltip text when you mouse over the tooltip container */ + .tooltip:hover .tooltiptext { + visibility: visible; + opacity: 1; + } + + .chat-card-button { + box-shadow: inset 0px 1px 0px 0px #a6827e; + background-image: url("../assets/ui/bandeau_01.webp"); + /*background-color: #7d5d3b00;*/ + border-radius: 3px; + border: 2px ridge #846109; + display: inline-block; + cursor: pointer; + color: #ffffff; + font-size: 0.8rem; + padding: 4px 4px 0px 4px; + text-decoration: none; + text-shadow: 0px 1px 0px #4d3534; + position: relative; + /*margin:2px;*/ + } + + .chat-card-button:hover { + background: linear-gradient(to bottom, #800000 5%, #3e0101 60%); + /*background-color: rgba(56, 33, 33, 60);*/ + } + + .chat-card-button:active { + position: relative; + top: 1px; + } + + h4.entry-name.document-name { + color: #f3eeee; + } + + .compendium h4.entry-name.document-name { + color: black; + } + + .fxmaster { + background: #443e37E0; + background-color: #443e37E0; + } + + .button-sheet-roll { + box-shadow: inset 0px 1px 0px 0px #a6827e; + background: linear-gradient(to bottom, #41545a 5%, #2e5561 100%); + background-color: #7d5d3b00; + border-radius: 4px; + border: 1px ridge #846109; + display: inline-block; + cursor: pointer; + color: #ffffff; + font-size: 0.8rem; + padding: 1px 1px 0px 1px; + text-decoration: none; + text-shadow: 0px 1px 0px #4d3534; + position: relative; + max-height: 1.7rem; + flex-grow: 1; + max-width: 3.9rem; + min-width: 3.9rem; + } + + .sheet.journal-entry.application .journal-sidebar .toc .page-heading .page-title { + color: beige; + } + + .button-sheet-roll:hover { + background: linear-gradient(to bottom, #800000 5%, #3e0101 100%); + background-color: rgb(56, 33, 33); + } + + .roll-tricherie-2 { + margin: 2px 2px 2px 2px; + box-shadow: inset 0px 1px 0px 0px #a6827e; + background: linear-gradient(to bottom, #41545a 5%, #2e5561 100%); + background-color: #7d5d3b00; + border-radius: 4px; + border: 1px ridge #846109; + padding: 1px 1px 0px 1px; + text-decoration: none; + text-shadow: 0px 1px 0px #4d3534; + color: beige; + } + + .button-sheet-roll:active { + position: relative; + top: 1px; + } + + .button-sheet-roll-long1 { + max-width: 6.1rem; + min-width: 6.1rem; + } + + .defense-sheet { + border-radius: 4px; + text-align: center; + display: inline-block; + font-size: 0.8rem; + padding: 1px 1px 0px 1px; + text-decoration: none; + position: relative; + max-height: 1.7rem; + margin-left: 4px; + flex-grow: 1; + max-width: 3.5rem; + min-width: 3.5rem; + } + + .plus-minus-button { + box-shadow: inset 0px 1px 0px 0px #a6827e; + background: linear-gradient(to bottom, #21374afc 5%, #152833ab 100%); + background-color: #7d5d3b00; + border-radius: 4px; + border: 2px ridge #846109; + display: inline-block; + cursor: pointer; + color: #ffffff; + padding: 3px 6px 2px 6px; + text-decoration: none; + text-shadow: 0px 1px 0px #4d3534; + position: relative; + margin: 3px; + max-width: 24px; + max-height: 24px; + } + + .river-button:hover, + .plus-minus-button:hover, + .chat-card-button:hover { + background: linear-gradient(to bottom, #800000 5%, #3e0101 100%); + background-color: red; + } + + .plus-minus-button:active, + .chat-card-button:active { + position: relative; + top: 1px; + } + + .plus-minus { + font-size: 0.9rem; + font-weight: bold; + } + + .ul-level1 { + padding-left: 2rem; + } + + .drop-equipment-effect, + .drop-power-effect, + .drop-perk-effect, + .drop-ability-effect, + .drop-effect-specaffected, + .drop-effect-spec, + .drop-ability-weapon, + .drop-ability-armor, + .drop-race-perk, + .drop-spec-perk, + .drop-ability-power, + .drop-ability-spec, + .drop-spec-power, + .drop-abilities, + .drop-optionnal-abilities, + .drop-specialperk1, + .drop-perk2, + .drop-spec1, + .drop-spec2 { + background: linear-gradient(to bottom, #6c95b9fc 5%, #105177ab 100%); + background-color: #7d5d3b00; + border-radius: 3px; + border: 2px ridge #846109; + } + + .label-name { + padding-top: 7px; + padding-left: 4px; + margin-left: 4px; + min-width: 5rem; + max-width: 5rem; + } + + /*************************************************************/ + .competence-name { + padding-top: 7px; + padding-left: 4px; + margin-left: 4px; + flex-grow: 2; + } + + /*************************************************************/ + .competence-niveau { + flex-grow: 1; + min-width: 64px; + max-width: 64px; + } + + /*************************************************************/ + .arme-defensif { + padding-top: 7px; + text-align: center; + flex-grow: 2; + } + + /*************************************************************/ + .magie-text-helper { + font-size: 0.8rem; + font-style: italic; + margin-left: 12px; + max-width: 95%; + text-align: justify; + } + + /*************************************************************/ + .item-name-img { + flex-grow: 1; + max-width: 2rem; + min-width: 2rem; + max-height: 2rem; + margin-right: 4px; + } + + /*************************************************************/ + #pause { + font-size: 2rem; + } + + #pause>h3 { + color: #CCC + } + + #pause>img { + content: url(../assets/ui/pause_heritier.webp); + height: 256px; + width: 256px; + top: -80px; + left: calc(50% - 132px); + } + + #logo { + content: url(../assets/ui/logo_main_01.webp); + width: 120px; + height: 40px; + } + + .dice-cell { + padding-left: 12px; + padding-right: 12px; + width: 60px; + text-align: center; + } + + .dice-formula, + .dice-total { + height: 54px; + position: relative; + } + + .item-name-label-header { + flex-grow: 2; + max-width: 12rem; + min-width: 12rem; + } + + .item-name-label { + flex-grow: 2; + max-width: 10rem; + min-width: 10rem; + } + + .item-name-label-level2 { + flex-grow: 2; + max-width: 9rem; + min-width: 9rem; + } + + .item-field-label-short { + padding-top: 6px; + flex-grow: 1; + max-width: 4rem; + min-width: 4rem; + } + + .item-field-label-short-num { + padding-top: 6px; + flex-grow: 1; + max-width: 2rem; + min-width: 2rem; + } + + .item-field-label-medium { + padding-top: 6px; + flex-grow: 1; + max-width: 6rem; + min-width: 6rem; + } + + .item-field-label-long { + padding-top: 6px; + flex-grow: 1; + max-width: 8rem; + min-width: 8rem; + } + + .item-field-label-long2 { + padding-top: 6px; + flex-grow: 1; + max-width: 14rem; + min-width: 14rem; + } + + .item-field-label-long2-img { + max-width: 16rem; + min-width: 16rem; + } + + .item-field-label-long3 { + padding-top: 6px; + flex-grow: 1; + max-width: 20rem; + min-width: 20rem; + } + + .item-control-end { + align-self: flex-end; + } + + .alternate-list { + margin-top: 2px; + flex-wrap: nowrap; + } + + .item-filler { + flex-grow: 6; + flex-shrink: 7; + } + + .item-controls-fixed { + margin-left: 0.5rem; + min-width: 3.2rem; + max-width: 3.2rem; + } + + .item-field { + justify-content: flex-start; + flex-grow: 1; + } + + .chat-success { + font-size: 1.2rem; + font-weight: bold; + color: darkgreen; + } + + .chat-failure { + font-size: 1.2rem; + font-weight: bold; + color: darkred; + } + + .adversite-modify { + margin-top: 12px; + } + + .argent-total-text { + margin-left: 4px; + } \ No newline at end of file diff --git a/modules/applications/heritiers-roll-dialog.mjs b/modules/applications/heritiers-roll-dialog.mjs new file mode 100644 index 0000000..53203e5 --- /dev/null +++ b/modules/applications/heritiers-roll-dialog.mjs @@ -0,0 +1,311 @@ +import { HeritiersUtility } from "../heritiers-utility.js" + +/** + * Dialogue de jet de dé pour Les Héritiers - Version AppV2 + */ +export class HeritiersRollDialog { + + /** + * Create and display the roll dialog + * @param {HeritiersActor} actor - The actor making the roll + * @param {Object} rollData - Data for the roll + * @returns {Promise} - Returns a dialog-like object for compatibility + */ + static async create(actor, rollData) { + // Préparer le contexte pour le template + const context = { + ...rollData, + img: actor.img, + name: actor.name, + config: game.system.lesheritiers.config, + } + + // Rendre le template en HTML + const content = await foundry.applications.handlebars.renderTemplate( + "systems/fvtt-les-heritiers/templates/roll-dialog-generic.hbs", + context + ) + + // Préparer les boutons selon le mode et le niveau + const buttons = this._prepareButtons(rollData) + + // Lancer le dialog de manière asynchrone (sans attendre) + setTimeout(() => { + foundry.applications.api.DialogV2.wait({ + window: { title: "Test de Capacité", icon: "fa-solid fa-dice" }, + classes: ["heritiers-roll-dialog"], + position: { width: 420, height: 'fit-content' }, + modal: false, + content, + buttons, + rejectClose: false, + render: (event, html) => { + this._activateListeners(html, rollData) + } + }) + }, 0) + + // Retourner un objet avec une méthode render() vide pour compatibilité + return { + render: () => {} // No-op for compatibility with old code + } + } + + /** + * Préparer les boutons selon le mode et le niveau de compétence + * @param {Object} rollData - Data for the roll + * @returns {Array} - Array of button configurations + * @private + */ + static _prepareButtons(rollData) { + const buttons = [] + + // Bouton d8 toujours disponible + buttons.push({ + action: "rolld8", + label: "Lancer 1d8", + icon: "fa-solid fa-dice-d8", + default: true, + callback: (event, button, dialog) => { + this._updateRollDataFromForm(rollData, button.form.elements) + this._executeRoll(rollData, "d8") + } + }) + + // Bouton d10 si niveau > 0 ou pouvoir + const enableD10 = rollData.mode === "pouvoir" || rollData.competence?.system.niveau > 0 + if (enableD10) { + buttons.push({ + action: "rolld10", + label: "Lancer 1d10", + icon: "fa-solid fa-dice-d10", + callback: (event, button, dialog) => { + this._updateRollDataFromForm(rollData, button.form.elements) + this._executeRoll(rollData, "d10") + } + }) + } + + // Bouton d12 si niveau > 1 ou pouvoir + const enableD12 = rollData.mode === "pouvoir" || rollData.competence?.system.niveau > 1 + if (enableD12) { + buttons.push({ + action: "rolld12", + label: "Lancer 1d12", + icon: "fa-solid fa-dice-d12", + callback: (event, button, dialog) => { + this._updateRollDataFromForm(rollData, button.form.elements) + this._executeRoll(rollData, "d12") + } + }) + } + + // Bouton Tricherie si disponible + if (rollData.tricherie) { + buttons.push({ + action: "rollTricherie", + label: "Lancer avec 1 Point de Tricherie", + icon: "fa-solid fa-mask", + callback: (event, button, dialog) => { + this._updateRollDataFromForm(rollData, button.form.elements) + this._executeRoll(rollData, "tricherie") + } + }) + } + + // Bouton Héritage si disponible + if (rollData.heritage) { + buttons.push({ + action: "rollHeritage", + label: "Lancer avec 1 Point d'Héritage", + icon: "fa-solid fa-crown", + callback: (event, button, dialog) => { + this._updateRollDataFromForm(rollData, button.form.elements) + this._executeRoll(rollData, "heritage") + } + }) + } + + // Si mode carac uniquement, on ne garde que d8 + if (rollData.mode === "carac") { + return [ + { + action: "rolld8", + label: "Lancer 1d8", + icon: "fa-solid fa-dice-d8", + default: true, + callback: (event, button, dialog) => { + this._updateRollDataFromForm(rollData, button.form.elements) + this._executeRoll(rollData, "d8") + } + } + ] + } + + return buttons + } + + /** + * Activer les listeners sur le formulaire + * @param {HTMLElement} html - L'élément HTML du dialog + * @param {Object} rollData - Data for the roll + * @private + */ + static _activateListeners(html, rollData) { + // Seuil de Difficulté + const sdValue = html.querySelector('#sdValue') + if (sdValue) { + sdValue.addEventListener('change', (event) => { + rollData.sdValue = Number(event.currentTarget.value) + }) + } + + // Caractéristique + const caracKey = html.querySelector('#caracKey') + if (caracKey) { + caracKey.addEventListener('change', (event) => { + rollData.caracKey = String(event.currentTarget.value) + }) + } + + // Bonus/Malus contextuel + const bonusMalusContext = html.querySelector('#bonus-malus-context') + if (bonusMalusContext) { + bonusMalusContext.addEventListener('change', (event) => { + rollData.bonusMalusContext = Number(event.currentTarget.value) + }) + } + + // Attaque à plusieurs + const bonusAttaquePlusieurs = html.querySelector('#bonus-attaque-plusieurs') + if (bonusAttaquePlusieurs) { + bonusAttaquePlusieurs.addEventListener('change', (event) => { + rollData.bonusAttaquePlusieurs = Number(event.currentTarget.value) + }) + } + + // Spécialité + const useSpecialite = html.querySelector('#useSpecialite') + if (useSpecialite) { + useSpecialite.addEventListener('change', (event) => { + rollData.useSpecialite = event.currentTarget.checked + }) + } + + // Points d'usage du pouvoir + const pouvoirPointsUsage = html.querySelector('#pouvoirPointsUsage') + if (pouvoirPointsUsage) { + pouvoirPointsUsage.addEventListener('change', (event) => { + rollData.pouvoirPointsUsage = Number(event.currentTarget.value) + }) + } + + // Attaque dans le dos + const attaqueDos = html.querySelector('#attaqueDos') + if (attaqueDos) { + attaqueDos.addEventListener('change', (event) => { + rollData.attaqueDos = event.currentTarget.checked + }) + } + + // Seconde arme + const secondeArme = html.querySelector('#bonus-attaque-seconde-arme') + if (secondeArme) { + secondeArme.addEventListener('change', (event) => { + rollData.secondeArme = String(event.currentTarget.value) + }) + } + + // Attaque ciblée + const attaqueCible = html.querySelector('#attaque-cible') + if (attaqueCible) { + attaqueCible.addEventListener('change', (event) => { + rollData.attaqueCible = String(event.currentTarget.value) + }) + } + + // Attaque à deux armes + const attaqueDeuxArmes = html.querySelector('#bonus-attaque-deux-armes') + if (attaqueDeuxArmes) { + attaqueDeuxArmes.addEventListener('change', (event) => { + rollData.attaqueDeuxArmes = Number(event.currentTarget.value) + }) + } + } + + /** + * Mettre à jour rollData avec les valeurs du formulaire + * @param {Object} rollData - L'objet rollData à mettre à jour + * @param {HTMLFormControlsCollection} formElements - Les éléments du formulaire + * @private + */ + static _updateRollDataFromForm(rollData, formElements) { + // Seuil de Difficulté + if (formElements.sdValue) { + rollData.sdValue = Number(formElements.sdValue.value) + } + + // Caractéristique + if (formElements.caracKey) { + rollData.caracKey = String(formElements.caracKey.value) + } + + // Bonus/Malus contextuel + if (formElements['bonus-malus-context']) { + rollData.bonusMalusContext = Number(formElements['bonus-malus-context'].value) + } + + // Attaque à plusieurs + if (formElements['bonus-attaque-plusieurs']) { + rollData.bonusAttaquePlusieurs = Number(formElements['bonus-attaque-plusieurs'].value) + } + + // Spécialité + if (formElements.useSpecialite !== undefined) { + rollData.useSpecialite = formElements.useSpecialite.checked + } + + // Points d'usage du pouvoir + if (formElements.pouvoirPointsUsage) { + rollData.pouvoirPointsUsage = Number(formElements.pouvoirPointsUsage.value) + } + + // Attaque dans le dos + if (formElements.attaqueDos !== undefined) { + rollData.attaqueDos = formElements.attaqueDos.checked + } + + // Seconde arme + if (formElements['bonus-attaque-seconde-arme']) { + rollData.secondeArme = String(formElements['bonus-attaque-seconde-arme'].value) + } + + // Attaque ciblée + if (formElements['attaque-cible']) { + rollData.attaqueCible = String(formElements['attaque-cible'].value) + } + + // Attaque à deux armes + if (formElements['bonus-attaque-deux-armes']) { + rollData.attaqueDeuxArmes = Number(formElements['bonus-attaque-deux-armes'].value) + } + } + + /** + * Exécuter le jet de dés + * @param {Object} rollData - Data for the roll + * @param {String} dice - Type de dé (d8, d10, d12, tricherie, heritage) + * @private + */ + static _executeRoll(rollData, dice) { + if (dice === "heritage") { + rollData.useHeritage = true + } else if (dice === "tricherie") { + rollData.useTricherie = true + } else { + rollData.mainDice = dice + } + + HeritiersUtility.rollHeritiers(rollData) + } +} diff --git a/modules/applications/sheets/_module.mjs b/modules/applications/sheets/_module.mjs new file mode 100644 index 0000000..ce7d6f0 --- /dev/null +++ b/modules/applications/sheets/_module.mjs @@ -0,0 +1,23 @@ +/** + * Export all application sheets for Les Héritiers + */ + +// Actor Sheets +export { default as HeritiersPersonnageSheet } from './personnage-sheet.mjs'; +export { default as HeritiersPnjSheet } from './pnj-sheet.mjs'; + +// Item Sheets +export { default as HeritiersAccessoireSheet } from './accessoire-sheet.mjs'; +export { default as HeritiersArmeSheet } from './arme-sheet.mjs'; +export { default as HeritiersAtoutFeeriqueSheet } from './atoutfeerique-sheet.mjs'; +export { default as HeritiersAvantageSheet } from './avantage-sheet.mjs'; +export { default as HeritiersCapaciteNaturelleSheet } from './capacitenaturelle-sheet.mjs'; +export { default as HeritiersCompetenceSheet } from './competence-sheet.mjs'; +export { default as HeritiersContactSheet } from './contact-sheet.mjs'; +export { default as HeritiersDesavantageSheet } from './desavantage-sheet.mjs'; +export { default as HeritiersEquipementSheet } from './equipement-sheet.mjs'; +export { default as HeritiersFeeSheet } from './fee-sheet.mjs'; +export { default as HeritiersPouvoirSheet } from './pouvoir-sheet.mjs'; +export { default as HeritiersProfilSheet } from './profil-sheet.mjs'; +export { default as HeritiersProtectionSheet } from './protection-sheet.mjs'; +export { default as HeritiersSortSheet } from './sort-sheet.mjs'; diff --git a/modules/applications/sheets/accessoire-sheet.mjs b/modules/applications/sheets/accessoire-sheet.mjs new file mode 100644 index 0000000..40f4ae1 --- /dev/null +++ b/modules/applications/sheets/accessoire-sheet.mjs @@ -0,0 +1,19 @@ +import HeritiersItemSheet from "./base-item-sheet.mjs" + +export default class HeritiersAccessoireSheet extends HeritiersItemSheet { + /** @override */ + static DEFAULT_OPTIONS = { + ...super.DEFAULT_OPTIONS, + window: { + ...super.DEFAULT_OPTIONS.window, + title: "SHEETS.Item.accessoire", + }, + } + + /** @override */ + static PARTS = { + sheet: { + template: "systems/fvtt-les-heritiers/templates/item-accessoire-sheet.html", + }, + } +} diff --git a/modules/applications/sheets/arme-sheet.mjs b/modules/applications/sheets/arme-sheet.mjs new file mode 100644 index 0000000..abe514c --- /dev/null +++ b/modules/applications/sheets/arme-sheet.mjs @@ -0,0 +1,19 @@ +import HeritiersItemSheet from "./base-item-sheet.mjs" + +export default class HeritiersArmeSheet extends HeritiersItemSheet { + /** @override */ + static DEFAULT_OPTIONS = { + ...super.DEFAULT_OPTIONS, + window: { + ...super.DEFAULT_OPTIONS.window, + title: "SHEETS.Item.arme", + }, + } + + /** @override */ + static PARTS = { + sheet: { + template: "systems/fvtt-les-heritiers/templates/item-arme-sheet.html", + }, + } +} diff --git a/modules/applications/sheets/atoutfeerique-sheet.mjs b/modules/applications/sheets/atoutfeerique-sheet.mjs new file mode 100644 index 0000000..3c35a2b --- /dev/null +++ b/modules/applications/sheets/atoutfeerique-sheet.mjs @@ -0,0 +1,19 @@ +import HeritiersItemSheet from "./base-item-sheet.mjs" + +export default class HeritiersAtoutFeeriqueSheet extends HeritiersItemSheet { + /** @override */ + static DEFAULT_OPTIONS = { + ...super.DEFAULT_OPTIONS, + window: { + ...super.DEFAULT_OPTIONS.window, + title: "SHEETS.Item.atoutfeerique", + }, + } + + /** @override */ + static PARTS = { + sheet: { + template: "systems/fvtt-les-heritiers/templates/item-atoutfeerique-sheet.html", + }, + } +} diff --git a/modules/applications/sheets/avantage-sheet.mjs b/modules/applications/sheets/avantage-sheet.mjs new file mode 100644 index 0000000..448a574 --- /dev/null +++ b/modules/applications/sheets/avantage-sheet.mjs @@ -0,0 +1,19 @@ +import HeritiersItemSheet from "./base-item-sheet.mjs" + +export default class HeritiersAvantageSheet extends HeritiersItemSheet { + /** @override */ + static DEFAULT_OPTIONS = { + ...super.DEFAULT_OPTIONS, + window: { + ...super.DEFAULT_OPTIONS.window, + title: "SHEETS.Item.avantage", + }, + } + + /** @override */ + static PARTS = { + sheet: { + template: "systems/fvtt-les-heritiers/templates/item-avantage-sheet.html", + }, + } +} diff --git a/modules/applications/sheets/base-actor-sheet.mjs b/modules/applications/sheets/base-actor-sheet.mjs new file mode 100644 index 0000000..4109f2c --- /dev/null +++ b/modules/applications/sheets/base-actor-sheet.mjs @@ -0,0 +1,618 @@ +const { HandlebarsApplicationMixin } = foundry.applications.api + +import { HeritiersUtility } from "../../heritiers-utility.js" + +export default class HeritiersActorSheet extends HandlebarsApplicationMixin(foundry.applications.sheets.ActorSheetV2) { + /** + * Different sheet modes. + * @enum {number} + */ + static SHEET_MODES = { EDIT: 0, PLAY: 1 } + + constructor(options = {}) { + super(options) + this.#dragDrop = this.#createDragDropHandlers() + this._sheetMode = this.constructor.SHEET_MODES.PLAY + } + + #dragDrop + + /** @override */ + static DEFAULT_OPTIONS = { + classes: ["fvtt-les-heritiers", "sheet", "actor"], + position: { + width: 780, + height: 840, + }, + window: { + resizable: true, + }, + form: { + submitOnChange: true, + closeOnSubmit: false, + }, + dragDrop: [{ dragSelector: ".item-list .item", dropSelector: "form" }], + actions: { + editImage: HeritiersActorSheet.#onEditImage, + toggleSheet: HeritiersActorSheet.#onToggleSheet, + editItem: HeritiersActorSheet.#onEditItem, + deleteItem: HeritiersActorSheet.#onDeleteItem, + createItem: HeritiersActorSheet.#onCreateItem, + equipItem: HeritiersActorSheet.#onEquipItem, + modifyQuantity: HeritiersActorSheet.#onModifyQuantity, + rollInitiative: HeritiersActorSheet.#onRollInitiative, + rollCarac: HeritiersActorSheet.#onRollCarac, + rollRang: HeritiersActorSheet.#onRollRang, + rollRootCompetence: HeritiersActorSheet.#onRollRootCompetence, + rollCompetence: HeritiersActorSheet.#onRollCompetence, + rollSort: HeritiersActorSheet.#onRollSort, + rollAttaqueArme: HeritiersActorSheet.#onRollAttaqueArme, + rollAttaqueBrutaleArme: HeritiersActorSheet.#onRollAttaqueBrutaleArme, + rollAttaqueChargeArme: HeritiersActorSheet.#onRollAttaqueChargeArme, + rollAssomerArme: HeritiersActorSheet.#onRollAssomerArme, + rollPouvoir: HeritiersActorSheet.#onRollPouvoir, + toggleMasque: HeritiersActorSheet.#onToggleMasque, + dialogRecupUsage: HeritiersActorSheet.#onDialogRecupUsage, + }, + } + + /** + * Is the sheet currently in 'Play' mode? + * @type {boolean} + */ + get isPlayMode() { + if (this._sheetMode === undefined) this._sheetMode = this.constructor.SHEET_MODES.PLAY + return this._sheetMode === this.constructor.SHEET_MODES.PLAY + } + + /** + * Is the sheet currently in 'Edit' mode? + * @type {boolean} + */ + get isEditMode() { + if (this._sheetMode === undefined) this._sheetMode = this.constructor.SHEET_MODES.PLAY + return this._sheetMode === this.constructor.SHEET_MODES.EDIT + } + + /** + * Tab groups state + * @type {object} + */ + tabGroups = { primary: "stats" } + + /** @override */ + async _prepareContext() { + const actor = this.document + + const context = { + actor: actor, + system: actor.system, + source: actor.toObject(), + fields: actor.schema.fields, + systemFields: actor.system.schema.fields, + isEditable: this.isEditable, + isEditMode: this.isEditMode, + isPlayMode: this.isPlayMode, + isGM: game.user.isGM, + config: CONFIG.HERITIERS, + enrichedDescription: await foundry.applications.ux.TextEditor.implementation.enrichHTML(actor.system.biodata?.description || "", { async: true }), + enrichedHabitat: await foundry.applications.ux.TextEditor.implementation.enrichHTML(actor.system.biodata?.habitat || "", { async: true }), + enrichedRevesetranges: await foundry.applications.ux.TextEditor.implementation.enrichHTML(actor.system.biodata?.revesetranges || "", { async: true }), + enrichedSecretsdecouverts: await foundry.applications.ux.TextEditor.implementation.enrichHTML(actor.system.biodata?.secretsdecouverts || "", { async: true }), + enrichedQuestions: await foundry.applications.ux.TextEditor.implementation.enrichHTML(actor.system.biodata?.questions || "", { async: true }), + enrichedPlayernotes: await foundry.applications.ux.TextEditor.implementation.enrichHTML(actor.system.biodata?.playernotes || "", { async: true }), + } + + return context + } + + /** @override */ + _onRender(context, options) { + super._onRender(context, options) + + // Activate drag & drop handlers + this.#dragDrop.forEach(d => d.bind(this.element)) + + // Manual tab navigation + const html = this.element + const tabLinks = html.querySelectorAll('.sheet-tabs a.item[data-tab]') + const tabContents = html.querySelectorAll('.sheet-body .tab[data-group="primary"]') + + // Hide all tabs initially + tabContents.forEach(tab => { + tab.classList.remove('active') + tab.style.display = 'none' + }) + + // Show active tab + const activeTab = this.tabGroups.primary + const activeTabContent = html.querySelector(`.tab[data-group="primary"][data-tab="${activeTab}"]`) + if (activeTabContent) { + activeTabContent.classList.add('active') + activeTabContent.style.display = 'block' + } + + // Activate the corresponding nav link + tabLinks.forEach(link => { + if (link.dataset.tab === activeTab) { + link.classList.add('active') + } else { + link.classList.remove('active') + } + }) + + // Tab click handler + tabLinks.forEach(link => { + link.addEventListener('click', (event) => { + event.preventDefault() + const tab = link.dataset.tab + + // Update state + this.tabGroups.primary = tab + + // Hide all tabs + tabContents.forEach(t => { + t.classList.remove('active') + t.style.display = 'none' + }) + + // Show selected tab + const selectedTab = html.querySelector(`.tab[data-group="primary"][data-tab="${tab}"]`) + if (selectedTab) { + selectedTab.classList.add('active') + selectedTab.style.display = 'block' + } + + // Update nav links + tabLinks.forEach(l => { + if (l.dataset.tab === tab) { + l.classList.add('active') + } else { + l.classList.remove('active') + } + }) + }) + }) + + // Inline item editing + html.querySelectorAll('.edit-item-data').forEach(input => { + input.addEventListener('change', (event) => { + const li = event.target.closest('.item') + const itemId = li?.dataset.itemId + const itemType = li?.dataset.itemType + const itemField = event.target.dataset.itemField + const dataType = event.target.dataset.dtype + const value = event.target.value + if (itemId && itemType && itemField) { + this.actor.editItemField(itemId, itemType, itemField, dataType, value) + } + }) + }) + } + + // #region Drag & Drop + + /** + * Create drag-and-drop workflow handlers for this Application + * @returns {DragDrop[]} An array of DragDrop handlers + * @private + */ + #createDragDropHandlers() { + return this.options.dragDrop.map((d) => { + d.permissions = { + dragstart: this._canDragStart.bind(this), + drop: this._canDragDrop.bind(this), + } + d.callbacks = { + dragstart: this._onDragStart.bind(this), + drop: this._onDrop.bind(this), + } + return new foundry.applications.ux.DragDrop(d) + }) + } + + /** + * Define whether a user is able to begin a dragstart workflow for a given drag selector + * @param {string} selector The candidate HTML selector for dragging + * @returns {boolean} Can the current user drag this selector? + * @protected + */ + _canDragStart(selector) { + return this.isEditable + } + + /** + * Define whether a user is able to conclude a drag-and-drop workflow for a given drop selector + * @param {string} selector The candidate HTML selector for the drop target + * @returns {boolean} Can the current user drop on this selector? + * @protected + */ + _canDragDrop(selector) { + return this.isEditable + } + + /** + * Callback actions which occur at the beginning of a drag start workflow. + * @param {DragEvent} event The originating DragEvent + * @protected + */ + _onDragStart(event) { + const li = event.currentTarget.closest(".item") + if (!li?.dataset.itemId) return + const item = this.actor.items.get(li.dataset.itemId) + if (!item) return + + const dragData = item.toDragData() + event.dataTransfer.setData("text/plain", JSON.stringify(dragData)) + } + + /** + * Callback actions which occur when a dragged element is dropped on a target. + * @param {DragEvent} event The originating DragEvent + * @protected + */ + async _onDrop(event) { + const data = foundry.applications.ux.TextEditor.implementation.getDragEventData(event) + const actor = this.actor + + // Handle different data types + switch (data.type) { + case "Item": + return this._onDropItem(event, data) + case "Actor": + return this._onDropActor(event, data) + case "ActiveEffect": + return this._onDropActiveEffect(event, data) + } + } + + /** + * Handle dropping an Item on the actor sheet + * @param {DragEvent} event + * @param {object} data + * @private + */ + async _onDropItem(event, data) { + if (!this.actor.isOwner) return false + + let item = await fromUuid(data.uuid) + if (item.pack) { + item = await HeritiersUtility.searchItem(item) + } + + const itemData = item.toObject ? item.toObject() : item + return this.actor.createEmbeddedDocuments("Item", [itemData]) + } + + /** + * Handle dropping an Actor on the sheet + * @param {DragEvent} event + * @param {object} data + * @private + */ + async _onDropActor(event, data) { + return false + } + + /** + * Handle dropping an ActiveEffect on the sheet + * @param {DragEvent} event + * @param {object} data + * @private + */ + async _onDropActiveEffect(event, data) { + return false + } + + // #endregion + + // #region Action Handlers + + /** + * Toggle between edit and play mode + * @param {Event} event + * @param {HTMLElement} target + * @private + */ + static #onToggleSheet(event, target) { + const wasEditMode = this.isEditMode + this._sheetMode = wasEditMode ? this.constructor.SHEET_MODES.PLAY : this.constructor.SHEET_MODES.EDIT + this.render({ force: true }) + } + + /** + * Edit the actor image + * @param {Event} event + * @param {HTMLElement} target + * @private + */ + static async #onEditImage(event, target) { + const fp = new FilePicker({ + type: "image", + current: this.actor.img, + callback: (path) => { + this.actor.update({ img: path }) + }, + }) + return fp.browse() + } + + /** + * Edit an item + * @param {Event} event + * @param {HTMLElement} target + * @private + */ + static async #onEditItem(event, target) { + const li = target.closest(".item") + const itemId = li?.dataset.itemId + if (!itemId) return + const item = this.actor.items.get(itemId) + if (item) item.sheet.render(true) + } + + /** + * Delete an item + * @param {Event} event + * @param {HTMLElement} target + * @private + */ + static async #onDeleteItem(event, target) { + const li = target.closest(".item") + await HeritiersUtility.confirmDelete(this, li) + } + + /** + * Create a new item + * @param {Event} event + * @param {HTMLElement} target + * @private + */ + static async #onCreateItem(event, target) { + const itemType = target.dataset.type + + // Cas spécial pour les sorts avec une compétence spécifique + if (itemType === "sort" && target.dataset.sortCompetence) { + const sortCompetence = target.dataset.sortCompetence + await this.actor.createEmbeddedDocuments('Item', [{ + name: `Nouveau ${itemType} de ${sortCompetence}`, + type: itemType, + system: { competence: sortCompetence } + }], { renderSheet: true }) + return + } + + await this.actor.createEmbeddedDocuments("Item", [{ name: `Nouveau ${itemType}`, type: itemType }], { renderSheet: true }) + } + + /** + * Equip/unequip an item + * @param {Event} event + * @param {HTMLElement} target + * @private + */ + static async #onEquipItem(event, target) { + const li = target.closest(".item") + const itemId = li?.dataset.itemId + if (itemId) { + await this.actor.equipItem(itemId) + this.render() + } + } + + /** + * Modify item quantity + * @param {Event} event + * @param {HTMLElement} target + * @private + */ + static async #onModifyQuantity(event, target) { + const li = target.closest(".item") + const itemId = li?.dataset.itemId + const value = Number(target.dataset.quantiteValue) + if (itemId) { + await this.actor.incDecQuantity(itemId, value) + } + } + + /** + * Roll initiative + * @param {Event} event + * @param {HTMLElement} target + * @private + */ + static async #onRollInitiative(event, target) { + await this.actor.rollInitiative() + } + + /** + * Roll caractéristique + * @param {Event} event + * @param {HTMLElement} target + * @private + */ + static async #onRollCarac(event, target) { + const key = target.dataset.key + if (key) { + await this.actor.rollCarac(key, false) + } + } + + /** + * Roll rang + * @param {Event} event + * @param {HTMLElement} target + * @private + */ + static async #onRollRang(event, target) { + const key = target.dataset.rangKey + if (key) { + await this.actor.rollRang(key) + } + } + + /** + * Roll root competence + * @param {Event} event + * @param {HTMLElement} target + * @private + */ + static async #onRollRootCompetence(event, target) { + const compKey = target.dataset.attrKey + if (compKey) { + await this.actor.rollRootCompetence(compKey) + } + } + + /** + * Roll competence + * @param {Event} event + * @param {HTMLElement} target + * @private + */ + static async #onRollCompetence(event, target) { + const li = target.closest(".item") + const compId = li?.dataset.itemId + if (compId) { + await this.actor.rollCompetence(compId) + } + } + + /** + * Roll sort + * @param {Event} event + * @param {HTMLElement} target + * @private + */ + static async #onRollSort(event, target) { + const li = target.closest(".item") + const sortId = li?.dataset.itemId + if (sortId) { + await this.actor.rollSort(sortId) + } + } + + /** + * Roll attaque arme + * @param {Event} event + * @param {HTMLElement} target + * @private + */ + static async #onRollAttaqueArme(event, target) { + const li = target.closest(".item") + const armeId = li?.dataset.itemId + if (armeId) { + await this.actor.rollAttaqueArme(armeId) + } + } + + /** + * Roll attaque brutale arme + * @param {Event} event + * @param {HTMLElement} target + * @private + */ + static async #onRollAttaqueBrutaleArme(event, target) { + const li = target.closest(".item") + const armeId = li?.dataset.itemId + if (armeId) { + await this.actor.rollAttaqueBrutaleArme(armeId) + } + } + + /** + * Roll attaque charge arme + * @param {Event} event + * @param {HTMLElement} target + * @private + */ + static async #onRollAttaqueChargeArme(event, target) { + const li = target.closest(".item") + const armeId = li?.dataset.itemId + if (armeId) { + await this.actor.rollAttaqueChargeArme(armeId) + } + } + + /** + * Roll assomer arme + * @param {Event} event + * @param {HTMLElement} target + * @private + */ + static async #onRollAssomerArme(event, target) { + const li = target.closest(".item") + const armeId = li?.dataset.itemId + if (armeId) { + await this.actor.rollAssomerArme(armeId) + } + } + + /** + * Roll pouvoir + * @param {Event} event + * @param {HTMLElement} target + * @private + */ + static async #onRollPouvoir(event, target) { + const li = target.closest(".item") + const pouvoirId = li?.dataset.itemId + if (pouvoirId) { + await this.actor.rollPouvoir(pouvoirId) + } + } + + /** + * Toggle masque + * @param {Event} event + * @param {HTMLElement} target + * @private + */ + static async #onToggleMasque(event, target) { + await this.actor.toggleMasqueStatut() + this.render() + } + + /** + * Dialog récupération usage + * @param {Event} event + * @param {HTMLElement} target + * @private + */ + static async #onDialogRecupUsage(event, target) { + new Dialog({ + title: "Récupération des Points d'Usage", + content: "

Combien de Points d'Usage souhaitez-vous récupérer ?

", + buttons: { + one: { + icon: '', + label: "1 Point", + callback: () => { + this.actor.recupUsage(1) + } + }, + two: { + icon: '', + label: "2 Points", + callback: () => { + this.actor.recupUsage(2) + } + }, + three: { + icon: '', + label: "3 Points", + callback: () => { + this.actor.recupUsage(3) + } + }, + cancel: { + icon: '', + label: "Annuler" + } + }, + default: "one" + }).render(true) + } + + // #endregion +} diff --git a/modules/applications/sheets/base-item-sheet.mjs b/modules/applications/sheets/base-item-sheet.mjs new file mode 100644 index 0000000..f31aefd --- /dev/null +++ b/modules/applications/sheets/base-item-sheet.mjs @@ -0,0 +1,212 @@ +const { HandlebarsApplicationMixin } = foundry.applications.api + +export default class HeritiersItemSheet extends HandlebarsApplicationMixin(foundry.applications.sheets.ItemSheetV2) { + constructor(options = {}) { + super(options) + this.#dragDrop = this.#createDragDropHandlers() + } + + #dragDrop + + /** @override */ + static DEFAULT_OPTIONS = { + classes: ["fvtt-les-heritiers", "item"], + position: { + width: 620, + height: 600, + }, + form: { + submitOnChange: true, + }, + window: { + resizable: true, + }, + tabs: [ + { + navSelector: 'nav[data-group="primary"]', + contentSelector: "section.sheet-body", + initial: "description", + }, + ], + dragDrop: [{ dragSelector: "[data-drag]", dropSelector: null }], + actions: { + editImage: HeritiersItemSheet.#onEditImage, + postItem: HeritiersItemSheet.#onPostItem, + }, + } + + /** + * Tab groups state + * @type {object} + */ + tabGroups = { primary: "description" } + + /** @override */ + async _prepareContext() { + const context = { + fields: this.document.schema.fields, + systemFields: this.document.system.schema.fields, + item: this.document, + system: this.document.system, + source: this.document.toObject(), + enrichedDescription: await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.document.system.description, { async: true }), + isEditMode: true, + isEditable: this.isEditable, + isGM: game.user.isGM, + config: CONFIG.HERITIERS, + } + return context + } + + /** @override */ + _onRender(context, options) { + super._onRender(context, options) + this.#dragDrop.forEach((d) => d.bind(this.element)) + + // Activate tab navigation manually + const nav = this.element.querySelector('nav.tabs[data-group]') + if (nav) { + const group = nav.dataset.group + // Activate the current tab + const activeTab = this.tabGroups[group] || "description" + nav.querySelectorAll('[data-tab]').forEach(link => { + const tab = link.dataset.tab + link.classList.toggle('active', tab === activeTab) + link.addEventListener('click', (event) => { + event.preventDefault() + this.tabGroups[group] = tab + this.render() + }) + }) + + // Show/hide tab content + this.element.querySelectorAll('[data-group="' + group + '"][data-tab]').forEach(content => { + content.classList.toggle('active', content.dataset.tab === activeTab) + }) + } + } + + // #region Drag-and-Drop Workflow + /** + * Create drag-and-drop workflow handlers for this Application + * @returns {DragDrop[]} An array of DragDrop handlers + * @private + */ + #createDragDropHandlers() { + return this.options.dragDrop.map((d) => { + d.permissions = { + dragstart: this._canDragStart.bind(this), + drop: this._canDragDrop.bind(this), + } + d.callbacks = { + dragstart: this._onDragStart.bind(this), + dragover: this._onDragOver.bind(this), + drop: this._onDrop.bind(this), + } + return new foundry.applications.ux.DragDrop(d) + }) + } + + /** + * Can the User start a drag workflow for a given drag selector? + * @param {string} selector The candidate HTML selector for the drag event + * @returns {boolean} Can the current user drag this selector? + * @protected + */ + _canDragStart(selector) { + return this.isEditable + } + + /** + * Can the User drop an entry at a given drop selector? + * @param {string} selector The candidate HTML selector for the drop event + * @returns {boolean} Can the current user drop on this selector? + * @protected + */ + _canDragDrop(selector) { + return this.isEditable + } + + /** + * Callback for dragstart events. + * @param {DragEvent} event The drag start event + * @protected + */ + _onDragStart(event) { + const target = event.currentTarget + const dragData = { type: "Item", uuid: this.document.uuid } + event.dataTransfer.setData("text/plain", JSON.stringify(dragData)) + } + + /** + * Callback for dragover events. + * @param {DragEvent} event The drag over event + * @protected + */ + _onDragOver(event) { + // Default behavior is fine + } + + /** + * Callback for drop events. + * @param {DragEvent} event The drop event + * @protected + */ + async _onDrop(event) { + const data = foundry.applications.ux.TextEditor.implementation.getDragEventData(event) + const item = await fromUuid(data.uuid) + if (!item) return + + console.log("Item dropped:", item) + } + // #endregion + + // #region Action Handlers + /** + * Edit the item image + * @param {Event} event The triggering event + * @param {HTMLElement} target The target element + * @private + */ + static async #onEditImage(event, target) { + const fp = new FilePicker({ + type: "image", + current: this.document.img, + callback: (path) => { + this.document.update({ img: path }) + }, + }) + return fp.browse() + } + + /** + * Post item to chat + * @param {Event} event The triggering event + * @param {HTMLElement} target The target element + * @private + */ + static async #onPostItem(event, target) { + let chatData = foundry.utils.duplicate(this.document) + if (this.document.actor) { + chatData.actor = { id: this.document.actor.id } + } + // Don't post any image for the item if the default image is used + if (chatData.img.includes("/blank.png") || chatData.img.includes("/mystery-man")) { + chatData.img = null + } + // JSON object for easy creation + chatData.jsondata = JSON.stringify({ + compendium: "postedItem", + payload: chatData, + }) + + const html = await renderTemplate('systems/fvtt-les-heritiers/templates/post-item.html', chatData) + const chatOptions = { + user: game.user.id, + content: html, + } + ChatMessage.create(chatOptions) + } + + // #endregion +} diff --git a/modules/applications/sheets/capacitenaturelle-sheet.mjs b/modules/applications/sheets/capacitenaturelle-sheet.mjs new file mode 100644 index 0000000..806ebad --- /dev/null +++ b/modules/applications/sheets/capacitenaturelle-sheet.mjs @@ -0,0 +1,19 @@ +import HeritiersItemSheet from "./base-item-sheet.mjs" + +export default class HeritiersCapaciteNaturelleSheet extends HeritiersItemSheet { + /** @override */ + static DEFAULT_OPTIONS = { + ...super.DEFAULT_OPTIONS, + window: { + ...super.DEFAULT_OPTIONS.window, + title: "SHEETS.Item.capacitenaturelle", + }, + } + + /** @override */ + static PARTS = { + sheet: { + template: "systems/fvtt-les-heritiers/templates/item-capacitenaturelle-sheet.html", + }, + } +} diff --git a/modules/applications/sheets/competence-sheet.mjs b/modules/applications/sheets/competence-sheet.mjs new file mode 100644 index 0000000..c1d1e4d --- /dev/null +++ b/modules/applications/sheets/competence-sheet.mjs @@ -0,0 +1,19 @@ +import HeritiersItemSheet from "./base-item-sheet.mjs" + +export default class HeritiersCompetenceSheet extends HeritiersItemSheet { + /** @override */ + static DEFAULT_OPTIONS = { + ...super.DEFAULT_OPTIONS, + window: { + ...super.DEFAULT_OPTIONS.window, + title: "SHEETS.Item.competence", + }, + } + + /** @override */ + static PARTS = { + sheet: { + template: "systems/fvtt-les-heritiers/templates/item-competence-sheet.html", + }, + } +} diff --git a/modules/applications/sheets/contact-sheet.mjs b/modules/applications/sheets/contact-sheet.mjs new file mode 100644 index 0000000..c58dea5 --- /dev/null +++ b/modules/applications/sheets/contact-sheet.mjs @@ -0,0 +1,19 @@ +import HeritiersItemSheet from "./base-item-sheet.mjs" + +export default class HeritiersContactSheet extends HeritiersItemSheet { + /** @override */ + static DEFAULT_OPTIONS = { + ...super.DEFAULT_OPTIONS, + window: { + ...super.DEFAULT_OPTIONS.window, + title: "SHEETS.Item.contact", + }, + } + + /** @override */ + static PARTS = { + sheet: { + template: "systems/fvtt-les-heritiers/templates/item-contact-sheet.html", + }, + } +} diff --git a/modules/applications/sheets/desavantage-sheet.mjs b/modules/applications/sheets/desavantage-sheet.mjs new file mode 100644 index 0000000..8d0585e --- /dev/null +++ b/modules/applications/sheets/desavantage-sheet.mjs @@ -0,0 +1,19 @@ +import HeritiersItemSheet from "./base-item-sheet.mjs" + +export default class HeritiersDesavantageSheet extends HeritiersItemSheet { + /** @override */ + static DEFAULT_OPTIONS = { + ...super.DEFAULT_OPTIONS, + window: { + ...super.DEFAULT_OPTIONS.window, + title: "SHEETS.Item.desavantage", + }, + } + + /** @override */ + static PARTS = { + sheet: { + template: "systems/fvtt-les-heritiers/templates/item-desavantage-sheet.html", + }, + } +} diff --git a/modules/applications/sheets/equipement-sheet.mjs b/modules/applications/sheets/equipement-sheet.mjs new file mode 100644 index 0000000..e9ee534 --- /dev/null +++ b/modules/applications/sheets/equipement-sheet.mjs @@ -0,0 +1,19 @@ +import HeritiersItemSheet from "./base-item-sheet.mjs" + +export default class HeritiersEquipementSheet extends HeritiersItemSheet { + /** @override */ + static DEFAULT_OPTIONS = { + ...super.DEFAULT_OPTIONS, + window: { + ...super.DEFAULT_OPTIONS.window, + title: "SHEETS.Item.equipement", + }, + } + + /** @override */ + static PARTS = { + sheet: { + template: "systems/fvtt-les-heritiers/templates/item-equipement-sheet.html", + }, + } +} diff --git a/modules/applications/sheets/fee-sheet.mjs b/modules/applications/sheets/fee-sheet.mjs new file mode 100644 index 0000000..179f634 --- /dev/null +++ b/modules/applications/sheets/fee-sheet.mjs @@ -0,0 +1,19 @@ +import HeritiersItemSheet from "./base-item-sheet.mjs" + +export default class HeritiersFeeSheet extends HeritiersItemSheet { + /** @override */ + static DEFAULT_OPTIONS = { + ...super.DEFAULT_OPTIONS, + window: { + ...super.DEFAULT_OPTIONS.window, + title: "SHEETS.Item.fee", + }, + } + + /** @override */ + static PARTS = { + sheet: { + template: "systems/fvtt-les-heritiers/templates/item-fee-sheet.html", + }, + } +} diff --git a/modules/applications/sheets/personnage-sheet.mjs b/modules/applications/sheets/personnage-sheet.mjs new file mode 100644 index 0000000..6b8481b --- /dev/null +++ b/modules/applications/sheets/personnage-sheet.mjs @@ -0,0 +1,59 @@ +import HeritiersActorSheet from "./base-actor-sheet.mjs" + +export default class HeritiersPersonnageSheet extends HeritiersActorSheet { + /** @override */ + static DEFAULT_OPTIONS = { + ...super.DEFAULT_OPTIONS, + classes: [...super.DEFAULT_OPTIONS.classes], + window: { + ...super.DEFAULT_OPTIONS.window, + title: "SHEETS.Actor.personnage", + }, + actions: { + ...super.DEFAULT_OPTIONS.actions, + }, + } + + /** @override */ + static PARTS = { + sheet: { + template: "systems/fvtt-les-heritiers/templates/actor-sheet.html", + }, + } + + /** @override */ + tabGroups = { primary: "stats" } + + /** @override */ + async _prepareContext() { + const context = await super._prepareContext() + const actor = this.document + + // Add personnage-specific data + context.skills = actor.getSkills() + context.utileSkillsMental = actor.organizeUtileSkills("mental") + context.utileSkillsPhysical = actor.organizeUtileSkills("physical") + context.competencesMagie = game.system.lesheritiers.config.competencesMagie || [] + context.futileSkills = actor.organizeFutileSkills() + context.contacts = actor.organizeContacts() + context.armes = foundry.utils.duplicate(actor.getWeapons()) + context.monnaies = foundry.utils.duplicate(actor.getMonnaies()) + context.pouvoirs = foundry.utils.duplicate(actor.getPouvoirs()) + context.fee = foundry.utils.duplicate(actor.getFee() || {}) + context.protections = foundry.utils.duplicate(actor.getArmors()) + context.combat = actor.getCombatValues() + context.equipements = foundry.utils.duplicate(actor.getEquipments()) + context.avantages = foundry.utils.duplicate(actor.getAvantages()) + context.atouts = foundry.utils.duplicate(actor.getAtouts()) + context.capacites = foundry.utils.duplicate(actor.getCapacites()) + context.desavantages = foundry.utils.duplicate(actor.getDesavantages()) + context.profils = foundry.utils.duplicate(actor.getProfils()) + context.pvMalus = actor.getPvMalus() + context.heritage = game.settings.get("fvtt-les-heritiers", "heritiers-heritage") + context.initiative = actor.getFlag("world", "last-initiative") || -1 + context.magieList = actor.prepareMagie() + context.isPNJ = false + + return context + } +} diff --git a/modules/applications/sheets/pnj-sheet.mjs b/modules/applications/sheets/pnj-sheet.mjs new file mode 100644 index 0000000..0d013f3 --- /dev/null +++ b/modules/applications/sheets/pnj-sheet.mjs @@ -0,0 +1,59 @@ +import HeritiersActorSheet from "./base-actor-sheet.mjs" + +export default class HeritiersPnjSheet extends HeritiersActorSheet { + /** @override */ + static DEFAULT_OPTIONS = { + ...super.DEFAULT_OPTIONS, + classes: [...super.DEFAULT_OPTIONS.classes], + window: { + ...super.DEFAULT_OPTIONS.window, + title: "SHEETS.Actor.pnj", + }, + actions: { + ...super.DEFAULT_OPTIONS.actions, + }, + } + + /** @override */ + static PARTS = { + sheet: { + template: "systems/fvtt-les-heritiers/templates/actor-pnj-sheet.html", + }, + } + + /** @override */ + tabGroups = { primary: "stats" } + + /** @override */ + async _prepareContext() { + const context = await super._prepareContext() + const actor = this.document + + // Add PNJ-specific data + context.skills = actor.getSkills() + context.utileSkillsMental = actor.organizeUtileSkills("mental") + context.utileSkillsPhysical = actor.organizeUtileSkills("physical") + context.competencesMagie = game.system.lesheritiers.config.competencesMagie || [] + context.futileSkills = actor.organizeFutileSkills() + context.contacts = actor.organizeContacts() + context.armes = foundry.utils.duplicate(actor.getWeapons()) + context.monnaies = foundry.utils.duplicate(actor.getMonnaies()) + context.pouvoirs = foundry.utils.duplicate(actor.getPouvoirs()) + context.fee = foundry.utils.duplicate(actor.getFee() || {}) + context.protections = foundry.utils.duplicate(actor.getArmors()) + context.combat = actor.getCombatValues() + context.equipements = foundry.utils.duplicate(actor.getEquipments()) + context.avantages = foundry.utils.duplicate(actor.getAvantages()) + context.atouts = foundry.utils.duplicate(actor.getAtouts()) + context.capacites = foundry.utils.duplicate(actor.getCapacites()) + context.desavantages = foundry.utils.duplicate(actor.getDesavantages()) + context.profils = foundry.utils.duplicate(actor.getProfils()) + context.pvMalus = actor.getPvMalus() + context.heritage = game.settings.get("fvtt-les-heritiers", "heritiers-heritage") + context.initiative = actor.getFlag("world", "last-initiative") || -1 + context.magieList = actor.prepareMagie() + context.isPNJ = true + + return context + } +} diff --git a/modules/applications/sheets/pouvoir-sheet.mjs b/modules/applications/sheets/pouvoir-sheet.mjs new file mode 100644 index 0000000..ed136fc --- /dev/null +++ b/modules/applications/sheets/pouvoir-sheet.mjs @@ -0,0 +1,19 @@ +import HeritiersItemSheet from "./base-item-sheet.mjs" + +export default class HeritiersPouvoirSheet extends HeritiersItemSheet { + /** @override */ + static DEFAULT_OPTIONS = { + ...super.DEFAULT_OPTIONS, + window: { + ...super.DEFAULT_OPTIONS.window, + title: "SHEETS.Item.pouvoir", + }, + } + + /** @override */ + static PARTS = { + sheet: { + template: "systems/fvtt-les-heritiers/templates/item-pouvoir-sheet.html", + }, + } +} diff --git a/modules/applications/sheets/profil-sheet.mjs b/modules/applications/sheets/profil-sheet.mjs new file mode 100644 index 0000000..0534574 --- /dev/null +++ b/modules/applications/sheets/profil-sheet.mjs @@ -0,0 +1,19 @@ +import HeritiersItemSheet from "./base-item-sheet.mjs" + +export default class HeritiersProfilSheet extends HeritiersItemSheet { + /** @override */ + static DEFAULT_OPTIONS = { + ...super.DEFAULT_OPTIONS, + window: { + ...super.DEFAULT_OPTIONS.window, + title: "SHEETS.Item.profil", + }, + } + + /** @override */ + static PARTS = { + sheet: { + template: "systems/fvtt-les-heritiers/templates/item-profil-sheet.html", + }, + } +} diff --git a/modules/applications/sheets/protection-sheet.mjs b/modules/applications/sheets/protection-sheet.mjs new file mode 100644 index 0000000..121f948 --- /dev/null +++ b/modules/applications/sheets/protection-sheet.mjs @@ -0,0 +1,19 @@ +import HeritiersItemSheet from "./base-item-sheet.mjs" + +export default class HeritiersProtectionSheet extends HeritiersItemSheet { + /** @override */ + static DEFAULT_OPTIONS = { + ...super.DEFAULT_OPTIONS, + window: { + ...super.DEFAULT_OPTIONS.window, + title: "SHEETS.Item.protection", + }, + } + + /** @override */ + static PARTS = { + sheet: { + template: "systems/fvtt-les-heritiers/templates/item-protection-sheet.html", + }, + } +} diff --git a/modules/applications/sheets/sort-sheet.mjs b/modules/applications/sheets/sort-sheet.mjs new file mode 100644 index 0000000..8e483a5 --- /dev/null +++ b/modules/applications/sheets/sort-sheet.mjs @@ -0,0 +1,19 @@ +import HeritiersItemSheet from "./base-item-sheet.mjs" + +export default class HeritiersSortSheet extends HeritiersItemSheet { + /** @override */ + static DEFAULT_OPTIONS = { + ...super.DEFAULT_OPTIONS, + window: { + ...super.DEFAULT_OPTIONS.window, + title: "SHEETS.Item.sort", + }, + } + + /** @override */ + static PARTS = { + sheet: { + template: "systems/fvtt-les-heritiers/templates/item-sort-sheet.html", + }, + } +} diff --git a/modules/heritiers-actor.js b/modules/heritiers-actor.js index 5e90490..7ab6e15 100644 --- a/modules/heritiers-actor.js +++ b/modules/heritiers-actor.js @@ -1,6 +1,6 @@ /* -------------------------------------------- */ import { HeritiersUtility } from "./heritiers-utility.js"; -import { HeritiersRollDialog } from "./heritiers-roll-dialog.js"; +import { HeritiersRollDialog } from "./applications/heritiers-roll-dialog.mjs"; /* -------------------------------------------- */ const __degatsBonus = [-2, -2, -1, -1, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 8, 8, 9, 9, 10, 10] diff --git a/modules/heritiers-commands.js b/modules/heritiers-commands.js index da9b4ad..0e03bfd 100644 --- a/modules/heritiers-commands.js +++ b/modules/heritiers-commands.js @@ -1,7 +1,7 @@ /* -------------------------------------------- */ import { HeritiersUtility } from "./heritiers-utility.js"; -import { HeritiersRollDialog } from "./heritiers-roll-dialog.js"; +import { HeritiersRollDialog } from "./applications/heritiers-roll-dialog.mjs"; /* -------------------------------------------- */ export class HeritiersCommands { diff --git a/modules/heritiers-main.js b/modules/heritiers-main.js index c0cf11a..56e6d4c 100644 --- a/modules/heritiers-main.js +++ b/modules/heritiers-main.js @@ -9,14 +9,17 @@ /* -------------------------------------------- */ // Import Modules import { HeritiersActor } from "./heritiers-actor.js"; -import { HeritiersItemSheet } from "./heritiers-item-sheet.js"; -import { HeritiersActorSheet } from "./heritiers-actor-sheet.js"; -import { HeritiersActorPNJSheet } from "./heritiers-actor-pnj-sheet.js"; +import { HeritiersItem } from "./heritiers-item.js"; import { HeritiersUtility } from "./heritiers-utility.js"; import { HeritiersCombat } from "./heritiers-combat.js"; -import { HeritiersItem } from "./heritiers-item.js"; import { HERITIERS_CONFIG } from "./heritiers-config.js"; +// Import DataModels +import * as models from "./models/index.mjs"; + +// Import AppV2 Sheets +import * as sheets from "./applications/sheets/_module.mjs"; + /* -------------------------------------------- */ /* Foundry VTT Initialization */ /* -------------------------------------------- */ @@ -45,22 +48,62 @@ Hooks.once("init", async function () { // Define custom Entity classes CONFIG.Combat.documentClass = HeritiersCombat CONFIG.Actor.documentClass = HeritiersActor + CONFIG.Actor.dataModels = { + personnage: models.PersonnageDataModel, + pnj: models.PnjDataModel + } + CONFIG.Item.documentClass = HeritiersItem + CONFIG.Item.dataModels = { + accessoire: models.AccessoireDataModel, + arme: models.ArmeDataModel, + atoutfeerique: models.AtoutFeeriqueDataModel, + avantage: models.AvantageDataModel, + capacitenaturelle: models.CapaciteNaturelleDataModel, + competence: models.CompetenceDataModel, + contact: models.ContactDataModel, + desavantage: models.DesavantageDataModel, + equipement: models.EquipementDataModel, + fee: models.FeeDataModel, + pouvoir: models.PouvoirDataModel, + profil: models.ProfilDataModel, + protection: models.ProtectionDataModel, + sort: models.SortDataModel + } + // Create an object of bonus/malus from -6 to +6 signed HERITIERS_CONFIG.bonusMalus = Array.from({ length: 7 }, (v, k) => toString(k - 6)) + CONFIG.HERITIERS = HERITIERS_CONFIG + game.system.lesheritiers = { HeritiersUtility, - config: HERITIERS_CONFIG + config: HERITIERS_CONFIG, + models, + sheets } /* -------------------------------------------- */ // Register sheet application classes foundry.documents.collections.Actors.unregisterSheet("core", foundry.appv1.sheets.ActorSheet); - foundry.documents.collections.Actors.registerSheet("fvtt-les-heritiers", HeritiersActorSheet, { types: ["personnage"], makeDefault: true }) - foundry.documents.collections.Actors.registerSheet("fvtt-les-heritiers", HeritiersActorPNJSheet, { types: ["pnj"], makeDefault: true }) + foundry.documents.collections.Actors.registerSheet("fvtt-les-heritiers", sheets.HeritiersPersonnageSheet, { types: ["personnage"], makeDefault: true }) + foundry.documents.collections.Actors.registerSheet("fvtt-les-heritiers", sheets.HeritiersPnjSheet, { types: ["pnj"], makeDefault: true }) + // Register AppV2 Item Sheets foundry.documents.collections.Items.unregisterSheet("core", foundry.appv1.sheets.ItemSheet); - foundry.documents.collections.Items.registerSheet("fvtt-les-heritiers", HeritiersItemSheet, { makeDefault: true }) + foundry.documents.collections.Items.registerSheet("fvtt-les-heritiers", sheets.HeritiersAccessoireSheet, { types: ["accessoire"], makeDefault: true }) + foundry.documents.collections.Items.registerSheet("fvtt-les-heritiers", sheets.HeritiersArmeSheet, { types: ["arme"], makeDefault: true }) + foundry.documents.collections.Items.registerSheet("fvtt-les-heritiers", sheets.HeritiersAtoutFeeriqueSheet, { types: ["atoutfeerique"], makeDefault: true }) + foundry.documents.collections.Items.registerSheet("fvtt-les-heritiers", sheets.HeritiersAvantageSheet, { types: ["avantage"], makeDefault: true }) + foundry.documents.collections.Items.registerSheet("fvtt-les-heritiers", sheets.HeritiersCapaciteNaturelleSheet, { types: ["capacitenaturelle"], makeDefault: true }) + foundry.documents.collections.Items.registerSheet("fvtt-les-heritiers", sheets.HeritiersCompetenceSheet, { types: ["competence"], makeDefault: true }) + foundry.documents.collections.Items.registerSheet("fvtt-les-heritiers", sheets.HeritiersContactSheet, { types: ["contact"], makeDefault: true }) + foundry.documents.collections.Items.registerSheet("fvtt-les-heritiers", sheets.HeritiersDesavantageSheet, { types: ["desavantage"], makeDefault: true }) + foundry.documents.collections.Items.registerSheet("fvtt-les-heritiers", sheets.HeritiersEquipementSheet, { types: ["equipement"], makeDefault: true }) + foundry.documents.collections.Items.registerSheet("fvtt-les-heritiers", sheets.HeritiersFeeSheet, { types: ["fee"], makeDefault: true }) + foundry.documents.collections.Items.registerSheet("fvtt-les-heritiers", sheets.HeritiersPouvoirSheet, { types: ["pouvoir"], makeDefault: true }) + foundry.documents.collections.Items.registerSheet("fvtt-les-heritiers", sheets.HeritiersProfilSheet, { types: ["profil"], makeDefault: true }) + foundry.documents.collections.Items.registerSheet("fvtt-les-heritiers", sheets.HeritiersProtectionSheet, { types: ["protection"], makeDefault: true }) + foundry.documents.collections.Items.registerSheet("fvtt-les-heritiers", sheets.HeritiersSortSheet, { types: ["sort"], makeDefault: true }) HeritiersUtility.init() diff --git a/modules/models/accessoire.mjs b/modules/models/accessoire.mjs new file mode 100644 index 0000000..c68ac0c --- /dev/null +++ b/modules/models/accessoire.mjs @@ -0,0 +1,16 @@ +/** + * Data model pour les accessoires + */ +export default class AccessoireDataModel extends foundry.abstract.TypeDataModel { + static defineSchema() { + const fields = foundry.data.fields; + return { + description: new fields.HTMLField({ initial: "" }), + rarete: new fields.NumberField({ initial: 0, integer: true }), + quantite: new fields.NumberField({ initial: 0, integer: true }), + prix: new fields.NumberField({ initial: 0, integer: true }), + equipped: new fields.BooleanField({ initial: false }), + lieu: new fields.NumberField({ initial: 0, integer: true }) + }; + } +} diff --git a/modules/models/arme.mjs b/modules/models/arme.mjs new file mode 100644 index 0000000..22a672c --- /dev/null +++ b/modules/models/arme.mjs @@ -0,0 +1,30 @@ +/** + * Data model pour les armes + */ +export default class ArmeDataModel extends foundry.abstract.TypeDataModel { + static defineSchema() { + const fields = foundry.data.fields; + return { + description: new fields.HTMLField({ initial: "" }), + rarete: new fields.NumberField({ initial: 0, integer: true }), + quantite: new fields.NumberField({ initial: 0, integer: true }), + prix: new fields.NumberField({ initial: 0, integer: true }), + equipped: new fields.BooleanField({ initial: false }), + categorie: new fields.StringField({ initial: "" }), + armetype: new fields.StringField({ initial: "" }), + degats: new fields.NumberField({ initial: 0, integer: true }), + precision: new fields.NumberField({ initial: 0, integer: true }), + cadence: new fields.StringField({ initial: "" }), + enraiement: new fields.StringField({ initial: "" }), + magasin: new fields.NumberField({ initial: 0, integer: true }), + charge: new fields.NumberField({ initial: 0, integer: true }), + portee: new fields.StringField({ initial: "" }), + legalite: new fields.StringField({ initial: "" }), + dissimulation: new fields.StringField({ initial: "" }), + zone: new fields.NumberField({ initial: 0, integer: true }), + temps: new fields.StringField({ initial: "" }), + allumage: new fields.StringField({ initial: "" }), + special: new fields.StringField({ initial: "" }) + }; + } +} diff --git a/modules/models/atoutfeerique.mjs b/modules/models/atoutfeerique.mjs new file mode 100644 index 0000000..a8e4846 --- /dev/null +++ b/modules/models/atoutfeerique.mjs @@ -0,0 +1,11 @@ +/** + * Data model pour les atouts féériques + */ +export default class AtoutFeeriqueDataModel extends foundry.abstract.TypeDataModel { + static defineSchema() { + const fields = foundry.data.fields; + return { + description: new fields.HTMLField({ initial: "" }) + }; + } +} diff --git a/modules/models/avantage.mjs b/modules/models/avantage.mjs new file mode 100644 index 0000000..f38d488 --- /dev/null +++ b/modules/models/avantage.mjs @@ -0,0 +1,11 @@ +/** + * Data model pour les avantages + */ +export default class AvantageDataModel extends foundry.abstract.TypeDataModel { + static defineSchema() { + const fields = foundry.data.fields; + return { + description: new fields.HTMLField({ initial: "" }) + }; + } +} diff --git a/modules/models/base-item.mjs b/modules/models/base-item.mjs new file mode 100644 index 0000000..af35cb5 --- /dev/null +++ b/modules/models/base-item.mjs @@ -0,0 +1,11 @@ +/** + * Base data model pour les items + */ +export default class BaseItemDataModel extends foundry.abstract.TypeDataModel { + static defineSchema() { + const fields = foundry.data.fields; + return { + description: new fields.HTMLField({ initial: "" }) + }; + } +} diff --git a/modules/models/capacitenaturelle.mjs b/modules/models/capacitenaturelle.mjs new file mode 100644 index 0000000..4a6d790 --- /dev/null +++ b/modules/models/capacitenaturelle.mjs @@ -0,0 +1,21 @@ +/** + * Data model pour les capacités naturelles + */ +export default class CapaciteNaturelleDataModel extends foundry.abstract.TypeDataModel { + static defineSchema() { + const fields = foundry.data.fields; + return { + pouvoirtype: new fields.StringField({ initial: "" }), + activation: new fields.StringField({ initial: "" }), + cibles: new fields.StringField({ initial: "" }), + effet: new fields.StringField({ initial: "" }), + duree: new fields.StringField({ initial: "" }), + portee: new fields.StringField({ initial: "" }), + resistance: new fields.StringField({ initial: "" }), + resistanceautre: new fields.StringField({ initial: "" }), + isvirulence: new fields.BooleanField({ initial: false }), + virulence: new fields.StringField({ initial: "" }), + description: new fields.HTMLField({ initial: "" }) + }; + } +} diff --git a/modules/models/competence.mjs b/modules/models/competence.mjs new file mode 100644 index 0000000..89d279c --- /dev/null +++ b/modules/models/competence.mjs @@ -0,0 +1,43 @@ +/** + * Data model pour les compétences + */ +export default class CompetenceDataModel extends foundry.abstract.TypeDataModel { + static defineSchema() { + const fields = foundry.data.fields; + return { + categorie: new fields.StringField({ initial: "" }), + profil: new fields.StringField({ initial: "" }), + niveau: new fields.NumberField({ initial: 0, integer: true }), + nomniveau: new fields.SchemaField({ + 1: new fields.StringField({ initial: "" }), + 2: new fields.StringField({ initial: "" }), + 3: new fields.StringField({ initial: "" }), + 4: new fields.StringField({ initial: "" }) + }), + nomniveausouffle: new fields.SchemaField({ + soufflecombat: new fields.SchemaField({ + 1: new fields.StringField({ initial: "" }), + 2: new fields.StringField({ initial: "" }), + 3: new fields.StringField({ initial: "" }), + 4: new fields.StringField({ initial: "" }) + }), + soufflemouvement: new fields.SchemaField({ + 1: new fields.StringField({ initial: "" }), + 2: new fields.NumberField({ initial: 0, integer: true }), + 3: new fields.StringField({ initial: "" }), + 4: new fields.StringField({ initial: "" }) + }), + souffleesprit: new fields.SchemaField({ + 1: new fields.StringField({ initial: "" }), + 2: new fields.StringField({ initial: "" }), + 3: new fields.StringField({ initial: "" }), + 4: new fields.StringField({ initial: "" }) + }) + }), + predilection: new fields.BooleanField({ initial: false }), + specialites: new fields.ArrayField(new fields.ObjectField(), { initial: [] }), + ismagie: new fields.BooleanField({ initial: false }), + description: new fields.HTMLField({ initial: "" }) + }; + } +} diff --git a/modules/models/contact.mjs b/modules/models/contact.mjs new file mode 100644 index 0000000..5c9661a --- /dev/null +++ b/modules/models/contact.mjs @@ -0,0 +1,12 @@ +/** + * Data model pour les contacts + */ +export default class ContactDataModel extends foundry.abstract.TypeDataModel { + static defineSchema() { + const fields = foundry.data.fields; + return { + contacttype: new fields.StringField({ initial: "" }), + description: new fields.HTMLField({ initial: "" }) + }; + } +} diff --git a/modules/models/desavantage.mjs b/modules/models/desavantage.mjs new file mode 100644 index 0000000..65bd2db --- /dev/null +++ b/modules/models/desavantage.mjs @@ -0,0 +1,11 @@ +/** + * Data model pour les désavantages + */ +export default class DesavantageDataModel extends foundry.abstract.TypeDataModel { + static defineSchema() { + const fields = foundry.data.fields; + return { + description: new fields.HTMLField({ initial: "" }) + }; + } +} diff --git a/modules/models/equipement.mjs b/modules/models/equipement.mjs new file mode 100644 index 0000000..63f9132 --- /dev/null +++ b/modules/models/equipement.mjs @@ -0,0 +1,15 @@ +/** + * Data model pour les équipements + */ +export default class EquipementDataModel extends foundry.abstract.TypeDataModel { + static defineSchema() { + const fields = foundry.data.fields; + return { + description: new fields.HTMLField({ initial: "" }), + rarete: new fields.NumberField({ initial: 0, integer: true }), + quantite: new fields.NumberField({ initial: 0, integer: true }), + prix: new fields.NumberField({ initial: 0, integer: true }), + equipped: new fields.BooleanField({ initial: false }) + }; + } +} diff --git a/modules/models/fee.mjs b/modules/models/fee.mjs new file mode 100644 index 0000000..72730f1 --- /dev/null +++ b/modules/models/fee.mjs @@ -0,0 +1,19 @@ +/** + * Data model pour les fées + */ +export default class FeeDataModel extends foundry.abstract.TypeDataModel { + static defineSchema() { + const fields = foundry.data.fields; + return { + feetype: new fields.NumberField({ initial: 0, integer: true }), + avantages: new fields.StringField({ initial: "" }), + desavantages: new fields.StringField({ initial: "" }), + pouvoirsfeeriquesmasque: new fields.StringField({ initial: "" }), + pouvoirsfeeriquesdemasque: new fields.StringField({ initial: "" }), + atoutsfeeriques: new fields.StringField({ initial: "" }), + competences: new fields.StringField({ initial: "" }), + capacitenaturelles: new fields.StringField({ initial: "" }), + description: new fields.HTMLField({ initial: "" }) + }; + } +} diff --git a/modules/models/index.mjs b/modules/models/index.mjs new file mode 100644 index 0000000..25bae25 --- /dev/null +++ b/modules/models/index.mjs @@ -0,0 +1,24 @@ +/** + * Index des DataModels pour Les Héritiers + * Ce fichier centralise tous les exports des modèles de données + */ + +// Modèles d'acteurs +export { default as PersonnageDataModel } from './personnage.mjs'; +export { default as PnjDataModel } from './pnj.mjs'; + +// Modèles d'items +export { default as AccessoireDataModel } from './accessoire.mjs'; +export { default as ArmeDataModel } from './arme.mjs'; +export { default as AtoutFeeriqueDataModel } from './atoutfeerique.mjs'; +export { default as AvantageDataModel } from './avantage.mjs'; +export { default as CapaciteNaturelleDataModel } from './capacitenaturelle.mjs'; +export { default as CompetenceDataModel } from './competence.mjs'; +export { default as ContactDataModel } from './contact.mjs'; +export { default as DesavantageDataModel } from './desavantage.mjs'; +export { default as EquipementDataModel } from './equipement.mjs'; +export { default as FeeDataModel } from './fee.mjs'; +export { default as PouvoirDataModel } from './pouvoir.mjs'; +export { default as ProfilDataModel } from './profil.mjs'; +export { default as ProtectionDataModel } from './protection.mjs'; +export { default as SortDataModel } from './sort.mjs'; diff --git a/modules/models/personnage.mjs b/modules/models/personnage.mjs new file mode 100644 index 0000000..db136a0 --- /dev/null +++ b/modules/models/personnage.mjs @@ -0,0 +1,234 @@ +/** + * Data model pour les personnages + */ +export default class PersonnageDataModel extends foundry.abstract.TypeDataModel { + static defineSchema() { + const fields = foundry.data.fields; + return { + // Template biodata + biodata: new fields.SchemaField({ + name: new fields.StringField({ initial: "" }), + activite: new fields.StringField({ initial: "" }), + nomhumain: new fields.StringField({ initial: "" }), + activites: new fields.StringField({ initial: "" }), + fortune: new fields.NumberField({ initial: 0, integer: true }), + traitscaracteres: new fields.StringField({ initial: "" }), + tailledemasquee: new fields.StringField({ initial: "" }), + taillemasquee: new fields.StringField({ initial: "" }), + poidsmasquee: new fields.StringField({ initial: "" }), + poidsdemasquee: new fields.StringField({ initial: "" }), + apparencemasquee: new fields.StringField({ initial: "" }), + apparencedemasquee: new fields.StringField({ initial: "" }), + titrefamille: new fields.StringField({ initial: "" }), + langues: new fields.StringField({ initial: "" }), + factionfeerique: new fields.StringField({ initial: "" }), + typetaille: new fields.StringField({ initial: "" }), + age: new fields.NumberField({ initial: 0, integer: true }), + poids: new fields.StringField({ initial: "" }), + taille: new fields.StringField({ initial: "" }), + cheveux: new fields.StringField({ initial: "" }), + sexe: new fields.StringField({ initial: "" }), + yeux: new fields.StringField({ initial: "" }), + description: new fields.HTMLField({ initial: "" }), + revesetranges: new fields.HTMLField({ initial: "" }), + secretsdecouverts: new fields.HTMLField({ initial: "" }), + questions: new fields.HTMLField({ initial: "" }), + habitat: new fields.HTMLField({ initial: "" }), + notes: new fields.HTMLField({ initial: "" }), + statut: new fields.StringField({ initial: "" }), + playernotes: new fields.HTMLField({ initial: "" }), + gmnotes: new fields.HTMLField({ initial: "" }), + magie: new fields.BooleanField({ initial: false }) + }), + // Template core + subactors: new fields.ArrayField(new fields.StringField(), { initial: [] }), + caracteristiques: new fields.SchemaField({ + agi: new fields.SchemaField({ + label: new fields.StringField({ initial: "Agilité" }), + labelnorm: new fields.StringField({ initial: "agilite" }), + abbrev: new fields.StringField({ initial: "agi" }), + kind: new fields.StringField({ initial: "physical" }), + value: new fields.NumberField({ initial: 1, integer: true }), + rang: new fields.NumberField({ initial: 0, integer: true }), + max: new fields.NumberField({ initial: 1, integer: true }) + }), + con: new fields.SchemaField({ + label: new fields.StringField({ initial: "Constitution" }), + labelnorm: new fields.StringField({ initial: "constitution" }), + abbrev: new fields.StringField({ initial: "con" }), + kind: new fields.StringField({ initial: "physical" }), + value: new fields.NumberField({ initial: 1, integer: true }), + rang: new fields.NumberField({ initial: 0, integer: true }), + max: new fields.NumberField({ initial: 1, integer: true }) + }), + for: new fields.SchemaField({ + label: new fields.StringField({ initial: "Force" }), + labelnorm: new fields.StringField({ initial: "force" }), + abbrev: new fields.StringField({ initial: "for" }), + kind: new fields.StringField({ initial: "physical" }), + value: new fields.NumberField({ initial: 1, integer: true }), + rang: new fields.NumberField({ initial: 0, integer: true }), + max: new fields.NumberField({ initial: 1, integer: true }) + }), + prec: new fields.SchemaField({ + label: new fields.StringField({ initial: "Précision" }), + labelnorm: new fields.StringField({ initial: "precision" }), + abbrev: new fields.StringField({ initial: "prec" }), + kind: new fields.StringField({ initial: "physical" }), + value: new fields.NumberField({ initial: 1, integer: true }), + rang: new fields.NumberField({ initial: 0, integer: true }), + max: new fields.NumberField({ initial: 1, integer: true }) + }), + esp: new fields.SchemaField({ + label: new fields.StringField({ initial: "Esprit" }), + labelnorm: new fields.StringField({ initial: "esprit" }), + abbrev: new fields.StringField({ initial: "esp" }), + kind: new fields.StringField({ initial: "mental" }), + value: new fields.NumberField({ initial: 1, integer: true }), + rang: new fields.NumberField({ initial: 0, integer: true }), + max: new fields.NumberField({ initial: 1, integer: true }) + }), + per: new fields.SchemaField({ + label: new fields.StringField({ initial: "Perception" }), + labelnorm: new fields.StringField({ initial: "perception" }), + abbrev: new fields.StringField({ initial: "per" }), + kind: new fields.StringField({ initial: "mental" }), + value: new fields.NumberField({ initial: 1, integer: true }), + rang: new fields.NumberField({ initial: 0, integer: true }), + max: new fields.NumberField({ initial: 1, integer: true }) + }), + pres: new fields.SchemaField({ + label: new fields.StringField({ initial: "Prestance" }), + labelnorm: new fields.StringField({ initial: "pres" }), + abbrev: new fields.StringField({ initial: "pres" }), + kind: new fields.StringField({ initial: "mental" }), + value: new fields.NumberField({ initial: 1, integer: true }), + rang: new fields.NumberField({ initial: 0, integer: true }), + max: new fields.NumberField({ initial: 1, integer: true }) + }), + san: new fields.SchemaField({ + label: new fields.StringField({ initial: "Sang-Froid" }), + labelnorm: new fields.StringField({ initial: "sangfroid" }), + abbrev: new fields.StringField({ initial: "san" }), + kind: new fields.StringField({ initial: "mental" }), + value: new fields.NumberField({ initial: 1, integer: true }), + rang: new fields.NumberField({ initial: 0, integer: true }), + max: new fields.NumberField({ initial: 1, integer: true }) + }) + }), + statutmasque: new fields.StringField({ initial: "masque" }), + rang: new fields.SchemaField({ + tricherie: new fields.SchemaField({ + label: new fields.StringField({ initial: "Tricherie" }), + value: new fields.NumberField({ initial: 0, integer: true }), + max: new fields.NumberField({ initial: 0, integer: true }) + }), + feerie: new fields.SchemaField({ + label: new fields.StringField({ initial: "Féerie" }), + value: new fields.NumberField({ initial: 0, integer: true }), + max: new fields.NumberField({ initial: 0, integer: true }) + }), + masque: new fields.SchemaField({ + label: new fields.StringField({ initial: "Masque" }), + value: new fields.NumberField({ initial: 0, integer: true }), + max: new fields.NumberField({ initial: 0, integer: true }) + }), + heritage: new fields.SchemaField({ + label: new fields.StringField({ initial: "Héritage" }), + value: new fields.NumberField({ initial: 0, integer: true }), + max: new fields.NumberField({ initial: 0, integer: true }), + scenarios: new fields.NumberField({ initial: 0, integer: true }) + }) + }), + pv: new fields.SchemaField({ + value: new fields.NumberField({ initial: 0, integer: true }), + max: new fields.NumberField({ initial: 0, integer: true }), + mod: new fields.NumberField({ initial: 0, integer: true }) + }), + competences: new fields.SchemaField({ + aventurier: new fields.SchemaField({ + label: new fields.StringField({ initial: "Aventurier" }), + niveau: new fields.NumberField({ initial: 0, integer: true }), + rang: new fields.NumberField({ initial: 0, integer: true }), + pp: new fields.NumberField({ initial: 0, integer: true }) + }), + combattant: new fields.SchemaField({ + label: new fields.StringField({ initial: "Combattant" }), + niveau: new fields.NumberField({ initial: 0, integer: true }), + rang: new fields.NumberField({ initial: 0, integer: true }), + pp: new fields.NumberField({ initial: 0, integer: true }) + }), + erudit: new fields.SchemaField({ + label: new fields.StringField({ initial: "Erudit" }), + niveau: new fields.NumberField({ initial: 0, integer: true }), + rang: new fields.NumberField({ initial: 0, integer: true }), + pp: new fields.NumberField({ initial: 0, integer: true }) + }), + gentleman: new fields.SchemaField({ + label: new fields.StringField({ initial: "Gentleman" }), + niveau: new fields.NumberField({ initial: 0, integer: true }), + rang: new fields.NumberField({ initial: 0, integer: true }), + pp: new fields.NumberField({ initial: 0, integer: true }) + }), + roublard: new fields.SchemaField({ + label: new fields.StringField({ initial: "Roublard" }), + niveau: new fields.NumberField({ initial: 0, integer: true }), + rang: new fields.NumberField({ initial: 0, integer: true }), + pp: new fields.NumberField({ initial: 0, integer: true }) + }), + savant: new fields.SchemaField({ + label: new fields.StringField({ initial: "Savant" }), + niveau: new fields.NumberField({ initial: 0, integer: true }), + rang: new fields.NumberField({ initial: 0, integer: true }), + pp: new fields.NumberField({ initial: 0, integer: true }) + }) + }), + magie: new fields.SchemaField({ + pointsame: new fields.SchemaField({ + value: new fields.NumberField({ initial: 0, integer: true }), + max: new fields.NumberField({ initial: 0, integer: true }) + }) + }), + experience: new fields.SchemaField({ + value: new fields.NumberField({ initial: 0, integer: true }), + pourtricher: new fields.NumberField({ initial: 0, integer: true }) + }), + combat: new fields.SchemaField({ + esquive: new fields.SchemaField({ + masquee: new fields.NumberField({ initial: 0, integer: true }), + demasquee: new fields.NumberField({ initial: 0, integer: true }) + }), + parade: new fields.SchemaField({ + masquee: new fields.NumberField({ initial: 0, integer: true }), + demasquee: new fields.NumberField({ initial: 0, integer: true }), + value: new fields.NumberField({ initial: 0, integer: true }) + }), + resistancephysique: new fields.SchemaField({ + value: new fields.NumberField({ initial: 0, integer: true }) + }), + resistancepsychique: new fields.SchemaField({ + value: new fields.NumberField({ initial: 0, integer: true }) + }), + protection: new fields.SchemaField({ + value: new fields.NumberField({ initial: 0, integer: true }) + }), + effetssecondaires: new fields.StringField({ initial: "" }), + dissimulation: new fields.SchemaField({ + value: new fields.NumberField({ initial: 0, integer: true }) + }), + initiative: new fields.SchemaField({ + masquee: new fields.NumberField({ initial: 0, integer: true }), + demasquee: new fields.NumberField({ initial: 0, integer: true }) + }), + corpsacorps: new fields.SchemaField({ + masquee: new fields.NumberField({ initial: 0, integer: true }), + demasquee: new fields.NumberField({ initial: 0, integer: true }) + }), + tir: new fields.SchemaField({ + masquee: new fields.NumberField({ initial: 0, integer: true }), + demasquee: new fields.NumberField({ initial: 0, integer: true }) + }) + }) + }; + } +} diff --git a/modules/models/pnj.mjs b/modules/models/pnj.mjs new file mode 100644 index 0000000..598f8a9 --- /dev/null +++ b/modules/models/pnj.mjs @@ -0,0 +1,10 @@ +/** + * Data model pour les PNJ + * Utilise le même schéma que les personnages + */ +import PersonnageDataModel from './personnage.mjs'; + +export default class PnjDataModel extends PersonnageDataModel { + // Les PNJ utilisent exactement le même schéma que les personnages + // On hérite simplement de PersonnageDataModel +} diff --git a/modules/models/pouvoir.mjs b/modules/models/pouvoir.mjs new file mode 100644 index 0000000..32c94b0 --- /dev/null +++ b/modules/models/pouvoir.mjs @@ -0,0 +1,29 @@ +/** + * Data model pour les pouvoirs + */ +export default class PouvoirDataModel extends foundry.abstract.TypeDataModel { + static defineSchema() { + const fields = foundry.data.fields; + return { + pouvoirtype: new fields.StringField({ initial: "" }), + masquetype: new fields.StringField({ initial: "" }), + niveau: new fields.StringField({ initial: "" }), + activation: new fields.StringField({ initial: "" }), + istest: new fields.BooleanField({ initial: false }), + feeriemasque: new fields.StringField({ initial: "feerie" }), + zoneffet: new fields.StringField({ initial: "" }), + testautre: new fields.StringField({ initial: "" }), + carac: new fields.StringField({ initial: "pre" }), + duree: new fields.StringField({ initial: "" }), + cibles: new fields.StringField({ initial: "" }), + effet: new fields.StringField({ initial: "" }), + portee: new fields.StringField({ initial: "" }), + resistance: new fields.StringField({ initial: "" }), + resistanceautre: new fields.StringField({ initial: "" }), + pointsusagecourant: new fields.NumberField({ initial: -1, integer: true }), + isvirulence: new fields.BooleanField({ initial: false }), + virulence: new fields.StringField({ initial: "" }), + description: new fields.HTMLField({ initial: "" }) + }; + } +} diff --git a/modules/models/profil.mjs b/modules/models/profil.mjs new file mode 100644 index 0000000..a39575c --- /dev/null +++ b/modules/models/profil.mjs @@ -0,0 +1,12 @@ +/** + * Data model pour les profils + */ +export default class ProfilDataModel extends foundry.abstract.TypeDataModel { + static defineSchema() { + const fields = foundry.data.fields; + return { + profiltype: new fields.StringField({ initial: "majeur" }), + description: new fields.HTMLField({ initial: "" }) + }; + } +} diff --git a/modules/models/protection.mjs b/modules/models/protection.mjs new file mode 100644 index 0000000..e874246 --- /dev/null +++ b/modules/models/protection.mjs @@ -0,0 +1,20 @@ +/** + * Data model pour les protections + */ +export default class ProtectionDataModel extends foundry.abstract.TypeDataModel { + static defineSchema() { + const fields = foundry.data.fields; + return { + description: new fields.HTMLField({ initial: "" }), + rarete: new fields.NumberField({ initial: 0, integer: true }), + quantite: new fields.NumberField({ initial: 0, integer: true }), + prix: new fields.NumberField({ initial: 0, integer: true }), + equipped: new fields.BooleanField({ initial: false }), + points: new fields.NumberField({ initial: 0, integer: true }), + protectiontype: new fields.StringField({ initial: "" }), + effetsecondaire: new fields.StringField({ initial: "" }), + malusagilite: new fields.NumberField({ initial: 0, integer: true }), + dissimulation: new fields.StringField({ initial: "" }) + }; + } +} diff --git a/modules/models/sort.mjs b/modules/models/sort.mjs new file mode 100644 index 0000000..f9b236e --- /dev/null +++ b/modules/models/sort.mjs @@ -0,0 +1,27 @@ +/** + * Data model pour les sorts + */ +export default class SortDataModel extends foundry.abstract.TypeDataModel { + static defineSchema() { + const fields = foundry.data.fields; + return { + niveau: new fields.StringField({ initial: "1" }), + rang: new fields.StringField({ initial: "1" }), + competence: new fields.StringField({ initial: "Druidisme" }), + carac1: new fields.StringField({ initial: "esp" }), + carac2: new fields.StringField({ initial: "none" }), + sdspecial: new fields.StringField({ initial: "" }), + duree: new fields.StringField({ initial: "" }), + portee: new fields.StringField({ initial: "" }), + concentration: new fields.StringField({ initial: "" }), + informatif: new fields.BooleanField({ initial: false }), + texteinformatif: new fields.StringField({ initial: "" }), + critique: new fields.StringField({ initial: "" }), + ingredients: new fields.StringField({ initial: "" }), + resistance: new fields.StringField({ initial: "" }), + coutactivation: new fields.StringField({ initial: "" }), + souffle: new fields.StringField({ initial: "" }), + description: new fields.HTMLField({ initial: "" }) + }; + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..879cf93 --- /dev/null +++ b/package.json @@ -0,0 +1,16 @@ +{ + "name": "fvtt-les-heritiers", + "version": "13.0.7", + "description": "Les Héritiers RPG for FoundryVTT (French)", + "scripts": { + "build": "gulp build", + "watch": "gulp watch" + }, + "author": "Uberwald/LeRatierBretonnien", + "license": "SEE LICENSE IN LICENCE.txt", + "devDependencies": { + "gulp": "^4.0.2", + "gulp-less": "^5.0.0", + "gulp-sourcemaps": "^3.0.0" + } +} diff --git a/system.json b/system.json index acc9618..ead91ee 100644 --- a/system.json +++ b/system.json @@ -220,7 +220,7 @@ "secondaryTokenAttribute": "bonneaventure.actuelle", "socket": true, "styles": [ - "styles/simple.css" + "styles/heritiers.css" ], "title": "Les Héritiers", "url": "https://www.uberwald.me/gitea/public/fvtt-les-heritiers", diff --git a/templates/actor-pnj-sheet.hbs b/templates/actor-pnj-sheet.hbs new file mode 100644 index 0000000..7c2b204 --- /dev/null +++ b/templates/actor-pnj-sheet.hbs @@ -0,0 +1,547 @@ +
+ + {{!-- Sheet Header --}} +
+
+
+ +
+

+
+ +
+
    + {{#each system.caracteristiques as |carac key|}} + {{#if (eq kind "physical")}} +
  • +

    {{carac.label}}

    + + +
  • + {{/if}} + {{/each}} +
+
+ +
+
    + {{#each system.caracteristiques as |carac key|}} + {{#if (eq kind "mental")}} +
  • +

    {{carac.label}}

    + + +
  • + {{/if}} + {{/each}} +
+
+ +
+ +
+ + + + + +    + + + +    + + + +
+ +
+
+
+ + {{!-- Sheet Tab Navigation --}} + + + {{!-- Sheet Body --}} +
+ + {{!-- Competence Tab --}} +
+ +
+ +
+ +
+ {{#each utileSkillsPhysical as |skillDef keyProfil|}} + {{> systems/fvtt-les-heritiers/templates/partial-utile-skills.hbs skillDef=skillDef keyProfil=keyProfil isPNJ=true}} + {{/each}} +
+ +
+ {{#each utileSkillsMental as |skillDef keyProfil|}} + {{> systems/fvtt-les-heritiers/templates/partial-utile-skills.hbs skillDef=skillDef keyProfil=keyProfil isPNJ=true}} + {{/each}} +
+ +
+ +
+
    +
  • + +

    +
    + + + +
     
    +
  • + {{#each futileSkills as |skill key|}} +
  • + {{skill.name}} + + + +
    + + +
    +
  • + {{/each}} +
+
+ + +
  • +

    Magie

    +
  • + +
    + +
    + + {{#each magieList as |magie idx|}} +
  • +

    +
    + + +
    +

    +
  • + +
    +
      +
    • + +

      +
      + + + +
       
      +
      + +
      +
    • + {{#each sorts as |sort key|}} +
    • + + {{sort.name}} + {{upperFirst sort.system.niveau}} + +
       
      +
      + + +
      +
    • + {{/each}} +
    +
    + {{/each}} + + +
    + +
    + + {{!-- Equipement Tab --}} +
    + +
      +
    • + +
    • +
    • + + + + + + + + + + +
    • +
    • + + + + + + +
    • +
    • + + + + +
    • +
    • + + + + + +
    • +
    • + + + + + +
    • +
    + +
    + +
    +
      +
    • + +

      +
      + + + + + + +
       
      +
      + +
      +
    • + {{#each armes as |arme key|}} +
    • + + {{arme.name}} + + + + + + + {{arme.system.degats}} + + +
       
      + +
    • + {{/each}} +
    +
    + +
    +
      +
    • + +

      +
      + + + +
       
      +
      + +
      +
    • + {{#each protections as |protection key|}} +
    • + + {{protection.name}} + + +
       
      +
      + + +
      +
    • + {{/each}} +
    +
    +
    +
    + + + {{!-- atouts Tab --}} +
    + +
    +
  • + + {{fee.name}} +
     
    +
    + + +
    +
  • +
    + +
    + +
    + +
    + +
    +
      +
    • + +

      +
      +
       
      +
      + +
      +
    • + {{#each avantages as |avantage key|}} +
    • + + {{avantage.name}} +
       
      +
      + + +
      +
    • + {{/each}} +
    +
    + +
    +
      +
    • + +

      +
      +
       
      +
      + +
      +
    • + {{#each desavantages as |desavantage key|}} +
    • + + {{desavantage.name}} +
       
      +
      + + +
      +
    • + {{/each}} +
    +
    + +
    +
      +
    • + +

      +
      +
       
      +
      + +
      +
    • + {{#each atouts as |atout key|}} +
    • + + {{atout.name}} +
       
      +
      + + +
      +
    • + {{/each}} +
    +
    + +
    +
      +
    • + +

      +
      + + + + + + + + + + + + +
       
      +
      + +
      +
    • + {{#each pouvoirs as |pouvoir key|}} +
    • + + {{pouvoir.name}} + {{upperFirst pouvoir.system.masquetype}} + {{upperFirst pouvoir.system.pouvoirtype}} + {{upperFirst pouvoir.system.niveau}} + {{pouvoir.system.pointsusagecourant}}/{{pouvoir.maxUsage}} + +
       
      +
      + + +
      +
    • + {{/each}} +
    +
    + +
    +
      +
    • + +

      +
      +
       
      +
      + +
      +
    • + {{#each capacites as |capa key|}} +
    • + + {{capa.name}} +
       
      +
      + + +
      +
    • + {{/each}} +
    +
    + +
    +
      +
    • + +

      +
      +
       
      +
      + +
      +
    • + {{#each equipements as |equip key|}} +
    • + + {{equip.name}} +
       
      +
      + + +
      +
    • + {{/each}} +
    +
    + + +
    + +
    + + +
    + +

    Historique

    +
    +
    + {{editor description target="system.biodata.description" button=true owner=owner editable=editable}} +
    + +
    + +
    +
    \ No newline at end of file diff --git a/templates/actor-pnj-sheet.hbs.backup b/templates/actor-pnj-sheet.hbs.backup new file mode 100644 index 0000000..105ebe2 --- /dev/null +++ b/templates/actor-pnj-sheet.hbs.backup @@ -0,0 +1,547 @@ +
    + + {{!-- Sheet Header --}} +
    +
    +
    + +
    +

    +
    + +
    +
      + {{#each system.caracteristiques as |carac key|}} + {{#if (eq kind "physical")}} +
    • +

      {{carac.label}}

      + + +
    • + {{/if}} + {{/each}} +
    +
    + +
    +
      + {{#each system.caracteristiques as |carac key|}} + {{#if (eq kind "mental")}} +
    • +

      {{carac.label}}

      + + +
    • + {{/if}} + {{/each}} +
    +
    + +
    + +
    + + + + + +    + + + +    + + + +
    + +
    +
    +
    + + {{!-- Sheet Tab Navigation --}} + + + {{!-- Sheet Body --}} +
    + + {{!-- Competence Tab --}} +
    + +
    + +
    + +
    + {{#each utileSkillsPhysical as |skillDef keyProfil|}} + {{> systems/fvtt-les-heritiers/templates/partial-utile-skills.hbs skillDef=skillDef keyProfil=keyProfil isPNJ=true}} + {{/each}} +
    + +
    + {{#each utileSkillsMental as |skillDef keyProfil|}} + {{> systems/fvtt-les-heritiers/templates/partial-utile-skills.hbs skillDef=skillDef keyProfil=keyProfil isPNJ=true}} + {{/each}} +
    + +
    + +
    +
      +
    • + +

      +
      + + + +
       
      +
    • + {{#each futileSkills as |skill key|}} +
    • + {{skill.name}} + + + +
      + + +
      +
    • + {{/each}} +
    +
    + + +
  • +

    Magie

    +
  • + +
    + +
    + + {{#each magieList as |magie idx|}} +
  • +

    +
    + + +
    +

    +
  • + +
    +
      +
    • + +

      +
      + + + +
       
      +
      + +
      +
    • + {{#each sorts as |sort key|}} +
    • + + {{sort.name}} + {{upperFirst sort.system.niveau}} + +
       
      +
      + + +
      +
    • + {{/each}} +
    +
    + {{/each}} + + +
    + +
    + + {{!-- Equipement Tab --}} +
    + +
      +
    • + +
    • +
    • + + + + + + + + + + +
    • +
    • + + + + + + +
    • +
    • + + + + +
    • +
    • + + + + + +
    • +
    • + + + + + +
    • +
    + +
    + +
    +
      +
    • + +

      +
      + + + + + + +
       
      +
      + +
      +
    • + {{#each armes as |arme key|}} +
    • + + {{arme.name}} + + + + + + + {{arme.system.degats}} + + +
       
      + +
    • + {{/each}} +
    +
    + +
    +
      +
    • + +

      +
      + + + +
       
      +
      + +
      +
    • + {{#each protections as |protection key|}} +
    • + + {{protection.name}} + + +
       
      +
      + + +
      +
    • + {{/each}} +
    +
    +
    +
    + + + {{!-- atouts Tab --}} +
    + +
    +
  • + + {{fee.name}} +
     
    +
    + + +
    +
  • +
    + +
    + +
    + +
    + +
    +
      +
    • + +

      +
      +
       
      +
      + +
      +
    • + {{#each avantages as |avantage key|}} +
    • + + {{avantage.name}} +
       
      +
      + + +
      +
    • + {{/each}} +
    +
    + +
    +
      +
    • + +

      +
      +
       
      +
      + +
      +
    • + {{#each desavantages as |desavantage key|}} +
    • + + {{desavantage.name}} +
       
      +
      + + +
      +
    • + {{/each}} +
    +
    + +
    +
      +
    • + +

      +
      +
       
      +
      + +
      +
    • + {{#each atouts as |atout key|}} +
    • + + {{atout.name}} +
       
      +
      + + +
      +
    • + {{/each}} +
    +
    + +
    +
      +
    • + +

      +
      + + + + + + + + + + + + +
       
      +
      + +
      +
    • + {{#each pouvoirs as |pouvoir key|}} +
    • + + {{pouvoir.name}} + {{upperFirst pouvoir.system.masquetype}} + {{upperFirst pouvoir.system.pouvoirtype}} + {{upperFirst pouvoir.system.niveau}} + {{pouvoir.system.pointsusagecourant}}/{{pouvoir.maxUsage}} + +
       
      +
      + + +
      +
    • + {{/each}} +
    +
    + +
    +
      +
    • + +

      +
      +
       
      +
      + +
      +
    • + {{#each capacites as |capa key|}} +
    • + + {{capa.name}} +
       
      +
      + + +
      +
    • + {{/each}} +
    +
    + +
    +
      +
    • + +

      +
      +
       
      +
      + +
      +
    • + {{#each equipements as |equip key|}} +
    • + + {{equip.name}} +
       
      +
      + + +
      +
    • + {{/each}} +
    +
    + + +
    + +
    + + +
    + +

    Historique

    +
    +
    + {{editor description target="system.biodata.description" button=true owner=owner editable=editable}} +
    + +
    + +
    +
    \ No newline at end of file diff --git a/templates/actor-sheet.hbs b/templates/actor-sheet.hbs new file mode 100644 index 0000000..9c0f463 --- /dev/null +++ b/templates/actor-sheet.hbs @@ -0,0 +1,948 @@ +
    + + {{!-- Sheet Header --}} +
    +
    +
    + +
    +

    +
    + +
    +
      + {{#each system.caracteristiques as |carac key|}} + {{#if (eq kind "physical")}} +
    • +

      {{carac.label}}

      + + +
    • + {{/if}} + {{/each}} +
    +
    + +
    +
      + {{#each system.caracteristiques as |carac key|}} + {{#if (eq kind "mental")}} +
    • +

      {{carac.label}}

      + + +
    • + {{/if}} + {{/each}} +
    +
    + +
    +
    + + + + + + +    + + + +    + + + +
    + +
    +
    +
    + + {{!-- Sheet Tab Navigation --}} + + + {{!-- Sheet Body --}} +
    + + {{!-- Competence Tab --}} +
    + +
    + +
    + +
    + {{#each utileSkillsPhysical as |skillDef keyProfil|}} + {{> systems/fvtt-les-heritiers/templates/partial-utile-skills.hbs skillDef=skillDef keyProfil=keyProfil + config=config}} + {{/each}} +
    + +
    + {{#each utileSkillsMental as |skillDef keyProfil|}} + {{> systems/fvtt-les-heritiers/templates/partial-utile-skills.hbs skillDef=skillDef keyProfil=keyProfil + config=config}} + {{/each}} +
    + +
    + +
    +
      +
    • + +

      +
      + + + +
       
      +
      + +
      +
    • + {{#each futileSkills as |skill key|}} +
    • + {{skill.name}} + + + +
      + + +
      +
    • + {{/each}} +
    +
    + +
    + +
    + + {{!-- Equipement Tab --}} +
    + +
      +
    • + +
    • +
    • + + + + + + + + + + + +
    • +
    • + + + + + + + + +
    • +
    • + + + + + +
    • +
    + +
    + +
    +
      +
    • + +

      +
      + + + + + + +
       
      +
      + +
      +
    • + {{#each armes as |arme key|}} +
    • + + {{arme.name}} + + + {{arme.system.degats}} + + + + + + + + + + + {{#if arme.system.isMelee}} + + + + + + + {{/if}} + +
       
      + +
    • + {{/each}} +
    +
    + +
    +
      +
    • + +

      +
      + + + +
       
      +
      + +
      +
    • + {{#each protections as |protection key|}} +
    • + + {{protection.name}} + + +
       
      +
      + + +
      +
    • + {{/each}} +
    +
    +
    +
    + + + {{!-- Fee Tab --}} +
    + +
    +
  • + + {{fee.name}} +
     
    +
    + + +
    +
  • +
    + +
    + +
    + +
    + +
    +
      +
    • + +

      +
      +
       
      +
      + +
      +
    • + {{#each avantages as |avantage key|}} +
    • + + {{avantage.name}} +
       
      +
      + + +
      +
    • + {{/each}} +
    +
    + +
    +
      +
    • + +

      +
      +
       
      +
      + +
      +
    • + {{#each desavantages as |desavantage key|}} +
    • + + {{desavantage.name}} +
       
      +
      + + +
      +
    • + {{/each}} +
    +
    + +
    +
      +
    • + +

      +
      +
       
      +
      + +
      +
    • + {{#each atouts as |atout key|}} +
    • + + {{atout.name}} +
       
      +
      + + +
      +
    • + {{/each}} +
    +
    + +
    +
      +
    • + +

      +
      + + + + + + + + + + + + +
       
      +
      + +
      +
    • + {{#each pouvoirs as |pouvoir key|}} +
    • + + {{pouvoir.name}} + {{upperFirst pouvoir.system.masquetype}} + {{upperFirst pouvoir.system.pouvoirtype}} + {{upperFirst pouvoir.system.niveau}} + {{pouvoir.system.pointsusagecourant}}/{{pouvoir.maxUsage}} + +
       
      +
      + + +
      +
    • + {{/each}} +
    +
    + + +
    +
      +
    • + +

      +
      +
       
      +
      + +
      +
    • + {{#each capacites as |capa key|}} +
    • + + {{capa.name}} +
       
      +
      + + +
      +
    • + {{/each}} +
    +
    + + +
    + +
    + + {{!-- Magie Tab --}} +
    + +
    +
      +
    • + + + +
    • +
    +
    + + {{#each magieList as |magie idx|}} +
  • +

    + + {{magie.rangSpecificName}} +
    + + +
    +

    +
  • + + {{#if (eq magie.name "Magie du Clan")}} +
    +

    Souffle de Combat

    +
      + {{#each sorts.soufflecombat as |niveau key|}} +
    • + +

      +
      +
      + {{#if @root.isGM}} + + {{/if}} +
      +
    • + {{#each niveau.sorts as |sort key|}} +
    • + + {{sort.name}} + {{#if sort.system.informatif}} + Informatif + {{else}} + {{upperFirst sort.system.niveau}} + {{/if}} + +
       
      +
      + + +
      +
    • + {{/each}} + {{/each}} +
    + +

    Souffle de Mouvement

    +
      + {{#each sorts.soufflemouvement as |niveau key|}} +
    • + +

      +
      +
      + {{#if @root.isGM}} + + {{/if}} +
      +
    • + {{#each niveau.sorts as |sort key|}} +
    • + + {{sort.name}} + {{#if sort.system.informatif}} + Informatif + {{else}} + {{upperFirst sort.system.niveau}} + {{/if}} + +
       
      +
      + + +
      +
    • + {{/each}} + {{/each}} +
    +

    Souffle de l'Esprit

    +
      + {{#each sorts.souffleesprit as |niveau key|}} +
    • + +

      +
      +
      + {{#if @root.isGM}} + + {{/if}} +
      +
    • + {{#each niveau.sorts as |sort key|}} +
    • + + {{sort.name}} + {{#if sort.system.informatif}} + Informatif + {{else}} + {{upperFirst sort.system.niveau}} + {{/if}} + +
       
      +
      + + +
      +
    • + {{/each}} + {{/each}} +
    + {{else}} +
    +
      + {{#each sorts as |niveau key|}} +
    • + +

      +
      +
      + {{#if @root.isGM}} + + {{/if}} +
      +
    • + {{#each niveau.sorts as |sort key|}} +
    • + + {{sort.name}} + + {{#if sort.system.informatif}} + Informatif + {{else}} + {{upperFirst sort.system.niveau}} + {{/if}} + +
       
      +
      + + +
      +
    • + {{/each}} + {{/each}} +
    +
    + {{/if}} + {{/each}} + +
    + + {{!-- Equipement Tab --}} +
    + +
    +
      +
    • + +

      +
      +
       
      +
      + +
      +
    • + {{#each equipements as |equip key|}} +
    • + + {{equip.name}} +
       
      +
      + + +
      +
    • + {{/each}} +
    +
    +
    + + {{!-- Contact Tab --}} +
    + +
    +
      +
    • + +

      +
      +
       
      +
      + +
      +
    • +
    + + {{#each contacts as |contactList idx|}} +
    +
      +
    • + +

      +
      +
       
      +
      + +
      +
    • + {{#each contactList.list as |contact key|}} +
    • + + {{contact.name}} +
       
      +
      + + +
      +
    • + {{/each}} +
    +
    + {{/each}} + +
    + + {{!-- Biography Tab --}} +
    + +
    +
      +
    • + +

      +
      + + + +
       
      +
      +
      +
    • + {{#each profils as |profil key|}} +
    • + + {{profil.name}} + {{upperFirst profil.system.profiltype}} +
       
      +
      + + +
      +
    • + {{/each}} +
    +
    + +
    +
    +
      +
    • + +
    • +
    • + +
    • +
    • + +
    • +
    • + +
    • +
    +
      +
    • + +
    • +
    • + +
    • +
    • + +
    • +
    • + +
    • +
    +
    +
    + +
    +
    +
      +
    • + + +
    • +
    • + + +
    • +
    • + + +
    • + {{#if isGM}} +
    • + + +
    • + {{/if}} +
    +
    + +
    +
      +
    • + + +
    • +
    • + + +
    • +
    • + + +
    • +
    • + + +
    • + +
    +
    + +
    +
      +
    • + + +
    • +
    • + + +
    • +
    • + + +
    • +
    • + + +
    • +
    +
    +
    + + {{#if isGM}} + {{#if system.biodata.magie}} +
    Magie activée : Glissez/Déplacez la/les compétences de Magie + nécessaires + depuis le compendium dans l'onglet "Magie", puis faites de même pour les sorts. +
    + {{/if}} + {{/if}} + +
    + +
    + +

    Historique

    +
    +
    + {{editor description target="system.biodata.description" button=true owner=owner editable=editable}} +
    + + +

    Notes diverses

    +
    +
    + {{editor playernotes target="system.biodata.playernotes" button=true owner=owner editable=editable}} +
    + + +

    Rêves étranges

    +
    +
    + {{editor revesetranges target="system.biodata.revesetranges" button=true owner=owner editable=editable}} +
    + + +

    Secrets découverts

    +
    +
    + {{editor secretsdecouverts target="system.biodata.secretsdecouverts" button=true owner=owner + editable=editable}} +
    + + +

    Questions en suspens

    +
    +
    + {{editor questions target="system.biodata.questions" button=true owner=owner editable=editable}} +
    + +
    + +
    +
    \ No newline at end of file diff --git a/templates/actor-sheet.hbs.backup b/templates/actor-sheet.hbs.backup new file mode 100644 index 0000000..3f93e74 --- /dev/null +++ b/templates/actor-sheet.hbs.backup @@ -0,0 +1,948 @@ +
    + + {{!-- Sheet Header --}} +
    +
    +
    + +
    +

    +
    + +
    +
      + {{#each system.caracteristiques as |carac key|}} + {{#if (eq kind "physical")}} +
    • +

      {{carac.label}}

      + + +
    • + {{/if}} + {{/each}} +
    +
    + +
    +
      + {{#each system.caracteristiques as |carac key|}} + {{#if (eq kind "mental")}} +
    • +

      {{carac.label}}

      + + +
    • + {{/if}} + {{/each}} +
    +
    + +
    +
    + + + + + + +    + + + +    + + + +
    + +
    +
    +
    + + {{!-- Sheet Tab Navigation --}} + + + {{!-- Sheet Body --}} +
    + + {{!-- Competence Tab --}} +
    + +
    + +
    + +
    + {{#each utileSkillsPhysical as |skillDef keyProfil|}} + {{> systems/fvtt-les-heritiers/templates/partial-utile-skills.hbs skillDef=skillDef keyProfil=keyProfil + config=config}} + {{/each}} +
    + +
    + {{#each utileSkillsMental as |skillDef keyProfil|}} + {{> systems/fvtt-les-heritiers/templates/partial-utile-skills.hbs skillDef=skillDef keyProfil=keyProfil + config=config}} + {{/each}} +
    + +
    + +
    +
      +
    • + +

      +
      + + + +
       
      +
      + +
      +
    • + {{#each futileSkills as |skill key|}} +
    • + {{skill.name}} + + + +
      + + +
      +
    • + {{/each}} +
    +
    + +
    + +
    + + {{!-- Equipement Tab --}} +
    + +
      +
    • + +
    • +
    • + + + + + + + + + + + +
    • +
    • + + + + + + + + +
    • +
    • + + + + + +
    • +
    + +
    + +
    +
      +
    • + +

      +
      + + + + + + +
       
      +
      + +
      +
    • + {{#each armes as |arme key|}} +
    • + + {{arme.name}} + + + {{arme.system.degats}} + + + + + + + + + + + {{#if arme.system.isMelee}} + + + + + + + {{/if}} + +
       
      + +
    • + {{/each}} +
    +
    + +
    +
      +
    • + +

      +
      + + + +
       
      +
      + +
      +
    • + {{#each protections as |protection key|}} +
    • + + {{protection.name}} + + +
       
      +
      + + +
      +
    • + {{/each}} +
    +
    +
    +
    + + + {{!-- Fee Tab --}} +
    + +
    +
  • + + {{fee.name}} +
     
    +
    + + +
    +
  • +
    + +
    + +
    + +
    + +
    +
      +
    • + +

      +
      +
       
      +
      + +
      +
    • + {{#each avantages as |avantage key|}} +
    • + + {{avantage.name}} +
       
      +
      + + +
      +
    • + {{/each}} +
    +
    + +
    +
      +
    • + +

      +
      +
       
      +
      + +
      +
    • + {{#each desavantages as |desavantage key|}} +
    • + + {{desavantage.name}} +
       
      +
      + + +
      +
    • + {{/each}} +
    +
    + +
    +
      +
    • + +

      +
      +
       
      +
      + +
      +
    • + {{#each atouts as |atout key|}} +
    • + + {{atout.name}} +
       
      +
      + + +
      +
    • + {{/each}} +
    +
    + +
    +
      +
    • + +

      +
      + + + + + + + + + + + + +
       
      +
      + +
      +
    • + {{#each pouvoirs as |pouvoir key|}} +
    • + + {{pouvoir.name}} + {{upperFirst pouvoir.system.masquetype}} + {{upperFirst pouvoir.system.pouvoirtype}} + {{upperFirst pouvoir.system.niveau}} + {{pouvoir.system.pointsusagecourant}}/{{pouvoir.maxUsage}} + +
       
      +
      + + +
      +
    • + {{/each}} +
    +
    + + +
    +
      +
    • + +

      +
      +
       
      +
      + +
      +
    • + {{#each capacites as |capa key|}} +
    • + + {{capa.name}} +
       
      +
      + + +
      +
    • + {{/each}} +
    +
    + + +
    + +
    + + {{!-- Magie Tab --}} +
    + +
    +
      +
    • + + + +
    • +
    +
    + + {{#each magieList as |magie idx|}} +
  • +

    + + {{magie.rangSpecificName}} +
    + + +
    +

    +
  • + + {{#if (eq magie.name "Magie du Clan")}} +
    +

    Souffle de Combat

    +
      + {{#each sorts.soufflecombat as |niveau key|}} +
    • + +

      +
      +
      + {{#if @root.isGM}} + + {{/if}} +
      +
    • + {{#each niveau.sorts as |sort key|}} +
    • + + {{sort.name}} + {{#if sort.system.informatif}} + Informatif + {{else}} + {{upperFirst sort.system.niveau}} + {{/if}} + +
       
      +
      + + +
      +
    • + {{/each}} + {{/each}} +
    + +

    Souffle de Mouvement

    +
      + {{#each sorts.soufflemouvement as |niveau key|}} +
    • + +

      +
      +
      + {{#if @root.isGM}} + + {{/if}} +
      +
    • + {{#each niveau.sorts as |sort key|}} +
    • + + {{sort.name}} + {{#if sort.system.informatif}} + Informatif + {{else}} + {{upperFirst sort.system.niveau}} + {{/if}} + +
       
      +
      + + +
      +
    • + {{/each}} + {{/each}} +
    +

    Souffle de l'Esprit

    +
      + {{#each sorts.souffleesprit as |niveau key|}} +
    • + +

      +
      +
      + {{#if @root.isGM}} + + {{/if}} +
      +
    • + {{#each niveau.sorts as |sort key|}} +
    • + + {{sort.name}} + {{#if sort.system.informatif}} + Informatif + {{else}} + {{upperFirst sort.system.niveau}} + {{/if}} + +
       
      +
      + + +
      +
    • + {{/each}} + {{/each}} +
    + {{else}} +
    +
      + {{#each sorts as |niveau key|}} +
    • + +

      +
      +
      + {{#if @root.isGM}} + + {{/if}} +
      +
    • + {{#each niveau.sorts as |sort key|}} +
    • + + {{sort.name}} + + {{#if sort.system.informatif}} + Informatif + {{else}} + {{upperFirst sort.system.niveau}} + {{/if}} + +
       
      +
      + + +
      +
    • + {{/each}} + {{/each}} +
    +
    + {{/if}} + {{/each}} + +
    + + {{!-- Equipement Tab --}} +
    + +
    +
      +
    • + +

      +
      +
       
      +
      + +
      +
    • + {{#each equipements as |equip key|}} +
    • + + {{equip.name}} +
       
      +
      + + +
      +
    • + {{/each}} +
    +
    +
    + + {{!-- Contact Tab --}} +
    + +
    +
      +
    • + +

      +
      +
       
      +
      + +
      +
    • +
    + + {{#each contacts as |contactList idx|}} +
    +
      +
    • + +

      +
      +
       
      +
      + +
      +
    • + {{#each contactList.list as |contact key|}} +
    • + + {{contact.name}} +
       
      +
      + + +
      +
    • + {{/each}} +
    +
    + {{/each}} + +
    + + {{!-- Biography Tab --}} +
    + +
    +
      +
    • + +

      +
      + + + +
       
      +
      +
      +
    • + {{#each profils as |profil key|}} +
    • + + {{profil.name}} + {{upperFirst profil.system.profiltype}} +
       
      +
      + + +
      +
    • + {{/each}} +
    +
    + +
    +
    +
      +
    • + +
    • +
    • + +
    • +
    • + +
    • +
    • + +
    • +
    +
      +
    • + +
    • +
    • + +
    • +
    • + +
    • +
    • + +
    • +
    +
    +
    + +
    +
    +
      +
    • + + +
    • +
    • + + +
    • +
    • + + +
    • + {{#if isGM}} +
    • + + +
    • + {{/if}} +
    +
    + +
    +
      +
    • + + +
    • +
    • + + +
    • +
    • + + +
    • +
    • + + +
    • + +
    +
    + +
    +
      +
    • + + +
    • +
    • + + +
    • +
    • + + +
    • +
    • + + +
    • +
    +
    +
    + + {{#if isGM}} + {{#if system.biodata.magie}} +
    Magie activée : Glissez/Déplacez la/les compétences de Magie + nécessaires + depuis le compendium dans l'onglet "Magie", puis faites de même pour les sorts. +
    + {{/if}} + {{/if}} + +
    + +
    + +

    Historique

    +
    +
    + {{editor description target="system.biodata.description" button=true owner=owner editable=editable}} +
    + + +

    Notes diverses

    +
    +
    + {{editor playernotes target="system.biodata.playernotes" button=true owner=owner editable=editable}} +
    + + +

    Rêves étranges

    +
    +
    + {{editor revesetranges target="system.biodata.revesetranges" button=true owner=owner editable=editable}} +
    + + +

    Secrets découverts

    +
    +
    + {{editor secretsdecouverts target="system.biodata.secretsdecouverts" button=true owner=owner + editable=editable}} +
    + + +

    Questions en suspens

    +
    +
    + {{editor questions target="system.biodata.questions" button=true owner=owner editable=editable}} +
    + +
    + +
    +
    \ No newline at end of file diff --git a/templates/chat-assommer-result.hbs b/templates/chat-assommer-result.hbs new file mode 100644 index 0000000..6119ea1 --- /dev/null +++ b/templates/chat-assommer-result.hbs @@ -0,0 +1,30 @@ +
    + {{#if actorImg}} + {{alias}} + {{/if}} +

    {{alias}}

    +
    + +
    + +{{#if actionImg}} +
    + {{name}} +
    +{{/if}} + +
    +
    + +
    +
      +
    • Assomer {{defenderName}} en état de : {{etatAssommer}}
    • + + {{#if isSuccess}} +
    • Marge : {{marge}}
    • +
    • {{defenderName}} est assomé pour {{dureeAssommer}} minutes !
    • + {{else}} +
    • {{defenderName}} n'a pas été assomé et est conscient la tentative !
    • + {{/if}} +
    +
    \ No newline at end of file diff --git a/templates/chat-cc-result.hbs b/templates/chat-cc-result.hbs new file mode 100644 index 0000000..42f9322 --- /dev/null +++ b/templates/chat-cc-result.hbs @@ -0,0 +1,43 @@ +
    + {{#if actorImg}} + {{alias}} + {{/if}} +

    {{alias}}

    +
    + +
    + +{{#if actionImg}} +
    + {{name}} +
    +{{/if}} + +
    +
    + +
    +
      +
    • Défense de {{defenderName}} : {{defenderMode}} ({{defenderValue}})
    • + + {{#if isSuccess}} +
    • Marge : {{marge}}
    • +
    • Degats de l'arme : {{degatsArme}}
    • + + {{#if (eq attaqueCible "membre")}} +
    • Cible un membre : La cible a -2 de malus sur ces actions avec ce membre (mouvement 2 si jambes) +
    • + {{/if}} + {{#if (eq attaqueCible "main")}} +
    • Cible une main : La cible ne peut plus utiliser sa main
    • + {{/if}} + + {{#if isCriticalSuccess}} +
    • Critique : Aubaine ou +2 aux dégats ci-dessus
    • + {{/if}} + {{else}} +
    • Echec face à la {{defenderMode}} !
    • + {{/if}} + +
    +
    \ No newline at end of file diff --git a/templates/chat-generic-result.hbs b/templates/chat-generic-result.hbs new file mode 100644 index 0000000..b9d3b52 --- /dev/null +++ b/templates/chat-generic-result.hbs @@ -0,0 +1,145 @@ +
    + {{#if actorImg}} + {{alias}} + {{/if}} +

    {{alias}}

    +
    + +
    + +{{#if actionImg}} +
    + {{name}} +
    +{{/if}} + +
    +
    + +
    +
      +
    • Caractéristique : {{carac.label}} ({{carac.value}})
    • + + {{#if rang}} +
    • {{rang.label}} : {{rang.value}}
    • + {{/if}} + + {{#if competence}} +
    • Compétence : {{competence.name}} ({{competence.system.niveau}})
    • + {{#if useSpecialite}} +
    • Bonus de spécialité +1
    • + {{/if}} + {{/if}} + + {{#if arme}} +
    • Attaque avec : {{arme.name}}
    • + {{#if (eq mode "assommer")}} +
    • Attaque pour assommer
    • + {{/if}} + {{/if}} + + {{#if pouvoir}} +
    • Pouvoir : {{pouvoir.name}}
    • +
    • Effet : {{pouvoir.system.effet}}
    • + {{#if (ne pouvoir.system.duree "")}} +
    • Durée : {{pouvoir.system.duree}}
    • + {{/if}} + {{#if (ne pouvoir.system.portee "")}} +
    • Portée : {{pouvoir.system.portee}}
    • + {{/if}} + {{#if (ne pouvoir.system.resistance "")}} +
    • Résistance : {{pouvoir.system.resistance}}
    • + {{/if}} + {{#if (ne pouvoir.system.resistanceautre "")}} +
    • Résistance autre : {{pouvoir.system.resistanceautre}}
    • + {{/if}} + {{#if (ne pouvoir.system.zoneeffet "")}} +
    • Zone d'effet : {{pouvoir.system.zoneeffet}}
    • + {{/if}} + {{#if (ne pouvoir.system.cibles "")}} +
    • Cibles : {{pouvoir.system.cibles}}
    • + {{/if}} + {{#if (ne pouvoir.system.virulence "")}} +
    • Virulence : {{pouvoir.system.virulence}}
    • + {{/if}} +
    • Points d'usage consommés : {{pouvoirPointsUsage}}
    • + {{/if}} + + {{#if sort}} +
    • Sort : {{sort.name}}
    • + {{#if (ne sort.system.resistance "")}} +
    • Résistance : {{sort.system.resistance}}
    • + {{/if}} + {{#if (ne sort.system.concentration "")}} +
    • Concentration : {{sort.system.concentration}}
    • + {{/if}} + {{#if (ne sort.system.duree "")}} +
    • Durée : {{sort.system.duree}}
    • + {{/if}} + {{#if (ne sort.system.portee "")}} +
    • Portée : {{sort.system.portee}}
    • + {{/if}} + {{#if (ne sort.system.ingredients "")}} +
    • Ingrédients : {{sort.system.ingredients}}
    • + {{/if}} + {{#if (ne sort.system.coutactivation "")}} +
    • Coût d'activation : {{sort.system.coutactivation}}
    • + {{/if}} + {{#if spendEsprit}} +
    • Points d'Esprit dépensé : 1
    • + {{else}} +
    • Coût en points d'Âme : {{sortPointsAme}}
    • + {{#if (eq sort.system.competence "Magie du Clan")}} +
    • Souffle : {{sort.system.souffle}}
    • +
    • Cout en PV : 2
    • + {{/if}} + {{/if}} + {{/if}} + + {{#if forcedValue}} +
    • Vous dépensez 2 points de Tricherie et utilisez une face adjacente du dé !
    • + {{/if}} + + {{#if noRoll}} + {{else}} +
    • Formule : {{diceFormula}}
    • +
    • Résultat du dé : {{diceResult}}
    • + + {{#if adjacentFaces}} +
    • Faces adjacentes : + {{#each adjacentFaces as |value key|}} + {{value}} + {{/each}} +
    • + {{/if}} + +
    • Total : {{finalResult}} {{#if (gt sdValue "-1")}}(Marge : {{marge}}){{/if}}
    • + + + {{#if (gt sdValue "-1")}} +
    • Seuil de difficulté : {{sdValue}}
    • + {{#if isSuccess}} +
    • Succès... +
    • + {{else}} +
    • Echec...
    • + {{/if}} + {{/if}} + + {{#if isBrelan}} +
    • Brelan sur 3 dés !
    • + {{/if}} + {{#if isSuite}} +
    • Suite sur 3 dés !
    • + {{/if}} + + {{#if isCriticalSuccess}} +
    • Réussite Critique !!!
    • + {{/if}} + {{#if isCriticalFailure}} +
    • Echec Critique !!!
    • + {{/if}} + {{/if}} + +
    +
    \ No newline at end of file diff --git a/templates/editor-notes-gm.hbs b/templates/editor-notes-gm.hbs new file mode 100644 index 0000000..ca22bd0 --- /dev/null +++ b/templates/editor-notes-gm.hbs @@ -0,0 +1,6 @@ +{{#if data.isGM}} +

    GM Notes :

    +
    + {{editor data.biodata.gmnotes target="system.biodata.gmnotes" button=true owner=owner editable=editable}} +
    +{{/if}} diff --git a/templates/item-accessoire-sheet.hbs b/templates/item-accessoire-sheet.hbs new file mode 100644 index 0000000..ba28fdf --- /dev/null +++ b/templates/item-accessoire-sheet.hbs @@ -0,0 +1,38 @@ +
    + + {{> systems/fvtt-les-heritiers/templates/partial-item-header.hbs this}} + + {{> systems/fvtt-les-heritiers/templates/partial-item-nav.hbs this}} + + {{> systems/fvtt-les-heritiers/templates/partial-item-description.hbs this}} + +
    +
      + +
    • + + +
    • + +
    • + + +
    • + +
    • + + +
    • + +
    • + + +
    • + +
    +
    +
    diff --git a/templates/item-arme-sheet.hbs b/templates/item-arme-sheet.hbs new file mode 100644 index 0000000..0328900 --- /dev/null +++ b/templates/item-arme-sheet.hbs @@ -0,0 +1,134 @@ +
    + + {{> systems/fvtt-les-heritiers/templates/partial-item-header.hbs this}} + + {{> systems/fvtt-les-heritiers/templates/partial-item-nav.hbs this}} + + {{> systems/fvtt-les-heritiers/templates/partial-item-description.hbs this}} + +
    +
      + +
    • + + +
    • + +
    • + + +
    • + +
    • + + +
    • + +
    • + + +
    • + +
    • + + +
    • + +
    • + + +
    • + +
    • + + +
    • + +
    • + + +
    • + +
    • + + +
    • + +
    • + + +
    • + +
    • + + +
    • + +
    • + + +
    • + +
    • + + +
    • + +
    • + + +
    • + +
    • + + +
    • + +
    • + + +
    • + +
    • + + +
    • + +
    • + + +
    • + +
    • + + +
    • + +
    +
    +
    diff --git a/templates/item-atoutfeerique-sheet.hbs b/templates/item-atoutfeerique-sheet.hbs new file mode 100644 index 0000000..c860de5 --- /dev/null +++ b/templates/item-atoutfeerique-sheet.hbs @@ -0,0 +1,17 @@ +
    + + {{> systems/fvtt-les-heritiers/templates/partial-item-header.hbs this}} + + {{> systems/fvtt-les-heritiers/templates/partial-item-nav.hbs this}} + + {{> systems/fvtt-les-heritiers/templates/partial-item-description.hbs this}} + +
    +
      + +
    • + +
    • +
    +
    +
    diff --git a/templates/item-avantage-sheet.hbs b/templates/item-avantage-sheet.hbs new file mode 100644 index 0000000..1a919d0 --- /dev/null +++ b/templates/item-avantage-sheet.hbs @@ -0,0 +1,17 @@ +
    + + {{> systems/fvtt-les-heritiers/templates/partial-item-header.hbs this}} + + {{> systems/fvtt-les-heritiers/templates/partial-item-nav.hbs this}} + + {{> systems/fvtt-les-heritiers/templates/partial-item-description.hbs this}} + +
    +
      + +
    • + +
    • +
    +
    +
    diff --git a/templates/item-capacitenaturelle-sheet.hbs b/templates/item-capacitenaturelle-sheet.hbs new file mode 100644 index 0000000..71acc0c --- /dev/null +++ b/templates/item-capacitenaturelle-sheet.hbs @@ -0,0 +1,79 @@ +
    + {{> systems/fvtt-les-heritiers/templates/partial-item-header.hbs}} + + {{> systems/fvtt-les-heritiers/templates/partial-item-nav.hbs}} + + + {{> systems/fvtt-les-heritiers/templates/partial-item-description.hbs}} + +
    + +
      + +
    • + + +
    • + +
    • + + +
    • + +
    • + + +
    • + +
    • + + +
    • + +
    • + + +
    • + +
    • + + +
    • + + {{#if (eq system.resistance "autre")}} +
    • + + +
    • + {{/if}} + +
    • + + +
    • + + {{#if system.isvirulence}} +
    • + + +
    • + {{/if}} + +
    +
    + + +
    diff --git a/templates/item-competence-sheet.hbs b/templates/item-competence-sheet.hbs new file mode 100644 index 0000000..0ff60bb --- /dev/null +++ b/templates/item-competence-sheet.hbs @@ -0,0 +1,81 @@ +
    + + {{> systems/fvtt-les-heritiers/templates/partial-item-header.hbs this}} + + {{> systems/fvtt-les-heritiers/templates/partial-item-nav.hbs this}} + + {{> systems/fvtt-les-heritiers/templates/partial-item-description.hbs this}} + +
    +
      + +
    • + + +
    • + +
    • + + +
    • + +
    • + + +
    • + +
    • + + +
    • + + {{#if (eq system.profil "magie")}} + {{#if (eq item.name "Magie du Clan")}} + {{#each system.nomniveausouffle.soufflecombat as |niveau key|}} +
    • + + +
    • + {{/each}} + {{#each system.nomniveausouffle.soufflemouvement as |niveau key|}} +
    • + + +
    • + {{/each}} + {{#each system.nomniveausouffle.souffleesprit as |niveau key|}} +
    • + + +
    • + {{/each}} + + {{else}} + {{#each system.nomniveau as |niveau key|}} +
    • + + +
    • + {{/each}} + {{/if}} + {{/if}} + +
    • +

      Spécialités

      +
    • + +
    +
    +
    diff --git a/templates/item-contact-sheet.hbs b/templates/item-contact-sheet.hbs new file mode 100644 index 0000000..0f5297e --- /dev/null +++ b/templates/item-contact-sheet.hbs @@ -0,0 +1,22 @@ +
    + + {{> systems/fvtt-les-heritiers/templates/partial-item-header.hbs this}} + + {{> systems/fvtt-les-heritiers/templates/partial-item-nav.hbs this}} + + {{> systems/fvtt-les-heritiers/templates/partial-item-description.hbs this}} + +
    +
      + +
    • + + +
    • + +
    +
    + +
    diff --git a/templates/item-desavantage-sheet.hbs b/templates/item-desavantage-sheet.hbs new file mode 100644 index 0000000..52e5585 --- /dev/null +++ b/templates/item-desavantage-sheet.hbs @@ -0,0 +1,17 @@ +
    + + {{> systems/fvtt-les-heritiers/templates/partial-item-header.hbs this}} + + {{> systems/fvtt-les-heritiers/templates/partial-item-nav.hbs this}} + + {{> systems/fvtt-les-heritiers/templates/partial-item-description.hbs this}} + +
    +
      + +
    • + +
    • +
    +
    +
    diff --git a/templates/item-equipement-sheet.hbs b/templates/item-equipement-sheet.hbs new file mode 100644 index 0000000..de4728e --- /dev/null +++ b/templates/item-equipement-sheet.hbs @@ -0,0 +1,38 @@ +
    + + {{> systems/fvtt-les-heritiers/templates/partial-item-header.hbs this}} + + {{> systems/fvtt-les-heritiers/templates/partial-item-nav.hbs this}} + + {{> systems/fvtt-les-heritiers/templates/partial-item-description.hbs this}} + +
    +
      + +
    • + + +
    • + +
    • + + +
    • + +
    • + + +
    • + +
    • + + +
    • + +
    +
    +
    diff --git a/templates/item-fee-sheet.hbs b/templates/item-fee-sheet.hbs new file mode 100644 index 0000000..8a19e5a --- /dev/null +++ b/templates/item-fee-sheet.hbs @@ -0,0 +1,78 @@ +
    + {{> systems/fvtt-les-heritiers/templates/partial-item-header.hbs}} + + {{> systems/fvtt-les-heritiers/templates/partial-item-nav.hbs}} + + + {{> systems/fvtt-les-heritiers/templates/partial-item-description.hbs}} + + +
    + +
      + +
    • + + +
    • + +
    • + +
    • +
    • + +
    • + +
    • + +
    • +
    • + +
    • + +
    • + +
    • +
    • + +
    • + +
    • + +
    • +
    • + +
    • + +
    • + +
    • +
    • + +
    • + +
    • + +
    • +
    • + +
    • + +
    • + +
    • +
    • + +
    • + + +
    + +
    + + + +
    diff --git a/templates/item-pouvoir-sheet.hbs b/templates/item-pouvoir-sheet.hbs new file mode 100644 index 0000000..c9acadf --- /dev/null +++ b/templates/item-pouvoir-sheet.hbs @@ -0,0 +1,157 @@ +
    + {{> systems/fvtt-les-heritiers/templates/partial-item-header.hbs}} + + {{> systems/fvtt-les-heritiers/templates/partial-item-nav.hbs}} + + + {{> systems/fvtt-les-heritiers/templates/partial-item-description.hbs}} + +
    + +
      + +
    • + + +
    • + +
    • + + +
    • + +
    • + + +
    • + +
    • + + +
    • + +
    • + + +
    • + + {{#if system.istest}} +
    • + + +
    • + + {{#if (eq system.feeriemasque "autre")}} +
    • + + +
    • + {{else}} +
    • + + +
    • + {{/if}} + + {{/if}} + +
    • + + {{#if (eq usageMax -1)}} + + {{else}} + + {{/if}} +
    • + +
    • + + +
    • + +
    • + + +
    • + +
    • + + +
    • + +
    • + + +
    • + +
    • + + +
    • + +
    • + + +
    • + + {{#if (eq system.resistance "autre")}} +
    • + + +
    • + {{/if}} + +
    • + + +
    • + + +
    • + + +
    • + + {{#if system.isvirulence}} +
    • + + +
    • + {{/if}} + +
    +
    + + +
    diff --git a/templates/item-profil-sheet.hbs b/templates/item-profil-sheet.hbs new file mode 100644 index 0000000..1a44929 --- /dev/null +++ b/templates/item-profil-sheet.hbs @@ -0,0 +1,20 @@ +
    + + {{> systems/fvtt-les-heritiers/templates/partial-item-header.hbs this}} + + {{> systems/fvtt-les-heritiers/templates/partial-item-nav.hbs this}} + + {{> systems/fvtt-les-heritiers/templates/partial-item-description.hbs this}} + +
    +
      +
    • + + +
    • +
    +
    + +
    diff --git a/templates/item-protection-sheet.hbs b/templates/item-protection-sheet.hbs new file mode 100644 index 0000000..b28c5b9 --- /dev/null +++ b/templates/item-protection-sheet.hbs @@ -0,0 +1,65 @@ +
    + + {{> systems/fvtt-les-heritiers/templates/partial-item-header.hbs this}} + + {{> systems/fvtt-les-heritiers/templates/partial-item-nav.hbs this}} + + {{> systems/fvtt-les-heritiers/templates/partial-item-description.hbs this}} + +
    +
      + +
    • + + +
    • + +
    • + + +
    • + +
    • + + +
    • + +
    • + + +
    • + +
    • + + +
    • + +
    • + + +
    • + +
    • + + +
    • + +
    • + + +
    • + +
    +
    +
    diff --git a/templates/item-sort-sheet.hbs b/templates/item-sort-sheet.hbs new file mode 100644 index 0000000..317e30d --- /dev/null +++ b/templates/item-sort-sheet.hbs @@ -0,0 +1,134 @@ +
    + {{> systems/fvtt-les-heritiers/templates/partial-item-header.hbs}} + + {{> systems/fvtt-les-heritiers/templates/partial-item-nav.hbs}} + + + {{> systems/fvtt-les-heritiers/templates/partial-item-description.hbs}} + +
    + +
      +
    • + + +
    • + + {{#if (eq system.competence "Magie du Clan")}} +
    • + + +
    • + {{/if}} + +
    • + + +
    • + +
    • + + +
    • + +
    • + + +
    • + +
    • + + +
    • + + {{#if system.informatif}} +
    • + + +
    • + {{/if}} + +
    • + + +
    • + + + +
    • + + +
    • + +
    • + + +
    • + +
    • + + +
    • + +
    • + + + +
    • + +
    • + + + +
    • + +
    • + + + +
    • + +
    • + + +
    • + +
    +
    + + +
    diff --git a/templates/partial-actor-equipment.hbs b/templates/partial-actor-equipment.hbs new file mode 100644 index 0000000..43e5106 --- /dev/null +++ b/templates/partial-actor-equipment.hbs @@ -0,0 +1,24 @@ +
  • + + {{#if (eq level 1)}} + {{equip.name}} + {{else}} + {{equip.name}} + {{/if}} + + + + +
     
    +
    + {{#if (eq level 1)}} + {{#if equip.system.equipped}}{{else}}{{/if}} + {{/if}} + +
    +
  • + diff --git a/templates/partial-item-description.hbs b/templates/partial-item-description.hbs new file mode 100644 index 0000000..e8fe08a --- /dev/null +++ b/templates/partial-item-description.hbs @@ -0,0 +1,6 @@ +
    +
    + {{editor description target="system.description" button=true owner=owner editable=editable}} +
    +
    + diff --git a/templates/partial-item-header.hbs b/templates/partial-item-header.hbs new file mode 100644 index 0000000..f1757ac --- /dev/null +++ b/templates/partial-item-header.hbs @@ -0,0 +1,9 @@ +
    +
    + +
    +

    +
    +
    +
    + diff --git a/templates/partial-item-nav.hbs b/templates/partial-item-nav.hbs new file mode 100644 index 0000000..42f8709 --- /dev/null +++ b/templates/partial-item-nav.hbs @@ -0,0 +1,6 @@ +{{!-- Sheet Tab Navigation --}} + + diff --git a/templates/partial-utile-skills.hbs b/templates/partial-utile-skills.hbs new file mode 100644 index 0000000..f350475 --- /dev/null +++ b/templates/partial-utile-skills.hbs @@ -0,0 +1,49 @@ +
    +
      +
    • + {{#if isPNJ}} + + +

      +
      +
      + {{else}} + +

      +
      + {{/if}} + + + + + {{#if isPNJ}} + + + + {{/if}} +
       
      +
    • + {{#each skillDef.skills as |skill key|}} +
    • + {{skill.name}} + + +
      + + +
      +
    • + {{#if (count skill.specList)}} + {{skill.specList}} + {{/if}} + + {{/each}} +
    +
    + diff --git a/templates/post-item.hbs b/templates/post-item.hbs new file mode 100644 index 0000000..3136d7f --- /dev/null +++ b/templates/post-item.hbs @@ -0,0 +1,9 @@ +
    +

    {{name}}

    + {{#if img}} + + {{/if}} +

    Description :

    +

    {{{system.description}}}

    +
    + diff --git a/templates/roll-dialog-generic.hbs b/templates/roll-dialog-generic.hbs new file mode 100644 index 0000000..b2f51fb --- /dev/null +++ b/templates/roll-dialog-generic.hbs @@ -0,0 +1,168 @@ +
    +
    + {{#if img}} + + {{/if}} +

    {{title}}

    +
    + +
    + + {{#if (eq mode "rang")}} +
    + {{rang.label}} + {{rang.value}} +
    + {{/if}} + + {{#if (eq mode "carac")}} +
    + Caracteristique + {{carac.label}} ({{carac.value}}) +
    + {{else}} +
    + Caracteristique + +
    + {{/if}} + + {{#if caracMessage}} +
    + {{caracMessage}} +
    + {{/if}} + + {{#if competence}} +
    + {{competence.name}} + {{competence.system.niveau}} +
    + {{#if competence.nbSpec}} +
    + Spécialités : {{competence.specList}} +
    +
    + Bonus de spécialité ? + +
    + {{/if}} + {{/if}} + + {{#if pouvoir}} +
    + Pouvoir : + {{pouvoir.name}} +
    +
    + Activation : + {{pouvoir.system.activation}} +
    + {{#if pouvoirBase}} +
    + {{pouvoirBase.label}} : + {{pouvoirBase.value}} +
    + {{/if}} +
    + Points d'usage consommés : + +
    + {{/if}} + + {{#each rulesMalus as |malus key|}} +
    + {{malus.name}} + {{malus.value}} +
    + {{/each}} + + {{#if (and arme arme.system.isMelee)}} +
    + Attaque à plusieurs + +
    +
    + Attaque dans le dos ? + +
    +
    + Attaque à deux armes + +
    +
    + Seconde arme + +
    + {{/if}} + + {{#if arme}} +
  • + + +
  • + {{/if}} + + {{#if sort}} +
    + Sort : + {{sort.name}} ({{sort.system.niveau}}) +
    +
    + Duree : + {{sort.system.duree}} +
    +
    + Portee : + {{sort.system.portee}} +
    +
    + Ingrédients : + {{sort.system.ingredients}} +
    + {{/if}} + +
    + Bonus/Malus + +
    + + {{#if cacheDifficulte}} +
    + Difficulté Cachée/Inconnue +
    + {{else}} +
    + Difficulté + +
    + {{/if}} + +
    + +
    \ No newline at end of file