Compare commits

..
Author SHA1 Message Date
fabres edeedb6b3d 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
2026-08-08 17:31:50 +02:00
fabres af05b57405 feat(creation): archétypes Voyageurs + hiérarchie conteneurs + alertes
Archétypes :
- Sélection par cartes cliquables à l'étape Haut-Rêve (12 voyageurs du
  compendium + création libre), avec image et nom
- Choix haut-rêvant verrouillé quand un archétype est sélectionné
- _appliquerArchetype pré-remplit caracs, beauté, attributs, compétences
  (par _id), sorts, équipement (par nom) et fortune (total monnaies de
  l'archétype) ; image token de l'archétype à la création
- _resetArchetype (création libre) remet tout aux valeurs par défaut
- Récapitulatif : ligne Archétype

Économie des troncs :
- _economieTroncs applique la règle des compétences troncs (Corps à
  corps/Dague/Esquive et armes) au budget de 3000 XP (le Baladin passe
  de 3160 à 3000 exactement)

Hiérarchie des conteneurs :
- La structure (dont contenu des conteneurs) est prise depuis l'item
  voyageur ; mapping archetypeID -> equipID -> nouvelID créé
- Les system.contenu des conteneurs sont reconstruits après création
  (sac à dos -> 11 contenus, ceinturon -> outre -> eau, etc.)

Fix budget équipement :
- La condition de blocage (depenseDelta > 0 && > restant) permet les
  réductions même quand le budget est négatif

Alertes items non mappés :
- Les éléments de l'archétype non retrouvés dans les compendiums sont
  collectés et signalés par notification toast + bandeaux d'avertissement
  aux étapes Haut-Rêve et Équipement
2026-08-08 09:10:46 +02:00
fabres bb7466b33e feat(creation): assistant de création de personnage (wizard)
Nouveau wizard ApplicationV2 pour créer un personnage de A à Z, lancé
depuis un bouton « Créer (wizard) » dans le répertoire d'acteurs.

Étapes :
- Haut-Rêve : choix haut-rêvant / non (conditionne Draconic et sorts)
- Caractéristiques : 14 caracs (6-15) + beauté (10-16), budget 160
  temps réel, dérivées calculées en direct, FORCE ≤ TAILLE+4
- Compétences : 67 compétences triées par catégorie puis nom, niveaux
  base→+3, coûts via la table de création (regles_creation_personnage),
  budget 3000 temps réel, Thanatos ×2, troncs, survie, Draconics
  désactivées si non haut-rêvant, XP = 0 (investissement suivi via
  compteurs.experience)
- Sorts (haut-rêvant) : filtrage R ≤ Draconic+3, coût auto (diff×10 ou
  70), cap 300 + pool partagé 3000
- Attributs : sexe, âge, taille, poids, yeux, cheveux, main, heure de
  naissance, biographie, description
- Équipement & Richesse : fortune de départ (50 sols), achat libre via
  arborescence par type + filtre + recherche, blocage budget, suivi
  encombrement (FORCE+TAILLE)/2, restant optimisé en monnaies sur la
  fiche (Dragon/Sol/Sou/Denier)
- Récapitulatif : vue complète + création de l'acteur (caracs, race
  Humain, compétences, sorts, don de haut-rêve, équipement, monnaies)

Corrections issues du review :
- « Précédent » directionnel (saut des sorts pour non haut-rêvant)
- Champ nom fonctionnel sur toutes les étapes
- system.xp des compétences à 0 (sémantique système)
- Sorts bloqués par le pool partagé 3000, pas seulement la cap 300
- Clamp des caractéristiques réécrit dans l'input
- Items « Sans compétence » du monde filtrés

CSS : thème wizard (variables --wizard-*), arborescence équipement,
steppers, barres de budget, scroll interne du contenu.
2026-08-07 23:24:50 +02:00
fabres fd3c228b32 Update changelog.md 2026-08-07 16:03:59 +02:00
fabres 9b3eceb96b fix(commerce): description pleine largeur sur la fiche
Release Creation / build (release) Successful in 2m13s
Le champ Description était dans un wrapper form-group (flex-direction: row)
qui le réduisait à la largeur de son contenu (~90px) au lieu de toute la
fiche (592px). Retrait de la classe form-group : le fieldset s'étire à
nouveau sur toute la largeur, comme sur les autres feuilles.

Valide par TC-06 (acteur commerce, 14/14) lors de la passe de
non-régression.

