Compare commits
21 Commits
foundryvtt
...
9.5.1
| Author | SHA1 | Date | |
|---|---|---|---|
| df1e0b9952 | |||
| b1e96af421 | |||
| 17d865b60b | |||
| 5f4e0c7ce5 | |||
| 8862698262 | |||
| 047933a610 | |||
| b489f65618 | |||
| 406a535c76 | |||
| 5bc6d0d2f5 | |||
| d557fac83f | |||
| f07ef0b01d | |||
| 301cc830bc | |||
| 786afeab74 | |||
| e0383def30 | |||
| 7dc51444f0 | |||
| 752a6701c0 | |||
| 0e8237c233 | |||
| df26a699a0 | |||
| 0a1fa37e49 | |||
| 5b7fba4c87 | |||
| d710061eeb |
89
.gitea/workflows/release.yaml
Normal file
89
.gitea/workflows/release.yaml
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
name: Release Creation
|
||||||
|
|
||||||
|
on:
|
||||||
|
release:
|
||||||
|
types: [published]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- run: echo "💡 The ${{ gitea.repository }} repository will be cloned to the runner."
|
||||||
|
|
||||||
|
- uses: RouxAntoine/checkout@v3.5.4
|
||||||
|
|
||||||
|
# Valider les JSON avant de packager
|
||||||
|
- name: Valider fr.json et module.json
|
||||||
|
run: |
|
||||||
|
python3 -mjson.tool fr.json > /dev/null
|
||||||
|
python3 -mjson.tool module.json > /dev/null
|
||||||
|
|
||||||
|
# Générer modules/loadScripts.js depuis scripts/
|
||||||
|
- name: Build (génération de loadScripts.js)
|
||||||
|
run: node scriptPacker.js
|
||||||
|
|
||||||
|
# Extraire le numéro de version depuis le tag (sans le 'v' initial)
|
||||||
|
- name: Extraire la version depuis le tag
|
||||||
|
id: get_version
|
||||||
|
uses: battila7/get-version-action@v2
|
||||||
|
|
||||||
|
# Mettre à jour version, url, manifest et download dans module.json
|
||||||
|
- name: Substituer les URLs de Manifest et Download
|
||||||
|
id: sub_manifest_link_version
|
||||||
|
uses: microsoft/variable-substitution@v1
|
||||||
|
with:
|
||||||
|
files: 'module.json'
|
||||||
|
env:
|
||||||
|
version: ${{ steps.get_version.outputs.version-without-v }}
|
||||||
|
url: https://www.uberwald.me/gitea/${{ gitea.repository }}
|
||||||
|
manifest: https://www.uberwald.me/gitea/public/foundryvtt-wh4-lang-fr-fr/releases/download/latest/module.json
|
||||||
|
download: https://www.uberwald.me/gitea/${{ gitea.repository }}/releases/download/${{ github.event.release.tag_name }}/foundryvtt-wh4-lang-fr-fr.zip
|
||||||
|
|
||||||
|
# Créer le zip avec uniquement les fichiers nécessaires au module Foundry
|
||||||
|
- name: Installer zip
|
||||||
|
run: |
|
||||||
|
apt update -y
|
||||||
|
apt install -y zip
|
||||||
|
|
||||||
|
- name: Créer l'archive foundryvtt-wh4-lang-fr-fr.zip
|
||||||
|
run: >
|
||||||
|
zip -r ./foundryvtt-wh4-lang-fr-fr.zip
|
||||||
|
module.json
|
||||||
|
fr.json
|
||||||
|
wh4_fr.js
|
||||||
|
patch-styles.css
|
||||||
|
README.md
|
||||||
|
LICENSE
|
||||||
|
compendium/
|
||||||
|
modules/
|
||||||
|
packs/
|
||||||
|
icons/
|
||||||
|
images/
|
||||||
|
trade/
|
||||||
|
|
||||||
|
# Publier le zip et le module.json sur la release Gitea
|
||||||
|
- name: setup go
|
||||||
|
uses: https://github.com/actions/setup-go@v4
|
||||||
|
with:
|
||||||
|
go-version: '>=1.20.1'
|
||||||
|
|
||||||
|
- name: Publier les assets sur la release Gitea
|
||||||
|
id: use-go-action
|
||||||
|
uses: https://gitea.com/actions/release-action@main
|
||||||
|
with:
|
||||||
|
files: |-
|
||||||
|
./foundryvtt-wh4-lang-fr-fr.zip
|
||||||
|
module.json
|
||||||
|
api_key: '${{ secrets.ALLOW_PUSH_RELEASE }}'
|
||||||
|
|
||||||
|
# Déclarer la release sur le portail FoundryVTT
|
||||||
|
- name: Publier sur FoundryVTT
|
||||||
|
uses: https://github.com/djlechuck/foundryvtt-publish-package-action@v1
|
||||||
|
with:
|
||||||
|
token: ${{ secrets.FOUNDRYVTT_RELEASE_TOKEN }}
|
||||||
|
id: 'wh4-fr-translation'
|
||||||
|
version: ${{ github.event.release.tag_name }}
|
||||||
|
manifest: 'https://www.uberwald.me/gitea/public/foundryvtt-wh4-lang-fr-fr/releases/download/latest/module.json'
|
||||||
|
notes: 'https://www.uberwald.me/gitea/${{ gitea.repository }}/releases/tag/${{ github.event.release.tag_name }}'
|
||||||
|
compatibility-minimum: '13'
|
||||||
|
compatibility-verified: '13'
|
||||||
19
.gitea/workflows/validate.yaml
Normal file
19
.gitea/workflows/validate.yaml
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
name: Validation JSON
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- '**'
|
||||||
|
pull_request:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
validate:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: RouxAntoine/checkout@v3.5.4
|
||||||
|
|
||||||
|
- name: Valider fr.json
|
||||||
|
run: python3 -mjson.tool fr.json > /dev/null
|
||||||
|
|
||||||
|
- name: Valider module.json
|
||||||
|
run: python3 -mjson.tool module.json > /dev/null
|
||||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,2 +1,3 @@
|
|||||||
.history/
|
.history/
|
||||||
.idea/
|
.idea/
|
||||||
|
.github/
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
image: python:3-alpine
|
|
||||||
|
|
||||||
before_script:
|
|
||||||
- apk update
|
|
||||||
- apk add zip
|
|
||||||
|
|
||||||
stages:
|
|
||||||
- test
|
|
||||||
- build
|
|
||||||
|
|
||||||
test:
|
|
||||||
stage: test
|
|
||||||
script:
|
|
||||||
- python -mjson.tool 'fr.json' > /dev/null
|
|
||||||
- python -mjson.tool 'module.json' > /dev/null
|
|
||||||
|
|
||||||
build:
|
|
||||||
stage: build
|
|
||||||
script:
|
|
||||||
- zip wh4-fr-FR.zip -r *.js *.json *.md compendium lang tables -x ".*"
|
|
||||||
artifacts:
|
|
||||||
name: wh4-fr-FR
|
|
||||||
when: on_success
|
|
||||||
paths:
|
|
||||||
- wh4-fr-FR.zip
|
|
||||||
when: on_success
|
|
||||||
only:
|
|
||||||
- tags
|
|
||||||
- master
|
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"label": "Items (Lustria)",
|
"label": "Items (Lustria)",
|
||||||
"folders": {
|
"folders": {
|
||||||
"Careers": "Carrières",
|
"Careers": "Carrières",
|
||||||
"Spells": "Sorts",
|
"Spells": "Sorts",
|
||||||
"Trappings": "Possessions",
|
"Trappings": "Possessions",
|
||||||
@@ -69,16 +69,10 @@
|
|||||||
"converter": "generic_localization"
|
"converter": "generic_localization"
|
||||||
},
|
},
|
||||||
"durationValue": "system.duration.value",
|
"durationValue": "system.duration.value",
|
||||||
"durationUnit": {
|
"durationUnit": "system.duration.unit",
|
||||||
"path": "system.duration.unit",
|
|
||||||
"converter": "disease_duration_unit"
|
|
||||||
},
|
|
||||||
"contraction": "system.contraction.value",
|
"contraction": "system.contraction.value",
|
||||||
"incubationValue": "system.incubation.value",
|
"incubationValue": "system.incubation.value",
|
||||||
"incubationUnit": {
|
"incubationUnit": "system.incubation.unit",
|
||||||
"path": "system.incubation.unit",
|
|
||||||
"converter": "disease_duration_unit"
|
|
||||||
},
|
|
||||||
"symptoms": "system.symptoms.value",
|
"symptoms": "system.symptoms.value",
|
||||||
"permanent": "system.permanent.value",
|
"permanent": "system.permanent.value",
|
||||||
"special": "system.special.value",
|
"special": "system.special.value",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"label": "Items (Old World Bundle II)",
|
"label": "Items (Old World Bundle II)",
|
||||||
"folders": {
|
"folders": {
|
||||||
"Lore of the Beasts": "Domaine des Bêtes",
|
"Lore of the Beasts": "Domaine des Bêtes",
|
||||||
"Lore of Death": "Domaine de la Mort",
|
"Lore of Death": "Domaine de la Mort",
|
||||||
"Lore of Fire": "Domaine du Feu",
|
"Lore of Fire": "Domaine du Feu",
|
||||||
@@ -78,16 +78,10 @@
|
|||||||
"converter": "generic_localization"
|
"converter": "generic_localization"
|
||||||
},
|
},
|
||||||
"durationValue": "system.duration.value",
|
"durationValue": "system.duration.value",
|
||||||
"durationUnit": {
|
"durationUnit": "system.duration.unit",
|
||||||
"path": "system.duration.unit",
|
|
||||||
"converter": "disease_duration_unit"
|
|
||||||
},
|
|
||||||
"contraction": "system.contraction.value",
|
"contraction": "system.contraction.value",
|
||||||
"incubationValue": "system.incubation.value",
|
"incubationValue": "system.incubation.value",
|
||||||
"incubationUnit": {
|
"incubationUnit": "system.incubation.unit",
|
||||||
"path": "system.incubation.unit",
|
|
||||||
"converter": "disease_duration_unit"
|
|
||||||
},
|
|
||||||
"symptoms": "system.symptoms.value",
|
"symptoms": "system.symptoms.value",
|
||||||
"permanent": "system.permanent.value",
|
"permanent": "system.permanent.value",
|
||||||
"special": "system.special.value",
|
"special": "system.special.value",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"label": "Items (Imperial Zoo)",
|
"label": "Items (Imperial Zoo)",
|
||||||
"folders": {
|
"folders": {
|
||||||
"Ammunition": "Munitions",
|
"Ammunition": "Munitions",
|
||||||
"Careers": "Carrières",
|
"Careers": "Carrières",
|
||||||
"Prayers": "Prières",
|
"Prayers": "Prières",
|
||||||
@@ -70,16 +70,10 @@
|
|||||||
"converter": "generic_localization"
|
"converter": "generic_localization"
|
||||||
},
|
},
|
||||||
"durationValue": "system.duration.value",
|
"durationValue": "system.duration.value",
|
||||||
"durationUnit": {
|
"durationUnit": "system.duration.unit",
|
||||||
"path": "system.duration.unit",
|
|
||||||
"converter": "disease_duration_unit"
|
|
||||||
},
|
|
||||||
"contraction": "system.contraction.value",
|
"contraction": "system.contraction.value",
|
||||||
"incubationValue": "system.incubation.value",
|
"incubationValue": "system.incubation.value",
|
||||||
"incubationUnit": {
|
"incubationUnit": "system.incubation.unit",
|
||||||
"path": "system.incubation.unit",
|
|
||||||
"converter": "disease_duration_unit"
|
|
||||||
},
|
|
||||||
"symptoms": "system.symptoms.value",
|
"symptoms": "system.symptoms.value",
|
||||||
"permanent": "system.permanent.value",
|
"permanent": "system.permanent.value",
|
||||||
"special": "system.special.value",
|
"special": "system.special.value",
|
||||||
|
|||||||
92
find-blessures-variables.cjs
Normal file
92
find-blessures-variables.cjs
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
const fs = require('fs');
|
||||||
|
const path = require('path');
|
||||||
|
|
||||||
|
// Patterns pour détecter les variables JavaScript nommées "Blessures"
|
||||||
|
const patterns = [
|
||||||
|
// Déclarations de variables
|
||||||
|
/\b(let|const|var)\s+Blessures\b/g,
|
||||||
|
// Paramètres de fonction
|
||||||
|
/function\s+\w*\s*\([^)]*\bBlessures\b[^)]*\)/g,
|
||||||
|
// Arrow functions avec paramètres
|
||||||
|
/\(\s*[^)]*\bBlessures\b[^)]*\)\s*=>/g,
|
||||||
|
// Arrow function avec un seul paramètre sans parenthèses
|
||||||
|
/\bBlessures\s*=>/g,
|
||||||
|
// Destructuration d'objets
|
||||||
|
/\{\s*[^}]*\bBlessures\b[^}]*\}\s*=/g,
|
||||||
|
// Destructuration de tableaux
|
||||||
|
/\[\s*[^\]]*\bBlessures\b[^\]]*\]\s*=/g,
|
||||||
|
// Catch clause
|
||||||
|
/catch\s*\(\s*Blessures\s*\)/g,
|
||||||
|
// For...of/in loops
|
||||||
|
/for\s*\(\s*(let|const|var)?\s*Blessures\s+(of|in)\b/g,
|
||||||
|
];
|
||||||
|
|
||||||
|
function findBlessuresInFile(filePath) {
|
||||||
|
const content = fs.readFileSync(filePath, 'utf-8');
|
||||||
|
const lines = content.split('\n');
|
||||||
|
const results = [];
|
||||||
|
|
||||||
|
lines.forEach((line, index) => {
|
||||||
|
patterns.forEach(pattern => {
|
||||||
|
pattern.lastIndex = 0; // Reset regex
|
||||||
|
if (pattern.test(line)) {
|
||||||
|
results.push({
|
||||||
|
line: index + 1,
|
||||||
|
content: line.trim()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
|
||||||
|
function walkDirectory(dir) {
|
||||||
|
const files = fs.readdirSync(dir);
|
||||||
|
const allResults = {};
|
||||||
|
|
||||||
|
files.forEach(file => {
|
||||||
|
const filePath = path.join(dir, file);
|
||||||
|
const stat = fs.statSync(filePath);
|
||||||
|
|
||||||
|
if (stat.isDirectory()) {
|
||||||
|
Object.assign(allResults, walkDirectory(filePath));
|
||||||
|
} else if (file.endsWith('.js')) {
|
||||||
|
const results = findBlessuresInFile(filePath);
|
||||||
|
if (results.length > 0) {
|
||||||
|
allResults[filePath] = results;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return allResults;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Main
|
||||||
|
const scriptsDir = path.join(__dirname, 'scripts');
|
||||||
|
|
||||||
|
console.log('🔍 Recherche des variables JavaScript nommées "Blessures" dans le répertoire scripts/...\n');
|
||||||
|
|
||||||
|
if (!fs.existsSync(scriptsDir)) {
|
||||||
|
console.error('❌ Le répertoire scripts/ n\'existe pas');
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
const results = walkDirectory(scriptsDir);
|
||||||
|
|
||||||
|
if (Object.keys(results).length === 0) {
|
||||||
|
console.log('✅ Aucune variable JavaScript nommée "Blessures" trouvée.');
|
||||||
|
} else {
|
||||||
|
console.log(`⚠️ ${Object.keys(results).length} fichier(s) contenant des variables "Blessures" :\n`);
|
||||||
|
|
||||||
|
Object.entries(results).forEach(([filePath, occurrences]) => {
|
||||||
|
const relativePath = path.relative(__dirname, filePath);
|
||||||
|
console.log(`📄 ${relativePath}`);
|
||||||
|
occurrences.forEach(({ line, content }) => {
|
||||||
|
console.log(` Ligne ${line}: ${content}`);
|
||||||
|
});
|
||||||
|
console.log('');
|
||||||
|
});
|
||||||
|
}
|
||||||
92
find-tests-variables.cjs
Normal file
92
find-tests-variables.cjs
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
const fs = require('fs');
|
||||||
|
const path = require('path');
|
||||||
|
|
||||||
|
// Patterns pour détecter les variables JavaScript nommées "Tests"
|
||||||
|
const patterns = [
|
||||||
|
// Déclarations de variables
|
||||||
|
/\b(let|const|var)\s+Tests\b/g,
|
||||||
|
// Paramètres de fonction
|
||||||
|
/function\s+\w*\s*\([^)]*\bTests\b[^)]*\)/g,
|
||||||
|
// Arrow functions avec paramètres
|
||||||
|
/\(\s*[^)]*\bTests\b[^)]*\)\s*=>/g,
|
||||||
|
// Arrow function avec un seul paramètre sans parenthèses
|
||||||
|
/\bTests\s*=>/g,
|
||||||
|
// Destructuration d'objets
|
||||||
|
/\{\s*[^}]*\bTests\b[^}]*\}\s*=/g,
|
||||||
|
// Destructuration de tableaux
|
||||||
|
/\[\s*[^\]]*\bTests\b[^\]]*\]\s*=/g,
|
||||||
|
// Catch clause
|
||||||
|
/catch\s*\(\s*Tests\s*\)/g,
|
||||||
|
// For...of/in loops
|
||||||
|
/for\s*\(\s*(let|const|var)?\s*Tests\s+(of|in)\b/g,
|
||||||
|
];
|
||||||
|
|
||||||
|
function findTestsInFile(filePath) {
|
||||||
|
const content = fs.readFileSync(filePath, 'utf-8');
|
||||||
|
const lines = content.split('\n');
|
||||||
|
const results = [];
|
||||||
|
|
||||||
|
lines.forEach((line, index) => {
|
||||||
|
patterns.forEach(pattern => {
|
||||||
|
pattern.lastIndex = 0; // Reset regex
|
||||||
|
if (pattern.test(line)) {
|
||||||
|
results.push({
|
||||||
|
line: index + 1,
|
||||||
|
content: line.trim()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
|
||||||
|
function walkDirectory(dir) {
|
||||||
|
const files = fs.readdirSync(dir);
|
||||||
|
const allResults = {};
|
||||||
|
|
||||||
|
files.forEach(file => {
|
||||||
|
const filePath = path.join(dir, file);
|
||||||
|
const stat = fs.statSync(filePath);
|
||||||
|
|
||||||
|
if (stat.isDirectory()) {
|
||||||
|
Object.assign(allResults, walkDirectory(filePath));
|
||||||
|
} else if (file.endsWith('.js')) {
|
||||||
|
const results = findTestsInFile(filePath);
|
||||||
|
if (results.length > 0) {
|
||||||
|
allResults[filePath] = results;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return allResults;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Main
|
||||||
|
const scriptsDir = path.join(__dirname, 'scripts');
|
||||||
|
|
||||||
|
console.log('🔍 Recherche des variables JavaScript nommées "Tests" dans le répertoire scripts/...\n');
|
||||||
|
|
||||||
|
if (!fs.existsSync(scriptsDir)) {
|
||||||
|
console.error('❌ Le répertoire scripts/ n\'existe pas');
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
const results = walkDirectory(scriptsDir);
|
||||||
|
|
||||||
|
if (Object.keys(results).length === 0) {
|
||||||
|
console.log('✅ Aucune variable JavaScript nommée "Tests" trouvée.');
|
||||||
|
} else {
|
||||||
|
console.log(`⚠️ ${Object.keys(results).length} fichier(s) contenant des variables "Tests" :\n`);
|
||||||
|
|
||||||
|
Object.entries(results).forEach(([filePath, occurrences]) => {
|
||||||
|
const relativePath = path.relative(__dirname, filePath);
|
||||||
|
console.log(`📄 ${relativePath}`);
|
||||||
|
occurrences.forEach(({ line, content }) => {
|
||||||
|
console.log(` Ligne ${line}: ${content}`);
|
||||||
|
});
|
||||||
|
console.log('');
|
||||||
|
});
|
||||||
|
}
|
||||||
11
foundryvtt-wh4-lang-fr-fr.code-workspace
Normal file
11
foundryvtt-wh4-lang-fr-fr.code-workspace
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"folders": [
|
||||||
|
{
|
||||||
|
"path": "."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "../WFRP4e-FoundryVTT"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"settings": {}
|
||||||
|
}
|
||||||
@@ -8,7 +8,7 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"url": "https://www.uberwald.me/gitea/public/foundryvtt-wh4-lang-fr-fr",
|
"url": "https://www.uberwald.me/gitea/public/foundryvtt-wh4-lang-fr-fr",
|
||||||
"version": "9.3.4",
|
"version": "9.4.3",
|
||||||
"esmodules": [
|
"esmodules": [
|
||||||
"wh4_fr.js",
|
"wh4_fr.js",
|
||||||
"modules/babele-register.js",
|
"modules/babele-register.js",
|
||||||
@@ -119,12 +119,12 @@
|
|||||||
"folders": []
|
"folders": []
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"manifest": "https://www.uberwald.me/gitea/public/foundryvtt-wh4-lang-fr-fr/raw/v10/module.json",
|
"manifest": "https://www.uberwald.me/gitea/public/foundryvtt-wh4-lang-fr-fr/releases/download/latest/module.json",
|
||||||
"download": "https://www.uberwald.me/gitea/public/foundryvtt-wh4-lang-fr-fr/archive/foundryvtt-wh4-lang-fr-9-3-4.zip",
|
"download": "https://www.uberwald.me/gitea/public/foundryvtt-wh4-lang-fr-fr/releases/download/latest/foundryvtt-wh4-lang-fr-fr.zip",
|
||||||
"id": "wh4-fr-translation",
|
"id": "wh4-fr-translation",
|
||||||
"compatibility": {
|
"compatibility": {
|
||||||
"minimum": "13",
|
"minimum": "13",
|
||||||
"verified": "13"
|
"verified": "14"
|
||||||
},
|
},
|
||||||
"relationships": {
|
"relationships": {
|
||||||
"systems": [
|
"systems": [
|
||||||
|
|||||||
@@ -16,30 +16,27 @@ const _patch_eis = () => {
|
|||||||
game.wfrp4e.config.symptomTreatment["swelling"] = "La plupart des traitements consistent à plonger la partie affectée, ou parfois tout le corps, dans un bain d'eau glacée pour réduire la chaleur qui accompagne les gonflements. Un <b> Test de Guérison Difficile (-20) étendu </b> nécessitant +3 DR réduit le renflement de <b> <a class ='chat-roll'> 2d10 </a> </b> heures. Chaque test dure une heure. Le patient se retrouve avec l'Etat Exténué +1 pour chaque test effectué au cours du processus. <br> <br> A la place, certains médecins saignent le patient avec une lame ou des sangsues. Un <b>Test de Guérison étendu </b> réussi nécessitant +4 SL et des Outils (médecin) réduit le renflement de (<a class ='chat-roll'> 1d10 </a> + Bonus d'Endurance du patient) heures. Chaque test a une difficulté de base <b> impossible (-50) </b> et dure une demi-heure.";
|
game.wfrp4e.config.symptomTreatment["swelling"] = "La plupart des traitements consistent à plonger la partie affectée, ou parfois tout le corps, dans un bain d'eau glacée pour réduire la chaleur qui accompagne les gonflements. Un <b> Test de Guérison Difficile (-20) étendu </b> nécessitant +3 DR réduit le renflement de <b> <a class ='chat-roll'> 2d10 </a> </b> heures. Chaque test dure une heure. Le patient se retrouve avec l'Etat Exténué +1 pour chaque test effectué au cours du processus. <br> <br> A la place, certains médecins saignent le patient avec une lame ou des sangsues. Un <b>Test de Guérison étendu </b> réussi nécessitant +4 SL et des Outils (médecin) réduit le renflement de (<a class ='chat-roll'> 1d10 </a> + Bonus d'Endurance du patient) heures. Chaque test a une difficulté de base <b> impossible (-50) </b> et dure une demi-heure.";
|
||||||
|
|
||||||
game.wfrp4e.config.loreEffects["tzeentch"] = {
|
game.wfrp4e.config.loreEffects["tzeentch"] = {
|
||||||
label: "Domaine de Tzeentch",
|
name: "Domaine de Tzeentch",
|
||||||
icon: "modules/wfrp4e-core/icons/spells/tzeentch.png",
|
img: "modules/wfrp4e-core/icons/spells/tzeentch.png",
|
||||||
transfer: true,
|
system: {
|
||||||
flags: {
|
transferData: {
|
||||||
wfrp4e: {
|
type: "target"
|
||||||
"effectApplication": "apply",
|
},
|
||||||
"effectTrigger": "oneTime",
|
scriptData: [{
|
||||||
"lore": true,
|
trigger: "immediate",
|
||||||
"script": `
|
label: "Test d'Endurance",
|
||||||
if (this.actor.isOwner)
|
script: `
|
||||||
args.actor.setupSkill("Résistance", {context : {failure: "1 Point de Corruption reçu", success : "1 Point de Chance gagné"}}).then(setupData => {
|
this.actor.setupSkill(game.i18n.localize("NAME.Endurance"), {appendTitle : " - " + this.effect.name, context : {failure: "1 Point de Corruption reçu", success : "1 Point de Chance gagné"}}).then(setupData => {
|
||||||
args.actor.basicTest(setupData).then(test =>
|
this.actor.basicTest(setupData).then(test => {
|
||||||
{
|
if (test.succeeded && this.actor.type == "character") {
|
||||||
if (test.result.result == "success" && args.actor.type == "character")
|
this.actor.update({"system.status.fortune.value" : this.actor.system.status.fortune.value + 1})
|
||||||
{
|
} else if (test.failed && this.actor.type == "character") {
|
||||||
args.actor.update({"system.status.fortune.value" : args.actor.system.status.fortune.value + 1})
|
this.actor.update({"system.status.corruption.value" : this.actor.system.status.corruption.value + 1})
|
||||||
}
|
}
|
||||||
else if (test.result.result == "failure" && args.actor.type == "character")
|
})
|
||||||
{
|
})
|
||||||
args.actor.update({"system.status.corruption.value" : args.actor.system.status.corruption.value + 1})
|
return false;`
|
||||||
}
|
}]
|
||||||
})
|
|
||||||
})`
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -133,10 +130,10 @@ const __auto_patch_translation_journal_compendium = async (compmod) => {
|
|||||||
if (game.user.isGM) {
|
if (game.user.isGM) {
|
||||||
let compData = game.packs.get("WH4-fr-translation.tables-des-traductions");
|
let compData = game.packs.get("WH4-fr-translation.tables-des-traductions");
|
||||||
compData.locked = false;
|
compData.locked = false;
|
||||||
let translEntries = await compData.getContent();
|
let translEntries = await compData.getDocuments();
|
||||||
for (let entryData of translEntries) {
|
for (let entryData of translEntries) {
|
||||||
let mydata = foundry.utils.duplicate(entryData.data);
|
let mydata = entryData.toObject();
|
||||||
mydata.content = mydata.content.replace(/wfrp4e-content/g, compmod);
|
mydata.text.content = mydata.text.content.replace(/wfrp4e-content/g, compmod);
|
||||||
entryData.update(mydata);
|
entryData.update(mydata);
|
||||||
}
|
}
|
||||||
compData.locked = true;
|
compData.locked = true;
|
||||||
@@ -175,9 +172,55 @@ const patch_core_tables = (tableList) => {
|
|||||||
|
|
||||||
/************************************************************************************/
|
/************************************************************************************/
|
||||||
const patch_trade_gazeteer = () => {
|
const patch_trade_gazeteer = () => {
|
||||||
if (game.wfrp4e.config.trade?.gazetteer) {
|
// Translate river cargoTypes to French (DotR module registers English values)
|
||||||
|
if (game.wfrp4e.trade?.tradeData?.river?.cargoTypes) {
|
||||||
|
Object.assign(game.wfrp4e.trade.tradeData.river.cargoTypes, {
|
||||||
|
"grain": game.i18n.localize("TRADE.Grain"),
|
||||||
|
"armaments": game.i18n.localize("TRADE.Armaments"),
|
||||||
|
"luxuries": game.i18n.localize("TRADE.Luxuries"),
|
||||||
|
"metal": game.i18n.localize("TRADE.Metal"),
|
||||||
|
"timber": game.i18n.localize("TRADE.Timber"),
|
||||||
|
"wine": game.i18n.localize("TRADE.Wine"),
|
||||||
|
"brandy": game.i18n.localize("TRADE.Brandy"),
|
||||||
|
"wool": game.i18n.localize("TRADE.Wool"),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// Translate maritime cargoTypes to French (SOC module)
|
||||||
|
if (game.wfrp4e.trade?.tradeData?.maritime?.cargoTypes) {
|
||||||
|
const maritimeKeys = {
|
||||||
|
"citrusfruit": "TRADE.Citrusfruit",
|
||||||
|
"olives": "TRADE.Olives",
|
||||||
|
"saltfish": "TRADE.Saltfish",
|
||||||
|
"stone": "TRADE.Stone",
|
||||||
|
};
|
||||||
|
for (let [key, locKey] of Object.entries(maritimeKeys)) {
|
||||||
|
if (game.wfrp4e.trade.tradeData.maritime.cargoTypes[key]) {
|
||||||
|
game.wfrp4e.trade.tradeData.maritime.cargoTypes[key] = game.i18n.localize(locKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Translate shared keys that may also appear in maritime
|
||||||
|
Object.assign(game.wfrp4e.trade.tradeData.maritime.cargoTypes,
|
||||||
|
Object.fromEntries(
|
||||||
|
Object.entries(game.wfrp4e.trade.tradeData.maritime.cargoTypes)
|
||||||
|
.filter(([k]) => game.wfrp4e.trade.tradeData.river?.cargoTypes?.[k])
|
||||||
|
.map(([k]) => [k, game.wfrp4e.trade.tradeData.river.cargoTypes[k]])
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
// Translate season names shown in the trade dialog
|
||||||
|
if (game.wfrp4e.trade?.seasons) {
|
||||||
|
Object.assign(game.wfrp4e.trade.seasons, {
|
||||||
|
"spring": game.i18n.localize("TRADE.Spring"),
|
||||||
|
"summer": game.i18n.localize("TRADE.Summer"),
|
||||||
|
"autumn": game.i18n.localize("TRADE.Autumn"),
|
||||||
|
"winter": game.i18n.localize("TRADE.Winter"),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// Replace the English DotR gazetteer with the French-translated one
|
||||||
|
// New API: game.wfrp4e.trade.gazetteers.river (replaces old game.wfrp4e.config.trade.gazetteer)
|
||||||
|
if (game.wfrp4e.trade?.gazetteers?.river?.length) {
|
||||||
fetch("modules/wh4-fr-translation/trade/gazetteer_dotr.json").then(r => r.json()).then(records => {
|
fetch("modules/wh4-fr-translation/trade/gazetteer_dotr.json").then(r => r.json()).then(records => {
|
||||||
game.wfrp4e.config.trade.gazetteer = records;
|
game.wfrp4e.trade.gazetteers.river = records;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -231,7 +274,7 @@ const __check_fix_wrong_modules = (chatFlag, patchFinished) => {
|
|||||||
}
|
}
|
||||||
} else if (game.user.isGM && patchFinished) {
|
} else if (game.user.isGM && patchFinished) {
|
||||||
ChatMessage.create({
|
ChatMessage.create({
|
||||||
content: "<div>Les modules WFRP4E ont été <strong>patchés avec succés</strong>. Vous pouvez y aller et que <strong>Shallya vous garde !</strong><div><div>Changements v9.3.4 : <ul><li>Ajout de la commande /voyage !</li><li>Améliorations de la commande /auberge</li><li>Très grosses mise à jour des scripts d'Effets et de leur traduction</li></ul></div>",
|
content: "<div>Les modules WFRP4E ont été <strong>patchés avec succés</strong>. Vous pouvez y aller et que <strong>Shallya vous garde !</strong><div><div>Changements v9.3.5 : <ul><li>Ajout de la commande /voyage !</li><li>Améliorations de la commande /auberge</li><li>Les joueurs doivent désormais pouvoir créer leur persos</li><li>Très grosses mise à jour des scripts d'Effets et de leur traduction</li></ul></div>",
|
||||||
user: game.user.id,
|
user: game.user.id,
|
||||||
whisper: ChatMessage.getWhisperRecipients("GM")
|
whisper: ChatMessage.getWhisperRecipients("GM")
|
||||||
});
|
});
|
||||||
@@ -358,6 +401,56 @@ Hooks.on('ready', () => {
|
|||||||
// Patch function for effects
|
// Patch function for effects
|
||||||
game.wfrp4e.utility.findKey = warhammer.utility.findKey
|
game.wfrp4e.utility.findKey = warhammer.utility.findKey
|
||||||
|
|
||||||
|
// Patch SpellModel.computeSpellDamage to handle English characteristic bonus names.
|
||||||
|
// Babele instantiates actors TWICE: first with untranslated data (English formulas like
|
||||||
|
// "Willpower Bonus+4"), then with translated data. The first pass fails because
|
||||||
|
// characteristicsBonus values are already French ("Bonus de Force Mentale").
|
||||||
|
// This patch pre-replaces English bonus names with numeric values before the original
|
||||||
|
// formula evaluation runs, preventing SyntaxErrors and notification spam.
|
||||||
|
const __EN_BONUS_TO_CHAR = {
|
||||||
|
"weapon skill bonus": "ws", "ballistic skill bonus": "bs",
|
||||||
|
"strength bonus": "s", "toughness bonus": "t",
|
||||||
|
"initiative bonus": "i", "agility bonus": "ag",
|
||||||
|
"dexterity bonus": "dex", "intelligence bonus": "int",
|
||||||
|
"willpower bonus": "wp", "fellowship bonus": "fel"
|
||||||
|
};
|
||||||
|
const SpellModel = CONFIG.Item.dataModels?.["spell"];
|
||||||
|
if (SpellModel?.prototype?.computeSpellDamage) {
|
||||||
|
const _origComputeSpellDamage = SpellModel.prototype.computeSpellDamage;
|
||||||
|
SpellModel.prototype.computeSpellDamage = function(formula, options) {
|
||||||
|
if (typeof formula === "string") {
|
||||||
|
const actor = options?.actor || this.parent?.actor;
|
||||||
|
if (actor?.system?.characteristics) {
|
||||||
|
let f = formula.toLowerCase();
|
||||||
|
for (const [enName, ch] of Object.entries(__EN_BONUS_TO_CHAR)) {
|
||||||
|
if (f.includes(enName)) {
|
||||||
|
const bonus = actor.system.characteristics[ch]?.bonus ?? 0;
|
||||||
|
f = f.replace(enName, bonus);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
formula = f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return _origComputeSpellDamage.call(this, formula, options);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Patch postSymptom to handle English symptom names in @Symptom[...] links.
|
||||||
|
// After i18nInit, config.symptoms values are French strings (e.g. "Fièvre"), so
|
||||||
|
// findKey("Fever", config.symptoms) fails. We normalize via game.i18n.localize first.
|
||||||
|
const _origPostSymptom = game.wfrp4e.utility.postSymptom.bind(game.wfrp4e.utility);
|
||||||
|
game.wfrp4e.utility.postSymptom = async function(symptom) {
|
||||||
|
const baseName = symptom.split("(")[0].trim();
|
||||||
|
const symkey = warhammer.utility.findKey(baseName, game.wfrp4e.config.symptoms);
|
||||||
|
if (!symkey) {
|
||||||
|
const localizedBase = game.i18n.localize(baseName);
|
||||||
|
if (localizedBase !== baseName) {
|
||||||
|
symptom = symptom.replace(baseName, localizedBase);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return _origPostSymptom(symptom);
|
||||||
|
};
|
||||||
|
|
||||||
/** New modifiers */
|
/** New modifiers */
|
||||||
game.wfrp4e.config.difficultyModifiers = {
|
game.wfrp4e.config.difficultyModifiers = {
|
||||||
"veasy": 60,
|
"veasy": 60,
|
||||||
@@ -385,7 +478,9 @@ Hooks.on('ready', () => {
|
|||||||
"doom": "Maudit (-40)"
|
"doom": "Maudit (-40)"
|
||||||
}
|
}
|
||||||
|
|
||||||
game.wfrp4e.warnDialog.render(true, { focus: true, left: 20, top: 20 });
|
if (game.user.isGM) {
|
||||||
|
game.wfrp4e.warnDialog.render(true, { focus: true, left: 20, top: 20 });
|
||||||
|
}
|
||||||
//setTimeout( __check_fix_wrong_modules, 2000, true, false);
|
//setTimeout( __check_fix_wrong_modules, 2000, true, false);
|
||||||
setTimeout(__check_fix_wrong_modules, 20000, true, true);
|
setTimeout(__check_fix_wrong_modules, 20000, true, true);
|
||||||
setTimeout(__add_actors_translation, 21000, false, true);
|
setTimeout(__add_actors_translation, 21000, false, true);
|
||||||
|
|||||||
@@ -30,6 +30,20 @@ const __SELECT_BONUS_PREFIX_D = {
|
|||||||
"agilité": 1
|
"agilité": 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Map English characteristic names (as they appear in spell formulas) to WFRP4e abbreviations
|
||||||
|
const __CHAR_EN_TO_ABBR = {
|
||||||
|
"weapon skill": "ws",
|
||||||
|
"ballistic skill": "bs",
|
||||||
|
"strength": "s",
|
||||||
|
"toughness": "t",
|
||||||
|
"initiative": "i",
|
||||||
|
"agility": "ag",
|
||||||
|
"dexterity": "dex",
|
||||||
|
"intelligence": "int",
|
||||||
|
"willpower": "wp",
|
||||||
|
"fellowship": "fel"
|
||||||
|
}
|
||||||
|
|
||||||
/************************************************************************************/
|
/************************************************************************************/
|
||||||
export class WFRP4FrTranslation {
|
export class WFRP4FrTranslation {
|
||||||
|
|
||||||
@@ -57,16 +71,23 @@ export class WFRP4FrTranslation {
|
|||||||
if (value == "You") return "Vous"; // Hop !
|
if (value == "You") return "Vous"; // Hop !
|
||||||
if (value == "Instant") return "Instantané"; // Hop !
|
if (value == "Instant") return "Instantané"; // Hop !
|
||||||
let translw = value;
|
let translw = value;
|
||||||
let re = /(.*)\s+[Bb]onus\s*(\w*)/i;
|
let re = /(.*)\s+[Bb]onus\s*(.*)/i; // (.*) at end captures modifiers like "+4"
|
||||||
let res = re.exec(value);
|
let res = re.exec(value);
|
||||||
let unit = "";
|
let unit = "";
|
||||||
if (res) { // Test "<charac> Bonus <unit>" pattern
|
if (res) { // Test "<charac> Bonus <modifier>" pattern
|
||||||
if (res[1]) { // We have char name, then convert it
|
if (res[1]) { // We have char name, then convert it
|
||||||
translw = game.i18n.localize(res[1].trim());
|
const charEN = res[1].trim().toLowerCase();
|
||||||
let bonusPrefix = (translw.toLowerCase() in __SELECT_BONUS_PREFIX_D) ? "Bonus d'" : "Bonus de ";
|
const abbr = __CHAR_EN_TO_ABBR[charEN];
|
||||||
translw = bonusPrefix + translw
|
if (abbr && game.wfrp4e?.config?.characteristicsBonus?.[abbr]) {
|
||||||
|
// Use the localized French bonus name from config (already resolved by localizeConfig at i18nInit)
|
||||||
|
translw = game.wfrp4e.config.characteristicsBonus[abbr];
|
||||||
|
} else {
|
||||||
|
translw = game.i18n.localize(res[1].trim());
|
||||||
|
let bonusPrefix = (translw.toLowerCase() in __SELECT_BONUS_PREFIX_D) ? "Bonus d'" : "Bonus de ";
|
||||||
|
translw = bonusPrefix + translw;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
unit = res[2];
|
unit = res[2]; // may be "+4", "-2", "2", "yards", etc.
|
||||||
} else {
|
} else {
|
||||||
re = /(\d+) (\w+)/i;
|
re = /(\d+) (\w+)/i;
|
||||||
res = re.exec(value);
|
res = re.exec(value);
|
||||||
@@ -90,6 +111,8 @@ export class WFRP4FrTranslation {
|
|||||||
if (unit == "Bonus") { // Another weird management
|
if (unit == "Bonus") { // Another weird management
|
||||||
console.log("Translating bonus", unit);
|
console.log("Translating bonus", unit);
|
||||||
translw = "Bonus de " + translw;
|
translw = "Bonus de " + translw;
|
||||||
|
} else if (unit && /^[+\-*\/]/.test(unit)) {
|
||||||
|
translw += unit; // No space before operators like "+4"
|
||||||
} else {
|
} else {
|
||||||
translw += " " + unit;
|
translw += " " + unit;
|
||||||
}
|
}
|
||||||
@@ -248,16 +271,16 @@ Hooks.once('init', () => {
|
|||||||
let translw = translItem?.name || undefined
|
let translw = translItem?.name || undefined
|
||||||
if (translw && translw != s1) {
|
if (translw && translw != s1) {
|
||||||
let res2 = re.exec(translw);
|
let res2 = re.exec(translw);
|
||||||
transl = res2[1] + "(" + subword + ")";
|
transl = res2[1].trim() + " (" + subword + ")";
|
||||||
} else {
|
} else {
|
||||||
s1 = res[1].trim() + " ( )";
|
s1 = res[1].trim() + " ( )";
|
||||||
translItem = game.babele.translate(compData.metadata.id, { name: s1, type: "skill" }, true)
|
translItem = game.babele.translate(compData.metadata.id, { name: s1, type: "skill" }, true)
|
||||||
translw = translItem?.name || undefined
|
translw = translItem?.name || undefined
|
||||||
if(translw) {
|
if(translw) {
|
||||||
let res2 = re.exec(translw);
|
let res2 = re.exec(translw);
|
||||||
transl = res2[1] + "(" + subword + ")";
|
transl = res2[1].trim() + " (" + subword + ")";
|
||||||
} else {
|
} else {
|
||||||
transl = res[1] + " (" + subword + ")";
|
transl = res[1].trim() + " (" + subword + ")";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -278,8 +301,25 @@ Hooks.once('init', () => {
|
|||||||
"process_effects": (effectsData, translations, data, tc, tc_translations) => {
|
"process_effects": (effectsData, translations, data, tc, tc_translations) => {
|
||||||
//console.log("Effects :", effectsData, translations, data, tc, tc_translations)
|
//console.log("Effects :", effectsData, translations, data, tc, tc_translations)
|
||||||
for (let e of effectsData) {
|
for (let e of effectsData) {
|
||||||
|
// Foundry v13 requires name; migrate legacy data where only label was stored
|
||||||
|
if (e.name == null) e.name = e.label || "";
|
||||||
let origName = e.name
|
let origName = e.name
|
||||||
e.name = tc_translations.name || game.i18n.localize(e.name)
|
// Symptom effects have their own name (Fever, Malaise, etc.) — don't overwrite with the parent item name
|
||||||
|
if (e.flags?.wfrp4e?.symptom) {
|
||||||
|
let symName = e.name;
|
||||||
|
let gravity = "";
|
||||||
|
if (symName.includes("(") && symName.includes(")")) {
|
||||||
|
let re = /(.*) +\((.*)\)/i;
|
||||||
|
let res = re.exec(symName);
|
||||||
|
if (res) {
|
||||||
|
symName = res[1].trim();
|
||||||
|
gravity = " (" + game.i18n.localize(res[2].trim()) + ")";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
e.name = game.i18n.localize(symName) + gravity;
|
||||||
|
} else {
|
||||||
|
e.name = tc_translations.name || game.i18n.localize(e.name) || e.label || ""
|
||||||
|
}
|
||||||
if ( e.flags?.wfrp4e?.scriptData) {
|
if ( e.flags?.wfrp4e?.scriptData) {
|
||||||
for (let script of e.flags.wfrp4e.scriptData) {
|
for (let script of e.flags.wfrp4e.scriptData) {
|
||||||
if (script?.label) {
|
if (script?.label) {
|
||||||
@@ -366,7 +406,7 @@ Hooks.once('init', () => {
|
|||||||
translItem = game.babele.translate(compData.metadata.id, { name: s1 }, true)
|
translItem = game.babele.translate(compData.metadata.id, { name: s1 }, true)
|
||||||
let translw = translItem?.name || undefined
|
let translw = translItem?.name || undefined
|
||||||
if (translw && translw != s1) {
|
if (translw && translw != s1) {
|
||||||
transl = translw + " (" + subword + ")";
|
transl = translw.trim() + " (" + subword + ")";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -396,10 +436,18 @@ Hooks.once('init', () => {
|
|||||||
return beast_traits
|
return beast_traits
|
||||||
}
|
}
|
||||||
//console.log("TRANS:", beast_traits)
|
//console.log("TRANS:", beast_traits)
|
||||||
|
// Normalize: Foundry v13 requires ActiveEffect.name; migrate legacy v12 data
|
||||||
|
for (let trait_en of beast_traits) {
|
||||||
|
if (trait_en.effects) {
|
||||||
|
for (let eff of trait_en.effects) {
|
||||||
|
if (eff.name == null) eff.name = eff.label || "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
for (let trait_en of beast_traits) {
|
for (let trait_en of beast_traits) {
|
||||||
let special = "";
|
let special = "";
|
||||||
let nbt = "";
|
let nbt = "";
|
||||||
let name_en = trait_en.name.trim(); // strip \r in some traits name
|
let name_en = trait_en.name.replace(/\r/g, '').trim(); // strip \r (including internal) in some traits name
|
||||||
if (!trait_en.name || trait_en.name.length == 0) {
|
if (!trait_en.name || trait_en.name.length == 0) {
|
||||||
console.log("Wrong item name found!!!!")
|
console.log("Wrong item name found!!!!")
|
||||||
continue
|
continue
|
||||||
@@ -415,8 +463,11 @@ Hooks.once('init', () => {
|
|||||||
} else if (name_en.includes("(") && name_en.includes(")")) { // Then process specific traits name with (xxxx) inside
|
} else if (name_en.includes("(") && name_en.includes(")")) { // Then process specific traits name with (xxxx) inside
|
||||||
let re = /(.*) \((.*)\)/i;
|
let re = /(.*) \((.*)\)/i;
|
||||||
let res = re.exec(name_en);
|
let res = re.exec(name_en);
|
||||||
name_en = res[1]; // Get the root traits name
|
if (!res) { console.warn("WFRP4E-FR | bestiary_traits: regex failed for trait:", name_en); }
|
||||||
special = " (" + game.i18n.localize(res[2].trim()) + ")"; // And the special keyword
|
else {
|
||||||
|
name_en = res[1]; // Get the root traits name
|
||||||
|
special = " (" + game.i18n.localize(res[2].trim()) + ")"; // And the special keyword
|
||||||
|
}
|
||||||
}
|
}
|
||||||
let validCompendiums = game.wfrp4e.tags.getPacksWithTag("trait")
|
let validCompendiums = game.wfrp4e.tags.getPacksWithTag("trait")
|
||||||
for (let compData of validCompendiums) {
|
for (let compData of validCompendiums) {
|
||||||
@@ -424,8 +475,10 @@ Hooks.once('init', () => {
|
|||||||
if (trait_fr?.name && trait_fr?.name != name_en) {
|
if (trait_fr?.name && trait_fr?.name != name_en) {
|
||||||
trait_fr.name = trait_fr.name || trait_en.name
|
trait_fr.name = trait_fr.name || trait_en.name
|
||||||
trait_en.name = nbt + trait_fr.name + special;
|
trait_en.name = nbt + trait_fr.name + special;
|
||||||
trait_en.system.description.value = trait_fr.system.description.value;
|
if ( trait_en.system?.description?.value && trait_fr.system?.description?.value) {
|
||||||
if (trait_en.system?.specification && isNaN(trait_en.system.specification.value)) { // This is a string, so translate it
|
trait_en.system.description.value = trait_fr.system.description.value;
|
||||||
|
}
|
||||||
|
if (trait_en?.system?.specification && isNaN(trait_en.system.specification?.value)) { // This is a string, so translate it
|
||||||
//console.log("Translating : ", trait_en.system.specification.value);
|
//console.log("Translating : ", trait_en.system.specification.value);
|
||||||
trait_en.system.specification.value = game.i18n.localize(trait_en.system.specification.value.trim());
|
trait_en.system.specification.value = game.i18n.localize(trait_en.system.specification.value.trim());
|
||||||
}
|
}
|
||||||
@@ -436,8 +489,11 @@ Hooks.once('init', () => {
|
|||||||
if (name_en.includes("(") && name_en.includes(")")) { // Then process specific skills name with (xxxx) inside
|
if (name_en.includes("(") && name_en.includes(")")) { // Then process specific skills name with (xxxx) inside
|
||||||
let re = /(.*) +\((.*)\)/i;
|
let re = /(.*) +\((.*)\)/i;
|
||||||
let res = re.exec(name_en);
|
let res = re.exec(name_en);
|
||||||
name_en = res[1].trim(); // Get the root skill name
|
if (!res) { console.warn("WFRP4E-FR | bestiary_traits: regex failed for skill:", name_en); }
|
||||||
special = " (" + game.i18n.localize(res[2].trim()) + ")"; // And the special keyword
|
else {
|
||||||
|
name_en = res[1].trim(); // Get the root skill name
|
||||||
|
special = " (" + game.i18n.localize(res[2].trim()) + ")"; // And the special keyword
|
||||||
|
}
|
||||||
}
|
}
|
||||||
let validCompendiums = game.wfrp4e.tags.getPacksWithTag("skill")
|
let validCompendiums = game.wfrp4e.tags.getPacksWithTag("skill")
|
||||||
for (let compData of validCompendiums) {
|
for (let compData of validCompendiums) {
|
||||||
@@ -482,8 +538,11 @@ Hooks.once('init', () => {
|
|||||||
if (name_en.includes("(") && name_en.includes(")")) { // Then process specific skills name with (xxxx) inside
|
if (name_en.includes("(") && name_en.includes(")")) { // Then process specific skills name with (xxxx) inside
|
||||||
let re = /(.*) +\((.*)\)/i;
|
let re = /(.*) +\((.*)\)/i;
|
||||||
let res = re.exec(name_en);
|
let res = re.exec(name_en);
|
||||||
name_en = res[1].trim(); // Get the root talent name, no parenthesis this time...
|
if (!res) { console.warn("WFRP4E-FR | bestiary_traits: regex failed for talent:", name_en); }
|
||||||
special = " (" + game.i18n.localize(res[2].trim()) + ")"; // And the special keyword
|
else {
|
||||||
|
name_en = res[1].trim(); // Get the root talent name, no parenthesis this time...
|
||||||
|
special = " (" + game.i18n.localize(res[2].trim()) + ")"; // And the special keyword
|
||||||
|
}
|
||||||
}
|
}
|
||||||
let validCompendiums = game.wfrp4e.tags.getPacksWithTag("talent")
|
let validCompendiums = game.wfrp4e.tags.getPacksWithTag("talent")
|
||||||
for (let compData of validCompendiums) {
|
for (let compData of validCompendiums) {
|
||||||
@@ -648,15 +707,15 @@ Hooks.once('init', () => {
|
|||||||
if (!effects) return;
|
if (!effects) return;
|
||||||
for (const element of effects) {
|
for (const element of effects) {
|
||||||
let effect = element;
|
let effect = element;
|
||||||
let label = effect.label;
|
let name = effect.name || effect.label;
|
||||||
let gravity = "";
|
let gravity = "";
|
||||||
if (label.includes("(") && label.includes(")")) { // Then process specific skills name with (xxxx) inside
|
if (name.includes("(") && name.includes(")")) {
|
||||||
let re = /(.*) +\((.*)\)/i;
|
let re = /(.*) +\((.*)\)/i;
|
||||||
let res = re.exec(label);
|
let res = re.exec(name);
|
||||||
label = res[1].trim(); // Get the gravity
|
name = res[1].trim();
|
||||||
gravity = " (" + game.i18n.localize(res[2].trim()) + ")"; // And the special keyword
|
gravity = " (" + game.i18n.localize(res[2].trim()) + ")";
|
||||||
}
|
}
|
||||||
effect.label = game.i18n.localize(label) + gravity;
|
effect.name = game.i18n.localize(name) + gravity;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// Auto-translate duration
|
// Auto-translate duration
|
||||||
|
|||||||
@@ -145,6 +145,39 @@ export class WH4FRPatchConfig {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/************************************************************************************/
|
||||||
|
static patch_symptom_severity() {
|
||||||
|
// The core module's symptomEffects scripts check for English severity terms
|
||||||
|
// ("Moderate", "Severe") in this.effect.name. French disease compendiums use
|
||||||
|
// translated severity ("Modéré(e)", "Grave"), so the checks would fail.
|
||||||
|
// We patch the relevant scriptData to also check for French severity terms.
|
||||||
|
const effects = game.wfrp4e.config.symptomEffects;
|
||||||
|
if (!effects) return;
|
||||||
|
|
||||||
|
// Patch blight: checks Moderate → easy, Severe → average, else → veasy
|
||||||
|
for (const key of ["blight", "gangrene"]) {
|
||||||
|
const effect = effects[key];
|
||||||
|
if (!effect?.system?.scriptData) continue;
|
||||||
|
for (const sd of effect.system.scriptData) {
|
||||||
|
if (sd.script && sd.script.includes('.includes("Moderate")')) {
|
||||||
|
sd.script = sd.script
|
||||||
|
.replace('includes("Moderate")', 'includes("Moderate") || this.effect.name.includes("Modéré")')
|
||||||
|
.replace('includes("Severe")', 'includes("Severe") || this.effect.name.includes("Grave")');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Patch convulsions: checks Moderate → -20, else → -10
|
||||||
|
if (effects.convulsions?.system?.scriptData) {
|
||||||
|
for (const sd of effects.convulsions.system.scriptData) {
|
||||||
|
if (sd.script && sd.script.includes('.includes("Moderate")')) {
|
||||||
|
sd.script = sd.script
|
||||||
|
.replace('includes("Moderate")', 'includes("Moderate") || this.effect.name.includes("Modéré")');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/************************************************************************************/
|
/************************************************************************************/
|
||||||
static fixSpeciesTable() {
|
static fixSpeciesTable() {
|
||||||
|
|
||||||
@@ -192,16 +225,15 @@ export class WH4FRPatchConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (game.wfrp4e.config.loreEffects) {
|
if (game.wfrp4e.config.loreEffects) {
|
||||||
game.wfrp4e.config.loreEffects["beasts"].label = "Domaine des Bêtes"
|
game.wfrp4e.config.loreEffects["beasts"].name = "Domaine des Bêtes"
|
||||||
game.wfrp4e.config.loreEffects["death"].label = "Domaine de la Mort"
|
game.wfrp4e.config.loreEffects["death"].name = "Domaine de la Mort"
|
||||||
game.wfrp4e.config.loreEffects["fire"].label = "Domaine du Feu"
|
game.wfrp4e.config.loreEffects["fire"].name = "Domaine du Feu"
|
||||||
game.wfrp4e.config.loreEffects["metal"].label = "Domaine du Métal"
|
game.wfrp4e.config.loreEffects["metal"].name = "Domaine du Métal"
|
||||||
game.wfrp4e.config.loreEffects["heavens"].label = "Domaine des Cieux"
|
game.wfrp4e.config.loreEffects["heavens"].name = "Domaine des Cieux"
|
||||||
game.wfrp4e.config.loreEffects["life"].label = "Domaine de la Vie"
|
game.wfrp4e.config.loreEffects["life"].name = "Domaine de la Vie"
|
||||||
game.wfrp4e.config.loreEffects["light"].label = "Domaine de la Lumière"
|
game.wfrp4e.config.loreEffects["light"].name = "Domaine de la Lumière"
|
||||||
game.wfrp4e.config.loreEffects["shadow"].label = "Domaine des Ombres"
|
game.wfrp4e.config.loreEffects["shadow"].name = "Domaine des Ombres"
|
||||||
game.wfrp4e.config.loreEffects["hedgecraft"].label = "Domaine de la Magie de Village"
|
game.wfrp4e.config.loreEffects["hedgecraft"].name = "Domaine de la Sorcellerie"
|
||||||
game.wfrp4e.config.loreEffects["hedgecraft"].label = "Domaine de la Sorcellerie"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (game.wfrp4e.config.species) {
|
if (game.wfrp4e.config.species) {
|
||||||
@@ -240,276 +272,10 @@ export class WH4FRPatchConfig {
|
|||||||
this.patch_career();
|
this.patch_career();
|
||||||
|
|
||||||
|
|
||||||
game.wfrp4e.config.symptomEffects = {
|
// Patch symptom severity scripts to support French severity terms
|
||||||
"blight": {
|
// The core module scripts check for "Moderate"/"Severe" in effect.name,
|
||||||
label: "Toxine",
|
// but French disease compendiums use "Modéré(e)"/"Grave" instead.
|
||||||
icon: "modules/wfrp4e-core/icons/diseases/disease.png",
|
this.patch_symptom_severity();
|
||||||
transfer: true,
|
|
||||||
flags: {
|
|
||||||
wfrp4e: {
|
|
||||||
"effectApplication": "actor",
|
|
||||||
"effectTrigger": "invoke",
|
|
||||||
"symptom": true,
|
|
||||||
"script": `
|
|
||||||
let difficulty = ""
|
|
||||||
if (this.effect.label.includes("Modéré"))
|
|
||||||
difficulty = "easy"
|
|
||||||
else if (this.effect.label.includes("Sévère"))
|
|
||||||
difficulty = "average"
|
|
||||||
else
|
|
||||||
difficulty = "veasy"
|
|
||||||
|
|
||||||
if (args.actor.isOwner)
|
|
||||||
{
|
|
||||||
args.actor.setupSkill("Résistance", {absolute: {difficulty}}).then(setupData => {
|
|
||||||
args.actor.basicTest(setupData).then(test =>
|
|
||||||
{
|
|
||||||
if (test.result.outcome == "failure")
|
|
||||||
args.actor.addCondition("dead")
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}`
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"buboes": {
|
|
||||||
label: "Bubons",
|
|
||||||
icon: "modules/wfrp4e-core/icons/diseases/disease.png",
|
|
||||||
transfer: true,
|
|
||||||
flags: {
|
|
||||||
wfrp4e: {
|
|
||||||
"effectApplication": "actor",
|
|
||||||
"effectTrigger": "prefillDialog",
|
|
||||||
"symptom": true,
|
|
||||||
"script": `
|
|
||||||
let applicableCharacteristics = ["ws", "bs", "s", "fel", "ag", "t", "dex"]
|
|
||||||
if (args.type == "weapon")
|
|
||||||
args.prefillModifiers.modifier -= 10
|
|
||||||
else if (args.type == "characteristic")
|
|
||||||
{
|
|
||||||
if (applicableCharacteristics.includes(args.item))
|
|
||||||
args.prefillModifiers.modifier -= 10
|
|
||||||
}
|
|
||||||
else if (args.type == "skill")
|
|
||||||
{
|
|
||||||
if (applicableCharacteristics.includes(args.item.characteristic.value))
|
|
||||||
args.prefillModifiers.modifier -= 10
|
|
||||||
}
|
|
||||||
`}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"convulsions": {
|
|
||||||
label: "Convulsions",
|
|
||||||
icon: "modules/wfrp4e-core/icons/diseases/disease.png",
|
|
||||||
transfer: true,
|
|
||||||
flags: {
|
|
||||||
wfrp4e: {
|
|
||||||
"effectApplication": "actor",
|
|
||||||
"effectTrigger": "prefillDialog",
|
|
||||||
"symptom": true,
|
|
||||||
"script": `
|
|
||||||
let modifier = 0
|
|
||||||
if (this.effect.label.includes("Modéré"))
|
|
||||||
modifier = -20
|
|
||||||
else
|
|
||||||
modifier = -10
|
|
||||||
|
|
||||||
let applicableCharacteristics = ["ws", "bs", "s", "ag", "t", "dex"]
|
|
||||||
if (args.type == "weapon")
|
|
||||||
args.prefillModifiers.modifier += modifier
|
|
||||||
else if (args.type == "characteristic")
|
|
||||||
{
|
|
||||||
if (applicableCharacteristics.includes(args.item))
|
|
||||||
args.prefillModifiers.modifier += modifier
|
|
||||||
}
|
|
||||||
else if (args.type == "skill")
|
|
||||||
{
|
|
||||||
if (applicableCharacteristics.includes(args.item.characteristic.value))
|
|
||||||
args.prefillModifiers.modifier += modifier
|
|
||||||
}
|
|
||||||
}`
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"fever": {
|
|
||||||
label: "Fièvre",
|
|
||||||
icon: "modules/wfrp4e-core/icons/diseases/disease.png",
|
|
||||||
transfer: true,
|
|
||||||
flags: {
|
|
||||||
wfrp4e: {
|
|
||||||
"effectApplication": "actor",
|
|
||||||
"effectTrigger": "prefillDialog",
|
|
||||||
"symptom": true,
|
|
||||||
"script": `
|
|
||||||
|
|
||||||
let applicableCharacteristics = ["ws", "bs", "s", "fel", "ag", "t", "dex"]
|
|
||||||
|
|
||||||
if (args.type == "weapon")
|
|
||||||
args.prefillModifiers.modifier -= 10
|
|
||||||
else if (args.type == "characteristic")
|
|
||||||
{
|
|
||||||
if (applicableCharacteristics.includes(args.item))
|
|
||||||
args.prefillModifiers.modifier -= 10
|
|
||||||
}
|
|
||||||
else if (args.type == "skill")
|
|
||||||
{
|
|
||||||
if (applicableCharacteristics.includes(args.item.characteristic.value))
|
|
||||||
args.prefillModifiers.modifier -= 10
|
|
||||||
}`,
|
|
||||||
"otherEffects": ["blight", "wounded"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"flux": {
|
|
||||||
label: "Intoxication Alimentaire",
|
|
||||||
icon: "modules/wfrp4e-core/icons/diseases/disease.png",
|
|
||||||
transfer: true,
|
|
||||||
flags: {
|
|
||||||
wfrp4e: {
|
|
||||||
"symptom": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"lingering": {
|
|
||||||
label: "Persistant",
|
|
||||||
icon: "modules/wfrp4e-core/icons/diseases/disease.png",
|
|
||||||
transfer: true,
|
|
||||||
flags: {
|
|
||||||
wfrp4e: {
|
|
||||||
"symptom": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"coughsAndSneezes": {
|
|
||||||
label: "Toux et éternuements",
|
|
||||||
icon: "modules/wfrp4e-core/icons/diseases/disease.png",
|
|
||||||
transfer: true,
|
|
||||||
flags: {
|
|
||||||
wfrp4e: {
|
|
||||||
"symptom": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"gangrene": {
|
|
||||||
label: "Gangrène",
|
|
||||||
icon: "modules/wfrp4e-core/icons/diseases/disease.png",
|
|
||||||
transfer: true,
|
|
||||||
flags: {
|
|
||||||
wfrp4e: {
|
|
||||||
"effectApplication": "actor",
|
|
||||||
"effectTrigger": "prefillDialog",
|
|
||||||
"symptom": true,
|
|
||||||
"script": `
|
|
||||||
if (args.type == "characteristic" && args.item == "fel")
|
|
||||||
{
|
|
||||||
if (args.item == "fel")
|
|
||||||
args.prefillModifiers.modifier -= 10
|
|
||||||
}
|
|
||||||
else if (args.type == "skill")
|
|
||||||
{
|
|
||||||
if (args.item.characteristic.value == "fel")
|
|
||||||
args.prefillModifiers.modifier -= 10
|
|
||||||
}
|
|
||||||
}`
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"malaise": {
|
|
||||||
label: "Malaise",
|
|
||||||
icon: "modules/wfrp4e-core/icons/diseases/disease.png",
|
|
||||||
transfer: true,
|
|
||||||
flags: {
|
|
||||||
wfrp4e: {
|
|
||||||
"effectApplication": "actor",
|
|
||||||
"effectTrigger": "prepareData",
|
|
||||||
"symptom": true,
|
|
||||||
"script": `
|
|
||||||
if (game.user.isUniqueGM)
|
|
||||||
{
|
|
||||||
let fatigued = args.actor.hasCondition("fatigued")
|
|
||||||
if (!fatigued)
|
|
||||||
{
|
|
||||||
args.actor.addCondition("fatigued")
|
|
||||||
ui.notifications.notify("Etat Extenué ajouté à " + args.actor.name + ", qui ne peut pas être enlevé tant que le symptôme Malaise est présent.")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"nausea": {
|
|
||||||
label: "Nausée",
|
|
||||||
icon: "modules/wfrp4e-core/icons/diseases/disease.png",
|
|
||||||
transfer: true,
|
|
||||||
flags: {
|
|
||||||
wfrp4e: {
|
|
||||||
"effectApplication": "actor",
|
|
||||||
"effectTrigger": "rollTest",
|
|
||||||
"symptom": true,
|
|
||||||
"script": `
|
|
||||||
if (this.actor.isOwner && args.test.result.outcome == "failure")
|
|
||||||
{
|
|
||||||
let applicableCharacteristics = ["ws", "bs", "s", "fel", "ag", "t", "dex"]
|
|
||||||
if (applicableCharacteristics.includes(args.test.result.characteristic))
|
|
||||||
this.actor.addCondition("stunned")
|
|
||||||
else if (args.test.result.skill && applicableCharacteristics.includes(args.test.result.skill.system.characteristic.value))
|
|
||||||
this.actor.addCondition("stunned")
|
|
||||||
else if (args.test.result.weapon)
|
|
||||||
this.actor.addCondition("stunned")
|
|
||||||
|
|
||||||
}
|
|
||||||
`
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"pox": {
|
|
||||||
label: "Démangeaisons",
|
|
||||||
icon: "modules/wfrp4e-core/icons/diseases/disease.png",
|
|
||||||
transfer: true,
|
|
||||||
flags: {
|
|
||||||
wfrp4e: {
|
|
||||||
"effectApplication": "actor",
|
|
||||||
"effectTrigger": "prefillDialog",
|
|
||||||
"symptom": true,
|
|
||||||
"script": `
|
|
||||||
|
|
||||||
if (args.type == "characteristic" && args.item == "fel")
|
|
||||||
args.prefillModifiers.modifier -= 10
|
|
||||||
else if (args.type == "skill")
|
|
||||||
{
|
|
||||||
if (args.item.characteristic.value == "fel")
|
|
||||||
args.prefillModifiers.modifier -= 10
|
|
||||||
}
|
|
||||||
}`
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"wounded": {
|
|
||||||
label: "Blessé",
|
|
||||||
icon: "modules/wfrp4e-core/icons/diseases/disease.png",
|
|
||||||
transfer: true,
|
|
||||||
flags: {
|
|
||||||
wfrp4e: {
|
|
||||||
"effectApplication": "actor",
|
|
||||||
"effectTrigger": "invoke",
|
|
||||||
"symptom": true,
|
|
||||||
"script": `
|
|
||||||
if (args.actor.isOwner)
|
|
||||||
{
|
|
||||||
args.actor.setupSkill("Résistance", {absolute: {difficulty : "average"}}).then(setupData => {
|
|
||||||
args.actor.basicTest(setupData).then(test =>
|
|
||||||
{
|
|
||||||
if (test.result.outcome == "failure")
|
|
||||||
fromUuid("Compendium.wfrp4e-core.diseases.kKccDTGzWzSXCBOb").then(disease => {
|
|
||||||
args.actor.createEmbeddedDocuments("Item", [disease.toObject()])
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}`
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
game.wfrp4e.config.effectApplication = {
|
game.wfrp4e.config.effectApplication = {
|
||||||
"actor": "Acteur",
|
"actor": "Acteur",
|
||||||
|
|||||||
@@ -155,7 +155,7 @@ export default class InnRoller {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Extraire les informations du résultat
|
// Extraire les informations du résultat
|
||||||
const resultText = rollResult.results[0]?.text || "Résultat inconnu";
|
const resultText = rollResult.results[0]?.name || rollResult.results[0]?.description || "Résultat inconnu";
|
||||||
const rollFormula = rollResult.roll?.formula || "1d100";
|
const rollFormula = rollResult.roll?.formula || "1d100";
|
||||||
const rollTotal = rollResult.roll?.total || 0;
|
const rollTotal = rollResult.roll?.total || 0;
|
||||||
|
|
||||||
@@ -349,7 +349,7 @@ export default class InnRoller {
|
|||||||
if (rollTable) {
|
if (rollTable) {
|
||||||
try {
|
try {
|
||||||
const roll = await rollTable.draw({ displayChat: false });
|
const roll = await rollTable.draw({ displayChat: false });
|
||||||
const resultText = roll.results[0]?.text || "Résultat inconnu";
|
const resultText = roll.results[0]?.name || roll.results[0]?.description || "Résultat inconnu";
|
||||||
results.push({
|
results.push({
|
||||||
category: this.getCategoryName(tableName),
|
category: this.getCategoryName(tableName),
|
||||||
name: resultText,
|
name: resultText,
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
|||||||
MANIFEST-001251
|
MANIFEST-001339
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
2026/01/07-15:05:51.801144 7f93ebfff6c0 Recovering log #1249
|
2026/04/13-23:10:07.603169 7fddd97be6c0 Recovering log #1337
|
||||||
2026/01/07-15:05:51.812047 7f93ebfff6c0 Delete type=3 #1247
|
2026/04/13-23:10:07.613544 7fddd97be6c0 Delete type=3 #1335
|
||||||
2026/01/07-15:05:51.812099 7f93ebfff6c0 Delete type=0 #1249
|
2026/04/13-23:10:07.613619 7fddd97be6c0 Delete type=0 #1337
|
||||||
2026/01/07-15:06:45.486999 7f93e9ffb6c0 Level-0 table #1254: started
|
2026/04/13-23:14:52.439353 7fddca1c26c0 Level-0 table #1342: started
|
||||||
2026/01/07-15:06:45.487020 7f93e9ffb6c0 Level-0 table #1254: 0 bytes OK
|
2026/04/13-23:14:52.439375 7fddca1c26c0 Level-0 table #1342: 0 bytes OK
|
||||||
2026/01/07-15:06:45.493208 7f93e9ffb6c0 Delete type=0 #1252
|
2026/04/13-23:14:52.447401 7fddca1c26c0 Delete type=0 #1340
|
||||||
2026/01/07-15:06:45.493509 7f93e9ffb6c0 Manual compaction at level-0 from '!journal!3IgmiprzLB6Lwenc' @ 72057594037927935 : 1 .. '!journal.pages!suuYN87Al1ZZWtQQ.jhgNnhWhrkOpKs1B' @ 0 : 0; will stop at (end)
|
2026/04/13-23:14:52.447538 7fddca1c26c0 Manual compaction at level-0 from '!journal!3IgmiprzLB6Lwenc' @ 72057594037927935 : 1 .. '!journal.pages!suuYN87Al1ZZWtQQ.jhgNnhWhrkOpKs1B' @ 0 : 0; will stop at (end)
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
2026/01/07-14:19:22.396531 7f93ebfff6c0 Recovering log #1245
|
2026/04/13-23:01:32.388566 7fddd97be6c0 Recovering log #1333
|
||||||
2026/01/07-14:19:22.406238 7f93ebfff6c0 Delete type=3 #1243
|
2026/04/13-23:01:32.399282 7fddd97be6c0 Delete type=3 #1331
|
||||||
2026/01/07-14:19:22.406300 7f93ebfff6c0 Delete type=0 #1245
|
2026/04/13-23:01:32.399346 7fddd97be6c0 Delete type=0 #1333
|
||||||
2026/01/07-15:04:29.638874 7f93e9ffb6c0 Level-0 table #1250: started
|
2026/04/13-23:07:12.207745 7fddca1c26c0 Level-0 table #1338: started
|
||||||
2026/01/07-15:04:29.638900 7f93e9ffb6c0 Level-0 table #1250: 0 bytes OK
|
2026/04/13-23:07:12.207766 7fddca1c26c0 Level-0 table #1338: 0 bytes OK
|
||||||
2026/01/07-15:04:29.650961 7f93e9ffb6c0 Delete type=0 #1248
|
2026/04/13-23:07:12.214487 7fddca1c26c0 Delete type=0 #1336
|
||||||
2026/01/07-15:04:29.667055 7f93e9ffb6c0 Manual compaction at level-0 from '!journal!3IgmiprzLB6Lwenc' @ 72057594037927935 : 1 .. '!journal.pages!suuYN87Al1ZZWtQQ.jhgNnhWhrkOpKs1B' @ 0 : 0; will stop at (end)
|
2026/04/13-23:07:12.214671 7fddca1c26c0 Manual compaction at level-0 from '!journal!3IgmiprzLB6Lwenc' @ 72057594037927935 : 1 .. '!journal.pages!suuYN87Al1ZZWtQQ.jhgNnhWhrkOpKs1B' @ 0 : 0; will stop at (end)
|
||||||
|
|||||||
Binary file not shown.
@@ -1 +1 @@
|
|||||||
MANIFEST-001253
|
MANIFEST-001341
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
2026/01/07-15:05:51.814570 7f93ea7fc6c0 Recovering log #1251
|
2026/04/13-23:10:07.616013 7fddcbfff6c0 Recovering log #1339
|
||||||
2026/01/07-15:05:51.824155 7f93ea7fc6c0 Delete type=3 #1249
|
2026/04/13-23:10:07.625710 7fddcbfff6c0 Delete type=3 #1337
|
||||||
2026/01/07-15:05:51.824233 7f93ea7fc6c0 Delete type=0 #1251
|
2026/04/13-23:10:07.625777 7fddcbfff6c0 Delete type=0 #1339
|
||||||
2026/01/07-15:06:45.493731 7f93e9ffb6c0 Level-0 table #1256: started
|
2026/04/13-23:14:52.426320 7fddca1c26c0 Level-0 table #1344: started
|
||||||
2026/01/07-15:06:45.493762 7f93e9ffb6c0 Level-0 table #1256: 0 bytes OK
|
2026/04/13-23:14:52.426354 7fddca1c26c0 Level-0 table #1344: 0 bytes OK
|
||||||
2026/01/07-15:06:45.500998 7f93e9ffb6c0 Delete type=0 #1254
|
2026/04/13-23:14:52.432796 7fddca1c26c0 Delete type=0 #1342
|
||||||
2026/01/07-15:06:45.529036 7f93e9ffb6c0 Manual compaction at level-0 from '!folders!3uquYH73ttCdoH0I' @ 72057594037927935 : 1 .. '!items!ylFhk7mGZOnAJTUT' @ 0 : 0; will stop at (end)
|
2026/04/13-23:14:52.447521 7fddca1c26c0 Manual compaction at level-0 from '!folders!3uquYH73ttCdoH0I' @ 72057594037927935 : 1 .. '!items!ylFhk7mGZOnAJTUT' @ 0 : 0; will stop at (end)
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
2026/01/07-14:19:22.408420 7f93ea7fc6c0 Recovering log #1247
|
2026/04/13-23:01:32.401911 7fddd8fbd6c0 Recovering log #1335
|
||||||
2026/01/07-14:19:22.419450 7f93ea7fc6c0 Delete type=3 #1245
|
2026/04/13-23:01:32.411157 7fddd8fbd6c0 Delete type=3 #1333
|
||||||
2026/01/07-14:19:22.419496 7f93ea7fc6c0 Delete type=0 #1247
|
2026/04/13-23:01:32.411219 7fddd8fbd6c0 Delete type=0 #1335
|
||||||
2026/01/07-15:04:29.689520 7f93e9ffb6c0 Level-0 table #1252: started
|
2026/04/13-23:07:12.194188 7fddca1c26c0 Level-0 table #1340: started
|
||||||
2026/01/07-15:04:29.689548 7f93e9ffb6c0 Level-0 table #1252: 0 bytes OK
|
2026/04/13-23:07:12.194235 7fddca1c26c0 Level-0 table #1340: 0 bytes OK
|
||||||
2026/01/07-15:04:29.701802 7f93e9ffb6c0 Delete type=0 #1250
|
2026/04/13-23:07:12.201298 7fddca1c26c0 Delete type=0 #1338
|
||||||
2026/01/07-15:04:29.713438 7f93e9ffb6c0 Manual compaction at level-0 from '!folders!3uquYH73ttCdoH0I' @ 72057594037927935 : 1 .. '!items!ylFhk7mGZOnAJTUT' @ 0 : 0; will stop at (end)
|
2026/04/13-23:07:12.214646 7fddca1c26c0 Manual compaction at level-0 from '!folders!3uquYH73ttCdoH0I' @ 72057594037927935 : 1 .. '!items!ylFhk7mGZOnAJTUT' @ 0 : 0; will stop at (end)
|
||||||
|
|||||||
Binary file not shown.
@@ -1 +1 @@
|
|||||||
MANIFEST-001251
|
MANIFEST-001339
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
2026/01/07-15:05:51.839318 7f93eaffd6c0 Recovering log #1249
|
2026/04/13-23:10:07.641322 7fddd9fbf6c0 Recovering log #1337
|
||||||
2026/01/07-15:05:51.849796 7f93eaffd6c0 Delete type=3 #1247
|
2026/04/13-23:10:07.651537 7fddd9fbf6c0 Delete type=3 #1335
|
||||||
2026/01/07-15:05:51.849857 7f93eaffd6c0 Delete type=0 #1249
|
2026/04/13-23:10:07.651623 7fddd9fbf6c0 Delete type=0 #1337
|
||||||
2026/01/07-15:06:45.501213 7f93e9ffb6c0 Level-0 table #1254: started
|
2026/04/13-23:14:52.478583 7fddca1c26c0 Level-0 table #1342: started
|
||||||
2026/01/07-15:06:45.501269 7f93e9ffb6c0 Level-0 table #1254: 0 bytes OK
|
2026/04/13-23:14:52.478613 7fddca1c26c0 Level-0 table #1342: 0 bytes OK
|
||||||
2026/01/07-15:06:45.508204 7f93e9ffb6c0 Delete type=0 #1252
|
2026/04/13-23:14:52.484781 7fddca1c26c0 Delete type=0 #1340
|
||||||
2026/01/07-15:06:45.529072 7f93e9ffb6c0 Manual compaction at level-0 from '!journal!cZtNgayIw2QFhC9u' @ 72057594037927935 : 1 .. '!journal.pages!cZtNgayIw2QFhC9u.ts265H1XkisLgdow' @ 0 : 0; will stop at (end)
|
2026/04/13-23:14:52.484989 7fddca1c26c0 Manual compaction at level-0 from '!journal!cZtNgayIw2QFhC9u' @ 72057594037927935 : 1 .. '!journal.pages!cZtNgayIw2QFhC9u.ts265H1XkisLgdow' @ 0 : 0; will stop at (end)
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
2026/01/07-14:19:22.434524 7f93ea7fc6c0 Recovering log #1245
|
2026/04/13-23:01:32.426243 7fddcbfff6c0 Recovering log #1333
|
||||||
2026/01/07-14:19:22.444128 7f93ea7fc6c0 Delete type=3 #1243
|
2026/04/13-23:01:32.436951 7fddcbfff6c0 Delete type=3 #1331
|
||||||
2026/01/07-14:19:22.444200 7f93ea7fc6c0 Delete type=0 #1245
|
2026/04/13-23:01:32.437016 7fddcbfff6c0 Delete type=0 #1333
|
||||||
2026/01/07-15:04:29.701936 7f93e9ffb6c0 Level-0 table #1250: started
|
2026/04/13-23:07:12.201427 7fddca1c26c0 Level-0 table #1338: started
|
||||||
2026/01/07-15:04:29.701958 7f93e9ffb6c0 Level-0 table #1250: 0 bytes OK
|
2026/04/13-23:07:12.201453 7fddca1c26c0 Level-0 table #1338: 0 bytes OK
|
||||||
2026/01/07-15:04:29.713305 7f93e9ffb6c0 Delete type=0 #1248
|
2026/04/13-23:07:12.207634 7fddca1c26c0 Delete type=0 #1336
|
||||||
2026/01/07-15:04:29.713449 7f93e9ffb6c0 Manual compaction at level-0 from '!journal!cZtNgayIw2QFhC9u' @ 72057594037927935 : 1 .. '!journal.pages!cZtNgayIw2QFhC9u.ts265H1XkisLgdow' @ 0 : 0; will stop at (end)
|
2026/04/13-23:07:12.214659 7fddca1c26c0 Manual compaction at level-0 from '!journal!cZtNgayIw2QFhC9u' @ 72057594037927935 : 1 .. '!journal.pages!cZtNgayIw2QFhC9u.ts265H1XkisLgdow' @ 0 : 0; will stop at (end)
|
||||||
|
|||||||
Binary file not shown.
0
packs/dons-de-rhya/001333.log
Normal file
0
packs/dons-de-rhya/001333.log
Normal file
0
packs/dons-de-rhya/001341.log
Normal file
0
packs/dons-de-rhya/001341.log
Normal file
@@ -1 +1 @@
|
|||||||
MANIFEST-001251
|
MANIFEST-001339
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
2026/01/07-15:05:51.788330 7f93eaffd6c0 Recovering log #1249
|
2026/04/13-23:10:07.590923 7fddd8fbd6c0 Recovering log #1337
|
||||||
2026/01/07-15:05:51.798442 7f93eaffd6c0 Delete type=3 #1247
|
2026/04/13-23:10:07.600770 7fddd8fbd6c0 Delete type=3 #1335
|
||||||
2026/01/07-15:05:51.798508 7f93eaffd6c0 Delete type=0 #1249
|
2026/04/13-23:10:07.600832 7fddd8fbd6c0 Delete type=0 #1337
|
||||||
2026/01/07-15:06:45.480176 7f93e9ffb6c0 Level-0 table #1254: started
|
2026/04/13-23:14:52.419409 7fddca1c26c0 Level-0 table #1342: started
|
||||||
2026/01/07-15:06:45.480197 7f93e9ffb6c0 Level-0 table #1254: 0 bytes OK
|
2026/04/13-23:14:52.419440 7fddca1c26c0 Level-0 table #1342: 0 bytes OK
|
||||||
2026/01/07-15:06:45.486885 7f93e9ffb6c0 Delete type=0 #1252
|
2026/04/13-23:14:52.426167 7fddca1c26c0 Delete type=0 #1340
|
||||||
2026/01/07-15:06:45.493497 7f93e9ffb6c0 Manual compaction at level-0 from '!journal!50u8VAjdmovyr0hx' @ 72057594037927935 : 1 .. '!journal.pages!yzw9I0r3hCK7PJnz.sPNCYj2nR3Cp3jHd' @ 0 : 0; will stop at (end)
|
2026/04/13-23:14:52.447511 7fddca1c26c0 Manual compaction at level-0 from '!journal!50u8VAjdmovyr0hx' @ 72057594037927935 : 1 .. '!journal.pages!yzw9I0r3hCK7PJnz.sPNCYj2nR3Cp3jHd' @ 0 : 0; will stop at (end)
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
2026/01/07-14:19:22.383713 7f93eb7fe6c0 Recovering log #1245
|
2026/04/13-23:01:32.376215 7fddcbfff6c0 Recovering log #1333
|
||||||
2026/01/07-14:19:22.394171 7f93eb7fe6c0 Delete type=3 #1243
|
2026/04/13-23:01:32.386265 7fddcbfff6c0 Delete type=3 #1331
|
||||||
2026/01/07-14:19:22.394305 7f93eb7fe6c0 Delete type=0 #1245
|
2026/04/13-23:01:32.386335 7fddcbfff6c0 Delete type=0 #1333
|
||||||
2026/01/07-15:04:29.651336 7f93e9ffb6c0 Level-0 table #1250: started
|
2026/04/13-23:07:12.172988 7fddca1c26c0 Level-0 table #1338: started
|
||||||
2026/01/07-15:04:29.651360 7f93e9ffb6c0 Level-0 table #1250: 0 bytes OK
|
2026/04/13-23:07:12.173015 7fddca1c26c0 Level-0 table #1338: 0 bytes OK
|
||||||
2026/01/07-15:04:29.666893 7f93e9ffb6c0 Delete type=0 #1248
|
2026/04/13-23:07:12.180381 7fddca1c26c0 Delete type=0 #1336
|
||||||
2026/01/07-15:04:29.667066 7f93e9ffb6c0 Manual compaction at level-0 from '!journal!50u8VAjdmovyr0hx' @ 72057594037927935 : 1 .. '!journal.pages!yzw9I0r3hCK7PJnz.sPNCYj2nR3Cp3jHd' @ 0 : 0; will stop at (end)
|
2026/04/13-23:07:12.187032 7fddca1c26c0 Manual compaction at level-0 from '!journal!50u8VAjdmovyr0hx' @ 72057594037927935 : 1 .. '!journal.pages!yzw9I0r3hCK7PJnz.sPNCYj2nR3Cp3jHd' @ 0 : 0; will stop at (end)
|
||||||
|
|||||||
Binary file not shown.
0
packs/plats-dauberges/001333.log
Normal file
0
packs/plats-dauberges/001333.log
Normal file
0
packs/plats-dauberges/001341.log
Normal file
0
packs/plats-dauberges/001341.log
Normal file
@@ -1 +1 @@
|
|||||||
MANIFEST-001251
|
MANIFEST-001339
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
2026/01/07-15:05:51.775857 7f93ea7fc6c0 Recovering log #1249
|
2026/04/13-23:10:07.578503 7fddd9fbf6c0 Recovering log #1337
|
||||||
2026/01/07-15:05:51.785876 7f93ea7fc6c0 Delete type=3 #1247
|
2026/04/13-23:10:07.588788 7fddd9fbf6c0 Delete type=3 #1335
|
||||||
2026/01/07-15:05:51.785947 7f93ea7fc6c0 Delete type=0 #1249
|
2026/04/13-23:10:07.588855 7fddd9fbf6c0 Delete type=0 #1337
|
||||||
2026/01/07-15:06:45.473201 7f93e9ffb6c0 Level-0 table #1254: started
|
2026/04/13-23:14:52.432890 7fddca1c26c0 Level-0 table #1342: started
|
||||||
2026/01/07-15:06:45.473242 7f93e9ffb6c0 Level-0 table #1254: 0 bytes OK
|
2026/04/13-23:14:52.432912 7fddca1c26c0 Level-0 table #1342: 0 bytes OK
|
||||||
2026/01/07-15:06:45.480074 7f93e9ffb6c0 Delete type=0 #1252
|
2026/04/13-23:14:52.439225 7fddca1c26c0 Delete type=0 #1340
|
||||||
2026/01/07-15:06:45.493481 7f93e9ffb6c0 Manual compaction at level-0 from '!tables!4l60Lxv8cpsyy2Cg' @ 72057594037927935 : 1 .. '!tables.results!tfaYKDZqu7kgZvRG.yvbwKursaixh2dby' @ 0 : 0; will stop at (end)
|
2026/04/13-23:14:52.447529 7fddca1c26c0 Manual compaction at level-0 from '!tables!4l60Lxv8cpsyy2Cg' @ 72057594037927935 : 1 .. '!tables.results!tfaYKDZqu7kgZvRG.yvbwKursaixh2dby' @ 0 : 0; will stop at (end)
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
2026/01/07-14:19:22.369653 7f93ebfff6c0 Recovering log #1245
|
2026/04/13-23:01:32.363321 7fddd9fbf6c0 Recovering log #1333
|
||||||
2026/01/07-14:19:22.381041 7f93ebfff6c0 Delete type=3 #1243
|
2026/04/13-23:01:32.373224 7fddd9fbf6c0 Delete type=3 #1331
|
||||||
2026/01/07-14:19:22.381133 7f93ebfff6c0 Delete type=0 #1245
|
2026/04/13-23:01:32.373285 7fddd9fbf6c0 Delete type=0 #1333
|
||||||
2026/01/07-15:04:29.629205 7f93e9ffb6c0 Level-0 table #1250: started
|
2026/04/13-23:07:12.180494 7fddca1c26c0 Level-0 table #1338: started
|
||||||
2026/01/07-15:04:29.629243 7f93e9ffb6c0 Level-0 table #1250: 0 bytes OK
|
2026/04/13-23:07:12.180514 7fddca1c26c0 Level-0 table #1338: 0 bytes OK
|
||||||
2026/01/07-15:04:29.638743 7f93e9ffb6c0 Delete type=0 #1248
|
2026/04/13-23:07:12.186759 7fddca1c26c0 Delete type=0 #1336
|
||||||
2026/01/07-15:04:29.667035 7f93e9ffb6c0 Manual compaction at level-0 from '!tables!4l60Lxv8cpsyy2Cg' @ 72057594037927935 : 1 .. '!tables.results!tfaYKDZqu7kgZvRG.yvbwKursaixh2dby' @ 0 : 0; will stop at (end)
|
2026/04/13-23:07:12.187045 7fddca1c26c0 Manual compaction at level-0 from '!tables!4l60Lxv8cpsyy2Cg' @ 72057594037927935 : 1 .. '!tables.results!tfaYKDZqu7kgZvRG.yvbwKursaixh2dby' @ 0 : 0; will stop at (end)
|
||||||
|
|||||||
Binary file not shown.
0
packs/tables-des-traductions/000976.log
Normal file
0
packs/tables-des-traductions/000976.log
Normal file
0
packs/tables-des-traductions/000984.log
Normal file
0
packs/tables-des-traductions/000984.log
Normal file
@@ -1 +1 @@
|
|||||||
MANIFEST-000894
|
MANIFEST-000982
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
2026/01/07-15:05:51.826614 7f93ebfff6c0 Recovering log #892
|
2026/04/13-23:10:07.628261 7fddd97be6c0 Recovering log #980
|
||||||
2026/01/07-15:05:51.837158 7f93ebfff6c0 Delete type=3 #890
|
2026/04/13-23:10:07.638743 7fddd97be6c0 Delete type=3 #978
|
||||||
2026/01/07-15:05:51.837206 7f93ebfff6c0 Delete type=0 #892
|
2026/04/13-23:10:07.638813 7fddd97be6c0 Delete type=0 #980
|
||||||
2026/01/07-15:06:45.521984 7f93e9ffb6c0 Level-0 table #897: started
|
2026/04/13-23:14:52.447639 7fddca1c26c0 Level-0 table #985: started
|
||||||
2026/01/07-15:06:45.522031 7f93e9ffb6c0 Level-0 table #897: 0 bytes OK
|
2026/04/13-23:14:52.447658 7fddca1c26c0 Level-0 table #985: 0 bytes OK
|
||||||
2026/01/07-15:06:45.528836 7f93e9ffb6c0 Delete type=0 #895
|
2026/04/13-23:14:52.454058 7fddca1c26c0 Delete type=0 #983
|
||||||
2026/01/07-15:06:45.529100 7f93e9ffb6c0 Manual compaction at level-0 from '!journal!056ILNNrLiPq3Gi3' @ 72057594037927935 : 1 .. '!journal.pages!yfZxl4I7XAuUF6r3.apXmOlZRmGT4GreB' @ 0 : 0; will stop at (end)
|
2026/04/13-23:14:52.484949 7fddca1c26c0 Manual compaction at level-0 from '!journal!056ILNNrLiPq3Gi3' @ 72057594037927935 : 1 .. '!journal.pages!yfZxl4I7XAuUF6r3.apXmOlZRmGT4GreB' @ 0 : 0; will stop at (end)
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
2026/01/07-14:19:22.421981 7f93eb7fe6c0 Recovering log #888
|
2026/04/13-23:01:32.413810 7fddd97be6c0 Recovering log #976
|
||||||
2026/01/07-14:19:22.432249 7f93eb7fe6c0 Delete type=3 #886
|
2026/04/13-23:01:32.423395 7fddd97be6c0 Delete type=3 #974
|
||||||
2026/01/07-14:19:22.432317 7f93eb7fe6c0 Delete type=0 #888
|
2026/04/13-23:01:32.423455 7fddd97be6c0 Delete type=0 #976
|
||||||
2026/01/07-15:04:29.679197 7f93e9ffb6c0 Level-0 table #893: started
|
2026/04/13-23:07:12.187249 7fddca1c26c0 Level-0 table #981: started
|
||||||
2026/01/07-15:04:29.679221 7f93e9ffb6c0 Level-0 table #893: 0 bytes OK
|
2026/04/13-23:07:12.187284 7fddca1c26c0 Level-0 table #981: 0 bytes OK
|
||||||
2026/01/07-15:04:29.689398 7f93e9ffb6c0 Delete type=0 #891
|
2026/04/13-23:07:12.194022 7fddca1c26c0 Delete type=0 #979
|
||||||
2026/01/07-15:04:29.713429 7f93e9ffb6c0 Manual compaction at level-0 from '!journal!056ILNNrLiPq3Gi3' @ 72057594037927935 : 1 .. '!journal.pages!yfZxl4I7XAuUF6r3.apXmOlZRmGT4GreB' @ 0 : 0; will stop at (end)
|
2026/04/13-23:07:12.214628 7fddca1c26c0 Manual compaction at level-0 from '!journal!056ILNNrLiPq3Gi3' @ 72057594037927935 : 1 .. '!journal.pages!yfZxl4I7XAuUF6r3.apXmOlZRmGT4GreB' @ 0 : 0; will stop at (end)
|
||||||
|
|||||||
Binary file not shown.
@@ -1,2 +0,0 @@
|
|||||||
let item = await fromUuid("Compendium.wfrp4e-core.items.weczkAMPlTjX7lqU")
|
|
||||||
this.actor.createEmbeddedDocuments("Item", [item])
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
return args.item?.system?.isRanged && args.data.targets[0]?.actor?.sizeNum < 3
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
// The imbiber immediately
|
|
||||||
// takes 3 Poisoned Conditions that cannot be resisted at first,
|
|
||||||
await this.actor.addCondition("poisoned", 3)
|
|
||||||
|
|
||||||
// recovers a number of Wounds equal to their Toughness Bonus,
|
|
||||||
await this.actor.modifyWounds(this.actor.system.characteristics.t.bonus)
|
|
||||||
|
|
||||||
// and acquires the Regenerate Creature Trait.
|
|
||||||
const hasRegenerate = this.actor.has("Regenerate")
|
|
||||||
if (hasRegenerate === undefined) {
|
|
||||||
fromUuid("Compendium.wfrp4e-core.items.SfUUdOGjdYpr3KSR").then(trait => {
|
|
||||||
let traitItem = trait.toObject()
|
|
||||||
this.actor.createEmbeddedDocuments("Item", [traitItem], {fromEffect: this.effect.id})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
this.script.scriptMessage(`<p><strong>${this.actor.prototypeToken.name}</strong> has
|
|
||||||
<ul>
|
|
||||||
<li>gained 3 Poisoned Conditions that cannot be resisted at first</li>
|
|
||||||
<li>recovered ${this.actor.system.characteristics.t.bonus} Wounds</li>
|
|
||||||
<li>acquired the Regenerate Creature Trait.</li>
|
|
||||||
</ul>
|
|
||||||
It’s up to Ranald if their regenerating can outpace their poisoning.</p>
|
|
||||||
<p>When all Poisoned Conditions are lost, so too is Regenerate.</p>`,
|
|
||||||
{ whisper: ChatMessage.getWhisperRecipients("GM"), blind: true })
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
this.actor.addCondition("blinded", 3)
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
let item = await fromUuid("Compendium.wfrp4e-core.items.8piWcBKFlQ2J1E3A")
|
|
||||||
let data = item.toObject();
|
|
||||||
data.system.location.key= this.item.system.location.key
|
|
||||||
this.actor.createEmbeddedDocuments("Item", [data])
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
if (!args.flags.quietenedApplied)
|
|
||||||
{
|
|
||||||
args.fields.modifier += 10;
|
|
||||||
args.flags.quietenedApplied = true
|
|
||||||
}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
return !args.options.terror && !args.extendedTest?.flags.wfrp4e?.fear
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
let spells = await warhammer.utility.findAllItems("spell", "Loading Spells")
|
|
||||||
|
|
||||||
let text = (await game.wfrp4e.tables.rollTable("random-caster", {hideDSN: true})).result
|
|
||||||
|
|
||||||
lore = Array.from(text.matchAll(/{(.+?)}/gm))[0][1]
|
|
||||||
|
|
||||||
if (text == "GM's Choice")
|
|
||||||
{
|
|
||||||
return this.script.scriptNotification(text)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (spellsWithLore.length > 0)
|
|
||||||
{
|
|
||||||
let spellsWithLore = spells.filter(i => game.wfrp4e.config.magicLores[i.system.lore.value] == lore)
|
|
||||||
let selectedSpell = spellsWithLore[Math.floor(CONFIG.Dice.randomUniform() * spellsWithLore.length)]
|
|
||||||
this.script.scriptNotification(selectedSpell.name);
|
|
||||||
this.actor.createEmbeddedDocuments("Item", [selectedSpell])
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ui.notifications.notify(`Could not find ${lore} spell. Try Again`)
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
let item = await fromUuid("Compendium.wfrp4e-core.items.4CMKeDTDrRQZbPIJ")
|
|
||||||
let fixation = (await game.wfrp4e.tables.rollTable("fixations"))
|
|
||||||
let data = item.toObject();
|
|
||||||
data.system.specification.value = fixation.result;
|
|
||||||
this.item.updateSource({name : this.item.name += ` (${fixation.result})`});
|
|
||||||
this.actor.createEmbeddedDocuments("Item", [data], {fromEffect : this.effect.id})
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
return !["t", "wp"].includes(args.characteristic)
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
let table = game.wfrp4e.tables.findTable("mutatephys");
|
|
||||||
if (!table)
|
|
||||||
{
|
|
||||||
return ui.notifications.error("Mutation table not found, please ensure a table with the `mutatephys` key is imported in the world.")
|
|
||||||
}
|
|
||||||
let result = (await table.roll()).results[0];
|
|
||||||
let uuid = `Compendium.${result.documentCollection}.${result.documentId}`
|
|
||||||
let item = await fromUuid(uuid);
|
|
||||||
|
|
||||||
if (item)
|
|
||||||
{
|
|
||||||
this.script.scriptNotification(`${item.name} added`)
|
|
||||||
this.actor.createEmbeddedDocuments("Item", [item])
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ui.notifications.error("Item could not be found: " + uuid)
|
|
||||||
}
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
let location = this.item.system.location.key;
|
|
||||||
|
|
||||||
if (location)
|
|
||||||
{
|
|
||||||
let dropped = this.item.system.weaponsAtLocation;
|
|
||||||
|
|
||||||
if (dropped.length)
|
|
||||||
{
|
|
||||||
this.script.scriptNotification(`Dropped ${dropped.map(i => i.name).join(", ")}!`)
|
|
||||||
for(let weapon of dropped)
|
|
||||||
{
|
|
||||||
await weapon.system.toggleEquip();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let roll = await new Roll("max(1, 1d10 - @system.characteristics.t.bonus)", this.actor).roll()
|
|
||||||
|
|
||||||
roll.toMessage(this.script.getChatData({flavor : `${this.effect.name} (Duration)`}));
|
|
||||||
|
|
||||||
this.effect.updateSource({"duration.rounds" : roll.total})
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
if (args.skill?.name != game.i18n.localize("NAME.Gossip"))
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
args.data.canReverse = true; // Kind of a kludge here, the talent Tests has a specific condition, but the description simply says "any gossip test can be reversed" so check it here instead of submission
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
if (args.applyAP && args.modifiers.ap.metal)
|
|
||||||
{
|
|
||||||
args.modifiers.ap.ignored += args.modifiers.ap.metal
|
|
||||||
args.modifiers.ap.details.push("<strong>" + this.effect.name + "</strong>: Ignore Metal (" + args.modifiers.ap.metal + ")");
|
|
||||||
args.modifiers.ap.metal = 0
|
|
||||||
}
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
let item = await fromUuid("Compendium.wfrp4e-core.items.GbDyBCu8ZjDp6dkj")
|
|
||||||
let data = item.toObject();
|
|
||||||
this.actor.createEmbeddedDocuments("Item", [data], {fromEffect : this.effect.id})
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
let item1 = await fromUuid("Compendium.wfrp4e-core.items.3S4OYOZLauXctmev")
|
|
||||||
let item2 = await fromUuid("Compendium.wfrp4e-core.items.7mCcI3q7hgWcmbBU")
|
|
||||||
|
|
||||||
let data1 = item1.toObject();
|
|
||||||
data1.system.location.key = this.item.system.location.key
|
|
||||||
|
|
||||||
let data2 = item2.toObject();
|
|
||||||
data2.system.location.key = this.item.system.location.key
|
|
||||||
|
|
||||||
this.actor.createEmbeddedDocuments("Item", [data1, data2], {fromEffect: this.effect.id})
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
args.fields.modifier -= 20;
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
if (!args.flags.strikeToStun)
|
|
||||||
{
|
|
||||||
args.flags.strikeToStun = true
|
|
||||||
args.fields.modifier += 20;
|
|
||||||
args.fields.hitLocation = "head";
|
|
||||||
}
|
|
||||||
args.fields.successBonus++;
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
return args.options.terror || args.extendedTest?.flags.wfrp4e?.fear
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
let type = this.item.getFlag("wfrp4e", "breath");
|
|
||||||
|
|
||||||
if (["fire", "electricity", "poison"].includes(type))
|
|
||||||
{
|
|
||||||
args.applyAP = false;
|
|
||||||
}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
args.fields.modifier -= 20
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
let state = !this.effect.disabled;
|
|
||||||
this.effect.update({"disabled": state});
|
|
||||||
|
|
||||||
if (state)
|
|
||||||
return ui.notifications.info("EFFECT.CreatureBackInWater", {localize: true})
|
|
||||||
|
|
||||||
return ui.notifications.info("EFFECT.CreatureOutOfWater", {localize: true});
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
if (!this.item.name.includes("(") || this.item.system.tests.value.includes("Terrain"))
|
|
||||||
{
|
|
||||||
let tests = this.item.system.tests.value
|
|
||||||
let name = this.item.name
|
|
||||||
|
|
||||||
// If name already specifies, make sure tests value reflects that
|
|
||||||
if (name.includes("("))
|
|
||||||
{
|
|
||||||
let terrain = name.split("(")[1].split(")")[0]
|
|
||||||
tests = tests.replace("the Terrain", terrain)
|
|
||||||
}
|
|
||||||
else // If no sense specified, provide dialog choice
|
|
||||||
{
|
|
||||||
let choice = await ItemDialog.create(ItemDialog.objectToArray({
|
|
||||||
coastal : "Coastal",
|
|
||||||
deserts : "Deserts",
|
|
||||||
marshes : "Marshes",
|
|
||||||
rocky : "Rocky",
|
|
||||||
tundra : "Tundra",
|
|
||||||
woodlands : "Woodlands"
|
|
||||||
}, this.item.img), 1, "Choose Terrain");
|
|
||||||
if (choice[0])
|
|
||||||
{
|
|
||||||
name = `${name.split("(")[0].trim()} (${choice[0].name})`
|
|
||||||
tests = tests.replace("the Terrain", choice[0].name + " Terrain")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.effect.updateSource({name})
|
|
||||||
this.item.updateSource({name, "system.tests.value" : tests})
|
|
||||||
}
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
let characteristics = {
|
|
||||||
"ws" : 5,
|
|
||||||
"bs" : 5,
|
|
||||||
"s" : 5,
|
|
||||||
"t" : 0,
|
|
||||||
"i" : 5,
|
|
||||||
"ag" : 5,
|
|
||||||
"dex" : 5,
|
|
||||||
"int" : 0,
|
|
||||||
"wp" : 5,
|
|
||||||
"fel" : 5
|
|
||||||
}
|
|
||||||
let items = []
|
|
||||||
|
|
||||||
let updateObj = this.actor.toObject();
|
|
||||||
|
|
||||||
let talents = (await Promise.all([game.wfrp4e.tables.rollTable("talents"), game.wfrp4e.tables.rollTable("talents"), game.wfrp4e.tables.rollTable("talents")])).map(i => i.text)
|
|
||||||
|
|
||||||
for (let ch in characteristics)
|
|
||||||
{
|
|
||||||
updateObj.system.characteristics[ch].modifier += characteristics[ch];
|
|
||||||
}
|
|
||||||
|
|
||||||
for (let talent of talents)
|
|
||||||
{
|
|
||||||
let talentItem = await game.wfrp4e.utility.findTalent(talent)
|
|
||||||
if (talentItem)
|
|
||||||
{
|
|
||||||
items.push(talentItem.toObject());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ui.notifications.warn(`Could not find ${talent}`, {permanent : true})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
await this.actor.update(updateObj)
|
|
||||||
this.actor.createEmbeddedDocuments("Item", items);
|
|
||||||
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
return args.characteristic != "t"
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
args.actor.details.move.run += 4
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
await this.actor.addCondition("ablaze", 2)
|
|
||||||
await this.script.scriptMessage(await this.actor.applyBasicDamage(this.effect.sourceTest.result.damage, {suppressMsg: true}))
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
return args.characteristic != "wp"
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
let test = await this.actor.setupCharacteristic("wp", {skipTargets: true, appendTitle : ` ${this.effect.name}`})
|
|
||||||
await test.roll()
|
|
||||||
if (test.succeeded)
|
|
||||||
{
|
|
||||||
this.effect.delete();
|
|
||||||
}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
args.options.cardsharp = true;
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
if (args.opposedTest.result.hitloc.value == this.item.system.location.key && args.totalWoundLoss > 0)
|
|
||||||
{
|
|
||||||
args.actor.addCondition("bleeding", 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
return ["ws", "bs", "s", "ag", "t", "dex"].includes(args.characteristic)
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
let test = await args.actor.setupCharacteristic("wp", {skipTargets: true, appendTitle : " - " + this.effect.name, context : {failure: "Gained a Stunned Condition"}})
|
|
||||||
await test.roll();
|
|
||||||
if (test.failed)
|
|
||||||
{
|
|
||||||
args.actor.addCondition("stunned")
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
this.actor.status.addArmour(1, {source: this.effect, magical : true})
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
this.script.scriptNotification(`Cannot enter ${this.effect.name}!`);
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
let healed = parseInt(this.effect.sourceTest.result.SL)
|
|
||||||
this.actor.modifyWounds(healed)
|
|
||||||
this.script.scriptMessage(`Healed ${healed} Wounds`)
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
let damage = this.effect.sourceActor.hasCondition("fatigued") ? 6 : 10;
|
|
||||||
|
|
||||||
let loc = "body"
|
|
||||||
|
|
||||||
let APatLoc = this.actor.system.status.armour[loc];
|
|
||||||
|
|
||||||
let metalAP = APatLoc.layers.reduce((metal, layer) => metal += ((layer.metal && !layer.magical) ? layer.value : 0), 0)
|
|
||||||
|
|
||||||
let APused = Math.max(0, APatLoc.value - metalAP); // remove metal AP at location;
|
|
||||||
|
|
||||||
damage -= (APused + this.actor.system.characteristics.t.bonus)
|
|
||||||
|
|
||||||
let msg = await this.actor.applyBasicDamage(damage, {suppressMsg : true, damageType : game.wfrp4e.config.DAMAGE_TYPE.IGNORE_ALL});
|
|
||||||
msg += ` (ignored ${metalAP} metal AP on ${game.wfrp4e.config.locations[loc]})`
|
|
||||||
this.script.scriptMessage(msg)
|
|
||||||
|
|
||||||
let test = await this.actor.setupSkill("Endurance", {fields : {difficulty : "difficult"}, appendTitle : ` - ${this.effect.name}`});
|
|
||||||
await test.roll();
|
|
||||||
if (test.failed)
|
|
||||||
this.actor.addCondition("stunned");
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
args.options.ballockKnife = true;
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
if (args.effect.conditionId == "bleeding")
|
|
||||||
args.data.damage -= 1
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
let choice = await ItemDialog.create(ItemDialog.objectToArray(game.wfrp4e.config.locations), 1, "Choose Location");
|
|
||||||
|
|
||||||
let location = choice[0].id;
|
|
||||||
|
|
||||||
let itemTargeted = this.actor.items.get(this.effect.getFlag("wfrp4e", "itemTargets")[0])
|
|
||||||
|
|
||||||
if (itemTargeted)
|
|
||||||
{
|
|
||||||
itemTargeted.update({[`system.APdamage.${location}`] : itemTargeted.system.APdamage[location] + 1})
|
|
||||||
}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
return args.options.reload
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
let item = await fromUuid("Compendium.wfrp4e-core.items.eWPN3CV2Eddwz8aM")
|
|
||||||
let data = item.toObject();
|
|
||||||
data.system.location.value = "Back"
|
|
||||||
this.actor.createEmbeddedDocuments("Item", [data], {fromEffect: this.effect.id})
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
game.wfrp4e.utility.postCorruptionTest(this.item.system.specification.value, {speaker : {alias: this.actor.prototypeToken.name}})
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
return args.item?.system.attackType
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
return !["fel"].includes(args.characteristic)
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user