Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 09f2349bab | |||
| d8eb23289e | |||
| 820a7d61cf | |||
| 755c349078 | |||
| 8fb27c2e82 | |||
| 98cf0bf8fd | |||
| 7d218f4a0a | |||
| 06b0ff7f78 | |||
| c6ddc96148 | |||
| 6883cc1020 | |||
| 1d6e6dd44e |
@@ -24,9 +24,20 @@ jobs:
|
||||
env:
|
||||
version: ${{ steps.get_version.outputs.version-without-v }}
|
||||
url: https://www.uberwald.me/gitea/${{ gitea.repository }}
|
||||
manifest: https://www.uberwald.me/gitea/public/fvtt-donjon-et-cie/releases/download/latest/system.json
|
||||
manifest: https://www.uberwald.me/gitea/uberwald/fvtt-donjon-et-cie/releases/download/latest/system.json
|
||||
download: https://www.uberwald.me/gitea/${{ gitea.repository }}/releases/download/${{ github.event.release.tag_name }}/fvtt-donjon-et-cie.zip
|
||||
|
||||
- name: Setup Node
|
||||
uses: https://github.com/actions/setup-node@v4
|
||||
with:
|
||||
node-version: 24
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
|
||||
- name: Build system and pack compendiums
|
||||
run: npm run build
|
||||
|
||||
- run: |
|
||||
apt update -y
|
||||
apt install -y zip
|
||||
@@ -53,7 +64,7 @@ jobs:
|
||||
token: ${{ secrets.FOUNDRYVTT_RELEASE_TOKEN }}
|
||||
id: "fvtt-donjon-et-cie"
|
||||
version: ${{ github.event.release.tag_name }}
|
||||
manifest: "https://www.uberwald.me/gitea/public/fvtt-donjon-et-cie/releases/download/latest/system.json"
|
||||
manifest: "https://www.uberwald.me/gitea/uberwald/fvtt-donjon-et-cie/releases/download/latest/system.json"
|
||||
notes: "https://www.uberwald.me/gitea/${{ gitea.repository }}/releases/download/${{ github.event.release.tag_name }}/fvtt-donjon-et-cie.zip"
|
||||
compatibility-minimum: "13"
|
||||
compatibility-verified: "14"
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 547 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 536 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 436 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 450 KiB |
+161
@@ -9,6 +9,7 @@
|
||||
"TYPES.Item.armure": "Armure",
|
||||
"TYPES.Item.equipement": "Equipement",
|
||||
"TYPES.Item.consommable": "Consommable",
|
||||
"TYPES.Item.entrainement": "Entrainement",
|
||||
"DNC.Roll.Characteristic": "Jet de caracteristique",
|
||||
"DNC.Roll.Attack": "Jet d'attaque",
|
||||
"DNC.Roll.Damage": "Jet de degats",
|
||||
@@ -23,6 +24,166 @@
|
||||
"DNC.Chat.SelectTarget": "Choisissez une cible presente sur la scene.",
|
||||
"DNC.Chat.TargetUnavailable": "La cible selectionnee n'est plus disponible.",
|
||||
"DNC.Chat.InvalidDamageTarget": "Impossible d'appliquer les degats a cette cible.",
|
||||
"DNC.Chat.Kicker.Resolution": "Resolution",
|
||||
"DNC.Chat.Kicker.Magic": "Magie",
|
||||
"DNC.Chat.Kicker.Wear": "Usure",
|
||||
"DNC.Chat.Kicker.Network": "Reseau",
|
||||
"DNC.Chat.Kicker.Logistics": "Logistique",
|
||||
"DNC.Chat.Kicker.Initiative": "Ordre de marche",
|
||||
"DNC.Chat.Success": "Reussite",
|
||||
"DNC.Chat.Failure": "Echec",
|
||||
"DNC.Chat.Favor": "Faveur",
|
||||
"DNC.Chat.Target": "Cible",
|
||||
"DNC.Chat.Kept": "Garde",
|
||||
"DNC.Chat.Rolls": "Lancers",
|
||||
"DNC.Chat.RollDamage": "Lancer les degats",
|
||||
"DNC.Chat.RollValue": "Jet",
|
||||
"DNC.Chat.AutoDisadvantage": "Desavantage automatique",
|
||||
"DNC.Chat.RiskChaos": "Risquer le Chaos",
|
||||
"DNC.Chat.Result": "Resultat",
|
||||
"DNC.Chat.Before": "Avant",
|
||||
"DNC.Chat.After": "Apres",
|
||||
"DNC.Chat.Total": "Total",
|
||||
"DNC.Chat.Bonus": "Bonus",
|
||||
"DNC.Chat.CombatSynced": "Combat synchronise",
|
||||
"DNC.Chat.TargetValue": "Valeur cible",
|
||||
"DNC.Chat.FavorDie": "De de faveur",
|
||||
"DNC.Chat.CharacteristicValue": "Valeur de la caracteristique",
|
||||
"DNC.Chat.HpCost": "Cout en PV",
|
||||
"DNC.Chat.FocusSpent": "Focus depense",
|
||||
"DNC.Chat.FocusRemaining": "Focus restant",
|
||||
"DNC.Chat.HpSpent": "PV depenses",
|
||||
"DNC.Chat.HpRemaining": "PV restants",
|
||||
"DNC.Chat.CasterRank": "Rang du lanceur",
|
||||
"DNC.Chat.Difficulty": "Difficulte",
|
||||
"DNC.Chat.Effect": "Effet",
|
||||
"DNC.Chat.StoredProtection": "Protection stockee pour ce combat",
|
||||
"DNC.Chat.ResourceWearsDown": "La ressource s'amenuise.",
|
||||
"DNC.Chat.ResourceStable": "La ressource tient bon.",
|
||||
"DNC.Chat.ResourceExhausted": "La ressource est epuisee.",
|
||||
"DNC.Chat.AutoDisadvantageCanceled": "le cout du sort depasse le rang du lanceur, mais une faveur l'a annule.",
|
||||
"DNC.Chat.AutoDisadvantageApplies": "le cout du sort depasse le rang du lanceur.",
|
||||
"DNC.Chat.FocusFrom": "depuis",
|
||||
"DNC.Chat.FocusUsed": "utilise",
|
||||
"DNC.Chat.FocusLeft": "restant",
|
||||
"DNC.Chat.FocusDropsTo": "le focus descend a",
|
||||
"DNC.Chat.FirstSpellScene": "premier sort de la scene",
|
||||
"DNC.Chat.FocusNoBenefit": "aucun apport pour cette scene.",
|
||||
"DNC.Chat.ChaosSubtitle": "La magie opere malgre l'echec ; le MJ determine les consequences.",
|
||||
"DNC.Chat.SpellMaintained": "Sort maintenu",
|
||||
"DNC.Chat.ChaosDieDrops": "Le de du Chaos descend d'un cran.",
|
||||
"DNC.Chat.ChaosDieExhausted": "Le de du Chaos est trop faible pour etre reutilise dans le Donjon.",
|
||||
"DNC.UI.Mode": "Mode",
|
||||
"DNC.UI.ModeNormal": "Normal",
|
||||
"DNC.UI.ModeAdvantage": "Avantage",
|
||||
"DNC.UI.ModeDisadvantage": "Desavantage",
|
||||
"DNC.UI.FavorBoost": "Coup de pouce",
|
||||
"DNC.UI.NoFavor": "Aucune faveur",
|
||||
"DNC.UI.RollAction": "Lancer",
|
||||
"DNC.UI.AttackAction": "Attaquer",
|
||||
"DNC.UI.UseAction": "Utiliser",
|
||||
"DNC.UI.Characteristic": "Caracteristique",
|
||||
"DNC.UI.Cost": "Cout",
|
||||
"DNC.UI.CurrentHp": "PV actuels",
|
||||
"DNC.UI.Rank": "Rang",
|
||||
"DNC.UI.Focus": "Focus",
|
||||
"DNC.UI.Chaos": "Chaos",
|
||||
"DNC.UI.Weapon": "Arme",
|
||||
"DNC.UI.Damage": "Degats",
|
||||
"DNC.UI.Range": "Portee",
|
||||
"DNC.UI.Spell": "Sortilege",
|
||||
"DNC.Dialog.InitiativeIntro": "<strong>{actorName}</strong> lance l'initiative.",
|
||||
"DNC.Dialog.InitiativeCurrent": "DEX actuelle : <strong>{dex}</strong>, bonus de fiche : <strong>{initiativeBonus}</strong>",
|
||||
"DNC.Dialog.CharacteristicUsed": "Caracteristique utilisee",
|
||||
"DNC.Dialog.ActorDamageBonus": "Bonus de degats de l'acteur",
|
||||
"DNC.Dialog.SpellAutoDisadvantage": "Le cout depasse le rang du lanceur : le jet se fera automatiquement avec desavantage.",
|
||||
"DNC.Dialog.UseUsageDie": "Utiliser <strong>{itemName}</strong> et lancer son de d'usage actuel.",
|
||||
"DNC.Dialog.CurrentValue": "Valeur actuelle",
|
||||
"DNC.Warn.NoFavorAvailable": "Aucune faveur disponible pour {label}.",
|
||||
"DNC.Warn.SpellInsufficientResources": "Le lanceur ne dispose pas d'assez de PV et de focus pour payer ce sort.",
|
||||
"DNC.Warn.ChaosUnavailable": "Le Chaos n'est pas disponible pour ce sort.",
|
||||
"DNC.Warn.TrainingExhausted": "Cet entrainement est epuise pour aujourd'hui. Reinitialisez son delta quotidien pour le lendemain.",
|
||||
"DNC.Settings.MissionPackMode.Name": "Mode de paquetage de mission",
|
||||
"DNC.Settings.MissionPackMode.Hint": "Choisit entre le tirage classique rapide et la regle optionnelle de campagne avec allocation des des par les joueurs.",
|
||||
"DNC.Settings.MissionPackMode.Classic": "Classique",
|
||||
"DNC.Settings.MissionPackMode.Campaign": "Campagne",
|
||||
"DNC.Macro.MissionPack.Title": "Paquetage de debut de mission",
|
||||
"DNC.Macro.MissionPack.ItemsAdded": "Objets ajoutes",
|
||||
"DNC.Macro.MissionPack.ItemsMissing": "Objets manquants",
|
||||
"DNC.Macro.MissionPack.Missing": "Introuvables",
|
||||
"DNC.Macro.MissionPack.CompleteChatSummary": "L'integralite du paquetage a ete ajoutee a la fiche.",
|
||||
"DNC.Macro.MissionPack.PartialChatSummary": "Les elements trouves du paquetage ont ete ajoutes a la fiche.",
|
||||
"DNC.Macro.MissionPack.NoResult": "Aucun resultat exploitable",
|
||||
"DNC.Macro.MissionPack.TableMissing": "Table introuvable : {table}",
|
||||
"DNC.Macro.MissionPack.WarnNoActor": "Impossible de determiner l'employe cible. Selectionnez un token ou attribuez un personnage a l'utilisateur.",
|
||||
"DNC.Macro.MissionPack.WarnMultipleTokens": "Selectionnez un seul token pour attribuer le paquetage.",
|
||||
"DNC.Macro.MissionPack.WarnInvalidActor": "Le paquetage de mission ne peut etre attribue qu'a un employe.",
|
||||
"DNC.Macro.MissionPack.WarnNoEmployees": "Aucun employe n'est disponible pour recevoir un paquetage.",
|
||||
"DNC.Macro.MissionPack.WarnGMOnly": "Cette interface de paquetage est reservee au MJ.",
|
||||
"DNC.Macro.MissionPack.WarnNothingAdded": "Aucun objet du paquetage n'a pu etre ajoute a la fiche.",
|
||||
"DNC.Macro.MissionPack.Success": "{actor} recoit {count} objet(s) de paquetage.",
|
||||
"DNC.Macro.MissionPack.Partial": "{actor} recoit {count} objet(s), mais {missing} entree(s) du paquetage sont introuvables.",
|
||||
"DNC.Macro.MissionPack.DialogTitle": "Paquetage de mission",
|
||||
"DNC.Macro.MissionPack.DialogIntro": "Selectionnez l'employe qui recevra le paquetage de debut de mission, puis lancez le tirage.",
|
||||
"DNC.Macro.MissionPack.ActiveMode": "Mode :",
|
||||
"DNC.Macro.MissionPack.ModeClassic": "Classique",
|
||||
"DNC.Macro.MissionPack.ModeClassicHint": "Le systeme tire directement les 4 tables d equipement, comme dans les one-shots.",
|
||||
"DNC.Macro.MissionPack.ModeCampaign": "Campagne",
|
||||
"DNC.Macro.MissionPack.ModeCampaignHint": "Le joueur alloue 1d20, 1d12, 1d10 et 1d8 aux 4 categories, puis l anciennete est ajoutee a chaque resultat.",
|
||||
"DNC.Macro.MissionPack.DialogActor": "Employe",
|
||||
"DNC.Macro.MissionPack.DialogAction": "Generer le paquetage",
|
||||
"DNC.Macro.MissionPack.SidebarButton": "Paquetage",
|
||||
"DNC.Macro.MissionPack.CampaignDialogLead": "En mode campagne, le joueur proprietaire choisira l affectation de ses des dans un dialogue dedie.",
|
||||
"DNC.Macro.MissionPack.CampaignDialogTitle": "Paquetage de campagne",
|
||||
"DNC.Macro.MissionPack.CampaignDialogSubtitle": "Repartition logistique",
|
||||
"DNC.Macro.MissionPack.CampaignDialogIntro": "{actor} prepare son paquetage de campagne. Repartissez les des entre les categories, puis indiquez la relation a l econome.",
|
||||
"DNC.Macro.MissionPack.CampaignDialogAction": "Valider l allocation",
|
||||
"DNC.Macro.MissionPack.CampaignDialogPlayer": "Joueur",
|
||||
"DNC.Macro.MissionPack.CampaignDialogRequester": "Demande de",
|
||||
"DNC.Macro.MissionPack.CampaignDialogRank": "Anciennete",
|
||||
"DNC.Macro.MissionPack.CampaignDialogRelation": "Relation a l econome",
|
||||
"DNC.Macro.MissionPack.CampaignDialogAssignHelp": "Attribuez un de different a chaque categorie de paquetage.",
|
||||
"DNC.Macro.MissionPack.CampaignDialogHelp": "Le d20 alloue servira aussi pour verifier l equipement unique. L anciennete est ajoutee a chaque jet apres avantage ou desavantage.",
|
||||
"DNC.Macro.MissionPack.CampaignController": "Choix joueur :",
|
||||
"DNC.Macro.MissionPack.CampaignRelation": "Relation :",
|
||||
"DNC.Macro.MissionPack.CampaignRequestCanceled": "Le paquetage de campagne pour {actor} n a pas ete valide par {player}.",
|
||||
"DNC.Macro.MissionPack.WarnDiceRequired": "Attribuez un de a chacune des 4 categories du paquetage.",
|
||||
"DNC.Macro.MissionPack.WarnDiceUnique": "Chaque de ne peut etre utilise qu une seule fois.",
|
||||
"DNC.Macro.MissionPack.Relation.positive": "Positive",
|
||||
"DNC.Macro.MissionPack.Relation.neutral": "Neutre",
|
||||
"DNC.Macro.MissionPack.Relation.negative": "Negative",
|
||||
"DNC.Macro.MissionPack.RollDetail": "{die} · {mode} · lancers {values} · garde {kept} · + anciennete {rank} = {total}",
|
||||
"DNC.Macro.MissionPack.TotalClamped": "Total retenu sur la table : {clamped} (au lieu de {total}).",
|
||||
"DNC.Macro.MissionPack.melee": "Arme de corps a corps",
|
||||
"DNC.Macro.MissionPack.ranged": "Arme a distance",
|
||||
"DNC.Macro.MissionPack.armor": "Armure",
|
||||
"DNC.Macro.MissionPack.misc": "Encas et equipement divers",
|
||||
"DNC.Macro.MissionPack.UniqueReference": "d20 de reference",
|
||||
"DNC.Macro.MissionPack.UniqueActorRoll": "d20 du joueur",
|
||||
"DNC.Macro.MissionPack.UniqueMatch": "Objet unique",
|
||||
"DNC.Macro.MissionPack.UniqueMiss": "Pas d objet unique",
|
||||
"DNC.Macro.MissionPack.UniqueGranted": "Objet unique ajoute :",
|
||||
"DNC.Macro.MissionPack.UniqueTableRoll": "tirage d objet unique",
|
||||
"DNC.Macro.MissionPack.UniqueRuleReminder": "Aucun objet unique supplementaire cette fois ci.",
|
||||
"DNC.Welcome.Kicker": "Accueil",
|
||||
"DNC.Welcome.Title": "Bienvenue dans Donjon & Cie",
|
||||
"DNC.Welcome.Subtitle": "Systeme FoundryVTT · version {version}",
|
||||
"DNC.Welcome.Seal": "GUIDE",
|
||||
"DNC.Welcome.PillSheets": "Fiches Application V2",
|
||||
"DNC.Welcome.PillChat": "Jets et cartes de chat",
|
||||
"DNC.Welcome.PillHelp": "Aide integree",
|
||||
"DNC.Welcome.Intro": "Le systeme est pret : vous pouvez creer des employes, gerer les PNJ, lancer les jets et utiliser les outils MJ directement depuis l'interface.",
|
||||
"DNC.Welcome.BulletActors": "Les fiches Employe et PNJ couvrent les caracteristiques, ressources, objets et actions de jeu courantes.",
|
||||
"DNC.Welcome.BulletItems": "Les objets peuvent etre lances, postes dans le chat et utilises avec leur de d'usure quand c'est pertinent.",
|
||||
"DNC.Welcome.BulletMissionPack": "Le bouton Paquetage du repertoire des acteurs permet au MJ de generer rapidement l'equipement de debut de mission.",
|
||||
"DNC.Welcome.HelpLabel": "Aide du systeme :",
|
||||
"DNC.Welcome.HelpLinkLabel": "ouvrir le journal d'aide",
|
||||
"DNC.Welcome.HelpFallback": "le compendium d'aide systeme est disponible dans les Compendiums.",
|
||||
"DNC.Welcome.CreditsLabel": "Credits :",
|
||||
"DNC.Welcome.CreditsText": "systeme FoundryVTT par LeRatierBretonnien. Donjon & Cie est un jeu de role edite par John Doe.",
|
||||
"DNC.Welcome.OfficialLabel": "Page officielle :",
|
||||
"DNC.Welcome.OfficialLinkText": "johndoe-rpg.com/catalogue/donjon-cie/",
|
||||
"DNC.Welcome.Footer": "Commencez par ouvrir le journal d'aide si vous voulez un tour rapide des ecrans et des workflows du systeme.",
|
||||
"DNC.Sheet.Create": "Creer",
|
||||
"DNC.Sheet.Delete": "Supprimer",
|
||||
"DNC.Sheet.Edit": "Editer",
|
||||
|
||||
+77
-43
@@ -1,44 +1,44 @@
|
||||
.characteristic-list {
|
||||
.dnc-actor-sheet .characteristic-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: @spacing-sm;
|
||||
}
|
||||
|
||||
.characteristic-row {
|
||||
.dnc-actor-sheet .characteristic-row {
|
||||
display: grid;
|
||||
grid-template-columns: 2rem 1fr 4rem;
|
||||
gap: @spacing-sm;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.characteristic-label {
|
||||
.dnc-actor-sheet .characteristic-label {
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.profile-counters {
|
||||
.dnc-actor-sheet .profile-counters {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr;
|
||||
gap: @spacing-md;
|
||||
}
|
||||
|
||||
.profile-card-wide {
|
||||
.dnc-actor-sheet .profile-card-wide {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.profile-layout {
|
||||
.dnc-actor-sheet .profile-layout {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(0, 1.15fr) minmax(320px, 0.85fr);
|
||||
gap: @spacing-lg;
|
||||
align-items: start;
|
||||
}
|
||||
|
||||
.profile-column {
|
||||
.dnc-actor-sheet .profile-column {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: @spacing-md;
|
||||
}
|
||||
|
||||
.favor-card {
|
||||
.dnc-actor-sheet .favor-card {
|
||||
margin: @spacing-md 0;
|
||||
padding: @spacing-md;
|
||||
border: 1px dashed fade(@color-border, 55%);
|
||||
@@ -46,29 +46,29 @@
|
||||
background: fade(@color-panel-strong, 35%);
|
||||
}
|
||||
|
||||
.favor-header h2 {
|
||||
.dnc-actor-sheet .favor-header h2 {
|
||||
margin-bottom: @spacing-sm;
|
||||
}
|
||||
|
||||
.favor-help {
|
||||
.dnc-actor-sheet .favor-help {
|
||||
margin: 0 0 @spacing-md;
|
||||
color: @color-muted;
|
||||
font-size: 0.82rem;
|
||||
}
|
||||
|
||||
.favor-list {
|
||||
.dnc-actor-sheet .favor-list {
|
||||
display: grid;
|
||||
gap: @spacing-sm;
|
||||
}
|
||||
|
||||
.favor-row {
|
||||
.dnc-actor-sheet .favor-row {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(0, 1fr) 4.5rem auto;
|
||||
gap: @spacing-sm;
|
||||
align-items: end;
|
||||
}
|
||||
|
||||
.favor-meta {
|
||||
.dnc-actor-sheet .favor-meta {
|
||||
min-height: 2.3rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@@ -79,59 +79,59 @@
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.magic-layout {
|
||||
.dnc-actor-sheet .magic-layout {
|
||||
align-items: start;
|
||||
margin-bottom: @spacing-md;
|
||||
}
|
||||
|
||||
.magic-layout .sheet-column {
|
||||
.dnc-actor-sheet .magic-layout .sheet-column {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: @spacing-md;
|
||||
}
|
||||
|
||||
.magic-resource-grid {
|
||||
.dnc-actor-sheet .magic-resource-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
|
||||
gap: @spacing-md;
|
||||
align-items: end;
|
||||
}
|
||||
|
||||
.chaos-table-wrapper {
|
||||
.dnc-actor-sheet .chaos-table-wrapper {
|
||||
margin-top: @spacing-md;
|
||||
}
|
||||
|
||||
.chaos-table-wrapper h3 {
|
||||
.dnc-actor-sheet .chaos-table-wrapper h3 {
|
||||
margin: 0 0 @spacing-sm;
|
||||
font-size: 0.95rem;
|
||||
}
|
||||
|
||||
.chaos-table-caption {
|
||||
.dnc-actor-sheet .chaos-table-caption {
|
||||
margin: 0 0 @spacing-sm;
|
||||
color: @color-muted;
|
||||
font-size: 0.78rem;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.chaos-table {
|
||||
.dnc-actor-sheet .chaos-table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
|
||||
.chaos-table th,
|
||||
.chaos-table td {
|
||||
.dnc-actor-sheet .chaos-table th,
|
||||
.dnc-actor-sheet .chaos-table td {
|
||||
padding: 0.4rem 0.45rem;
|
||||
border: 1px solid fade(@color-border, 35%);
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.chaos-table th {
|
||||
.dnc-actor-sheet .chaos-table th {
|
||||
text-align: left;
|
||||
background: fade(@color-panel-strong, 55%);
|
||||
}
|
||||
|
||||
.sheet-tabs {
|
||||
.dnc-actor-sheet .sheet-tabs {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: @spacing-sm;
|
||||
@@ -139,7 +139,7 @@
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.sheet-tab {
|
||||
.dnc-actor-sheet .sheet-tab {
|
||||
border: 1px solid fade(@color-border, 80%);
|
||||
border-radius: @radius-md;
|
||||
background: fade(@color-panel-strong, 55%);
|
||||
@@ -148,32 +148,32 @@
|
||||
padding: @spacing-sm @spacing-md;
|
||||
}
|
||||
|
||||
.sheet-tab.active {
|
||||
.dnc-actor-sheet .sheet-tab.active {
|
||||
background: @color-accent;
|
||||
border-color: darken(@color-accent, 12%);
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.sheet-tab-panel {
|
||||
.dnc-actor-sheet .sheet-tab-panel {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.sheet-tab-panel.active {
|
||||
.dnc-actor-sheet .sheet-tab-panel.active {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.item-list {
|
||||
.dnc-actor-sheet .item-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: @spacing-md;
|
||||
}
|
||||
|
||||
.item-section.is-dragover {
|
||||
.dnc-actor-sheet .item-section.is-dragover {
|
||||
border-color: @color-accent;
|
||||
box-shadow: 0 0 0 2px fade(@color-accent, 20%);
|
||||
}
|
||||
|
||||
.item-dropzone {
|
||||
.dnc-actor-sheet .item-dropzone {
|
||||
border: 1px dashed fade(@color-border, 75%);
|
||||
border-radius: @radius-md;
|
||||
padding: @spacing-md;
|
||||
@@ -188,18 +188,18 @@
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.item-dropzone.has-items {
|
||||
.dnc-actor-sheet .item-dropzone.has-items {
|
||||
padding: @spacing-sm @spacing-md;
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
|
||||
.item-section.is-dragover .item-dropzone {
|
||||
.dnc-actor-sheet .item-section.is-dragover .item-dropzone {
|
||||
border-color: @color-accent;
|
||||
background: fade(@color-accent, 12%);
|
||||
color: @color-ink;
|
||||
}
|
||||
|
||||
.item {
|
||||
.dnc-actor-sheet .item {
|
||||
display: grid;
|
||||
grid-template-columns: 48px 1fr auto;
|
||||
gap: @spacing-md;
|
||||
@@ -208,12 +208,12 @@
|
||||
padding-top: @spacing-md;
|
||||
}
|
||||
|
||||
.item:first-child {
|
||||
.dnc-actor-sheet .item:first-child {
|
||||
border-top: 0;
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
.item img {
|
||||
.dnc-actor-sheet .item img {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
object-fit: cover;
|
||||
@@ -222,19 +222,19 @@
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.item-main p {
|
||||
.dnc-actor-sheet .item-main p {
|
||||
margin: @spacing-sm 0 0;
|
||||
color: @color-muted;
|
||||
}
|
||||
|
||||
.item-title-row {
|
||||
.dnc-actor-sheet .item-title-row {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: @spacing-sm;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.item-meta {
|
||||
.dnc-actor-sheet .item-meta {
|
||||
border-radius: 999px;
|
||||
background: @color-panel-strong;
|
||||
color: @color-ink;
|
||||
@@ -242,26 +242,60 @@
|
||||
padding: 0.1rem 0.5rem;
|
||||
}
|
||||
|
||||
.item-actions {
|
||||
.dnc-actor-sheet .item-actions {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: @spacing-sm;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.pnj-layout .sheet-column {
|
||||
.dnc-pnj-sheet .pnj-layout .sheet-column {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: @spacing-md;
|
||||
}
|
||||
|
||||
.pnj-combat-grid {
|
||||
.dnc-pnj-sheet .pnj-combat-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
gap: @spacing-md;
|
||||
align-items: end;
|
||||
}
|
||||
|
||||
.pnj-combat-grid .span-two {
|
||||
.dnc-pnj-sheet .pnj-combat-grid .span-two {
|
||||
grid-column: 1 / -1;
|
||||
}
|
||||
|
||||
.dnc-pnj-sheet .pnj-attack-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: @spacing-md;
|
||||
}
|
||||
|
||||
.dnc-pnj-sheet .pnj-attack-list .section-header {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.dnc-pnj-sheet .pnj-attack-list h3 {
|
||||
margin: 0;
|
||||
font-size: 0.95rem;
|
||||
color: @color-ink;
|
||||
}
|
||||
|
||||
.dnc-pnj-sheet .pnj-attack-rows {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: @spacing-md;
|
||||
}
|
||||
|
||||
.dnc-pnj-sheet .pnj-attack-row {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(0, 1fr) 4.5rem max-content;
|
||||
gap: @spacing-md;
|
||||
align-items: end;
|
||||
}
|
||||
|
||||
.dnc-pnj-sheet .pnj-attack-row .item-actions {
|
||||
align-self: end;
|
||||
gap: @spacing-sm;
|
||||
}
|
||||
|
||||
+31
-20
@@ -60,7 +60,7 @@
|
||||
padding: @spacing-lg;
|
||||
}
|
||||
|
||||
.sheet-card {
|
||||
.dnc-sheet .sheet-card {
|
||||
border: 2px solid @color-border;
|
||||
border-radius: @radius-md;
|
||||
background: rgba(255, 248, 236, 0.92);
|
||||
@@ -78,23 +78,23 @@
|
||||
letter-spacing: 0.04em;
|
||||
}
|
||||
|
||||
.sheet-header {
|
||||
.dnc-sheet .sheet-header {
|
||||
display: grid;
|
||||
grid-template-columns: 140px 1fr;
|
||||
gap: @spacing-lg;
|
||||
align-items: start;
|
||||
}
|
||||
|
||||
.sheet-header.compact {
|
||||
.dnc-sheet .sheet-header.compact {
|
||||
grid-template-columns: 110px 1fr;
|
||||
gap: @spacing-md;
|
||||
}
|
||||
|
||||
.portrait {
|
||||
.dnc-sheet .portrait {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.portrait img {
|
||||
.dnc-sheet .portrait img {
|
||||
width: 100%;
|
||||
aspect-ratio: 1;
|
||||
object-fit: cover;
|
||||
@@ -103,7 +103,7 @@
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.icon-button {
|
||||
.dnc-sheet .icon-button {
|
||||
position: absolute;
|
||||
right: @spacing-sm;
|
||||
bottom: @spacing-sm;
|
||||
@@ -115,14 +115,14 @@
|
||||
height: 2rem;
|
||||
}
|
||||
|
||||
.identity-grid,
|
||||
.identity-grid.two-columns {
|
||||
.dnc-sheet .identity-grid,
|
||||
.dnc-sheet .identity-grid.two-columns {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, minmax(0, 1fr));
|
||||
gap: @spacing-md;
|
||||
}
|
||||
|
||||
.identity-grid.two-columns {
|
||||
.dnc-sheet .identity-grid.two-columns {
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
}
|
||||
|
||||
@@ -135,12 +135,18 @@
|
||||
gap: 0.25rem;
|
||||
}
|
||||
|
||||
.dnc-employe-sheet .sheet-header.compact .hp-field {
|
||||
grid-column: span 2;
|
||||
}
|
||||
|
||||
.dnc-employe-sheet .sheet-header.compact input[type="number"] {
|
||||
max-width: 4.75rem;
|
||||
}
|
||||
|
||||
.dnc-employe-sheet .sheet-header.compact .counter-field input[type="number"] {
|
||||
max-width: 4rem;
|
||||
.dnc-employe-sheet .sheet-header.compact .counter-field input[name="system.sante.pv.value"],
|
||||
.dnc-employe-sheet .sheet-header.compact .counter-field input[name="system.sante.pv.max"] {
|
||||
width: 5.25rem;
|
||||
max-width: 5.25rem;
|
||||
}
|
||||
|
||||
.dnc-pnj-sheet .sheet-header.compact .identity-grid {
|
||||
@@ -152,14 +158,19 @@
|
||||
gap: 0.25rem;
|
||||
}
|
||||
|
||||
.dnc-pnj-sheet .sheet-header.compact .hp-field {
|
||||
grid-column: span 2;
|
||||
}
|
||||
|
||||
.dnc-pnj-sheet .sheet-header.compact input[type="number"] {
|
||||
width: 4.5rem;
|
||||
max-width: 4.5rem;
|
||||
}
|
||||
|
||||
.dnc-pnj-sheet .sheet-header.compact .counter-field input[type="number"] {
|
||||
width: 3.75rem;
|
||||
max-width: 3.75rem;
|
||||
.dnc-pnj-sheet .sheet-header.compact .counter-field input[name="system.sante.pv.value"],
|
||||
.dnc-pnj-sheet .sheet-header.compact .counter-field input[name="system.sante.pv.max"] {
|
||||
width: 5.25rem;
|
||||
max-width: 5.25rem;
|
||||
}
|
||||
|
||||
.dnc-sheet label {
|
||||
@@ -175,20 +186,20 @@
|
||||
color: @color-muted;
|
||||
}
|
||||
|
||||
.readonly-field {
|
||||
.dnc-sheet .readonly-field {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: @spacing-sm;
|
||||
}
|
||||
|
||||
.readonly-field > span {
|
||||
.dnc-sheet .readonly-field > span {
|
||||
font-size: 0.8rem;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.04em;
|
||||
color: @color-muted;
|
||||
}
|
||||
|
||||
.readonly-field p {
|
||||
.dnc-sheet .readonly-field p {
|
||||
margin: 0;
|
||||
border: 1px solid rgba(91, 70, 52, 0.55);
|
||||
border-radius: 6px;
|
||||
@@ -215,18 +226,18 @@
|
||||
min-height: 4.5rem;
|
||||
}
|
||||
|
||||
.sheet-columns {
|
||||
.dnc-sheet .sheet-columns {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(250px, 320px) 1fr;
|
||||
gap: @spacing-lg;
|
||||
}
|
||||
|
||||
.sheet-sections {
|
||||
.dnc-sheet .sheet-sections {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
gap: @spacing-lg;
|
||||
}
|
||||
|
||||
.compact-sections {
|
||||
.dnc-sheet .compact-sections {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
@@ -378,6 +378,30 @@
|
||||
linear-gradient(135deg, #f7fbff 0%, #9fb8d7 100%);
|
||||
}
|
||||
|
||||
.dnc-chat-card-welcome {
|
||||
border-color: fade(@color-accent, 34%);
|
||||
background:
|
||||
linear-gradient(180deg, rgba(255, 250, 240, 0.84) 0%, rgba(239, 219, 179, 0.94) 100%),
|
||||
linear-gradient(135deg, #fffaf0 0%, #dcb772 100%);
|
||||
}
|
||||
|
||||
.chat-welcome-intro {
|
||||
font-size: 0.82rem;
|
||||
line-height: 1.45;
|
||||
}
|
||||
|
||||
.chat-welcome-link {
|
||||
margin-top: @spacing-md;
|
||||
padding: 0.6rem 0.8rem;
|
||||
border: 1px solid fade(@color-accent, 24%);
|
||||
border-radius: 12px;
|
||||
background: fade(@color-accent, 8%);
|
||||
}
|
||||
|
||||
.chat-welcome-link a.content-link {
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.dnc-chat-card-spell .chat-actions + .chat-actions {
|
||||
margin-top: @spacing-sm;
|
||||
}
|
||||
|
||||
+12
-12
@@ -1,14 +1,14 @@
|
||||
.counter-field {
|
||||
.dnc-sheet .counter-field {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: @spacing-sm;
|
||||
}
|
||||
|
||||
.counter-field button,
|
||||
.item-actions button,
|
||||
.sheet-footer button,
|
||||
.text-button,
|
||||
.roll-button {
|
||||
.dnc-sheet .counter-field button,
|
||||
.dnc-sheet .item-actions button,
|
||||
.dnc-sheet .sheet-footer button,
|
||||
.dnc-sheet .text-button,
|
||||
.dnc-sheet .roll-button {
|
||||
border: 1px solid @color-border;
|
||||
border-radius: @radius-sm;
|
||||
background: linear-gradient(180deg, #fdf9f2 0%, #e8d5ba 100%);
|
||||
@@ -17,20 +17,20 @@
|
||||
padding: 0.35rem 0.65rem;
|
||||
}
|
||||
|
||||
.text-button {
|
||||
.dnc-sheet .text-button {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.roll-button {
|
||||
.dnc-sheet .roll-button {
|
||||
width: 2rem;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.with-controls {
|
||||
.dnc-sheet .with-controls {
|
||||
gap: @spacing-sm;
|
||||
}
|
||||
|
||||
.section-header {
|
||||
.dnc-sheet .section-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
@@ -38,12 +38,12 @@
|
||||
margin-bottom: @spacing-md;
|
||||
}
|
||||
|
||||
.empty-state {
|
||||
.dnc-sheet .empty-state {
|
||||
margin: 0;
|
||||
color: @color-muted;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.span-two {
|
||||
.dnc-sheet .span-two {
|
||||
grid-column: span 2;
|
||||
}
|
||||
|
||||
@@ -34,3 +34,149 @@
|
||||
.dnc-roll-dialog .window-content {
|
||||
background: linear-gradient(180deg, #f7efe0 0%, #e3d0b1 100%);
|
||||
}
|
||||
|
||||
.dnc-mission-pack-mode,
|
||||
.dnc-mission-pack-note {
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.dnc-mission-pack-campaign {
|
||||
gap: @spacing-lg;
|
||||
}
|
||||
|
||||
.dnc-mission-pack-hero {
|
||||
padding: @spacing-lg;
|
||||
border: 1px solid fade(@color-border, 35%);
|
||||
border-radius: @radius-md;
|
||||
background:
|
||||
linear-gradient(180deg, fade(#ffffff, 65%) 0%, fade(@color-panel, 68%) 100%),
|
||||
linear-gradient(135deg, fade(@color-accent, 8%) 0%, fade(@color-accent, 0%) 100%);
|
||||
box-shadow: 0 8px 18px fade(@color-shadow, 10%);
|
||||
}
|
||||
|
||||
.dnc-mission-pack-kicker {
|
||||
margin: 0 0 0.25rem;
|
||||
font-size: 0.72rem;
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.14em;
|
||||
text-transform: uppercase;
|
||||
color: fade(@color-accent, 82%);
|
||||
}
|
||||
|
||||
.dnc-mission-pack-hero h2 {
|
||||
margin: 0;
|
||||
font-family: @font-display;
|
||||
font-size: 1.4rem;
|
||||
line-height: 1.1;
|
||||
color: @color-accent;
|
||||
}
|
||||
|
||||
.dnc-mission-pack-subtitle {
|
||||
margin-top: 0.2rem;
|
||||
font-size: 0.78rem;
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.16em;
|
||||
text-transform: uppercase;
|
||||
color: fade(@color-border, 78%);
|
||||
}
|
||||
|
||||
.dnc-mission-pack-intro {
|
||||
margin-top: @spacing-sm;
|
||||
color: @color-muted;
|
||||
}
|
||||
|
||||
.dnc-mission-pack-meta-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
gap: @spacing-md;
|
||||
}
|
||||
|
||||
.dnc-mission-pack-meta-card {
|
||||
display: grid;
|
||||
gap: 0.2rem;
|
||||
padding: @spacing-md;
|
||||
border: 1px solid fade(@color-border, 30%);
|
||||
border-radius: @radius-md;
|
||||
background: fade(#ffffff, 42%);
|
||||
}
|
||||
|
||||
.dnc-mission-pack-meta-card span {
|
||||
font-size: 0.72rem;
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.08em;
|
||||
text-transform: uppercase;
|
||||
color: @color-muted;
|
||||
}
|
||||
|
||||
.dnc-mission-pack-meta-card strong {
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.dnc-mission-pack-section {
|
||||
display: grid;
|
||||
gap: @spacing-md;
|
||||
}
|
||||
|
||||
.dnc-mission-pack-select {
|
||||
padding: @spacing-md;
|
||||
border: 1px solid fade(@color-border, 32%);
|
||||
border-radius: @radius-md;
|
||||
background: fade(#ffffff, 36%);
|
||||
}
|
||||
|
||||
.dnc-mission-pack-assignments {
|
||||
display: grid;
|
||||
gap: @spacing-md;
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
}
|
||||
|
||||
.dnc-mission-pack-assignment {
|
||||
display: grid;
|
||||
gap: @spacing-sm;
|
||||
padding: @spacing-md;
|
||||
border: 1px solid fade(@color-border, 35%);
|
||||
border-radius: @radius-md;
|
||||
background: fade(#ffffff, 38%);
|
||||
box-shadow: inset 0 1px 0 fade(#ffffff, 55%);
|
||||
}
|
||||
|
||||
.dnc-mission-pack-assignment span {
|
||||
font-size: 0.82rem;
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.04em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.dnc-mission-pack-note {
|
||||
color: @color-muted;
|
||||
}
|
||||
|
||||
.dnc-mission-pack-note-foot {
|
||||
padding: @spacing-md;
|
||||
border-top: 1px solid fade(@color-border, 24%);
|
||||
}
|
||||
|
||||
.dnc-mission-pack-dialog .window-header {
|
||||
background:
|
||||
linear-gradient(180deg, fade(#fdf6e7, 96%) 0%, fade(#ead4aa, 96%) 100%),
|
||||
linear-gradient(90deg, fade(@color-accent, 12%) 0%, fade(@color-accent, 0%) 100%);
|
||||
border-bottom: 1px solid fade(@color-border, 35%);
|
||||
}
|
||||
|
||||
.dnc-mission-pack-dialog .window-title {
|
||||
color: @color-accent;
|
||||
font-family: @font-display;
|
||||
letter-spacing: 0.03em;
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
.dnc-mission-pack-dialog .window-header button {
|
||||
color: @color-ink;
|
||||
}
|
||||
|
||||
@media (max-width: 640px) {
|
||||
.dnc-mission-pack-meta-grid,
|
||||
.dnc-mission-pack-assignments {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
}
|
||||
|
||||
.sheet-footer {
|
||||
.dnc-item-sheet .sheet-footer {
|
||||
display: flex;
|
||||
gap: @spacing-md;
|
||||
justify-content: flex-end;
|
||||
|
||||
@@ -32,7 +32,7 @@ export class DonjonEtCieRollDialog {
|
||||
buttons: [
|
||||
{
|
||||
action: "roll",
|
||||
label: "Lancer",
|
||||
label: game.i18n.localize("DNC.UI.RollAction"),
|
||||
icon: "fa-solid fa-bolt",
|
||||
default: true,
|
||||
callback: async (event, button) => {
|
||||
@@ -70,7 +70,7 @@ export class DonjonEtCieRollDialog {
|
||||
buttons: [
|
||||
{
|
||||
action: "roll",
|
||||
label: "Lancer",
|
||||
label: game.i18n.localize("DNC.UI.RollAction"),
|
||||
icon: "fa-solid fa-dice-d20",
|
||||
default: true,
|
||||
callback: async (event, button) => {
|
||||
@@ -107,7 +107,7 @@ export class DonjonEtCieRollDialog {
|
||||
buttons: [
|
||||
{
|
||||
action: "roll",
|
||||
label: "Attaquer",
|
||||
label: game.i18n.localize("DNC.UI.AttackAction"),
|
||||
icon: "fa-solid fa-sword",
|
||||
default: true,
|
||||
callback: async (event, button) => {
|
||||
@@ -153,7 +153,7 @@ export class DonjonEtCieRollDialog {
|
||||
buttons: [
|
||||
{
|
||||
action: "roll",
|
||||
label: "Lancer",
|
||||
label: game.i18n.localize("DNC.UI.RollAction"),
|
||||
icon: "fa-solid fa-wand-magic-sparkles",
|
||||
default: true,
|
||||
callback: async (event, button) => {
|
||||
@@ -185,7 +185,7 @@ export class DonjonEtCieRollDialog {
|
||||
buttons: [
|
||||
{
|
||||
action: "roll",
|
||||
label: "Utiliser",
|
||||
label: game.i18n.localize("DNC.UI.UseAction"),
|
||||
icon: "fa-solid fa-hourglass-half",
|
||||
default: true,
|
||||
callback: async (event, button) => {
|
||||
@@ -218,7 +218,7 @@ export class DonjonEtCieRollDialog {
|
||||
buttons: [
|
||||
{
|
||||
action: "roll",
|
||||
label: "Lancer",
|
||||
label: game.i18n.localize("DNC.UI.RollAction"),
|
||||
icon: "fa-solid fa-burst",
|
||||
default: true,
|
||||
callback: async (event, button) => {
|
||||
|
||||
@@ -37,6 +37,7 @@ export default class DonjonEtCieActorSheet extends HandlebarsApplicationMixin(fo
|
||||
rollDamage: DonjonEtCieActorSheet.#onRollDamage,
|
||||
rollSpell: DonjonEtCieActorSheet.#onRollSpell,
|
||||
rollUsage: DonjonEtCieActorSheet.#onRollUsage,
|
||||
resetUsage: DonjonEtCieActorSheet.#onResetUsage,
|
||||
useFavorService: DonjonEtCieActorSheet.#onUseFavorService,
|
||||
postItem: DonjonEtCieActorSheet.#onPostItem,
|
||||
adjustCounter: DonjonEtCieActorSheet.#onAdjustCounter
|
||||
@@ -216,6 +217,11 @@ export default class DonjonEtCieActorSheet extends HandlebarsApplicationMixin(fo
|
||||
return this.document.rollUsage(target.closest("[data-item-id]")?.dataset.itemId);
|
||||
}
|
||||
|
||||
static async #onResetUsage(event, target) {
|
||||
event.preventDefault();
|
||||
return this.document.resetUsage(target.closest("[data-item-id]")?.dataset.itemId);
|
||||
}
|
||||
|
||||
static async #onUseFavorService(event, target) {
|
||||
event.preventDefault();
|
||||
return this.document.useFavorService(target.dataset.department);
|
||||
|
||||
@@ -29,7 +29,8 @@ export default class DonjonEtCieItemSheet extends HandlebarsApplicationMixin(fou
|
||||
editImage: DonjonEtCieItemSheet.#onEditImage,
|
||||
postItem: DonjonEtCieItemSheet.#onPostItem,
|
||||
rollItem: DonjonEtCieItemSheet.#onRollItem,
|
||||
rollDamageItem: DonjonEtCieItemSheet.#onRollDamageItem
|
||||
rollDamageItem: DonjonEtCieItemSheet.#onRollDamageItem,
|
||||
resetUsageItem: DonjonEtCieItemSheet.#onResetUsageItem
|
||||
}
|
||||
};
|
||||
|
||||
@@ -49,12 +50,14 @@ export default class DonjonEtCieItemSheet extends HandlebarsApplicationMixin(fou
|
||||
isWeapon: item.type === "arme",
|
||||
isArmor: item.type === "armure",
|
||||
isConsumable: item.type === "consommable",
|
||||
isTraining: item.type === "entrainement",
|
||||
isSpell: item.type === "sortilege",
|
||||
canRollDamage: Boolean(item.system.degats),
|
||||
isEquipment: item.type === "equipement",
|
||||
isCapacity: item.type === "capacite",
|
||||
isLanguage: item.type === "langue",
|
||||
isTrait: item.type === "trait",
|
||||
canResetUsage: item.type === "entrainement" && Number(item.system.deltaMax ?? 0) > 0 && Number(item.system.delta ?? 0) !== Number(item.system.deltaMax ?? 0),
|
||||
armorProtectionDisplay: Number(item.system.resultatProtection ?? 0) > 0 ? item.system.resultatProtection : "—",
|
||||
weaponCharacteristicLabel: item.type === "arme" ? DonjonEtCieUtility.getWeaponCharacteristicLabel(item.system.categorie) : null,
|
||||
enrichedDescription: await foundry.applications.ux.TextEditor.implementation.enrichHTML(item.system.description ?? "", { async: true }),
|
||||
@@ -119,4 +122,9 @@ export default class DonjonEtCieItemSheet extends HandlebarsApplicationMixin(fou
|
||||
event.preventDefault();
|
||||
return this.document.rollDamage();
|
||||
}
|
||||
|
||||
static async #onResetUsageItem(event) {
|
||||
event.preventDefault();
|
||||
return this.document.resetUsageDie();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ export default class DonjonEtCieEmployeSheet extends DonjonEtCieActorSheet {
|
||||
combatSections: ["armes", "armures", "consommables", "equipements"].map(getSection),
|
||||
spellSection: getSection("sortileges"),
|
||||
capacitySection: getSection("capacites"),
|
||||
profileSections: ["langues"].map(getSection)
|
||||
profileSections: ["langues", "entrainements"].map(getSection)
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,9 @@ export default class DonjonEtCiePNJSheet extends DonjonEtCieActorSheet {
|
||||
...super.DEFAULT_OPTIONS.actions,
|
||||
rollPnjArmor: DonjonEtCiePNJSheet.#onRollPnjArmor,
|
||||
rollPnjCourage: DonjonEtCiePNJSheet.#onRollPnjCourage,
|
||||
rollPnjAttackDamage: DonjonEtCiePNJSheet.#onRollPnjAttackDamage
|
||||
rollPnjAttackDamage: DonjonEtCiePNJSheet.#onRollPnjAttackDamage,
|
||||
createPnjAttack: DonjonEtCiePNJSheet.#onCreatePnjAttack,
|
||||
deletePnjAttack: DonjonEtCiePNJSheet.#onDeletePnjAttack
|
||||
}
|
||||
};
|
||||
|
||||
@@ -48,7 +50,7 @@ export default class DonjonEtCiePNJSheet extends DonjonEtCieActorSheet {
|
||||
armorDisplay: Number(system.defense?.armure?.delta ?? 0) ? `Δ${system.defense.armure.delta}` : "—",
|
||||
storedArmor: Number(system.defense?.armure?.resultatProtection ?? 0) > 0 ? system.defense.armure.resultatProtection : "—",
|
||||
courageDisplay: Number(system.defense?.courage?.delta ?? 0) ? `Δ${system.defense.courage.delta}` : "—",
|
||||
hasAttackDamage: Boolean(system.attaque?.degats)
|
||||
pnjAttacks: this.document.getPnjAttacks()
|
||||
};
|
||||
}
|
||||
|
||||
@@ -64,6 +66,16 @@ export default class DonjonEtCiePNJSheet extends DonjonEtCieActorSheet {
|
||||
|
||||
static async #onRollPnjAttackDamage(event) {
|
||||
event.preventDefault();
|
||||
return this.document.rollPnjAttackDamage();
|
||||
return this.document.rollPnjAttackDamage(event.target.closest("[data-attack-index]")?.dataset.attackIndex ?? 0);
|
||||
}
|
||||
|
||||
static async #onCreatePnjAttack(event) {
|
||||
event.preventDefault();
|
||||
return this.document.createPnjAttack();
|
||||
}
|
||||
|
||||
static async #onDeletePnjAttack(event) {
|
||||
event.preventDefault();
|
||||
return this.document.deletePnjAttack(event.target.closest("[data-attack-index]")?.dataset.attackIndex ?? 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,12 @@ import { DonjonEtCieUtility } from "./donjon-et-cie-utility.mjs";
|
||||
import { DonjonEtCieRollDialog } from "./applications/donjon-et-cie-roll-dialog.mjs";
|
||||
|
||||
export class DonjonEtCieActor extends Actor {
|
||||
static defaultPnjAttack = {
|
||||
nom: "Attaque",
|
||||
degats: "1d6",
|
||||
notes: ""
|
||||
};
|
||||
|
||||
prepareDerivedData() {
|
||||
super.prepareDerivedData();
|
||||
|
||||
@@ -23,6 +29,19 @@ export class DonjonEtCieActor extends Actor {
|
||||
}
|
||||
}
|
||||
|
||||
async _preUpdate(changed, options, user) {
|
||||
if (
|
||||
foundry.utils.hasProperty(changed, "system.magie.focus.delta")
|
||||
&& !foundry.utils.hasProperty(changed, "system.magie.focus.resultat")
|
||||
&& !foundry.utils.hasProperty(changed, "system.magie.focus.sceneId")
|
||||
) {
|
||||
foundry.utils.setProperty(changed, "system.magie.focus.resultat", 0);
|
||||
foundry.utils.setProperty(changed, "system.magie.focus.sceneId", "");
|
||||
}
|
||||
|
||||
return super._preUpdate(changed, options, user);
|
||||
}
|
||||
|
||||
getCharacteristicEntries() {
|
||||
return DonjonEtCieUtility.getCharacteristicEntries(this.system);
|
||||
}
|
||||
@@ -158,6 +177,50 @@ export class DonjonEtCieActor extends Actor {
|
||||
if (item) return DonjonEtCieRollDialog.createUsage(item);
|
||||
}
|
||||
|
||||
async resetUsage(itemId) {
|
||||
const item = this.items.get(itemId);
|
||||
if (item?.type === "entrainement") return item.resetUsageDie();
|
||||
}
|
||||
|
||||
getPnjAttacks() {
|
||||
if (this.type !== "pnj") return [];
|
||||
|
||||
const attacks = Array.isArray(this.system.attaques) ? this.system.attaques : [];
|
||||
if (attacks.length) return attacks.map((attack, index) => ({
|
||||
index,
|
||||
nom: attack.nom || `Attaque ${index + 1}`,
|
||||
degats: attack.degats || "",
|
||||
notes: attack.notes || ""
|
||||
}));
|
||||
|
||||
const legacy = this.system.attaque;
|
||||
if (legacy) {
|
||||
return [{
|
||||
index: 0,
|
||||
nom: legacy.nom || "Attaque",
|
||||
degats: legacy.degats || "",
|
||||
notes: legacy.notes || ""
|
||||
}];
|
||||
}
|
||||
|
||||
return [{ index: 0, ...foundry.utils.deepClone(this.constructor.defaultPnjAttack) }];
|
||||
}
|
||||
|
||||
async createPnjAttack() {
|
||||
if (this.type !== "pnj") return null;
|
||||
const attaques = this.getPnjAttacks().map(({ nom, degats, notes }) => ({ nom, degats, notes }));
|
||||
attaques.push(foundry.utils.deepClone(this.constructor.defaultPnjAttack));
|
||||
return this.update({ "system.attaques": attaques });
|
||||
}
|
||||
|
||||
async deletePnjAttack(index) {
|
||||
if (this.type !== "pnj") return null;
|
||||
const attaques = this.getPnjAttacks().map(({ nom, degats, notes }) => ({ nom, degats, notes }));
|
||||
attaques.splice(Number(index), 1);
|
||||
if (!attaques.length) attaques.push(foundry.utils.deepClone(this.constructor.defaultPnjAttack));
|
||||
return this.update({ "system.attaques": attaques });
|
||||
}
|
||||
|
||||
#createPnjResourceProxy({ label, deltaPath, protectionPath = null }) {
|
||||
const delta = Number(foundry.utils.getProperty(this, deltaPath) ?? 0);
|
||||
const protection = protectionPath ? Number(foundry.utils.getProperty(this, protectionPath) ?? 0) : 0;
|
||||
@@ -198,9 +261,10 @@ export class DonjonEtCieActor extends Actor {
|
||||
}));
|
||||
}
|
||||
|
||||
async rollPnjAttackDamage() {
|
||||
const attackName = this.system.attaque?.nom || "Attaque";
|
||||
const attackDamage = this.system.attaque?.degats || "";
|
||||
async rollPnjAttackDamage(index = 0) {
|
||||
const attack = this.getPnjAttacks()[Number(index)] ?? null;
|
||||
const attackName = attack?.nom || "Attaque";
|
||||
const attackDamage = attack?.degats || "";
|
||||
if (!attackDamage) return null;
|
||||
|
||||
return DonjonEtCieRollDialog.createDamage(this, {
|
||||
@@ -208,7 +272,7 @@ export class DonjonEtCieActor extends Actor {
|
||||
type: "attaque",
|
||||
system: {
|
||||
degats: attackDamage,
|
||||
portee: this.system.attaque?.notes || ""
|
||||
portee: attack?.notes || ""
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -114,7 +114,8 @@ export const DONJON_ET_CIE = {
|
||||
armes: { label: "Armes", createType: "arme" },
|
||||
armures: { label: "Armures", createType: "armure" },
|
||||
equipements: { label: "Equipements", createType: "equipement" },
|
||||
consommables: { label: "Consommables", createType: "consommable" }
|
||||
consommables: { label: "Consommables", createType: "consommable" },
|
||||
entrainements: { label: "Entrainements", createType: "entrainement" }
|
||||
},
|
||||
sectionTypes: {
|
||||
traits: ["trait"],
|
||||
@@ -124,6 +125,7 @@ export const DONJON_ET_CIE = {
|
||||
armes: ["arme"],
|
||||
armures: ["armure"],
|
||||
equipements: ["equipement"],
|
||||
consommables: ["consommable"]
|
||||
consommables: ["consommable"],
|
||||
entrainements: ["entrainement"]
|
||||
}
|
||||
};
|
||||
|
||||
@@ -27,10 +27,18 @@ export class DonjonEtCieItem extends Item {
|
||||
return Number(this.system.delta ?? 0);
|
||||
}
|
||||
|
||||
get usageDieMax() {
|
||||
return Number(this.system.deltaMax ?? this.system.delta ?? 0);
|
||||
}
|
||||
|
||||
async roll() {
|
||||
if (this.type === "arme") return DonjonEtCieRollDialog.createWeapon(this.actor, this);
|
||||
if (this.type === "sortilege") return DonjonEtCieRollDialog.createSpell(this.actor, this);
|
||||
if (this.usageDie) return DonjonEtCieRollDialog.createUsage(this);
|
||||
if (this.type === "entrainement" && this.usageDieMax > 0) {
|
||||
ui.notifications.warn(game.i18n.localize("DNC.Warn.TrainingExhausted"));
|
||||
return null;
|
||||
}
|
||||
return this.postToChat();
|
||||
}
|
||||
|
||||
@@ -54,4 +62,11 @@ export class DonjonEtCieItem extends Item {
|
||||
content
|
||||
});
|
||||
}
|
||||
|
||||
async resetUsageDie() {
|
||||
if (this.type !== "entrainement") return this;
|
||||
const deltaMax = this.usageDieMax;
|
||||
if (!deltaMax) return this;
|
||||
return this.update({ "system.delta": deltaMax });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,925 @@
|
||||
/**
|
||||
* Donjon & Cie - Systeme FoundryVTT
|
||||
*
|
||||
* Donjon & Cie est un jeu de role edite par John Doe.
|
||||
* Ce systeme FoundryVTT est une implementation independante et n'est pas
|
||||
* affilie a John Doe.
|
||||
*
|
||||
* @author LeRatierBretonnien
|
||||
* @copyright 2025–2026 LeRatierBretonnien
|
||||
* @license CC BY-NC-SA 4.0 – https://creativecommons.org/licenses/by-nc-sa/4.0/
|
||||
*/
|
||||
|
||||
import { DonjonEtCieUtility } from "./donjon-et-cie-utility.mjs";
|
||||
|
||||
export class DonjonEtCieMacros {
|
||||
static MISSION_PACK_MODE_SETTING = "missionPackMode";
|
||||
static MISSION_PACK_SOCKET_SCOPE = "missionPackCampaign";
|
||||
static MISSION_PACK_REQUEST_TIMEOUT = 300000;
|
||||
static MISSION_PACK_CAMPAIGN_DICE = [20, 12, 10, 8];
|
||||
static MISSION_PACK_STEWARD_MODES = {
|
||||
positive: "avantage",
|
||||
neutral: "normal",
|
||||
negative: "desavantage"
|
||||
};
|
||||
static #campaignRequests = new Map();
|
||||
static #socketRegistered = false;
|
||||
|
||||
static MISSION_PACK_TABLES = [
|
||||
{ key: "melee", name: "Armes de corps a corps", multiple: false },
|
||||
{ key: "ranged", name: "Armes a distance", multiple: false },
|
||||
{ key: "armor", name: "Armures", multiple: false },
|
||||
{ key: "misc", name: "Encas et equipement divers", multiple: true }
|
||||
];
|
||||
|
||||
static MISSION_PACK_UNIQUE_ITEMS = [
|
||||
{
|
||||
name: "L epee de Monsieur Noir",
|
||||
type: "arme",
|
||||
system: {
|
||||
categorie: "melee",
|
||||
caracteristique: "force",
|
||||
degats: "1d6",
|
||||
portee: "",
|
||||
mains: 1,
|
||||
equipee: false,
|
||||
description: "<p>Elle n a rien de particulier mais confere un prestige important.</p><p>Avantage a tous les jets d interaction avec les employes de Donjon & Cie.</p>",
|
||||
notes: ""
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "Fil a plomb d Arnezon",
|
||||
type: "equipement",
|
||||
system: {
|
||||
quantite: 1,
|
||||
equipee: false,
|
||||
emplacement: "",
|
||||
description: "<p>Il oscille de maniere clairement etrange en presence d un passage secret.</p>",
|
||||
notes: ""
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "Boussole de Drize Durban",
|
||||
type: "equipement",
|
||||
system: {
|
||||
quantite: 1,
|
||||
equipee: false,
|
||||
emplacement: "",
|
||||
description: "<p>Trois reglages : pointe vers le client, le resident ou l employe le plus proche.</p>",
|
||||
notes: ""
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "Boule de cristal de la supervision",
|
||||
type: "equipement",
|
||||
system: {
|
||||
quantite: 1,
|
||||
equipee: false,
|
||||
emplacement: "",
|
||||
description: "<p>Permet de voir toute personne ou lieu qu on connait deja.</p><p>Jet de SAG pour la controler. La plupart des huiles sentent quand on les observe.</p>",
|
||||
notes: ""
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "Dent du dragon Leogradonardicus III",
|
||||
type: "equipement",
|
||||
system: {
|
||||
quantite: 1,
|
||||
equipee: false,
|
||||
emplacement: "",
|
||||
description: "<p>Un jet de CHA reussi permet de controler les reptiles inintelligents et de charmer les humanoides reptiliens.</p>",
|
||||
notes: ""
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "Doigt d Aarcarcerax",
|
||||
type: "consommable",
|
||||
system: {
|
||||
quantite: 1,
|
||||
delta: 4,
|
||||
effet: "Tue la creature vers qui on pointe le doigt.",
|
||||
description: "<p>Tue la creature vers qui on pointe le doigt.</p><p>La liche sait instantanement qu on a retrouve son doigt.</p>",
|
||||
notes: ""
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "Cape de Vlad von Drakovitch",
|
||||
type: "consommable",
|
||||
system: {
|
||||
quantite: 1,
|
||||
delta: 6,
|
||||
effet: "Permet de se transformer en 1-3 rats, 4-5 chauve-souris, 6 forme gazeuse.",
|
||||
description: "<p>Delta 6 charges.</p><p>Permet de se transformer en 1-3 rats, 4-5 chauve-souris, 6 forme gazeuse.</p>",
|
||||
notes: ""
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "Vieux carnet de notes d Affalella",
|
||||
type: "consommable",
|
||||
system: {
|
||||
quantite: 1,
|
||||
delta: 6,
|
||||
effet: "Fonctionne comme des faveurs de la Mercatique utilisables uniquement dans les aires client.",
|
||||
description: "<p>Vieux carnet de notes d Affalella, directrice de la Mercatique.</p><p>Fonctionne comme Delta 6 faveurs de la Mercatique utilisables uniquement dans les aires client.</p>",
|
||||
notes: ""
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "Ancienne cle universelle de Paiji",
|
||||
type: "consommable",
|
||||
system: {
|
||||
quantite: 1,
|
||||
delta: 8,
|
||||
effet: "Ouvre tous les coffres, portes, armoires et autres serrures du Donjon.",
|
||||
description: "<p>Ancienne cle universelle de Paiji, directeur de la Maintenance.</p><p>Delta 8 usages. Ouvre tous les coffres, portes, armoires et autres serrures du Donjon.</p>",
|
||||
notes: ""
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "Baguette d urgence",
|
||||
type: "equipement",
|
||||
system: {
|
||||
quantite: 1,
|
||||
equipee: false,
|
||||
emplacement: "",
|
||||
description: "<p>Teleporte l utilisateur au palier des huiles lorsque la baguette est brisee.</p>",
|
||||
notes: ""
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
static registerSocketListeners() {
|
||||
if (this.#socketRegistered || !game.socket) return;
|
||||
|
||||
game.socket.on(`system.${game.system.id}`, (payload) => {
|
||||
void this.#handleSocketMessage(payload);
|
||||
});
|
||||
|
||||
this.#socketRegistered = true;
|
||||
}
|
||||
|
||||
static #normalizeName(value) {
|
||||
return String(value ?? "")
|
||||
.normalize("NFD")
|
||||
.replace(/\p{Diacritic}/gu, "")
|
||||
.replace(/['’]/g, " ")
|
||||
.replace(/\s+/g, " ")
|
||||
.trim()
|
||||
.toLowerCase();
|
||||
}
|
||||
|
||||
static #getMissionPackLabel(key) {
|
||||
return game.i18n.localize(`DNC.Macro.MissionPack.${key}`);
|
||||
}
|
||||
|
||||
static #getModeLabel(mode) {
|
||||
if (mode === "avantage") return game.i18n.localize("DNC.UI.ModeAdvantage");
|
||||
if (mode === "desavantage") return game.i18n.localize("DNC.UI.ModeDisadvantage");
|
||||
return game.i18n.localize("DNC.UI.ModeNormal");
|
||||
}
|
||||
|
||||
static #getMissionPackMode() {
|
||||
return String(game.settings.get("fvtt-donjon-et-cie", this.MISSION_PACK_MODE_SETTING) ?? "classic");
|
||||
}
|
||||
|
||||
static #getMissionPackModeLabel(mode) {
|
||||
return game.i18n.localize(mode === "campaign"
|
||||
? "DNC.Macro.MissionPack.ModeCampaign"
|
||||
: "DNC.Macro.MissionPack.ModeClassic");
|
||||
}
|
||||
|
||||
static #getMissionPackModeDescription(mode) {
|
||||
return game.i18n.localize(mode === "campaign"
|
||||
? "DNC.Macro.MissionPack.ModeCampaignHint"
|
||||
: "DNC.Macro.MissionPack.ModeClassicHint");
|
||||
}
|
||||
|
||||
static #getStewardRelationLabel(relation) {
|
||||
return game.i18n.localize(`DNC.Macro.MissionPack.Relation.${relation ?? "neutral"}`);
|
||||
}
|
||||
|
||||
static #getStewardRelationOptions() {
|
||||
return ["positive", "neutral", "negative"].map((relation) => ({
|
||||
value: relation,
|
||||
label: this.#getStewardRelationLabel(relation)
|
||||
}));
|
||||
}
|
||||
|
||||
static #getCampaignDiceOptions() {
|
||||
return this.MISSION_PACK_CAMPAIGN_DICE.map((sides) => ({
|
||||
value: String(sides),
|
||||
label: `1d${sides}`
|
||||
}));
|
||||
}
|
||||
|
||||
static #getDefaultCampaignAssignments() {
|
||||
return Object.fromEntries(this.MISSION_PACK_TABLES.map((spec, index) => [spec.key, String(this.MISSION_PACK_CAMPAIGN_DICE[index])]));
|
||||
}
|
||||
|
||||
static #getDefaultMissionPackActorId(actors) {
|
||||
const controlledActor = canvas?.tokens?.controlled?.[0]?.actor ?? null;
|
||||
if (controlledActor?.type === "employe") return controlledActor.id;
|
||||
return actors[0]?.id ?? "";
|
||||
}
|
||||
|
||||
static #getMissionPackActorOptions() {
|
||||
return game.actors
|
||||
.filter((actor) => actor.type === "employe")
|
||||
.sort((a, b) => a.name.localeCompare(b.name, "fr", { sensitivity: "base" }))
|
||||
.map((actor) => ({
|
||||
value: actor.id,
|
||||
label: actor.name
|
||||
}));
|
||||
}
|
||||
|
||||
static #getMissionPackOwnerUsers(actor) {
|
||||
return game.users
|
||||
.filter((user) => !user.isGM && actor.testUserPermission(user, CONST.DOCUMENT_OWNERSHIP_LEVELS.OWNER))
|
||||
.sort((a, b) => Number(b.active) - Number(a.active) || a.name.localeCompare(b.name, "fr", { sensitivity: "base" }));
|
||||
}
|
||||
|
||||
static #getCampaignTargetUser(actor) {
|
||||
return this.#getMissionPackOwnerUsers(actor).find((user) => user.active) ?? null;
|
||||
}
|
||||
|
||||
static async #resolveMissionPackActor(target = null) {
|
||||
if (target?.documentName === "Actor") return target;
|
||||
if (target?.actor?.documentName === "Actor") return target.actor;
|
||||
if (typeof target === "string" && target) {
|
||||
const document = await fromUuid(target);
|
||||
if (document?.documentName === "Actor") return document;
|
||||
if (document?.actor?.documentName === "Actor") return document.actor;
|
||||
}
|
||||
|
||||
const controlledTokens = canvas?.tokens?.controlled ?? [];
|
||||
if (controlledTokens.length === 1 && controlledTokens[0]?.actor) return controlledTokens[0].actor;
|
||||
if (controlledTokens.length > 1) {
|
||||
ui.notifications.warn(game.i18n.localize("DNC.Macro.MissionPack.WarnMultipleTokens"));
|
||||
return null;
|
||||
}
|
||||
|
||||
return game.user.character ?? null;
|
||||
}
|
||||
|
||||
static async #getRandomTableDocuments() {
|
||||
const worldTables = game.tables?.contents ?? [];
|
||||
if (worldTables.length) return worldTables;
|
||||
|
||||
const pack = game.packs.get("fvtt-donjon-et-cie.random-tables");
|
||||
return pack ? pack.getDocuments() : [];
|
||||
}
|
||||
|
||||
static async #findRollTableByName(name) {
|
||||
const normalizedName = this.#normalizeName(name);
|
||||
const worldTable = game.tables.find((table) => this.#normalizeName(table.name) === normalizedName);
|
||||
if (worldTable) return worldTable;
|
||||
|
||||
const packTables = await this.#getRandomTableDocuments();
|
||||
return packTables.find((table) => this.#normalizeName(table.name) === normalizedName) ?? null;
|
||||
}
|
||||
|
||||
static async #getEquipmentDocuments() {
|
||||
const pack = game.packs.get("fvtt-donjon-et-cie.equipment");
|
||||
const packDocuments = pack ? await pack.getDocuments() : [];
|
||||
return [...(game.items?.contents ?? []), ...packDocuments];
|
||||
}
|
||||
|
||||
static async #findItemByName(name) {
|
||||
const normalizedName = this.#normalizeName(name);
|
||||
const documents = await this.#getEquipmentDocuments();
|
||||
return documents.find((item) => this.#normalizeName(item.name) === normalizedName) ?? null;
|
||||
}
|
||||
|
||||
static #extractUuidTargets(text) {
|
||||
const matches = [...String(text ?? "").matchAll(/@UUID\[([^\]]+)\](?:\{([^}]+)\})?/g)];
|
||||
return matches.map((match) => ({
|
||||
uuid: match[1],
|
||||
label: match[2] ?? ""
|
||||
}));
|
||||
}
|
||||
|
||||
static #extractPlainTextEntries(text) {
|
||||
const rawText = String(text ?? "")
|
||||
.replace(/<[^>]+>/g, " ")
|
||||
.replace(/\s+/g, " ")
|
||||
.trim();
|
||||
|
||||
if (!rawText) return [];
|
||||
|
||||
return rawText
|
||||
.split(",")
|
||||
.map((entry) => entry.trim())
|
||||
.filter(Boolean)
|
||||
.filter((entry) => !/^dotation\s+\d+$/i.test(entry));
|
||||
}
|
||||
|
||||
static async #evaluateRoll(formula) {
|
||||
const roll = await (new Roll(formula)).evaluate();
|
||||
const values = roll.dice
|
||||
.flatMap((die) => die.results.map((result) => Number(result.result ?? result.count ?? 0)))
|
||||
.filter((value) => Number.isFinite(value));
|
||||
|
||||
return {
|
||||
roll,
|
||||
total: Number(roll.total ?? 0),
|
||||
values
|
||||
};
|
||||
}
|
||||
|
||||
static #formatRollValues(values, kept) {
|
||||
if (!values.length) return String(kept ?? 0);
|
||||
if (values.length === 1) return String(values[0]);
|
||||
return `${values.join(" / ")} -> ${kept}`;
|
||||
}
|
||||
|
||||
static async #rollPackDie(sides, { mode = "normal" } = {}) {
|
||||
const formula = mode === "avantage"
|
||||
? `2d${sides}kh`
|
||||
: mode === "desavantage"
|
||||
? `2d${sides}kl`
|
||||
: `1d${sides}`;
|
||||
const evaluated = await this.#evaluateRoll(formula);
|
||||
|
||||
return {
|
||||
sides: Number(sides),
|
||||
dieLabel: `1d${sides}`,
|
||||
roll: evaluated.roll,
|
||||
values: evaluated.values,
|
||||
valuesLabel: this.#formatRollValues(evaluated.values, evaluated.total),
|
||||
kept: evaluated.total,
|
||||
mode,
|
||||
modeLabel: this.#getModeLabel(mode)
|
||||
};
|
||||
}
|
||||
|
||||
static #createInlineItemData(spec) {
|
||||
return {
|
||||
name: spec.name,
|
||||
type: spec.type,
|
||||
img: DonjonEtCieUtility.getDefaultItemIcon(spec.type),
|
||||
system: foundry.utils.deepClone(spec.system)
|
||||
};
|
||||
}
|
||||
|
||||
static #getTableResults(table) {
|
||||
return table?.results?.contents ?? [];
|
||||
}
|
||||
|
||||
static #getTableRange(result) {
|
||||
const rawRange = Array.isArray(result?.range)
|
||||
? result.range
|
||||
: result?._source?.range ?? [];
|
||||
return [Number(rawRange[0] ?? 0), Number(rawRange[1] ?? 0)];
|
||||
}
|
||||
|
||||
static #findTableResultByTotal(table, total) {
|
||||
const entries = this.#getTableResults(table)
|
||||
.map((result) => ({
|
||||
result,
|
||||
range: this.#getTableRange(result)
|
||||
}))
|
||||
.filter(({ range }) => Number.isFinite(range[0]) && Number.isFinite(range[1]) && range[1] >= range[0])
|
||||
.sort((a, b) => a.range[0] - b.range[0]);
|
||||
|
||||
if (!entries.length) {
|
||||
return {
|
||||
result: null,
|
||||
clampedTotal: total,
|
||||
range: null
|
||||
};
|
||||
}
|
||||
|
||||
const minimum = entries[0].range[0];
|
||||
const maximum = entries.at(-1).range[1];
|
||||
const clampedTotal = Math.max(minimum, Math.min(maximum, total));
|
||||
const match = entries.find(({ range }) => clampedTotal >= range[0] && clampedTotal <= range[1]) ?? entries.at(-1);
|
||||
|
||||
return {
|
||||
result: match.result,
|
||||
clampedTotal,
|
||||
range: match.range
|
||||
};
|
||||
}
|
||||
|
||||
static async #resolveUniqueMissionPackEntry({ comparisonRoll = null } = {}) {
|
||||
const reference = await this.#rollPackDie(20);
|
||||
const actorEvaluation = comparisonRoll == null ? await this.#rollPackDie(20) : null;
|
||||
const actorRoll = Number(comparisonRoll ?? actorEvaluation?.kept ?? 0);
|
||||
|
||||
if (reference.kept !== actorRoll) {
|
||||
return {
|
||||
matched: false,
|
||||
referenceRoll: reference.kept,
|
||||
actorRoll,
|
||||
uniqueRoll: null,
|
||||
itemName: "",
|
||||
itemData: null,
|
||||
rolls: [reference.roll, ...(actorEvaluation ? [actorEvaluation.roll] : [])]
|
||||
};
|
||||
}
|
||||
|
||||
const uniqueRoll = await this.#rollPackDie(this.MISSION_PACK_UNIQUE_ITEMS.length);
|
||||
const spec = this.MISSION_PACK_UNIQUE_ITEMS[Math.max(0, uniqueRoll.kept - 1)] ?? this.MISSION_PACK_UNIQUE_ITEMS[0];
|
||||
const document = await this.#findItemByName(spec.name);
|
||||
const itemData = document ? this.#toEmbeddedItemData(document) : this.#createInlineItemData(spec);
|
||||
|
||||
return {
|
||||
matched: true,
|
||||
referenceRoll: reference.kept,
|
||||
actorRoll,
|
||||
uniqueRoll: uniqueRoll.kept,
|
||||
itemName: document?.name ?? spec.name,
|
||||
itemData,
|
||||
rolls: [reference.roll, ...(actorEvaluation ? [actorEvaluation.roll] : []), uniqueRoll.roll]
|
||||
};
|
||||
}
|
||||
|
||||
static async #resolveTableResultEntries(result, { multiple = false } = {}) {
|
||||
if (!result) {
|
||||
return {
|
||||
display: game.i18n.localize("DNC.Macro.MissionPack.NoResult"),
|
||||
entries: []
|
||||
};
|
||||
}
|
||||
|
||||
const source = result._source ?? {};
|
||||
const resultName = String(result.name ?? source.name ?? "").trim();
|
||||
const resultDescription = String(result.description ?? source.description ?? "").trim();
|
||||
const resultText = String(source.text ?? "").trim();
|
||||
const resultLabel = resultName || resultDescription || resultText;
|
||||
|
||||
const documentUuid = result.type === "document"
|
||||
? result.documentUuid ?? source.documentUuid ?? null
|
||||
: null;
|
||||
|
||||
if (documentUuid) {
|
||||
const document = await fromUuid(documentUuid);
|
||||
const label = document?.name ?? resultLabel;
|
||||
return {
|
||||
display: label,
|
||||
entries: label ? [{ name: label, document }] : []
|
||||
};
|
||||
}
|
||||
|
||||
const sourceText = resultDescription || resultText || resultLabel;
|
||||
const uuidTargets = this.#extractUuidTargets(sourceText);
|
||||
if (uuidTargets.length) {
|
||||
const entries = [];
|
||||
for (const target of uuidTargets) {
|
||||
const document = await fromUuid(target.uuid);
|
||||
const name = document?.name ?? target.label;
|
||||
if (!name) continue;
|
||||
entries.push({ name, document });
|
||||
}
|
||||
|
||||
return {
|
||||
display: entries.map((entry) => entry.name).join(", "),
|
||||
entries
|
||||
};
|
||||
}
|
||||
|
||||
const names = multiple
|
||||
? this.#extractPlainTextEntries(sourceText || resultLabel)
|
||||
: [resultLabel].filter(Boolean);
|
||||
|
||||
return {
|
||||
display: names.join(", "),
|
||||
entries: names.map((name) => ({ name, document: null }))
|
||||
};
|
||||
}
|
||||
|
||||
static #toEmbeddedItemData(item) {
|
||||
const data = foundry.utils.deepClone(item.toObject());
|
||||
delete data._id;
|
||||
delete data.folder;
|
||||
delete data.sort;
|
||||
return data;
|
||||
}
|
||||
|
||||
static async #materializeMissionPackEntries(entries) {
|
||||
const embeddedItems = [];
|
||||
const addedNames = [];
|
||||
const missingNames = [];
|
||||
|
||||
for (const entry of entries) {
|
||||
const item = entry.document ?? await this.#findItemByName(entry.name);
|
||||
if (!item) {
|
||||
missingNames.push(entry.name);
|
||||
continue;
|
||||
}
|
||||
|
||||
embeddedItems.push(this.#toEmbeddedItemData(item));
|
||||
addedNames.push(item.name);
|
||||
}
|
||||
|
||||
return {
|
||||
embeddedItems,
|
||||
addedNames,
|
||||
missingNames
|
||||
};
|
||||
}
|
||||
|
||||
static async #openCampaignAllocationDialog(actor, { playerName = "", requesterName = "" } = {}) {
|
||||
const content = await foundry.applications.handlebars.renderTemplate(
|
||||
"systems/fvtt-donjon-et-cie/templates/dialogs/mission-pack-campaign-dialog.hbs",
|
||||
{
|
||||
actorName: actor.name,
|
||||
playerName,
|
||||
requesterName,
|
||||
rank: Number(actor.system.anciennete?.rang ?? actor.system.sante?.dv ?? 0),
|
||||
assignments: this.MISSION_PACK_TABLES.map((spec) => ({
|
||||
key: spec.key,
|
||||
label: this.#getMissionPackLabel(spec.key),
|
||||
fieldName: `${spec.key}Die`,
|
||||
selectedDie: this.#getDefaultCampaignAssignments()[spec.key]
|
||||
})),
|
||||
diceOptions: this.#getCampaignDiceOptions(),
|
||||
relationOptions: this.#getStewardRelationOptions(),
|
||||
selectedRelation: "neutral"
|
||||
}
|
||||
);
|
||||
|
||||
return foundry.applications.api.DialogV2.wait({
|
||||
window: {
|
||||
title: game.i18n.localize("DNC.Macro.MissionPack.CampaignDialogTitle"),
|
||||
icon: "fa-solid fa-dice"
|
||||
},
|
||||
classes: ["dnc-roll-dialog", "dnc-mission-pack-dialog"],
|
||||
content,
|
||||
modal: true,
|
||||
buttons: [
|
||||
{
|
||||
action: "confirm",
|
||||
label: game.i18n.localize("DNC.Macro.MissionPack.CampaignDialogAction"),
|
||||
icon: "fa-solid fa-check",
|
||||
default: true,
|
||||
callback: async (event, button) => {
|
||||
const assignments = Object.fromEntries(this.MISSION_PACK_TABLES.map((spec) => [
|
||||
spec.key,
|
||||
Number(button.form.elements[`${spec.key}Die`]?.value ?? 0)
|
||||
]));
|
||||
const selectedDice = Object.values(assignments).filter((value) => value > 0);
|
||||
|
||||
if (selectedDice.length !== this.MISSION_PACK_TABLES.length) {
|
||||
ui.notifications.warn(game.i18n.localize("DNC.Macro.MissionPack.WarnDiceRequired"));
|
||||
return null;
|
||||
}
|
||||
|
||||
if (new Set(selectedDice).size !== selectedDice.length) {
|
||||
ui.notifications.warn(game.i18n.localize("DNC.Macro.MissionPack.WarnDiceUnique"));
|
||||
return null;
|
||||
}
|
||||
|
||||
return {
|
||||
assignments,
|
||||
stewardRelation: button.form.elements.stewardRelation?.value ?? "neutral"
|
||||
};
|
||||
}
|
||||
}
|
||||
],
|
||||
rejectClose: false
|
||||
});
|
||||
}
|
||||
|
||||
static async #handleSocketMessage(payload) {
|
||||
if (payload?.scope !== this.MISSION_PACK_SOCKET_SCOPE) return;
|
||||
|
||||
if (payload.type === "campaign-response") {
|
||||
const pending = this.#campaignRequests.get(payload.requestId);
|
||||
if (!pending) return;
|
||||
clearTimeout(pending.timeoutId);
|
||||
this.#campaignRequests.delete(payload.requestId);
|
||||
pending.resolve(payload.result ?? null);
|
||||
return;
|
||||
}
|
||||
|
||||
if (payload.type !== "campaign-request" || payload.targetUserId !== game.user.id) return;
|
||||
|
||||
const actor = await fromUuid(payload.actorUuid);
|
||||
const allocation = actor
|
||||
? await this.#openCampaignAllocationDialog(actor, {
|
||||
playerName: game.user.name,
|
||||
requesterName: payload.requesterName ?? ""
|
||||
})
|
||||
: null;
|
||||
|
||||
game.socket.emit(`system.${game.system.id}`, {
|
||||
scope: this.MISSION_PACK_SOCKET_SCOPE,
|
||||
type: "campaign-response",
|
||||
requestId: payload.requestId,
|
||||
result: allocation
|
||||
? {
|
||||
allocation,
|
||||
responderUserId: game.user.id,
|
||||
responderName: game.user.name
|
||||
}
|
||||
: {
|
||||
allocation: null,
|
||||
responderUserId: game.user.id,
|
||||
responderName: game.user.name
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
static async #requestCampaignAllocation(actor, targetUser) {
|
||||
if (!targetUser || targetUser.id === game.user.id) {
|
||||
const allocation = await this.#openCampaignAllocationDialog(actor, {
|
||||
playerName: game.user.name,
|
||||
requesterName: game.user.name
|
||||
});
|
||||
return allocation ? { allocation, responderName: game.user.name } : null;
|
||||
}
|
||||
|
||||
const requestId = foundry.utils.randomID();
|
||||
const responsePromise = new Promise((resolve) => {
|
||||
const timeoutId = globalThis.setTimeout(() => {
|
||||
this.#campaignRequests.delete(requestId);
|
||||
resolve(null);
|
||||
}, this.MISSION_PACK_REQUEST_TIMEOUT);
|
||||
this.#campaignRequests.set(requestId, { resolve, timeoutId });
|
||||
});
|
||||
|
||||
game.socket.emit(`system.${game.system.id}`, {
|
||||
scope: this.MISSION_PACK_SOCKET_SCOPE,
|
||||
type: "campaign-request",
|
||||
requestId,
|
||||
targetUserId: targetUser.id,
|
||||
actorUuid: actor.uuid,
|
||||
requesterName: game.user.name
|
||||
});
|
||||
|
||||
const response = await responsePromise;
|
||||
if (!response?.allocation) {
|
||||
ui.notifications.warn(game.i18n.format("DNC.Macro.MissionPack.CampaignRequestCanceled", {
|
||||
actor: actor.name,
|
||||
player: targetUser.name
|
||||
}));
|
||||
return null;
|
||||
}
|
||||
|
||||
return {
|
||||
allocation: response.allocation,
|
||||
responderName: response.responderName ?? targetUser.name
|
||||
};
|
||||
}
|
||||
|
||||
static async #finalizeMissionPack(actor, drawPlans, {
|
||||
generationMode = "classic",
|
||||
controllerName = "",
|
||||
stewardRelation = "neutral",
|
||||
uniqueComparisonRoll = null
|
||||
} = {}) {
|
||||
const draws = [];
|
||||
const embeddedItems = [];
|
||||
const rolls = [];
|
||||
let missingCount = 0;
|
||||
|
||||
for (const plan of drawPlans) {
|
||||
rolls.push(...(plan.rolls ?? []).filter((roll) => roll instanceof Roll));
|
||||
|
||||
if (plan.failed || !plan.resolved) {
|
||||
draws.push({
|
||||
label: this.#getMissionPackLabel(plan.spec.key),
|
||||
display: game.i18n.format("DNC.Macro.MissionPack.TableMissing", { table: plan.spec.name }),
|
||||
addedNames: [],
|
||||
addedSummary: "",
|
||||
missingNames: [],
|
||||
missingSummary: "",
|
||||
failed: true
|
||||
});
|
||||
continue;
|
||||
}
|
||||
|
||||
const materialized = await this.#materializeMissionPackEntries(plan.resolved.entries);
|
||||
embeddedItems.push(...materialized.embeddedItems);
|
||||
missingCount += materialized.missingNames.length;
|
||||
|
||||
draws.push({
|
||||
label: this.#getMissionPackLabel(plan.spec.key),
|
||||
display: plan.resolved.display || game.i18n.localize("DNC.Macro.MissionPack.NoResult"),
|
||||
addedNames: materialized.addedNames,
|
||||
addedSummary: materialized.addedNames.join(", "),
|
||||
missingNames: materialized.missingNames,
|
||||
missingSummary: materialized.missingNames.join(", "),
|
||||
failed: false,
|
||||
...plan.detail
|
||||
});
|
||||
}
|
||||
|
||||
const uniqueEntry = await this.#resolveUniqueMissionPackEntry({ comparisonRoll: uniqueComparisonRoll });
|
||||
rolls.push(...(uniqueEntry.rolls ?? []).filter((roll) => roll instanceof Roll));
|
||||
if (uniqueEntry.itemData) {
|
||||
embeddedItems.push(uniqueEntry.itemData);
|
||||
}
|
||||
|
||||
const createdItems = embeddedItems.length
|
||||
? await actor.createEmbeddedDocuments("Item", embeddedItems, { renderSheet: false })
|
||||
: [];
|
||||
|
||||
const content = await foundry.applications.handlebars.renderTemplate(
|
||||
"systems/fvtt-donjon-et-cie/templates/chat/mission-pack-card.hbs",
|
||||
{
|
||||
title: game.i18n.localize("DNC.Macro.MissionPack.Title"),
|
||||
actorName: actor.name,
|
||||
createdCount: createdItems.length,
|
||||
missingCount,
|
||||
draws,
|
||||
uniqueEntry,
|
||||
isCampaign: generationMode === "campaign",
|
||||
generationModeLabel: this.#getMissionPackModeLabel(generationMode),
|
||||
controllerName,
|
||||
stewardRelationLabel: generationMode === "campaign" ? this.#getStewardRelationLabel(stewardRelation) : ""
|
||||
}
|
||||
);
|
||||
|
||||
await ChatMessage.create({
|
||||
speaker: ChatMessage.getSpeaker({ actor }),
|
||||
user: game.user.id,
|
||||
content,
|
||||
rolls
|
||||
});
|
||||
|
||||
if (createdItems.length && !missingCount) {
|
||||
ui.notifications.info(game.i18n.format("DNC.Macro.MissionPack.Success", {
|
||||
actor: actor.name,
|
||||
count: createdItems.length
|
||||
}));
|
||||
} else if (createdItems.length) {
|
||||
ui.notifications.warn(game.i18n.format("DNC.Macro.MissionPack.Partial", {
|
||||
actor: actor.name,
|
||||
count: createdItems.length,
|
||||
missing: missingCount
|
||||
}));
|
||||
} else {
|
||||
ui.notifications.warn(game.i18n.localize("DNC.Macro.MissionPack.WarnNothingAdded"));
|
||||
}
|
||||
|
||||
return {
|
||||
actor,
|
||||
createdItems,
|
||||
missingCount,
|
||||
draws,
|
||||
uniqueEntry,
|
||||
generationMode,
|
||||
controllerName,
|
||||
stewardRelation
|
||||
};
|
||||
}
|
||||
|
||||
static async #grantClassicMissionPack(actor) {
|
||||
const drawPlans = [];
|
||||
|
||||
for (const spec of this.MISSION_PACK_TABLES) {
|
||||
const table = await this.#findRollTableByName(spec.name);
|
||||
if (!table) {
|
||||
drawPlans.push({ spec, failed: true, resolved: null, rolls: [] });
|
||||
continue;
|
||||
}
|
||||
|
||||
const draw = await table.draw({ displayChat: false });
|
||||
const result = draw.results?.[0] ?? null;
|
||||
drawPlans.push({
|
||||
spec,
|
||||
failed: false,
|
||||
resolved: await this.#resolveTableResultEntries(result, { multiple: spec.multiple }),
|
||||
detail: null,
|
||||
rolls: draw.roll instanceof Roll ? [draw.roll] : []
|
||||
});
|
||||
}
|
||||
|
||||
return this.#finalizeMissionPack(actor, drawPlans, {
|
||||
generationMode: "classic"
|
||||
});
|
||||
}
|
||||
|
||||
static async #grantCampaignMissionPack(actor) {
|
||||
const targetUser = this.#getCampaignTargetUser(actor);
|
||||
const allocationResult = await this.#requestCampaignAllocation(actor, targetUser);
|
||||
if (!allocationResult?.allocation) return null;
|
||||
|
||||
const rankBonus = Number(actor.system.anciennete?.rang ?? actor.system.sante?.dv ?? 0);
|
||||
const stewardRelation = allocationResult.allocation.stewardRelation ?? "neutral";
|
||||
const mode = this.MISSION_PACK_STEWARD_MODES[stewardRelation] ?? "normal";
|
||||
const drawPlans = [];
|
||||
let uniqueComparisonRoll = null;
|
||||
|
||||
for (const spec of this.MISSION_PACK_TABLES) {
|
||||
const table = await this.#findRollTableByName(spec.name);
|
||||
if (!table) {
|
||||
drawPlans.push({ spec, failed: true, resolved: null, rolls: [] });
|
||||
continue;
|
||||
}
|
||||
|
||||
const sides = Number(allocationResult.allocation.assignments?.[spec.key] ?? 0);
|
||||
const rollData = await this.#rollPackDie(sides, { mode });
|
||||
if (sides === 20) uniqueComparisonRoll = rollData.kept;
|
||||
|
||||
const total = rollData.kept + rankBonus;
|
||||
const tableResult = this.#findTableResultByTotal(table, total);
|
||||
|
||||
drawPlans.push({
|
||||
spec,
|
||||
failed: false,
|
||||
resolved: await this.#resolveTableResultEntries(tableResult.result, { multiple: spec.multiple }),
|
||||
detail: {
|
||||
dieLabel: rollData.dieLabel,
|
||||
modeLabel: rollData.modeLabel,
|
||||
rollValuesLabel: rollData.valuesLabel,
|
||||
kept: rollData.kept,
|
||||
rankBonus,
|
||||
total,
|
||||
resolvedTotal: tableResult.clampedTotal,
|
||||
clamped: tableResult.clampedTotal !== total
|
||||
},
|
||||
rolls: [rollData.roll]
|
||||
});
|
||||
}
|
||||
|
||||
return this.#finalizeMissionPack(actor, drawPlans, {
|
||||
generationMode: "campaign",
|
||||
controllerName: allocationResult.responderName ?? targetUser?.name ?? game.user.name,
|
||||
stewardRelation,
|
||||
uniqueComparisonRoll
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Open the GM-only mission pack dialog.
|
||||
* @returns {Promise<object|null>}
|
||||
*/
|
||||
static async openMissionPackDialog() {
|
||||
if (!game.user.isGM) {
|
||||
ui.notifications.warn(game.i18n.localize("DNC.Macro.MissionPack.WarnGMOnly"));
|
||||
return null;
|
||||
}
|
||||
|
||||
const actorOptions = this.#getMissionPackActorOptions();
|
||||
if (!actorOptions.length) {
|
||||
ui.notifications.warn(game.i18n.localize("DNC.Macro.MissionPack.WarnNoEmployees"));
|
||||
return null;
|
||||
}
|
||||
|
||||
const mode = this.#getMissionPackMode();
|
||||
const selectedActorId = this.#getDefaultMissionPackActorId(actorOptions.map((option) => game.actors.get(option.value)).filter(Boolean));
|
||||
const content = await foundry.applications.handlebars.renderTemplate(
|
||||
"systems/fvtt-donjon-et-cie/templates/dialogs/mission-pack-dialog.hbs",
|
||||
{
|
||||
actorOptions,
|
||||
selectedActorId,
|
||||
modeLabel: this.#getMissionPackModeLabel(mode),
|
||||
modeDescription: this.#getMissionPackModeDescription(mode),
|
||||
isCampaign: mode === "campaign"
|
||||
}
|
||||
);
|
||||
|
||||
return foundry.applications.api.DialogV2.wait({
|
||||
window: {
|
||||
title: game.i18n.localize("DNC.Macro.MissionPack.DialogTitle"),
|
||||
icon: "fa-solid fa-box-open"
|
||||
},
|
||||
classes: ["dnc-roll-dialog"],
|
||||
content,
|
||||
modal: false,
|
||||
buttons: [
|
||||
{
|
||||
action: "grant",
|
||||
label: game.i18n.localize("DNC.Macro.MissionPack.DialogAction"),
|
||||
icon: "fa-solid fa-box-open",
|
||||
default: true,
|
||||
callback: async (event, button) => {
|
||||
const actorId = button.form.elements.actorId?.value ?? "";
|
||||
const actor = actorId ? game.actors.get(actorId) : null;
|
||||
if (!actor) {
|
||||
ui.notifications.warn(game.i18n.localize("DNC.Macro.MissionPack.WarnNoActor"));
|
||||
return null;
|
||||
}
|
||||
return this.grantMissionPack(actor);
|
||||
}
|
||||
}
|
||||
],
|
||||
rejectClose: false
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw the initial mission pack for the resolved actor and add the resulting items.
|
||||
* @param {Actor|string|null} target Resolved actor, token, or UUID. Defaults to selected token or user character.
|
||||
* @returns {Promise<object|null>}
|
||||
*/
|
||||
static async grantMissionPack(target = null) {
|
||||
const actor = await this.#resolveMissionPackActor(target);
|
||||
if (!actor) {
|
||||
ui.notifications.warn(game.i18n.localize("DNC.Macro.MissionPack.WarnNoActor"));
|
||||
return null;
|
||||
}
|
||||
|
||||
if (actor.type !== "employe") {
|
||||
ui.notifications.warn(game.i18n.localize("DNC.Macro.MissionPack.WarnInvalidActor"));
|
||||
return null;
|
||||
}
|
||||
|
||||
return this.#getMissionPackMode() === "campaign"
|
||||
? this.#grantCampaignMissionPack(actor)
|
||||
: this.#grantClassicMissionPack(actor);
|
||||
}
|
||||
}
|
||||
@@ -19,6 +19,31 @@ import * as models from "./models/index.mjs";
|
||||
import * as sheets from "./applications/sheets/_module.mjs";
|
||||
import { DonjonEtCieRollDialog } from "./applications/donjon-et-cie-roll-dialog.mjs";
|
||||
import { DonjonEtCieRolls } from "./donjon-et-cie-rolls.mjs";
|
||||
import { DonjonEtCieMacros } from "./donjon-et-cie-macros.mjs";
|
||||
|
||||
const WELCOME_MESSAGE_SETTING = "welcomeMessageVersion";
|
||||
|
||||
function injectActorDirectoryMissionPackButton(app, element) {
|
||||
if (!game.user.isGM) return;
|
||||
|
||||
const root = app?.element ?? element?.[0] ?? element;
|
||||
if (!(root instanceof HTMLElement)) return;
|
||||
|
||||
const headerActions = root.querySelector(".directory-header .header-actions");
|
||||
if (!(headerActions instanceof HTMLElement)) return;
|
||||
if (headerActions.querySelector(".dnc-mission-pack-button")) return;
|
||||
|
||||
const button = document.createElement("button");
|
||||
button.type = "button";
|
||||
button.className = "dnc-mission-pack-button";
|
||||
button.title = game.i18n.localize("DNC.Macro.MissionPack.SidebarButton");
|
||||
button.setAttribute("aria-label", game.i18n.localize("DNC.Macro.MissionPack.SidebarButton"));
|
||||
button.innerHTML = `<i class="fa-solid fa-box-open" inert></i><span>${game.i18n.localize("DNC.Macro.MissionPack.SidebarButton")}</span>`;
|
||||
button.addEventListener("click", () => {
|
||||
void game.system.donjonEtCie.macros.openMissionPackDialog();
|
||||
});
|
||||
headerActions.append(button);
|
||||
}
|
||||
|
||||
function onChatActionClick(event) {
|
||||
const button = event.target.closest("[data-action='rollChatDamage'], [data-action='rollSpellChaos'], [data-action='applyDamage']");
|
||||
@@ -64,6 +89,86 @@ function onChatActionClick(event) {
|
||||
})();
|
||||
}
|
||||
|
||||
function registerSystemSettings() {
|
||||
game.settings.register("fvtt-donjon-et-cie", WELCOME_MESSAGE_SETTING, {
|
||||
name: "Version du message de bienvenue",
|
||||
hint: "Usage interne pour eviter de republier le message de bienvenue a chaque chargement.",
|
||||
scope: "world",
|
||||
config: false,
|
||||
type: String,
|
||||
default: ""
|
||||
});
|
||||
|
||||
game.settings.register("fvtt-donjon-et-cie", DonjonEtCieMacros.MISSION_PACK_MODE_SETTING, {
|
||||
name: "Mode de paquetage de mission",
|
||||
hint: "Choisit entre le tirage classique rapide et la regle optionnelle de campagne avec allocation des des par les joueurs.",
|
||||
scope: "world",
|
||||
config: true,
|
||||
type: String,
|
||||
default: "classic",
|
||||
choices: {
|
||||
classic: "Classique",
|
||||
campaign: "Campagne"
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async function getHelpJournalLink() {
|
||||
const pack = [...game.packs.values()].find((candidate) => candidate.metadata.name === "system-help");
|
||||
if (!pack) return null;
|
||||
|
||||
const index = await pack.getIndex();
|
||||
const entry = index.find((document) => document.name === "Aide du systeme");
|
||||
if (!entry?._id) return null;
|
||||
|
||||
const journal = await pack.getDocument(entry._id);
|
||||
if (!journal?.uuid) return null;
|
||||
|
||||
return `@UUID[${journal.uuid}]{${game.i18n.localize("DNC.Welcome.HelpLinkLabel")}}`;
|
||||
}
|
||||
|
||||
async function maybeCreateWelcomeMessage() {
|
||||
if (!game.user.isGM) return;
|
||||
|
||||
const currentVersion = String(game.system.version ?? "");
|
||||
const shownVersion = String(game.settings.get("fvtt-donjon-et-cie", WELCOME_MESSAGE_SETTING) ?? "");
|
||||
if (shownVersion === currentVersion) return;
|
||||
|
||||
const helpJournalLink = await getHelpJournalLink();
|
||||
const content = await foundry.applications.handlebars.renderTemplate(
|
||||
"systems/fvtt-donjon-et-cie/templates/chat/welcome-card.hbs",
|
||||
{
|
||||
title: game.i18n.localize("DNC.Welcome.Title"),
|
||||
subtitle: game.i18n.format("DNC.Welcome.Subtitle", { version: currentVersion }),
|
||||
intro: game.i18n.localize("DNC.Welcome.Intro"),
|
||||
bullets: [
|
||||
game.i18n.localize("DNC.Welcome.BulletActors"),
|
||||
game.i18n.localize("DNC.Welcome.BulletItems"),
|
||||
game.i18n.localize("DNC.Welcome.BulletMissionPack")
|
||||
],
|
||||
helpLabel: game.i18n.localize("DNC.Welcome.HelpLabel"),
|
||||
helpLink: helpJournalLink,
|
||||
helpFallback: game.i18n.localize("DNC.Welcome.HelpFallback"),
|
||||
footer: game.i18n.localize("DNC.Welcome.Footer"),
|
||||
creditsLabel: game.i18n.localize("DNC.Welcome.CreditsLabel"),
|
||||
creditsText: game.i18n.localize("DNC.Welcome.CreditsText"),
|
||||
officialLabel: game.i18n.localize("DNC.Welcome.OfficialLabel"),
|
||||
officialUrl: "https://johndoe-rpg.com/catalogue/donjon-cie/",
|
||||
officialLinkText: game.i18n.localize("DNC.Welcome.OfficialLinkText")
|
||||
}
|
||||
);
|
||||
|
||||
await ChatMessage.create({
|
||||
speaker: {
|
||||
alias: game.system.title
|
||||
},
|
||||
user: game.user.id,
|
||||
content: await TextEditor.enrichHTML(content, { async: true })
|
||||
});
|
||||
|
||||
await game.settings.set("fvtt-donjon-et-cie", WELCOME_MESSAGE_SETTING, currentVersion);
|
||||
}
|
||||
|
||||
Hooks.once("init", async () => {
|
||||
const startupBanner =
|
||||
`▗▄▄▄ ▗▄▖ ▗▖ ▗▖ ▗▖ ▗▄▖ ▗▖ ▗▖ ▗▄▄▄▖▗▄▄▄▖ ▗▄▄▖▗▄▄▄▖▗▞▀▚▖
|
||||
@@ -75,6 +180,7 @@ Hooks.once("init", async () => {
|
||||
console.log(`%c${startupBanner}`, "font-family: monospace; white-space: pre; line-height: 1.1;");
|
||||
console.log("Initialisation du systeme Donjon & Cie");
|
||||
|
||||
registerSystemSettings();
|
||||
await DonjonEtCieUtility.preloadHandlebarsTemplates();
|
||||
|
||||
CONFIG.Combat.initiative = {
|
||||
@@ -97,7 +203,8 @@ Hooks.once("init", async () => {
|
||||
arme: models.ArmeDataModel,
|
||||
armure: models.ArmureDataModel,
|
||||
equipement: models.EquipementDataModel,
|
||||
consommable: models.ConsommableDataModel
|
||||
consommable: models.ConsommableDataModel,
|
||||
entrainement: models.EntrainementDataModel
|
||||
};
|
||||
|
||||
game.system.donjonEtCie = {
|
||||
@@ -106,7 +213,8 @@ Hooks.once("init", async () => {
|
||||
sheets,
|
||||
rolls: DonjonEtCieRolls,
|
||||
dialogs: DonjonEtCieRollDialog,
|
||||
utility: DonjonEtCieUtility
|
||||
utility: DonjonEtCieUtility,
|
||||
macros: DonjonEtCieMacros
|
||||
};
|
||||
|
||||
foundry.documents.collections.Actors.unregisterSheet("core", foundry.appv1.sheets.ActorSheet);
|
||||
@@ -114,11 +222,17 @@ Hooks.once("init", async () => {
|
||||
foundry.documents.collections.Actors.registerSheet("fvtt-donjon-et-cie", sheets.DonjonEtCiePNJSheet, { types: ["pnj"], makeDefault: true });
|
||||
|
||||
foundry.documents.collections.Items.unregisterSheet("core", foundry.appv1.sheets.ItemSheet);
|
||||
for (const type of ["trait", "langue", "capacite", "sortilege", "arme", "armure", "equipement", "consommable"]) {
|
||||
for (const type of ["trait", "langue", "capacite", "sortilege", "arme", "armure", "equipement", "consommable", "entrainement"]) {
|
||||
foundry.documents.collections.Items.registerSheet("fvtt-donjon-et-cie", sheets.DonjonEtCieItemSheet, { types: [type], makeDefault: true });
|
||||
}
|
||||
});
|
||||
|
||||
Hooks.once("ready", () => {
|
||||
DonjonEtCieMacros.registerSocketListeners();
|
||||
document.addEventListener("click", onChatActionClick);
|
||||
void maybeCreateWelcomeMessage();
|
||||
});
|
||||
|
||||
Hooks.on("renderActorDirectory", (app, element) => {
|
||||
injectActorDirectoryMissionPackButton(app, element);
|
||||
});
|
||||
|
||||
@@ -14,12 +14,14 @@ import { DonjonEtCieUtility } from "./donjon-et-cie-utility.mjs";
|
||||
import { DONJON_ET_CIE } from "./donjon-et-cie-config.mjs";
|
||||
|
||||
export class DonjonEtCieRolls {
|
||||
static async #createChatCard(actor, template, context) {
|
||||
static async #createChatCard(actor, template, context, { rolls = [] } = {}) {
|
||||
const content = await foundry.applications.handlebars.renderTemplate(template, context);
|
||||
const validRolls = rolls.filter((roll) => roll instanceof Roll);
|
||||
await ChatMessage.create({
|
||||
speaker: ChatMessage.getSpeaker({ actor }),
|
||||
user: game.user.id,
|
||||
content
|
||||
content,
|
||||
rolls: validRolls
|
||||
});
|
||||
}
|
||||
|
||||
@@ -35,8 +37,9 @@ export class DonjonEtCieRolls {
|
||||
}
|
||||
|
||||
static #getModeLabel(mode) {
|
||||
if (mode === "avantage") return "Avantage";
|
||||
if (mode === "desavantage") return "Desavantage";
|
||||
if (mode === "avantage") return game.i18n.localize("DNC.UI.ModeAdvantage");
|
||||
if (mode === "desavantage") return game.i18n.localize("DNC.UI.ModeDisadvantage");
|
||||
if (mode === "normal") return game.i18n.localize("DNC.UI.ModeNormal");
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -67,7 +70,7 @@ export class DonjonEtCieRolls {
|
||||
const kept = this.#selectKeptValue(values, mode, "low");
|
||||
const success = kept <= target;
|
||||
|
||||
return { characteristic, characteristicKey, target, values, kept, success, mode, isNaturalOne: kept === 1, isNaturalTwenty: kept === 20 };
|
||||
return { characteristic, characteristicKey, target, values, kept, success, mode, roll, isNaturalOne: kept === 1, isNaturalTwenty: kept === 20 };
|
||||
}
|
||||
|
||||
static async #resolveFavorBoost(actor, favorKey, mode = "normal") {
|
||||
@@ -77,7 +80,7 @@ export class DonjonEtCieRolls {
|
||||
const path = `system.faveurs.${favorKey}.delta`;
|
||||
const before = Number(foundry.utils.getProperty(actor, path) ?? 0);
|
||||
if (!before) {
|
||||
ui.notifications.warn(`Aucune faveur disponible pour ${label}.`);
|
||||
ui.notifications.warn(game.i18n.format("DNC.Warn.NoFavorAvailable", { label }));
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -100,6 +103,7 @@ export class DonjonEtCieRolls {
|
||||
effectiveMode: this.#applyFavorMode(mode),
|
||||
modeBefore: mode,
|
||||
modeAfter: this.#applyFavorMode(mode),
|
||||
rolls: resolved.rolls,
|
||||
note: degraded
|
||||
? "Le coup de pouce reste anonyme : un collegue du departement a donne l'info utile."
|
||||
: "Le coup de pouce tient bon : nommez le collegue, ses trois traits et la relation pour le trombinoscope."
|
||||
@@ -113,7 +117,7 @@ export class DonjonEtCieRolls {
|
||||
const path = `system.faveurs.${favorKey}.delta`;
|
||||
const before = Number(foundry.utils.getProperty(actor, path) ?? 0);
|
||||
if (!before) {
|
||||
ui.notifications.warn(`Aucune faveur disponible pour ${label}.`);
|
||||
ui.notifications.warn(game.i18n.format("DNC.Warn.NoFavorAvailable", { label }));
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -128,7 +132,7 @@ export class DonjonEtCieRolls {
|
||||
after: DonjonEtCieUtility.formatUsageDie(after),
|
||||
autoSpent: true,
|
||||
note: "La faveur est brulee pour obtenir directement l'aide souhaitee, a la discretion du MJ."
|
||||
});
|
||||
}, { rolls: [] });
|
||||
|
||||
return { key: favorKey, label, before, after };
|
||||
}
|
||||
@@ -171,6 +175,7 @@ export class DonjonEtCieRolls {
|
||||
before: focusDelta,
|
||||
after,
|
||||
degraded,
|
||||
rolls: resolved.rolls,
|
||||
values: resolved.values
|
||||
};
|
||||
}
|
||||
@@ -182,32 +187,32 @@ export class DonjonEtCieRolls {
|
||||
if (!result) return null;
|
||||
|
||||
await this.#createChatCard(actor, "systems/fvtt-donjon-et-cie/templates/chat/roll-card.hbs", {
|
||||
title: label ?? "Jet de caracteristique",
|
||||
title: label ?? game.i18n.localize("DNC.Roll.Characteristic"),
|
||||
subtitle: result.characteristic.label,
|
||||
formula: result.values.length > 1 ? "2d20" : "1d20",
|
||||
mode: effectiveMode,
|
||||
modeLabel: this.#getModeLabel(effectiveMode),
|
||||
target: result.target,
|
||||
targetPillLabel: "Cible",
|
||||
targetPillLabel: game.i18n.localize("DNC.Chat.Target"),
|
||||
targetPillValue: result.target,
|
||||
values: result.values,
|
||||
kept: result.kept,
|
||||
keptPillLabel: "Garde",
|
||||
keptPillLabel: game.i18n.localize("DNC.Chat.Kept"),
|
||||
keptPillValue: result.kept,
|
||||
success: result.success,
|
||||
favorLabel: favor?.label ?? null,
|
||||
favorNote: favor?.note ?? null,
|
||||
details: [
|
||||
{ label: "Caracteristique", value: result.characteristic.label },
|
||||
{ label: "Valeur cible", value: result.target },
|
||||
{ label: game.i18n.localize("DNC.UI.Characteristic"), value: result.characteristic.label },
|
||||
{ label: game.i18n.localize("DNC.Chat.TargetValue"), value: result.target },
|
||||
...(favor ? [
|
||||
{ label: "Faveur", value: favor.label },
|
||||
{ label: "Dé de faveur", value: favor.result },
|
||||
{ label: "Avant", value: DonjonEtCieUtility.formatUsageDie(favor.before) },
|
||||
{ label: "Apres", value: DonjonEtCieUtility.formatUsageDie(favor.after) }
|
||||
{ label: game.i18n.localize("DNC.Chat.Favor"), value: favor.label },
|
||||
{ label: game.i18n.localize("DNC.Chat.FavorDie"), value: favor.result },
|
||||
{ label: game.i18n.localize("DNC.Chat.Before"), value: DonjonEtCieUtility.formatUsageDie(favor.before) },
|
||||
{ label: game.i18n.localize("DNC.Chat.After"), value: DonjonEtCieUtility.formatUsageDie(favor.after) }
|
||||
] : [])
|
||||
]
|
||||
});
|
||||
}, { rolls: [...(favor?.rolls ?? []), result.roll] });
|
||||
|
||||
return { ...result, favor, mode: effectiveMode };
|
||||
}
|
||||
@@ -245,7 +250,7 @@ export class DonjonEtCieRolls {
|
||||
mode: result.mode,
|
||||
modeLabel: this.#getModeLabel(result.mode),
|
||||
syncedCombat
|
||||
});
|
||||
}, { rolls: result.rolls });
|
||||
|
||||
return { total: result.kept, die, dieValues, dex, bonus: sheetBonus, mode: result.mode, syncedCombat };
|
||||
}
|
||||
@@ -270,7 +275,7 @@ export class DonjonEtCieRolls {
|
||||
formula: roll.formula,
|
||||
total: roll.total,
|
||||
dieValues
|
||||
});
|
||||
}, { rolls: [roll] });
|
||||
|
||||
return { formula: roll.formula, total: roll.total, dieValues };
|
||||
}
|
||||
@@ -297,7 +302,7 @@ export class DonjonEtCieRolls {
|
||||
targetPillValue: result.target,
|
||||
values: result.values,
|
||||
kept: result.kept,
|
||||
keptPillLabel: "Jet",
|
||||
keptPillLabel: game.i18n.localize("DNC.Chat.RollValue"),
|
||||
keptPillValue: result.kept,
|
||||
success: result.success,
|
||||
favorLabel: favor?.label ?? null,
|
||||
@@ -305,19 +310,19 @@ export class DonjonEtCieRolls {
|
||||
showDamageButton: result.success && Boolean(item.system.degats),
|
||||
itemUuid: item.uuid,
|
||||
details: [
|
||||
{ label: "Arme", value: item.name },
|
||||
{ label: "Caracteristique", value: characteristicLabel },
|
||||
{ label: game.i18n.localize("DNC.UI.Weapon"), value: item.name },
|
||||
{ label: game.i18n.localize("DNC.UI.Characteristic"), value: characteristicLabel },
|
||||
{ label: `Valeur de ${characteristicLabel}`, value: result.target },
|
||||
{ label: "Degats", value: item.system.degats || "—" },
|
||||
{ label: "Portee", value: item.system.portee || "—" },
|
||||
{ label: game.i18n.localize("DNC.UI.Damage"), value: item.system.degats || "—" },
|
||||
{ label: game.i18n.localize("DNC.UI.Range"), value: item.system.portee || "—" },
|
||||
...(favor ? [
|
||||
{ label: "Faveur", value: favor.label },
|
||||
{ label: "Dé de faveur", value: favor.result },
|
||||
{ label: "Avant", value: DonjonEtCieUtility.formatUsageDie(favor.before) },
|
||||
{ label: "Apres", value: DonjonEtCieUtility.formatUsageDie(favor.after) }
|
||||
{ label: game.i18n.localize("DNC.Chat.Favor"), value: favor.label },
|
||||
{ label: game.i18n.localize("DNC.Chat.FavorDie"), value: favor.result },
|
||||
{ label: game.i18n.localize("DNC.Chat.Before"), value: DonjonEtCieUtility.formatUsageDie(favor.before) },
|
||||
{ label: game.i18n.localize("DNC.Chat.After"), value: DonjonEtCieUtility.formatUsageDie(favor.after) }
|
||||
] : [])
|
||||
]
|
||||
});
|
||||
}, { rolls: [...(favor?.rolls ?? []), result.roll] });
|
||||
|
||||
return { ...result, favor, mode: effectiveMode };
|
||||
}
|
||||
@@ -350,7 +355,7 @@ export class DonjonEtCieRolls {
|
||||
sourceLabel: item.name,
|
||||
targets,
|
||||
hasTargets: targets.length > 0
|
||||
});
|
||||
}, { rolls: result.rolls });
|
||||
|
||||
return { total: result.kept, formula: result.formula, bonus: totalBonus, values: result.values, mode: result.mode };
|
||||
}
|
||||
@@ -388,6 +393,7 @@ export class DonjonEtCieRolls {
|
||||
static async rollSpell(actor, item, { mode = "normal", favorKey = "" } = {}) {
|
||||
const characteristicKey = item.system.caracteristique || "intelligence";
|
||||
const focus = await this.#ensureFocus(actor);
|
||||
const currentSceneId = DonjonEtCieUtility.getCurrentSceneId();
|
||||
const rank = Number(actor.system.anciennete?.rang ?? actor.system.sante?.dv ?? 0);
|
||||
const cost = Number(item.system.coutPv ?? 0);
|
||||
const autoDisadvantage = cost > rank;
|
||||
@@ -398,18 +404,23 @@ export class DonjonEtCieRolls {
|
||||
|
||||
if (!result) return null;
|
||||
|
||||
const currentPv = Number(actor.system.sante?.pv?.value ?? 0);
|
||||
const availableMagicHp = currentPv + focus.activeValue;
|
||||
const liveActor = game.actors.get(actor.id) ?? actor;
|
||||
const currentPv = Number(liveActor.system.sante?.pv?.value ?? 0);
|
||||
const currentFocusSceneId = liveActor.system.magie?.focus?.sceneId ?? "";
|
||||
const currentFocusValue = currentFocusSceneId === currentSceneId
|
||||
? Number(liveActor.system.magie?.focus?.resultat ?? 0)
|
||||
: 0;
|
||||
const availableMagicHp = currentPv + currentFocusValue;
|
||||
|
||||
if (cost > availableMagicHp) {
|
||||
ui.notifications.warn("Le lanceur ne dispose pas d'assez de PV et de focus pour payer ce sort.");
|
||||
ui.notifications.warn(game.i18n.localize("DNC.Warn.SpellInsufficientResources"));
|
||||
return null;
|
||||
}
|
||||
|
||||
const characteristicShort = DONJON_ET_CIE.characteristics[characteristicKey]?.short ?? characteristicKey;
|
||||
const success = result.isNaturalTwenty ? false : result.success;
|
||||
const focusSpent = result.isNaturalOne ? 0 : Math.min(cost, focus.activeValue);
|
||||
const focusRemaining = Math.max(focus.activeValue - focusSpent, 0);
|
||||
const focusSpent = result.isNaturalOne ? 0 : Math.min(cost, currentFocusValue);
|
||||
const focusRemaining = Math.max(currentFocusValue - focusSpent, 0);
|
||||
const spentPv = result.isNaturalOne ? 0 : Math.max(cost - focusSpent, 0);
|
||||
const remainingPv = Math.max(currentPv - spentPv, 0);
|
||||
const updateData = {};
|
||||
@@ -445,7 +456,7 @@ export class DonjonEtCieRolls {
|
||||
targetPillValue: result.target,
|
||||
values: result.values,
|
||||
kept: result.kept,
|
||||
keptPillLabel: "Jet",
|
||||
keptPillLabel: game.i18n.localize("DNC.Chat.RollValue"),
|
||||
keptPillValue: result.kept,
|
||||
success,
|
||||
specialNote,
|
||||
@@ -454,23 +465,23 @@ export class DonjonEtCieRolls {
|
||||
itemUuid: item.uuid,
|
||||
actorUuid: actor.uuid,
|
||||
details: [
|
||||
{ label: "Sortilege", value: item.name },
|
||||
{ label: "Caracteristique", value: result.characteristic.label },
|
||||
{ label: "Valeur de la caracteristique", value: result.target },
|
||||
{ label: "Cout en PV", value: cost },
|
||||
{ label: "Focus", value: focus.activeValue > 0 ? `${focus.activeValue} (${DonjonEtCieUtility.formatUsageDie(focus.before)})` : "—" },
|
||||
{ label: "Focus depense", value: focusSpent },
|
||||
{ label: "Focus restant", value: focusRemaining },
|
||||
{ label: "PV depenses", value: spentPv },
|
||||
{ label: "PV restants", value: remainingPv },
|
||||
{ label: "Rang du lanceur", value: rank },
|
||||
{ label: "Difficulte", value: item.system.difficulte ?? 0 },
|
||||
{ label: "Effet", value: item.system.effet || "—" },
|
||||
{ label: game.i18n.localize("DNC.UI.Spell"), value: item.name },
|
||||
{ label: game.i18n.localize("DNC.UI.Characteristic"), value: result.characteristic.label },
|
||||
{ label: game.i18n.localize("DNC.Chat.CharacteristicValue"), value: result.target },
|
||||
{ label: game.i18n.localize("DNC.Chat.HpCost"), value: cost },
|
||||
{ label: game.i18n.localize("DNC.UI.Focus"), value: focus.activeValue > 0 ? `${focus.activeValue} (${DonjonEtCieUtility.formatUsageDie(focus.before)})` : "—" },
|
||||
{ label: game.i18n.localize("DNC.Chat.FocusSpent"), value: focusSpent },
|
||||
{ label: game.i18n.localize("DNC.Chat.FocusRemaining"), value: focusRemaining },
|
||||
{ label: game.i18n.localize("DNC.Chat.HpSpent"), value: spentPv },
|
||||
{ label: game.i18n.localize("DNC.Chat.HpRemaining"), value: remainingPv },
|
||||
{ label: game.i18n.localize("DNC.Chat.CasterRank"), value: rank },
|
||||
{ label: game.i18n.localize("DNC.Chat.Difficulty"), value: item.system.difficulte ?? 0 },
|
||||
{ label: game.i18n.localize("DNC.Chat.Effect"), value: item.system.effet || "—" },
|
||||
...(favor ? [
|
||||
{ label: "Faveur", value: favor.label },
|
||||
{ label: "Dé de faveur", value: favor.result },
|
||||
{ label: "Avant", value: DonjonEtCieUtility.formatUsageDie(favor.before) },
|
||||
{ label: "Apres", value: DonjonEtCieUtility.formatUsageDie(favor.after) }
|
||||
{ label: game.i18n.localize("DNC.Chat.Favor"), value: favor.label },
|
||||
{ label: game.i18n.localize("DNC.Chat.FavorDie"), value: favor.result },
|
||||
{ label: game.i18n.localize("DNC.Chat.Before"), value: DonjonEtCieUtility.formatUsageDie(favor.before) },
|
||||
{ label: game.i18n.localize("DNC.Chat.After"), value: DonjonEtCieUtility.formatUsageDie(favor.after) }
|
||||
] : [])
|
||||
],
|
||||
focusRolled: focus.rolled,
|
||||
@@ -482,7 +493,7 @@ export class DonjonEtCieRolls {
|
||||
focusDegraded: focus.degraded,
|
||||
spentPv,
|
||||
remainingPv
|
||||
});
|
||||
}, { rolls: [...(favor?.rolls ?? []), ...(focus.rolls ?? []), result.roll] });
|
||||
|
||||
return { ...result, success, spentPv, remainingPv, cost, focus, focusSpent, focusRemaining, favor, mode: effectiveMode };
|
||||
}
|
||||
@@ -490,7 +501,7 @@ export class DonjonEtCieRolls {
|
||||
static async rollSpellChaos(actor, item) {
|
||||
const before = Number(actor?.system?.magie?.chaos?.delta ?? 12);
|
||||
if (!before || before < 4) {
|
||||
ui.notifications.warn("Le Chaos n'est pas disponible pour ce sort.");
|
||||
ui.notifications.warn(game.i18n.localize("DNC.Warn.ChaosUnavailable"));
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -513,7 +524,7 @@ export class DonjonEtCieRolls {
|
||||
degraded,
|
||||
exhausted: after < 4,
|
||||
itemName: item.name
|
||||
});
|
||||
}, { rolls: resolved.rolls });
|
||||
|
||||
return { result, before, after, degraded, chaosEntry };
|
||||
}
|
||||
@@ -551,7 +562,7 @@ export class DonjonEtCieRolls {
|
||||
protectionStored: item.type === "armure" ? result : null,
|
||||
degraded,
|
||||
exhausted: after === 0
|
||||
});
|
||||
}, { rolls: resolved.rolls });
|
||||
|
||||
return { result, values: resolved.values, mode: resolved.mode, before, after, degraded };
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ export class DonjonEtCieUtility {
|
||||
trait: "systems/fvtt-donjon-et-cie/assets/icons/system/items/trait.svg",
|
||||
sortilege: "systems/fvtt-donjon-et-cie/assets/icons/system/items/sortilege.svg",
|
||||
equipement: "systems/fvtt-donjon-et-cie/assets/icons/system/items/equipement.svg",
|
||||
entrainement: "systems/fvtt-donjon-et-cie/assets/icons/system/items/capacite.svg",
|
||||
other: "systems/fvtt-donjon-et-cie/assets/icons/system/items/autre.svg"
|
||||
};
|
||||
|
||||
@@ -33,6 +34,8 @@ export class DonjonEtCieUtility {
|
||||
"systems/fvtt-donjon-et-cie/templates/dialogs/damage-roll.hbs",
|
||||
"systems/fvtt-donjon-et-cie/templates/dialogs/spell-roll.hbs",
|
||||
"systems/fvtt-donjon-et-cie/templates/dialogs/usage-roll.hbs",
|
||||
"systems/fvtt-donjon-et-cie/templates/dialogs/mission-pack-dialog.hbs",
|
||||
"systems/fvtt-donjon-et-cie/templates/dialogs/mission-pack-campaign-dialog.hbs",
|
||||
"systems/fvtt-donjon-et-cie/templates/chat/roll-card.hbs",
|
||||
"systems/fvtt-donjon-et-cie/templates/chat/spell-card.hbs",
|
||||
"systems/fvtt-donjon-et-cie/templates/chat/chaos-card.hbs",
|
||||
@@ -42,7 +45,9 @@ export class DonjonEtCieUtility {
|
||||
"systems/fvtt-donjon-et-cie/templates/chat/favor-card.hbs",
|
||||
"systems/fvtt-donjon-et-cie/templates/chat/initiative-card.hbs",
|
||||
"systems/fvtt-donjon-et-cie/templates/chat/usage-card.hbs",
|
||||
"systems/fvtt-donjon-et-cie/templates/chat/item-card.hbs"
|
||||
"systems/fvtt-donjon-et-cie/templates/chat/item-card.hbs",
|
||||
"systems/fvtt-donjon-et-cie/templates/chat/mission-pack-card.hbs",
|
||||
"systems/fvtt-donjon-et-cie/templates/chat/welcome-card.hbs"
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -167,6 +172,13 @@ export class DonjonEtCieUtility {
|
||||
static enrichItemForSheet(item) {
|
||||
const system = item.system;
|
||||
const delta = Number(system.delta ?? 0);
|
||||
const deltaMax = Number(system.deltaMax ?? delta ?? 0);
|
||||
const usageLabel = item.type === "entrainement" && deltaMax > 0
|
||||
? `${this.formatUsageDie(delta)} / ${this.formatUsageDie(deltaMax)}`
|
||||
: delta > 0
|
||||
? this.formatUsageDie(delta)
|
||||
: null;
|
||||
|
||||
return {
|
||||
id: item.id,
|
||||
name: item.name,
|
||||
@@ -174,7 +186,7 @@ export class DonjonEtCieUtility {
|
||||
img: item.img,
|
||||
system,
|
||||
uuid: item.uuid,
|
||||
usageLabel: delta > 0 ? this.formatUsageDie(delta) : null,
|
||||
usageLabel,
|
||||
protectionLabel: item.type === "armure" && Number(system.resultatProtection ?? 0) > 0 ? `Protection ${system.resultatProtection}` : null,
|
||||
weaponCharacteristicLabel: item.type === "arme" ? this.getWeaponCharacteristicLabel(system.categorie) : null,
|
||||
canRoll: ["arme", "sortilege"].includes(item.type),
|
||||
@@ -182,7 +194,8 @@ export class DonjonEtCieUtility {
|
||||
canRollDamage: Boolean(system.degats),
|
||||
rollAction: item.type === "sortilege" ? "rollSpell" : "rollWeapon",
|
||||
damageAction: "rollDamage",
|
||||
isEquipped: Boolean(system.equipee)
|
||||
isEquipped: Boolean(system.equipee),
|
||||
canReset: item.type === "entrainement" && deltaMax > 0 && delta !== deltaMax
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
/**
|
||||
* Donjon & Cie - Systeme FoundryVTT
|
||||
*
|
||||
* Donjon & Cie est un jeu de role edite par John Doe.
|
||||
* Ce systeme FoundryVTT est une implementation independante et n'est pas
|
||||
* affilie a John Doe.
|
||||
*
|
||||
* @author LeRatierBretonnien
|
||||
* @copyright 2025–2026 LeRatierBretonnien
|
||||
* @license CC BY-NC-SA 4.0 – https://creativecommons.org/licenses/by-nc-sa/4.0/
|
||||
*/
|
||||
|
||||
import BaseItemDataModel from "./base-item.mjs";
|
||||
|
||||
export default class EntrainementDataModel extends BaseItemDataModel {
|
||||
static defineSchema() {
|
||||
const fields = foundry.data.fields;
|
||||
return {
|
||||
...super.defineSchema(),
|
||||
delta: new fields.NumberField({ initial: 4, integer: true }),
|
||||
deltaMax: new fields.NumberField({ initial: 4, integer: true }),
|
||||
effet: new fields.StringField({ initial: "" })
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -19,5 +19,6 @@ export { default as ArmeDataModel } from "./arme.mjs";
|
||||
export { default as ArmureDataModel } from "./armure.mjs";
|
||||
export { default as EquipementDataModel } from "./equipement.mjs";
|
||||
export { default as ConsommableDataModel } from "./consommable.mjs";
|
||||
export { default as EntrainementDataModel } from "./entrainement.mjs";
|
||||
export { default as EmployeDataModel } from "./employe.mjs";
|
||||
export { default as PnjDataModel } from "./pnj.mjs";
|
||||
|
||||
@@ -13,6 +13,11 @@
|
||||
export default class PnjDataModel extends foundry.abstract.TypeDataModel {
|
||||
static defineSchema() {
|
||||
const fields = foundry.data.fields;
|
||||
const makeAttack = () => new fields.SchemaField({
|
||||
nom: new fields.StringField({ initial: "Attaque" }),
|
||||
degats: new fields.StringField({ initial: "1d6" }),
|
||||
notes: new fields.StringField({ initial: "" })
|
||||
});
|
||||
|
||||
return {
|
||||
espece: new fields.StringField({ initial: "" }),
|
||||
@@ -35,10 +40,9 @@ export default class PnjDataModel extends foundry.abstract.TypeDataModel {
|
||||
delta: new fields.NumberField({ initial: 0, integer: true })
|
||||
})
|
||||
}),
|
||||
attaque: new fields.SchemaField({
|
||||
nom: new fields.StringField({ initial: "Attaque" }),
|
||||
degats: new fields.StringField({ initial: "1d6" }),
|
||||
notes: new fields.StringField({ initial: "" })
|
||||
attaque: makeAttack(),
|
||||
attaques: new fields.ArrayField(makeAttack(), {
|
||||
initial: [{ nom: "Attaque", degats: "1d6", notes: "" }]
|
||||
}),
|
||||
pouvoirsSpeciaux: new fields.HTMLField({ initial: "" }),
|
||||
description: new fields.HTMLField({ initial: "" }),
|
||||
|
||||
Generated
+739
@@ -9,12 +9,165 @@
|
||||
"version": "0.1.0",
|
||||
"license": "UNLICENSED",
|
||||
"devDependencies": {
|
||||
"@foundryvtt/foundryvtt-cli": "^1.1.0",
|
||||
"gulp": "^4.0.2",
|
||||
"gulp-less": "^5.0.0",
|
||||
"gulp-rename": "^2.0.0",
|
||||
"gulp-sourcemaps": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@foundryvtt/foundryvtt-cli": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@foundryvtt/foundryvtt-cli/-/foundryvtt-cli-1.1.0.tgz",
|
||||
"integrity": "sha512-ergKZDUSgQ79168r38ORyN4v/UTliA40rxElaUh5iS27Qw9H8Ep/ll8j3/HfiikO3XUDwYxZLfDJfbcyj2i9TQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"chalk": "^5.4.1",
|
||||
"classic-level": "^1.4.1",
|
||||
"esm": "^3.2.25",
|
||||
"js-yaml": "^4.1.0",
|
||||
"mkdirp": "^3.0.1",
|
||||
"nedb-promises": "^6.2.3",
|
||||
"yargs": "^17.7.2"
|
||||
},
|
||||
"bin": {
|
||||
"fvtt": "fvtt.mjs"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">17.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@foundryvtt/foundryvtt-cli/node_modules/ansi-regex": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
|
||||
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/@foundryvtt/foundryvtt-cli/node_modules/cliui": {
|
||||
"version": "8.0.1",
|
||||
"resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
|
||||
"integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"string-width": "^4.2.0",
|
||||
"strip-ansi": "^6.0.1",
|
||||
"wrap-ansi": "^7.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@foundryvtt/foundryvtt-cli/node_modules/get-caller-file": {
|
||||
"version": "2.0.5",
|
||||
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
|
||||
"integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": "6.* || 8.* || >= 10.*"
|
||||
}
|
||||
},
|
||||
"node_modules/@foundryvtt/foundryvtt-cli/node_modules/is-fullwidth-code-point": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
|
||||
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/@foundryvtt/foundryvtt-cli/node_modules/string-width": {
|
||||
"version": "4.2.3",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
|
||||
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"emoji-regex": "^8.0.0",
|
||||
"is-fullwidth-code-point": "^3.0.0",
|
||||
"strip-ansi": "^6.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/@foundryvtt/foundryvtt-cli/node_modules/strip-ansi": {
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
|
||||
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ansi-regex": "^5.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/@foundryvtt/foundryvtt-cli/node_modules/wrap-ansi": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
|
||||
"integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ansi-styles": "^4.0.0",
|
||||
"string-width": "^4.1.0",
|
||||
"strip-ansi": "^6.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/wrap-ansi?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/@foundryvtt/foundryvtt-cli/node_modules/y18n": {
|
||||
"version": "5.0.8",
|
||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
|
||||
"integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/@foundryvtt/foundryvtt-cli/node_modules/yargs": {
|
||||
"version": "17.7.2",
|
||||
"resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",
|
||||
"integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"cliui": "^8.0.1",
|
||||
"escalade": "^3.1.1",
|
||||
"get-caller-file": "^2.0.5",
|
||||
"require-directory": "^2.1.1",
|
||||
"string-width": "^4.2.3",
|
||||
"y18n": "^5.0.5",
|
||||
"yargs-parser": "^21.1.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@foundryvtt/foundryvtt-cli/node_modules/yargs-parser": {
|
||||
"version": "21.1.1",
|
||||
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
|
||||
"integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@gulp-sourcemaps/identity-map": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@gulp-sourcemaps/identity-map/-/identity-map-2.0.1.tgz",
|
||||
@@ -81,6 +234,67 @@
|
||||
"xtend": "~4.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@seald-io/binary-search-tree": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@seald-io/binary-search-tree/-/binary-search-tree-1.0.3.tgz",
|
||||
"integrity": "sha512-qv3jnwoakeax2razYaMsGI/luWdliBLHTdC6jU55hQt1hcFqzauH/HsBollQ7IR4ySTtYhT+xyHoijpA16C+tA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@seald-io/nedb": {
|
||||
"version": "4.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@seald-io/nedb/-/nedb-4.1.2.tgz",
|
||||
"integrity": "sha512-bDr6TqjBVS2rDyYM9CPxAnotj5FuNL9NF8o7h7YyFXM7yruqT4ddr+PkSb2mJvvw991bqdftazkEo38gykvaww==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@seald-io/binary-search-tree": "^1.0.3",
|
||||
"localforage": "^1.10.0",
|
||||
"util": "^0.12.5"
|
||||
}
|
||||
},
|
||||
"node_modules/abstract-level": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/abstract-level/-/abstract-level-1.0.4.tgz",
|
||||
"integrity": "sha512-eUP/6pbXBkMbXFdx4IH2fVgvB7M0JvR7/lIL33zcs0IBcwjdzSSl31TOJsaCzmKSSDF9h8QYSOJux4Nd4YJqFg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"buffer": "^6.0.3",
|
||||
"catering": "^2.1.0",
|
||||
"is-buffer": "^2.0.5",
|
||||
"level-supports": "^4.0.0",
|
||||
"level-transcoder": "^1.0.1",
|
||||
"module-error": "^1.0.1",
|
||||
"queue-microtask": "^1.2.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/abstract-level/node_modules/is-buffer": {
|
||||
"version": "2.0.5",
|
||||
"resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz",
|
||||
"integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/feross"
|
||||
},
|
||||
{
|
||||
"type": "patreon",
|
||||
"url": "https://www.patreon.com/feross"
|
||||
},
|
||||
{
|
||||
"type": "consulting",
|
||||
"url": "https://feross.org/support"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/acorn": {
|
||||
"version": "6.4.2",
|
||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz",
|
||||
@@ -130,6 +344,22 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/ansi-styles": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
|
||||
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"color-convert": "^2.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/ansi-wrap": {
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-wrap/-/ansi-wrap-0.1.0.tgz",
|
||||
@@ -184,6 +414,13 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/argparse": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
|
||||
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
|
||||
"dev": true,
|
||||
"license": "Python-2.0"
|
||||
},
|
||||
"node_modules/arr-diff": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
|
||||
@@ -397,6 +634,22 @@
|
||||
"node": ">= 4.5.0"
|
||||
}
|
||||
},
|
||||
"node_modules/available-typed-arrays": {
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz",
|
||||
"integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"possible-typed-array-names": "^1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/bach": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/bach/-/bach-1.2.0.tgz",
|
||||
@@ -457,6 +710,27 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/base64-js": {
|
||||
"version": "1.5.1",
|
||||
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
|
||||
"integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/feross"
|
||||
},
|
||||
{
|
||||
"type": "patreon",
|
||||
"url": "https://www.patreon.com/feross"
|
||||
},
|
||||
{
|
||||
"type": "consulting",
|
||||
"url": "https://feross.org/support"
|
||||
}
|
||||
],
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/binary-extensions": {
|
||||
"version": "1.13.1",
|
||||
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz",
|
||||
@@ -511,6 +785,31 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/buffer": {
|
||||
"version": "6.0.3",
|
||||
"resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz",
|
||||
"integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/feross"
|
||||
},
|
||||
{
|
||||
"type": "patreon",
|
||||
"url": "https://www.patreon.com/feross"
|
||||
},
|
||||
{
|
||||
"type": "consulting",
|
||||
"url": "https://feross.org/support"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"base64-js": "^1.3.1",
|
||||
"ieee754": "^1.2.1"
|
||||
}
|
||||
},
|
||||
"node_modules/buffer-equal": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-1.0.1.tgz",
|
||||
@@ -612,6 +911,29 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/catering": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/catering/-/catering-2.1.1.tgz",
|
||||
"integrity": "sha512-K7Qy8O9p76sL3/3m7/zLKbRkyOlSZAgzEaLhyj2mXS8PsCud2Eo4hAb8aLtZqHh0QGqLcb9dlJSu6lHRVENm1w==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/chalk": {
|
||||
"version": "5.6.2",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz",
|
||||
"integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": "^12.17.0 || ^14.13 || >=16.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/chalk?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/chokidar": {
|
||||
"version": "2.1.8",
|
||||
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz",
|
||||
@@ -678,6 +1000,24 @@
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/classic-level": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/classic-level/-/classic-level-1.4.1.tgz",
|
||||
"integrity": "sha512-qGx/KJl3bvtOHrGau2WklEZuXhS3zme+jf+fsu6Ej7W7IP/C49v7KNlWIsT1jZu0YnfzSIYDGcEWpCa1wKGWXQ==",
|
||||
"dev": true,
|
||||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"abstract-level": "^1.0.2",
|
||||
"catering": "^2.1.0",
|
||||
"module-error": "^1.0.1",
|
||||
"napi-macros": "^2.2.2",
|
||||
"node-gyp-build": "^4.3.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/cliui": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz",
|
||||
@@ -768,6 +1108,26 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/color-convert": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
||||
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"color-name": "~1.1.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=7.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/color-name": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
|
||||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/color-support": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz",
|
||||
@@ -1075,6 +1435,13 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/emoji-regex": {
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
|
||||
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/end-of-stream": {
|
||||
"version": "1.4.5",
|
||||
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz",
|
||||
@@ -1198,6 +1565,26 @@
|
||||
"es6-symbol": "^3.1.1"
|
||||
}
|
||||
},
|
||||
"node_modules/escalade": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
|
||||
"integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/esm": {
|
||||
"version": "3.2.25",
|
||||
"resolved": "https://registry.npmjs.org/esm/-/esm-3.2.25.tgz",
|
||||
"integrity": "sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/esniff": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/esniff/-/esniff-2.0.1.tgz",
|
||||
@@ -1492,6 +1879,22 @@
|
||||
"readable-stream": "^2.3.6"
|
||||
}
|
||||
},
|
||||
"node_modules/for-each": {
|
||||
"version": "0.3.5",
|
||||
"resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz",
|
||||
"integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"is-callable": "^1.2.7"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/for-in": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
|
||||
@@ -1590,6 +1993,16 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/generator-function": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/generator-function/-/generator-function-2.0.1.tgz",
|
||||
"integrity": "sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/get-caller-file": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz",
|
||||
@@ -1951,6 +2364,22 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/has-tostringtag": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
|
||||
"integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"has-symbols": "^1.0.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/has-value": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz",
|
||||
@@ -2040,6 +2469,27 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/ieee754": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
|
||||
"integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/feross"
|
||||
},
|
||||
{
|
||||
"type": "patreon",
|
||||
"url": "https://www.patreon.com/feross"
|
||||
},
|
||||
{
|
||||
"type": "consulting",
|
||||
"url": "https://feross.org/support"
|
||||
}
|
||||
],
|
||||
"license": "BSD-3-Clause"
|
||||
},
|
||||
"node_modules/image-size": {
|
||||
"version": "0.5.5",
|
||||
"resolved": "https://registry.npmjs.org/image-size/-/image-size-0.5.5.tgz",
|
||||
@@ -2054,6 +2504,13 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/immediate": {
|
||||
"version": "3.0.6",
|
||||
"resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz",
|
||||
"integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/inflight": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
|
||||
@@ -2127,6 +2584,23 @@
|
||||
"node": ">= 0.10"
|
||||
}
|
||||
},
|
||||
"node_modules/is-arguments": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.2.0.tgz",
|
||||
"integrity": "sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"call-bound": "^1.0.2",
|
||||
"has-tostringtag": "^1.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/is-arrayish": {
|
||||
"version": "0.2.1",
|
||||
"resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
|
||||
@@ -2154,6 +2628,19 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/is-callable": {
|
||||
"version": "1.2.7",
|
||||
"resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz",
|
||||
"integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/is-core-module": {
|
||||
"version": "2.16.1",
|
||||
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz",
|
||||
@@ -2230,6 +2717,26 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/is-generator-function": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.2.tgz",
|
||||
"integrity": "sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"call-bound": "^1.0.4",
|
||||
"generator-function": "^2.0.0",
|
||||
"get-proto": "^1.0.1",
|
||||
"has-tostringtag": "^1.0.2",
|
||||
"safe-regex-test": "^1.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/is-glob": {
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
|
||||
@@ -2296,6 +2803,25 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/is-regex": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz",
|
||||
"integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"call-bound": "^1.0.2",
|
||||
"gopd": "^1.2.0",
|
||||
"has-tostringtag": "^1.0.2",
|
||||
"hasown": "^2.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/is-relative": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz",
|
||||
@@ -2309,6 +2835,22 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/is-typed-array": {
|
||||
"version": "1.1.15",
|
||||
"resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz",
|
||||
"integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"which-typed-array": "^1.1.16"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/is-unc-path": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz",
|
||||
@@ -2386,6 +2928,19 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/js-yaml": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz",
|
||||
"integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"argparse": "^2.0.1"
|
||||
},
|
||||
"bin": {
|
||||
"js-yaml": "bin/js-yaml.js"
|
||||
}
|
||||
},
|
||||
"node_modules/json-stable-stringify-without-jsonify": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
|
||||
@@ -2489,6 +3044,40 @@
|
||||
"source-map": "~0.6.0"
|
||||
}
|
||||
},
|
||||
"node_modules/level-supports": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/level-supports/-/level-supports-4.0.1.tgz",
|
||||
"integrity": "sha512-PbXpve8rKeNcZ9C1mUicC9auIYFyGpkV9/i6g76tLgANwWhtG2v7I4xNBUlkn3lE2/dZF3Pi0ygYGtLc4RXXdA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/level-transcoder": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/level-transcoder/-/level-transcoder-1.0.1.tgz",
|
||||
"integrity": "sha512-t7bFwFtsQeD8cl8NIoQ2iwxA0CL/9IFw7/9gAjOonH0PWTTiRfY7Hq+Ejbsxh86tXobDQ6IOiddjNYIfOBs06w==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"buffer": "^6.0.3",
|
||||
"module-error": "^1.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/lie": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/lie/-/lie-3.1.1.tgz",
|
||||
"integrity": "sha512-RiNhHysUjhrDQntfYSfY4MU24coXXdEOgw9WGcKHNeEwffDYbF//u87M1EWaMGzuFoSbqW0C9C6lEEhDOAswfw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"immediate": "~3.0.5"
|
||||
}
|
||||
},
|
||||
"node_modules/liftoff": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/liftoff/-/liftoff-3.1.0.tgz",
|
||||
@@ -2549,6 +3138,16 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/localforage": {
|
||||
"version": "1.10.0",
|
||||
"resolved": "https://registry.npmjs.org/localforage/-/localforage-1.10.0.tgz",
|
||||
"integrity": "sha512-14/H1aX7hzBBmmh7sGPd+AOMkkIrHM3Z1PAyGgZigA1H1p5O5ANnMyWzvpAETtG68/dC4pC0ncy3+PPGzXZHPg==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"lie": "3.1.1"
|
||||
}
|
||||
},
|
||||
"node_modules/lru-queue": {
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/lru-queue/-/lru-queue-0.1.0.tgz",
|
||||
@@ -2837,6 +3436,32 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/mkdirp": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz",
|
||||
"integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"mkdirp": "dist/cjs/src/bin.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/module-error": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/module-error/-/module-error-1.0.2.tgz",
|
||||
"integrity": "sha512-0yuvsqSCv8LbaOKhnsQ/T5JhyFlCYLPXK3U2sgV10zoKQwzs/MyfuQUOZQ1V/6OCOJsK/TRgNVrPuPDqtdMFtA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/ms": {
|
||||
"version": "2.1.3",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||
@@ -2935,6 +3560,23 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/napi-macros": {
|
||||
"version": "2.2.2",
|
||||
"resolved": "https://registry.npmjs.org/napi-macros/-/napi-macros-2.2.2.tgz",
|
||||
"integrity": "sha512-hmEVtAGYzVQpCKdbQea4skABsdXW4RUh5t5mJ2zzqowJS2OyXZTU1KhDVFhx+NlWZ4ap9mqR9TcDO3LTTttd+g==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/nedb-promises": {
|
||||
"version": "6.2.3",
|
||||
"resolved": "https://registry.npmjs.org/nedb-promises/-/nedb-promises-6.2.3.tgz",
|
||||
"integrity": "sha512-enq0IjNyBz9Qy9W/QPCcLGh/QORGBjXbIeZeWvIjO3OMLyAvlKT3hiJubP2BKEiFniUlR3L01o18ktqgn5jxqA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@seald-io/nedb": "^4.0.2"
|
||||
}
|
||||
},
|
||||
"node_modules/needle": {
|
||||
"version": "3.5.0",
|
||||
"resolved": "https://registry.npmjs.org/needle/-/needle-3.5.0.tgz",
|
||||
@@ -2960,6 +3602,18 @@
|
||||
"dev": true,
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/node-gyp-build": {
|
||||
"version": "4.8.4",
|
||||
"resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.4.tgz",
|
||||
"integrity": "sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"node-gyp-build": "bin.js",
|
||||
"node-gyp-build-optional": "optional.js",
|
||||
"node-gyp-build-test": "build-test.js"
|
||||
}
|
||||
},
|
||||
"node_modules/normalize-package-data": {
|
||||
"version": "2.5.0",
|
||||
"resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz",
|
||||
@@ -3455,6 +4109,16 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/possible-typed-array-names": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz",
|
||||
"integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/postcss": {
|
||||
"version": "7.0.39",
|
||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
|
||||
@@ -3521,6 +4185,27 @@
|
||||
"pump": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/queue-microtask": {
|
||||
"version": "1.2.3",
|
||||
"resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
|
||||
"integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/feross"
|
||||
},
|
||||
{
|
||||
"type": "patreon",
|
||||
"url": "https://www.patreon.com/feross"
|
||||
},
|
||||
{
|
||||
"type": "consulting",
|
||||
"url": "https://feross.org/support"
|
||||
}
|
||||
],
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/read-pkg": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz",
|
||||
@@ -3840,6 +4525,24 @@
|
||||
"ret": "~0.1.10"
|
||||
}
|
||||
},
|
||||
"node_modules/safe-regex-test": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz",
|
||||
"integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"call-bound": "^1.0.2",
|
||||
"es-errors": "^1.3.0",
|
||||
"is-regex": "^1.2.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/safer-buffer": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
|
||||
@@ -4727,6 +5430,20 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/util": {
|
||||
"version": "0.12.5",
|
||||
"resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz",
|
||||
"integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"inherits": "^2.0.3",
|
||||
"is-arguments": "^1.0.4",
|
||||
"is-generator-function": "^1.0.7",
|
||||
"is-typed-array": "^1.1.3",
|
||||
"which-typed-array": "^1.1.2"
|
||||
}
|
||||
},
|
||||
"node_modules/util-deprecate": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||
@@ -4908,6 +5625,28 @@
|
||||
"dev": true,
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/which-typed-array": {
|
||||
"version": "1.1.20",
|
||||
"resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.20.tgz",
|
||||
"integrity": "sha512-LYfpUkmqwl0h9A2HL09Mms427Q1RZWuOHsukfVcKRq9q95iQxdw0ix1JQrqbcDR9PH1QDwf5Qo8OZb5lksZ8Xg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"available-typed-arrays": "^1.0.7",
|
||||
"call-bind": "^1.0.8",
|
||||
"call-bound": "^1.0.4",
|
||||
"for-each": "^0.3.5",
|
||||
"get-proto": "^1.0.1",
|
||||
"gopd": "^1.2.0",
|
||||
"has-tostringtag": "^1.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/wrap-ansi": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz",
|
||||
|
||||
+5
-2
@@ -4,11 +4,14 @@
|
||||
"description": "Systeme FoundryVTT pour Donjon & Cie",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"build": "gulp build",
|
||||
"watch": "gulp watch"
|
||||
"build": "gulp build && npm run pack:compendiums",
|
||||
"watch": "gulp watch",
|
||||
"pack:compendiums": "node ./tools/packCompendiums.mjs",
|
||||
"unpack:compendiums": "node ./tools/unpackCompendiums.mjs"
|
||||
},
|
||||
"license": "UNLICENSED",
|
||||
"devDependencies": {
|
||||
"@foundryvtt/foundryvtt-cli": "^1.1.0",
|
||||
"gulp": "^4.0.2",
|
||||
"gulp-less": "^5.0.0",
|
||||
"gulp-rename": "^2.0.0",
|
||||
|
||||
@@ -1 +1 @@
|
||||
MANIFEST-000019
|
||||
MANIFEST-000077
|
||||
|
||||
+7
-3
@@ -1,3 +1,7 @@
|
||||
2026/04/13-20:45:52.211396 7f68497ed6c0 Recovering log #17
|
||||
2026/04/13-20:45:52.220887 7f68497ed6c0 Delete type=3 #15
|
||||
2026/04/13-20:45:52.220974 7f68497ed6c0 Delete type=0 #17
|
||||
2026/05/09-23:26:00.662378 7fe6d3fff6c0 Recovering log #75
|
||||
2026/05/09-23:26:00.714642 7fe6d3fff6c0 Delete type=3 #73
|
||||
2026/05/09-23:26:00.714705 7fe6d3fff6c0 Delete type=0 #75
|
||||
2026/05/09-23:32:35.906147 7fe6d37fe6c0 Level-0 table #80: started
|
||||
2026/05/09-23:32:35.906185 7fe6d37fe6c0 Level-0 table #80: 0 bytes OK
|
||||
2026/05/09-23:32:35.912511 7fe6d37fe6c0 Delete type=0 #78
|
||||
2026/05/09-23:32:35.920264 7fe6d37fe6c0 Manual compaction at level-0 from '!folders!K9aiFu0dE6UYiXBd' @ 72057594037927935 : 1 .. '!items!zyqLzmpbHxK3jt5q' @ 0 : 0; will stop at (end)
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
2026/04/13-15:38:21.573543 7f2a6bfff6c0 Recovering log #12
|
||||
2026/04/13-15:38:21.584944 7f2a6bfff6c0 Delete type=3 #10
|
||||
2026/04/13-15:38:21.585068 7f2a6bfff6c0 Delete type=0 #12
|
||||
2026/04/13-15:53:03.495112 7f2a69ffb6c0 Level-0 table #18: started
|
||||
2026/04/13-15:53:03.495152 7f2a69ffb6c0 Level-0 table #18: 0 bytes OK
|
||||
2026/04/13-15:53:03.502660 7f2a69ffb6c0 Delete type=0 #16
|
||||
2026/04/13-15:53:03.512745 7f2a69ffb6c0 Manual compaction at level-0 from '!folders!K9aiFu0dE6UYiXBd' @ 72057594037927935 : 1 .. '!items!zyqLzmpbHxK3jt5q' @ 0 : 0; will stop at (end)
|
||||
2026/04/13-15:53:03.512766 7f2a69ffb6c0 Manual compaction at level-1 from '!folders!K9aiFu0dE6UYiXBd' @ 72057594037927935 : 1 .. '!items!zyqLzmpbHxK3jt5q' @ 0 : 0; will stop at (end)
|
||||
2026/05/09-23:24:27.244461 7fe6d3fff6c0 Recovering log #71
|
||||
2026/05/09-23:24:27.261516 7fe6d3fff6c0 Delete type=3 #69
|
||||
2026/05/09-23:24:27.261564 7fe6d3fff6c0 Delete type=0 #71
|
||||
2026/05/09-23:25:01.848661 7fe6d37fe6c0 Level-0 table #76: started
|
||||
2026/05/09-23:25:01.848715 7fe6d37fe6c0 Level-0 table #76: 0 bytes OK
|
||||
2026/05/09-23:25:01.854909 7fe6d37fe6c0 Delete type=0 #74
|
||||
2026/05/09-23:25:01.877929 7fe6d37fe6c0 Manual compaction at level-0 from '!folders!K9aiFu0dE6UYiXBd' @ 72057594037927935 : 1 .. '!items!zyqLzmpbHxK3jt5q' @ 0 : 0; will stop at (end)
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1 +1 @@
|
||||
MANIFEST-000006
|
||||
MANIFEST-000064
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
2026/04/13-20:45:52.223768 7f6849fee6c0 Recovering log #4
|
||||
2026/04/13-20:45:52.234123 7f6849fee6c0 Delete type=3 #2
|
||||
2026/04/13-20:45:52.234212 7f6849fee6c0 Delete type=0 #4
|
||||
2026/05/09-23:26:00.734399 7fe7211fe6c0 Recovering log #62
|
||||
2026/05/09-23:26:00.785619 7fe7211fe6c0 Delete type=3 #60
|
||||
2026/05/09-23:26:00.785680 7fe7211fe6c0 Delete type=0 #62
|
||||
2026/05/09-23:32:35.893861 7fe6d37fe6c0 Level-0 table #67: started
|
||||
2026/05/09-23:32:35.893901 7fe6d37fe6c0 Level-0 table #67: 0 bytes OK
|
||||
2026/05/09-23:32:35.899905 7fe6d37fe6c0 Delete type=0 #65
|
||||
2026/05/09-23:32:35.920244 7fe6d37fe6c0 Manual compaction at level-0 from '!tables!PPsxQgHwLCQ2gjSW' @ 72057594037927935 : 1 .. '!tables.results!wJZXUo4q5b5vE3Dy.zFTPLMc9zOl5hISV' @ 0 : 0; will stop at (end)
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
2026/04/13-15:38:21.601302 7f2a6a7fc6c0 Delete type=3 #1
|
||||
2026/04/13-15:53:03.477052 7f2a69ffb6c0 Level-0 table #5: started
|
||||
2026/04/13-15:53:03.481742 7f2a69ffb6c0 Level-0 table #5: 39147 bytes OK
|
||||
2026/04/13-15:53:03.488722 7f2a69ffb6c0 Delete type=0 #3
|
||||
2026/04/13-15:53:03.512725 7f2a69ffb6c0 Manual compaction at level-0 from '!tables!PPsxQgHwLCQ2gjSW' @ 72057594037927935 : 1 .. '!tables.results!wJZXUo4q5b5vE3Dy.zFTPLMc9zOl5hISV' @ 0 : 0; will stop at (end)
|
||||
2026/05/09-23:24:27.266509 7fe7211fe6c0 Recovering log #58
|
||||
2026/05/09-23:24:27.282592 7fe7211fe6c0 Delete type=3 #56
|
||||
2026/05/09-23:24:27.282660 7fe7211fe6c0 Delete type=0 #58
|
||||
2026/05/09-23:25:01.864644 7fe6d37fe6c0 Level-0 table #63: started
|
||||
2026/05/09-23:25:01.864678 7fe6d37fe6c0 Level-0 table #63: 0 bytes OK
|
||||
2026/05/09-23:25:01.871922 7fe6d37fe6c0 Delete type=0 #61
|
||||
2026/05/09-23:25:01.877952 7fe6d37fe6c0 Manual compaction at level-0 from '!tables!PPsxQgHwLCQ2gjSW' @ 72057594037927935 : 1 .. '!tables.results!wJZXUo4q5b5vE3Dy.zFTPLMc9zOl5hISV' @ 0 : 0; will stop at (end)
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1 @@
|
||||
MANIFEST-000002
|
||||
@@ -0,0 +1,5 @@
|
||||
2026/05/09-23:29:14.636398 7f54217ed6c0 Delete type=3 #1
|
||||
2026/05/09-23:29:14.638741 7f5403fff6c0 Level-0 table #5: started
|
||||
2026/05/09-23:29:14.666649 7f5403fff6c0 Level-0 table #5: 3056 bytes OK
|
||||
2026/05/09-23:29:14.731617 7f5403fff6c0 Delete type=0 #3
|
||||
2026/05/09-23:29:14.731832 7f5403fff6c0 Manual compaction at level-0 from '!journal!69Da9YvF9BfOV7oK' @ 72057594037927935 : 1 .. '!journal.pages!69Da9YvF9BfOV7oK.XM0eLkgKXPyskV65' @ 0 : 0; will stop at (end)
|
||||
@@ -0,0 +1,41 @@
|
||||
{
|
||||
"_id": "69Da9YvF9BfOV7oK",
|
||||
"name": "Aide du systeme",
|
||||
"folder": null,
|
||||
"categories": [],
|
||||
"sort": 0,
|
||||
"_key": "!journal!69Da9YvF9BfOV7oK",
|
||||
"ownership": {
|
||||
"default": 0
|
||||
},
|
||||
"flags": {},
|
||||
"pages": [
|
||||
{
|
||||
"_id": "XM0eLkgKXPyskV65",
|
||||
"name": "Guide",
|
||||
"type": "text",
|
||||
"title": {
|
||||
"show": true,
|
||||
"level": 1
|
||||
},
|
||||
"text": {
|
||||
"format": 1,
|
||||
"content": "<section>\n <h1>Donjon & Cie — Aide du systeme</h1>\n <p>Ce journal presente les principaux ecrans et usages du systeme FoundryVTT pour <strong>Donjon & Cie</strong>. Il suit l'organisation du jeu : employes, PNJ, objets, ressources magiques, jets et outils MJ.</p>\n</section>\n<section>\n <h2>1. Fiche Employe</h2>\n <p>La fiche <strong>Employe</strong> regroupe les informations essentielles du personnage : concept, anciennete, DV, PV, attaques, caracteristiques et inventaire. Les trois onglets organisent le jeu en <em>Combat & materiel</em>, <em>Magie & capacites</em> et <em>Profil & langues</em>.</p>\n <ul>\n <li><strong>DV</strong> et <strong>PV</strong> sont accessibles en haut de fiche.</li>\n <li>Les sections d'objets acceptent le glisser-deposer depuis le repertoire des items ou les compendiums.</li>\n <li>Les boutons d'action permettent de lancer un jet, les degats, ou publier un objet dans le chat.</li>\n </ul>\n <figure>\n <img src=\"systems/fvtt-donjon-et-cie/assets/help/employe-sheet.png\" alt=\"Fiche employe\" />\n <figcaption>La fiche Employe centralise combat, equipement et ressources.</figcaption>\n </figure>\n</section>\n<section>\n <h2>2. Magie, focus, chaos et capacites</h2>\n <p>L'onglet <strong>Magie & capacites</strong> rassemble les ressources du lanceur de sorts :</p>\n <ul>\n <li>le <strong>Rang</strong>, le <strong>Focus</strong> et le <strong>Chaos</strong> ;</li>\n <li>la <strong>Table du Chaos</strong> pour resoudre rapidement les incidents magiques ;</li>\n <li>la liste des <strong>Sortileges</strong>, avec les <strong>Capacites</strong> affichees juste en dessous.</li>\n </ul>\n <p>Les boutons de ligne permettent de lancer le sort, ses degats, ou de poster sa fiche dans le chat.</p>\n <figure>\n <img src=\"systems/fvtt-donjon-et-cie/assets/help/magie-capacites.png\" alt=\"Onglet magie et capacites\" />\n <figcaption>Les Capacites sont placees sous les Sortileges pour rester coherentes avec les regles et la lecture de fiche.</figcaption>\n </figure>\n</section>\n<section>\n <h2>3. Fiche PNJ</h2>\n <p>La fiche <strong>PNJ</strong> est optimisee pour le jeu rapide :</p>\n <ul>\n <li>valeurs de <strong>DV</strong>, <strong>PV</strong>, <strong>ARM</strong> et <strong>COU</strong> en acces direct ;</li>\n <li>liste d'<strong>attaques multiples</strong> editable ligne par ligne ;</li>\n <li>bouton de jet de degats sur chaque attaque.</li>\n </ul>\n <p>Le layout favorise le nom de l'attaque, avec des tooltips sur les champs pour garder une interface compacte.</p>\n <figure>\n <img src=\"systems/fvtt-donjon-et-cie/assets/help/pnj-sheet.png\" alt=\"Fiche PNJ\" />\n <figcaption>Un PNJ peut maintenant posseder plusieurs attaques distinctes.</figcaption>\n </figure>\n</section>\n<section>\n <h2>4. Paquetage de mission</h2>\n <p>Le MJ dispose d'un outil de <strong>Paquetage</strong> accessible depuis le haut du repertoire des acteurs. Il ouvre un dialogue permettant de choisir l'employe cible puis de lancer la dotation de debut de mission.</p>\n <ul>\n <li>Le systeme tire silencieusement sur les tables d'armes, armures et equipement divers.</li>\n <li>Les objets trouves sont ajoutes automatiquement a la fiche du personnage.</li>\n <li>Un message de synthese est publie dans le chat.</li>\n </ul>\n <figure>\n <img src=\"systems/fvtt-donjon-et-cie/assets/help/mission-pack-dialog.png\" alt=\"Dialogue de paquetage de mission\" />\n <figcaption>Le bouton Paquetage ouvre un dialogue MJ pour attribuer rapidement la dotation d'entree en mission.</figcaption>\n </figure>\n</section>\n<section>\n <h2>5. Jets et messages de chat</h2>\n <p>Les cartes de chat servent d'interface de resolution. On y retrouve selon les cas :</p>\n <ul>\n <li>les resultats de jets de caracteristique, d'attaque, de degats et de magie ;</li>\n <li>les usages de ressources a de d'usure ;</li>\n <li>les syntheses de paquetage et d'autres actions systeme.</li>\n </ul>\n <p>Quand un objet ou une action propose un bouton <em>Poster dans le chat</em>, cela permet de partager proprement l'information avec la table sans ouvrir la fiche du document.</p>\n</section>\n<section>\n <h2>6. Conseils d'utilisation</h2>\n <ul>\n <li>Utilisez le glisser-deposer pour equiper rapidement un employe.</li>\n <li>Gardez les PNJ ouverts pendant les scenes pour acceder vite a leurs attaques et defenses.</li>\n <li>Le sidebar <strong>Acteurs</strong> concentre les outils MJ utiles, notamment le paquetage de mission.</li>\n <li>Les compendiums du systeme contiennent l'equipement et les tables aleatoires servant de base au jeu.</li>\n </ul>\n</section>"
|
||||
},
|
||||
"system": {},
|
||||
"image": {},
|
||||
"video": {
|
||||
"controls": true,
|
||||
"volume": 0.5
|
||||
},
|
||||
"src": null,
|
||||
"category": null,
|
||||
"sort": 0,
|
||||
"ownership": {
|
||||
"default": -1
|
||||
},
|
||||
"flags": {},
|
||||
"_key": "!journal.pages!69Da9YvF9BfOV7oK.XM0eLkgKXPyskV65"
|
||||
}
|
||||
]
|
||||
}
|
||||
+251
-76
@@ -57,7 +57,7 @@
|
||||
gap: 1rem;
|
||||
padding: 1rem;
|
||||
}
|
||||
.sheet-card {
|
||||
.dnc-sheet .sheet-card {
|
||||
border: 2px solid #5b4634;
|
||||
border-radius: 10px;
|
||||
background: rgba(255, 248, 236, 0.92);
|
||||
@@ -73,20 +73,20 @@
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.04em;
|
||||
}
|
||||
.sheet-header {
|
||||
.dnc-sheet .sheet-header {
|
||||
display: grid;
|
||||
grid-template-columns: 140px 1fr;
|
||||
gap: 1rem;
|
||||
align-items: start;
|
||||
}
|
||||
.sheet-header.compact {
|
||||
.dnc-sheet .sheet-header.compact {
|
||||
grid-template-columns: 110px 1fr;
|
||||
gap: 0.75rem;
|
||||
}
|
||||
.portrait {
|
||||
.dnc-sheet .portrait {
|
||||
position: relative;
|
||||
}
|
||||
.portrait img {
|
||||
.dnc-sheet .portrait img {
|
||||
width: 100%;
|
||||
aspect-ratio: 1;
|
||||
object-fit: cover;
|
||||
@@ -94,7 +94,7 @@
|
||||
border: 3px solid #5b4634;
|
||||
background: #fff;
|
||||
}
|
||||
.icon-button {
|
||||
.dnc-sheet .icon-button {
|
||||
position: absolute;
|
||||
right: 0.4rem;
|
||||
bottom: 0.4rem;
|
||||
@@ -105,13 +105,13 @@
|
||||
width: 2rem;
|
||||
height: 2rem;
|
||||
}
|
||||
.identity-grid,
|
||||
.identity-grid.two-columns {
|
||||
.dnc-sheet .identity-grid,
|
||||
.dnc-sheet .identity-grid.two-columns {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, minmax(0, 1fr));
|
||||
gap: 0.75rem;
|
||||
}
|
||||
.identity-grid.two-columns {
|
||||
.dnc-sheet .identity-grid.two-columns {
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
}
|
||||
.dnc-employe-sheet .sheet-header.compact .identity-grid {
|
||||
@@ -121,11 +121,16 @@
|
||||
.dnc-employe-sheet .sheet-header.compact label {
|
||||
gap: 0.25rem;
|
||||
}
|
||||
.dnc-employe-sheet .sheet-header.compact .hp-field {
|
||||
grid-column: span 2;
|
||||
}
|
||||
.dnc-employe-sheet .sheet-header.compact input[type="number"] {
|
||||
max-width: 4.75rem;
|
||||
}
|
||||
.dnc-employe-sheet .sheet-header.compact .counter-field input[type="number"] {
|
||||
max-width: 4rem;
|
||||
.dnc-employe-sheet .sheet-header.compact .counter-field input[name="system.sante.pv.value"],
|
||||
.dnc-employe-sheet .sheet-header.compact .counter-field input[name="system.sante.pv.max"] {
|
||||
width: 5.25rem;
|
||||
max-width: 5.25rem;
|
||||
}
|
||||
.dnc-pnj-sheet .sheet-header.compact .identity-grid {
|
||||
grid-template-columns: repeat(4, minmax(0, 1fr));
|
||||
@@ -134,13 +139,17 @@
|
||||
.dnc-pnj-sheet .sheet-header.compact label {
|
||||
gap: 0.25rem;
|
||||
}
|
||||
.dnc-pnj-sheet .sheet-header.compact .hp-field {
|
||||
grid-column: span 2;
|
||||
}
|
||||
.dnc-pnj-sheet .sheet-header.compact input[type="number"] {
|
||||
width: 4.5rem;
|
||||
max-width: 4.5rem;
|
||||
}
|
||||
.dnc-pnj-sheet .sheet-header.compact .counter-field input[type="number"] {
|
||||
width: 3.75rem;
|
||||
max-width: 3.75rem;
|
||||
.dnc-pnj-sheet .sheet-header.compact .counter-field input[name="system.sante.pv.value"],
|
||||
.dnc-pnj-sheet .sheet-header.compact .counter-field input[name="system.sante.pv.max"] {
|
||||
width: 5.25rem;
|
||||
max-width: 5.25rem;
|
||||
}
|
||||
.dnc-sheet label {
|
||||
display: flex;
|
||||
@@ -153,18 +162,18 @@
|
||||
letter-spacing: 0.04em;
|
||||
color: #6d5a4f;
|
||||
}
|
||||
.readonly-field {
|
||||
.dnc-sheet .readonly-field {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.4rem;
|
||||
}
|
||||
.readonly-field > span {
|
||||
.dnc-sheet .readonly-field > span {
|
||||
font-size: 0.8rem;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.04em;
|
||||
color: #6d5a4f;
|
||||
}
|
||||
.readonly-field p {
|
||||
.dnc-sheet .readonly-field p {
|
||||
margin: 0;
|
||||
border: 1px solid rgba(91, 70, 52, 0.55);
|
||||
border-radius: 6px;
|
||||
@@ -188,29 +197,29 @@
|
||||
resize: vertical;
|
||||
min-height: 4.5rem;
|
||||
}
|
||||
.sheet-columns {
|
||||
.dnc-sheet .sheet-columns {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(250px, 320px) 1fr;
|
||||
gap: 1rem;
|
||||
}
|
||||
.sheet-sections {
|
||||
.dnc-sheet .sheet-sections {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
gap: 1rem;
|
||||
}
|
||||
.compact-sections {
|
||||
.dnc-sheet .compact-sections {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
.counter-field {
|
||||
.dnc-sheet .counter-field {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.4rem;
|
||||
}
|
||||
.counter-field button,
|
||||
.item-actions button,
|
||||
.sheet-footer button,
|
||||
.text-button,
|
||||
.roll-button {
|
||||
.dnc-sheet .counter-field button,
|
||||
.dnc-sheet .item-actions button,
|
||||
.dnc-sheet .sheet-footer button,
|
||||
.dnc-sheet .text-button,
|
||||
.dnc-sheet .roll-button {
|
||||
border: 1px solid #5b4634;
|
||||
border-radius: 6px;
|
||||
background: linear-gradient(180deg, #fdf9f2 0%, #e8d5ba 100%);
|
||||
@@ -218,90 +227,90 @@
|
||||
min-height: 2rem;
|
||||
padding: 0.35rem 0.65rem;
|
||||
}
|
||||
.text-button {
|
||||
.dnc-sheet .text-button {
|
||||
white-space: nowrap;
|
||||
}
|
||||
.roll-button {
|
||||
.dnc-sheet .roll-button {
|
||||
width: 2rem;
|
||||
padding: 0;
|
||||
}
|
||||
.with-controls {
|
||||
.dnc-sheet .with-controls {
|
||||
gap: 0.4rem;
|
||||
}
|
||||
.section-header {
|
||||
.dnc-sheet .section-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
gap: 0.75rem;
|
||||
margin-bottom: 0.75rem;
|
||||
}
|
||||
.empty-state {
|
||||
.dnc-sheet .empty-state {
|
||||
margin: 0;
|
||||
color: #6d5a4f;
|
||||
font-style: italic;
|
||||
}
|
||||
.span-two {
|
||||
.dnc-sheet .span-two {
|
||||
grid-column: span 2;
|
||||
}
|
||||
.characteristic-list {
|
||||
.dnc-actor-sheet .characteristic-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.4rem;
|
||||
}
|
||||
.characteristic-row {
|
||||
.dnc-actor-sheet .characteristic-row {
|
||||
display: grid;
|
||||
grid-template-columns: 2rem 1fr 4rem;
|
||||
gap: 0.4rem;
|
||||
align-items: center;
|
||||
}
|
||||
.characteristic-label {
|
||||
.dnc-actor-sheet .characteristic-label {
|
||||
font-weight: 700;
|
||||
}
|
||||
.profile-counters {
|
||||
.dnc-actor-sheet .profile-counters {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr;
|
||||
gap: 0.75rem;
|
||||
}
|
||||
.profile-card-wide {
|
||||
.dnc-actor-sheet .profile-card-wide {
|
||||
width: 100%;
|
||||
}
|
||||
.profile-layout {
|
||||
.dnc-actor-sheet .profile-layout {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(0, 1.15fr) minmax(320px, 0.85fr);
|
||||
gap: 1rem;
|
||||
align-items: start;
|
||||
}
|
||||
.profile-column {
|
||||
.dnc-actor-sheet .profile-column {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.75rem;
|
||||
}
|
||||
.favor-card {
|
||||
.dnc-actor-sheet .favor-card {
|
||||
margin: 0.75rem 0;
|
||||
padding: 0.75rem;
|
||||
border: 1px dashed rgba(91, 70, 52, 0.55);
|
||||
border-radius: 10px;
|
||||
background: rgba(226, 208, 177, 0.35);
|
||||
}
|
||||
.favor-header h2 {
|
||||
.dnc-actor-sheet .favor-header h2 {
|
||||
margin-bottom: 0.4rem;
|
||||
}
|
||||
.favor-help {
|
||||
.dnc-actor-sheet .favor-help {
|
||||
margin: 0 0 0.75rem;
|
||||
color: #6d5a4f;
|
||||
font-size: 0.82rem;
|
||||
}
|
||||
.favor-list {
|
||||
.dnc-actor-sheet .favor-list {
|
||||
display: grid;
|
||||
gap: 0.4rem;
|
||||
}
|
||||
.favor-row {
|
||||
.dnc-actor-sheet .favor-row {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(0, 1fr) 4.5rem auto;
|
||||
gap: 0.4rem;
|
||||
align-items: end;
|
||||
}
|
||||
.favor-meta {
|
||||
.dnc-actor-sheet .favor-meta {
|
||||
min-height: 2.3rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@@ -311,57 +320,57 @@
|
||||
border: 1px solid rgba(91, 70, 52, 0.35);
|
||||
font-weight: 700;
|
||||
}
|
||||
.magic-layout {
|
||||
.dnc-actor-sheet .magic-layout {
|
||||
align-items: start;
|
||||
margin-bottom: 0.75rem;
|
||||
}
|
||||
.magic-layout .sheet-column {
|
||||
.dnc-actor-sheet .magic-layout .sheet-column {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.75rem;
|
||||
}
|
||||
.magic-resource-grid {
|
||||
.dnc-actor-sheet .magic-resource-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
|
||||
gap: 0.75rem;
|
||||
align-items: end;
|
||||
}
|
||||
.chaos-table-wrapper {
|
||||
.dnc-actor-sheet .chaos-table-wrapper {
|
||||
margin-top: 0.75rem;
|
||||
}
|
||||
.chaos-table-wrapper h3 {
|
||||
.dnc-actor-sheet .chaos-table-wrapper h3 {
|
||||
margin: 0 0 0.4rem;
|
||||
font-size: 0.95rem;
|
||||
}
|
||||
.chaos-table-caption {
|
||||
.dnc-actor-sheet .chaos-table-caption {
|
||||
margin: 0 0 0.4rem;
|
||||
color: #6d5a4f;
|
||||
font-size: 0.78rem;
|
||||
font-style: italic;
|
||||
}
|
||||
.chaos-table {
|
||||
.dnc-actor-sheet .chaos-table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
.chaos-table th,
|
||||
.chaos-table td {
|
||||
.dnc-actor-sheet .chaos-table th,
|
||||
.dnc-actor-sheet .chaos-table td {
|
||||
padding: 0.4rem 0.45rem;
|
||||
border: 1px solid rgba(91, 70, 52, 0.35);
|
||||
vertical-align: top;
|
||||
}
|
||||
.chaos-table th {
|
||||
.dnc-actor-sheet .chaos-table th {
|
||||
text-align: left;
|
||||
background: rgba(226, 208, 177, 0.55);
|
||||
}
|
||||
.sheet-tabs {
|
||||
.dnc-actor-sheet .sheet-tabs {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 0.4rem;
|
||||
margin: 1rem 0 0.75rem;
|
||||
justify-content: center;
|
||||
}
|
||||
.sheet-tab {
|
||||
.dnc-actor-sheet .sheet-tab {
|
||||
border: 1px solid rgba(91, 70, 52, 0.8);
|
||||
border-radius: 10px;
|
||||
background: rgba(226, 208, 177, 0.55);
|
||||
@@ -369,27 +378,27 @@
|
||||
font-weight: 700;
|
||||
padding: 0.4rem 0.75rem;
|
||||
}
|
||||
.sheet-tab.active {
|
||||
.dnc-actor-sheet .sheet-tab.active {
|
||||
background: #8b2e17;
|
||||
border-color: #561d0e;
|
||||
color: #fff;
|
||||
}
|
||||
.sheet-tab-panel {
|
||||
.dnc-actor-sheet .sheet-tab-panel {
|
||||
display: none;
|
||||
}
|
||||
.sheet-tab-panel.active {
|
||||
.dnc-actor-sheet .sheet-tab-panel.active {
|
||||
display: block;
|
||||
}
|
||||
.item-list {
|
||||
.dnc-actor-sheet .item-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.75rem;
|
||||
}
|
||||
.item-section.is-dragover {
|
||||
.dnc-actor-sheet .item-section.is-dragover {
|
||||
border-color: #8b2e17;
|
||||
box-shadow: 0 0 0 2px rgba(139, 46, 23, 0.2);
|
||||
}
|
||||
.item-dropzone {
|
||||
.dnc-actor-sheet .item-dropzone {
|
||||
border: 1px dashed rgba(91, 70, 52, 0.75);
|
||||
border-radius: 10px;
|
||||
padding: 0.75rem;
|
||||
@@ -403,16 +412,16 @@
|
||||
font-size: 0.9rem;
|
||||
font-weight: 600;
|
||||
}
|
||||
.item-dropzone.has-items {
|
||||
.dnc-actor-sheet .item-dropzone.has-items {
|
||||
padding: 0.4rem 0.75rem;
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
.item-section.is-dragover .item-dropzone {
|
||||
.dnc-actor-sheet .item-section.is-dragover .item-dropzone {
|
||||
border-color: #8b2e17;
|
||||
background: rgba(139, 46, 23, 0.12);
|
||||
color: #221b18;
|
||||
}
|
||||
.item {
|
||||
.dnc-actor-sheet .item {
|
||||
display: grid;
|
||||
grid-template-columns: 48px 1fr auto;
|
||||
gap: 0.75rem;
|
||||
@@ -420,11 +429,11 @@
|
||||
border-top: 1px dashed rgba(91, 70, 52, 0.45);
|
||||
padding-top: 0.75rem;
|
||||
}
|
||||
.item:first-child {
|
||||
.dnc-actor-sheet .item:first-child {
|
||||
border-top: 0;
|
||||
padding-top: 0;
|
||||
}
|
||||
.item img {
|
||||
.dnc-actor-sheet .item img {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
object-fit: cover;
|
||||
@@ -432,43 +441,71 @@
|
||||
border: 1px solid #5b4634;
|
||||
background: #fff;
|
||||
}
|
||||
.item-main p {
|
||||
.dnc-actor-sheet .item-main p {
|
||||
margin: 0.4rem 0 0;
|
||||
color: #6d5a4f;
|
||||
}
|
||||
.item-title-row {
|
||||
.dnc-actor-sheet .item-title-row {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 0.4rem;
|
||||
align-items: center;
|
||||
}
|
||||
.item-meta {
|
||||
.dnc-actor-sheet .item-meta {
|
||||
border-radius: 999px;
|
||||
background: #e2d0b1;
|
||||
color: #221b18;
|
||||
font-size: 0.75rem;
|
||||
padding: 0.1rem 0.5rem;
|
||||
}
|
||||
.item-actions {
|
||||
.dnc-actor-sheet .item-actions {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 0.4rem;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
.pnj-layout .sheet-column {
|
||||
.dnc-pnj-sheet .pnj-layout .sheet-column {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.75rem;
|
||||
}
|
||||
.pnj-combat-grid {
|
||||
.dnc-pnj-sheet .pnj-combat-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
gap: 0.75rem;
|
||||
align-items: end;
|
||||
}
|
||||
.pnj-combat-grid .span-two {
|
||||
.dnc-pnj-sheet .pnj-combat-grid .span-two {
|
||||
grid-column: 1 / -1;
|
||||
}
|
||||
.dnc-pnj-sheet .pnj-attack-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.75rem;
|
||||
}
|
||||
.dnc-pnj-sheet .pnj-attack-list .section-header {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.dnc-pnj-sheet .pnj-attack-list h3 {
|
||||
margin: 0;
|
||||
font-size: 0.95rem;
|
||||
color: #221b18;
|
||||
}
|
||||
.dnc-pnj-sheet .pnj-attack-rows {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.75rem;
|
||||
}
|
||||
.dnc-pnj-sheet .pnj-attack-row {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(0, 1fr) 4.5rem max-content;
|
||||
gap: 0.75rem;
|
||||
align-items: end;
|
||||
}
|
||||
.dnc-pnj-sheet .pnj-attack-row .item-actions {
|
||||
align-self: end;
|
||||
gap: 0.4rem;
|
||||
}
|
||||
.application.fvtt-donjon-et-cie.item {
|
||||
display: flex !important;
|
||||
flex-direction: column;
|
||||
@@ -492,7 +529,7 @@
|
||||
.dnc-item-sheet .identity-grid {
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
}
|
||||
.sheet-footer {
|
||||
.dnc-item-sheet .sheet-footer {
|
||||
display: flex;
|
||||
gap: 0.75rem;
|
||||
justify-content: flex-end;
|
||||
@@ -528,6 +565,126 @@
|
||||
.dnc-roll-dialog .window-content {
|
||||
background: linear-gradient(180deg, #f7efe0 0%, #e3d0b1 100%);
|
||||
}
|
||||
.dnc-mission-pack-mode,
|
||||
.dnc-mission-pack-note {
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
.dnc-mission-pack-campaign {
|
||||
gap: 1rem;
|
||||
}
|
||||
.dnc-mission-pack-hero {
|
||||
padding: 1rem;
|
||||
border: 1px solid rgba(91, 70, 52, 0.35);
|
||||
border-radius: 10px;
|
||||
background: linear-gradient(180deg, rgba(255, 255, 255, 0.65) 0%, rgba(241, 229, 208, 0.68) 100%), linear-gradient(135deg, rgba(139, 46, 23, 0.08) 0%, rgba(139, 46, 23, 0) 100%);
|
||||
box-shadow: 0 8px 18px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
.dnc-mission-pack-kicker {
|
||||
margin: 0 0 0.25rem;
|
||||
font-size: 0.72rem;
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.14em;
|
||||
text-transform: uppercase;
|
||||
color: rgba(139, 46, 23, 0.82);
|
||||
}
|
||||
.dnc-mission-pack-hero h2 {
|
||||
margin: 0;
|
||||
font-family: "IM Fell English SC", "Palatino Linotype", "Book Antiqua", Palatino, serif;
|
||||
font-size: 1.4rem;
|
||||
line-height: 1.1;
|
||||
color: #8b2e17;
|
||||
}
|
||||
.dnc-mission-pack-subtitle {
|
||||
margin-top: 0.2rem;
|
||||
font-size: 0.78rem;
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.16em;
|
||||
text-transform: uppercase;
|
||||
color: rgba(91, 70, 52, 0.78);
|
||||
}
|
||||
.dnc-mission-pack-intro {
|
||||
margin-top: 0.4rem;
|
||||
color: #6d5a4f;
|
||||
}
|
||||
.dnc-mission-pack-meta-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
gap: 0.75rem;
|
||||
}
|
||||
.dnc-mission-pack-meta-card {
|
||||
display: grid;
|
||||
gap: 0.2rem;
|
||||
padding: 0.75rem;
|
||||
border: 1px solid rgba(91, 70, 52, 0.3);
|
||||
border-radius: 10px;
|
||||
background: rgba(255, 255, 255, 0.42);
|
||||
}
|
||||
.dnc-mission-pack-meta-card span {
|
||||
font-size: 0.72rem;
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.08em;
|
||||
text-transform: uppercase;
|
||||
color: #6d5a4f;
|
||||
}
|
||||
.dnc-mission-pack-meta-card strong {
|
||||
font-size: 1rem;
|
||||
}
|
||||
.dnc-mission-pack-section {
|
||||
display: grid;
|
||||
gap: 0.75rem;
|
||||
}
|
||||
.dnc-mission-pack-select {
|
||||
padding: 0.75rem;
|
||||
border: 1px solid rgba(91, 70, 52, 0.32);
|
||||
border-radius: 10px;
|
||||
background: rgba(255, 255, 255, 0.36);
|
||||
}
|
||||
.dnc-mission-pack-assignments {
|
||||
display: grid;
|
||||
gap: 0.75rem;
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
}
|
||||
.dnc-mission-pack-assignment {
|
||||
display: grid;
|
||||
gap: 0.4rem;
|
||||
padding: 0.75rem;
|
||||
border: 1px solid rgba(91, 70, 52, 0.35);
|
||||
border-radius: 10px;
|
||||
background: rgba(255, 255, 255, 0.38);
|
||||
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.55);
|
||||
}
|
||||
.dnc-mission-pack-assignment span {
|
||||
font-size: 0.82rem;
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.04em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
.dnc-mission-pack-note {
|
||||
color: #6d5a4f;
|
||||
}
|
||||
.dnc-mission-pack-note-foot {
|
||||
padding: 0.75rem;
|
||||
border-top: 1px solid rgba(91, 70, 52, 0.24);
|
||||
}
|
||||
.dnc-mission-pack-dialog .window-header {
|
||||
background: linear-gradient(180deg, rgba(253, 246, 231, 0.96) 0%, rgba(234, 212, 170, 0.96) 100%), linear-gradient(90deg, rgba(139, 46, 23, 0.12) 0%, rgba(139, 46, 23, 0) 100%);
|
||||
border-bottom: 1px solid rgba(91, 70, 52, 0.35);
|
||||
}
|
||||
.dnc-mission-pack-dialog .window-title {
|
||||
color: #8b2e17;
|
||||
font-family: "IM Fell English SC", "Palatino Linotype", "Book Antiqua", Palatino, serif;
|
||||
letter-spacing: 0.03em;
|
||||
text-shadow: none;
|
||||
}
|
||||
.dnc-mission-pack-dialog .window-header button {
|
||||
color: #221b18;
|
||||
}
|
||||
@media (max-width: 640px) {
|
||||
.dnc-mission-pack-meta-grid,
|
||||
.dnc-mission-pack-assignments {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
.dnc-chat-card {
|
||||
position: relative;
|
||||
border: 2px solid #5b4634;
|
||||
@@ -835,6 +992,24 @@
|
||||
.dnc-chat-card-favor {
|
||||
background: linear-gradient(180deg, rgba(248, 251, 255, 0.8) 0%, rgba(205, 220, 238, 0.94) 100%), linear-gradient(135deg, #f7fbff 0%, #9fb8d7 100%);
|
||||
}
|
||||
.dnc-chat-card-welcome {
|
||||
border-color: rgba(139, 46, 23, 0.34);
|
||||
background: linear-gradient(180deg, rgba(255, 250, 240, 0.84) 0%, rgba(239, 219, 179, 0.94) 100%), linear-gradient(135deg, #fffaf0 0%, #dcb772 100%);
|
||||
}
|
||||
.chat-welcome-intro {
|
||||
font-size: 0.82rem;
|
||||
line-height: 1.45;
|
||||
}
|
||||
.chat-welcome-link {
|
||||
margin-top: 0.75rem;
|
||||
padding: 0.6rem 0.8rem;
|
||||
border: 1px solid rgba(139, 46, 23, 0.24);
|
||||
border-radius: 12px;
|
||||
background: rgba(139, 46, 23, 0.08);
|
||||
}
|
||||
.chat-welcome-link a.content-link {
|
||||
font-weight: 700;
|
||||
}
|
||||
.dnc-chat-card-spell .chat-actions + .chat-actions {
|
||||
margin-top: 0.4rem;
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
+18
@@ -52,6 +52,18 @@
|
||||
"PLAYER": "OBSERVER",
|
||||
"ASSISTANT": "OWNER"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "JournalEntry",
|
||||
"label": "Aide du système",
|
||||
"name": "system-help",
|
||||
"path": "packs/system-help",
|
||||
"system": "fvtt-donjon-et-cie",
|
||||
"flags": {},
|
||||
"ownership": {
|
||||
"PLAYER": "OBSERVER",
|
||||
"ASSISTANT": "OWNER"
|
||||
}
|
||||
}
|
||||
],
|
||||
"documentTypes": {
|
||||
@@ -118,6 +130,12 @@
|
||||
"description",
|
||||
"notes"
|
||||
]
|
||||
},
|
||||
"entrainement": {
|
||||
"htmlFields": [
|
||||
"description",
|
||||
"notes"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
<button type="button" data-action="rollHitDice" aria-label="Lancer le de de vie" title="Lancer le de de vie"><i class="fa-solid fa-dice-d20"></i></button>
|
||||
</div>
|
||||
</label>
|
||||
<label class="with-controls">
|
||||
<label class="with-controls hp-field" style="grid-column: span 2;">
|
||||
<span>PV</span>
|
||||
<div class="counter-field">
|
||||
<button type="button" data-action="adjustCounter" data-path="system.sante.pv.value" data-delta="-1">-</button>
|
||||
@@ -150,6 +150,9 @@
|
||||
{{#if this.canUse}}
|
||||
<button type="button" data-action="rollUsage" aria-label="Utiliser {{this.name}}" title="Utiliser {{this.name}}"><i class="fa-solid fa-hourglass-half"></i></button>
|
||||
{{/if}}
|
||||
{{#if this.canReset}}
|
||||
<button type="button" data-action="resetUsage" aria-label="Reinitialiser {{this.name}}" title="Reinitialiser"><i class="fa-solid fa-arrow-rotate-left"></i></button>
|
||||
{{/if}}
|
||||
<button type="button" data-action="postItem" aria-label="Poster {{this.name}} dans le chat" title="Poster dans le chat"><i class="fa-solid fa-message"></i></button>
|
||||
<button type="button" data-action="editItem" aria-label="Editer {{this.name}}" title="Editer"><i class="fa-solid fa-pen"></i></button>
|
||||
<button type="button" data-action="deleteItem" aria-label="Supprimer {{this.name}}" title="Supprimer"><i class="fa-solid fa-trash"></i></button>
|
||||
@@ -212,47 +215,6 @@
|
||||
</table>
|
||||
</div>
|
||||
</section>
|
||||
<section class="sheet-card item-section">
|
||||
<header class="section-header">
|
||||
<h2>{{capacitySection.label}}</h2>
|
||||
<button type="button" class="text-button" data-action="createItem" data-type="{{capacitySection.createType}}">+ Ajouter</button>
|
||||
</header>
|
||||
<div class="item-list">
|
||||
{{#if capacitySection.items.length}}
|
||||
{{#each capacitySection.items}}
|
||||
<article class="item" data-item-id="{{this.id}}">
|
||||
<img src="{{this.img}}" alt="{{this.name}}">
|
||||
<div class="item-main">
|
||||
<div class="item-title-row">
|
||||
<strong>{{this.name}}</strong>
|
||||
{{#if this.usageLabel}}<span class="item-meta">{{this.usageLabel}}</span>{{/if}}
|
||||
{{#if this.protectionLabel}}<span class="item-meta">{{this.protectionLabel}}</span>{{/if}}
|
||||
</div>
|
||||
{{#if this.system.effet}}<p>{{this.system.effet}}</p>{{/if}}
|
||||
{{#if this.system.degats}}<p>Degats : {{this.system.degats}}</p>{{/if}}
|
||||
</div>
|
||||
<div class="item-actions">
|
||||
{{#if this.canRoll}}
|
||||
<button type="button" data-action="{{this.rollAction}}" aria-label="Lancer {{this.name}}" title="Lancer {{this.name}}"><i class="fa-solid fa-dice-d20"></i></button>
|
||||
{{/if}}
|
||||
{{#if this.canRollDamage}}
|
||||
<button type="button" data-action="rollDamage" aria-label="Lancer les degats de {{this.name}}" title="Lancer les degats"><i class="fa-solid fa-burst"></i></button>
|
||||
{{/if}}
|
||||
{{#if this.canUse}}
|
||||
<button type="button" data-action="rollUsage" aria-label="Utiliser {{this.name}}" title="Utiliser {{this.name}}"><i class="fa-solid fa-hourglass-half"></i></button>
|
||||
{{/if}}
|
||||
<button type="button" data-action="postItem" aria-label="Poster {{this.name}} dans le chat" title="Poster dans le chat"><i class="fa-solid fa-message"></i></button>
|
||||
<button type="button" data-action="editItem" aria-label="Editer {{this.name}}" title="Editer"><i class="fa-solid fa-pen"></i></button>
|
||||
<button type="button" data-action="deleteItem" aria-label="Supprimer {{this.name}}" title="Supprimer"><i class="fa-solid fa-trash"></i></button>
|
||||
</div>
|
||||
</article>
|
||||
{{/each}}
|
||||
{{/if}}
|
||||
<div class="item-dropzone {{#if capacitySection.items.length}}has-items{{/if}}" data-item-type="{{capacitySection.createType}}">
|
||||
Glissez-deposez ici les {{capacitySection.label}}.
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</section>
|
||||
<section class="sheet-column">
|
||||
<section class="sheet-card item-section">
|
||||
@@ -284,6 +246,9 @@
|
||||
{{#if this.canUse}}
|
||||
<button type="button" data-action="rollUsage" aria-label="Utiliser {{this.name}}" title="Utiliser {{this.name}}"><i class="fa-solid fa-hourglass-half"></i></button>
|
||||
{{/if}}
|
||||
{{#if this.canReset}}
|
||||
<button type="button" data-action="resetUsage" aria-label="Reinitialiser {{this.name}}" title="Reinitialiser"><i class="fa-solid fa-arrow-rotate-left"></i></button>
|
||||
{{/if}}
|
||||
<button type="button" data-action="postItem" aria-label="Poster {{this.name}} dans le chat" title="Poster dans le chat"><i class="fa-solid fa-message"></i></button>
|
||||
<button type="button" data-action="editItem" aria-label="Editer {{this.name}}" title="Editer"><i class="fa-solid fa-pen"></i></button>
|
||||
<button type="button" data-action="deleteItem" aria-label="Supprimer {{this.name}}" title="Supprimer"><i class="fa-solid fa-trash"></i></button>
|
||||
@@ -296,6 +261,50 @@
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<section class="sheet-card item-section">
|
||||
<header class="section-header">
|
||||
<h2>{{capacitySection.label}}</h2>
|
||||
<button type="button" class="text-button" data-action="createItem" data-type="{{capacitySection.createType}}">+ Ajouter</button>
|
||||
</header>
|
||||
<div class="item-list">
|
||||
{{#if capacitySection.items.length}}
|
||||
{{#each capacitySection.items}}
|
||||
<article class="item" data-item-id="{{this.id}}">
|
||||
<img src="{{this.img}}" alt="{{this.name}}">
|
||||
<div class="item-main">
|
||||
<div class="item-title-row">
|
||||
<strong>{{this.name}}</strong>
|
||||
{{#if this.usageLabel}}<span class="item-meta">{{this.usageLabel}}</span>{{/if}}
|
||||
{{#if this.protectionLabel}}<span class="item-meta">{{this.protectionLabel}}</span>{{/if}}
|
||||
</div>
|
||||
{{#if this.system.effet}}<p>{{this.system.effet}}</p>{{/if}}
|
||||
{{#if this.system.degats}}<p>Degats : {{this.system.degats}}</p>{{/if}}
|
||||
</div>
|
||||
<div class="item-actions">
|
||||
{{#if this.canRoll}}
|
||||
<button type="button" data-action="{{this.rollAction}}" aria-label="Lancer {{this.name}}" title="Lancer {{this.name}}"><i class="fa-solid fa-dice-d20"></i></button>
|
||||
{{/if}}
|
||||
{{#if this.canRollDamage}}
|
||||
<button type="button" data-action="rollDamage" aria-label="Lancer les degats de {{this.name}}" title="Lancer les degats"><i class="fa-solid fa-burst"></i></button>
|
||||
{{/if}}
|
||||
{{#if this.canUse}}
|
||||
<button type="button" data-action="rollUsage" aria-label="Utiliser {{this.name}}" title="Utiliser {{this.name}}"><i class="fa-solid fa-hourglass-half"></i></button>
|
||||
{{/if}}
|
||||
{{#if this.canReset}}
|
||||
<button type="button" data-action="resetUsage" aria-label="Reinitialiser {{this.name}}" title="Reinitialiser"><i class="fa-solid fa-arrow-rotate-left"></i></button>
|
||||
{{/if}}
|
||||
<button type="button" data-action="postItem" aria-label="Poster {{this.name}} dans le chat" title="Poster dans le chat"><i class="fa-solid fa-message"></i></button>
|
||||
<button type="button" data-action="editItem" aria-label="Editer {{this.name}}" title="Editer"><i class="fa-solid fa-pen"></i></button>
|
||||
<button type="button" data-action="deleteItem" aria-label="Supprimer {{this.name}}" title="Supprimer"><i class="fa-solid fa-trash"></i></button>
|
||||
</div>
|
||||
</article>
|
||||
{{/each}}
|
||||
{{/if}}
|
||||
<div class="item-dropzone {{#if capacitySection.items.length}}has-items{{/if}}" data-item-type="{{capacitySection.createType}}">
|
||||
Glissez-deposez ici les {{capacitySection.label}}.
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</section>
|
||||
</section>
|
||||
</section>
|
||||
@@ -398,6 +407,9 @@
|
||||
{{#if this.canUse}}
|
||||
<button type="button" data-action="rollUsage" aria-label="Utiliser {{this.name}}" title="Utiliser {{this.name}}"><i class="fa-solid fa-hourglass-half"></i></button>
|
||||
{{/if}}
|
||||
{{#if this.canReset}}
|
||||
<button type="button" data-action="resetUsage" aria-label="Reinitialiser {{this.name}}" title="Reinitialiser"><i class="fa-solid fa-arrow-rotate-left"></i></button>
|
||||
{{/if}}
|
||||
<button type="button" data-action="postItem" aria-label="Poster {{this.name}} dans le chat" title="Poster dans le chat"><i class="fa-solid fa-message"></i></button>
|
||||
<button type="button" data-action="editItem" aria-label="Editer {{this.name}}" title="Editer"><i class="fa-solid fa-pen"></i></button>
|
||||
<button type="button" data-action="deleteItem" aria-label="Supprimer {{this.name}}" title="Supprimer"><i class="fa-solid fa-trash"></i></button>
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
<button type="button" data-action="rollHitDice" aria-label="Lancer le de de vie" title="Lancer le de de vie"><i class="fa-solid fa-dice-d20"></i></button>
|
||||
</div>
|
||||
</label>
|
||||
<label class="with-controls">
|
||||
<label class="with-controls hp-field" style="grid-column: span 2;">
|
||||
<span>PV</span>
|
||||
<div class="counter-field">
|
||||
<button type="button" data-action="adjustCounter" data-path="system.sante.pv.value" data-delta="-1">-</button>
|
||||
@@ -72,23 +72,30 @@
|
||||
<span>Valeurs</span>
|
||||
<p>ARM {{armorDisplay}} · COU {{courageDisplay}}</p>
|
||||
</div>
|
||||
<section class="pnj-attack-list span-two">
|
||||
<header class="section-header">
|
||||
<h3>Attaques</h3>
|
||||
<button type="button" class="text-button" data-action="createPnjAttack">+ Ajouter</button>
|
||||
</header>
|
||||
<div class="pnj-attack-rows">
|
||||
{{#each pnjAttacks}}
|
||||
<article class="pnj-attack-row" data-attack-index="{{this.index}}">
|
||||
<label>
|
||||
<span>ATT</span>
|
||||
<input type="text" name="system.attaque.nom" value="{{system.attaque.nom}}">
|
||||
<input type="text" name="system.attaques.{{this.index}}.nom" value="{{this.nom}}" aria-label="Nom de l'attaque" title="Nom de l'attaque">
|
||||
</label>
|
||||
<label>
|
||||
<span>Degats</span>
|
||||
<div class="counter-field">
|
||||
<input type="text" name="system.attaque.degats" value="{{system.attaque.degats}}">
|
||||
{{#if hasAttackDamage}}
|
||||
<button type="button" data-action="rollPnjAttackDamage" aria-label="Lancer les degats de l'attaque" title="Lancer les degats"><i class="fa-solid fa-burst"></i></button>
|
||||
<input type="text" name="system.attaques.{{this.index}}.degats" value="{{this.degats}}" aria-label="Dégâts" title="Dégâts">
|
||||
</label>
|
||||
<div class="item-actions">
|
||||
{{#if this.degats}}
|
||||
<button type="button" data-action="rollPnjAttackDamage" aria-label="Lancer les degats de {{this.nom}}" title="Lancer les degats"><i class="fa-solid fa-burst"></i></button>
|
||||
{{/if}}
|
||||
<button type="button" data-action="deletePnjAttack" aria-label="Supprimer {{this.nom}}" title="Supprimer"><i class="fa-solid fa-trash"></i></button>
|
||||
</div>
|
||||
</label>
|
||||
<label class="span-two">
|
||||
<span>Notes d'attaque</span>
|
||||
<input type="text" name="system.attaque.notes" value="{{system.attaque.notes}}">
|
||||
</label>
|
||||
</article>
|
||||
{{/each}}
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
<section class="dnc-chat-card dnc-chat-card-chaos">
|
||||
<header class="chat-card-header">
|
||||
<div class="chat-card-heading">
|
||||
<p class="chat-card-kicker">Chaos</p>
|
||||
<p class="chat-card-kicker">{{localize "DNC.UI.Chaos"}}</p>
|
||||
<h2>{{title}}</h2>
|
||||
<p class="chat-card-subtitle">La magie opere malgre l'echec ; le MJ determine les consequences.</p>
|
||||
<p class="chat-card-subtitle">{{localize "DNC.Chat.ChaosSubtitle"}}</p>
|
||||
</div>
|
||||
<div class="chat-card-total">
|
||||
<span>Jet</span>
|
||||
<span>{{localize "DNC.Chat.RollValue"}}</span>
|
||||
<strong>{{value}}</strong>
|
||||
</div>
|
||||
</header>
|
||||
<div class="chat-pill-row">
|
||||
<span class="chat-pill success">Sort maintenu</span>
|
||||
<span class="chat-pill">Avant {{before}}</span>
|
||||
<span class="chat-pill">Apres {{after}}</span>
|
||||
<span class="chat-pill success">{{localize "DNC.Chat.SpellMaintained"}}</span>
|
||||
<span class="chat-pill">{{localize "DNC.Chat.Before"}} {{before}}</span>
|
||||
<span class="chat-pill">{{localize "DNC.Chat.After"}} {{after}}</span>
|
||||
</div>
|
||||
{{#if chaosEntry}}
|
||||
<div class="chat-chaos-result">
|
||||
@@ -22,9 +22,9 @@
|
||||
</div>
|
||||
{{/if}}
|
||||
{{#if degraded}}
|
||||
<p class="chat-note warning">Le de du Chaos descend d'un cran.</p>
|
||||
<p class="chat-note warning">{{localize "DNC.Chat.ChaosDieDrops"}}</p>
|
||||
{{/if}}
|
||||
{{#if exhausted}}
|
||||
<p class="chat-note warning">Le de du Chaos est trop faible pour etre reutilise dans le Donjon.</p>
|
||||
<p class="chat-note warning">{{localize "DNC.Chat.ChaosDieExhausted"}}</p>
|
||||
{{/if}}
|
||||
</section>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<section class="dnc-chat-card dnc-chat-card-favor">
|
||||
<header class="chat-card-header">
|
||||
<div class="chat-card-heading">
|
||||
<p class="chat-card-kicker">Reseau</p>
|
||||
<p class="chat-card-kicker">{{localize "DNC.Chat.Kicker.Network"}}</p>
|
||||
<h2>{{title}}</h2>
|
||||
{{#if subtitle}}<p class="chat-card-subtitle">{{subtitle}}</p>{{/if}}
|
||||
</div>
|
||||
@@ -10,8 +10,8 @@
|
||||
</div>
|
||||
</header>
|
||||
<div class="chat-pill-row">
|
||||
<span class="chat-pill">Avant {{before}}</span>
|
||||
<span class="chat-pill">Apres {{after}}</span>
|
||||
<span class="chat-pill">{{localize "DNC.Chat.Before"}} {{before}}</span>
|
||||
<span class="chat-pill">{{localize "DNC.Chat.After"}} {{after}}</span>
|
||||
</div>
|
||||
<p class="chat-note">{{note}}</p>
|
||||
</section>
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
<section class="dnc-chat-card dnc-chat-card-initiative">
|
||||
<header class="initiative-header">
|
||||
<div class="chat-card-heading">
|
||||
<p class="chat-card-kicker">Ordre de marche</p>
|
||||
<p class="chat-card-kicker">{{localize "DNC.Chat.Kicker.Initiative"}}</p>
|
||||
<h2>{{title}}</h2>
|
||||
<p class="chat-card-subtitle">{{actorName}}</p>
|
||||
{{#if modeLabel}}<p class="chat-card-subtitle">{{modeLabel}}</p>{{/if}}
|
||||
</div>
|
||||
<div class="initiative-total">
|
||||
<span class="initiative-total-label">Total</span>
|
||||
<span class="initiative-total-label">{{localize "DNC.Chat.Total"}}</span>
|
||||
<strong>{{total}}</strong>
|
||||
</div>
|
||||
</header>
|
||||
@@ -24,19 +24,19 @@
|
||||
</div>
|
||||
<div class="initiative-operator">+</div>
|
||||
<div class="initiative-part">
|
||||
<span class="initiative-part-label">Bonus</span>
|
||||
<span class="initiative-part-label">{{localize "DNC.Chat.Bonus"}}</span>
|
||||
<strong>{{bonus}}</strong>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p class="initiative-formula">{{formula}}</p>
|
||||
{{#if dieValues.[1]}}
|
||||
<p class="roll-values">Lancers : {{#each dieValues}}<span>{{this}}</span>{{/each}}</p>
|
||||
<p class="roll-values">{{localize "DNC.Chat.Rolls"}} : {{#each dieValues}}<span>{{this}}</span>{{/each}}</p>
|
||||
{{/if}}
|
||||
|
||||
{{#if syncedCombat}}
|
||||
<div class="initiative-sync">
|
||||
<span class="chat-pill success">Combat synchronise</span>
|
||||
<span class="chat-pill success">{{localize "DNC.Chat.CombatSynced"}}</span>
|
||||
<p>{{syncedCombat.name}} · rang {{syncedCombat.rank}} / {{syncedCombat.total}}</p>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
<section class="dnc-chat-card dnc-chat-card-item dnc-chat-card-mission-pack">
|
||||
<header class="chat-card-header">
|
||||
<div class="chat-card-heading">
|
||||
<p class="chat-card-kicker">{{localize "DNC.Chat.Kicker.Logistics"}}</p>
|
||||
<h2>{{title}}</h2>
|
||||
<p class="chat-card-subtitle">{{actorName}}</p>
|
||||
</div>
|
||||
<div class="chat-card-seal {{#if missingCount}}failure{{else}}success{{/if}}">
|
||||
{{createdCount}}
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="chat-pill-row">
|
||||
<span class="chat-pill">{{localize "DNC.Macro.MissionPack.ActiveMode"}} {{generationModeLabel}}</span>
|
||||
{{#if isCampaign}}<span class="chat-pill">{{localize "DNC.Macro.MissionPack.CampaignController"}} {{controllerName}}</span>{{/if}}
|
||||
{{#if isCampaign}}<span class="chat-pill">{{localize "DNC.Macro.MissionPack.CampaignRelation"}} {{stewardRelationLabel}}</span>{{/if}}
|
||||
<span class="chat-pill success">{{localize "DNC.Macro.MissionPack.ItemsAdded"}} {{createdCount}}</span>
|
||||
{{#if missingCount}}<span class="chat-pill failure">{{localize "DNC.Macro.MissionPack.ItemsMissing"}} {{missingCount}}</span>{{/if}}
|
||||
</div>
|
||||
|
||||
<p class="chat-note">
|
||||
{{#if missingCount}}
|
||||
{{localize "DNC.Macro.MissionPack.PartialChatSummary"}}
|
||||
{{else}}
|
||||
{{localize "DNC.Macro.MissionPack.CompleteChatSummary"}}
|
||||
{{/if}}
|
||||
</p>
|
||||
|
||||
<ul class="chat-details">
|
||||
{{#each draws}}
|
||||
<li>
|
||||
<strong>{{this.label}}</strong> : {{this.display}}
|
||||
{{#if this.dieLabel}}
|
||||
<br>{{localize "DNC.Macro.MissionPack.RollDetail" die=this.dieLabel mode=this.modeLabel values=this.rollValuesLabel kept=this.kept rank=this.rankBonus total=this.total}}
|
||||
{{#if this.clamped}}<br>{{localize "DNC.Macro.MissionPack.TotalClamped" total=this.total clamped=this.resolvedTotal}}{{/if}}
|
||||
{{/if}}
|
||||
{{#if this.missingSummary}}<br>{{localize "DNC.Macro.MissionPack.Missing"}} : {{this.missingSummary}}{{/if}}
|
||||
</li>
|
||||
{{/each}}
|
||||
</ul>
|
||||
|
||||
<div class="chat-pill-row">
|
||||
<span class="chat-pill">{{localize "DNC.Macro.MissionPack.UniqueReference"}} {{uniqueEntry.referenceRoll}}</span>
|
||||
<span class="chat-pill">{{localize "DNC.Macro.MissionPack.UniqueActorRoll"}} {{uniqueEntry.actorRoll}}</span>
|
||||
<span class="chat-pill {{#if uniqueEntry.matched}}success{{else}}failure{{/if}}">
|
||||
{{#if uniqueEntry.matched}}
|
||||
{{localize "DNC.Macro.MissionPack.UniqueMatch"}}
|
||||
{{else}}
|
||||
{{localize "DNC.Macro.MissionPack.UniqueMiss"}}
|
||||
{{/if}}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{{#if uniqueEntry.matched}}
|
||||
<p class="chat-note">
|
||||
<strong>{{localize "DNC.Macro.MissionPack.UniqueGranted"}}</strong> {{uniqueEntry.itemName}}
|
||||
{{#if uniqueEntry.uniqueRoll}}({{localize "DNC.Macro.MissionPack.UniqueTableRoll"}} {{uniqueEntry.uniqueRoll}}){{/if}}
|
||||
</p>
|
||||
{{else}}
|
||||
<p class="chat-note">{{localize "DNC.Macro.MissionPack.UniqueRuleReminder"}}</p>
|
||||
{{/if}}
|
||||
</section>
|
||||
@@ -1,7 +1,7 @@
|
||||
<section class="dnc-chat-card dnc-chat-card-roll">
|
||||
<header class="chat-card-header">
|
||||
<div class="chat-card-heading">
|
||||
<p class="chat-card-kicker">Resolution</p>
|
||||
<p class="chat-card-kicker">{{localize "DNC.Chat.Kicker.Resolution"}}</p>
|
||||
<h2>{{title}}</h2>
|
||||
{{#if subtitle}}<p class="chat-card-subtitle">{{subtitle}}</p>{{/if}}
|
||||
</div>
|
||||
@@ -10,23 +10,23 @@
|
||||
</div>
|
||||
</header>
|
||||
<div class="chat-pill-row">
|
||||
<span class="chat-pill {{#if success}}success{{else}}failure{{/if}}">{{#if success}}Reussite{{else}}Echec{{/if}}</span>
|
||||
<span class="chat-pill {{#if success}}success{{else}}failure{{/if}}">{{#if success}}{{localize "DNC.Chat.Success"}}{{else}}{{localize "DNC.Chat.Failure"}}{{/if}}</span>
|
||||
{{#if modeLabel}}<span class="chat-pill">{{modeLabel}}</span>{{/if}}
|
||||
{{#if favorLabel}}<span class="chat-pill">Faveur {{favorLabel}}</span>{{/if}}
|
||||
{{#if targetPillLabel}}<span class="chat-pill">{{targetPillLabel}} {{targetPillValue}}</span>{{else}}<span class="chat-pill">Cible {{target}}</span>{{/if}}
|
||||
{{#if keptPillLabel}}<span class="chat-pill">{{keptPillLabel}} {{keptPillValue}}</span>{{else}}<span class="chat-pill">Garde {{kept}}</span>{{/if}}
|
||||
{{#if favorLabel}}<span class="chat-pill">{{localize "DNC.Chat.Favor"}} {{favorLabel}}</span>{{/if}}
|
||||
{{#if targetPillLabel}}<span class="chat-pill">{{targetPillLabel}} {{targetPillValue}}</span>{{else}}<span class="chat-pill">{{localize "DNC.Chat.Target"}} {{target}}</span>{{/if}}
|
||||
{{#if keptPillLabel}}<span class="chat-pill">{{keptPillLabel}} {{keptPillValue}}</span>{{else}}<span class="chat-pill">{{localize "DNC.Chat.Kept"}} {{kept}}</span>{{/if}}
|
||||
</div>
|
||||
<div class="chat-keyline">
|
||||
<span class="chat-keyline-label">Lancers</span>
|
||||
<span class="chat-keyline-label">{{localize "DNC.Chat.Rolls"}}</span>
|
||||
<p class="roll-values">{{#each values}}<span>{{this}}</span>{{/each}}</p>
|
||||
</div>
|
||||
{{#if favorNote}}
|
||||
<p class="chat-note"><strong>Faveur</strong> : {{favorNote}}</p>
|
||||
<p class="chat-note"><strong>{{localize "DNC.Chat.Favor"}}</strong> : {{favorNote}}</p>
|
||||
{{/if}}
|
||||
{{#if showDamageButton}}
|
||||
<div class="chat-actions">
|
||||
<button type="button" class="chat-action-button" data-action="rollChatDamage" data-item-uuid="{{itemUuid}}">
|
||||
<i class="fa-solid fa-burst"></i> Lancer les degats
|
||||
<i class="fa-solid fa-burst"></i> {{localize "DNC.Chat.RollDamage"}}
|
||||
</button>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<section class="dnc-chat-card dnc-chat-card-spell">
|
||||
<header class="chat-card-header">
|
||||
<div class="chat-card-heading">
|
||||
<p class="chat-card-kicker">Magie</p>
|
||||
<p class="chat-card-kicker">{{localize "DNC.Chat.Kicker.Magic"}}</p>
|
||||
<h2>{{title}}</h2>
|
||||
{{#if subtitle}}<p class="chat-card-subtitle">{{subtitle}}</p>{{/if}}
|
||||
</div>
|
||||
@@ -10,57 +10,57 @@
|
||||
</div>
|
||||
</header>
|
||||
<div class="chat-pill-row">
|
||||
<span class="chat-pill {{#if success}}success{{else}}failure{{/if}}">{{#if success}}Reussite{{else}}Echec{{/if}}</span>
|
||||
<span class="chat-pill {{#if success}}success{{else}}failure{{/if}}">{{#if success}}{{localize "DNC.Chat.Success"}}{{else}}{{localize "DNC.Chat.Failure"}}{{/if}}</span>
|
||||
{{#if modeLabel}}<span class="chat-pill">{{modeLabel}}</span>{{/if}}
|
||||
{{#if favorLabel}}<span class="chat-pill">Faveur {{favorLabel}}</span>{{/if}}
|
||||
{{#if favorLabel}}<span class="chat-pill">{{localize "DNC.Chat.Favor"}} {{favorLabel}}</span>{{/if}}
|
||||
<span class="chat-pill">{{targetPillLabel}} {{targetPillValue}}</span>
|
||||
<span class="chat-pill">Jet {{keptPillValue}}</span>
|
||||
<span class="chat-pill">{{localize "DNC.Chat.RollValue"}} {{keptPillValue}}</span>
|
||||
</div>
|
||||
<div class="chat-keyline">
|
||||
<span class="chat-keyline-label">Lancers</span>
|
||||
<span class="chat-keyline-label">{{localize "DNC.Chat.Rolls"}}</span>
|
||||
<p class="roll-values">{{#each values}}<span>{{this}}</span>{{/each}}</p>
|
||||
</div>
|
||||
{{#if autoDisadvantage}}
|
||||
<p class="chat-note">
|
||||
<strong>Desavantage automatique</strong> :
|
||||
<strong>{{localize "DNC.Chat.AutoDisadvantage"}}</strong> :
|
||||
{{#if autoDisadvantageCanceled}}
|
||||
le cout du sort depasse le rang du lanceur, mais une faveur l'a annule.
|
||||
{{localize "DNC.Chat.AutoDisadvantageCanceled"}}
|
||||
{{else}}
|
||||
le cout du sort depasse le rang du lanceur.
|
||||
{{localize "DNC.Chat.AutoDisadvantageApplies"}}
|
||||
{{/if}}
|
||||
</p>
|
||||
{{/if}}
|
||||
{{#if favorNote}}
|
||||
<p class="chat-note"><strong>Faveur</strong> : {{favorNote}}</p>
|
||||
<p class="chat-note"><strong>{{localize "DNC.Chat.Favor"}}</strong> : {{favorNote}}</p>
|
||||
{{/if}}
|
||||
{{#if focusValue}}
|
||||
<p class="chat-note">
|
||||
<strong>Focus</strong> : {{focusValue}} depuis {{focusBeforeLabel}}
|
||||
{{#if focusSpent}} · {{focusSpent}} utilise{{/if}}
|
||||
· {{focusRemaining}} restant
|
||||
{{#if focusDegraded}} · le focus descend a {{focusAfterLabel}}{{/if}}
|
||||
{{#if focusRolled}} · premier sort de la scene{{/if}}
|
||||
<strong>{{localize "DNC.UI.Focus"}}</strong> : {{focusValue}} {{localize "DNC.Chat.FocusFrom"}} {{focusBeforeLabel}}
|
||||
{{#if focusSpent}} · {{focusSpent}} {{localize "DNC.Chat.FocusUsed"}}{{/if}}
|
||||
· {{focusRemaining}} {{localize "DNC.Chat.FocusLeft"}}
|
||||
{{#if focusDegraded}} · {{localize "DNC.Chat.FocusDropsTo"}} {{focusAfterLabel}}{{/if}}
|
||||
{{#if focusRolled}} · {{localize "DNC.Chat.FirstSpellScene"}}{{/if}}
|
||||
</p>
|
||||
{{else}}
|
||||
{{#if focusRolled}}
|
||||
<p class="chat-note"><strong>Focus</strong> : aucun apport pour cette scene.</p>
|
||||
<p class="chat-note"><strong>{{localize "DNC.UI.Focus"}}</strong> : {{localize "DNC.Chat.FocusNoBenefit"}}</p>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
<p class="chat-note"><strong>PV depenses</strong> : {{spentPv}} · <strong>PV restants</strong> : {{remainingPv}}</p>
|
||||
<p class="chat-note"><strong>{{localize "DNC.Chat.HpSpent"}}</strong> : {{spentPv}} · <strong>{{localize "DNC.Chat.HpRemaining"}}</strong> : {{remainingPv}}</p>
|
||||
{{#if specialNote}}
|
||||
<p class="chat-note warning">{{specialNote}}</p>
|
||||
{{/if}}
|
||||
{{#if showDamageButton}}
|
||||
<div class="chat-actions">
|
||||
<button type="button" class="chat-action-button" data-action="rollChatDamage" data-item-uuid="{{itemUuid}}">
|
||||
<i class="fa-solid fa-burst"></i> Lancer les degats
|
||||
<i class="fa-solid fa-burst"></i> {{localize "DNC.Chat.RollDamage"}}
|
||||
</button>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{#if showChaosButton}}
|
||||
<div class="chat-actions">
|
||||
<button type="button" class="chat-action-button" data-action="rollSpellChaos" data-actor-uuid="{{actorUuid}}" data-item-uuid="{{itemUuid}}">
|
||||
<i class="fa-solid fa-dice-d20"></i> Risquer le Chaos
|
||||
<i class="fa-solid fa-dice-d20"></i> {{localize "DNC.Chat.RiskChaos"}}
|
||||
</button>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<section class="dnc-chat-card dnc-chat-card-usage">
|
||||
<header class="chat-card-header">
|
||||
<div class="chat-card-heading">
|
||||
<p class="chat-card-kicker">Usure</p>
|
||||
<p class="chat-card-kicker">{{localize "DNC.Chat.Kicker.Wear"}}</p>
|
||||
<h2>{{title}}</h2>
|
||||
</div>
|
||||
<div class="chat-card-seal {{#if degraded}}failure{{else}}success{{/if}}">
|
||||
@@ -10,17 +10,17 @@
|
||||
</header>
|
||||
<div class="chat-pill-row">
|
||||
{{#if modeLabel}}<span class="chat-pill">{{modeLabel}}</span>{{/if}}
|
||||
<span class="chat-pill">Resultat {{value}}</span>
|
||||
<span class="chat-pill">Avant {{before}}</span>
|
||||
<span class="chat-pill">Apres {{after}}</span>
|
||||
<span class="chat-pill">{{localize "DNC.Chat.Result"}} {{value}}</span>
|
||||
<span class="chat-pill">{{localize "DNC.Chat.Before"}} {{before}}</span>
|
||||
<span class="chat-pill">{{localize "DNC.Chat.After"}} {{after}}</span>
|
||||
</div>
|
||||
{{#if values.[1]}}
|
||||
<div class="chat-keyline">
|
||||
<span class="chat-keyline-label">Lancers</span>
|
||||
<span class="chat-keyline-label">{{localize "DNC.Chat.Rolls"}}</span>
|
||||
<p class="roll-values">{{#each values}}<span>{{this}}</span>{{/each}}</p>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{#if protectionStored}}<p class="chat-note">Protection stockee pour ce combat : <strong>{{protectionStored}}</strong>.</p>{{/if}}
|
||||
{{#if degraded}}<p class="chat-note">La ressource s'amenuise.</p>{{else}}<p class="chat-note">La ressource tient bon.</p>{{/if}}
|
||||
{{#if exhausted}}<p class="warning">La ressource est epuisee.</p>{{/if}}
|
||||
{{#if protectionStored}}<p class="chat-note">{{localize "DNC.Chat.StoredProtection"}} : <strong>{{protectionStored}}</strong>.</p>{{/if}}
|
||||
{{#if degraded}}<p class="chat-note">{{localize "DNC.Chat.ResourceWearsDown"}}</p>{{else}}<p class="chat-note">{{localize "DNC.Chat.ResourceStable"}}</p>{{/if}}
|
||||
{{#if exhausted}}<p class="warning">{{localize "DNC.Chat.ResourceExhausted"}}</p>{{/if}}
|
||||
</section>
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
<section class="dnc-chat-card dnc-chat-card-welcome">
|
||||
<header class="chat-card-header">
|
||||
<div class="chat-card-heading">
|
||||
<p class="chat-card-kicker">{{localize "DNC.Welcome.Kicker"}}</p>
|
||||
<h2>{{title}}</h2>
|
||||
<p class="chat-card-subtitle">{{subtitle}}</p>
|
||||
</div>
|
||||
<div class="chat-card-seal success">
|
||||
{{localize "DNC.Welcome.Seal"}}
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<p class="chat-note chat-welcome-intro">{{intro}}</p>
|
||||
|
||||
<ul class="chat-details chat-details-ornate">
|
||||
{{#each bullets}}
|
||||
<li>{{this}}</li>
|
||||
{{/each}}
|
||||
</ul>
|
||||
|
||||
<p class="chat-note chat-welcome-link">
|
||||
<strong>{{helpLabel}}</strong>
|
||||
{{#if helpLink}}
|
||||
{{{helpLink}}}
|
||||
{{else}}
|
||||
{{helpFallback}}
|
||||
{{/if}}
|
||||
</p>
|
||||
|
||||
<p class="chat-note">
|
||||
<strong>{{creditsLabel}}</strong> {{creditsText}}
|
||||
</p>
|
||||
|
||||
<p class="chat-note">
|
||||
<strong>{{officialLabel}}</strong>
|
||||
<a href="{{officialUrl}}" target="_blank" rel="noopener">{{officialLinkText}}</a>
|
||||
</p>
|
||||
|
||||
<p class="chat-note">{{footer}}</p>
|
||||
</section>
|
||||
@@ -1,18 +1,18 @@
|
||||
<div class="dnc-dialog-form">
|
||||
<p><strong>{{actorName}}</strong> effectue un jet de <strong>{{characteristic.label}}</strong>.</p>
|
||||
<label>
|
||||
<span>Mode</span>
|
||||
<span>{{localize "DNC.UI.Mode"}}</span>
|
||||
<select name="mode">
|
||||
<option value="normal">Normal</option>
|
||||
<option value="avantage">Avantage</option>
|
||||
<option value="desavantage">Desavantage</option>
|
||||
<option value="normal">{{localize "DNC.UI.ModeNormal"}}</option>
|
||||
<option value="avantage">{{localize "DNC.UI.ModeAdvantage"}}</option>
|
||||
<option value="desavantage">{{localize "DNC.UI.ModeDisadvantage"}}</option>
|
||||
</select>
|
||||
</label>
|
||||
{{#if hasFavorOptions}}
|
||||
<label>
|
||||
<span>Coup de pouce</span>
|
||||
<span>{{localize "DNC.UI.FavorBoost"}}</span>
|
||||
<select name="favorDepartment">
|
||||
<option value="">Aucune faveur</option>
|
||||
<option value="">{{localize "DNC.UI.NoFavor"}}</option>
|
||||
{{selectOptions favorOptions selected="" labelAttr="label" valueAttr="value" localize=false}}
|
||||
</select>
|
||||
</label>
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
<div class="dnc-dialog-form">
|
||||
<p><strong>{{item.name}}</strong> inflige <strong>{{item.system.degats}}</strong>.</p>
|
||||
<p>Bonus de degats de l'acteur : <strong>{{actorBonus}}</strong></p>
|
||||
<p>{{localize "DNC.Dialog.ActorDamageBonus"}} : <strong>{{actorBonus}}</strong></p>
|
||||
<label>
|
||||
<span>Mode</span>
|
||||
<span>{{localize "DNC.UI.Mode"}}</span>
|
||||
<select name="mode">
|
||||
<option value="normal">Normal</option>
|
||||
<option value="avantage">Avantage</option>
|
||||
<option value="desavantage">Desavantage</option>
|
||||
<option value="normal">{{localize "DNC.UI.ModeNormal"}}</option>
|
||||
<option value="avantage">{{localize "DNC.UI.ModeAdvantage"}}</option>
|
||||
<option value="desavantage">{{localize "DNC.UI.ModeDisadvantage"}}</option>
|
||||
</select>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
<div class="dnc-dialog-form">
|
||||
<p><strong>{{actorName}}</strong> lance l'initiative.</p>
|
||||
<p>DEX actuelle : <strong>{{dex}}</strong>, bonus de fiche : <strong>{{initiativeBonus}}</strong></p>
|
||||
<p>{{localize "DNC.Dialog.InitiativeIntro" actorName=actorName}}</p>
|
||||
<p>{{localize "DNC.Dialog.InitiativeCurrent" dex=dex initiativeBonus=initiativeBonus}}</p>
|
||||
<label>
|
||||
<span>Mode</span>
|
||||
<span>{{localize "DNC.UI.Mode"}}</span>
|
||||
<select name="mode">
|
||||
<option value="normal">Normal</option>
|
||||
<option value="avantage">Avantage</option>
|
||||
<option value="desavantage">Desavantage</option>
|
||||
<option value="normal">{{localize "DNC.UI.ModeNormal"}}</option>
|
||||
<option value="avantage">{{localize "DNC.UI.ModeAdvantage"}}</option>
|
||||
<option value="desavantage">{{localize "DNC.UI.ModeDisadvantage"}}</option>
|
||||
</select>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
<div class="dnc-dialog-form dnc-mission-pack-campaign">
|
||||
<header class="dnc-mission-pack-hero">
|
||||
<p class="dnc-mission-pack-kicker">{{localize "DNC.Chat.Kicker.Logistics"}}</p>
|
||||
<h2>{{localize "DNC.Macro.MissionPack.CampaignDialogTitle"}}</h2>
|
||||
<p class="dnc-mission-pack-subtitle">{{localize "DNC.Macro.MissionPack.CampaignDialogSubtitle"}}</p>
|
||||
<p class="dnc-mission-pack-intro">{{localize "DNC.Macro.MissionPack.CampaignDialogIntro" actor=actorName}}</p>
|
||||
</header>
|
||||
|
||||
<section class="dnc-mission-pack-meta-grid">
|
||||
<article class="dnc-mission-pack-meta-card">
|
||||
<span>{{localize "DNC.Macro.MissionPack.DialogActor"}}</span>
|
||||
<strong>{{actorName}}</strong>
|
||||
</article>
|
||||
<article class="dnc-mission-pack-meta-card">
|
||||
<span>{{localize "DNC.Macro.MissionPack.CampaignDialogPlayer"}}</span>
|
||||
<strong>{{playerName}}</strong>
|
||||
</article>
|
||||
{{#if requesterName}}
|
||||
<article class="dnc-mission-pack-meta-card">
|
||||
<span>{{localize "DNC.Macro.MissionPack.CampaignDialogRequester"}}</span>
|
||||
<strong>{{requesterName}}</strong>
|
||||
</article>
|
||||
{{/if}}
|
||||
<article class="dnc-mission-pack-meta-card">
|
||||
<span>{{localize "DNC.Macro.MissionPack.CampaignDialogRank"}}</span>
|
||||
<strong>+{{rank}}</strong>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<section class="dnc-mission-pack-section">
|
||||
<label class="dnc-mission-pack-select">
|
||||
<span>{{localize "DNC.Macro.MissionPack.CampaignDialogRelation"}}</span>
|
||||
<select name="stewardRelation">
|
||||
{{selectOptions relationOptions selected=selectedRelation labelAttr="label" valueAttr="value" localize=false}}
|
||||
</select>
|
||||
</label>
|
||||
</section>
|
||||
|
||||
<section class="dnc-mission-pack-section">
|
||||
<p class="dnc-mission-pack-note">{{localize "DNC.Macro.MissionPack.CampaignDialogAssignHelp"}}</p>
|
||||
<div class="dnc-mission-pack-assignments">
|
||||
{{#each assignments}}
|
||||
<label class="dnc-mission-pack-assignment">
|
||||
<span>{{this.label}}</span>
|
||||
<select name="{{this.fieldName}}">
|
||||
{{selectOptions ../diceOptions selected=this.selectedDie labelAttr="label" valueAttr="value" localize=false}}
|
||||
</select>
|
||||
</label>
|
||||
{{/each}}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<p class="dnc-mission-pack-note dnc-mission-pack-note-foot">{{localize "DNC.Macro.MissionPack.CampaignDialogHelp"}}</p>
|
||||
</div>
|
||||
@@ -0,0 +1,14 @@
|
||||
<div class="dnc-dialog-form">
|
||||
<p>{{localize "DNC.Macro.MissionPack.DialogIntro"}}</p>
|
||||
<p class="dnc-mission-pack-mode"><strong>{{localize "DNC.Macro.MissionPack.ActiveMode"}}</strong> {{modeLabel}}</p>
|
||||
<p>{{modeDescription}}</p>
|
||||
<label>
|
||||
<span>{{localize "DNC.Macro.MissionPack.DialogActor"}}</span>
|
||||
<select name="actorId">
|
||||
{{selectOptions actorOptions selected=selectedActorId labelAttr="label" valueAttr="value" localize=false}}
|
||||
</select>
|
||||
</label>
|
||||
{{#if isCampaign}}
|
||||
<p class="dnc-mission-pack-note">{{localize "DNC.Macro.MissionPack.CampaignDialogLead"}}</p>
|
||||
{{/if}}
|
||||
</div>
|
||||
@@ -1,47 +1,47 @@
|
||||
<div class="dnc-dialog-form">
|
||||
<p><strong>{{actorName}}</strong> lance <strong>{{item.name}}</strong>.</p>
|
||||
<label>
|
||||
<span>Caracteristique</span>
|
||||
<span>{{localize "DNC.UI.Characteristic"}}</span>
|
||||
<input type="text" value="{{characteristic.label}} ({{characteristic.value}})" readonly>
|
||||
</label>
|
||||
<label>
|
||||
<span>Cout</span>
|
||||
<span>{{localize "DNC.UI.Cost"}}</span>
|
||||
<input type="text" value="{{item.system.coutPv}} PV" readonly>
|
||||
</label>
|
||||
<label>
|
||||
<span>PV actuels</span>
|
||||
<span>{{localize "DNC.UI.CurrentHp"}}</span>
|
||||
<input type="text" value="{{currentPv}}" readonly>
|
||||
</label>
|
||||
<label>
|
||||
<span>Rang</span>
|
||||
<span>{{localize "DNC.UI.Rank"}}</span>
|
||||
<input type="text" value="{{rank}}" readonly>
|
||||
</label>
|
||||
<label>
|
||||
<span>Focus</span>
|
||||
<span>{{localize "DNC.UI.Focus"}}</span>
|
||||
<input type="text" value="{{#if focusIsActive}}{{focusDisplay}}{{else}}{{focusLabel}}{{/if}}" readonly>
|
||||
</label>
|
||||
<label>
|
||||
<span>Chaos</span>
|
||||
<span>{{localize "DNC.UI.Chaos"}}</span>
|
||||
<input type="text" value="{{chaosLabel}}" readonly>
|
||||
</label>
|
||||
<label>
|
||||
<span>Mode</span>
|
||||
<span>{{localize "DNC.UI.Mode"}}</span>
|
||||
<select name="mode">
|
||||
<option value="normal">Normal</option>
|
||||
<option value="avantage">Avantage</option>
|
||||
<option value="desavantage">Desavantage</option>
|
||||
<option value="normal">{{localize "DNC.UI.ModeNormal"}}</option>
|
||||
<option value="avantage">{{localize "DNC.UI.ModeAdvantage"}}</option>
|
||||
<option value="desavantage">{{localize "DNC.UI.ModeDisadvantage"}}</option>
|
||||
</select>
|
||||
</label>
|
||||
{{#if hasFavorOptions}}
|
||||
<label>
|
||||
<span>Coup de pouce</span>
|
||||
<span>{{localize "DNC.UI.FavorBoost"}}</span>
|
||||
<select name="favorDepartment">
|
||||
<option value="">Aucune faveur</option>
|
||||
<option value="">{{localize "DNC.UI.NoFavor"}}</option>
|
||||
{{selectOptions favorOptions selected="" labelAttr="label" valueAttr="value" localize=false}}
|
||||
</select>
|
||||
</label>
|
||||
{{/if}}
|
||||
{{#if autoDisadvantage}}
|
||||
<p class="dialog-help warning">Le cout depasse le rang du lanceur : le jet se fera automatiquement avec desavantage.</p>
|
||||
<p class="dialog-help warning">{{localize "DNC.Dialog.SpellAutoDisadvantage"}}</p>
|
||||
{{/if}}
|
||||
</div>
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
<div class="dnc-dialog-form">
|
||||
<p>Utiliser <strong>{{item.name}}</strong> et lancer son de d'usage actuel.</p>
|
||||
<p>Valeur actuelle : <strong>Δ{{item.system.delta}}</strong></p>
|
||||
<p>{{localize "DNC.Dialog.UseUsageDie" itemName=item.name}}</p>
|
||||
<p>{{localize "DNC.Dialog.CurrentValue"}} : <strong>Δ{{item.system.delta}}</strong></p>
|
||||
<label>
|
||||
<span>Mode</span>
|
||||
<span>{{localize "DNC.UI.Mode"}}</span>
|
||||
<select name="mode">
|
||||
<option value="normal">Normal</option>
|
||||
<option value="avantage">Avantage</option>
|
||||
<option value="desavantage">Desavantage</option>
|
||||
<option value="normal">{{localize "DNC.UI.ModeNormal"}}</option>
|
||||
<option value="avantage">{{localize "DNC.UI.ModeAdvantage"}}</option>
|
||||
<option value="desavantage">{{localize "DNC.UI.ModeDisadvantage"}}</option>
|
||||
</select>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
<div class="dnc-dialog-form">
|
||||
<p><strong>{{actorName}}</strong> attaque avec <strong>{{item.name}}</strong>.</p>
|
||||
<p>Caracteristique utilisee : <strong>{{characteristicLabel}}</strong> (<strong>{{characteristicValue}}</strong>).</p>
|
||||
<p>{{localize "DNC.Dialog.CharacteristicUsed"}} : <strong>{{characteristicLabel}}</strong> (<strong>{{characteristicValue}}</strong>).</p>
|
||||
<label>
|
||||
<span>Mode</span>
|
||||
<span>{{localize "DNC.UI.Mode"}}</span>
|
||||
<select name="mode">
|
||||
<option value="normal">Normal</option>
|
||||
<option value="avantage">Avantage</option>
|
||||
<option value="desavantage">Desavantage</option>
|
||||
<option value="normal">{{localize "DNC.UI.ModeNormal"}}</option>
|
||||
<option value="avantage">{{localize "DNC.UI.ModeAdvantage"}}</option>
|
||||
<option value="desavantage">{{localize "DNC.UI.ModeDisadvantage"}}</option>
|
||||
</select>
|
||||
</label>
|
||||
{{#if hasFavorOptions}}
|
||||
<label>
|
||||
<span>Coup de pouce</span>
|
||||
<span>{{localize "DNC.UI.FavorBoost"}}</span>
|
||||
<select name="favorDepartment">
|
||||
<option value="">Aucune faveur</option>
|
||||
<option value="">{{localize "DNC.UI.NoFavor"}}</option>
|
||||
{{selectOptions favorOptions selected="" labelAttr="label" valueAttr="value" localize=false}}
|
||||
</select>
|
||||
</label>
|
||||
|
||||
@@ -53,7 +53,7 @@
|
||||
<input type="number" name="system.quantite" value="{{system.quantite}}">
|
||||
</label>
|
||||
<label>
|
||||
<span>Delta</span>
|
||||
<span>De d'usure</span>
|
||||
<select name="system.delta">{{selectOptions config.usageDieOptions selected=system.delta localize=false}}</select>
|
||||
</label>
|
||||
<label class="span-two">
|
||||
@@ -73,6 +73,21 @@
|
||||
</label>
|
||||
{{/if}}
|
||||
|
||||
{{#if isTraining}}
|
||||
<label>
|
||||
<span>De d'usure courant</span>
|
||||
<select name="system.delta">{{selectOptions config.usageDieOptions selected=system.delta localize=false blank="Epuise"}}</select>
|
||||
</label>
|
||||
<label>
|
||||
<span>De d'usure max</span>
|
||||
<select name="system.deltaMax">{{selectOptions config.usageDieOptions selected=system.deltaMax localize=false}}</select>
|
||||
</label>
|
||||
<label class="span-two">
|
||||
<span>Effet</span>
|
||||
<input type="text" name="system.effet" value="{{system.effet}}">
|
||||
</label>
|
||||
{{/if}}
|
||||
|
||||
{{#if isSpell}}
|
||||
<label>
|
||||
<span>Caracteristique</span>
|
||||
@@ -144,6 +159,9 @@
|
||||
<footer class="sheet-footer">
|
||||
<button type="button" data-action="postItem" aria-label="Poster dans le chat"><i class="fa-solid fa-message"></i> Poster dans le chat</button>
|
||||
<button type="button" data-action="rollItem" aria-label="Utiliser ou lancer l'objet"><i class="fa-solid fa-dice-d20"></i> Utiliser / lancer</button>
|
||||
{{#if canResetUsage}}
|
||||
<button type="button" data-action="resetUsageItem" aria-label="Reinitialiser l'usage"><i class="fa-solid fa-arrow-rotate-left"></i> Reinitialiser</button>
|
||||
{{/if}}
|
||||
{{#if canRollDamage}}
|
||||
<button type="button" data-action="rollDamageItem" aria-label="Lancer les degats"><i class="fa-solid fa-burst"></i> Lancer les degats</button>
|
||||
{{/if}}
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
import { compilePack, extractPack } from "@foundryvtt/foundryvtt-cli";
|
||||
import { promises as fs } from "node:fs";
|
||||
import path from "node:path";
|
||||
|
||||
const ROOT_DIR = process.cwd();
|
||||
|
||||
export class CompendiumsManager {
|
||||
static async packToDistDir(srcDir = "packs_src", distDir = "packs", mode = "json") {
|
||||
const yaml = mode === "yaml";
|
||||
const packs = await fs.readdir(path.join(ROOT_DIR, srcDir));
|
||||
for (const pack of packs) {
|
||||
if (pack.startsWith(".")) continue;
|
||||
|
||||
const sourcePath = path.join(ROOT_DIR, srcDir, pack);
|
||||
const targetPath = path.join(ROOT_DIR, distDir, pack);
|
||||
await fs.rm(targetPath, { recursive: true, force: true });
|
||||
console.log(`Packing ${pack}`);
|
||||
await compilePack(sourcePath, targetPath, { yaml });
|
||||
}
|
||||
}
|
||||
|
||||
static async unpackToSrcDir(srcDir = "packs_src", distDir = "packs", mode = "json") {
|
||||
const yaml = mode === "yaml";
|
||||
const packs = await fs.readdir(path.join(ROOT_DIR, distDir));
|
||||
for (const pack of packs) {
|
||||
if (pack.startsWith(".")) continue;
|
||||
|
||||
const sourcePath = path.join(ROOT_DIR, distDir, pack);
|
||||
const targetPath = path.join(ROOT_DIR, srcDir, pack);
|
||||
await fs.mkdir(targetPath, { recursive: true });
|
||||
|
||||
const existingFiles = await fs.readdir(targetPath);
|
||||
for (const file of existingFiles) {
|
||||
await fs.unlink(path.join(targetPath, file));
|
||||
}
|
||||
|
||||
console.log(`Unpacking ${pack}`);
|
||||
await extractPack(sourcePath, targetPath, {
|
||||
yaml,
|
||||
transformName: (doc) => CompendiumsManager.transformName(doc, yaml)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
static transformName(doc, yaml) {
|
||||
const safeName = (doc.name ?? doc._id ?? "document").replace(/[^a-zA-Z0-9_-]+/g, "_");
|
||||
const type = doc._key?.split("!")[1] ?? doc.type ?? "document";
|
||||
const extension = yaml ? "yml" : "json";
|
||||
return `${type}_${safeName}_${doc._id}.${extension}`;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
import { CompendiumsManager } from "./CompendiumsManager.mjs";
|
||||
|
||||
await CompendiumsManager.packToDistDir();
|
||||
@@ -0,0 +1,3 @@
|
||||
import { CompendiumsManager } from "./CompendiumsManager.mjs";
|
||||
|
||||
await CompendiumsManager.unpackToSrcDir();
|
||||
Reference in New Issue
Block a user