Ajoute aussi les permissions d'exécution manquantes sur les scripts
TC-02 et TC-07 (l'orchestrateur les sautait silencieusement).
2026-08-07 15:54:09 +02:00
fabres 73b91285e3 fix(sommeil): insomnie, château dormant automatique et reprise de nuit
Nouveau mode de repos (nouveau-mode-repos) :
- Insomnie (Queue de Dragon) : bannière d'avertissement dans le dialogue,
  rafraîchissement du drapeau à l'ouverture, vérification en direct dans la
  boucle de sommeil (coupe la récupération fatigue/rêve si elle surgit en
  cours de nuit), drapeau bidirectionnel (setInfoSommeilInsomnie) et mention
  dans le dialogue Château Dormant.
- Château Dormant : déclenchement automatique quand l'heure absolue de fin
  de nuit (11) est atteinte, au lieu de seulement après 12 h de sommeil.
- Rêve de Dragon : reprise de nuit possible — system.sommeil.heures
  initialisé à la durée, heures restantes conservées au réveil, dialogue
  pré-rempli avec bannière 'Reprise de nuit' et remise à zéro après une
  nuit complète.
- Don 'double rêve' : second jet de récupération de rêve par heure.
- Garde anti-boucle infinie si l'insomnie apparaît pendant le sommeil.
- Info-bulle sur le réveil forcé.

Perte de rêve des enchantements au Château Dormant :
- Suppression du message en double (whisper dédié) : texte intégré au
  résumé du CD ; la gemme renvoie désormais nouveaupr.
2026-08-07 15:54:09 +02:00
18 changed files with 3273 additions and 26 deletions
+42
View File
@@ -1,5 +1,47 @@
# 13.0
## 14.0.4 - Le sommeil de Tétragor
### Sommeil & Château Dormant (nouveau mode de repos)
- Insomnie (Queue de Dragon)
- bannière d'avertissement dans le dialogue de repos
- rafraîchissement du drapeau à l'ouverture du dialogue
- vérification en direct dans la boucle de sommeil : si l'insomnie surgit en
cours de nuit, la récupération de fatigue et de rêve est interrompue
- drapeau remis à jour dans les deux sens (levée possible)
- mention dans le dialogue Château Dormant
- Château Dormant automatique : déclenché quand l'heure de fin de nuit (11) est
réellement atteinte, au lieu de seulement après 12 heures de sommeil
- Reprise de nuit après un Rêve de Dragon
- la durée de sommeil est conservée
- les heures restantes sont proposées à la réouverture du dialogue avec une
bannière « Reprise de nuit »
- remise à zéro après une nuit complète
- don « double rêve » : second jet de récupération de rêve par heure (parité
ancien mode)
- garde anti-boucle infinie si l'insomnie apparaît pendant le sommeil
- info-bulle sur le réveil forcé
- perte de rêve des enchantements au Château Dormant : suppression du message en
double (whisper dédié), texte intégré au résumé ; la gemme renvoie son
nouveau total de points de rêve
### Commerces
- achat depuis un commerce en quantité illimitée : la quantité achetée est
correctement utilisée au lieu de celle du commerce
- fiche commerce : le champ Description utilise toute la largeur de la fiche
### Compétences
- ne plus créer d'item « Sans compétence » lors des migrations
## 14.0.3 - Les bases de Tétragor
- XP des compétences : les bases de catégorie peuvent être négatives
(base stockée en entier signé, migration 14.0.3)
- réorganisation des titres CSS
## 14.0.2 - Le grang ménage de Tétragor
### Migration Foundry V14
+804
View File
@@ -115,6 +115,22 @@ body {
--color-profile-border: hsla(0, 0%, 80%, 0.05);
--color-background-chat-message: hsla(60, 12%, 85%, 0.9);
--color-background-chat-whisper: repeating-linear-gradient(120deg, hsla(60, 12%, 85%, 0.75), hsla(60, 12%, 85%, 0.75) 1rem, hsla(60, 12%, 85%, 0.8) 1rem, hsla(60, 12%, 85%, 0.75) 1.5rem);
/* =================== WIZARD CREATION PERSONNAGE ============ */
--wizard-bg-primary: rgba(20, 18, 15, 0.95);
--wizard-bg-secondary: rgba(35, 30, 25, 0.9);
--wizard-accent-gold: #D4AF37;
--wizard-accent-dream: #6A5ACD;
--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);
--wizard-step-pending: rgba(128, 128, 128, 0.2);
--wizard-flag-success: #2a8a2a;
--wizard-flag-warning: #ffa500;
--wizard-flag-error: #ff4444;
}
.system-foundryvtt-reve-de-dragon {
/* =================== En-têtes de feuilles ============ */
@@ -153,6 +169,9 @@ body {
/*when hovering an item:*/
/*when navigating through the items using the arrow keys:*/
/*************************************************************/
/* ======================================================================
WIZARD DE CREATION DE PERSONNAGE - THEME "REVE EVEILLE"
====================================================================== */
}
.system-foundryvtt-reve-de-dragon .monnaie-content {
padding: 0px;
@@ -8321,3 +8340,788 @@ body {
border: none;
border-radius: 0.2rem;
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage {
/* 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: 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 ==================== */
/* ==================== ERREURS ==================== */
/* ==================== BOUTONS DE NAVIGATION ==================== */
/* ==================== SECTION RECAPITULATIF ==================== */
/* ==================== ANIMATIONS ==================== */
/* Effet de lueur pour l'étape active */
/* 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: 0.5rem 1rem;
border-bottom: 2px solid var(--wizard-border);
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.3);
align-items: center;
gap: 1rem;
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-header h2 {
font-family: "MedievalSharp", serif;
font-size: 1.3rem;
color: var(--wizard-accent-gold);
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.5);
margin: 0;
flex: 0 0 auto;
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-header input[name="name"] {
flex: 1;
background: var(--wizard-bg-secondary);
border: 1px solid var(--wizard-border);
color: var(--wizard-text-primary);
font-family: "CaslonAntique", serif;
font-size: 1.1rem;
padding: 0.5rem 1rem;
border-radius: 4px;
box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.2);
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-header input[name="name"]::placeholder {
color: var(--wizard-text-secondary);
font-style: italic;
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-header input[name="name"]:focus {
border-color: var(--wizard-accent-gold);
box-shadow: 0 0 8px rgba(212, 175, 55, 0.5), inset 0 2px 4px rgba(0, 0, 0, 0.2);
outline: none;
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-progress {
background: var(--wizard-bg-secondary);
padding: 0.4rem 1rem;
border-bottom: 1px solid var(--wizard-border);
position: relative;
justify-content: space-between;
/* Lignes de connexion entre étapes - effet "chemin de rêve" */
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-progress::before {
content: '';
position: absolute;
top: 50%;
left: 10%;
right: 10%;
height: 2px;
background: linear-gradient(90deg, transparent, var(--wizard-border), transparent);
z-index: 0;
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-progress .wizard-step {
position: relative;
z-index: 1;
cursor: pointer;
transition: all 0.3s ease;
display: flex;
flex-direction: column;
align-items: center;
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: 1.5rem;
height: 1.5rem;
border-radius: 50%;
background: var(--wizard-bg-secondary);
border: 1px solid var(--wizard-border);
color: var(--wizard-text-secondary);
font-family: "GrenzeGotisch", serif;
font-weight: bold;
font-size: 0.85rem;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);
transition: all 0.3s ease;
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.7rem;
color: var(--wizard-text-secondary);
white-space: nowrap;
text-align: center;
line-height: 1.2;
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-progress .wizard-step.active .step-num {
background: var(--wizard-accent-gold);
color: var(--wizard-bg-primary);
border-color: var(--wizard-accent-gold);
box-shadow: 0 0 10px rgba(212, 175, 55, 0.7);
transform: scale(1.1);
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-progress .wizard-step.active .step-label {
color: var(--wizard-text-primary);
font-weight: bold;
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-progress .wizard-step.done .step-num {
background: var(--wizard-accent-dream);
border-color: var(--wizard-accent-dream);
color: white;
box-shadow: 0 0 8px rgba(106, 90, 205, 0.5);
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-progress .wizard-step.done .step-label {
color: var(--wizard-accent-dream);
font-weight: 500;
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-progress .wizard-step.pending {
opacity: 0.6;
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-progress .wizard-step.pending .step-num {
background: var(--wizard-bg-secondary);
border-color: var(--wizard-step-pending);
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-progress .wizard-step.pending .step-label {
color: var(--wizard-text-secondary);
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-progress .wizard-step:hover:not(.pending) .step-num {
transform: scale(1.05);
box-shadow: 0 0 12px rgba(212, 175, 55, 0.6);
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-content {
flex: 1;
padding-right: 0.5rem;
display: flex;
flex-direction: column;
overflow-y: auto;
/* Fond avec texture subtile */
background: var(--wizard-bg-primary);
background-image: url('../assets/ui/bg_left.webp');
background-size: cover;
background-position: center;
background-repeat: no-repeat;
border: 1px solid var(--wizard-border);
border-radius: 4px;
padding: 1rem;
margin: 1rem 0;
/* Typographie hiérarchisée */
/* Grille des caractéristiques - style "tableau de rune" */
/* 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.15rem;
border-bottom: 1px solid var(--wizard-border);
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 {
font-family: "CaslonAntique", serif;
color: var(--wizard-accent-magic);
font-size: 1.2rem;
margin: 1.5rem 0 1rem;
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-content p {
font-family: "CaslonAntique", serif;
color: var(--wizard-text-body);
font-size: 1rem;
line-height: 1.6;
margin: 0.8rem 0;
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-content .caracs-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 0.1rem;
background: rgba(0, 0, 0, 0.15);
padding: 0.2rem;
border-radius: 4px;
border: 1px solid var(--wizard-border);
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-content .caracs-grid .carac-ligne {
display: flex;
align-items: center;
padding: 0.1rem 0.3rem;
border-bottom: 1px solid rgba(191, 149, 63, 0.1);
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-content .caracs-grid .carac-ligne label {
font-family: "CaslonAntique", serif;
color: var(--wizard-bg-primary) !important;
flex: 1;
font-weight: 500;
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-content .caracs-grid .carac-ligne input {
background: var(--wizard-bg-secondary);
border: 1px solid var(--wizard-border);
color: var(--wizard-text-primary);
font-family: "CaslonAntique", serif;
width: 5rem;
text-align: center;
padding: 0.2rem;
border-radius: 4px;
font-weight: bold;
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-content .caracs-grid .carac-ligne input:focus {
border-color: var(--wizard-accent-gold);
box-shadow: 0 0 8px rgba(212, 175, 55, 0.5);
outline: none;
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-content .caracs-derivees {
justify-content: space-around;
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-content .caracs-derivees .form-group {
text-align: center;
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-content .caracs-derivees .form-group label {
font-family: "CaslonAntique", serif;
color: var(--wizard-bg-primary) !important;
font-weight: 500;
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-content .caracs-derivees .form-group span {
font-family: "CaslonAntique", serif;
color: var(--wizard-accent-gold);
font-weight: bold;
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-content .budget-label {
display: inline-block;
background: var(--wizard-bg-secondary);
border: 1px solid var(--wizard-border);
padding: 0.3rem 0.8rem;
border-radius: 20px;
margin-right: 0.5rem;
font-family: "CaslonAntique", serif;
color: var(--wizard-text-primary);
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-content .budget-label strong {
color: var(--wizard-accent-gold);
font-weight: bold;
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-content .liste-competences-creation,
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-content .liste-sorts-creation {
list-style: none;
margin: 0;
padding: 0;
overflow-y: auto;
flex: 1;
min-height: 0;
background: rgba(0, 0, 0, 0.05);
border-radius: 4px;
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-content .liste-competences-creation .competence-header,
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-content .liste-sorts-creation .competence-header {
background: var(--wizard-bg-secondary);
font-family: "MedievalSharp", serif;
font-size: 0.9rem;
color: var(--wizard-accent-gold);
text-transform: uppercase;
letter-spacing: 1px;
padding: 0.5rem 0.8rem;
border-bottom: 1px solid var(--wizard-border);
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-content .liste-competences-creation .list-item,
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-content .liste-sorts-creation .list-item {
display: flex;
padding: 0.15rem 0.3rem;
transition: background 0.2s ease;
align-items: center;
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-content .liste-competences-creation .list-item:hover,
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-content .liste-sorts-creation .list-item:hover {
background: rgba(212, 175, 55, 0.1);
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-content .liste-competences-creation .list-item.inaccessible,
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-content .liste-sorts-creation .list-item.inaccessible {
opacity: 0.4;
background: rgba(128, 128, 128, 0.1);
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-content .liste-competences-creation .list-item.draconic,
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-content .liste-sorts-creation .list-item.draconic {
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,
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-content .liste-sorts-creation .sort-nom {
font-family: "CaslonAntique", serif;
flex: 3;
color: var(--wizard-bg-primary) !important;
font-weight: 500;
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-content .liste-competences-creation .comp-cat,
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-content .liste-sorts-creation .comp-cat,
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-content .liste-competences-creation .comp-base,
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-content .liste-sorts-creation .comp-base,
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-content .liste-competences-creation .sort-voie,
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-content .liste-sorts-creation .sort-voie,
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-content .liste-competences-creation .sort-diff,
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-content .liste-sorts-creation .sort-diff {
font-family: "CaslonAntique", serif;
font-size: 0.85rem;
flex: 1;
text-align: center;
color: var(--wizard-text-secondary);
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-content .liste-competences-creation .comp-niveau,
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-content .liste-sorts-creation .comp-niveau {
flex: 1;
text-align: center;
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-content .liste-competences-creation .comp-niveau select,
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-content .liste-sorts-creation .comp-niveau select {
background: var(--wizard-bg-secondary);
border: 1px solid var(--wizard-border);
color: var(--wizard-text-primary);
font-family: "CaslonAntique", serif;
padding: 0.2rem;
border-radius: 3px;
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-content .liste-competences-creation .comp-cout,
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-content .liste-sorts-creation .comp-cout,
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-content .liste-competences-creation .sort-cout,
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-content .liste-sorts-creation .sort-cout {
flex: 1;
text-align: right;
font-family: "GrenzeGotisch", serif;
color: var(--wizard-accent-gold);
font-weight: bold;
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-content .liste-competences-creation .sort-check-col,
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-content .liste-sorts-creation .sort-check-col {
flex: 0.5;
text-align: center;
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-content .attr-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 0.6rem 1rem;
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-content .attr-grid .form-group {
display: flex;
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-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 {
background: var(--wizard-bg-secondary);
border: 1px solid var(--wizard-border);
color: var(--wizard-text-primary);
font-family: "CaslonAntique", serif;
padding: 0.3rem 0.5rem;
border-radius: 4px;
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,
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-content .attr-grid .form-group select:focus {
border-color: var(--wizard-accent-gold);
box-shadow: 0 0 8px rgba(212, 175, 55, 0.5);
outline: none;
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-content .attr-grid .form-group textarea {
min-height: 80px;
resize: vertical;
font-family: "CaslonAntique", serif;
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-content .signe-input {
width: 100%;
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-content .attr-input {
width: 100%;
}
.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));
gap: 0.5rem;
margin-top: 0.5rem;
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-content .archetype-grid .archetype-card {
display: flex;
flex-direction: column;
align-items: center;
gap: 0.3rem;
padding: 0.5rem;
border: 1px solid var(--color-border-light-tertiary);
border-radius: 0.3rem;
cursor: pointer;
text-align: center;
background: rgba(0, 0, 0, 0.06);
transition: background 0.15s, border-color 0.15s;
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-content .archetype-grid .archetype-card:hover {
background: rgba(0, 0, 0, 0.12);
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-content .archetype-grid .archetype-card.selected {
border-color: var(--wizard-accent-gold);
background: var(--wizard-step-active);
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-content .archetype-grid .archetype-card img {
width: 4.5rem;
height: 4.5rem;
object-fit: cover;
border-radius: 0.2rem;
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-content .archetype-grid .archetype-card .archetype-name {
font-size: 0.85rem;
line-height: 1.1;
min-height: 2.2rem;
display: flex;
align-items: center;
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-content .archetype-lock {
margin-left: 0.5rem;
font-style: italic;
color: var(--wizard-accent-dream);
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-content .equip-header {
margin-bottom: 0.5rem;
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-content .equip-header .budget-labels {
justify-content: space-between;
margin-top: 0.3rem;
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-content .equip-filtres {
gap: 0.5rem;
margin-bottom: 0.5rem;
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-content .equip-filtres select {
width: 12rem;
}
.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;
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-content .equip-arborescence .equip-type.hidden {
display: none;
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-content .equip-arborescence .equip-type-header {
display: flex;
align-items: center;
gap: 0.4rem;
padding: 0.25rem 0.4rem;
background: rgba(0, 0, 0, 0.08);
border-radius: 0.2rem;
cursor: pointer;
user-select: none;
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-content .equip-arborescence .equip-type-header:hover {
background: rgba(0, 0, 0, 0.14);
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-content .equip-arborescence .equip-type-header .equip-type-count {
color: var(--color-text-dark-secondary);
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-content .equip-arborescence .equip-type-list {
list-style: none;
margin: 0;
padding: 0;
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-content .equip-arborescence .equip-type-list.collapsed {
display: none;
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-content .equip-arborescence .equip-type-list .equip-ligne {
display: flex;
align-items: center;
padding: 0.15rem 0.3rem;
border-bottom: 1px solid var(--color-border-light-tertiary);
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-content .equip-arborescence .equip-type-list .equip-ligne.hidden {
display: none;
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-content .equip-arborescence .equip-type-list .equip-ligne.equip-header-ligne {
font-weight: bold;
border-bottom: 1px solid var(--color-border-light-tertiary);
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-content .equip-arborescence .equip-type-list .equip-ligne .equip-nom {
flex: 3;
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-content .equip-arborescence .equip-type-list .equip-ligne .equip-cout,
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-content .equip-arborescence .equip-type-list .equip-ligne .equip-enc,
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-content .equip-arborescence .equip-type-list .equip-ligne .equip-total {
flex: 1;
text-align: center;
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-content .equip-arborescence .equip-type-list .equip-ligne .equip-qte-col {
flex: 1.4;
display: flex;
align-items: center;
justify-content: center;
gap: 0.15rem;
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-content .equip-arborescence .equip-type-list .equip-ligne .equip-qte-col button {
width: 1.4rem;
height: 1.4rem;
padding: 0;
display: inline-flex;
align-items: center;
justify-content: center;
cursor: pointer;
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-content .equip-arborescence .equip-type-list .equip-ligne .equip-qte-col input {
width: 3rem;
text-align: center;
}
.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;
padding-left: 1.2rem;
list-style: none;
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-warning li {
padding: 0.15rem 0;
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-erreurs {
margin: 0.5rem 0;
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-erreurs ul {
margin: 0;
padding-left: 1.2rem;
list-style: none;
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-erreurs li {
color: var(--wizard-flag-error);
padding: 0.3rem 0;
font-family: "CaslonAntique", serif;
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-buttons {
background: var(--wizard-bg-secondary);
padding: 0.4rem 0.6rem;
border-top: 1px solid var(--wizard-border);
justify-content: flex-end;
gap: 0.5rem;
margin-top: 0.25rem;
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-buttons button {
font-family: "MedievalSharp", serif;
font-size: 0.9rem;
letter-spacing: 0.5px;
padding: 0.25rem 1rem;
border: 1px solid var(--wizard-border);
border-radius: 4px;
cursor: pointer;
transition: all 0.3s ease;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
/* Bouton Précédent */
/* Boutons Suivant/Terminer */
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-buttons button[data-action="previous"] {
background: #999 !important;
color: #000 !important;
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-buttons button[data-action="previous"]:hover:not(:disabled) {
background: #aaa !important;
transform: translateY(-2px);
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.4);
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-buttons button[data-action="next"],
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-buttons button[data-action="finish"] {
background: #D4AF37 !important;
color: #000 !important;
font-weight: bold;
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-buttons button[data-action="next"]:hover:not(:disabled),
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-buttons button[data-action="finish"]:hover:not(:disabled) {
background: #F0D78C !important;
transform: translateY(-2px);
box-shadow: 0 0 15px rgba(212, 175, 55, 0.5);
text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.3);
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-buttons button:disabled {
opacity: 0.4;
cursor: not-allowed;
transform: none;
box-shadow: none;
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .recap-section {
background: rgba(0, 0, 0, 0.1);
border: 1px solid var(--wizard-border);
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;
color: var(--wizard-accent-gold);
border-bottom: 1px solid var(--wizard-border);
padding-bottom: 0.5rem;
margin: 0 0 1rem;
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .recap-section .recap-list {
padding-left: 1.5rem;
list-style: none;
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .recap-section .recap-list li {
padding: 0.3rem 0;
border-bottom: 1px solid rgba(191, 149, 63, 0.1);
font-family: "CaslonAntique", serif;
color: var(--wizard-text-body);
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .recap-section p {
font-family: "CaslonAntique", serif;
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);
}
50% {
box-shadow: 0 0 15px rgba(212, 175, 55, 0.8);
}
100% {
box-shadow: 0 0 5px rgba(212, 175, 55, 0.5);
}
}
@keyframes shake {
0%,
100% {
transform: translateX(0);
}
25% {
transform: translateX(-5px);
}
75% {
transform: translateX(5px);
}
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .wizard-step.active .step-num {
animation: pulse-glow 2s ease-in-out infinite;
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage [data-tooltip] {
position: relative;
cursor: help;
border-bottom: 1px dotted var(--wizard-border);
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage [data-tooltip]:hover::after {
content: attr(data-tooltip);
position: absolute;
bottom: 100%;
left: 50%;
transform: translateX(-50%);
background: var(--wizard-bg-secondary);
color: var(--wizard-text-primary);
border: 1px solid var(--wizard-border);
padding: 0.5rem 0.8rem;
border-radius: 4px;
font-size: 0.85rem;
font-family: "CaslonAntique", serif;
white-space: nowrap;
z-index: 100;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.4);
}
.system-foundryvtt-reve-de-dragon .rdd-creation-personnage .form-group {
margin: 0;
}
+18
View File
@@ -63,4 +63,22 @@ body {
hsla(60, 12%, 85%, 0.75) 1rem,
hsla(60, 12%, 85%, 0.8) 1rem,
hsla(60, 12%, 85%, 0.75) 1.5rem);
/* =================== WIZARD CREATION PERSONNAGE ============ */
// Couleurs spécifiques au wizard de création
--wizard-bg-primary: rgba(20, 18, 15, 0.95);
--wizard-bg-secondary: rgba(35, 30, 25, 0.9);
--wizard-accent-gold: #D4AF37;
--wizard-accent-dream: #6A5ACD;
--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);
--wizard-step-pending: rgba(128, 128, 128, 0.2);
--wizard-flag-success: #2a8a2a;
--wizard-flag-warning: #ffa500;
--wizard-flag-error: #ff4444;
}
+795
View File
@@ -3144,4 +3144,799 @@
button.creer-resultat { background: #2a8a2a; color: #fff; border: none; border-radius: 0.2rem; }
}
}
/* ======================================================================
WIZARD DE CREATION DE PERSONNAGE - THEME "REVE EVEILLE"
====================================================================== */
.rdd-creation-personnage {
/* 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: 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: 0.5rem 1rem;
border-bottom: 2px solid var(--wizard-border);
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.3);
align-items: center;
gap: 1rem;
h2 {
font-family: "MedievalSharp", serif;
font-size: 1.3rem;
color: var(--wizard-accent-gold);
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.5);
margin: 0;
flex: 0 0 auto;
}
input[name="name"] {
flex: 1;
background: var(--wizard-bg-secondary);
border: 1px solid var(--wizard-border);
color: var(--wizard-text-primary);
font-family: "CaslonAntique", serif;
font-size: 1.1rem;
padding: 0.5rem 1rem;
border-radius: 4px;
box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.2);
&::placeholder {
color: var(--wizard-text-secondary);
font-style: italic;
}
&:focus {
border-color: var(--wizard-accent-gold);
box-shadow: 0 0 8px rgba(212, 175, 55, 0.5), inset 0 2px 4px rgba(0, 0, 0, 0.2);
outline: none;
}
}
}
/* ==================== BARRE DE PROGRESSION ==================== */
.wizard-progress {
background: var(--wizard-bg-secondary);
padding: 0.4rem 1rem;
border-bottom: 1px solid var(--wizard-border);
position: relative;
justify-content: space-between;
/* Lignes de connexion entre étapes - effet "chemin de rêve" */
&::before {
content: '';
position: absolute;
top: 50%;
left: 10%;
right: 10%;
height: 2px;
background: linear-gradient(90deg,
transparent, var(--wizard-border), transparent);
z-index: 0;
}
.wizard-step {
position: relative;
z-index: 1;
cursor: pointer;
transition: all 0.3s ease;
display: flex;
flex-direction: column;
align-items: center;
padding: 0.2rem 0.5rem;
flex: 1;
.step-icon {
display: none;
}
.step-num {
display: inline-flex;
align-items: center;
justify-content: center;
width: 1.5rem;
height: 1.5rem;
border-radius: 50%;
background: var(--wizard-bg-secondary);
border: 1px solid var(--wizard-border);
color: var(--wizard-text-secondary);
font-family: "GrenzeGotisch", serif;
font-weight: bold;
font-size: 0.85rem;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);
transition: all 0.3s ease;
margin-bottom: 0.15rem;
}
.step-label {
font-family: "CaslonAntique", serif;
font-size: 0.7rem;
color: var(--wizard-text-secondary);
white-space: nowrap;
text-align: center;
line-height: 1.2;
}
/* Etat ACTIF */
&.active {
.step-num {
background: var(--wizard-accent-gold);
color: var(--wizard-bg-primary);
border-color: var(--wizard-accent-gold);
box-shadow: 0 0 10px rgba(212, 175, 55, 0.7);
transform: scale(1.1);
}
.step-label {
color: var(--wizard-text-primary);
font-weight: bold;
}
}
/* Etat TERMINE */
&.done {
.step-num {
background: var(--wizard-accent-dream);
border-color: var(--wizard-accent-dream);
color: white;
box-shadow: 0 0 8px rgba(106, 90, 205, 0.5);
}
.step-label {
color: var(--wizard-accent-dream);
font-weight: 500;
}
}
/* Etat EN ATTENTE */
&.pending {
opacity: 0.6;
.step-num {
background: var(--wizard-bg-secondary);
border-color: var(--wizard-step-pending);
}
.step-label {
color: var(--wizard-text-secondary);
}
}
/* Effet de survol */
&:hover:not(.pending) {
.step-num {
transform: scale(1.05);
box-shadow: 0 0 12px rgba(212, 175, 55, 0.6);
}
}
}
}
/* ==================== CONTENU PRINCIPAL ==================== */
.wizard-content {
flex: 1;
padding-right: 0.5rem;
display: flex;
flex-direction: column;
overflow-y: auto;
/* Fond avec texture subtile */
background: var(--wizard-bg-primary);
background-image: url('../assets/ui/bg_left.webp');
background-size: cover;
background-position: center;
background-repeat: no-repeat;
border: 1px solid var(--wizard-border);
border-radius: 4px;
padding: 1rem;
margin: 1rem 0;
/* Typographie hiérarchisée */
h3 {
font-family: "MedievalSharp", serif;
color: var(--wizard-accent-gold);
font-size: 1.15rem;
border-bottom: 1px solid var(--wizard-border);
padding-bottom: 0.25rem;
margin: 0.25rem 0 0.5rem;
text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.3);
}
h4 {
font-family: "CaslonAntique", serif;
color: var(--wizard-accent-magic);
font-size: 1.2rem;
margin: 1.5rem 0 1rem;
}
p {
font-family: "CaslonAntique", serif;
color: var(--wizard-text-body);
font-size: 1rem;
line-height: 1.6;
margin: 0.8rem 0;
}
/* Grille des caractéristiques - style "tableau de rune" */
.caracs-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 0.1rem;
background: rgba(0, 0, 0, 0.15);
padding: 0.2rem;
border-radius: 4px;
border: 1px solid var(--wizard-border);
.carac-ligne {
display: flex;
align-items: center;
padding: 0.1rem 0.3rem;
border-bottom: 1px solid rgba(191, 149, 63, 0.1);
label {
font-family: "CaslonAntique", serif;
color: var(--wizard-bg-primary) !important;
flex: 1;
font-weight: 500;
}
input {
background: var(--wizard-bg-secondary);
border: 1px solid var(--wizard-border);
color: var(--wizard-text-primary);
font-family: "CaslonAntique", serif;
width: 5rem;
text-align: center;
padding: 0.2rem;
border-radius: 4px;
font-weight: bold;
&:focus {
border-color: var(--wizard-accent-gold);
box-shadow: 0 0 8px rgba(212, 175, 55, 0.5);
outline: none;
}
}
}
}
.caracs-derivees {
justify-content: space-around;
.form-group {
text-align: center;
label {
font-family: "CaslonAntique", serif;
color: var(--wizard-bg-primary) !important;
font-weight: 500;
}
span {
font-family: "CaslonAntique", serif;
color: var(--wizard-accent-gold);
font-weight: bold;
}
}
}
/* Budget et indicateurs - style "compteur de rêves" */
.budget-label {
display: inline-block;
background: var(--wizard-bg-secondary);
border: 1px solid var(--wizard-border);
padding: 0.3rem 0.8rem;
border-radius: 20px;
margin-right: 0.5rem;
font-family: "CaslonAntique", serif;
color: var(--wizard-text-primary);
strong {
color: var(--wizard-accent-gold);
font-weight: bold;
}
}
/* Listes de compétences et sorts */
.liste-competences-creation, .liste-sorts-creation {
list-style: none;
margin: 0;
padding: 0;
overflow-y: auto;
flex: 1;
min-height: 0;
background: rgba(0, 0, 0, 0.05);
border-radius: 4px;
.competence-header {
background: var(--wizard-bg-secondary);
font-family: "MedievalSharp", serif;
font-size: 0.9rem;
color: var(--wizard-accent-gold);
text-transform: uppercase;
letter-spacing: 1px;
padding: 0.5rem 0.8rem;
border-bottom: 1px solid var(--wizard-border);
}
.list-item {
display: flex;
padding: 0.15rem 0.3rem;
transition: background 0.2s ease;
align-items: center;
&:hover {
background: rgba(212, 175, 55, 0.1);
}
&.inaccessible {
opacity: 0.4;
background: rgba(128, 128, 128, 0.1);
}
&.draconic {
background: linear-gradient(135deg,
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 {
font-family: "CaslonAntique", serif;
flex: 3;
color: var(--wizard-bg-primary) !important;
font-weight: 500;
}
.comp-cat, .comp-base, .sort-voie, .sort-diff {
font-family: "CaslonAntique", serif;
font-size: 0.85rem;
flex: 1;
text-align: center;
color: var(--wizard-text-secondary);
}
.comp-niveau {
flex: 1;
text-align: center;
select {
background: var(--wizard-bg-secondary);
border: 1px solid var(--wizard-border);
color: var(--wizard-text-primary);
font-family: "CaslonAntique", serif;
padding: 0.2rem;
border-radius: 3px;
}
}
.comp-cout, .sort-cout {
flex: 1;
text-align: right;
font-family: "GrenzeGotisch", serif;
color: var(--wizard-accent-gold);
font-weight: bold;
}
.sort-check-col {
flex: 0.5;
text-align: center;
}
}
/* Grille d'attributs */
.attr-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 0.6rem 1rem;
.form-group {
display: flex;
flex-direction: row;
align-items: center;
gap: 0.5rem;
label {
font-family: "CaslonAntique", serif;
color: var(--wizard-text-body);
font-weight: 500;
flex: 0 0 7.5rem;
}
input, select {
background: var(--wizard-bg-secondary);
border: 1px solid var(--wizard-border);
color: var(--wizard-text-primary);
font-family: "CaslonAntique", serif;
padding: 0.3rem 0.5rem;
border-radius: 4px;
flex: 1;
min-width: 0;
box-sizing: border-box;
&:focus {
border-color: var(--wizard-accent-gold);
box-shadow: 0 0 8px rgba(212, 175, 55, 0.5);
outline: none;
}
}
textarea {
min-height: 80px;
resize: vertical;
font-family: "CaslonAntique", serif;
}
}
}
.signe-input { width: 100%; }
.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));
gap: 0.5rem;
margin-top: 0.5rem;
.archetype-card {
display: flex;
flex-direction: column;
align-items: center;
gap: 0.3rem;
padding: 0.5rem;
border: 1px solid var(--color-border-light-tertiary);
border-radius: 0.3rem;
cursor: pointer;
text-align: center;
background: rgba(0, 0, 0, 0.06);
transition: background 0.15s, border-color 0.15s;
&:hover { background: rgba(0, 0, 0, 0.12); }
&.selected {
border-color: var(--wizard-accent-gold);
background: var(--wizard-step-active);
}
img {
width: 4.5rem;
height: 4.5rem;
object-fit: cover;
border-radius: 0.2rem;
}
.archetype-name {
font-size: 0.85rem;
line-height: 1.1;
min-height: 2.2rem;
display: flex;
align-items: center;
}
}
}
.archetype-lock {
margin-left: 0.5rem;
font-style: italic;
color: var(--wizard-accent-dream);
}
.equip-header {
margin-bottom: 0.5rem;
.budget-labels {
justify-content: space-between;
margin-top: 0.3rem;
}
}
.equip-filtres {
gap: 0.5rem;
margin-bottom: 0.5rem;
select { width: 12rem; }
input { flex: 1; }
}
.equip-arborescence {
flex: 1;
min-height: 12rem;
overflow-y: auto;
.equip-type {
margin-bottom: 0.3rem;
&.hidden { display: none; }
}
.equip-type-header {
display: flex;
align-items: center;
gap: 0.4rem;
padding: 0.25rem 0.4rem;
background: rgba(0, 0, 0, 0.08);
border-radius: 0.2rem;
cursor: pointer;
user-select: none;
&:hover { background: rgba(0, 0, 0, 0.14); }
.equip-type-count { color: var(--color-text-dark-secondary); }
}
.equip-type-list {
list-style: none;
margin: 0;
padding: 0;
&.collapsed { display: none; }
.equip-ligne {
display: flex;
align-items: center;
padding: 0.15rem 0.3rem;
border-bottom: 1px solid var(--color-border-light-tertiary);
&.hidden { display: none; }
&.equip-header-ligne {
font-weight: bold;
border-bottom: 1px solid var(--color-border-light-tertiary);
}
.equip-nom { flex: 3; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.equip-cout, .equip-enc, .equip-total { flex: 1; text-align: center; }
.equip-qte-col {
flex: 1.4;
display: flex;
align-items: center;
justify-content: center;
gap: 0.15rem;
button {
width: 1.4rem;
height: 1.4rem;
padding: 0;
display: inline-flex;
align-items: center;
justify-content: center;
cursor: pointer;
}
input { width: 3rem; text-align: center; }
}
}
}
}
}
/* ==================== ERREURS ==================== */
.wizard-warning {
margin: 0.5rem 0;
max-height: 6rem;
overflow-y: auto;
flex-shrink: 0;
ul {
margin: 0;
padding-left: 1.2rem;
list-style: none;
}
li {
padding: 0.15rem 0;
}
}
.wizard-erreurs {
margin: 0.5rem 0;
ul {
margin: 0;
padding-left: 1.2rem;
list-style: none;
}
li {
color: var(--wizard-flag-error);
padding: 0.3rem 0;
font-family: "CaslonAntique", serif;
}
}
/* ==================== BOUTONS DE NAVIGATION ==================== */
.wizard-buttons {
background: var(--wizard-bg-secondary);
padding: 0.4rem 0.6rem;
border-top: 1px solid var(--wizard-border);
justify-content: flex-end;
gap: 0.5rem;
margin-top: 0.25rem;
button {
font-family: "MedievalSharp", serif;
font-size: 0.9rem;
letter-spacing: 0.5px;
padding: 0.25rem 1rem;
border: 1px solid var(--wizard-border);
border-radius: 4px;
cursor: pointer;
transition: all 0.3s ease;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
/* Bouton Précédent */
&[data-action="previous"] {
background: #999 !important;
color: #000 !important;
&:hover:not(:disabled) {
background: #aaa !important;
transform: translateY(-2px);
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.4);
}
}
/* Boutons Suivant/Terminer */
&[data-action="next"], &[data-action="finish"] {
background: #D4AF37 !important;
color: #000 !important;
font-weight: bold;
&:hover:not(:disabled) {
background: #F0D78C !important;
transform: translateY(-2px);
box-shadow: 0 0 15px rgba(212, 175, 55, 0.5);
text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.3);
}
}
&:disabled {
opacity: 0.4;
cursor: not-allowed;
transform: none;
box-shadow: none;
}
}
}
/* ==================== SECTION RECAPITULATIF ==================== */
.recap-section {
background: rgba(0, 0, 0, 0.1);
border: 1px solid var(--wizard-border);
border-radius: 4px;
padding: 1rem;
margin-bottom: 1.5rem;
h4 {
font-family: "MedievalSharp", serif;
color: var(--wizard-accent-gold);
border-bottom: 1px solid var(--wizard-border);
padding-bottom: 0.5rem;
margin: 0 0 1rem;
}
.recap-list {
padding-left: 1.5rem;
list-style: none;
li {
padding: 0.3rem 0;
border-bottom: 1px solid rgba(191, 149, 63, 0.1);
font-family: "CaslonAntique", serif;
color: var(--wizard-text-body);
}
}
p {
font-family: "CaslonAntique", serif;
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 ==================== */
@keyframes pulse-glow {
0% { box-shadow: 0 0 5px rgba(212, 175, 55, 0.5); }
50% { box-shadow: 0 0 15px rgba(212, 175, 55, 0.8); }
100% { box-shadow: 0 0 5px rgba(212, 175, 55, 0.5); }
}
@keyframes shake {
0%, 100% { transform: translateX(0); }
25% { transform: translateX(-5px); }
75% { transform: translateX(5px); }
}
/* Effet de lueur pour l'étape active */
.wizard-step.active .step-num {
animation: pulse-glow 2s ease-in-out infinite;
}
/* Tooltips contextuelles */
[data-tooltip] {
position: relative;
cursor: help;
border-bottom: 1px dotted var(--wizard-border);
}
[data-tooltip]:hover::after {
content: attr(data-tooltip);
position: absolute;
bottom: 100%;
left: 50%;
transform: translateX(-50%);
background: var(--wizard-bg-secondary);
color: var(--wizard-text-primary);
border: 1px solid var(--wizard-border);
padding: 0.5rem 0.8rem;
border-radius: 4px;
font-size: 0.85rem;
font-family: "CaslonAntique", serif;
white-space: nowrap;
z-index: 100;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.4);
}
/* Form group styling - Supprimé pour réduire espacements */
.form-group {
margin: 0;
}
}
}
+12 -10
View File
@@ -221,14 +221,18 @@ export class RdDActor extends RdDBaseActorSang {
if (toUpdate.length > 0) {
console.log('perte de rêve des enchantements', toUpdate)
const messageUpdates = await Promise.all(
toUpdate.map(async it => await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-pertereve-enchantement-chateaudormant.hbs`, it)))
await ChatMessage.create({
whisper: ChatUtility.getOwners(this),
content: messageUpdates.reduce(Misc.joining('<br>'))
})
if (message) {
message.content += messageUpdates.reduce(Misc.joining(' ')) + ' '
message.content += toUpdate
.map(it => {
const type = it.item.type === 'potion' ? 'potion' : 'gemme'
const nouveaupr = it.nouveaupr ?? it.item.system.pr
let texte = `La ${type} enchantée ${it.item.name} de ${it.alias} a perdu un Point de Rêve (nouveau total : ${nouveaupr}).`
if (type === 'potion' && nouveaupr === 0) {
texte += ` Sa potion étant désormais à 0 Point de Rêve, elle est inutilisable et peut être jetée.`
}
return texte
})
.reduce(Misc.joining(' ')) + ' '
}
await this.updateEmbeddedDocuments('Item', toUpdate.map(it => it.update));
}
@@ -399,9 +403,7 @@ export class RdDActor extends RdDBaseActorSang {
}
async setInfoSommeilInsomnie() {
if (EffetsDraconiques.isSujetInsomnie(this)) {
await this.update({ 'system.sommeil.insomnie': true });
}
await this.update({ 'system.sommeil.insomnie': EffetsDraconiques.isSujetInsomnie(this) });
}
async setInfoSommeilMoral(situationMoral) {
+126
View File
@@ -0,0 +1,126 @@
/**
* Table des coûts de création de personnage.
*
* Donne le nombre de points d'expérience préliminaire à dépenser pour atteindre
* un niveau visé depuis la base de la compétence. Cette table est spécifique à
* la création (elle diffère légèrement de la table d'XP cumulative utilisée en
* jeu). Source : regles/regles_creation_personnage.txt.
*
* Lignes : niveau visé (de -10 à +3).
* Colonnes : base de la compétence (-11, -8, -6, -4).
* Valeur : points à dépenser pour passer de la base au niveau visé.
*/
const TABLE_COUT_CREATION = {
// niveau visé : { '-11': cout, '-8': cout, '-6': cout, '-4': cout }
'-10': { '-11': 5, '-8': 0, '-6': 0, '-4': 0 },
'-9': { '-11': 10, '-8': 0, '-6': 0, '-4': 0 },
'-8': { '-11': 15, '-8': 0, '-6': 0, '-4': 0 },
'-7': { '-11': 25, '-8': 10, '-6': 0, '-4': 0 },
'-6': { '-11': 35, '-8': 20, '-6': 0, '-4': 0 },
'-5': { '-11': 45, '-8': 30, '-6': 10, '-4': 0 },
'-4': { '-11': 55, '-8': 40, '-6': 20, '-4': 0 },
'-3': { '-11': 70, '-8': 55, '-6': 35, '-4': 15 },
'-2': { '-11': 85, '-8': 70, '-6': 50, '-4': 30 },
'-1': { '-11': 100, '-8': 85, '-6': 65, '-4': 45 },
'0': { '-11': 115, '-8': 100, '-6': 80, '-4': 60 },
'+1': { '-11': 135, '-8': 120, '-6': 100, '-4': 80 },
'+2': { '-11': 155, '-8': 140, '-6': 120, '-4': 100 },
'+3': { '-11': 175, '-8': 160, '-6': 140, '-4': 120 },
}
const NIVEAUX_CREATION = ['-10', '-9', '-8', '-7', '-6', '-5', '-4', '-3', '-2', '-1', '0', '+1', '+2', '+3']
const NIVEAU_MAX_CREATION = 3
const BASES = [-11, -8, -6, -4]
/**
* Coût en points préliminaires pour atteindre un niveau depuis une base.
* @param {number} base - niveau de base de la compétence (-11, -8, -6, -4)
* @param {number} niveau - niveau visé (entre base et +3)
* @returns {number} points à dépenser (0 si niveau <= base)
*/
export function coutPourAtteindre(base, niveau) {
if (niveau <= base) return 0
const col = String(base)
const lig = formatNiveau(niveau)
const cout = TABLE_COUT_CREATION[lig]?.[col]
if (cout === undefined) {
throw new Error(`Coût de création non défini pour base=${base}, niveau=${niveau}`)
}
return cout
}
/**
* Liste des niveaux accessibles à la création pour une compétence de base donnée.
* @param {number} base
* @returns {number[]} niveaux de base jusqu'à +3
*/
export function niveauxAccessibles(base) {
const result = []
for (let n = base; n <= NIVEAU_MAX_CREATION; n++) {
result.push(n)
}
return result
}
/**
* Coût total d'une compétence à la création.
* Thanatos coûte le double (le surplus détruit des points dans une autre voie).
* @param {object} competence - item compétence (avec system.base, system.niveau, system.categorie)
* @param {number} niveau - niveau visé
* @returns {number} points à dépenser
*/
export function coutCompetenceCreation(competence, niveau) {
const base = competence.system.base
const cout = coutPourAtteindre(base, niveau)
const isThanatos = competence.name?.toLowerCase().includes('thanatos')
return isThanatos ? cout * 2 : cout
}
/**
* Coût d'un sort à la création.
* Sort à difficulté variable : 70 points.
* Sinon : |difficulte| × 10.
* @param {object} sort - item sort
* @returns {number}
*/
export function coutSortCreation(sort) {
const diff = String(sort.system.difficulte).toLowerCase()
if (diff === 'variable') return 70
return Math.abs(Number(sort.system.difficulte)) * 10
}
/**
* Vérifie si un sort est accessible à la création selon le niveau de Draconic.
* Règle : difficulté du sort <= niveau Draconic + 3.
* Les sorts nécessitant un grimoire ne sont pas accessibles (à filtrer en amont).
* @param {object} sort
* @param {number} niveauDraconic - niveau de la voie correspondante
* @returns {boolean}
*/
export function sortAccessible(sort, niveauDraconic) {
const diff = String(sort.system.difficulte).toLowerCase()
if (diff === 'variable') {
// Annulation de magie : forfait 70, accessible si une voie connue >= 0
return niveauDraconic >= 0
}
const difficulte = Math.abs(Number(sort.system.difficulte))
return difficulte <= niveauDraconic + 3
}
function formatNiveau(n) {
if (n > 0) return `+${n}`
return String(n)
}
export const COUT_CREATION = {
TABLE_COUT_CREATION,
NIVEAUX_CREATION,
NIVEAU_MAX_CREATION,
BASES,
coutPourAtteindre,
niveauxAccessibles,
coutCompetenceCreation,
coutSortCreation,
sortAccessible,
}
File diff suppressed because it is too large Load Diff
+1
View File
@@ -100,6 +100,7 @@ export class RdDItemGemme extends RdDItem {
return {
alias: this.parent.getAlias(),
item: this,
nouveaupr: nouveauReve,
update: {
_id: this.id,
'system.pr': nouveauReve,
+14
View File
@@ -62,6 +62,7 @@ import { RdDTMRDialog } from "./rdd-tmr-dialog.js"
import { OptionsAvancees } from "./settings/options-avancees.js"
import { ExportScriptarium } from "./actor/export-scriptarium/export-scriptarium.js"
import { AppPersonnageAleatoire } from "./actor/random/app-personnage-aleatoire.js"
import { CreationPersonnageWizard } from "./actor/creation/creation-personnage-wizard.mjs"
import { RdDStatBlockParser } from "./apps/rdd-import-stats.js"
import { RdDJournalSheet } from "./journal/journal-sheet.mjs"
import { RdDCombat } from "./combat/rdd-combat.js"
@@ -461,6 +462,19 @@ export class SystemReveDeDragon {
}
this.setupAccueil()
Hooks.on("renderActorDirectory", (app, html) => {
const header = html.querySelector ? html.querySelector(".header-actions") : html.find(".header-actions")
if (header && !header.querySelector(".creation-wizard-btn")) {
const btn = document.createElement("button")
btn.type = "button"
btn.className = "creation-wizard-btn"
btn.innerHTML = `<i class="fa-solid fa-wand-magic-sparkles" inert></i><span>Créer (wizard)</span>`
btn.addEventListener("click", () => new CreationPersonnageWizard().render({ force: true }))
header.appendChild(btn)
}
})
ui.actors?.render({ force: true })
}
async setupAccueil() {
+2 -1
View File
@@ -1,10 +1,11 @@
import { renderTemplate } from "../constants.js"
import { EffetsDraconiques } from "../tmr/effets-draconiques.js"
export class DialogNouveauReposCD {
static async prompt(actor) {
const date = game.system.rdd.calendrier.dateCourante()
let moralChoisi = actor.system.sommeil?.moral ?? "neutre"
const data = { name: actor.name, moral: moralChoisi }
const data = { name: actor.name, moral: moralChoisi, insomnie: EffetsDraconiques.isSujetInsomnie(actor) }
const content = await renderTemplate(
"systems/foundryvtt-reve-de-dragon/templates/sommeil/dialog-nouveau-repos-cd.hbs",
data
+25 -5
View File
@@ -1,6 +1,8 @@
import { renderTemplate } from "../constants.js"
import { RdDTimestamp, RDD_HEURES_PAR_JOUR } from "../time/rdd-timestamp.js"
import { ChatUtility } from "../chat-utility.js"
import { EffetsDraconiques } from "../tmr/effets-draconiques.js"
import { ReglesOptionnelles } from "../settings/regles-optionnelles.js"
import { DialogNouveauReposCD } from "./dialog-nouveau-repos-cd.js"
export class DialogNouveauRepos extends foundry.applications.api.DialogV2 {
@@ -9,10 +11,19 @@ export class DialogNouveauRepos extends foundry.applications.api.DialogV2 {
const now = game.system.rdd.calendrier.timestamp
const heureCourante = now.heure
const hourDefs = RdDTimestamp.definitions()
const insomnie = EffetsDraconiques.isSujetInsomnie(actor)
const repriseHeures = Math.max(actor.system.sommeil?.heures ?? 0, 0)
const data = {
name: actor.name, img: actor.img, hourDefinitions: hourDefs,
heureDebutDefaut: heureCourante,
heureFinDefaut: Math.min(heureCourante + 7, 11),
heureFinDefaut: repriseHeures > 0
? (heureCourante + repriseHeures - 1) % RDD_HEURES_PAR_JOUR
: Math.min(heureCourante + 7, 11),
insomnie,
repriseHeures,
}
if (!ReglesOptionnelles.isUsing("chateau-dormant-gardien") || !actor.isPersonnageJoueur()) {
await actor.update({ "system.sommeil.insomnie": insomnie })
}
const content = await renderTemplate("systems/foundryvtt-reve-de-dragon/templates/sommeil/dialog-nouveau-repos.hbs", data)
new DialogNouveauRepos(content, actor).render({ force: true })
@@ -126,7 +137,7 @@ export class DialogNouveauRepos extends foundry.applications.api.DialogV2 {
content: this.actor.name + ": "
}
const dormi = { heures: 0, etat: "dort", jetsReve: [] }
const insomnie = this.actor.system.sommeil?.insomnie || duree === 0
const insomnie = this.actor.system.sommeil?.insomnie || EffetsDraconiques.isSujetInsomnie(this.actor) || duree === 0
await this.actor.recupereEndurance({ message, demi: insomnie })
if (insomnie) {
message.content += "Vous ne trouvez pas le sommeil"
@@ -135,6 +146,7 @@ export class DialogNouveauRepos extends foundry.applications.api.DialogV2 {
if (!avaitFatigue && heureDebut >= 6 && heureDebut <= 11) {
duree = RDD_HEURES_PAR_JOUR - heureDebut + 1
}
await this.actor.update({ "system.sommeil": { heures: duree } })
let cdProcessed = false
let h = 0
while (true) {
@@ -142,12 +154,18 @@ export class DialogNouveauRepos extends foundry.applications.api.DialogV2 {
if (reveilForce && dormi.heures >= heuresForce) break
if (!avaitFatigue && h >= duree) break
if (avaitFatigue && this.actor.system.sante.fatigue.value <= this.actor.getFatigueMin()) break
if (avaitFatigue && EffetsDraconiques.isSujetInsomnie(this.actor)) break
await this.actor.$recupererEthylisme(message)
await this.actor.$recupererFatigue(message)
await this.actor.$jetRecuperationReve(dormi, message)
if (!EffetsDraconiques.isSujetInsomnie(this.actor)) {
await this.actor.$recupererFatigue(message)
await this.actor.$jetRecuperationReve(dormi, message)
if (dormi.etat === "dort" && EffetsDraconiques.isDonDoubleReve(this.actor)) {
await this.actor.$jetRecuperationReve(dormi, message)
}
}
dormi.heures++
if (dormi.etat !== "dort") break
if (h % RDD_HEURES_PAR_JOUR === RDD_HEURES_PAR_JOUR - 1 && !cdProcessed) {
if ((heureDebut + h) % RDD_HEURES_PAR_JOUR === RDD_HEURES_PAR_JOUR - 1 && !cdProcessed) {
cdProcessed = true
const cdData = await DialogNouveauReposCD.prompt(this.actor)
if (cdData.stress.valeur > 0) {
@@ -172,6 +190,8 @@ export class DialogNouveauRepos extends foundry.applications.api.DialogV2 {
}
if (dormi.etat === "eveil") {
await this.actor.reveilReveDeDragon(message, dormi.heures)
} else if (this.actor.system.sommeil?.heures) {
await this.actor.update({ "system.sommeil": { heures: 0 } })
}
message.content += `Vous avez dormi ${dormi.heures <= 1 ? "une heure" : (dormi.heures + " heures")}. `
}
+1 -1
View File
@@ -35,7 +35,7 @@
{{!-- Sheet Body --}}
<section class="sheet-body">
<div class="flexcol form-group medium-editor">
<div class="flexcol medium-editor">
<fieldset>
<div>
<label>Description :</label>
+368
View File
@@ -0,0 +1,368 @@
<form class="rdd-creation-personnage flexcol">
<div class="flexrow wizard-header">
<h2>Création de personnage</h2>
<input type="text" name="name" value="{{data.name}}" placeholder="Nom du personnage" />
</div>
<div class="wizard-progress flexrow">
{{#each etapes}}
<div class="wizard-step {{#if (eq ../step this.num)}}active{{/if}} {{#if (lt ../step this.num)}}pending{{/if}} {{#if (gt ../step this.num)}}done{{/if}}" data-tooltip="{{this.tooltip}}">
<i class="fas {{this.icon}} step-icon"></i>
<span class="step-num">{{this.num}}</span>
<span class="step-label">{{this.label}}</span>
</div>
{{/each}}
</div>
<div class="wizard-content">
{{!-- Étape 0 : Haut-Rêve --}}
{{#if (eq step 0)}}
<h3>Haut-Rêve ou non ?</h3>
<p>Avant de commencer la création, choix fondamental : votre personnage sera-t-il haut-rêvant (magicien) ou non ? Le don de haut-rêve s'acquiert dans l'enfance ; un personnage adulte n'aura pratiquement aucune chance de le devenir ensuite.</p>
<p>Le principe de création est identique, mais les haut-rêvants doivent réserver des points pour les compétences de magie (Draconic) et pour les sorts.</p>
<div class="form-group">
<label><input type="radio" name="hautRevant" value="false" {{#unless data.hautRevant}}checked{{/unless}} {{#if data.archetype}}disabled{{/if}} /> Non haut-rêvant</label>
<label><input type="radio" name="hautRevant" value="true" {{#if data.hautRevant}}checked{{/if}} {{#if data.archetype}}disabled{{/if}} /> Haut-rêvant</label>
{{#if data.archetype}}<span class="archetype-lock">(archétype sélectionné : choix verrouillé)</span>{{/if}}
</div>
<h3>Archétype (Voyageurs)</h3>
<p>Vous pouvez bâtir votre personnage sur un archétype du compendium Voyageurs : ses caractéristiques, compétences, sorts, équipement et fortune seront pré-remplis, puis personnalisables.</p>
<div class="archetype-grid">
<div class="archetype-card {{#unless data.archetype}}selected{{/unless}}" data-archetype-id="">
<img src="systems/foundryvtt-reve-de-dragon/icons/voyageurs/personnage.webp" alt="Aucun" />
<span class="archetype-name">Création libre</span>
</div>
{{#each voyageurs}}
<div class="archetype-card {{#if (eq ../data.archetype.id this.id)}}selected{{/if}}" data-archetype-id="{{this.id}}">
<img src="{{this.img}}" alt="{{this.name}}" />
<span class="archetype-name">{{this.name}}</span>
</div>
{{/each}}
</div>
{{#if data.equipement.nonMappes.length}}
<div class="wizard-warning notification warning">
<strong>Éléments de l'archétype « {{data.archetype.name}} » non retrouvés dans les compendiums :</strong>
<ul>
{{#each data.equipement.nonMappes}}
<li>{{this}}</li>
{{/each}}
</ul>
</div>
{{/if}}
{{/if}}
{{!-- Étape 1 : Caractéristiques --}}
{{#if (eq step 1)}}
<h3>Caractéristiques (160 points)</h3>
<p>Répartissez librement 160 points entre les 14 caractéristiques (moyenne 11,4). Aucune ne peut être inférieure à 6 ni supérieure à 15. La FORCE ne peut dépasser TAILLE+4. La Beauté a un minimum de 10 ; au-delà de 10, chaque point est prélevé sur les 160.</p>
<div class="form-group">
<span class="budget-label">Total : <strong id="budget-caracs-total">{{budgetCaracs.total}}</strong> / 160</span>
<span class="budget-label">Restant : <strong id="budget-caracs-restant">{{budgetCaracs.restant}}</strong></span>
</div>
<div class="caracs-grid">
{{#each caracsPrimaires}}
<div class="form-group carac-ligne">
<label>{{lookup ../labelsCaracs this}}</label>
<input type="number" class="carac-input" data-carac="{{this}}" value="{{lookup ../data.caracs this}}" min="6" max="15" />
</div>
{{/each}}
<div class="form-group carac-ligne">
<label>Beauté</label>
<input type="number" class="carac-input" data-carac="beaute" value="{{data.beaute}}" min="10" max="16" />
</div>
</div>
<h4>Caractéristiques dérivées</h4>
<div id="caracs-derivees" class="caracs-derivees flexrow">
{{#each caracsDerivees}}
<div class="form-group">
<label>{{lookup ../labelsCaracs this}}</label>
<span data-carac="{{this}}">{{lookup ../caracsDeriveesCalculees this}}</span>
</div>
{{/each}}
</div>
{{/if}}
{{!-- Étape 2 : Compétences --}}
{{#if (eq step 2)}}
<h3>Compétences (3000 points)</h3>
<p>Disposez de 3000 points d'expérience préliminaire dans les compétences. Aucune ne peut dépasser +3. Les compétences de catégorie Draconic ne sont accessibles que si vous êtes haut-rêvant. Thanatos coûte le double. Les survies ne peuvent dépasser Survie en Extérieur tant que celle-ci n'a pas atteint 0.</p>
<div class="form-group">
<span class="budget-label">Compétences dépensé : <strong id="budget-competences-depense">{{budgetCompetences.depense}}</strong></span>
<span class="budget-label">Restant (avec sorts) : <strong id="budget-competences-restant">{{budgetCompetences.restant}}</strong></span>
</div>
<ul class="item-list alterne-list liste-competences-creation">
<li class="competence-header flexrow">
<span class="comp-nom">Nom</span>
<span class="comp-cat">Catégorie</span>
<span class="comp-base">Base</span>
<span class="comp-niveau">Niveau</span>
<span class="comp-cout">Coût</span>
</li>
{{#each competences}}
<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>
<span class="comp-niveau">
<select class="niveau-comp" data-comp-id="{{this._id}}" {{#if (and this.isDraconic (not ../data.hautRevant))}}disabled{{/if}}>
{{#each this.niveauxAccessibles}}
<option value="{{this}}" {{#if (eq this ../this.system.niveau)}}selected{{/if}}>{{this}}</option>
{{/each}}
</select>
</span>
<span class="comp-cout">{{this.cout}}</span>
</li>
{{/each}}
</ul>
{{/if}}
{{!-- Étape 3 : Sorts --}}
{{#if (eq step 3)}}
<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> / {{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">
<span class="sort-check-col"></span>
<span class="sort-nom">Sort</span>
<span class="sort-voie">Voie</span>
<span class="sort-diff">Diff.</span>
<span class="sort-cout">Coût</span>
</li>
{{#each sorts}}
<li class="item flexrow list-item {{#unless this.accessible}}inaccessible{{/unless}}">
<span class="sort-check-col">
<input type="checkbox" class="sort-check" data-sort-id="{{this._id}}" {{#if (array-includes ../sortsChoisis this._id)}}checked{{/if}} {{#unless this.accessible}}disabled{{/unless}} />
</span>
<span class="sort-nom">{{this.name}}</span>
<span class="sort-voie">{{this.system.draconic}}</span>
<span class="sort-diff">{{this.system.difficulte}}</span>
<span class="sort-cout">{{this.cout}}</span>
</li>
{{/each}}
</ul>
{{/if}}
{{!-- Étape 4 : Attributs du personnage --}}
{{#if (eq step 4)}}
<h3>Attributs du personnage</h3>
<p>Saisissez librement les attributs physiques et la description de votre personnage.</p>
<div class="attr-grid">
<div class="form-group">
<label>Sexe</label>
<select class="attr-input" data-attr="sexe">
<option value="">—</option>
<option value="masculin" {{#if (eq data.attributs.sexe "masculin")}}selected{{/if}}>Masculin</option>
<option value="féminin" {{#if (eq data.attributs.sexe "féminin")}}selected{{/if}}>Féminin</option>
</select>
</div>
<div class="form-group">
<label>Âge</label>
<input type="text" class="attr-input" data-attr="age" value="{{data.attributs.age}}" placeholder="ex: 25" />
</div>
<div class="form-group">
<label>Taille</label>
<input type="text" class="attr-input" data-attr="taille" value="{{data.attributs.taille}}" placeholder="ex: 1m75" />
</div>
<div class="form-group">
<label>Poids</label>
<input type="text" class="attr-input" data-attr="poids" value="{{data.attributs.poids}}" placeholder="ex: 70 kg" />
</div>
<div class="form-group">
<label>Yeux</label>
<input type="text" class="attr-input" data-attr="yeux" value="{{data.attributs.yeux}}" placeholder="ex: bleus" />
</div>
<div class="form-group">
<label>Cheveux</label>
<input type="text" class="attr-input" data-attr="cheveux" value="{{data.attributs.cheveux}}" placeholder="ex: bruns" />
</div>
<div class="form-group">
<label>Main directrice</label>
<select class="attr-input" data-attr="main">
<option value="droitier" {{#if (eq data.attributs.main "droitier")}}selected{{/if}}>Droitier</option>
<option value="gaucher" {{#if (eq data.attributs.main "gaucher")}}selected{{/if}}>Gaucher</option>
<option value="ambidextre" {{#if (eq data.attributs.main "ambidextre")}}selected{{/if}}>Ambidextre</option>
</select>
</div>
<div class="form-group">
<label>Heure de naissance</label>
<input type="text" class="attr-input" data-attr="heure" value="{{data.attributs.heure}}" placeholder="ex: Vaisseau" />
</div>
</div>
<div class="form-group">
<label>Biographie</label>
<textarea class="attr-input" data-attr="biographie" rows="3">{{data.attributs.biographie}}</textarea>
</div>
<div class="form-group">
<label>Description</label>
<textarea class="attr-input" data-attr="description" rows="3">{{data.attributs.description}}</textarea>
</div>
{{/if}}
{{!-- Étape 5 : Équipement & Richesse --}}
{{#if (eq step 5)}}
<h3>Équipement & Richesse de départ</h3>
<p>Votre personnage commence avec une fortune de {{FORTUNE_DEFAUT}} sols (ajustable). Achetez vos vêtements, armes et équipement, puis gardez le reste en espèces.</p>
{{#if data.equipement.nonMappes.length}}
<div class="wizard-warning notification warning">
<strong>Éléments de l'archétype non retrouvés dans les compendiums :</strong>
<ul>
{{#each data.equipement.nonMappes}}
<li>{{this}}</li>
{{/each}}
</ul>
</div>
{{/if}}
<div class="equip-header">
<div class="form-group">
<label>Fortune (sols)</label>
<input type="number" name="fortune" value="{{data.equipement.fortune}}" min="0" step="0.5" />
</div>
<div class="budget-labels flexrow">
<span>Fortune : <strong id="budget-equip-fortune">{{budgetEquipement.fortune}}</strong> sols</span>
<span>Équipement dépensé : <strong id="budget-equip-depense">{{budgetEquipement.depense}}</strong> sols</span>
<span>Restant : <strong id="budget-equip-restant">{{budgetEquipement.restant}}</strong> sols</span>
<span>Encombrement : <strong id="encombrement-equip">{{encombrementEquipement.total}} / {{encombrementEquipement.max}}</strong></span>
</div>
</div>
<div class="equip-filtres flexrow">
<select name="filtre-type">
<option value="tous" {{#if (eq data.equipement.filtreType "tous")}}selected{{/if}}>Tous les types</option>
{{#each typesEquipement}}
<option value="{{this}}" {{#if (eq ../data.equipement.filtreType this)}}selected{{/if}}>{{this}}</option>
{{/each}}
</select>
<input type="text" name="recherche-equip" value="{{data.equipement.recherche}}" placeholder="Rechercher un équipement..." />
</div>
<div class="equip-arborescence">
{{#each groupes}}
<div class="equip-type" data-type="{{this.type}}">
<div class="equip-type-header" data-type="{{this.type}}">
<i class="fa-solid fa-chevron-right"></i>
<span class="equip-type-name">{{this.type}}</span>
<span class="equip-type-count">({{this.items.length}})</span>
</div>
<ul class="equip-type-list">
<li class="equip-ligne equip-header-ligne">
<span class="equip-nom">Nom</span>
<span class="equip-cout">Coût</span>
<span class="equip-enc">Enc.</span>
<span class="equip-qte-col">Qté</span>
<span class="equip-total">Total</span>
</li>
{{#each this.items}}
<li class="equip-ligne" data-name="{{this.name}}">
<span class="equip-nom">{{this.name}}</span>
<span class="equip-cout">{{this.cout}} s</span>
<span class="equip-enc">{{this.encombrement}}</span>
<span class="equip-qte-col">
<button type="button" class="equip-qte-moins" data-item-id="{{this._id}}"></button>
<input type="number" class="equip-qte" data-item-id="{{this._id}}" value="{{this.quantite}}" min="0" />
<button type="button" class="equip-qte-plus" data-item-id="{{this._id}}">+</button>
</span>
<span class="equip-total">{{this.depense}} s</span>
</li>
{{/each}}
</ul>
</div>
{{/each}}
</div>
{{/if}}
{{!-- Étape 6 : Récapitulatif --}}
{{#if (eq step 6)}}
<h3>Récapitulatif</h3>
<div class="recap-section">
<h4>Identité</h4>
<p><strong>Nom :</strong> {{data.name}}</p>
<p><strong>Haut-rêvant :</strong> {{#if data.hautRevant}}Oui{{else}}Non{{/if}}</p>
{{#if data.archetype}}<p><strong>Archétype :</strong> {{data.archetype.name}}</p>{{/if}}
</div>
<div class="recap-section">
<h4>Caractéristiques</h4>
<div class="flexrow recup-caracs">
{{#each caracsPrimaires}}
<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}}
<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}}
<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>
<div class="recap-section">
<h4>Compétences</h4>
<p>Dépensé : {{budgetCompetences.depense}} / {{TOTAL_XP_PRELIMINAIRE}} — Restant : {{budgetCompetences.restant}} (en XP)</p>
<ul class="recap-list">
{{#each competencesModifiees}}
<li>{{this.name}} ({{this.system.base}}{{this.system.niveau}}) : {{this.cout}} pts</li>
{{/each}}
</ul>
</div>
{{#if data.hautRevant}}
<div class="recap-section">
<h4>Sorts</h4>
<p>Dépensé : {{budgetSorts.depense}} / {{MAX_XP_SORTS}}</p>
<ul class="recap-list">
{{#each sortsChoisisDetail}}
<li>{{this.name}} ({{this.system.draconic}} R{{this.system.difficulte}}) : {{this.cout}} pts</li>
{{/each}}
</ul>
</div>
{{/if}}
{{#if (or data.attributs.sexe data.attributs.age data.attributs.taille data.attributs.poids data.attributs.yeux data.attributs.cheveux data.attributs.heure)}}
<div class="recap-section">
<h4>Attributs</h4>
{{#if data.attributs.sexe}}<p>Sexe : {{data.attributs.sexe}}</p>{{/if}}
{{#if data.attributs.age}}<p>Âge : {{data.attributs.age}}</p>{{/if}}
{{#if data.attributs.taille}}<p>Taille : {{data.attributs.taille}}</p>{{/if}}
{{#if data.attributs.poids}}<p>Poids : {{data.attributs.poids}}</p>{{/if}}
{{#if data.attributs.yeux}}<p>Yeux : {{data.attributs.yeux}}</p>{{/if}}
{{#if data.attributs.cheveux}}<p>Cheveux : {{data.attributs.cheveux}}</p>{{/if}}
{{#if data.attributs.main}}<p>Main : {{data.attributs.main}}</p>{{/if}}
{{#if data.attributs.heure}}<p>Heure de naissance : {{data.attributs.heure}}</p>{{/if}}
</div>
{{/if}}
<div class="recap-section">
<h4>Équipement & Richesse</h4>
<p>Fortune : {{budgetEquipement.fortune}} sols — Dépensé : {{budgetEquipement.depense}} sols — Restant : {{budgetEquipement.restant}} sols</p>
{{#if equipementChoisi.length}}
<ul class="recap-list">
{{#each equipementChoisi}}
<li>{{this.name}} × {{this.quantite}} : {{this.depense}} sols</li>
{{/each}}
</ul>
{{else}}
<p>Aucun équipement choisi.</p>
{{/if}}
</div>
{{/if}}
</div>
<div class="wizard-buttons flexrow">
{{#if (gt step 0)}}
<button type="button" data-action="previous">Précédent</button>
{{/if}}
{{#if (lt step 6)}}
<button type="button" data-action="next" {{#unless etapeValide}}disabled{{/unless}}>Suivant</button>
{{else}}
<button type="button" data-action="finish" {{#unless etapeValide}}disabled{{/unless}}>Terminer</button>
{{/if}}
</div>
</form>
@@ -1,8 +0,0 @@
<h4><img class="chat-icon" src="{{item.img}}" data-tooltip="{{item.name}}" />
La {{item.type}} enchantée {{item.name}} de {{alias}} a perdu un Point de Rêve (nouveau total : {{nouveaupr}}).</h4>
<hr>
<p>
{{#if (and (eq item.type 'potion') (eq nouveaupr 0))}}
Sa {{item.type}} étant désormais à 0 Point de Rêve, elle est inutilisable et peut être jetée.
{{/if}}
</p>
@@ -2,6 +2,9 @@
<div class="flexcol">
<h2>Château Dormant — {{name}}</h2>
<p>La nuit touche à sa fin. Renseignez les informations pour le passage à Vaisseau.</p>
{{#if insomnie}}
<p class="notification warning">Nuit d'insomnie (Queue de Dragon) : aucun sommeil n'est récupéré.</p>
{{/if}}
<div class="form-group">
<label>Points de stress du jour</label>
<input type="number" name="cd-stress" value="0" min="0" max="200">
+11 -1
View File
@@ -17,9 +17,19 @@
<div class="form-group">
<span>Durée : <strong><span id="duree-sommeil">0</span> heures</strong></span>
</div>
{{#if repriseHeures}}
<div id="avertissements-reprise">
<p class="notification info">Reprise de nuit : {{repriseHeures}} heures restantes après votre Rêve de Dragon.</p>
</div>
{{/if}}
{{#if insomnie}}
<div id="avertissements-insomnie">
<p class="notification warning">Insomnie cette nuit (Queue de Dragon) : vous ne trouverez pas le sommeil.</p>
</div>
{{/if}}
<div class="form-group">
<input type="checkbox" name="reveil-force" id="reveil-force">
<label for="reveil-force">Réveil forcé après</label>
<label for="reveil-force" data-tooltip="Vous serez réveillé après ce nombre d'heures, même si votre fatigue n'est pas totalement récupérée.">Réveil forcé après</label>
<input type="number" name="heures-force" value="1" min="1" max="12" disabled>
<span>heures</span>
</div>
View File
View File