fix(creation): fallback équipement archétype, ergonomie et récapitulatif

- équipements non retrouvés dans les compendiums recopiés depuis l'archétype
  (fallback fromArchetype) : liste, budget, création d'items et conteneurs OK
- correction du spread system qui écrasait quantite/cout/encombrement
- fenêtre +10% de hauteur, titres et boutons de navigation compactés
- formulaire remplit la fenêtre v13 : boutons calés en bas sur toutes les étapes
- textes du récapitulatif en brun (--wizard-text-body), caracs en pastilles
This commit is contained in:
fabres
2026-08-08 17:31:50 +02:00
parent af05b57405
commit edeedb6b3d
5 changed files with 356 additions and 102 deletions
+128 -32
View File
@@ -123,6 +123,7 @@ body {
--wizard-accent-magic: #9370DB;
--wizard-text-primary: #F5F5DC;
--wizard-text-secondary: #D2B48C;
--wizard-text-body: #8B6914;
--wizard-border: rgba(191, 149, 63, 0.4);
--wizard-step-active: rgba(212, 175, 55, 0.3);
--wizard-step-done: rgba(106, 90, 205, 0.4);
@@ -8343,10 +8344,13 @@ body {
/* Arriere-plan global avec effets de rêve */
background: var(--wizard-bg-primary);
background-image: radial-gradient(circle at 10% 20%, rgba(212, 175, 55, 0.05) 0%, transparent 30%), radial-gradient(circle at 90% 80%, rgba(106, 90, 205, 0.05) 0%, transparent 30%);
min-height: 80vh;
min-height: 60vh;
max-height: calc(100vh - 3rem);
display: flex;
flex-direction: column;
box-shadow: 0 0 20px rgba(0, 0, 0, 0.5);
/* Zone interne de la fenêtre v13 : plein écran, colonne flex
(sinon .wizard-content ne remplit pas la hauteur disponible) */
/* ==================== EN-TETE DU WIZARD ==================== */
/* ==================== BARRE DE PROGRESSION ==================== */
/* ==================== CONTENU PRINCIPAL ==================== */
@@ -8358,9 +8362,20 @@ body {
/* Tooltips contextuelles */
/* Form group styling - Supprimé pour réduire espacements */
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .window-content {
display: flex;
flex-direction: column;
flex: 1;
min-height: 0;
/* Le formulaire (même classe que la fenêtre) doit remplir la zone */
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .window-content > form.rdd-creation-personnage {
flex: 1 1 0%;
min-height: 0;
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-header {
background: linear-gradient(135deg, var(--gradient-gold), var(--gradient-violet));
padding: 1rem;
padding: 0.5rem 1rem;
border-bottom: 2px solid var(--wizard-border);
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.3);
align-items: center;
@@ -8368,7 +8383,7 @@ body {
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-header h2 {
font-family: "MedievalSharp", serif;
font-size: 1.8rem;
font-size: 1.3rem;
color: var(--wizard-accent-gold);
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.5);
margin: 0;
@@ -8396,7 +8411,7 @@ body {
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-progress {
background: var(--wizard-bg-secondary);
padding: 1rem;
padding: 0.4rem 1rem;
border-bottom: 1px solid var(--wizard-border);
position: relative;
justify-content: space-between;
@@ -8420,33 +8435,36 @@ body {
display: flex;
flex-direction: column;
align-items: center;
padding: 0.5rem;
padding: 0.2rem 0.5rem;
flex: 1;
/* Etat ACTIF */
/* Etat TERMINE */
/* Etat EN ATTENTE */
/* Effet de survol */
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-progress .wizard-step .step-icon {
display: none;
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-progress .wizard-step .step-num {
display: inline-flex;
align-items: center;
justify-content: center;
width: 2rem;
height: 2rem;
width: 1.5rem;
height: 1.5rem;
border-radius: 50%;
background: var(--wizard-bg-secondary);
border: 2px solid var(--wizard-border);
border: 1px solid var(--wizard-border);
color: var(--wizard-text-secondary);
font-family: "GrenzeGotisch", serif;
font-weight: bold;
font-size: 1.1rem;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
font-size: 0.85rem;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);
transition: all 0.3s ease;
margin-bottom: 0.3rem;
margin-bottom: 0.15rem;
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-progress .wizard-step .step-label {
font-family: "CaslonAntique", serif;
font-size: 0.85rem;
font-size: 0.7rem;
color: var(--wizard-text-secondary);
white-space: nowrap;
text-align: center;
@@ -8490,7 +8508,8 @@ body {
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-content {
flex: 1;
padding-right: 0.5rem;
max-height: calc(100vh - 14rem);
display: flex;
flex-direction: column;
overflow-y: auto;
/* Fond avec texture subtile */
background: var(--wizard-bg-primary);
@@ -8507,14 +8526,16 @@ body {
/* Budget et indicateurs - style "compteur de rêves" */
/* Listes de compétences et sorts */
/* Grille d'attributs */
/* Biographie / Description : occuper toute la hauteur restante
(boutons précédent/suivant calés en bas comme les autres étapes) */
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-content h3 {
font-family: "MedievalSharp", serif;
color: var(--wizard-accent-gold);
font-size: 1.5rem;
font-size: 1.15rem;
border-bottom: 1px solid var(--wizard-border);
padding-bottom: 0.5rem;
margin: 0;
padding-bottom: 0.25rem;
margin: 0.25rem 0 0.5rem;
text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.3);
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-content h4 {
@@ -8525,7 +8546,7 @@ body {
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-content p {
font-family: "CaslonAntique", serif;
color: var(--wizard-text-secondary);
color: var(--wizard-text-body);
font-size: 1rem;
line-height: 1.6;
margin: 0.8rem 0;
@@ -8603,7 +8624,8 @@ body {
margin: 0;
padding: 0;
overflow-y: auto;
max-height: calc(60vh - 7rem);
flex: 1;
min-height: 0;
background: rgba(0, 0, 0, 0.05);
border-radius: 4px;
}
@@ -8639,6 +8661,20 @@ body {
background: linear-gradient(135deg, rgba(106, 90, 205, 0.15), rgba(147, 112, 219, 0.1));
border-left: 3px solid var(--wizard-accent-dream);
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-content .liste-competences-creation .list-item.xp-depense,
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-content .liste-sorts-creation .list-item.xp-depense {
background: rgba(212, 175, 55, 0.15);
box-shadow: inset 3px 0 0 var(--wizard-accent-gold);
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-content .liste-competences-creation .list-item.xp-depense .comp-nom::before,
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-content .liste-sorts-creation .list-item.xp-depense .comp-nom::before {
content: "✦ ";
color: var(--wizard-accent-gold);
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-content .liste-competences-creation .list-item.xp-depense .comp-cout,
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-content .liste-sorts-creation .list-item.xp-depense .comp-cout {
color: #FFD700;
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-content .liste-competences-creation .comp-nom,
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-content .liste-sorts-creation .comp-nom,
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-content .liste-competences-creation .sort-nom,
@@ -8694,17 +8730,19 @@ body {
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-content .attr-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 1rem;
gap: 0.6rem 1rem;
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-content .attr-grid .form-group {
display: flex;
flex-direction: column;
gap: 0.3rem;
flex-direction: row;
align-items: center;
gap: 0.5rem;
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-content .attr-grid .form-group label {
font-family: "CaslonAntique", serif;
color: var(--wizard-text-primary);
color: var(--wizard-text-body);
font-weight: 500;
flex: 0 0 7.5rem;
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-content .attr-grid .form-group input,
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-content .attr-grid .form-group select {
@@ -8712,9 +8750,10 @@ body {
border: 1px solid var(--wizard-border);
color: var(--wizard-text-primary);
font-family: "CaslonAntique", serif;
padding: 0.5rem;
padding: 0.3rem 0.5rem;
border-radius: 4px;
width: 100%;
flex: 1;
min-width: 0;
box-sizing: border-box;
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-content .attr-grid .form-group input:focus,
@@ -8737,6 +8776,24 @@ body {
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-content textarea.attr-input {
box-sizing: border-box;
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-content > .form-group:has(textarea) {
display: flex;
flex-direction: column;
gap: 0.3rem;
flex: 1;
min-height: 0;
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-content > .form-group:has(textarea) textarea {
flex: 1;
min-height: 80px;
resize: none;
width: 100%;
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-content > .form-group > label {
font-family: "CaslonAntique", serif;
color: var(--wizard-text-body);
font-weight: 500;
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-content .archetype-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(9rem, 1fr));
@@ -8798,6 +8855,11 @@ body {
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-content .equip-filtres input {
flex: 1;
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-content .equip-arborescence {
flex: 1;
min-height: 12rem;
overflow-y: auto;
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-content .equip-arborescence .equip-type {
margin-bottom: 0.3rem;
}
@@ -8876,6 +8938,9 @@ body {
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-warning {
margin: 0.5rem 0;
max-height: 6rem;
overflow-y: auto;
flex-shrink: 0;
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-warning ul {
margin: 0;
@@ -8900,17 +8965,17 @@ body {
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-buttons {
background: var(--wizard-bg-secondary);
padding: 1rem;
padding: 0.4rem 0.6rem;
border-top: 1px solid var(--wizard-border);
justify-content: flex-end;
gap: 0.8rem;
margin-top: 0.5rem;
gap: 0.5rem;
margin-top: 0.25rem;
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-buttons button {
font-family: "MedievalSharp", serif;
font-size: 1.1rem;
letter-spacing: 1px;
padding: 0.6rem 2rem;
font-size: 0.9rem;
letter-spacing: 0.5px;
padding: 0.25rem 1rem;
border: 1px solid var(--wizard-border);
border-radius: 4px;
cursor: pointer;
@@ -8953,6 +9018,7 @@ body {
border-radius: 4px;
padding: 1rem;
margin-bottom: 1.5rem;
/* Caractéristiques en "pastilles" (style tableau de rune) */
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .recap-section h4 {
font-family: "MedievalSharp", serif;
@@ -8969,15 +9035,45 @@ body {
padding: 0.3rem 0;
border-bottom: 1px solid rgba(191, 149, 63, 0.1);
font-family: "CaslonAntique", serif;
color: var(--wizard-text-secondary);
color: var(--wizard-text-body);
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .recap-section p {
font-family: "CaslonAntique", serif;
color: var(--wizard-text-secondary);
color: var(--wizard-text-body);
font-size: 1rem;
line-height: 1.6;
margin: 0.5rem 0;
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .recap-section .recup-caracs,
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .recap-section .recap-derivees {
flex-wrap: wrap;
gap: 0.4rem;
margin: 0.4rem 0;
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .recap-section .recup-caracs .recap-chip,
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .recap-section .recap-derivees .recap-chip {
display: flex;
align-items: center;
gap: 0.4rem;
background: rgba(0, 0, 0, 0.15);
border: 1px solid var(--wizard-border);
border-radius: 4px;
padding: 0.25rem 0.6rem;
font-family: "CaslonAntique", serif;
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .recap-section .recup-caracs .recap-chip .recap-chip-label,
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .recap-section .recap-derivees .recap-chip .recap-chip-label {
color: var(--wizard-text-body);
font-weight: 500;
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .recap-section .recup-caracs .recap-chip .recap-chip-value,
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .recap-section .recap-derivees .recap-chip .recap-chip-value {
color: var(--wizard-text-body);
font-weight: bold;
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .recap-section .recap-derivees {
margin-top: 0.6rem;
}
@keyframes pulse-glow {
0% {
box-shadow: 0 0 5px rgba(212, 175, 55, 0.5);
+1
View File
@@ -73,6 +73,7 @@ body {
--wizard-accent-magic: #9370DB;
--wizard-text-primary: #F5F5DC;
--wizard-text-secondary: #D2B48C;
--wizard-text-body: #8B6914;
--wizard-border: rgba(191, 149, 63, 0.4);
--wizard-step-active: rgba(212, 175, 55, 0.3);
--wizard-step-done: rgba(106, 90, 205, 0.4);
+132 -32
View File
@@ -3155,15 +3155,31 @@
background-image:
radial-gradient(circle at 10% 20%, rgba(212, 175, 55, 0.05) 0%, transparent 30%),
radial-gradient(circle at 90% 80%, rgba(106, 90, 205, 0.05) 0%, transparent 30%);
min-height: 80vh;
min-height: 60vh;
max-height: calc(100vh - 3rem);
display: flex;
flex-direction: column;
box-shadow: 0 0 20px rgba(0, 0, 0, 0.5);
/* Zone interne de la fenêtre v13 : plein écran, colonne flex
(sinon .wizard-content ne remplit pas la hauteur disponible) */
.window-content {
display: flex;
flex-direction: column;
flex: 1;
min-height: 0;
/* Le formulaire (même classe que la fenêtre) doit remplir la zone */
> form.rdd-creation-personnage {
flex: 1 1 0%;
min-height: 0;
}
}
/* ==================== EN-TETE DU WIZARD ==================== */
.wizard-header {
background: linear-gradient(135deg, var(--gradient-gold), var(--gradient-violet));
padding: 1rem;
padding: 0.5rem 1rem;
border-bottom: 2px solid var(--wizard-border);
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.3);
align-items: center;
@@ -3171,7 +3187,7 @@
h2 {
font-family: "MedievalSharp", serif;
font-size: 1.8rem;
font-size: 1.3rem;
color: var(--wizard-accent-gold);
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.5);
margin: 0;
@@ -3205,7 +3221,7 @@
/* ==================== BARRE DE PROGRESSION ==================== */
.wizard-progress {
background: var(--wizard-bg-secondary);
padding: 1rem;
padding: 0.4rem 1rem;
border-bottom: 1px solid var(--wizard-border);
position: relative;
justify-content: space-between;
@@ -3231,30 +3247,34 @@
display: flex;
flex-direction: column;
align-items: center;
padding: 0.5rem;
padding: 0.2rem 0.5rem;
flex: 1;
.step-icon {
display: none;
}
.step-num {
display: inline-flex;
align-items: center;
justify-content: center;
width: 2rem;
height: 2rem;
width: 1.5rem;
height: 1.5rem;
border-radius: 50%;
background: var(--wizard-bg-secondary);
border: 2px solid var(--wizard-border);
border: 1px solid var(--wizard-border);
color: var(--wizard-text-secondary);
font-family: "GrenzeGotisch", serif;
font-weight: bold;
font-size: 1.1rem;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
font-size: 0.85rem;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);
transition: all 0.3s ease;
margin-bottom: 0.3rem;
margin-bottom: 0.15rem;
}
.step-label {
font-family: "CaslonAntique", serif;
font-size: 0.85rem;
font-size: 0.7rem;
color: var(--wizard-text-secondary);
white-space: nowrap;
text-align: center;
@@ -3316,7 +3336,8 @@
.wizard-content {
flex: 1;
padding-right: 0.5rem;
max-height: calc(100vh - 14rem);
display: flex;
flex-direction: column;
overflow-y: auto;
/* Fond avec texture subtile */
@@ -3334,10 +3355,10 @@
h3 {
font-family: "MedievalSharp", serif;
color: var(--wizard-accent-gold);
font-size: 1.5rem;
font-size: 1.15rem;
border-bottom: 1px solid var(--wizard-border);
padding-bottom: 0.5rem;
margin: 0;
padding-bottom: 0.25rem;
margin: 0.25rem 0 0.5rem;
text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.3);
}
@@ -3350,7 +3371,7 @@
p {
font-family: "CaslonAntique", serif;
color: var(--wizard-text-secondary);
color: var(--wizard-text-body);
font-size: 1rem;
line-height: 1.6;
margin: 0.8rem 0;
@@ -3439,7 +3460,8 @@
margin: 0;
padding: 0;
overflow-y: auto;
max-height: calc(60vh - 7rem);
flex: 1;
min-height: 0;
background: rgba(0, 0, 0, 0.05);
border-radius: 4px;
@@ -3474,6 +3496,20 @@
rgba(106, 90, 205, 0.15), rgba(147, 112, 219, 0.1));
border-left: 3px solid var(--wizard-accent-dream);
}
&.xp-depense {
background: rgba(212, 175, 55, 0.15);
box-shadow: inset 3px 0 0 var(--wizard-accent-gold);
.comp-nom::before {
content: "✦ ";
color: var(--wizard-accent-gold);
}
.comp-cout {
color: #FFD700;
}
}
}
.comp-nom, .sort-nom {
@@ -3518,17 +3554,19 @@
.attr-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 1rem;
gap: 0.6rem 1rem;
.form-group {
display: flex;
flex-direction: column;
gap: 0.3rem;
flex-direction: row;
align-items: center;
gap: 0.5rem;
label {
font-family: "CaslonAntique", serif;
color: var(--wizard-text-primary);
color: var(--wizard-text-body);
font-weight: 500;
flex: 0 0 7.5rem;
}
input, select {
@@ -3536,9 +3574,10 @@
border: 1px solid var(--wizard-border);
color: var(--wizard-text-primary);
font-family: "CaslonAntique", serif;
padding: 0.5rem;
padding: 0.3rem 0.5rem;
border-radius: 4px;
width: 100%;
flex: 1;
min-width: 0;
box-sizing: border-box;
&:focus {
@@ -3560,6 +3599,29 @@
.attr-input { width: 100%; }
textarea.attr-input { box-sizing: border-box; }
/* Biographie / Description : occuper toute la hauteur restante
(boutons précédent/suivant calés en bas comme les autres étapes) */
> .form-group:has(textarea) {
display: flex;
flex-direction: column;
gap: 0.3rem;
flex: 1;
min-height: 0;
textarea {
flex: 1;
min-height: 80px;
resize: none;
width: 100%;
}
}
> .form-group > label {
font-family: "CaslonAntique", serif;
color: var(--wizard-text-body);
font-weight: 500;
}
.archetype-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(9rem, 1fr));
@@ -3617,6 +3679,9 @@
input { flex: 1; }
}
.equip-arborescence {
flex: 1;
min-height: 12rem;
overflow-y: auto;
.equip-type {
margin-bottom: 0.3rem;
&.hidden { display: none; }
@@ -3675,6 +3740,9 @@
/* ==================== ERREURS ==================== */
.wizard-warning {
margin: 0.5rem 0;
max-height: 6rem;
overflow-y: auto;
flex-shrink: 0;
ul {
margin: 0;
padding-left: 1.2rem;
@@ -3702,17 +3770,17 @@
/* ==================== BOUTONS DE NAVIGATION ==================== */
.wizard-buttons {
background: var(--wizard-bg-secondary);
padding: 1rem;
padding: 0.4rem 0.6rem;
border-top: 1px solid var(--wizard-border);
justify-content: flex-end;
gap: 0.8rem;
margin-top: 0.5rem;
gap: 0.5rem;
margin-top: 0.25rem;
button {
font-family: "MedievalSharp", serif;
font-size: 1.1rem;
letter-spacing: 1px;
padding: 0.6rem 2rem;
font-size: 0.9rem;
letter-spacing: 0.5px;
padding: 0.25rem 1rem;
border: 1px solid var(--wizard-border);
border-radius: 4px;
cursor: pointer;
@@ -3778,17 +3846,49 @@
padding: 0.3rem 0;
border-bottom: 1px solid rgba(191, 149, 63, 0.1);
font-family: "CaslonAntique", serif;
color: var(--wizard-text-secondary);
color: var(--wizard-text-body);
}
}
p {
font-family: "CaslonAntique", serif;
color: var(--wizard-text-secondary);
color: var(--wizard-text-body);
font-size: 1rem;
line-height: 1.6;
margin: 0.5rem 0;
}
/* Caractéristiques en "pastilles" (style tableau de rune) */
.recup-caracs, .recap-derivees {
flex-wrap: wrap;
gap: 0.4rem;
margin: 0.4rem 0;
.recap-chip {
display: flex;
align-items: center;
gap: 0.4rem;
background: rgba(0, 0, 0, 0.15);
border: 1px solid var(--wizard-border);
border-radius: 4px;
padding: 0.25rem 0.6rem;
font-family: "CaslonAntique", serif;
.recap-chip-label {
color: var(--wizard-text-body);
font-weight: 500;
}
.recap-chip-value {
color: var(--wizard-text-body);
font-weight: bold;
}
}
}
.recap-derivees {
margin-top: 0.6rem;
}
}
/* ==================== ANIMATIONS ==================== */
@@ -60,7 +60,7 @@ export class CreationPersonnageWizard extends HandlebarsApplicationMixin(foundry
static DEFAULT_OPTIONS = {
classes: ['rdd-creation-personnage'],
window: { title: "Création de personnage" },
position: { width: 760, height: 'fit-content' },
position: { width: 760, height: 792 },
};
constructor(options = {}) {
@@ -250,33 +250,44 @@ export class CreationPersonnageWizard extends HandlebarsApplicationMixin(foundry
}
}
// Équipement : mapper par nom, fortune = total monnaies de l'archétype.
// Équipement : mapper par nom ; à défaut, recopier l'item de l'archétype
// tel quel (il n'existe pas dans le compendium équipement).
// La structure (dont le contenu des conteneurs) est prise depuis l'item
// du voyageur, les coûts/encombrements depuis le compendium équipement.
// du voyageur, les coûts/encombrements depuis le compendium équipement
// (ou depuis l'item lui-même en fallback).
this.data.equipement.selection = {};
this._archetypeIdMap = new Map();
const itemsEquip = voyageur.items.filter(i => ![ITEM_TYPES.competence, ITEM_TYPES.monnaie, ITEM_TYPES.sort, ITEM_TYPES.tete].includes(i.type));
for (const item of itemsEquip) {
const equip = this._equipement.find(e => Grammar.equalsInsensitive(e.name, item.name));
const quantite = Number(item.system.quantite ?? 1);
if (quantite <= 0) continue;
const structure = { ...item.system };
delete structure._id;
if (equip) {
const quantite = Number(item.system.quantite ?? 1);
if (quantite > 0) {
const structure = { ...item.system };
delete structure._id;
this._archetypeIdMap.set(item.id, equip._id);
this.data.equipement.selection[equip._id] = {
item: { ...equip, structure },
quantite,
};
}
this._archetypeIdMap.set(item.id, equip._id);
this.data.equipement.selection[equip._id] = {
item: { ...equip, structure },
quantite,
};
} else {
this.data.equipement.nonMappes.push(item.name);
this._archetypeIdMap.set(item.id, item._id);
this.data.equipement.selection[item._id] = {
item: {
_id: item._id,
name: item.name,
type: item.type,
img: item.img,
structure,
cout: Number(item.system.cout ?? 0),
encombrement: Number(item.system.encombrement ?? 0),
fromArchetype: true,
},
quantite,
};
}
}
const fortune = voyageur.items
.filter(i => i.type === ITEM_TYPES.monnaie)
.reduce((sum, m) => sum + (Number(m.system.cout ?? 0) * Number(m.system.quantite ?? 0)), 0);
this.data.equipement.fortune = Number(fortune.toFixed(2));
this.data.equipement.fortune = FORTUNE_DEFAUT;
// Token / image
this._archetypeImg = voyageur.img;
@@ -338,21 +349,34 @@ export class CreationPersonnageWizard extends HandlebarsApplicationMixin(foundry
break;
case ETAPE_CARACTERISTIQUES:
el.querySelectorAll("input.carac-input").forEach(inp =>
inp.addEventListener("input", event => {
const carac = event.target.dataset.carac;
const min = carac === 'beaute' ? 10 : 6;
const max = carac === 'beaute' ? 16 : 15;
const raw = Number(event.target.value);
const val = Math.max(min, Math.min(max, Number.isNaN(raw) ? min : raw));
event.target.value = val;
el.querySelectorAll("input.carac-input").forEach(inp => {
const min = () => inp.dataset.carac === 'beaute' ? 10 : 6;
const max = () => inp.dataset.carac === 'beaute' ? 16 : 15;
const lire = () => {
const carac = inp.dataset.carac;
const raw = Number(inp.value);
const val = Math.max(min(), Math.min(max(), Number.isNaN(raw) ? min() : raw));
return { carac, val };
};
const stocker = ({ carac, val }) => {
if (carac === 'beaute') {
this.data.beaute = val;
} else {
this.data.caracs[carac] = val;
}
this._mettreAJourBudget(el);
}));
};
inp.addEventListener("input", () => {
// On ne réécrit pas le champ pendant la frappe (sinon taper
// "12" donnerait "1" -> clamp 6 -> puis "62" -> clamp 15).
stocker(lire());
});
inp.addEventListener("change", () => {
const { carac, val } = lire();
inp.value = val;
stocker({ carac, val });
});
});
break;
case ETAPE_COMPETENCES: {
@@ -377,6 +401,7 @@ export class CreationPersonnageWizard extends HandlebarsApplicationMixin(foundry
comp.system.xp = 0;
const li = event.target.closest(".list-item");
if (li) {
li.classList.toggle("xp-depense", nouveauNiveau > comp.system.base);
const coutEl = li.querySelector(".comp-cout");
if (coutEl) coutEl.textContent = coutApres;
}
@@ -468,14 +493,19 @@ export class CreationPersonnageWizard extends HandlebarsApplicationMixin(foundry
}
_changerQuantite(el, itemId, delta) {
const item = this._equipement.find(it => it._id === itemId);
const item = this._getEquipementItem(itemId);
if (!item) return;
const actuel = this.data.equipement.selection[itemId]?.quantite ?? 0;
this._setQuantite(el, itemId, actuel + delta);
}
_getEquipementItem(itemId) {
return this._equipement.find(it => it._id === itemId)
?? this.data.equipement.selection[itemId]?.item;
}
_setQuantite(el, itemId, quantite) {
const item = this._equipement.find(it => it._id === itemId);
const item = this._getEquipementItem(itemId);
if (!item) return;
quantite = Math.max(0, quantite);
if (quantite === 0) {
@@ -536,6 +566,7 @@ export class CreationPersonnageWizard extends HandlebarsApplicationMixin(foundry
setColor("#budget-competences-restant", bp.restant);
set("#budget-sorts-depense", bs.depense);
setColor("#budget-sorts-restant", bs.restant);
setColor("#budget-pool-restant", bp.restant);
set("#budget-equip-fortune", be.fortune.toFixed(2));
set("#budget-equip-depense", be.depense.toFixed(2));
setColor("#budget-equip-restant", be.restant);
@@ -739,6 +770,19 @@ export class CreationPersonnageWizard extends HandlebarsApplicationMixin(foundry
depense: selection ? selection.quantite * item.cout : 0,
});
}
for (const sel of Object.values(this.data.equipement.selection)) {
if (!sel.item.fromArchetype) continue;
if (this._equipement.some(it => it._id === sel.item._id)) continue;
const item = sel.item;
if (filtre !== "tous" && filtre !== item.type) continue;
if (recherche && !item.name.toLowerCase().includes(recherche)) continue;
if (!groupes[item.type]) groupes[item.type] = [];
groupes[item.type].push({
...item,
quantite: sel.quantite,
depense: sel.quantite * item.cout,
});
}
return Object.entries(groupes).map(([type, items]) => ({ type, items }));
}
@@ -884,13 +928,13 @@ export class CreationPersonnageWizard extends HandlebarsApplicationMixin(foundry
// la hiérarchie des conteneurs.
const itemsCrees = [];
for (const sel of selection) {
const item = this._equipement.find(it => it._id === sel.item._id);
const item = this._getEquipementItem(sel.item._id);
if (!item) continue;
const system = {
...(item.structure ? { ...item.structure } : {}),
quantite: sel.quantite,
cout: item.cout,
encombrement: item.encombrement,
...(item.structure ? { ...item.structure } : {}),
};
delete system.contenu; // recréé après le mapping
delete system._id;
@@ -980,7 +1024,10 @@ export class CreationPersonnageWizard extends HandlebarsApplicationMixin(foundry
}
_typesEquipement() {
const types = [...new Set(this._equipement.map(it => it.type))].sort();
const types = [...new Set([
...this._equipement.map(it => it.type),
...Object.values(this.data.equipement.selection).map(sel => sel.item.type),
])].sort();
return types;
}
+16 -6
View File
@@ -100,7 +100,7 @@
<span class="comp-cout">Coût</span>
</li>
{{#each competences}}
<li class="item flexrow list-item {{#if this.isDraconic}}draconic{{/if}}">
<li class="item flexrow list-item {{#if this.isDraconic}}draconic{{/if}} {{#if (gt this.system.niveau this.system.base)}}xp-depense{{/if}}">
<span class="comp-nom">{{this.name}}</span>
<span class="comp-cat">{{this.system.categorie}}</span>
<span class="comp-base">{{this.system.base}}</span>
@@ -122,8 +122,9 @@
<h3>Sorts et rituels (max 300 points)</h3>
<p>Les sorts coûtent leur difficulté × 10 (Annulation de magie : 70 points). Un sort n'est accessible que si sa difficulté ne dépasse pas le niveau de Draconic + 3. Maximum 300 points sur les 3000.</p>
<div class="form-group">
<span class="budget-label">Sorts dépensé : <strong id="budget-sorts-depense">{{budgetSorts.depense}}</strong></span>
<span class="budget-label">Restant : <strong id="budget-sorts-restant">{{budgetSorts.restant}}</strong></span>
<span class="budget-label">Sorts dépensé : <strong id="budget-sorts-depense">{{budgetSorts.depense}}</strong> / {{MAX_XP_SORTS}}</span>
<span class="budget-label">Restant (cap sorts) : <strong id="budget-sorts-restant">{{budgetSorts.restant}}</strong></span>
<span class="budget-label">Restant XP disponible (avec sorts) : <strong id="budget-pool-restant">{{budgetCompetences.restant}}</strong></span>
</div>
<ul class="item-list alterne-list liste-sorts-creation">
<li class="competence-header flexrow">
@@ -286,13 +287,22 @@
<h4>Caractéristiques</h4>
<div class="flexrow recup-caracs">
{{#each caracsPrimaires}}
<span>{{lookup ../labelsCaracs this}}: {{lookup ../data.caracs this}}</span>
<div class="recap-chip">
<span class="recap-chip-label">{{lookup ../labelsCaracs this}}</span>
<span class="recap-chip-value">{{lookup ../data.caracs this}}</span>
</div>
{{/each}}
<span>Beauté: {{data.beaute}}</span>
<div class="recap-chip">
<span class="recap-chip-label">Beauté</span>
<span class="recap-chip-value">{{data.beaute}}</span>
</div>
</div>
<div class="flexrow recap-derivees">
{{#each caracsDerivees}}
<span>{{lookup ../labelsCaracs this}}: {{lookup ../caracsDeriveesCalculees this}}</span>
<div class="recap-chip">
<span class="recap-chip-label">{{lookup ../labelsCaracs this}}</span>
<span class="recap-chip-value">{{lookup ../caracsDeriveesCalculees this}}</span>
</div>
{{/each}}
</div>
</div>