appv2: correction des éditeurs ProseMirror et scrollbar sur les fiches d'acteur
- Migration des fiches acteur V2 : racine <form> → <section> (DocumentSheetV2 encapsule déjà dans <form>, élimine les formulaires imbriqués) - Ajout de submitOnChange: true sur la feuille de base acteur (nécessaire pour que les événements change des éditeurs déclenchent la mise à jour) - Ajout de toggled=true + wrapper <fieldset><div><label> sur tous les formInput (comportement identique aux fiches d'objet) - CSS : .window-content > section ajouté à côté de > form (évite la perte du flex layout et des scrollbar en passant de form à section) - Modèles acteur : passage de StringField à HTMLField pour les champs description/notes/biographie/notesmj (permet le rendu ProseMirror) - Ajout de systemFields dans le contexte _prepareContext()
This commit is contained in:
@@ -4895,7 +4895,8 @@ body {
|
||||
margin: 0;
|
||||
padding: 0.2rem;
|
||||
}
|
||||
.system-foundryvtt-reve-de-dragon .window-app.sheet .window-content {
|
||||
.system-foundryvtt-reve-de-dragon .window-app.sheet .window-content,
|
||||
.system-foundryvtt-reve-de-dragon .application.sheet .window-content {
|
||||
margin: 0.2rem;
|
||||
padding: 0;
|
||||
}
|
||||
@@ -4952,7 +4953,8 @@ body {
|
||||
margin-bottom: 0px;
|
||||
border: 0;
|
||||
}
|
||||
.system-foundryvtt-reve-de-dragon .window-app.sheet .window-content .sheet-header h1.charname input[type="text"] {
|
||||
.system-foundryvtt-reve-de-dragon .window-app.sheet .window-content .sheet-header h1.charname input[type="text"],
|
||||
.system-foundryvtt-reve-de-dragon .application.sheet .window-content .sheet-header h1.charname input[type="text"] {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
@@ -5051,6 +5053,12 @@ body {
|
||||
.system-foundryvtt-reve-de-dragon nav.sheet-tabs .item {
|
||||
position: relative;
|
||||
padding: 0.1rem 0.2rem;
|
||||
color: rgba(52, 52, 52, 0.95);
|
||||
}
|
||||
.system-foundryvtt-reve-de-dragon .sheet nav.sheet-tabs .item.active {
|
||||
color: #4a0404;
|
||||
text-decoration: underline;
|
||||
text-shadow: none;
|
||||
}
|
||||
.system-foundryvtt-reve-de-dragon nav.sheet-tabs .item:after {
|
||||
content: "";
|
||||
@@ -5490,7 +5498,7 @@ body {
|
||||
width: 100%;
|
||||
}
|
||||
.system-foundryvtt-reve-de-dragon .tab.hautreve {
|
||||
height: 200px;
|
||||
height: 100%;
|
||||
}
|
||||
.system-foundryvtt-reve-de-dragon .oeuvre-buttons {
|
||||
gap: 0.5rem;
|
||||
@@ -5663,8 +5671,17 @@ body {
|
||||
.system-foundryvtt-reve-de-dragon .rdd.sheet .window-content {
|
||||
overflow: hidden;
|
||||
}
|
||||
.system-foundryvtt-reve-de-dragon .rdd.sheet .window-content > form,
|
||||
.system-foundryvtt-reve-de-dragon .rdd.sheet .window-content > section {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
}
|
||||
.system-foundryvtt-reve-de-dragon .rdd.sheet .window-content .sheet-body {
|
||||
overflow-y: scroll;
|
||||
overflow-y: auto;
|
||||
scrollbar-width: auto;
|
||||
scrollbar-color: auto;
|
||||
}
|
||||
.system-foundryvtt-reve-de-dragon .rdd.sheet .window-content .sheet-body .tab {
|
||||
padding-bottom: 30px;
|
||||
@@ -5687,7 +5704,7 @@ body {
|
||||
justify-content: stretch;
|
||||
}
|
||||
.system-foundryvtt-reve-de-dragon .rdd.sheet .window-content .sheet-body .carac-list .caracteristique .carac-value {
|
||||
flex-basis: 15%;
|
||||
flex-basis: 2rem;
|
||||
flex-grow: 0;
|
||||
}
|
||||
.system-foundryvtt-reve-de-dragon .rdd.sheet .window-content .sheet-body .carac-list .caracteristique .carac-xp {
|
||||
@@ -5714,20 +5731,20 @@ body {
|
||||
.system-foundryvtt-reve-de-dragon .prosemirror menu {
|
||||
background-color: var(--color-background-chat-message);
|
||||
}
|
||||
.system-foundryvtt-reve-de-dragon .app.sheet fieldset :is(label, input) {
|
||||
.system-foundryvtt-reve-de-dragon :is(.app, .application).sheet fieldset :is(label, input) {
|
||||
font-family: CaslonAntique;
|
||||
text-align: justify;
|
||||
font-size: 1rem;
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
.system-foundryvtt-reve-de-dragon .app.sheet input.attribute-value {
|
||||
.system-foundryvtt-reve-de-dragon :is(.app, .application).sheet input.attribute-value {
|
||||
background-color: rgba(0, 0, 0, 0.05);
|
||||
border: 1px solid var(--color-border-light-tertiary);
|
||||
padding: 1px 3px;
|
||||
height: var(--form-field-height);
|
||||
border-radius: 3px;
|
||||
}
|
||||
.system-foundryvtt-reve-de-dragon .app.sheet div.form-group {
|
||||
.system-foundryvtt-reve-de-dragon :is(.app, .application).sheet div.form-group {
|
||||
clear: both;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
@@ -5735,20 +5752,25 @@ body {
|
||||
margin: 0.1rem 0;
|
||||
align-items: center;
|
||||
}
|
||||
.system-foundryvtt-reve-de-dragon .app.sheet .editor.prosemirror {
|
||||
height: fit-content;
|
||||
min-height: 6rem;
|
||||
.system-foundryvtt-reve-de-dragon :is(.app, .application).sheet div.form-group.large-editor {
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
}
|
||||
.system-foundryvtt-reve-de-dragon .app.sheet .editor.prosemirror .editor-container {
|
||||
min-height: 6rem;
|
||||
.system-foundryvtt-reve-de-dragon :is(.app, .application).sheet .editor.prosemirror {
|
||||
height: fit-content;
|
||||
min-height: 12rem;
|
||||
overflow: auto;
|
||||
}
|
||||
.system-foundryvtt-reve-de-dragon :is(.app, .application).sheet .editor.prosemirror .editor-container {
|
||||
min-height: 12rem;
|
||||
height: calc(100% - 3rem);
|
||||
margin: 0;
|
||||
flex: none;
|
||||
}
|
||||
.system-foundryvtt-reve-de-dragon .app.sheet.journal-entry-page .editor.prosemirror {
|
||||
.system-foundryvtt-reve-de-dragon :is(.app, .application).sheet.journal-entry-page .editor.prosemirror {
|
||||
height: 100%;
|
||||
}
|
||||
.system-foundryvtt-reve-de-dragon .app.sheet.journal-entry-page .editor.prosemirror .editor-container {
|
||||
.system-foundryvtt-reve-de-dragon :is(.app, .application).sheet.journal-entry-page .editor.prosemirror .editor-container {
|
||||
height: calc(100% - 6rem);
|
||||
}
|
||||
.system-foundryvtt-reve-de-dragon .large-editor {
|
||||
@@ -5798,10 +5820,12 @@ body {
|
||||
.system-foundryvtt-reve-de-dragon .foundryvtt-reve-de-dragon .tabs .item {
|
||||
line-height: 40px;
|
||||
font-weight: bold;
|
||||
color: rgba(52, 52, 52, 0.95);
|
||||
}
|
||||
.system-foundryvtt-reve-de-dragon .foundryvtt-reve-de-dragon .tabs .item.active {
|
||||
text-decoration: underline;
|
||||
text-shadow: none;
|
||||
color: #4a0404;
|
||||
}
|
||||
.system-foundryvtt-reve-de-dragon .foundryvtt-reve-de-dragon .item-list {
|
||||
list-style: none;
|
||||
@@ -5980,31 +6004,58 @@ body {
|
||||
background-color: var(--background-color-button);
|
||||
color: var(--rdd-color-text-primary);
|
||||
}
|
||||
.system-foundryvtt-reve-de-dragon .window-app .window-content {
|
||||
.system-foundryvtt-reve-de-dragon .window-app .window-content,
|
||||
.system-foundryvtt-reve-de-dragon .application .window-content {
|
||||
background: url(../assets/ui/bg_left.webp) no-repeat left top;
|
||||
color: var(--rdd-color-text-primary);
|
||||
}
|
||||
.system-foundryvtt-reve-de-dragon .window-app .window-content .sheet-header {
|
||||
.system-foundryvtt-reve-de-dragon .window-app .window-content .sheet-header,
|
||||
.system-foundryvtt-reve-de-dragon .application .window-content .sheet-header {
|
||||
background: #011d33 url(../assets/ui/bg_header.webp) no-repeat left top;
|
||||
}
|
||||
.system-foundryvtt-reve-de-dragon .window-app .window-content .sheet-header label,
|
||||
.system-foundryvtt-reve-de-dragon .application .window-content .sheet-header label,
|
||||
.system-foundryvtt-reve-de-dragon .window-app .window-content .sheet-header .hint,
|
||||
.system-foundryvtt-reve-de-dragon .application .window-content .sheet-header .hint,
|
||||
.system-foundryvtt-reve-de-dragon .window-app .window-content .sheet-header .permissions-list,
|
||||
.system-foundryvtt-reve-de-dragon .application .window-content .sheet-header .permissions-list,
|
||||
.system-foundryvtt-reve-de-dragon .window-app .window-content .sheet-header nav.tabs,
|
||||
.system-foundryvtt-reve-de-dragon .application .window-content .sheet-header nav.tabs,
|
||||
.system-foundryvtt-reve-de-dragon .window-app .window-content .sheet-header nav.tabs button,
|
||||
.system-foundryvtt-reve-de-dragon .application .window-content .sheet-header nav.tabs button,
|
||||
.system-foundryvtt-reve-de-dragon .window-app .window-content .sheet-header nav.tabs button .count,
|
||||
.system-foundryvtt-reve-de-dragon .application .window-content .sheet-header nav.tabs button .count,
|
||||
.system-foundryvtt-reve-de-dragon .window-app .window-content .sheet-header div,
|
||||
.system-foundryvtt-reve-de-dragon .window-app .window-content .sheet-header button {
|
||||
.system-foundryvtt-reve-de-dragon .application .window-content .sheet-header div,
|
||||
.system-foundryvtt-reve-de-dragon .window-app .window-content .sheet-header button,
|
||||
.system-foundryvtt-reve-de-dragon .application .window-content .sheet-header button {
|
||||
color: rgba(255, 255, 255, 0.9);
|
||||
}
|
||||
.system-foundryvtt-reve-de-dragon .window-app .window-content .sheet-header input {
|
||||
.system-foundryvtt-reve-de-dragon .window-app .window-content .sheet-header input,
|
||||
.system-foundryvtt-reve-de-dragon .application .window-content .sheet-header input {
|
||||
color: rgba(255, 255, 255, 0.9);
|
||||
border: 0 none;
|
||||
margin-bottom: 0.2rem;
|
||||
}
|
||||
.system-foundryvtt-reve-de-dragon .window-app .window-content .sheet-header input[type="checkbox"] {
|
||||
.system-foundryvtt-reve-de-dragon .window-app .window-content .sheet-header input[type="checkbox"],
|
||||
.system-foundryvtt-reve-de-dragon .application .window-content .sheet-header input[type="checkbox"] {
|
||||
color: rgba(255, 255, 255, 0.75);
|
||||
}
|
||||
.system-foundryvtt-reve-de-dragon :is(.window-app, .application).sheet .window-content :is(input[type="text"], input[type="number"], select) {
|
||||
background: var(--rdd-input-background);
|
||||
border: 1px solid var(--rdd-color-border-input);
|
||||
color: var(--rdd-color-text-primary);
|
||||
}
|
||||
.system-foundryvtt-reve-de-dragon :is(.window-app, .application).sheet .window-content .sheet-header :is(input[type="text"], input[type="number"], select) {
|
||||
background: transparent;
|
||||
color: rgba(255, 255, 255, 0.9);
|
||||
border: 0 none;
|
||||
}
|
||||
.system-foundryvtt-reve-de-dragon :is(.window-app, .application).sheet .window-content .sheet-body :is(input.carac-value, input.carac-xp, input.derivee-value, input.competence-value, input.competence-xp, input.competence-carac, input.competence-damage, input.competence-archetype) {
|
||||
height: 1.6rem;
|
||||
line-height: normal;
|
||||
padding: 0 0.2rem;
|
||||
}
|
||||
.system-foundryvtt-reve-de-dragon input[type="number"] {
|
||||
text-align: right;
|
||||
padding-right: 0.5rem;
|
||||
@@ -6239,43 +6290,43 @@ body {
|
||||
width: 100%;
|
||||
max-width: 90%;
|
||||
}
|
||||
.system-foundryvtt-reve-de-dragon .window-app.sheet .window-content :is(.tooltip, .tooltip-overflow):hover .tooltiptext {
|
||||
.system-foundryvtt-reve-de-dragon :is(.window-app, .application).sheet .window-content :is(.tooltip, .tooltip-overflow):hover .tooltiptext {
|
||||
top: 2rem;
|
||||
left: 2rem;
|
||||
margin: 0;
|
||||
padding: 0.25rem;
|
||||
}
|
||||
.system-foundryvtt-reve-de-dragon .window-app.sheet .window-content .carac-value,
|
||||
.system-foundryvtt-reve-de-dragon .window-app.sheet .window-content .competence-xp {
|
||||
.system-foundryvtt-reve-de-dragon :is(.window-app, .application).sheet .window-content .carac-value,
|
||||
.system-foundryvtt-reve-de-dragon :is(.window-app, .application).sheet .window-content .competence-xp {
|
||||
flex-grow: 0;
|
||||
margin: 0.05rem;
|
||||
flex-basis: 2rem;
|
||||
text-align: center;
|
||||
}
|
||||
.system-foundryvtt-reve-de-dragon .window-app.sheet .window-content .carac-value,
|
||||
.system-foundryvtt-reve-de-dragon .window-app.sheet .window-content .competence-value {
|
||||
.system-foundryvtt-reve-de-dragon :is(.window-app, .application).sheet .window-content .carac-value,
|
||||
.system-foundryvtt-reve-de-dragon :is(.window-app, .application).sheet .window-content .competence-value {
|
||||
flex-grow: 0;
|
||||
margin: 0.05rem;
|
||||
flex-basis: 2rem;
|
||||
text-align: center;
|
||||
}
|
||||
.system-foundryvtt-reve-de-dragon .window-app.sheet .window-content .carac-value,
|
||||
.system-foundryvtt-reve-de-dragon .window-app.sheet .window-content .competence-archetype {
|
||||
.system-foundryvtt-reve-de-dragon :is(.window-app, .application).sheet .window-content .carac-value,
|
||||
.system-foundryvtt-reve-de-dragon :is(.window-app, .application).sheet .window-content .competence-archetype {
|
||||
flex-grow: 0;
|
||||
margin: 0.05rem;
|
||||
flex-basis: 2rem;
|
||||
text-align: center;
|
||||
}
|
||||
.system-foundryvtt-reve-de-dragon .window-app.sheet .window-content .at-archetype {
|
||||
.system-foundryvtt-reve-de-dragon :is(.window-app, .application).sheet .window-content .at-archetype {
|
||||
border-left: 3px solid var(--color-archetype-atteint, #b8860b);
|
||||
}
|
||||
.system-foundryvtt-reve-de-dragon .window-app.sheet .window-content .archetype-check {
|
||||
.system-foundryvtt-reve-de-dragon :is(.window-app, .application).sheet .window-content .archetype-check {
|
||||
color: var(--color-archetype-atteint, #b8860b);
|
||||
font-size: 0.75rem;
|
||||
margin-left: 0.15rem;
|
||||
}
|
||||
.system-foundryvtt-reve-de-dragon .window-app.sheet .window-content .carac-value,
|
||||
.system-foundryvtt-reve-de-dragon .window-app.sheet .window-content .competence-xp-sort {
|
||||
.system-foundryvtt-reve-de-dragon :is(.window-app, .application).sheet .window-content .carac-value,
|
||||
.system-foundryvtt-reve-de-dragon :is(.window-app, .application).sheet .window-content .competence-xp-sort {
|
||||
flex-grow: 0;
|
||||
margin: 0.05rem;
|
||||
flex-basis: 2rem;
|
||||
|
||||
@@ -69,7 +69,8 @@
|
||||
margin: 0;
|
||||
padding: 0.2rem;
|
||||
}
|
||||
.window-app.sheet .window-content {
|
||||
.window-app.sheet .window-content,
|
||||
.application.sheet .window-content {
|
||||
margin: 0.2rem;
|
||||
padding: 0;
|
||||
}
|
||||
@@ -119,6 +120,11 @@
|
||||
}
|
||||
|
||||
.window-app.sheet
|
||||
.window-content
|
||||
.sheet-header
|
||||
h1.charname
|
||||
input[type="text"],
|
||||
.application.sheet
|
||||
.window-content
|
||||
.sheet-header
|
||||
h1.charname
|
||||
@@ -235,6 +241,13 @@
|
||||
nav.sheet-tabs .item {
|
||||
position: relative;
|
||||
padding: 0.1rem 0.2rem;
|
||||
color: rgba(52, 52, 52, 0.95);
|
||||
}
|
||||
|
||||
.sheet nav.sheet-tabs .item.active {
|
||||
color: #4a0404;
|
||||
text-decoration: underline;
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
nav.sheet-tabs .item:after {
|
||||
@@ -650,7 +663,7 @@
|
||||
|
||||
.btn-voir-tables-encaissement { width: 100%; }
|
||||
|
||||
.tab.hautreve { height: 200px; }
|
||||
.tab.hautreve { height: 100%; }
|
||||
|
||||
.oeuvre-buttons { gap: 0.5rem; flex-wrap: wrap; }
|
||||
|
||||
@@ -811,8 +824,16 @@
|
||||
.rdd.sheet {
|
||||
.window-content {
|
||||
overflow: hidden;
|
||||
> form, > section {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
}
|
||||
.sheet-body {
|
||||
overflow-y: scroll;
|
||||
overflow-y: auto;
|
||||
scrollbar-width: auto;
|
||||
scrollbar-color: auto;
|
||||
.tab {
|
||||
padding-bottom: 30px;
|
||||
}
|
||||
@@ -835,7 +856,7 @@
|
||||
justify-content: stretch;
|
||||
|
||||
.carac-value {
|
||||
flex-basis: 15%;
|
||||
flex-basis: 2rem;
|
||||
flex-grow: 0;
|
||||
}
|
||||
.carac-xp {
|
||||
@@ -872,7 +893,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
.app.sheet{
|
||||
:is(.app, .application).sheet{
|
||||
fieldset :is(label, input) {
|
||||
font-family: CaslonAntique;
|
||||
text-align: justify;
|
||||
@@ -897,19 +918,25 @@
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
div.form-group.large-editor {
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.editor.prosemirror {
|
||||
height: fit-content;
|
||||
min-height: 6rem;
|
||||
min-height: 12rem;
|
||||
overflow: auto;
|
||||
|
||||
.editor-container {
|
||||
min-height: 6rem;
|
||||
min-height: 12rem;
|
||||
height: calc(100% - 3rem);
|
||||
margin: 0;
|
||||
flex: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
.app.sheet.journal-entry-page .editor.prosemirror{
|
||||
:is(.app, .application).sheet.journal-entry-page .editor.prosemirror{
|
||||
height: 100%;
|
||||
.editor-container {
|
||||
height: calc(100% - 6rem);
|
||||
@@ -976,11 +1003,13 @@
|
||||
.foundryvtt-reve-de-dragon .tabs .item {
|
||||
line-height: 40px;
|
||||
font-weight: bold;
|
||||
color: rgba(52, 52, 52, 0.95);
|
||||
}
|
||||
|
||||
.foundryvtt-reve-de-dragon .tabs .item.active {
|
||||
text-decoration: underline;
|
||||
text-shadow: none;
|
||||
color: #4a0404;
|
||||
}
|
||||
|
||||
.foundryvtt-reve-de-dragon .item-list {
|
||||
@@ -1160,7 +1189,8 @@
|
||||
|
||||
/* ======================================== */
|
||||
/* Sheet */
|
||||
.window-app .window-content {
|
||||
.window-app .window-content,
|
||||
.application .window-content {
|
||||
background: url(../assets/ui/bg_left.webp) no-repeat left top;
|
||||
color: var(--rdd-color-text-primary);
|
||||
|
||||
@@ -1190,6 +1220,24 @@
|
||||
}
|
||||
}
|
||||
|
||||
:is(.window-app, .application).sheet .window-content :is(input[type="text"], input[type="number"], select) {
|
||||
background: var(--rdd-input-background);
|
||||
border: 1px solid var(--rdd-color-border-input);
|
||||
color: var(--rdd-color-text-primary);
|
||||
}
|
||||
:is(.window-app, .application).sheet .window-content .sheet-header :is(input[type="text"], input[type="number"], select) {
|
||||
background: transparent;
|
||||
color: rgba(255, 255, 255, 0.9);
|
||||
border: 0 none;
|
||||
}
|
||||
|
||||
:is(.window-app, .application).sheet .window-content .sheet-body
|
||||
:is(input.carac-value, input.carac-xp, input.derivee-value, input.competence-value, input.competence-xp, input.competence-carac, input.competence-damage, input.competence-archetype) {
|
||||
height: 1.6rem;
|
||||
line-height: normal;
|
||||
padding: 0 0.2rem;
|
||||
}
|
||||
|
||||
input[type="number"] {
|
||||
text-align: right;
|
||||
padding-right: 0.5rem;
|
||||
@@ -1442,7 +1490,7 @@
|
||||
max-width: 90%;
|
||||
}
|
||||
|
||||
.window-app.sheet
|
||||
:is(.window-app, .application).sheet
|
||||
.window-content
|
||||
:is(.tooltip, .tooltip-overflow):hover
|
||||
.tooltiptext {
|
||||
@@ -1452,37 +1500,37 @@
|
||||
padding: 0.25rem;
|
||||
}
|
||||
|
||||
.window-app.sheet .window-content .carac-value,
|
||||
.window-app.sheet .window-content .competence-xp {
|
||||
:is(.window-app, .application).sheet .window-content .carac-value,
|
||||
:is(.window-app, .application).sheet .window-content .competence-xp {
|
||||
flex-grow: 0;
|
||||
margin: 0.05rem;
|
||||
flex-basis: 2rem;
|
||||
text-align: center;
|
||||
}
|
||||
.window-app.sheet .window-content .carac-value,
|
||||
.window-app.sheet .window-content .competence-value {
|
||||
:is(.window-app, .application).sheet .window-content .carac-value,
|
||||
:is(.window-app, .application).sheet .window-content .competence-value {
|
||||
flex-grow: 0;
|
||||
margin: 0.05rem;
|
||||
flex-basis: 2rem;
|
||||
text-align: center;
|
||||
}
|
||||
.window-app.sheet .window-content .carac-value,
|
||||
.window-app.sheet .window-content .competence-archetype {
|
||||
:is(.window-app, .application).sheet .window-content .carac-value,
|
||||
:is(.window-app, .application).sheet .window-content .competence-archetype {
|
||||
flex-grow: 0;
|
||||
margin: 0.05rem;
|
||||
flex-basis: 2rem;
|
||||
text-align: center;
|
||||
}
|
||||
.window-app.sheet .window-content .at-archetype {
|
||||
:is(.window-app, .application).sheet .window-content .at-archetype {
|
||||
border-left: 3px solid var(--color-archetype-atteint, #b8860b);
|
||||
}
|
||||
.window-app.sheet .window-content .archetype-check {
|
||||
:is(.window-app, .application).sheet .window-content .archetype-check {
|
||||
color: var(--color-archetype-atteint, #b8860b);
|
||||
font-size: 0.75rem;
|
||||
margin-left: 0.15rem;
|
||||
}
|
||||
.window-app.sheet .window-content .carac-value,
|
||||
.window-app.sheet .window-content .competence-xp-sort {
|
||||
:is(.window-app, .application).sheet .window-content .carac-value,
|
||||
:is(.window-app, .application).sheet .window-content .competence-xp-sort {
|
||||
flex-grow: 0;
|
||||
margin: 0.05rem;
|
||||
flex-basis: 2rem;
|
||||
|
||||
@@ -0,0 +1,468 @@
|
||||
const { HandlebarsApplicationMixin } = foundry.applications.api
|
||||
|
||||
import { RdDUtility } from "../../rdd-utility.js"
|
||||
import { Misc } from "../../misc.js"
|
||||
import { DialogSplitItem } from "../../dialog-split-item.js"
|
||||
import { RdDSheetUtility } from "../../rdd-sheet-utility.js"
|
||||
import { Monnaie } from "../../item-monnaie.js"
|
||||
import { ITEM_TYPES } from "../../constants.js"
|
||||
import { RdDItem } from "../../item.js"
|
||||
import { RdDTextEditor } from "../../apps/rdd-text-roll-editor.js"
|
||||
import { ItemAction } from "../../item/item-actions.js"
|
||||
import { DialogVerifierIngredients } from "../../dialog-verifier-ingredients.js"
|
||||
import { DialogLancerRecette } from "../../dialog-lancer-recette.js"
|
||||
import { ChatUtility } from "../../chat-utility.js"
|
||||
import { RdDItemBlessure } from "../../item/blessure.js"
|
||||
import { Grammar } from "../../grammar.js"
|
||||
import { SYSTEM_RDD } from "../../constants.js"
|
||||
|
||||
export class RdDBaseActorSheetV2 extends HandlebarsApplicationMixin(foundry.applications.sheets.ActorSheetV2) {
|
||||
|
||||
get actor() { return this.document }
|
||||
|
||||
// Was this.options.* — custom state
|
||||
vueDetaillee = false
|
||||
triEquipement = "name"
|
||||
recherche = undefined
|
||||
|
||||
static TYPE = undefined
|
||||
|
||||
static DEFAULT_OPTIONS = {
|
||||
classes: ["rdd", "sheet", "actor"],
|
||||
position: { width: 640 },
|
||||
form: { submitOnChange: true, closeOnSubmit: false },
|
||||
window: { resizable: true, controls: [] },
|
||||
actions: {
|
||||
postToChat: RdDBaseActorSheetV2._onPostToChat,
|
||||
},
|
||||
}
|
||||
|
||||
//#region Registration
|
||||
|
||||
static register() {
|
||||
foundry.documents.collections.Actors.registerSheet(SYSTEM_RDD, this, {
|
||||
types: [this.TYPE],
|
||||
makeDefault: true,
|
||||
})
|
||||
}
|
||||
|
||||
static async registerAll(...sheetClasses) {
|
||||
const handlebars = []
|
||||
sheetClasses.forEach(sheetClass => {
|
||||
if (sheetClass.PARTS) {
|
||||
Object.values(sheetClass.PARTS).forEach(part => {
|
||||
if (part.template) handlebars.push(part.template)
|
||||
})
|
||||
}
|
||||
sheetClass.register()
|
||||
})
|
||||
await foundry.applications.handlebars.loadTemplates(Misc.distinct(handlebars))
|
||||
}
|
||||
|
||||
//#endregion
|
||||
|
||||
//#region Data
|
||||
|
||||
async _prepareContext() {
|
||||
Monnaie.validerMonnaies(this.actor)
|
||||
this.actor.computeEtatGeneral()
|
||||
|
||||
this._sheetOptions = foundry.utils.mergeObject(
|
||||
RdDSheetUtility.mergeDocumentRights({ ...this.options }, this.actor, this.isEditable),
|
||||
{ vueDetaillee: this.vueDetaillee, triEquipement: this.triEquipement, recherche: this.recherche },
|
||||
{ inplace: false }
|
||||
)
|
||||
const ctx = {
|
||||
title: this.title,
|
||||
id: this.actor.id,
|
||||
type: this.actor.type,
|
||||
img: this.actor.img,
|
||||
name: this.actor.name,
|
||||
system: this.actor.system,
|
||||
systemFields: this.actor.system.schema.fields,
|
||||
description: await RdDTextEditor.enrichHTML(this.actor.system.description, this.actor),
|
||||
notesmj: await RdDTextEditor.enrichHTML(this.actor.system.notesmj, this.actor),
|
||||
options: this._sheetOptions,
|
||||
effects: this.actor.effects,
|
||||
editable: this.isEditable,
|
||||
cssClass: this.isEditable ? "editable" : "locked",
|
||||
limited: this.actor.limited,
|
||||
owner: this.actor.isOwner,
|
||||
}
|
||||
|
||||
RdDUtility.filterItemsPerTypeForSheet(ctx, this.actor.itemTypes, this.triEquipement)
|
||||
ctx.calc = {
|
||||
fortune: Monnaie.toSolsDeniers(this.actor.getFortune()),
|
||||
prixTotalEquipement: this.actor.computePrixTotalEquipement(),
|
||||
encTotal: this.actor.getEncTotal(),
|
||||
}
|
||||
|
||||
this.objetVersConteneur = RdDUtility.buildArbreDeConteneurs(ctx.conteneurs, ctx.inventaires)
|
||||
this._appliquerRechercheObjets(ctx.conteneurs, ctx.inventaires)
|
||||
ctx.conteneurs = RdDUtility.conteneursRacine(ctx.conteneurs)
|
||||
ctx.competences.filter(it => it.type == ITEM_TYPES.competencecreature)
|
||||
.forEach(it => it.isdommages = it.isDommages())
|
||||
|
||||
return ctx
|
||||
}
|
||||
|
||||
_appliquerRechercheObjets(conteneurs, inventaires) {
|
||||
if (this.recherche?.text) {
|
||||
const recherche = this.recherche
|
||||
const allVisible = inventaires.filter(it => it.isNomTypeLike(recherche.text)).map(it => it.id)
|
||||
let addVisible = conteneurs.filter(it => it.isNomTypeLike(recherche.text)).map(it => it.id)
|
||||
do {
|
||||
allVisible.push(...addVisible)
|
||||
const parentsIds = conteneurs.filter(it => it.system.contenu.find(id => allVisible.includes(id))).map(it => it.id)
|
||||
addVisible = parentsIds.filter(id => !allVisible.includes(id))
|
||||
}
|
||||
while (addVisible.length > 0)
|
||||
inventaires.forEach(it => it.system.isHidden = !allVisible.includes(it.id))
|
||||
conteneurs.forEach(it => it.system.isHidden = !allVisible.includes(it.id))
|
||||
}
|
||||
else {
|
||||
inventaires.forEach(it => it.system.isHidden = false)
|
||||
conteneurs.forEach(it => it.system.isHidden = false)
|
||||
}
|
||||
}
|
||||
|
||||
//#endregion
|
||||
|
||||
//#region Rendering
|
||||
|
||||
async _renderFrame(options) {
|
||||
const frame = await super._renderFrame(options)
|
||||
return frame
|
||||
}
|
||||
|
||||
async _onRender(context, options) {
|
||||
await super._onRender(context, options)
|
||||
this.html = $(this.element)
|
||||
|
||||
const nav = this.element.querySelector(".sheet-tabs")
|
||||
if (nav) {
|
||||
const tab = this.tabGroups?.primary || nav.querySelector("[data-tab]")?.dataset.tab
|
||||
if (tab) this.changeTab(tab, "primary", { force: true })
|
||||
}
|
||||
|
||||
this.html.find(".actionItem").click(async event => await ItemAction.onActionItem(event, this.actor, this._sheetOptions))
|
||||
this.html.find(".item-edit").click(async event => await this._onItemEdit(event))
|
||||
this.html.find(".item-verify-ingredients").click(async event => await this._onVerifyIngredients(event))
|
||||
this.html.find(".item-lancer-recette").click(async event => await this._onLancerRecette(event))
|
||||
this.html.find(".conteneur-name a").click(async event => {
|
||||
RdDUtility.toggleAfficheContenu(this._getItemId(event))
|
||||
this.render({ force: true })
|
||||
})
|
||||
|
||||
this.html.find(".actor-montrer").click(async event => await this.actor.postActorToChat())
|
||||
|
||||
this.html.find(".recherche")
|
||||
.each((_index, field) => this._rechercheSelectArea(field))
|
||||
.keyup(async event => this._rechercherKeyup(event))
|
||||
.change(async event => this._rechercherKeyup(event))
|
||||
|
||||
this.html.find(".recherche").prop("disabled", false)
|
||||
|
||||
this.html.find(".item-list .item").dblclick(async event => {
|
||||
const item = this._getItem(event)
|
||||
if (item) item.sheet.render({ force: true })
|
||||
})
|
||||
|
||||
this.html.find(".tri-equipement").change(event => {
|
||||
this.triEquipement = event.currentTarget.value
|
||||
this.render({ force: true })
|
||||
})
|
||||
|
||||
if (!this.isEditable) return
|
||||
|
||||
this.html.find(".item-equip-armure").click(async event => await this.actor.equiperObjet(this._getItem(event)))
|
||||
this.html.find(".item-delete").click(async event => await RdDUtility.confirmActorItemDelete(this._getItem(event), this.actor))
|
||||
this.html.find(".item-quantite-plus").click(async event => await this.actor.itemQuantiteIncDec(this._getItemId(event), 1))
|
||||
this.html.find(".item-quantite-moins").click(async event => await this.actor.itemQuantiteIncDec(this._getItemId(event), -1))
|
||||
this.html.find(".item-quantite").change(async event => {
|
||||
const input = event.currentTarget
|
||||
const item = this.actor.items.get(input.dataset.itemId)
|
||||
if (item) {
|
||||
const newQty = Math.max(0, parseInt(input.value) || 0)
|
||||
await item.update({ "system.quantite": newQty })
|
||||
if (newQty === 0) this.render({ force: true })
|
||||
}
|
||||
})
|
||||
this.html.find(".item-quantite").on("contextmenu", async event => {
|
||||
event.preventDefault()
|
||||
const item = this._getItem(event)
|
||||
if (!item?.isInventaire()) return
|
||||
new Dialog({
|
||||
title: `Quantité — ${item.name}`,
|
||||
content: `<p>Réduire la quantité de :</p>
|
||||
<select class="qty-amount">
|
||||
<option value="1">1</option>
|
||||
<option value="5">5</option>
|
||||
<option value="10">10</option>
|
||||
<option value="all">Tout jeter</option>
|
||||
</select>`,
|
||||
buttons: {
|
||||
reduce: {
|
||||
icon: '<i class="fas fa-minus"></i>',
|
||||
label: "Retirer",
|
||||
callback: html => {
|
||||
const amount = html.find(".qty-amount").val()
|
||||
if (amount === "all") {
|
||||
item.delete()
|
||||
this.render({ force: true })
|
||||
} else {
|
||||
item.update({ "system.quantite": Math.max(0, item.system.quantite - parseInt(amount)) })
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
}).render({ force: true })
|
||||
})
|
||||
|
||||
this.html.find(".creer-un-objet").click(async event => await this._selectObjetTypeToCreate())
|
||||
this.html.find(".nettoyer-conteneurs").click(async event => await this.actor.nettoyerConteneurs())
|
||||
this.html.find(".quick-add-ration").click(async event => {
|
||||
const existante = this.actor.items.find(it => it.type === "nourritureboisson" && it.name === "Ration")
|
||||
if (existante) {
|
||||
await existante.update({ "system.quantite": Math.max(0, Number(existante.system.quantite) + 1) })
|
||||
} else {
|
||||
await this.actor.createEmbeddedDocuments("Item", [{
|
||||
name: "Ration", type: "nourritureboisson",
|
||||
img: "systems/foundryvtt-reve-de-dragon/icons/objets/provision_crue.webp",
|
||||
system: { sust: 1, encombrement: 0.1, quantite: 1, cout: 0.1, boisson: false },
|
||||
}], { renderSheet: false })
|
||||
}
|
||||
this.render({ force: true })
|
||||
})
|
||||
this.html.find(".quick-add-eau").click(async event => {
|
||||
const existante = this.actor.items.find(it => it.type === "nourritureboisson" && it.name === "Eau")
|
||||
if (existante) {
|
||||
await existante.update({ "system.quantite": Math.max(0, Number(existante.system.quantite) + 1) })
|
||||
} else {
|
||||
await this.actor.createEmbeddedDocuments("Item", [{
|
||||
name: "Eau", type: "nourritureboisson",
|
||||
img: "systems/foundryvtt-reve-de-dragon/icons/objets/outre.webp",
|
||||
system: { desaltere: 1, encombrement: 0.1, quantite: 1, cout: 0.05, boisson: true },
|
||||
}], { renderSheet: false })
|
||||
}
|
||||
this.render({ force: true })
|
||||
})
|
||||
|
||||
this.html.find(".vue-detaillee").click(async event => {
|
||||
this.vueDetaillee = !this.vueDetaillee
|
||||
this.render({ force: true })
|
||||
})
|
||||
|
||||
// Revel listeners (was base-actor-reve-sheet.js)
|
||||
this.html.find(".button-encaissement").click(async event => await this.actor.encaisser())
|
||||
this.html.find(".roll-carac").click(async event => {
|
||||
await this.actor.rollCarac(Grammar.toLowerCaseNoAccent(event.currentTarget.attributes["data-carac-name"].value))
|
||||
})
|
||||
this.html.find(".roll-competence").click(async event => await this.actor.rollCompetence(this._getItemId(event)))
|
||||
this.html.find(".endurance-plus").click(async event => await this.actor.santeIncDec("endurance", 1))
|
||||
this.html.find(".endurance-moins").click(async event => await this.actor.santeIncDec("endurance", -1))
|
||||
|
||||
if (game.user.isGM) {
|
||||
this.html.find(".button-remise-a-neuf").click(async event => await this.actor.remiseANeuf())
|
||||
this.html.find(".delete-active-effect").click(async event => await this.actor.removeEffect(this.html.find(event.currentTarget).parents(".active-effect").data("effect")))
|
||||
this.html.find(".enlever-tous-effets").click(async event => await this.actor.removeEffects())
|
||||
}
|
||||
this.html.find(".competence-add").click(async event =>
|
||||
await this.actor.createEmbeddedDocuments("Item", [{
|
||||
type: ITEM_TYPES.competencecreature,
|
||||
name: "Nouvelle competence",
|
||||
img: "systems/foundryvtt-reve-de-dragon/icons/compcreature-serres.webp",
|
||||
system: { carac_value: this.actor.getForce() },
|
||||
}], { renderSheet: true })
|
||||
)
|
||||
this.html.find(".roll-text").click(async event => await RdDTextEditor.rollText(event, this.actor))
|
||||
this.html.find(".chat-roll-text").click(async event => await RdDTextEditor.chatRollText(event))
|
||||
|
||||
if (this.vueDetaillee) {
|
||||
this.html.find(".carac-value").change(async event => {
|
||||
if (event.currentTarget.name.includes("carac.")) {
|
||||
const caracName = event.currentTarget.name.replace("carac.", "")
|
||||
await this.actor.updateCarac(caracName, parseInt(event.currentTarget.value))
|
||||
}
|
||||
})
|
||||
this.html.find(".competence-value").change(async event => {
|
||||
const compName = event.currentTarget.attributes.compname.value
|
||||
await this.actor.updateCompetence(compName, parseInt(event.currentTarget.value))
|
||||
})
|
||||
}
|
||||
|
||||
// Sang listeners (was base-actor-sang-sheet.js)
|
||||
this.html.find(".creer-blessure-legere").click(async event => await RdDItemBlessure.createBlessure(this.actor, 2))
|
||||
this.html.find(".creer-blessure-grave").click(async event => await RdDItemBlessure.createBlessure(this.actor, 4))
|
||||
this.html.find(".creer-blessure-critique").click(async event => await RdDItemBlessure.createBlessure(this.actor, 6))
|
||||
this.html.find(".subir-blessure-contusion").click(async event => await RdDItemBlessure.applyFullBlessure(this.actor, 0))
|
||||
this.html.find(".subir-blessure-legere").click(async event => await RdDItemBlessure.applyFullBlessure(this.actor, 2))
|
||||
this.html.find(".subir-blessure-grave").click(async event => await RdDItemBlessure.applyFullBlessure(this.actor, 4))
|
||||
this.html.find(".subir-blessure-critique").click(async event => await RdDItemBlessure.applyFullBlessure(this.actor, 6))
|
||||
this.html.find(".jet-vie").click(async event => await this.actor.jetDeVie())
|
||||
this.html.find(".jet-endurance").click(async event => await this._jetEndurance())
|
||||
this.html.find(".vie-plus").click(async event => await this.actor.santeIncDec("vie", 1))
|
||||
this.html.find(".vie-moins").click(async event => await this.actor.santeIncDec("vie", -1))
|
||||
}
|
||||
|
||||
async _jetEndurance() {
|
||||
const endurance = this.actor.getEnduranceActuelle()
|
||||
const result = await this.actor.jetEndurance(endurance)
|
||||
await ChatMessage.create({
|
||||
content: `Jet d'Endurance : ${result.jetEndurance} / ${endurance}
|
||||
<br>${this.actor.name} a ${result.sonne ? "échoué" : "réussi"} son Jet d'Endurance ${result.sonne ? "et devient Sonné" : ""}`,
|
||||
whisper: ChatUtility.getOwners(this.actor),
|
||||
})
|
||||
}
|
||||
|
||||
_rechercherKeyup(event) {
|
||||
const currentTarget = event.currentTarget
|
||||
const nouvelleRecherche = this._optionRecherche(currentTarget)
|
||||
if (this.recherche?.text != nouvelleRecherche?.text) {
|
||||
this.recherche = nouvelleRecherche
|
||||
if (this._timerRecherche) clearTimeout(this._timerRecherche)
|
||||
this._timerRecherche = setTimeout(() => {
|
||||
this._timerRecherche = undefined
|
||||
this.render({ force: true })
|
||||
}, 500)
|
||||
}
|
||||
}
|
||||
|
||||
_rechercheSelectArea(field) {
|
||||
if (this.recherche) {
|
||||
field.focus()
|
||||
field.setSelectionRange(this.recherche.start, this.recherche.end)
|
||||
}
|
||||
}
|
||||
|
||||
_optionRecherche(target) {
|
||||
if (!target.value?.length) return undefined
|
||||
return {
|
||||
text: target.value,
|
||||
start: target.selectionStart,
|
||||
end: target.selectionEnd,
|
||||
}
|
||||
}
|
||||
|
||||
//#endregion
|
||||
|
||||
//#region Drop
|
||||
|
||||
async _onDropItem(event, item) {
|
||||
const destItemId = this.html.find(event.target)?.closest(".item").attr("data-item-id")
|
||||
const previousItemIds = new Set(this.actor.items.keys())
|
||||
const dropParams = await RdDSheetUtility.prepareItemDropParameters(destItemId, this.actor, { uuid: item.uuid }, this.objetVersConteneur)
|
||||
if (dropParams) {
|
||||
const callSuper = await this.actor.processDropItem(dropParams)
|
||||
if (callSuper) {
|
||||
await super._onDropItem(event, item)
|
||||
}
|
||||
if (destItemId && dropParams.sourceActorId !== this.actor.id) {
|
||||
const container = this.actor.items.get(destItemId)
|
||||
if (container?.isConteneur()) {
|
||||
const dropped = [...this.actor.items].find(i => !previousItemIds.has(i.id))
|
||||
if (dropped && !this.actor.findConteneur(dropped)) {
|
||||
await this.actor.ajouterDansConteneur(dropped, container, () => {})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async _onDropActor(event, actor) {
|
||||
this.actor.addSubActeur(actor)
|
||||
await super._onDropActor(event, actor)
|
||||
}
|
||||
|
||||
//#endregion
|
||||
|
||||
//#region Helpers
|
||||
|
||||
_getItemId(event) {
|
||||
return RdDSheetUtility.getItemId(event)
|
||||
}
|
||||
|
||||
_getItem(event) {
|
||||
return RdDSheetUtility.getItem(event, this.actor)
|
||||
}
|
||||
|
||||
async _onItemEdit(event) {
|
||||
const item = this._getItem(event)
|
||||
if (item) item.sheet.render({ force: true })
|
||||
}
|
||||
|
||||
async _onVerifyIngredients(event) {
|
||||
event.preventDefault()
|
||||
const item = this._getItem(event)
|
||||
if (!item || item.type !== ITEM_TYPES.recettealchimique) return
|
||||
DialogVerifierIngredients.create(item, this.actor)
|
||||
}
|
||||
|
||||
async _onLancerRecette(event) {
|
||||
event.preventDefault()
|
||||
const item = this._getItem(event)
|
||||
if (!item || item.type !== ITEM_TYPES.recettealchimique) return
|
||||
const ingredients = Misc.safeJsonParse(item.system.ingredients, [])
|
||||
if (!ingredients.length) {
|
||||
ui.notifications.warn("Cette recette n'a pas d'ingrédients définis.")
|
||||
return
|
||||
}
|
||||
DialogLancerRecette.create(item, this.actor)
|
||||
}
|
||||
|
||||
//#endregion
|
||||
|
||||
//#region Actions
|
||||
|
||||
static async _onPostToChat(event, target) {
|
||||
await this.actor.postActorToChat()
|
||||
}
|
||||
|
||||
//#endregion
|
||||
|
||||
//#region Item operations
|
||||
|
||||
async _selectObjetTypeToCreate() {
|
||||
const types = this._getTypesInventaire().sort(Misc.ascending(type => Misc.typeName("Item", type)))
|
||||
let content = `<span class="generic-label">Selectionnez le type d'équipement</span><select class="item-type">`
|
||||
for (const typeName of types) {
|
||||
content += `<option value="${typeName}">${Misc.typeName("Item", typeName)}</option>`
|
||||
}
|
||||
content += "</select>"
|
||||
new Dialog({
|
||||
title: "Créer un équipement",
|
||||
content: content,
|
||||
buttons: {
|
||||
create: {
|
||||
icon: '<i class="fas fa-check"></i>',
|
||||
label: "Créer l'objet",
|
||||
callback: () => this.actor.createItem($(".item-type").val()),
|
||||
},
|
||||
},
|
||||
}).render({ force: true })
|
||||
}
|
||||
|
||||
_getTypesInventaire() {
|
||||
return RdDItem.getItemTypesInventaire()
|
||||
}
|
||||
|
||||
async splitItem(item) {
|
||||
const dialog = await DialogSplitItem.create(item, (it, split) => this._onSplitItem(it, split))
|
||||
dialog.render({ force: true })
|
||||
}
|
||||
|
||||
async _onSplitItem(item, split) {
|
||||
if (split >= 1 && split < item.system.quantite) {
|
||||
await item.diminuerQuantite(split)
|
||||
const splitItem = foundry.utils.deepClone(item)
|
||||
splitItem.system.quantite = split
|
||||
await this.actor.createEmbeddedDocuments("Item", [splitItem])
|
||||
}
|
||||
}
|
||||
|
||||
vendre(item) {
|
||||
item?.proposerVente(this.actor.getQuantiteDisponible(item))
|
||||
}
|
||||
|
||||
//#endregion
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
import { RdDBaseActorSheetV2 } from "./base-actor-sheet.mjs"
|
||||
import { RdDItem } from "../../item.js"
|
||||
import { ACTOR_TYPES } from "../../constants.js"
|
||||
|
||||
export class RdDCommerceSheetV2 extends RdDBaseActorSheetV2 {
|
||||
|
||||
static TYPE = ACTOR_TYPES.commerce
|
||||
|
||||
static DEFAULT_OPTIONS = Object.assign({}, RdDBaseActorSheetV2.DEFAULT_OPTIONS, {
|
||||
position: { width: 600, height: 720 },
|
||||
})
|
||||
|
||||
static PARTS = {
|
||||
form: { template: "systems/foundryvtt-reve-de-dragon/templates/actor/commerce-actor-sheet.hbs" },
|
||||
}
|
||||
|
||||
get title() {
|
||||
if (this.actor.token && this.actor.token !== this.actor.prototypeToken) {
|
||||
return this.actor.token.name
|
||||
}
|
||||
return super.title
|
||||
}
|
||||
|
||||
async _prepareContext() {
|
||||
const ctx = await super._prepareContext()
|
||||
if (this.actor.token && this.actor.token !== this.actor.prototypeToken) {
|
||||
foundry.utils.mergeObject(ctx, {
|
||||
title: this.actor.token.name,
|
||||
token: { img: this.actor.token.texture.src },
|
||||
}, { overwrite: true })
|
||||
}
|
||||
return ctx
|
||||
}
|
||||
|
||||
async _onRender(context, options) {
|
||||
await super._onRender(context, options)
|
||||
if (!this.isEditable) return
|
||||
|
||||
this.html.find("input.item-quantite").change(async event => {
|
||||
const newQuantite = Math.max(0, Number.parseInt(this.html.find(event.currentTarget).val()))
|
||||
await this._getItem(event)?.update({ "system.quantite": newQuantite })
|
||||
})
|
||||
this.html.find("input.item-cout").change(async event => {
|
||||
const newCout = Math.max(0, Number(this.html.find(event.currentTarget).val()))
|
||||
await this._getItem(event)?.update({ "system.cout": newCout })
|
||||
})
|
||||
}
|
||||
|
||||
_getTypesInventaire() {
|
||||
return RdDItem.getItemTypesInventaire("all")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
import { RdDBaseActorSheetV2 } from "./base-actor-sheet.mjs"
|
||||
import { ACTOR_TYPES } from "../../constants.js"
|
||||
|
||||
export class RdDCreatureSheetV2 extends RdDBaseActorSheetV2 {
|
||||
|
||||
static TYPE = ACTOR_TYPES.creature
|
||||
|
||||
static DEFAULT_OPTIONS = Object.assign({}, RdDBaseActorSheetV2.DEFAULT_OPTIONS, {
|
||||
position: { width: 640, height: 720 },
|
||||
})
|
||||
|
||||
static PARTS = {
|
||||
form: { template: "systems/foundryvtt-reve-de-dragon/templates/actor-creature-sheet.hbs" },
|
||||
}
|
||||
|
||||
async _onRender(context, options) {
|
||||
await super._onRender(context, options)
|
||||
if (!this.isEditable) return
|
||||
|
||||
this.html.find(".creature-carac").change(async event => {
|
||||
const compName = event.currentTarget.attributes.compname.value
|
||||
await this.actor.updateCreatureCompetence(compName, "carac_value", parseInt(event.target.value))
|
||||
})
|
||||
this.html.find(".creature-niveau").change(async event => {
|
||||
const compName = event.currentTarget.attributes.compname.value
|
||||
await this.actor.updateCreatureCompetence(compName, "niveau", parseInt(event.target.value))
|
||||
})
|
||||
this.html.find(".creature-dommages").change(async event => {
|
||||
const compName = event.currentTarget.attributes.compname.value
|
||||
await this.actor.updateCreatureCompetence(compName, "dommages", parseInt(event.target.value))
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
import { RdDBaseActorSheetV2 } from "./base-actor-sheet.mjs"
|
||||
import { RdDSheetUtility } from "../../rdd-sheet-utility.js"
|
||||
import { RdDUtility } from "../../rdd-utility.js"
|
||||
import { DialogSelect } from "../../dialog-select.js"
|
||||
import { ACTOR_TYPES } from "../../constants.js"
|
||||
|
||||
export class RdDActorEntiteSheetV2 extends RdDBaseActorSheetV2 {
|
||||
|
||||
static TYPE = ACTOR_TYPES.entite
|
||||
|
||||
static DEFAULT_OPTIONS = Object.assign({}, RdDBaseActorSheetV2.DEFAULT_OPTIONS, {
|
||||
position: { width: 640, height: 720 },
|
||||
})
|
||||
|
||||
static PARTS = {
|
||||
form: { template: "systems/foundryvtt-reve-de-dragon/templates/actor-entite-sheet.hbs" },
|
||||
}
|
||||
|
||||
async _prepareContext() {
|
||||
const ctx = await super._prepareContext()
|
||||
ctx.niveau = this.actor.getNiveau()
|
||||
const { niveau: _, ...caracRest } = ctx.system.carac
|
||||
ctx.system = { ...ctx.system, carac: caracRest }
|
||||
ctx.resonances = this.actor.system.sante.resonnance.actors
|
||||
.map(actorId => game.actors.get(actorId))
|
||||
.filter(actor => actor != undefined)
|
||||
.map(actor => ({ id: actor.id, name: actor.name, img: actor.img }))
|
||||
return ctx
|
||||
}
|
||||
|
||||
async _onRender(context, options) {
|
||||
await super._onRender(context, options)
|
||||
if (!this.isEditable) return
|
||||
|
||||
this.html.find(".creature-carac").change(async event => {
|
||||
const compName = event.currentTarget.attributes.compname.value
|
||||
await this.actor.updateCreatureCompetence(compName, "carac_value", parseInt(event.target.value))
|
||||
})
|
||||
this.html.find(".creature-dommages").change(async event => {
|
||||
const compName = event.currentTarget.attributes.compname.value
|
||||
await this.actor.updateCreatureCompetence(compName, "dommages", parseInt(event.target.value))
|
||||
})
|
||||
|
||||
this.html.find(".resonance-add").click(async event =>
|
||||
await DialogSelect.select({
|
||||
label: "Choisir un acteur à accorder",
|
||||
list: game.actors.filter(it => true),
|
||||
},
|
||||
it => this._resonanceAdd(it.id))
|
||||
)
|
||||
|
||||
this.html.find(".resonance-delete").click(async event => {
|
||||
const li = RdDSheetUtility.getEventElement(event)
|
||||
const actorId = li.data("actor-id")
|
||||
if (actorId) {
|
||||
const actorResonance = game.actors.get(actorId)
|
||||
RdDUtility.confirmSubActeurDelete(this, actorResonance, li, () => {
|
||||
this._resonanceDelete(actorId)
|
||||
RdDUtility.slideOnDelete(this, li)
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
async _onDropActor(event, dragData) {
|
||||
const dropActor = fromUuidSync(dragData.uuid)
|
||||
await this.actor.setEntiteReveAccordee(dropActor)
|
||||
await super._onDropActor(event, dragData)
|
||||
}
|
||||
|
||||
async _resonanceAdd(actorId) {
|
||||
const newResonances = [...this.actor.system.sante.resonnance.actors, actorId]
|
||||
await this.actor.update({ "system.sante.resonnance.actors": newResonances })
|
||||
}
|
||||
|
||||
async _resonanceDelete(actorId) {
|
||||
console.log("Delete : ", actorId)
|
||||
const newResonances = this.actor.system.sante.resonnance.actors.filter(id => id !== actorId)
|
||||
await this.actor.update({ "system.sante.resonnance.actors": newResonances }, { render: false })
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
import { RdDActorSheetV2 } from "./personnage-sheet.mjs"
|
||||
import { SYSTEM_RDD } from "../../constants.js"
|
||||
import { Misc } from "../../misc.js"
|
||||
import { EXPORT_CSV_SCRIPTARIUM, OptionsAvancees } from "../../settings/options-avancees.js"
|
||||
import { ExportScriptarium } from "../../actor/export-scriptarium/export-scriptarium.js"
|
||||
import { CATEGORIES_COMPETENCES_BASE, CATEGORIES_DRACONIC, Mapping } from "../../actor/export-scriptarium/mapping.js"
|
||||
|
||||
export class RdDActorExportSheetV2 extends RdDActorSheetV2 {
|
||||
|
||||
static TYPE = "personnage"
|
||||
|
||||
static DEFAULT_OPTIONS = Object.assign({}, RdDActorSheetV2.DEFAULT_OPTIONS, {
|
||||
position: { width: 550 },
|
||||
})
|
||||
|
||||
static PARTS = {
|
||||
form: { template: "systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/actor-encart-sheet.hbs" },
|
||||
}
|
||||
|
||||
showCompNiveauBase = false
|
||||
vueArchetype = false
|
||||
|
||||
static async init() {
|
||||
await foundry.applications.handlebars.loadTemplates([
|
||||
"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/arme.hbs",
|
||||
"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/arme-titre.hbs",
|
||||
"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/blessure.hbs",
|
||||
"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/blessures.hbs",
|
||||
"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/carac.hbs",
|
||||
"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/carac-compteur.hbs",
|
||||
"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/carac-derivee.hbs",
|
||||
"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/carac-derivee-compteur.hbs",
|
||||
"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/competences.hbs",
|
||||
"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/esquive.hbs",
|
||||
"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/fatigue.hbs",
|
||||
"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/protection.hbs",
|
||||
"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/sort.hbs",
|
||||
])
|
||||
}
|
||||
|
||||
static register() {
|
||||
foundry.documents.collections.Actors.registerSheet(SYSTEM_RDD, this, {
|
||||
types: ["personnage"],
|
||||
makeDefault: false,
|
||||
label: "Feuille simplifiée",
|
||||
})
|
||||
}
|
||||
|
||||
async _prepareContext() {
|
||||
const ctx = await super._prepareContext()
|
||||
ctx.context = Mapping.prepareContext(this.actor)
|
||||
ctx.attaques = this.actor.listActionsAttaque()
|
||||
ctx.export = this._getMappingValues(ctx.context, this.actor)
|
||||
ctx.competences = this._getCompetences(CATEGORIES_COMPETENCES_BASE)
|
||||
ctx.draconic = this._getCompetences(CATEGORIES_DRACONIC)
|
||||
const legeres = this.actor.countBlessures(it => it.isLegere())
|
||||
const graves = this.actor.countBlessures(it => it.isGrave())
|
||||
const critiques = this.actor.countBlessures(it => it.isCritique())
|
||||
ctx.etat = {
|
||||
surenc: this.actor.computeMalusSurEncombrement(),
|
||||
fatigue: {
|
||||
value: this.actor.getFatigueActuelle(),
|
||||
max: this.actor.getFatigueMax(),
|
||||
malus: this.actor.malusFatigue(),
|
||||
},
|
||||
blessures: legeres + graves + critiques,
|
||||
blessure: [legeres > 0, legeres > 1, legeres > 2, legeres > 3, legeres > 4, graves > 0, graves > 1, critiques > 0],
|
||||
}
|
||||
ctx.options.exportScriptarium = OptionsAvancees.isUsing(EXPORT_CSV_SCRIPTARIUM)
|
||||
return ctx
|
||||
}
|
||||
|
||||
_getMappingValues(context, actor) {
|
||||
return Object.fromEntries(Mapping.getMapping().map(it => [it.column, {
|
||||
colName: it.colName ?? it.column,
|
||||
column: it.column,
|
||||
rollClass: it.rollClass,
|
||||
value: String(it.getter(actor, context)),
|
||||
}]))
|
||||
}
|
||||
|
||||
_getCompetences(categories) {
|
||||
const competences = Mapping.getCompetencesCategorie(this.actor, categories)
|
||||
if (competences.length == 0) return ""
|
||||
const byCategories = Mapping.competencesByCategoriesByNiveau(competences, categories)
|
||||
const listByCategories = Object.values(byCategories)
|
||||
.map(it => it.competencesParNiveau)
|
||||
.map(byNiveau => {
|
||||
const niveaux = Object.keys(byNiveau).map(it => Number(it)).sort(Misc.ascending())
|
||||
if (niveaux.length == 0) return undefined
|
||||
const listCategorieByNiveau = niveaux.map(niveau => {
|
||||
const list = byNiveau[niveau].sort(Misc.ascending(it => it.name))
|
||||
return { niveau, list }
|
||||
})
|
||||
return Misc.concat(listCategorieByNiveau)
|
||||
}).filter(it => it != undefined)
|
||||
return Misc.concat(listByCategories)
|
||||
}
|
||||
|
||||
async _onRender(context, options) {
|
||||
await super._onRender(context, options)
|
||||
|
||||
this.html.find(".click-blessure-remove").click(async event =>
|
||||
await this.actor.supprimerBlessure({
|
||||
gravite: this.html.find(event.currentTarget).data("gravite"),
|
||||
})
|
||||
)
|
||||
this.html.find(".click-blessure-add").click(async event => {
|
||||
const blessure = this.actor.nouvelleBlessure(this.html.find(event.currentTarget).data("gravite"))
|
||||
await this.actor.createEmbeddedDocuments("Item", [blessure])
|
||||
})
|
||||
this.html.find(".button-export").click(async event => await
|
||||
ExportScriptarium.INSTANCE.exportActors([this.actor],
|
||||
`${this.actor.uuid}-${this.actor.name}`
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,403 @@
|
||||
import { RdDBaseActorSheetV2 } from "./base-actor-sheet.mjs"
|
||||
import { RdDUtility } from "../../rdd-utility.js"
|
||||
import { HtmlUtility } from "../../html-utility.js"
|
||||
import { RdDBonus } from "../../rdd-bonus.js"
|
||||
import { Misc } from "../../misc.js"
|
||||
import { RdDCombatManager } from "../../rdd-combat.js"
|
||||
import { CARACS, RdDCarac } from "../../rdd-carac.js"
|
||||
import { DialogSplitItem } from "../../dialog-split-item.js"
|
||||
import { ReglesOptionnelles } from "../../settings/regles-optionnelles.js"
|
||||
import { RdDSheetUtility } from "../../rdd-sheet-utility.js"
|
||||
import { MAINS_DIRECTRICES } from "../../actor.js"
|
||||
import { ACTOR_TYPES, ITEM_TYPES } from "../../constants.js"
|
||||
import { RdDItem } from "../../item.js"
|
||||
import { RdDItemCompetence } from "../../item-competence.js"
|
||||
import { RdDItemBlessure } from "../../item/blessure.js"
|
||||
import { RdDEmpoignade } from "../../rdd-empoignade.js"
|
||||
import { RdDCoeur } from "../../coeur/rdd-coeur.js"
|
||||
import { AppPersonnageAleatoire } from "../../actor/random/app-personnage-aleatoire.js"
|
||||
import { RdDTextEditor } from "../../apps/rdd-text-roll-editor.js"
|
||||
import { MORAL } from "../../moral/apprecier.mjs"
|
||||
import { RdDItemSort } from "../../item-sort.js"
|
||||
|
||||
export class RdDActorSheetV2 extends RdDBaseActorSheetV2 {
|
||||
|
||||
static TYPE = ACTOR_TYPES.personnage
|
||||
|
||||
static DEFAULT_OPTIONS = Object.assign({}, RdDBaseActorSheetV2.DEFAULT_OPTIONS, {
|
||||
position: { width: 640 },
|
||||
})
|
||||
|
||||
static PARTS = {
|
||||
form: { template: "systems/foundryvtt-reve-de-dragon/templates/actor-sheet.hbs" },
|
||||
}
|
||||
|
||||
showCompNiveauBase = false
|
||||
vueArchetype = false
|
||||
armesList = []
|
||||
|
||||
async _prepareContext() {
|
||||
const ctx = await super._prepareContext()
|
||||
ctx.options.showCompNiveauBase = this.showCompNiveauBase
|
||||
ctx.options.vueArchetype = this.vueArchetype
|
||||
ctx.biographie = await RdDTextEditor.enrichHTML(ctx.system.biographie, this.actor)
|
||||
ctx.notes = await RdDTextEditor.enrichHTML(ctx.system.notes, this.actor)
|
||||
|
||||
foundry.utils.mergeObject(ctx.calc, {
|
||||
surenc: this.actor.computeMalusSurEncombrement(),
|
||||
surprise: RdDBonus.find(this.actor.getSurprise(false)).label,
|
||||
blessures: this.actor.computeResumeBlessure(ctx.system.blessures),
|
||||
caracTotal: RdDCarac.computeTotal(ctx.system.carac, ctx.system.beaute),
|
||||
caracTotalXp: RdDCarac.computeTotalXp(ctx.system.carac, ctx.system.beaute),
|
||||
surEncombrementMessage: this.actor.isSurenc() ? "Sur-Encombrement!" : "",
|
||||
malusArmure: this.actor.getMalusArmure(),
|
||||
})
|
||||
|
||||
this._timerRecherche = undefined
|
||||
|
||||
if (ctx.type == ACTOR_TYPES.personnage) {
|
||||
ctx.options.mainsDirectrices = MAINS_DIRECTRICES
|
||||
ctx.byCateg = Misc.classify(ctx.competences, it => it.system.categorie)
|
||||
foundry.utils.mergeObject(ctx.calc, {
|
||||
comptageArchetype: RdDItemCompetence.computeResumeArchetype(ctx.competences),
|
||||
competenceXPTotal: RdDItemCompetence.computeTotalXP(ctx.competences),
|
||||
sortsXPTotal: RdDItemSort.computeTotalXP(this.actor.itemTypes[ITEM_TYPES.sort]),
|
||||
fatigue: RdDUtility.calculFatigueHtml(ctx.system.sante.fatigue.value, ctx.system.sante.endurance.max),
|
||||
})
|
||||
this._amendTacheCommunes(ctx)
|
||||
|
||||
ctx.competences.forEach(item => {
|
||||
item.system.isHidden = this.recherche
|
||||
? !item.isNomLike(this.recherche.text)
|
||||
: (this.showCompNiveauBase && RdDItemCompetence.isNiveauBase(item))
|
||||
RdDItemCompetence.levelUp(item, ctx.system.compteurs.experience.value)
|
||||
})
|
||||
|
||||
Object.values(ctx.system.carac).forEach(c => RdDCarac.levelUp(c))
|
||||
|
||||
ctx.esquives = this.actor.getCompetencesEsquive()
|
||||
ctx.combat = this.actor.listActionsAttaque()
|
||||
ctx.empoignades = this.actor.getEmpoignades()
|
||||
this.armesList = ctx.combat
|
||||
|
||||
ctx.ajustementsConditions = CONFIG.RDD.ajustementsConditions
|
||||
ctx.difficultesLibres = CONFIG.RDD.difficultesLibres
|
||||
|
||||
ctx.hautreve = {
|
||||
isDemiReve: this.actor.isDemiReve(),
|
||||
cacheTMR: this.actor.isTMRCache(),
|
||||
}
|
||||
|
||||
ctx.livresLus = ctx.livres.filter(l => l.system.estCopieLue)
|
||||
ctx.livres = ctx.livres.filter(l => !l.system.estCopieLue)
|
||||
|
||||
ctx.race = this.actor.itemTypes[ITEM_TYPES.race].find(it => true)
|
||||
ctx.subacteurs = {
|
||||
vehicules: this.actor.listeVehicules(),
|
||||
montures: this.actor.listeMontures(),
|
||||
suivants: this.actor.listeSuivants(),
|
||||
}
|
||||
|
||||
if (this.actor.getDraconics().find(it => it.system.niveau > -11) && !this.actor.isHautRevant()) {
|
||||
ui.notifications.error(`${this.actor.name} a des compétences draconiques, mais pas le don de Haut-Rêve!
|
||||
<br>Ajoutez-lui la tête "Don de Haut-Rêve" pour lui permettre d'utiliser ses compétences et d'accéder aux terres médianes du rêve`)
|
||||
}
|
||||
}
|
||||
else {
|
||||
console.error("Ouverture actor-sheet avec un acteur non personnage")
|
||||
}
|
||||
|
||||
return ctx
|
||||
}
|
||||
|
||||
_amendTacheCommunes(ctx) {
|
||||
ctx.taches.forEach(tache => {
|
||||
if (tache.isTacheCommune()) {
|
||||
const tacheCommune = tache.getTacheOuCommune()
|
||||
tache.system = foundry.utils.deepClone(tacheCommune.system)
|
||||
tache.system.tacheCommuneId = tache.system.tacheCommuneId
|
||||
}
|
||||
return tache
|
||||
})
|
||||
}
|
||||
|
||||
async _onRender(context, options) {
|
||||
await super._onRender(context, options)
|
||||
if (!this.isEditable) return
|
||||
|
||||
HtmlUtility.showControlWhen(this.html.find(".appliquerFatigue"), ReglesOptionnelles.isUsing("appliquer-fatigue"))
|
||||
|
||||
this.html.find(".subacteur-open").click(async event => {
|
||||
const subActorId = RdDSheetUtility.getEventItemData(event, "subactor-id")
|
||||
this._openSubActeur(subActorId)
|
||||
})
|
||||
|
||||
this.html.find(".show-hide-competences").click(async event => {
|
||||
this.showCompNiveauBase = !this.showCompNiveauBase
|
||||
this.render({ force: true })
|
||||
})
|
||||
|
||||
this.html.find(".button-tmr-visu").click(async event => await this.actor.displayTMR("visu"))
|
||||
|
||||
this.html.find(".sheet-possession-attack").click(async event => {
|
||||
const poss = RdDSheetUtility.getItem(event, this.actor)
|
||||
await this.actor.conjurerPossession(poss)
|
||||
})
|
||||
|
||||
this.html.find(".subacteur-coeur-toggle a").click(async event => {
|
||||
const subActorId = RdDSheetUtility.getEventItemData(event, "subactor-id")
|
||||
const coeurNombre = $(event.currentTarget).data("numero-coeur")
|
||||
await RdDCoeur.toggleSubActeurCoeur(this.actor.id, subActorId, coeurNombre)
|
||||
})
|
||||
this.html.find(".subacteur-tendre-moment").click(async event => {
|
||||
const subActorId = RdDSheetUtility.getEventItemData(event, "subactor-id")
|
||||
await RdDCoeur.startSubActeurTendreMoment(this.actor.id, subActorId)
|
||||
})
|
||||
this.html.find(".subacteur-delete").click(async event => {
|
||||
const li = RdDSheetUtility.getEventElement(event)
|
||||
const subActorId = li.data("subactor-id")
|
||||
this._deleteSubActeur(subActorId, li)
|
||||
})
|
||||
|
||||
this.html.find("input.derivee-value[name='system.compteurs.stress.value']").change(async event =>
|
||||
await this.actor.updateCompteurValue("stress", parseInt(event.target.value))
|
||||
)
|
||||
this.html.find("input.derivee-value[name='system.compteurs.experience.value']").change(async event =>
|
||||
await this.actor.updateCompteurValue("experience", parseInt(event.target.value))
|
||||
)
|
||||
|
||||
this.html.find(".creer-tache").click(async event => await this._createEmptyTache())
|
||||
this.html.find(".creer-une-oeuvre").click(async event => await this._selectTypeOeuvreToCreate())
|
||||
this.html.find(".creer-tache-blessure-legere").click(async event => await RdDItemBlessure.createTacheSoinBlessure(this.actor, 2))
|
||||
this.html.find(".creer-tache-blessure-grave").click(async event => await RdDItemBlessure.createTacheSoinBlessure(this.actor, 4))
|
||||
this.html.find(".creer-tache-blessure-critique").click(async event => await RdDItemBlessure.createTacheSoinBlessure(this.actor, 6))
|
||||
|
||||
this.html.find(".blessure-premierssoins-done").change(async event => {
|
||||
await this._getBlessure(event)?.setSoinsBlessure({ premierssoins: { done: event.currentTarget.checked } })
|
||||
})
|
||||
this.html.find(".blessure-soinscomplets-done").change(async event => {
|
||||
await this._getBlessure(event)?.setSoinsBlessure({ soinscomplets: { done: event.currentTarget.checked } })
|
||||
})
|
||||
this.html.find(".blessure-premierssoins-bonus").change(async event => {
|
||||
await this._getBlessure(event)?.setSoinsBlessure({ premierssoins: { bonus: Number(event.currentTarget.value) } })
|
||||
})
|
||||
this.html.find(".blessure-soinscomplets-bonus").change(async event => {
|
||||
await this._getBlessure(event)?.setSoinsBlessure({ soinscomplets: { bonus: Number(event.currentTarget.value) } })
|
||||
})
|
||||
|
||||
this.html.find(".roll-chance-actuelle").click(async event => await this.actor.rollCarac(CARACS.CHANCE_ACTUELLE))
|
||||
this.html.find(".button-appel-chance").click(async event => await this.actor.rollAppelChance())
|
||||
|
||||
this.html.find('[name="jet-astrologie"]').click(async event => await this.actor.astrologieNombresAstraux())
|
||||
this.html.find(".action-tache").click(async event => await this.actor.rollTache(RdDSheetUtility.getItemId(event)))
|
||||
this.html.find(".meditation-label a").click(async event => await this.actor.rollMeditation(RdDSheetUtility.getItemId(event)))
|
||||
|
||||
this.html.find(".action-chant").click(async event => await this.actor.rollChant(RdDSheetUtility.getItemId(event)))
|
||||
this.html.find(".action-danse").click(async event => await this.actor.rollDanse(RdDSheetUtility.getItemId(event)))
|
||||
this.html.find(".action-musique").click(async event => await this.actor.rollMusique(RdDSheetUtility.getItemId(event)))
|
||||
this.html.find(".action-oeuvre").click(async event => await this.actor.rollOeuvre(RdDSheetUtility.getItemId(event)))
|
||||
this.html.find(".action-jeu").click(async event => await this.actor.rollJeu(RdDSheetUtility.getItemId(event)))
|
||||
this.html.find(".action-recettecuisine").click(async event => await this.actor.rollRecetteCuisine(RdDSheetUtility.getItemId(event)))
|
||||
|
||||
this.html.find(".description-aleatoire").click(async event => new AppPersonnageAleatoire(this.actor).render({ force: true }))
|
||||
|
||||
this.html.find(".gerer-herbes").click(async event => {
|
||||
const { DialogGererHerbes } = await import("../../dialog-gerer-herbes.js")
|
||||
DialogGererHerbes.create(this.actor)
|
||||
})
|
||||
this.html.find(".gerer-ingredients").click(async event => {
|
||||
const { DialogGererIngredients } = await import("../../dialog-gerer-ingredients.js")
|
||||
DialogGererIngredients.create(this.actor)
|
||||
})
|
||||
this.html.find(".gerer-deniers").click(async event => {
|
||||
const { DialogGererDeniers } = await import("../../dialog-gerer-deniers.js")
|
||||
DialogGererDeniers.create(this.actor)
|
||||
})
|
||||
this.html.find(".gerer-potions").click(async event => {
|
||||
const { DialogGererPotions } = await import("../../dialog-gerer-potions.js")
|
||||
DialogGererPotions.create(this.actor)
|
||||
})
|
||||
|
||||
if (game.user.isGM) {
|
||||
this.html.find(".experiencelog-delete").click(async event => {
|
||||
const li = this.html.find(event.currentTarget)?.parents(".experiencelog")
|
||||
const key = Number(li.data("key") ?? -1)
|
||||
await this.actor.deleteExperienceLog(key, 1)
|
||||
})
|
||||
this.html.find(".experiencelog-delete-previous").click(async event => {
|
||||
const li = this.html.find(event.currentTarget)?.parents(".experiencelog")
|
||||
const key = Number(li.data("key") ?? -1)
|
||||
await this.actor.deleteExperienceLog(0, key + 1)
|
||||
})
|
||||
this.html.find(".forcer-tmr-aleatoire").click(async event => await this.actor.reinsertionAleatoire("Action MJ"))
|
||||
this.html.find(".don-de-haut-reve").click(async event => await this.actor.addDonDeHautReve())
|
||||
this.html.find(".afficher-tmr").click(async event => await this.actor.changeTMRVisible())
|
||||
}
|
||||
|
||||
this.html.find(".roll-reve-actuel").click(async event => await this.actor.rollReveActuel({ resistance: false }))
|
||||
this.html.find(".button-reve-resistance").click(async event => await this.actor.rollReveResistance())
|
||||
this.html.find(".action-empoignade").click(async event => await RdDEmpoignade.onAttaqueEmpoignadeFromItem(RdDSheetUtility.getItem(event, this.actor)))
|
||||
|
||||
this.html.find(".roll-arme").click(async event => {
|
||||
const action = this._getActionCombat(event)
|
||||
await this.actor.rollArme(action.arme, action.main)
|
||||
})
|
||||
|
||||
this.html.find(".roll-init-arme").click(async event => {
|
||||
const combatant = game.combat.combatants.find(c => c.actor.id == this.actor.id)
|
||||
if (combatant) {
|
||||
RdDCombatManager.rollInitiativeAction(combatant.id, this._getActionCombat(event))
|
||||
}
|
||||
else {
|
||||
ui.notifications.info("Impossible de lancer l'initiative sans être dans un combat.")
|
||||
}
|
||||
})
|
||||
|
||||
this.html.find(".button-tmr").click(async event => await this.actor.displayTMR("normal"))
|
||||
this.html.find(".button-tmr-rapide").click(async event => await this.actor.displayTMR("rapide"))
|
||||
|
||||
this.html.find(".button-repos").click(async event => await this.actor.repos())
|
||||
|
||||
this.html.find(".carac-xp-augmenter").click(async event =>
|
||||
await this.actor.updateCaracXPAuto(event.currentTarget.name.replace("augmenter.", ""))
|
||||
)
|
||||
this.html.find(".competence-xp-augmenter").click(async event =>
|
||||
await this.actor.updateCompetenceXPAuto(RdDSheetUtility.getItemId(event))
|
||||
)
|
||||
this.html.find(".competence-stress-augmenter").click(async event => {
|
||||
await this.actor.updateCompetenceStress(RdDSheetUtility.getItemId(event))
|
||||
this.render({ force: true })
|
||||
})
|
||||
|
||||
if (this.vueDetaillee) {
|
||||
this.html.find("input.carac-xp").change(async event => {
|
||||
const caracName = event.currentTarget.name.replace(".xp", "").replace("system.carac.", "")
|
||||
await this.actor.updateCaracXP(caracName, parseInt(event.target.value))
|
||||
})
|
||||
this.html.find("input.competence-xp").change(async event => {
|
||||
const compName = event.currentTarget.attributes.compname.value
|
||||
await this.actor.updateCompetenceXP(compName, parseInt(event.target.value))
|
||||
})
|
||||
this.html.find("input.competence-xp-sort").change(async event => {
|
||||
const compName = event.currentTarget.attributes.compname.value
|
||||
await this.actor.updateCompetenceXPSort(compName, parseInt(event.target.value))
|
||||
})
|
||||
|
||||
this.html.find(".toggle-archetype").click(async event => {
|
||||
this.vueArchetype = !this.vueArchetype
|
||||
this.render({ force: true })
|
||||
})
|
||||
this.html.find(".competence-archetype").change(async event => {
|
||||
const compName = event.currentTarget.attributes.compname.value
|
||||
await this.actor.updateCompetenceArchetype(compName, parseInt(event.target.value))
|
||||
})
|
||||
this.html.find(".nouvelle-incarnation").click(async event => await this.actor.nouvelleIncarnation())
|
||||
this.html.find(".repartition-archetype-aleatoire").click(async event => await this.actor.repartitionArchetypeAleatoire())
|
||||
}
|
||||
|
||||
this.html.find(".pointsreve-value").change(async event =>
|
||||
await this.actor.update({ "system.reve.reve.value": event.currentTarget.value })
|
||||
)
|
||||
this.html.find(".seuil-reve-value").change(async event =>
|
||||
await this.actor.update({ "system.reve.seuil.value": event.currentTarget.value })
|
||||
)
|
||||
|
||||
this.html.find(".stress-test").click(async event => await this.actor.transformerStress())
|
||||
this.html.find(".moral-malheureux").click(async event => await this.actor.jetDeMoral(MORAL.MALHEUREUX))
|
||||
this.html.find(".moral-neutre").click(async event => await this.actor.jetDeMoral(MORAL.NEUTRE))
|
||||
this.html.find(".moral-heureux").click(async event => await this.actor.jetDeMoral(MORAL.HEUREUX))
|
||||
this.html.find(".button-ethylisme").click(async event => await this.actor.jetEthylisme())
|
||||
this.html.find(".btn-sust-externe").click(async event => await this.actor.mangerExterne())
|
||||
this.html.find(".btn-sust-rations").click(async event => await this.actor.mangerRations())
|
||||
|
||||
this.html.find(".ptreve-actuel-plus").click(async event => await this.actor.reveActuelIncDec(1))
|
||||
this.html.find(".ptreve-actuel-moins").click(async event => await this.actor.reveActuelIncDec(-1))
|
||||
this.html.find(".chance-actuelle-plus").click(async event => await this.actor.chanceActuelleIncDec(1))
|
||||
this.html.find(".chance-actuelle-moins").click(async event => await this.actor.chanceActuelleIncDec(-1))
|
||||
this.html.find(".fatigue-plus").click(async event => await this.actor.santeIncDec("fatigue", 1))
|
||||
this.html.find(".fatigue-moins").click(async event => await this.actor.santeIncDec("fatigue", -1))
|
||||
}
|
||||
|
||||
_getBlessure(event) {
|
||||
const blessureId = this.html.find(event.currentTarget).parents(".item-blessure").data("item-id")
|
||||
return this.actor.getItem(blessureId, "blessure")
|
||||
}
|
||||
|
||||
isCompetenceAffichable(competence) {
|
||||
return !this.showCompNiveauBase || !RdDItemCompetence.isNiveauBase(competence)
|
||||
}
|
||||
|
||||
async _onDropActor(event, dragData) {
|
||||
const dropActor = fromUuidSync(dragData.uuid)
|
||||
this.actor.addSubActeur(dropActor)
|
||||
await super._onDrop(event, dragData)
|
||||
}
|
||||
|
||||
_openSubActeur(actorId) {
|
||||
game.actors.get(actorId)?.sheet.render({ force: true })
|
||||
}
|
||||
|
||||
_deleteSubActeur(actorId, li) {
|
||||
if (actorId) {
|
||||
const subActor = game.actors.get(actorId)
|
||||
RdDUtility.confirmSubActeurDelete(this, subActor, li, () => {
|
||||
console.log("Delete : ", subActor.id)
|
||||
this.actor.deleteSubActeur(subActor.id)
|
||||
RdDUtility.slideOnDelete(this, li)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
async _selectTypeOeuvreToCreate() {
|
||||
const types = RdDItem.getTypesOeuvres()
|
||||
let content = `<span class="generic-label">Selectionnez le type d'oeuvre</span><select class="item-type">`
|
||||
for (const typeName of types) {
|
||||
content += `<option value="${typeName}">${Misc.typeName("Item", typeName)}</option>`
|
||||
}
|
||||
content += "</select>"
|
||||
new Dialog({
|
||||
title: "Créer une oeuvre",
|
||||
content: content,
|
||||
buttons: {
|
||||
create: {
|
||||
icon: '<i class="fas fa-check"></i>',
|
||||
label: "Créer l'oeuvre",
|
||||
callback: () => this.actor.createItem($(".item-type").val()),
|
||||
},
|
||||
},
|
||||
}).render({ force: true })
|
||||
}
|
||||
|
||||
async _createEmptyTache() {
|
||||
await this.actor.createItem(ITEM_TYPES.tache, "Nouvelle tache")
|
||||
}
|
||||
|
||||
_getActionCombat(event) {
|
||||
const li = this.html.find(event.currentTarget)?.parents(".item")
|
||||
const armeName = li.data("arme-name")
|
||||
const compName = li.data("competence-name")
|
||||
const arme = this.armesList.find(a => a.arme.name == armeName && a.comp.name == compName)
|
||||
if (!arme) {
|
||||
return {
|
||||
name: armeName,
|
||||
arme: { name: armeName },
|
||||
comp: { name: compName },
|
||||
}
|
||||
}
|
||||
return arme
|
||||
}
|
||||
|
||||
async splitItem(item) {
|
||||
const dialog = await DialogSplitItem.create(item, (it, split) => this._onSplitItem(it, split))
|
||||
dialog.render({ force: true })
|
||||
}
|
||||
|
||||
async _onSplitItem(item, split) {
|
||||
if (split >= 1 && split < item.system.quantite) {
|
||||
await item.diminuerQuantite(split)
|
||||
const splitItem = foundry.utils.deepClone(item)
|
||||
splitItem.system.quantite = split
|
||||
await this.actor.createEmbeddedDocuments("Item", [splitItem])
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
import { RdDBaseActorSheetV2 } from "./base-actor-sheet.mjs"
|
||||
import { ACTOR_TYPES } from "../../constants.js"
|
||||
|
||||
export class RdDActorVehiculeSheetV2 extends RdDBaseActorSheetV2 {
|
||||
|
||||
static TYPE = ACTOR_TYPES.vehicule
|
||||
|
||||
static DEFAULT_OPTIONS = Object.assign({}, RdDBaseActorSheetV2.DEFAULT_OPTIONS, {
|
||||
position: { width: 640, height: 720 },
|
||||
})
|
||||
|
||||
static PARTS = {
|
||||
form: { template: "systems/foundryvtt-reve-de-dragon/templates/actor-vehicule-sheet.hbs" },
|
||||
}
|
||||
|
||||
async _prepareContext() {
|
||||
const ctx = await super._prepareContext()
|
||||
ctx.editable = this.isEditable
|
||||
ctx.cssClass = this.isEditable ? "editable" : "locked"
|
||||
ctx.effects = this.actor.effects
|
||||
ctx.limited = this.actor.limited
|
||||
ctx.owner = this.actor.isOwner
|
||||
this.recherche = undefined
|
||||
return ctx
|
||||
}
|
||||
|
||||
async _onRender(context, options) {
|
||||
await super._onRender(context, options)
|
||||
if (!this.isEditable) return
|
||||
|
||||
this.html.find(".resistance-moins").click(async event => await this.actor.vehicleIncDec("resistance", -1))
|
||||
this.html.find(".resistance-plus").click(async event => await this.actor.vehicleIncDec("resistance", 1))
|
||||
this.html.find(".structure-moins").click(async event => await this.actor.vehicleIncDec("structure", -1))
|
||||
this.html.find(".structure-plus").click(async event => await this.actor.vehicleIncDec("structure", 1))
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
const fields = foundry.data.fields;
|
||||
|
||||
export function statField(initialValue = 0, label = "", derivee = false) {
|
||||
return new fields.SchemaField({
|
||||
type: new fields.StringField({ initial: "number" }),
|
||||
value: new fields.NumberField({ initial: initialValue, integer: true }),
|
||||
label: new fields.StringField({ initial: label }),
|
||||
xp: new fields.NumberField({ initial: 0, integer: true }),
|
||||
derivee: new fields.BooleanField({ initial: derivee }),
|
||||
});
|
||||
}
|
||||
|
||||
export function santeField(initialValue = 0, initialMax = 0, label = "", derivee = false) {
|
||||
return new fields.SchemaField({
|
||||
type: new fields.StringField({ initial: "number" }),
|
||||
value: new fields.NumberField({ initial: initialValue, integer: true }),
|
||||
max: new fields.NumberField({ initial: initialMax, integer: true }),
|
||||
label: new fields.StringField({ initial: label }),
|
||||
derivee: new fields.BooleanField({ initial: derivee }),
|
||||
});
|
||||
}
|
||||
|
||||
export function attributField(initialValue = 0, label = "", derivee = false, isString = false) {
|
||||
if (isString) {
|
||||
return new fields.SchemaField({
|
||||
type: new fields.StringField({ initial: "string" }),
|
||||
value: new fields.StringField({ initial: String(initialValue) }),
|
||||
label: new fields.StringField({ initial: label }),
|
||||
derivee: new fields.BooleanField({ initial: derivee }),
|
||||
});
|
||||
}
|
||||
return new fields.SchemaField({
|
||||
type: new fields.StringField({ initial: "number" }),
|
||||
value: new fields.NumberField({ initial: initialValue, integer: false }),
|
||||
label: new fields.StringField({ initial: label }),
|
||||
derivee: new fields.BooleanField({ initial: derivee }),
|
||||
});
|
||||
}
|
||||
|
||||
export function compteurField(initialValue = 0, label = "", isInput = false) {
|
||||
return new fields.SchemaField({
|
||||
value: new fields.NumberField({ initial: initialValue, integer: true }),
|
||||
label: new fields.StringField({ initial: label }),
|
||||
...(isInput ? { isInput: new fields.BooleanField({ initial: true }) } : {}),
|
||||
});
|
||||
}
|
||||
|
||||
export function compteurMaxField(initialValue = 0, initialMax = 0, label = "") {
|
||||
return new fields.SchemaField({
|
||||
value: new fields.NumberField({ initial: initialValue, integer: true }),
|
||||
max: new fields.NumberField({ initial: initialMax, integer: true }),
|
||||
label: new fields.StringField({ initial: label }),
|
||||
isInput: new fields.BooleanField({ initial: true }),
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
import { STRING, HTMLSTRING } from "../common/field-types.mjs";
|
||||
|
||||
const fields = foundry.data.fields;
|
||||
|
||||
export default class RdDModelCommerce extends foundry.abstract.TypeDataModel {
|
||||
static defineSchema() {
|
||||
return {
|
||||
pourcentage: new fields.NumberField({ initial: 100, integer: true }),
|
||||
illimite: new fields.BooleanField({ initial: false }),
|
||||
description: new fields.HTMLField({ initial: "", ...HTMLSTRING }),
|
||||
race: new fields.StringField({ initial: "", ...STRING }),
|
||||
notesmj: new fields.HTMLField({ initial: "", ...HTMLSTRING }),
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
import { STRING, HTMLSTRING } from "../common/field-types.mjs";
|
||||
import { statField, santeField, attributField, compteurField } from "./_actor-helpers.mjs";
|
||||
|
||||
const fields = foundry.data.fields;
|
||||
|
||||
export default class RdDModelCreature extends foundry.abstract.TypeDataModel {
|
||||
static defineSchema() {
|
||||
return {
|
||||
carac: new fields.SchemaField({
|
||||
taille: statField(10, "Taille"),
|
||||
constitution: statField(10, "Constitution"),
|
||||
force: statField(10, "Force"),
|
||||
perception: statField(10, "Perception"),
|
||||
volonte: statField(10, "Volonté"),
|
||||
reve: statField(10, "Rêve"),
|
||||
}),
|
||||
sante: new fields.SchemaField({
|
||||
vie: santeField(10, 10, "Vie"),
|
||||
endurance: santeField(10, 10, "Endurance"),
|
||||
bonusPotion: new fields.NumberField({ initial: 0, integer: true }),
|
||||
}),
|
||||
attributs: new fields.SchemaField({
|
||||
plusdom: attributField(0, "+dom", true),
|
||||
encombrement: attributField(0.0, "Encombrement", true),
|
||||
vitesse: attributField(0, "Vitesse", false, true),
|
||||
protection: attributField(0, "Protection naturelle", false),
|
||||
}),
|
||||
compteurs: new fields.SchemaField({
|
||||
etat: compteurField(0, "Etat général"),
|
||||
}),
|
||||
description: new fields.HTMLField({ initial: "", ...HTMLSTRING }),
|
||||
race: new fields.StringField({ initial: "", ...STRING }),
|
||||
notesmj: new fields.HTMLField({ initial: "", ...HTMLSTRING }),
|
||||
};
|
||||
}
|
||||
|
||||
prepareDerivedData() {
|
||||
const actor = this.parent;
|
||||
|
||||
this.sante.vie.max = Math.ceil((actor.getTaille() + actor.getConstitution()) / 2);
|
||||
this.sante.vie.value = Math.min(this.sante.vie.value, this.sante.vie.max);
|
||||
this.attributs.encombrement.value = actor.getEncombrementMax();
|
||||
|
||||
this.attributs.plusdom.value = actor.getBonusDegat();
|
||||
this.sante.endurance.max = actor.getEnduranceMax();
|
||||
this.sante.endurance.value = Math.min(this.sante.endurance.value, this.sante.endurance.max);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
import { STRING, HTMLSTRING } from "../common/field-types.mjs";
|
||||
import { statField, santeField, attributField, compteurField } from "./_actor-helpers.mjs";
|
||||
|
||||
const fields = foundry.data.fields;
|
||||
|
||||
export default class RdDModelEntite extends foundry.abstract.TypeDataModel {
|
||||
static defineSchema() {
|
||||
return {
|
||||
definition: new fields.SchemaField({
|
||||
categorieentite: new fields.StringField({ initial: "", ...STRING }),
|
||||
typeentite: new fields.StringField({ initial: "", ...STRING }),
|
||||
}),
|
||||
carac: new fields.SchemaField({
|
||||
taille: statField(10, "Taille"),
|
||||
reve: statField(10, "Rêve"),
|
||||
niveau: statField(0, "Niveau"),
|
||||
}),
|
||||
sante: new fields.SchemaField({
|
||||
endurance: santeField(10, 10, "Endurance"),
|
||||
resonnance: new fields.SchemaField({
|
||||
actors: new fields.ArrayField(
|
||||
new fields.StringField({ initial: "", ...STRING }),
|
||||
{ initial: [], required: true, nullable: false }
|
||||
),
|
||||
}),
|
||||
}),
|
||||
compteurs: new fields.SchemaField({
|
||||
etat: compteurField(0, "Etat général"),
|
||||
}),
|
||||
attributs: new fields.SchemaField({
|
||||
plusdom: attributField(0, "+dom", true),
|
||||
vitesse: attributField(0, "Vitesse", false, true),
|
||||
protection: attributField(0, "Protection naturelle", false),
|
||||
}),
|
||||
description: new fields.HTMLField({ initial: "", ...HTMLSTRING }),
|
||||
race: new fields.StringField({ initial: "", ...STRING }),
|
||||
notesmj: new fields.HTMLField({ initial: "", ...HTMLSTRING }),
|
||||
};
|
||||
}
|
||||
|
||||
prepareDerivedData() {
|
||||
const actor = this.parent;
|
||||
|
||||
this.attributs.plusdom.value = actor.getBonusDegat();
|
||||
this.sante.endurance.max = actor.getEnduranceMax();
|
||||
this.sante.endurance.value = Math.min(this.sante.endurance.value, this.sante.endurance.max);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,188 @@
|
||||
import { STRING, HTMLSTRING, MODEL_ARRAY } from "../common/field-types.mjs";
|
||||
import { statField, santeField, attributField, compteurField, compteurMaxField } from "./_actor-helpers.mjs";
|
||||
import { ITEM_TYPES } from "../constants.js";
|
||||
import { RdDItemRace } from "../item/race.js";
|
||||
import { RdDCarac } from "../rdd-carac.js";
|
||||
import RdDItemTete from "../documents/tete.mjs";
|
||||
import { Misc } from "../misc.js";
|
||||
|
||||
const fields = foundry.data.fields;
|
||||
|
||||
export default class RdDModelPersonnage extends foundry.abstract.TypeDataModel {
|
||||
static defineSchema() {
|
||||
return {
|
||||
carac: new fields.SchemaField({
|
||||
taille: statField(10, "Taille"),
|
||||
apparence: statField(10, "Apparence"),
|
||||
constitution: statField(10, "Constitution"),
|
||||
force: statField(10, "Force"),
|
||||
agilite: statField(10, "Agilité"),
|
||||
dexterite: statField(10, "Dextérité"),
|
||||
vue: statField(10, "Vue"),
|
||||
ouie: statField(10, "Ouïe"),
|
||||
odoratgout: statField(10, "Odorat-Goût"),
|
||||
volonte: statField(10, "Volonté"),
|
||||
intellect: statField(10, "Intellect"),
|
||||
empathie: statField(10, "Empathie"),
|
||||
reve: statField(10, "Rêve"),
|
||||
chance: statField(10, "Chance"),
|
||||
melee: statField(10, "Mêlée", true),
|
||||
tir: statField(10, "Tir", true),
|
||||
lancer: statField(10, "Lancer", true),
|
||||
derobee: statField(10, "Dérobée", true),
|
||||
}),
|
||||
sante: new fields.SchemaField({
|
||||
vie: santeField(10, 10, "Vie", true),
|
||||
endurance: santeField(10, 10, "Endurance", true),
|
||||
fatigue: santeField(0, 0, "Fatigue", true),
|
||||
bonusPotion: new fields.NumberField({ initial: 0, integer: true }),
|
||||
}),
|
||||
attributs: new fields.SchemaField({
|
||||
sconst: attributField(0, "S. Const", true),
|
||||
sust: attributField(0, "Sustentation", true),
|
||||
plusdom: attributField(0, "+dom", true),
|
||||
encombrement: attributField(0.0, "Encombrement", true),
|
||||
protection: attributField(0, "Protection naturelle", false),
|
||||
hautrevant: attributField("", "Haut rêvant", true, true),
|
||||
}),
|
||||
reve: new fields.SchemaField({
|
||||
reve: new fields.SchemaField({
|
||||
value: new fields.NumberField({ initial: 10, integer: true }),
|
||||
max: new fields.NumberField({ initial: 0, integer: true }),
|
||||
label: new fields.StringField({ initial: "Points de Rêve actuels" }),
|
||||
thanatosused: new fields.BooleanField({ initial: false }),
|
||||
}),
|
||||
seuil: new fields.SchemaField({
|
||||
value: new fields.NumberField({ initial: 10, integer: true }),
|
||||
max: new fields.NumberField({ initial: 0, integer: true }),
|
||||
label: new fields.StringField({ initial: "Seuil de Rêve" }),
|
||||
}),
|
||||
tmrpos: new fields.SchemaField({
|
||||
coord: new fields.StringField({ initial: "A1" }),
|
||||
label: new fields.StringField({ initial: "Position TMR" }),
|
||||
cache: new fields.BooleanField({ initial: false }),
|
||||
}),
|
||||
refoulement: new fields.SchemaField({
|
||||
value: new fields.NumberField({ initial: 0, integer: true }),
|
||||
label: new fields.StringField({ initial: "Points de Refoulement" }),
|
||||
}),
|
||||
}),
|
||||
compteurs: new fields.SchemaField({
|
||||
sust: compteurField(0, "Sust.", true),
|
||||
eau: compteurField(0, "Eau", true),
|
||||
moral: compteurField(0, "Moral", true),
|
||||
exaltation: compteurField(0, "Exaltation", true),
|
||||
dissolution: compteurField(0, "Dissolution", true),
|
||||
chance: compteurMaxField(0, 0, "Chance actuelle"),
|
||||
destinee: compteurField(0, "Destinée", true),
|
||||
voyage: compteurField(0, "Voyage", true),
|
||||
etat: compteurField(0, "Etat général"),
|
||||
ethylisme: new fields.SchemaField({
|
||||
value: new fields.NumberField({ initial: 1, integer: true }),
|
||||
label: new fields.StringField({ initial: "Ethylisme" }),
|
||||
isInput: new fields.BooleanField({ initial: true }),
|
||||
nb_doses: new fields.NumberField({ initial: 0, integer: true }),
|
||||
jet_moral: new fields.BooleanField({ initial: false }),
|
||||
}),
|
||||
stress: new fields.SchemaField({
|
||||
value: new fields.NumberField({ initial: 0, integer: true }),
|
||||
label: new fields.StringField({ initial: "Stress" }),
|
||||
isStress: new fields.BooleanField({ initial: true }),
|
||||
isInput: new fields.BooleanField({ initial: true }),
|
||||
}),
|
||||
experience: compteurField(0, "Experience", true),
|
||||
bonmoments: new fields.ArrayField(
|
||||
new fields.SchemaField({
|
||||
value: new fields.NumberField({ initial: 0, integer: true }),
|
||||
label: new fields.StringField({ initial: "" }),
|
||||
}),
|
||||
{ ...MODEL_ARRAY }
|
||||
),
|
||||
}),
|
||||
sommeil: new fields.SchemaField({
|
||||
nouveaujour: new fields.BooleanField({ initial: false }),
|
||||
date: new fields.SchemaField({
|
||||
indexDate: new fields.NumberField({ initial: -1, integer: true }),
|
||||
indexMinute: new fields.NumberField({ initial: 0, integer: true }),
|
||||
}),
|
||||
insomnie: new fields.BooleanField({ initial: false }),
|
||||
moral: new fields.StringField({ initial: "" }),
|
||||
heures: new fields.NumberField({ initial: 0, integer: true }),
|
||||
}),
|
||||
metier: new fields.StringField({ initial: "", ...STRING }),
|
||||
biographie: new fields.HTMLField({ initial: "", ...HTMLSTRING }),
|
||||
notes: new fields.HTMLField({ initial: "", ...HTMLSTRING }),
|
||||
notesmj: new fields.HTMLField({ initial: "", ...HTMLSTRING }),
|
||||
race: new fields.StringField({ initial: "", ...STRING }),
|
||||
yeux: new fields.StringField({ initial: "", ...STRING }),
|
||||
cheveux: new fields.StringField({ initial: "", ...STRING }),
|
||||
taille: new fields.StringField({ initial: "", ...STRING }),
|
||||
poids: new fields.StringField({ initial: "", ...STRING }),
|
||||
heure: new fields.StringField({ initial: "", ...STRING }),
|
||||
sexe: new fields.StringField({ initial: "", ...STRING }),
|
||||
age: new fields.NumberField({ initial: 0, integer: true }),
|
||||
beaute: new fields.NumberField({ initial: 10, integer: true }),
|
||||
main: new fields.StringField({ initial: "droitier", ...STRING }),
|
||||
experiencelog: new fields.ArrayField(
|
||||
new fields.SchemaField({
|
||||
date: new fields.NumberField({ initial: 0, integer: true }),
|
||||
topic: new fields.StringField({ initial: "", ...STRING }),
|
||||
from: new fields.NumberField({ initial: 0, integer: true }),
|
||||
to: new fields.NumberField({ initial: 0, integer: true }),
|
||||
description: new fields.StringField({ initial: "", ...STRING }),
|
||||
}),
|
||||
{ ...MODEL_ARRAY }
|
||||
),
|
||||
subacteurs: new fields.SchemaField({
|
||||
suivants: new fields.ArrayField(
|
||||
new fields.SchemaField({
|
||||
id: new fields.StringField({ initial: "", ...STRING }),
|
||||
}),
|
||||
{ ...MODEL_ARRAY }
|
||||
),
|
||||
montures: new fields.ArrayField(
|
||||
new fields.SchemaField({
|
||||
id: new fields.StringField({ initial: "", ...STRING }),
|
||||
}),
|
||||
{ ...MODEL_ARRAY }
|
||||
),
|
||||
vehicules: new fields.ArrayField(
|
||||
new fields.SchemaField({
|
||||
id: new fields.StringField({ initial: "", ...STRING }),
|
||||
}),
|
||||
{ ...MODEL_ARRAY }
|
||||
),
|
||||
}),
|
||||
description: new fields.HTMLField({ initial: "", ...HTMLSTRING }),
|
||||
};
|
||||
}
|
||||
|
||||
prepareDerivedData() {
|
||||
const actor = this.parent;
|
||||
|
||||
RdDItemRace.applyRacialLimits(actor);
|
||||
|
||||
this.carac.melee.value = Math.floor((actor.getForce() + Misc.toInt(this.carac.agilite.value)) / 2);
|
||||
this.carac.tir.value = Math.floor((Misc.toInt(this.carac.vue.value) + Misc.toInt(this.carac.dexterite.value)) / 2);
|
||||
this.carac.lancer.value = Math.floor((Misc.toInt(this.carac.tir.value) + Misc.toInt(this.carac.force.value)) / 2);
|
||||
this.carac.derobee.value = Math.floor(((21 - Misc.toInt(this.carac.taille.value)) + Misc.toInt(this.carac.agilite.value)) / 2);
|
||||
|
||||
this.sante.vie.max = Math.ceil((actor.getTaille() + actor.getConstitution()) / 2);
|
||||
this.sante.vie.value = Math.min(this.sante.vie.value, this.sante.vie.max);
|
||||
this.attributs.encombrement.value = actor.getEncombrementMax();
|
||||
|
||||
this.attributs.plusdom.value = actor.getBonusDegat();
|
||||
this.sante.endurance.max = actor.getEnduranceMax();
|
||||
this.sante.endurance.value = Math.min(this.sante.endurance.value, this.sante.endurance.max);
|
||||
|
||||
this.attributs.sconst.value = RdDCarac.calculSConst(actor.getConstitution());
|
||||
this.attributs.sust.value = RdDCarac.getCaracDerivee(actor.getTaille()).sust;
|
||||
this.sante.fatigue.max = actor.getFatigueMax();
|
||||
this.sante.fatigue.value = Math.min(this.sante.fatigue.value, this.sante.fatigue.max);
|
||||
this.reve.reve.max = 3 * actor.getReve();
|
||||
this.compteurs.chance.max = actor.getChance();
|
||||
this.attributs.hautrevant.value = actor.itemTypes[ITEM_TYPES.tete]?.find(it => RdDItemTete.isDonDeHautReve(it))
|
||||
? "Haut rêvant"
|
||||
: "";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
import { STRING, HTMLSTRING, INTEGER } from "../common/field-types.mjs";
|
||||
|
||||
const fields = foundry.data.fields;
|
||||
|
||||
export default class RdDModelVehicule extends foundry.abstract.TypeDataModel {
|
||||
static defineSchema() {
|
||||
return {
|
||||
categorie: new fields.StringField({ initial: "", ...STRING }),
|
||||
vitesse: new fields.StringField({ initial: "", ...STRING }),
|
||||
bonus: new fields.StringField({ initial: "", ...STRING }),
|
||||
manoeuvrabilite: new fields.StringField({ initial: "", ...STRING }),
|
||||
equipage: new fields.NumberField({ initial: 0, ...INTEGER }),
|
||||
capacite_encombrement: new fields.NumberField({ initial: 0.0, integer: false }),
|
||||
etat: new fields.SchemaField({
|
||||
resistance: new fields.SchemaField({
|
||||
type: new fields.StringField({ initial: "number" }),
|
||||
max: new fields.NumberField({ initial: 20, integer: true }),
|
||||
value: new fields.NumberField({ initial: 20, integer: true }),
|
||||
label: new fields.StringField({ initial: "Résistance" }),
|
||||
derivee: new fields.BooleanField({ initial: false }),
|
||||
}),
|
||||
structure: new fields.SchemaField({
|
||||
type: new fields.StringField({ initial: "number" }),
|
||||
max: new fields.NumberField({ initial: 10, integer: true }),
|
||||
value: new fields.NumberField({ initial: 10, integer: true }),
|
||||
label: new fields.StringField({ initial: "Structure" }),
|
||||
derivee: new fields.BooleanField({ initial: false }),
|
||||
}),
|
||||
}),
|
||||
description: new fields.HTMLField({ initial: "", ...HTMLSTRING }),
|
||||
race: new fields.StringField({ initial: "", ...STRING }),
|
||||
notesmj: new fields.HTMLField({ initial: "", ...HTMLSTRING }),
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
<form class="{{cssClass}}" autocomplete="off">
|
||||
<section class="{{cssClass}}" autocomplete="off">
|
||||
|
||||
{{!-- Sheet Header --}}
|
||||
<header class="sheet-header">
|
||||
@@ -34,9 +34,9 @@
|
||||
|
||||
{{!-- Sheet Tab Navigation --}}
|
||||
<nav class="sheet-tabs tabs" data-group="primary">
|
||||
<a class="item" data-tab="carac">Caractéristiques</a>
|
||||
<a class="item" data-tab="items">Équipement</a>
|
||||
<a class="item" data-tab="description">Description</a>
|
||||
<a class="item" data-action="tab" data-group="primary" data-tab="carac">Caractéristiques</a>
|
||||
<a class="item" data-action="tab" data-group="primary" data-tab="items">Équipement</a>
|
||||
<a class="item" data-action="tab" data-group="primary" data-tab="description">Description</a>
|
||||
</nav>
|
||||
|
||||
{{!-- Sheet Body --}}
|
||||
@@ -70,13 +70,16 @@
|
||||
|
||||
{{!-- Description Tab --}}
|
||||
<div class="tab description" data-group="primary" data-tab="description">
|
||||
<div class="form-group large-editor">
|
||||
{{editor description target="system.description" button=true owner=options.isOwner editable=options.editable engine="prosemirror"}}
|
||||
</div>
|
||||
<h3>Description</h3>
|
||||
<fieldset>
|
||||
<div>
|
||||
{{formInput systemFields.description enriched=description value=system.description name="system.description" toggled=true}}
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/editor-notes-mj.hbs"}}
|
||||
|
||||
</div>
|
||||
|
||||
</section>
|
||||
</form>
|
||||
</section>
|
||||
</section>
|
||||
@@ -1,4 +1,4 @@
|
||||
<form class="{{cssClass}}" autocomplete="off">
|
||||
<section class="{{cssClass}}" autocomplete="off">
|
||||
|
||||
{{!-- Sheet Header --}}
|
||||
<header class="sheet-header">
|
||||
@@ -48,12 +48,15 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group large-editor">
|
||||
{{editor description target="system.description" button=true owner=options.isOwner editable=options.editable engine="prosemirror"}}
|
||||
</div>
|
||||
<h3>Description</h3>
|
||||
<fieldset>
|
||||
<div>
|
||||
{{formInput systemFields.description enriched=description value=system.description name="system.description" toggled=true}}
|
||||
</div>
|
||||
</fieldset>
|
||||
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/editor-notes-mj.hbs"}}
|
||||
|
||||
</div>
|
||||
|
||||
</section>
|
||||
</form>
|
||||
</section>
|
||||
+21
-18
@@ -1,4 +1,4 @@
|
||||
<form class="{{cssClass}}" autocomplete="off">
|
||||
<section class="{{cssClass}}" autocomplete="off">
|
||||
{{>'systems/foundryvtt-reve-de-dragon/templates/scripts/autocomplete-script.hbs'}}
|
||||
|
||||
{{!-- Sheet Header --}}
|
||||
@@ -22,14 +22,14 @@
|
||||
{{!-- Sheet Tab Navigation --}}
|
||||
<nav class="sheet-tabs tabs" data-group="primary">
|
||||
{{#if options.isObserver}}
|
||||
<a class="item" data-tab="carac" data-tooltip="Caractéristiques">Carac.</a>
|
||||
<a class="item" data-tab="competences" data-tooltip="Caractéristiques">Compétences</a>
|
||||
<a class="item" data-tab="combat" data-tooltip="Combat et santé">Combat</a>
|
||||
<a class="item" data-tab="connaissances" data-tooltip="Savoirs et tâches">Savoirs&Taches</a>
|
||||
<a class="item" data-tab="hautreve" data-tooltip="Haut-rêve">Haut-Rêve</a>
|
||||
<a class="item" data-action="tab" data-group="primary" data-tab="carac" data-tooltip="Caractéristiques">Carac.</a>
|
||||
<a class="item" data-action="tab" data-group="primary" data-tab="competences" data-tooltip="Caractéristiques">Compétences</a>
|
||||
<a class="item" data-action="tab" data-group="primary" data-tab="combat" data-tooltip="Combat et santé">Combat</a>
|
||||
<a class="item" data-action="tab" data-group="primary" data-tab="connaissances" data-tooltip="Savoirs et tâches">Savoirs&Taches</a>
|
||||
<a class="item" data-action="tab" data-group="primary" data-tab="hautreve" data-tooltip="Haut-rêve">Haut-Rêve</a>
|
||||
{{/if}}
|
||||
<a class="item" data-tab="items" data-tooltip="Liste d'équipement">Équipement</a>
|
||||
<a class="item" data-tab="description" data-tooltip="Description et compagnons">Description</a>
|
||||
<a class="item" data-action="tab" data-group="primary" data-tab="items" data-tooltip="Liste d'équipement">Équipement</a>
|
||||
<a class="item" data-action="tab" data-group="primary" data-tab="description" data-tooltip="Description et compagnons">Description</a>
|
||||
</nav>
|
||||
|
||||
{{!-- Sheet Body --}}
|
||||
@@ -152,9 +152,9 @@
|
||||
{{> "systems/foundryvtt-reve-de-dragon/templates/actor/liens-animaux.hbs"}}
|
||||
{{> "systems/foundryvtt-reve-de-dragon/templates/actor/liens-vehicules.hbs"}}
|
||||
</div>
|
||||
|
||||
|
||||
{{!-- Biography Tab --}}
|
||||
<div class="tab biography" data-group="primary" data-tab="description">
|
||||
<div class="tab biography" data-group="primary" data-tab="description">
|
||||
<article class="flexrow">
|
||||
<ul class="item-list alterne-list">
|
||||
<li class="flexrow list-item" data-tooltip="Glisser une Race depuis un compendium pour changer">
|
||||
@@ -225,18 +225,21 @@
|
||||
|
||||
<article class="flexcol">
|
||||
<h3>Biographie</h3>
|
||||
<div class="form-group large-editor">
|
||||
{{editor biographie target="system.biographie" button=true owner=options.isOwner editable=options.editable engine="prosemirror"}}
|
||||
</div>
|
||||
<fieldset>
|
||||
<div>
|
||||
{{formInput systemFields.biographie enriched=biographie value=system.biographie name="system.biographie" toggled=true}}
|
||||
</div>
|
||||
</fieldset>
|
||||
<h3>Notes</h3>
|
||||
<div class="form-group large-editor">
|
||||
{{editor notes target="system.notes" button=true owner=options.isOwner editable=options.editable engine="prosemirror"}}
|
||||
</div>
|
||||
<fieldset>
|
||||
<div>
|
||||
{{formInput systemFields.notes enriched=notes value=system.notes name="system.notes" toggled=true}}
|
||||
</div>
|
||||
</fieldset>
|
||||
{{> "systems/foundryvtt-reve-de-dragon/templates/actor/xp-journal.hbs"}}
|
||||
{{> "systems/foundryvtt-reve-de-dragon/templates/actor/editor-notes-mj.hbs"}}
|
||||
</article>
|
||||
</div>
|
||||
|
||||
</section>
|
||||
</form>
|
||||
|
||||
</section>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<form class="{{cssClass}}" autocomplete="off">
|
||||
<section class="{{cssClass}}" autocomplete="off">
|
||||
|
||||
{{!-- Sheet Header --}}
|
||||
<header class="sheet-header">
|
||||
@@ -36,8 +36,8 @@
|
||||
|
||||
{{!-- Sheet Tab Navigation --}}
|
||||
<nav class="sheet-tabs tabs" data-group="primary">
|
||||
<a class="item" data-tab="description">Description</a>
|
||||
<a class="item" data-tab="items">Chargement</a>
|
||||
<a class="item" data-action="tab" data-group="primary" data-tab="description">Description</a>
|
||||
<a class="item" data-action="tab" data-group="primary" data-tab="items">Chargement</a>
|
||||
</nav>
|
||||
|
||||
{{!-- Sheet Body --}}
|
||||
@@ -83,9 +83,12 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group large-editor">
|
||||
{{editor description target="system.description" button=true owner=options.isOwner editable=options.editable engine="prosemirror"}}
|
||||
</div>
|
||||
<h3>Description</h3>
|
||||
<fieldset>
|
||||
<div>
|
||||
{{formInput systemFields.description enriched=description value=system.description name="system.description" toggled=true}}
|
||||
</div>
|
||||
</fieldset>
|
||||
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/editor-notes-mj.hbs"}}
|
||||
</div>
|
||||
|
||||
@@ -96,4 +99,4 @@
|
||||
</div>
|
||||
|
||||
</section>
|
||||
</form>
|
||||
</section>
|
||||
@@ -1,4 +1,4 @@
|
||||
<form class="{{cssClass}}" autocomplete="off">
|
||||
<section class="{{cssClass}}" autocomplete="off">
|
||||
|
||||
{{!-- Sheet Header --}}
|
||||
<header class="sheet-header">
|
||||
@@ -36,7 +36,12 @@
|
||||
{{!-- Sheet Body --}}
|
||||
<section class="sheet-body">
|
||||
<div class="flexcol form-group medium-editor">
|
||||
{{editor description target="system.description" button=true owner=options.isOwner editable=options.isOwner engine="prosemirror"}}
|
||||
<fieldset>
|
||||
<div>
|
||||
<label>Description :</label>
|
||||
{{formInput systemFields.description enriched=description value=system.description name="system.description" toggled=true}}
|
||||
</div>
|
||||
</fieldset>
|
||||
</div>
|
||||
<hr>
|
||||
{{> "systems/foundryvtt-reve-de-dragon/templates/actor/commerce-inventaire.hbs"}}
|
||||
@@ -50,4 +55,4 @@
|
||||
{{> "systems/foundryvtt-reve-de-dragon/templates/actor/editor-notes-mj.hbs"}}
|
||||
<br>
|
||||
</section>
|
||||
</form>
|
||||
</section>
|
||||
@@ -1,6 +1,8 @@
|
||||
{{#if options.isGM}}
|
||||
<h3>Notes du MJ : </h3>
|
||||
<div class="form-group large-editor">
|
||||
{{editor notesmj target="system.notesmj" button=true owner=options.isOwner editable=options.editable engine="prosemirror"}}
|
||||
</div>
|
||||
<fieldset>
|
||||
<div>
|
||||
{{formInput systemFields.notesmj enriched=notesmj value=system.notesmj name="system.notesmj" toggled=true}}
|
||||
</div>
|
||||
</fieldset>
|
||||
{{/if}}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<form class="{{cssClass}}" autocomplete="off" >
|
||||
<section class="{{cssClass}}" autocomplete="off" >
|
||||
<section class="sheet-header flexrow">
|
||||
<div class="flex-grow-0-5">
|
||||
<img class="profile-img" src="{{img}}" data-edit="img" data-tooltip="{{name}}" />
|
||||
@@ -128,4 +128,4 @@
|
||||
</div>
|
||||
{{/if}}
|
||||
</section>
|
||||
</form>
|
||||
</section>
|
||||
Reference in New Issue
Block a user