Compare commits

..

7 Commits

Author SHA1 Message Date
8862698262 Nombreuses corections de scripts...
All checks were successful
Validation JSON / validate (push) Successful in 15s
Release Creation / build (release) Successful in 57s
2026-03-07 15:02:18 +01:00
047933a610 Cleanup old gitlab files
All checks were successful
Validation JSON / validate (push) Successful in 18s
Release Creation / build (release) Successful in 50s
2026-03-07 13:29:29 +01:00
b489f65618 Corrections sur la commande /trade et synchronisation des traductions manquantes 2026-03-07 13:29:09 +01:00
406a535c76 Corrections sur la commande /trade et synchronisation des traductions manquantes 2026-03-07 09:34:41 +01:00
5bc6d0d2f5 Corrections sur les scripts avec wounds/blessures 2026-03-05 20:44:48 +01:00
d557fac83f Corrections sur Sens Aiguisé 2026-03-04 11:46:29 +01:00
f07ef0b01d Fix release 2026-03-01 10:19:24 +01:00
93 changed files with 6687 additions and 2306 deletions

View 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'

View 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

View File

@@ -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

View 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
View 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('');
});
}

View File

@@ -5,9 +5,6 @@
}, },
{ {
"path": "../WFRP4e-FoundryVTT" "path": "../WFRP4e-FoundryVTT"
},
{
"path": "../WarhammerLibrary-FVTT"
} }
], ],
"settings": {} "settings": {}

4025
fr.json

File diff suppressed because it is too large Load Diff

View File

@@ -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.4.0", "version": "9.4.3",
"esmodules": [ "esmodules": [
"wh4_fr.js", "wh4_fr.js",
"modules/babele-register.js", "modules/babele-register.js",
@@ -119,8 +119,8 @@
"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-7.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",

View File

@@ -133,10 +133,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 +175,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;
}); });
} }
} }

File diff suppressed because one or more lines are too long

View File

@@ -1 +1 @@
MANIFEST-001287 MANIFEST-001311

View File

@@ -1,7 +1,7 @@
2026/01/29-22:56:42.449653 7f78b77fe6c0 Recovering log #1285 2026/03/07-00:45:53.808506 7fe8c37fe6c0 Recovering log #1309
2026/01/29-22:56:42.460601 7f78b77fe6c0 Delete type=3 #1283 2026/03/07-00:45:53.819278 7fe8c37fe6c0 Delete type=3 #1307
2026/01/29-22:56:42.460653 7f78b77fe6c0 Delete type=0 #1285 2026/03/07-00:45:53.819338 7fe8c37fe6c0 Delete type=0 #1309
2026/01/29-22:57:35.335489 7f78b67fc6c0 Level-0 table #1290: started 2026/03/07-01:11:49.557068 7fe8c2ffd6c0 Level-0 table #1314: started
2026/01/29-22:57:35.335514 7f78b67fc6c0 Level-0 table #1290: 0 bytes OK 2026/03/07-01:11:49.557102 7fe8c2ffd6c0 Level-0 table #1314: 0 bytes OK
2026/01/29-22:57:35.341828 7f78b67fc6c0 Delete type=0 #1288 2026/03/07-01:11:49.563625 7fe8c2ffd6c0 Delete type=0 #1312
2026/01/29-22:57:35.348187 7f78b67fc6c0 Manual compaction at level-0 from '!journal!3IgmiprzLB6Lwenc' @ 72057594037927935 : 1 .. '!journal.pages!suuYN87Al1ZZWtQQ.jhgNnhWhrkOpKs1B' @ 0 : 0; will stop at (end) 2026/03/07-01:11:49.577541 7fe8c2ffd6c0 Manual compaction at level-0 from '!journal!3IgmiprzLB6Lwenc' @ 72057594037927935 : 1 .. '!journal.pages!suuYN87Al1ZZWtQQ.jhgNnhWhrkOpKs1B' @ 0 : 0; will stop at (end)

View File

@@ -1,7 +1,7 @@
2026/01/29-20:23:41.937265 7fac3cbfe6c0 Recovering log #1281 2026/03/05-20:38:02.743870 7f7930fff6c0 Recovering log #1305
2026/01/29-20:23:41.947854 7fac3cbfe6c0 Delete type=3 #1279 2026/03/05-20:38:02.754744 7f7930fff6c0 Delete type=3 #1303
2026/01/29-20:23:41.947908 7fac3cbfe6c0 Delete type=0 #1281 2026/03/05-20:38:02.754879 7f7930fff6c0 Delete type=0 #1305
2026/01/29-20:30:28.237866 7fa9a6fef6c0 Level-0 table #1286: started 2026/03/05-20:42:36.083534 7f78e15b46c0 Level-0 table #1310: started
2026/01/29-20:30:28.237897 7fa9a6fef6c0 Level-0 table #1286: 0 bytes OK 2026/03/05-20:42:36.083606 7f78e15b46c0 Level-0 table #1310: 0 bytes OK
2026/01/29-20:30:28.274449 7fa9a6fef6c0 Delete type=0 #1284 2026/03/05-20:42:36.090385 7f78e15b46c0 Delete type=0 #1308
2026/01/29-20:30:28.305057 7fa9a6fef6c0 Manual compaction at level-0 from '!journal!3IgmiprzLB6Lwenc' @ 72057594037927935 : 1 .. '!journal.pages!suuYN87Al1ZZWtQQ.jhgNnhWhrkOpKs1B' @ 0 : 0; will stop at (end) 2026/03/05-20:42:36.111635 7f78e15b46c0 Manual compaction at level-0 from '!journal!3IgmiprzLB6Lwenc' @ 72057594037927935 : 1 .. '!journal.pages!suuYN87Al1ZZWtQQ.jhgNnhWhrkOpKs1B' @ 0 : 0; will stop at (end)

View File

@@ -1 +1 @@
MANIFEST-001289 MANIFEST-001313

View File

@@ -1,7 +1,7 @@
2026/01/29-22:56:42.465768 7f78b7fff6c0 Recovering log #1287 2026/03/07-00:45:53.822265 7fe9111ff6c0 Recovering log #1311
2026/01/29-22:56:42.475309 7f78b7fff6c0 Delete type=3 #1285 2026/03/07-00:45:53.832029 7fe9111ff6c0 Delete type=3 #1309
2026/01/29-22:56:42.475364 7f78b7fff6c0 Delete type=0 #1287 2026/03/07-00:45:53.832089 7fe9111ff6c0 Delete type=0 #1311
2026/01/29-22:57:35.362417 7f78b67fc6c0 Level-0 table #1292: started 2026/03/07-01:11:49.549791 7fe8c2ffd6c0 Level-0 table #1316: started
2026/01/29-22:57:35.362439 7f78b67fc6c0 Level-0 table #1292: 0 bytes OK 2026/03/07-01:11:49.549814 7fe8c2ffd6c0 Level-0 table #1316: 0 bytes OK
2026/01/29-22:57:35.369784 7f78b67fc6c0 Delete type=0 #1290 2026/03/07-01:11:49.556940 7fe8c2ffd6c0 Delete type=0 #1314
2026/01/29-22:57:35.376148 7f78b67fc6c0 Manual compaction at level-0 from '!folders!3uquYH73ttCdoH0I' @ 72057594037927935 : 1 .. '!items!ylFhk7mGZOnAJTUT' @ 0 : 0; will stop at (end) 2026/03/07-01:11:49.577524 7fe8c2ffd6c0 Manual compaction at level-0 from '!folders!3uquYH73ttCdoH0I' @ 72057594037927935 : 1 .. '!items!ylFhk7mGZOnAJTUT' @ 0 : 0; will stop at (end)

View File

@@ -1,7 +1,7 @@
2026/01/29-20:23:41.951251 7fac277fe6c0 Recovering log #1283 2026/03/05-20:38:02.758975 7f78e37fe6c0 Recovering log #1307
2026/01/29-20:23:41.961856 7fac277fe6c0 Delete type=3 #1281 2026/03/05-20:38:02.770688 7f78e37fe6c0 Delete type=3 #1305
2026/01/29-20:23:41.961911 7fac277fe6c0 Delete type=0 #1283 2026/03/05-20:38:02.770801 7f78e37fe6c0 Delete type=0 #1307
2026/01/29-20:30:28.274586 7fa9a6fef6c0 Level-0 table #1288: started 2026/03/05-20:42:36.097432 7f78e15b46c0 Level-0 table #1312: started
2026/01/29-20:30:28.274614 7fa9a6fef6c0 Level-0 table #1288: 0 bytes OK 2026/03/05-20:42:36.097481 7f78e15b46c0 Level-0 table #1312: 0 bytes OK
2026/01/29-20:30:28.304924 7fa9a6fef6c0 Delete type=0 #1286 2026/03/05-20:42:36.104419 7f78e15b46c0 Delete type=0 #1310
2026/01/29-20:30:28.305066 7fa9a6fef6c0 Manual compaction at level-0 from '!folders!3uquYH73ttCdoH0I' @ 72057594037927935 : 1 .. '!items!ylFhk7mGZOnAJTUT' @ 0 : 0; will stop at (end) 2026/03/05-20:42:36.111679 7f78e15b46c0 Manual compaction at level-0 from '!folders!3uquYH73ttCdoH0I' @ 72057594037927935 : 1 .. '!items!ylFhk7mGZOnAJTUT' @ 0 : 0; will stop at (end)

View File

@@ -1 +1 @@
MANIFEST-001287 MANIFEST-001311

View File

@@ -1,7 +1,7 @@
2026/01/29-22:56:42.493062 7f78b6ffd6c0 Recovering log #1285 2026/03/07-00:45:53.847464 7fe8c3fff6c0 Recovering log #1309
2026/01/29-22:56:42.503149 7f78b6ffd6c0 Delete type=3 #1283 2026/03/07-00:45:53.857503 7fe8c3fff6c0 Delete type=3 #1307
2026/01/29-22:56:42.503203 7f78b6ffd6c0 Delete type=0 #1285 2026/03/07-00:45:53.857563 7fe8c3fff6c0 Delete type=0 #1309
2026/01/29-22:57:35.355694 7f78b67fc6c0 Level-0 table #1290: started 2026/03/07-01:11:49.577693 7fe8c2ffd6c0 Level-0 table #1314: started
2026/01/29-22:57:35.355726 7f78b67fc6c0 Level-0 table #1290: 0 bytes OK 2026/03/07-01:11:49.577722 7fe8c2ffd6c0 Level-0 table #1314: 0 bytes OK
2026/01/29-22:57:35.362323 7f78b67fc6c0 Delete type=0 #1288 2026/03/07-01:11:49.583840 7fe8c2ffd6c0 Delete type=0 #1312
2026/01/29-22:57:35.376141 7f78b67fc6c0 Manual compaction at level-0 from '!journal!cZtNgayIw2QFhC9u' @ 72057594037927935 : 1 .. '!journal.pages!cZtNgayIw2QFhC9u.ts265H1XkisLgdow' @ 0 : 0; will stop at (end) 2026/03/07-01:11:49.612617 7fe8c2ffd6c0 Manual compaction at level-0 from '!journal!cZtNgayIw2QFhC9u' @ 72057594037927935 : 1 .. '!journal.pages!cZtNgayIw2QFhC9u.ts265H1XkisLgdow' @ 0 : 0; will stop at (end)

View File

@@ -1,7 +1,7 @@
2026/01/29-20:23:41.979254 7fac277fe6c0 Recovering log #1281 2026/03/05-20:38:02.790472 7f78e3fff6c0 Recovering log #1305
2026/01/29-20:23:41.990432 7fac277fe6c0 Delete type=3 #1279 2026/03/05-20:38:02.801425 7f78e3fff6c0 Delete type=3 #1303
2026/01/29-20:23:41.990499 7fac277fe6c0 Delete type=0 #1281 2026/03/05-20:38:02.801553 7f78e3fff6c0 Delete type=0 #1305
2026/01/29-20:30:28.407331 7fa9a6fef6c0 Level-0 table #1286: started 2026/03/05-20:42:36.090593 7f78e15b46c0 Level-0 table #1310: started
2026/01/29-20:30:28.407362 7fa9a6fef6c0 Level-0 table #1286: 0 bytes OK 2026/03/05-20:42:36.090646 7f78e15b46c0 Level-0 table #1310: 0 bytes OK
2026/01/29-20:30:28.441323 7fa9a6fef6c0 Delete type=0 #1284 2026/03/05-20:42:36.097257 7f78e15b46c0 Delete type=0 #1308
2026/01/29-20:30:28.642713 7fa9a6fef6c0 Manual compaction at level-0 from '!journal!cZtNgayIw2QFhC9u' @ 72057594037927935 : 1 .. '!journal.pages!cZtNgayIw2QFhC9u.ts265H1XkisLgdow' @ 0 : 0; will stop at (end) 2026/03/05-20:42:36.111659 7f78e15b46c0 Manual compaction at level-0 from '!journal!cZtNgayIw2QFhC9u' @ 72057594037927935 : 1 .. '!journal.pages!cZtNgayIw2QFhC9u.ts265H1XkisLgdow' @ 0 : 0; will stop at (end)

View File

@@ -1 +1 @@
MANIFEST-001287 MANIFEST-001311

View File

@@ -1,7 +1,7 @@
2026/01/29-22:56:42.435103 7f78cc9ff6c0 Recovering log #1285 2026/03/07-00:45:53.792556 7fe8c3fff6c0 Recovering log #1309
2026/01/29-22:56:42.445358 7f78cc9ff6c0 Delete type=3 #1283 2026/03/07-00:45:53.805674 7fe8c3fff6c0 Delete type=3 #1307
2026/01/29-22:56:42.445414 7f78cc9ff6c0 Delete type=0 #1285 2026/03/07-00:45:53.805724 7fe8c3fff6c0 Delete type=0 #1309
2026/01/29-22:57:35.328574 7f78b67fc6c0 Level-0 table #1290: started 2026/03/07-01:11:49.563712 7fe8c2ffd6c0 Level-0 table #1314: started
2026/01/29-22:57:35.328607 7f78b67fc6c0 Level-0 table #1290: 0 bytes OK 2026/03/07-01:11:49.563733 7fe8c2ffd6c0 Level-0 table #1314: 0 bytes OK
2026/01/29-22:57:35.335392 7f78b67fc6c0 Delete type=0 #1288 2026/03/07-01:11:49.570212 7fe8c2ffd6c0 Delete type=0 #1312
2026/01/29-22:57:35.348176 7f78b67fc6c0 Manual compaction at level-0 from '!journal!50u8VAjdmovyr0hx' @ 72057594037927935 : 1 .. '!journal.pages!yzw9I0r3hCK7PJnz.sPNCYj2nR3Cp3jHd' @ 0 : 0; will stop at (end) 2026/03/07-01:11:49.577555 7fe8c2ffd6c0 Manual compaction at level-0 from '!journal!50u8VAjdmovyr0hx' @ 72057594037927935 : 1 .. '!journal.pages!yzw9I0r3hCK7PJnz.sPNCYj2nR3Cp3jHd' @ 0 : 0; will stop at (end)

View File

@@ -1,7 +1,7 @@
2026/01/29-20:23:41.924353 7fac3d3ff6c0 Recovering log #1281 2026/03/05-20:38:02.727495 7f78e2ffd6c0 Recovering log #1305
2026/01/29-20:23:41.933825 7fac3d3ff6c0 Delete type=3 #1279 2026/03/05-20:38:02.739900 7f78e2ffd6c0 Delete type=3 #1303
2026/01/29-20:23:41.933878 7fac3d3ff6c0 Delete type=0 #1281 2026/03/05-20:38:02.740017 7f78e2ffd6c0 Delete type=0 #1305
2026/01/29-20:30:28.174496 7fa9a6fef6c0 Level-0 table #1286: started 2026/03/05-20:42:36.060514 7f78e15b46c0 Level-0 table #1310: started
2026/01/29-20:30:28.174527 7fa9a6fef6c0 Level-0 table #1286: 0 bytes OK 2026/03/05-20:42:36.060577 7f78e15b46c0 Level-0 table #1310: 0 bytes OK
2026/01/29-20:30:28.203862 7fa9a6fef6c0 Delete type=0 #1284 2026/03/05-20:42:36.067949 7f78e15b46c0 Delete type=0 #1308
2026/01/29-20:30:28.305039 7fa9a6fef6c0 Manual compaction at level-0 from '!journal!50u8VAjdmovyr0hx' @ 72057594037927935 : 1 .. '!journal.pages!yzw9I0r3hCK7PJnz.sPNCYj2nR3Cp3jHd' @ 0 : 0; will stop at (end) 2026/03/05-20:42:36.083144 7f78e15b46c0 Manual compaction at level-0 from '!journal!50u8VAjdmovyr0hx' @ 72057594037927935 : 1 .. '!journal.pages!yzw9I0r3hCK7PJnz.sPNCYj2nR3Cp3jHd' @ 0 : 0; will stop at (end)

View File

@@ -1 +1 @@
MANIFEST-001287 MANIFEST-001311

View File

@@ -1,7 +1,7 @@
2026/01/29-22:56:42.421350 7f78b6ffd6c0 Recovering log #1285 2026/03/07-00:45:53.774458 7fe8c37fe6c0 Recovering log #1309
2026/01/29-22:56:42.431020 7f78b6ffd6c0 Delete type=3 #1283 2026/03/07-00:45:53.787633 7fe8c37fe6c0 Delete type=3 #1307
2026/01/29-22:56:42.431080 7f78b6ffd6c0 Delete type=0 #1285 2026/03/07-00:45:53.787702 7fe8c37fe6c0 Delete type=0 #1309
2026/01/29-22:57:35.341932 7f78b67fc6c0 Level-0 table #1290: started 2026/03/07-01:11:49.543331 7fe8c2ffd6c0 Level-0 table #1314: started
2026/01/29-22:57:35.341953 7f78b67fc6c0 Level-0 table #1290: 0 bytes OK 2026/03/07-01:11:49.543361 7fe8c2ffd6c0 Level-0 table #1314: 0 bytes OK
2026/01/29-22:57:35.348055 7f78b67fc6c0 Delete type=0 #1288 2026/03/07-01:11:49.549597 7fe8c2ffd6c0 Delete type=0 #1312
2026/01/29-22:57:35.348196 7f78b67fc6c0 Manual compaction at level-0 from '!tables!4l60Lxv8cpsyy2Cg' @ 72057594037927935 : 1 .. '!tables.results!tfaYKDZqu7kgZvRG.yvbwKursaixh2dby' @ 0 : 0; will stop at (end) 2026/03/07-01:11:49.549676 7fe8c2ffd6c0 Manual compaction at level-0 from '!tables!4l60Lxv8cpsyy2Cg' @ 72057594037927935 : 1 .. '!tables.results!tfaYKDZqu7kgZvRG.yvbwKursaixh2dby' @ 0 : 0; will stop at (end)

View File

@@ -1,7 +1,7 @@
2026/01/29-20:23:41.909492 7fac277fe6c0 Recovering log #1281 2026/03/05-20:38:02.710364 7f7930fff6c0 Recovering log #1305
2026/01/29-20:23:41.920402 7fac277fe6c0 Delete type=3 #1279 2026/03/05-20:38:02.722794 7f7930fff6c0 Delete type=3 #1303
2026/01/29-20:23:41.920469 7fac277fe6c0 Delete type=0 #1281 2026/03/05-20:38:02.722917 7f7930fff6c0 Delete type=0 #1305
2026/01/29-20:30:28.203984 7fa9a6fef6c0 Level-0 table #1286: started 2026/03/05-20:42:36.068193 7f78e15b46c0 Level-0 table #1310: started
2026/01/29-20:30:28.204007 7fa9a6fef6c0 Level-0 table #1286: 0 bytes OK 2026/03/05-20:42:36.068246 7f78e15b46c0 Level-0 table #1310: 0 bytes OK
2026/01/29-20:30:28.237718 7fa9a6fef6c0 Delete type=0 #1284 2026/03/05-20:42:36.074966 7f78e15b46c0 Delete type=0 #1308
2026/01/29-20:30:28.305049 7fa9a6fef6c0 Manual compaction at level-0 from '!tables!4l60Lxv8cpsyy2Cg' @ 72057594037927935 : 1 .. '!tables.results!tfaYKDZqu7kgZvRG.yvbwKursaixh2dby' @ 0 : 0; will stop at (end) 2026/03/05-20:42:36.083182 7f78e15b46c0 Manual compaction at level-0 from '!tables!4l60Lxv8cpsyy2Cg' @ 72057594037927935 : 1 .. '!tables.results!tfaYKDZqu7kgZvRG.yvbwKursaixh2dby' @ 0 : 0; will stop at (end)

View File

@@ -1 +1 @@
MANIFEST-000930 MANIFEST-000954

View File

@@ -1,7 +1,7 @@
2026/01/29-22:56:42.478978 7f78b77fe6c0 Recovering log #928 2026/03/07-00:45:53.835083 7fe8c37fe6c0 Recovering log #952
2026/01/29-22:56:42.489559 7f78b77fe6c0 Delete type=3 #926 2026/03/07-00:45:53.844848 7fe8c37fe6c0 Delete type=3 #950
2026/01/29-22:56:42.489615 7f78b77fe6c0 Delete type=0 #928 2026/03/07-00:45:53.844893 7fe8c37fe6c0 Delete type=0 #952
2026/01/29-22:57:35.369875 7f78b67fc6c0 Level-0 table #933: started 2026/03/07-01:11:49.570293 7fe8c2ffd6c0 Level-0 table #957: started
2026/01/29-22:57:35.369900 7f78b67fc6c0 Level-0 table #933: 0 bytes OK 2026/03/07-01:11:49.570316 7fe8c2ffd6c0 Level-0 table #957: 0 bytes OK
2026/01/29-22:57:35.376019 7f78b67fc6c0 Delete type=0 #931 2026/03/07-01:11:49.577407 7fe8c2ffd6c0 Delete type=0 #955
2026/01/29-22:57:35.376158 7f78b67fc6c0 Manual compaction at level-0 from '!journal!056ILNNrLiPq3Gi3' @ 72057594037927935 : 1 .. '!journal.pages!yfZxl4I7XAuUF6r3.apXmOlZRmGT4GreB' @ 0 : 0; will stop at (end) 2026/03/07-01:11:49.577567 7fe8c2ffd6c0 Manual compaction at level-0 from '!journal!056ILNNrLiPq3Gi3' @ 72057594037927935 : 1 .. '!journal.pages!yfZxl4I7XAuUF6r3.apXmOlZRmGT4GreB' @ 0 : 0; will stop at (end)

View File

@@ -1,7 +1,7 @@
2026/01/29-20:23:41.966258 7fac3cbfe6c0 Recovering log #924 2026/03/05-20:38:02.775184 7f7930fff6c0 Recovering log #948
2026/01/29-20:23:41.975859 7fac3cbfe6c0 Delete type=3 #922 2026/03/05-20:38:02.786747 7f7930fff6c0 Delete type=3 #946
2026/01/29-20:23:41.975913 7fac3cbfe6c0 Delete type=0 #924 2026/03/05-20:38:02.786856 7f7930fff6c0 Delete type=0 #948
2026/01/29-20:30:28.375267 7fa9a6fef6c0 Level-0 table #929: started 2026/03/05-20:42:36.104620 7f78e15b46c0 Level-0 table #953: started
2026/01/29-20:30:28.375310 7fa9a6fef6c0 Level-0 table #929: 0 bytes OK 2026/03/05-20:42:36.104679 7f78e15b46c0 Level-0 table #953: 0 bytes OK
2026/01/29-20:30:28.407196 7fa9a6fef6c0 Delete type=0 #927 2026/03/05-20:42:36.111433 7f78e15b46c0 Delete type=0 #951
2026/01/29-20:30:28.642703 7fa9a6fef6c0 Manual compaction at level-0 from '!journal!056ILNNrLiPq3Gi3' @ 72057594037927935 : 1 .. '!journal.pages!yfZxl4I7XAuUF6r3.apXmOlZRmGT4GreB' @ 0 : 0; will stop at (end) 2026/03/05-20:42:36.111701 7f78e15b46c0 Manual compaction at level-0 from '!journal!056ILNNrLiPq3Gi3' @ 72057594037927935 : 1 .. '!journal.pages!yfZxl4I7XAuUF6r3.apXmOlZRmGT4GreB' @ 0 : 0; will stop at (end)

View File

@@ -1,31 +1,28 @@
if (!this.item.name.includes("(") || this.item.system.tests.value.includes("Terrain") || this.item.system.tests.value.toLowerCase().includes("(any)")) if (!this.item.name.includes("(") || this.item.system.tests.value.includes("Terrain") || this.item.system.tests.value.toLowerCase().includes("(any)")) {
{ let tests = this.item.system.tests.value
let Tests = this.item.system.tests.value
let name = this.item.name let name = this.item.name
// If name already specifies, make sure Tests value reflects that // If name already specifies, make sure Tests value reflects that
if (name.includes("(") && !name.toLowerCase().includes("(any)")) if (name.includes("(") && !name.toLowerCase().includes("(any)")) {
{
let terrain = name.split("(")[1].split(")")[0] let terrain = name.split("(")[1].split(")")[0]
tests = tests.replace("the Terrain", terrain) tests = tests.replace("the Terrain", terrain)
} }
else // If no sense specified, provide dialog choice else // If no sense specified, provide dialog choice
{ {
let choice = await ItemDialog.create(ItemDialog.objectToArray({ let choice = await ItemDialog.create(ItemDialog.objectToArray({
coastal : "Littoral", coastal: "Littoral",
deserts : "Déserts", deserts: "Déserts",
marshes : "Marécages", marshes: "Marécages",
rocky : "Rocailleux", rocky: "Rocailleux",
tundra : "Toundra", tundra: "Toundra",
woodlands : "Régions boisées" woodlands: "Régions boisées"
}, this.item.img), 1, "Choisissez un Terrain"); }, this.item.img), 1, "Choisissez un Terrain");
if (choice[0]) if (choice[0]) {
{
name = `${name.split("(")[0].trim()} (${choice[0].name})` name = `${name.split("(")[0].trim()} (${choice[0].name})`
tests = tests.replace("Terrain", choice[0].name + " Terrain") tests = tests.replace("Terrain", choice[0].name + " Terrain")
} }
} }
this.effect.updateSource({name}) this.effect.updateSource({ name })
this.item.updateSource({name, "system.tests.value" : tests}) this.item.updateSource({ name, "system.tests.value": tests })
} }

View File

@@ -14,7 +14,7 @@
let updateObj = this.actor.toObject(); let updateObj = this.actor.toObject();
let talents = (await Promise.tout([game.wfrp4e.tables.rollTable("talents"), game.wfrp4e.tables.rollTable("talents"), game.wfrp4e.tables.rollTable("talents")])).map(i => i.text) 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) for (let ch in characteristics)
{ {

View File

@@ -1,6 +1,6 @@
let test = await args.actor.setupCharacteristic("wp", {skipTargets: true, appendTitle : " - " + this.effect.name, context : {failure: "Gain de 1 état Sonné"}}) let test = await args.actor.setupCharacteristic("wp", {skipTargets: true, appendTitle : " - " + this.effect.name, context : {failure: "Gain de 1 état Sonné"}})
await Test.roll(); await test.roll();
if (Test.Échoué) if (test.failed)
{ {
args.actor.addCondition("stunned") args.actor.addCondition("stunned")
} }

View File

@@ -1,6 +1,6 @@
let test = await this.actor.setupCharacteristic("ag", {skipTargets: true, appendTitle : ` - ${this.effect.name}`}); let test = await this.actor.setupCharacteristic("ag", {skipTargets: true, appendTitle : ` - ${this.effect.name}`});
await Test.roll(); await test.roll();
if (Test.Échoué) if (test.failed)
{ {
this.actor.addCondition("bleeding"); this.actor.addCondition("bleeding");
} }

View File

@@ -10,17 +10,17 @@ scriptData[0].script = `
let chatData = {whisper: ChatMessage.getWhisperRecipients("GM")}; let chatData = {whisper: ChatMessage.getWhisperRecipients("GM")};
let message = ""; let message = "";
let Blessures = foundry.utils.duplicate(this.actor.status.Blessures); let wounds = foundry.utils.duplicate(this.actor.status.wounds);
let regenRoll = await new Roll("1d10").roll({allowInteractive : false}); let regenRoll = await new Roll("1d10").roll({allowInteractive : false});
let regen = regenRoll.total; let regen = regenRoll.total;
if (Blessures.value >= Blessures.max) if (wounds.value >= wounds.max)
return; return;
if (Blessures.value > 0) { if (wounds.value > 0) {
Blessures.value += Math.floor(regen / 2); wounds.value += Math.floor(regen / 2);
if (Blessures.value > Blessures.max) { if (wounds.value > wounds.max) {
Blessures.value = Blessures.max; wounds.value = wounds.max;
} }
message += \`<b>\${this.actor.name}</b> regagne \${regen} Blessures.\`; message += \`<b>\${this.actor.name}</b> regagne \${regen} Blessures.\`;
@@ -29,7 +29,7 @@ scriptData[0].script = `
} }
} else if (regen >= 8) { } else if (regen >= 8) {
message += \`<b>\${this.actor.name}</b> a obtenu un \${regen} et regagne 1 Blessure.\`; message += \`<b>\${this.actor.name}</b> a obtenu un \${regen} et regagne 1 Blessure.\`;
Blessures.value += 1; wounds.value += 1;
if (regen === 10) { if (regen === 10) {
message += "<br>De plus, il régénère une Blessure Critique."; message += "<br>De plus, il régénère une Blessure Critique.";
} }
@@ -37,7 +37,7 @@ scriptData[0].script = `
message += \`<b>\${this.actor.name}</b> Résultat de régénération de \${regen} - Aucun effet.\`; message += \`<b>\${this.actor.name}</b> Résultat de régénération de \${regen} - Aucun effet.\`;
} }
await this.actor.update({"system.status.wounds": Blessures}); await this.actor.update({"system.status.wounds": wounds});
this.script.message(message, {whisper: ChatMessage.getWhisperRecipients("GM")}); this.script.message(message, {whisper: ChatMessage.getWhisperRecipients("GM")});
` `
@@ -46,4 +46,4 @@ await effet.update({
"system.scriptData": scriptData "system.scriptData": scriptData
}); });
await trait.update({name}); await trait.update({ name });

View File

@@ -1,6 +1,6 @@
let test = await this.actor.setupCharacteristic("wp", {skipTargets: true, appendTitle : " - " + this.effect.name, context : {failure: "GAin d'1 état Sonné"}}) let test = await this.actor.setupCharacteristic("wp", {skipTargets: true, appendTitle : " - " + this.effect.name, context : {failure: "GAin d'1 état Sonné"}})
await Test.roll(); await test.roll();
if (Test.Échoué) if (test.failed)
{ {
this.actor.addCondition("stunned"); this.actor.addCondition("stunned");
} }

View File

@@ -22,7 +22,7 @@ let Test = await actor.setupSkill('Calme', {
fields: {difficulty: 'easy'}, fields: {difficulty: 'easy'},
characteristic: 'wp', characteristic: 'wp',
}); });
await Test.roll(); await test.roll();
if (!Test.succeeded) { if (!Test.succeeded) {
Test.result.other.push(`<b>${actor.name}</b> est devenu @Condition[Stunned] par la vue.`); Test.result.other.push(`<b>${actor.name}</b> est devenu @Condition[Stunned] par la vue.`);

View File

@@ -10,12 +10,12 @@ const test = await this.actor.setupSkill(game.i18n.localize("NAME.Résistance"),
} }
}); });
await Test.roll(); await test.roll();
if (Test.Échoué) { if (test.failed) {
await this.actor.addEffectItems(bloodyFluxUUID, this.effet); await this.actor.addEffectItems(bloodyFluxUUID, this.effet);
} else { } else {
const SL = Test.result.SL; const SL = test.result.SL;
const heal = 1 + SL; const heal = 1 + SL;
await this.actor.modifyWounds(heal); await this.actor.modifyWounds(heal);
this.script.message(`Butcher a soigné ${heal} Blessures.`); this.script.message(`Butcher a soigné ${heal} Blessures.`);

View File

@@ -1,12 +1,12 @@
// Imbibing this substance grants the user the utilisateur d Creature Trait. // Imbibing this substance grants the user the Painless Creature Trait.
const hasutilisateur d = this.actor.has("Insensible à la douleur"); const hasPainless = this.actor.has("Insensible à la douleur");
if (hasutilisateur d === undefined) if (hasPainless === undefined)
{ {
let item = await fromUuid("Compendium.wfrp4e-core.items.wMwSRDmgiF2IdCJr"); let item = await fromUuid("Compendium.wfrp4e-core.items.wMwSRDmgiF2IdCJr");
let data = item.toObject() let data = item.toObject()
this.actor.createEmbeddedDocuments("Item", [data], {fromEffect: this.effect.id}) this.actor.createEmbeddedDocuments("Item", [data], {fromEffect: this.effect.id})
this.script.message( this.script.scriptMessage(
`<p><strong>${this.actor.prototypeToken.name}</strong> a acquis le Trait de Créature Insensible à la douleur. Cet `<p><strong>${this.actor.prototypeToken.name}</strong> a acquis le Trait de Créature Insensible à la douleur. Cet
effet dure une heure, après quoi il se dissipe et l'effet complet effet dure une heure, après quoi il se dissipe et l'effet complet
de toutes les blessures du buveur s'abat d'un coup.</p> de toutes les blessures du buveur s'abat d'un coup.</p>

View File

@@ -7,9 +7,9 @@ const test = await args.actor.setupSkill(game.i18n.localize("NAME.Résistance"),
} }
}); });
await Test.roll(); await test.roll();
if (Test.Échoué) { if (test.failed) {
args.actor.addCondition("poisoned"); args.actor.addCondition("poisoned");
const speaker = ChatMessage.getSpeaker({actor: args.actor}); const speaker = ChatMessage.getSpeaker({actor: args.actor});
this.script.message(`<p>${speaker.alias} a reçu 1 état @Condition[Poisoned] de Venin d'Araignée.</p><p>Les victimes réduites à 0 blessures et qui souffrent d'un état @Condition[Poisoned] de ces flèches deviennent @Condition[Unconcious], mais ne risquent pas la mort à cause des états @Condition[Poisoned] restants comme ce serait normalement le cas.</p>`); this.script.message(`<p>${speaker.alias} a reçu 1 état @Condition[Poisoned] de Venin d'Araignée.</p><p>Les victimes réduites à 0 blessures et qui souffrent d'un état @Condition[Poisoned] de ces flèches deviennent @Condition[Unconcious], mais ne risquent pas la mort à cause des états @Condition[Poisoned] restants comme ce serait normalement le cas.</p>`);

View File

@@ -1,7 +1,7 @@
if (args.test.result.SL < 0) if (args.test.result.SL < 0)
{ {
this.script.message(`Gain de ${Math.abs(args.test.result.SL)} Points de Corruption`, {whisper : ChatMessage.getWhisperRecipients("GM")}) this.script.message(`Gain de ${Math.abs(args.test.result.SL)} Points de Corruption`, {whisper : ChatMessage.getWhisperRecipients("GM")})
if (args.Test.Échoué && this.actor.type == "character") if (args.test.failed && this.actor.type == "character")
{ {
this.actor.update({"system.status.corruption.value" : parseInt(this.actor.status.corruption.value) + Math.abs(args.test.result.SL)}) this.actor.update({"system.status.corruption.value" : parseInt(this.actor.status.corruption.value) + Math.abs(args.test.result.SL)})
} }

View File

@@ -13,9 +13,9 @@ let test = await actor.setupCharacteristic("s", {
} }
}); });
await Test.roll(); await test.roll();
if (Test.succeeded) { if (test.succeeded) {
let SL = parseInt(Test.result.SL); let SL = parseInt(test.result.SL);
let name = this.effect.name.replace(/\d+/, rating => parseInt(rating) - SL); let name = this.effect.name.replace(/\d+/, rating => parseInt(rating) - SL);
await this.effect.update({name}); await this.effect.update({name});
} }

View File

@@ -1,11 +1,11 @@
let test = await this.actor.setupCharacteristic("s", {appendTitle : ` - ${this.effect.name}`, fields : {difficulty : "difficult"}}); let test = await this.actor.setupCharacteristic("s", {appendTitle : ` - ${this.effect.name}`, fields : {difficulty : "difficult"}});
await Test.roll(); await test.roll();
if (Test.Échoué) if (test.failed)
{ {
if (Test.isCriticalFumble == "fumble") if (test.isCriticalFumble == "fumble")
{ {
return this.script.message(`<strong>${this.actor.name}</strong> meurt alors qu'il est entraîné dans l'Aethyr (à moins qu'il ne dépense un point de Destinée pour éviter cela).`); return this.script.message(`<strong>${this.actor.name}</strong> meurt alors qu'il est entraîné dans l'Aethyr (à moins qu'il ne dépense un point de Destinée pour éviter cela).`);
} }

View File

@@ -22,7 +22,7 @@ let Test = await actor.setupSkill('Calme', {
fields: {difficulty: 'easy'}, fields: {difficulty: 'easy'},
characteristic: 'wp', characteristic: 'wp',
}); });
await Test.roll(); await test.roll();
if (!Test.succeeded) { if (!Test.succeeded) {
Test.result.other.push(`<b>${actor.name}</b> est devenu fasciné par la vue et incapable d'effectuer une quelconque action autre que de se déplacer vers la lumière.`); Test.result.other.push(`<b>${actor.name}</b> est devenu fasciné par la vue et incapable d'effectuer une quelconque action autre que de se déplacer vers la lumière.`);

View File

@@ -1,4 +1,4 @@
if (args.test.characteristicKey == "wp" && args.Test.Échoué && args.Test.result.SL <= -3) if (args.test.characteristicKey == "wp" && args.test.failed && args.test.result.SL <= -3)
{ {
this.script.notification("Ajout de A Terre"); this.script.notification("Ajout de A Terre");
this.actor.addCondition("prone") this.actor.addCondition("prone")

View File

@@ -1,6 +1,6 @@
let test = await this.actor.setupCharacteristic("wp", {skipTargets: true, appendTitle : ` - ${this.effect.name}`}) let test = await this.actor.setupCharacteristic("wp", {skipTargets: true, appendTitle : ` - ${this.effect.name}`})
await Test.roll(); await test.roll();
if (Test.succeeded) if (test.succeeded)
{ {
this.script.message("Peut réaliser une Action ou un Déplacement (choisissez-en un)") this.script.message("Peut réaliser une Action ou un Déplacement (choisissez-en un)")
} }

View File

@@ -1 +1 @@
this.script.scirptMessage(await this.actor.applyBasicDamage(20, {suppressMsg: true}); this.script.scriptMessage(await this.actor.applyBasicDamage(20, {suppressMsg: true}));

View File

@@ -1,7 +1,7 @@
let test = await this.actor.setupSkill(game.i18n.localize("NAME.Dodge"), {fields : {difficulty : "hard"}, appendTitle : ` - ${this.effect.name}`}) let test = await this.actor.setupSkill(game.i18n.localize("NAME.Dodge"), {fields : {difficulty : "hard"}, appendTitle : ` - ${this.effect.name}`})
await Test.roll(); await test.roll();
if (Test.Échoué) { if (test.failed) {
this.script.scriptMessage(await this.actor.applyBasicDamage(20, {suppressMsg: true})); this.script.scriptMessage(await this.actor.applyBasicDamage(20, {suppressMsg: true}));
this.script.scriptMessage(`${this.actor.name} est victime de @UUID[Compendium.wfrp4e-core.journals.JournalEntry.NS3YGlJQxwTggjRX.JournalEntryPage.WCivInLZrqEtZzF4#drowning-and-suffocation]{Suffocation}`); this.script.scriptMessage(`${this.actor.name} est victime de @UUID[Compendium.wfrp4e-core.journals.JournalEntry.NS3YGlJQxwTggjRX.JournalEntryPage.WCivInLZrqEtZzF4#drowning-and-suffocation]{Suffocation}`);
} }

View File

@@ -1,6 +1,6 @@
if (args.test.characteristicKey == "wp") if (args.test.characteristicKey == "wp")
{ {
if (args.Test.Échoué) if (args.test.failed)
{ {
this.actor.addSystemEffect("convulsions") this.actor.addSystemEffect("convulsions")
this.script.message(`Test de FM échoué, <b>${this.actor.prototypeToken.name}</b> reçoit @Symptom[Convulsions] pour [[1d10]] heures`) this.script.message(`Test de FM échoué, <b>${this.actor.prototypeToken.name}</b> reçoit @Symptom[Convulsions] pour [[1d10]] heures`)

View File

@@ -9,7 +9,7 @@ if (god)
{ {
let prayers = await warhammer.utility.findAllItems("prayer", "Chargement des Prières", true, ["system.type.value", "system.god.value"]) let prayers = await warhammer.utility.findAllItems("prayer", "Chargement des Prières", true, ["system.type.value", "system.god.value"])
let blessings = prayers.filter(p => p.system.god.value.split(",").map(i => i.trim().toLowerCase()).includes(god.toLowerCase()) && p.system.type.value == "blessing") let blessings = prayers.filter(p => p.system.god.value.split(",").map(i => i.trim().toLowerCase()).includes(god.toLowerCase()) && p.system.type.value == "blessing")
let configBlessings = await Promise.tout((game.wfrp4e.config.godBlessings[god.toLowerCase()] || []).map(fromUuid)); let configBlessings = await Promise.all((game.wfrp4e.config.godBlessings[god.toLowerCase()] || []).map(fromUuid));
if (god == "Foi Antique") if (god == "Foi Antique")
{ {
blessings = await ItemDialog.create(prayers.filter(i => i.system.type.value == "blessing"), 6, {text : "Sélectionnez 6 Bénédictions", title : "Béni"}) blessings = await ItemDialog.create(prayers.filter(i => i.system.type.value == "blessing"), 6, {text : "Sélectionnez 6 Bénédictions", title : "Béni"})

View File

@@ -1,6 +1,6 @@
let test = await this.actor.setupCharacteristic("wp", {skipTargets: true, appendTitle : ` - ${this.effect.name}`}) let test = await this.actor.setupCharacteristic("wp", {skipTargets: true, appendTitle : ` - ${this.effect.name}`})
await Test.roll(); await test.roll();
if (Test.Échoué) if (test.failed)
{ {
this.script.message(await game.wfrp4e.tables.formatChatRoll("enrage-beast")) this.script.message(await game.wfrp4e.tables.formatChatRoll("enrage-beast"))
} }

View File

@@ -1,7 +1,7 @@
if (this.actor.Species.toLowerCase() != "skaven") { if (this.actor.Species.toLowerCase() != "skaven") {
this.actor.setupCharacteristic("t", {skipTargets: true, appendTitle : ` - Utilise ${this.effect.name}`, fields: { difficulty: "difficult" } }).then(async Test => { this.actor.setupCharacteristic("t", {skipTargets: true, appendTitle : ` - Utilise ${this.effect.name}`, fields: { difficulty: "difficult" } }).then(async Test => {
await Test.roll() await test.roll()
if (Test.Échoué) if (test.failed)
{ {
let toughnessLost = Math.ceil(CONFIG.Dice.randomUniform() * 10) let toughnessLost = Math.ceil(CONFIG.Dice.randomUniform() * 10)
this.actor.update({ "system.characteristics.t.initial": this.actor.characteristics.t.initial - toughnessLost }) this.actor.update({ "system.characteristics.t.initial": this.actor.characteristics.t.initial - toughnessLost })

View File

@@ -1,7 +1,7 @@
let test = await this.actor.setupCharacteristic("wp", {fields: {difficulty : "average"}, skipTargets: true, appendTitle : ` - ${this.effect.name}`}) let test = await this.actor.setupCharacteristic("wp", {fields: {difficulty : "average"}, skipTargets: true, appendTitle : ` - ${this.effect.name}`})
await Test.roll(); await test.roll();
if (Test.Échoué) if (test.failed)
{ {
let stuns = Math.max(1, Math.abs(Test.result.SL)) let stuns = Math.max(1, Math.abs(test.result.SL))
this.actor.addCondition("stunned", stuns) this.actor.addCondition("stunned", stuns)
} }

View File

@@ -5,8 +5,8 @@ if (this.actor.uuid == this.effect.sourceActor.uuid)
if (this.actor.has("À Sang Froid") && !this.actor.hasSystemEffect("nausea")) { if (this.actor.has("À Sang Froid") && !this.actor.hasSystemEffect("nausea")) {
let test = await this.actor.setupSkill(game.i18n.localize("NAME.Résistance"), {appendTitle : `- ${this.effect.name}`}) let test = await this.actor.setupSkill(game.i18n.localize("NAME.Résistance"), {appendTitle : `- ${this.effect.name}`})
await Test.roll(); await test.roll();
if (Test.Échoué) if (test.failed)
{ {
let myRoll = await new Roll("1d10").roll({allowInteractive : false}); let myRoll = await new Roll("1d10").roll({allowInteractive : false});

View File

@@ -5,15 +5,15 @@ let wounds = foundry.utils.duplicate(this.actor.status.wounds)
let regenRoll = await new Roll("1d10").roll({allowInteractive : false}); let regenRoll = await new Roll("1d10").roll({allowInteractive : false});
let regen = regenRoll.total; let regen = regenRoll.total;
if (Blessures.value >= Blessures.max) if (wounds.value >= wounds.max)
return return
if (Blessures.value > 0) if (wounds.value > 0)
{ {
Blessures.value += regen wounds.value += regen
if (Blessures.value > Blessures.max) if (wounds.value > wounds.max)
{ {
Blessures.value = Blessures.max wounds.value = wounds.max
} }
message += `<b>${this.actor.name}</b> regagne ${regen} Point de Blessures.` message += `<b>${this.actor.name}</b> regagne ${regen} Point de Blessures.`
@@ -25,7 +25,7 @@ if (Blessures.value > 0)
else if (regen >= 8) else if (regen >= 8)
{ {
message += `<b>${this.actor.name}</b> a fait un ${regen} et regagne 1 Point de Blessures.` message += `<b>${this.actor.name}</b> a fait un ${regen} et regagne 1 Point de Blessures.`
Blessures.value += 1 wounds.value += 1
if (regen == 10) if (regen == 10)
{ {
message += `<br>De plus, il guérit d'une Blessure Critique.` message += `<br>De plus, il guérit d'une Blessure Critique.`
@@ -36,5 +36,5 @@ else
message += `<b>${this.actor.name}</b> a fait un ${regen} et ne régénère pas de Point de Blessures.` message += `<b>${this.actor.name}</b> a fait un ${regen} et ne régénère pas de Point de Blessures.`
} }
await this.actor.update({ "system.status.wounds": Blessures }) await this.actor.update({ "system.status.wounds": wounds })
this.script.message(message, { whisper: ChatMessage.getWhisperRecipients("GM") }) this.script.message(message, { whisper: ChatMessage.getWhisperRecipients("GM") })

View File

@@ -1,6 +1,6 @@
let test = await this.actor.setupSkill("Résistance", {fields : {difficulty : "difficult"}, appendTitle : ` - ${this.effect.name}`}); let test = await this.actor.setupSkill("Résistance", {fields : {difficulty : "difficult"}, appendTitle : ` - ${this.effect.name}`});
await Test.roll(); await test.roll();
if (Test.Échoué) if (test.failed)
{ {
await this.actor.addCondition("blinded"); await this.actor.addCondition("blinded");
} }

View File

@@ -1,7 +1,7 @@
const test = await this.actor.setupCharacteristic("int", {fields: {difficulty: "easy"}, skipTargets: true, appendTitle : ` - ${this.effect.name}`}); const test = await this.actor.setupCharacteristic("int", {fields: {difficulty: "easy"}, skipTargets: true, appendTitle : ` - ${this.effect.name}`});
await Test.roll(); await test.roll();
if (Test.Échoué) { if (test.failed) {
this.actor.addCondition('stunned'); this.actor.addCondition('stunned');
} }

View File

@@ -1,6 +1,6 @@
let test = await this.actor.setupCharacteristic("ag", {skipTargets: true, appendTitle : ` - ${this.effect.name}`, context: { failure: "Goes Prone" }}) let test = await this.actor.setupCharacteristic("ag", {skipTargets: true, appendTitle : ` - ${this.effect.name}`, context: { failure: "Goes Prone" }})
await Test.roll(); await test.roll();
if (Test.Échoué) if (test.failed)
{ {
this.actor.addCondition("prone"); this.actor.addCondition("prone");
} }

View File

@@ -7,9 +7,9 @@ const test = await this.actor.setupSkill(game.i18n.localize("NAME.Résistance"),
} }
}); });
await Test.roll(); await test.roll();
if (Test.Échoué) { if (test.failed) {
const SL = Number(Test.result.SL); const SL = Number(test.result.SL);
this.script.message(`Butcher perd ${SL} dents.`); this.script.message(`Butcher perd ${SL} dents.`);
} }

View File

@@ -1 +1 @@
,args.fields.slBonus++;,args.fields.slBonus++;,args.fields.slBonus++; args.fields.slBonus++;

View File

@@ -7,8 +7,8 @@ let difficulty = ""
difficulty = "veasy" difficulty = "veasy"
let test = await this.actor.setupSkill(game.i18n.localize("NAME.Résistance"), {context : {failure : this.actor.name + " meurt de la Pourriture"}, fields: {difficulty}, appendTitle : " - Pourriture"}) let test = await this.actor.setupSkill(game.i18n.localize("NAME.Résistance"), {context : {failure : this.actor.name + " meurt de la Pourriture"}, fields: {difficulty}, appendTitle : " - Pourriture"})
await Test.roll(); await test.roll();
if (Test.Échoué) if (test.failed)
{ {
this.actor.addCondition("dead"); this.actor.addCondition("dead");
} }

View File

@@ -7,8 +7,8 @@ let difficulty = ""
difficulty = "veasy" difficulty = "veasy"
let test = await this.actor.setupSkill(game.i18n.localize("NAME.Résistance"), {context : {failure : this.actor.name + " meurt de la Pourriture"}, fields: {difficulty}, appendTitle : " - Pourriture"}) let test = await this.actor.setupSkill(game.i18n.localize("NAME.Résistance"), {context : {failure : this.actor.name + " meurt de la Pourriture"}, fields: {difficulty}, appendTitle : " - Pourriture"})
await Test.roll(); await test.roll();
if (Test.Échoué) if (test.failed)
{ {
this.actor.addCondition("dead"); this.actor.addCondition("dead");
} }

View File

@@ -1,7 +1,7 @@
let test = await this.actor.setupCharacteristic("i", {skipTargets: true, appendTitle : ` - ${this.effect.name}`, fields : {difficulty : "easy"}}) let test = await this.actor.setupCharacteristic("i", {skipTargets: true, appendTitle : ` - ${this.effect.name}`, fields : {difficulty : "easy"}})
await Test.roll(); await test.roll();
if (!Test.succeeded) if (!test.succeeded)
{ {
this.actor.addCondition("stunned"); this.actor.addCondition("stunned");
} }

View File

@@ -1,7 +1,7 @@
let test = await this.actor.setupCharacteristic("ag", {fields : {difficulty : "hard"}}); let test = await this.actor.setupCharacteristic("ag", {fields : {difficulty : "hard"}});
await Test.roll(); await test.roll();
if (Test.Échoué) if (test.failed)
{ {
await this.actor.addCondition("bleeding") await this.actor.addCondition("bleeding")
await this.actor.addCondition("entangled") await this.actor.addCondition("entangled")

View File

@@ -9,8 +9,8 @@ if (SL >= 3)
let test = await args.actor.setupCharacteristic("wp", {fields: {difficulty}, skipTargets: true, appendTitle : " - " + this.effect.name, context : {failure: "Reçoit un état Sonné"}}) let test = await args.actor.setupCharacteristic("wp", {fields: {difficulty}, skipTargets: true, appendTitle : " - " + this.effect.name, context : {failure: "Reçoit un état Sonné"}})
await Test.roll(); await test.roll();
if (Test.Échoué) if (test.failed)
{ {
args.actor.addCondition("stunned"); args.actor.addCondition("stunned");
} }

View File

@@ -12,7 +12,7 @@ const test = await this.actor.setupCharacteristic("t", {
} }
}); });
await Test.roll(); await test.roll();
if (Test.failure) { if (test.failure) {
await this.actor.addCondition("prone"); await this.actor.addCondition("prone");
} }

View File

@@ -1,6 +1,6 @@
let test = await this.actor.setupSkill("Résistance", {fields : {difficulty : "difficult", appendTitle : ` - ${this.effect.name}`}}); let test = await this.actor.setupSkill("Résistance", {fields : {difficulty : "difficult", appendTitle : ` - ${this.effect.name}`}});
await Test.roll(); await test.roll();
if (Test.Échoué) if (test.failed)
{ {
await this.actor.addCondition("blinded"); await this.actor.addCondition("blinded");
} }

View File

@@ -1,8 +1,8 @@
let test = await this.actor.setupCharacteristic("wp", {skipTargets: true, appendTitle : ` - ${this.effect.name}`}) let test = await this.actor.setupCharacteristic("wp", {skipTargets: true, appendTitle : ` - ${this.effect.name}`})
await Test.roll(); await test.roll();
let opposedResult = Test.opposedMessages[0]?.system.opposedHandler?.resultMessage?.system.opposedTest?.result let opposedResult = test.opposedMessages[0]?.system.opposedHandler?.resultMessage?.system.opposedTest?.result
if (opposedResult?.winner == "attacker") if (opposedResult?.winner == "attacker")
{ {

View File

@@ -1,7 +1,7 @@
let test = await this.actor.setupCharacteristic("t", { appendTitle: ` - ${this.effect.name}`, fields: { difficulty: "challenging" } }) let test = await this.actor.setupCharacteristic("t", { appendTitle: ` - ${this.effect.name}`, fields: { difficulty: "challenging" } })
await Test.roll(); await test.roll();
if (Test.Échoué) if (test.failed)
{ {
let ageAdded = Math.ceil(CONFIG.Dice.randomUniform() * 10) + Math.ceil(CONFIG.Dice.randomUniform() * 10) let ageAdded = Math.ceil(CONFIG.Dice.randomUniform() * 10) + Math.ceil(CONFIG.Dice.randomUniform() * 10)
let ws = Math.ceil(CONFIG.Dice.randomUniform() * 10) let ws = Math.ceil(CONFIG.Dice.randomUniform() * 10)

View File

@@ -1,5 +1,5 @@
if (args.opposedTest.result.differenceSL >= 0 && args.opposedTest.result.differenceSL <= 2 && args.opposedTest.result.winner == "attacker") if (args.opposedTest.result.differenceSL >= 0 && args.opposedTest.result.differenceSL <= 2 && args.opposedTest.result.winner == "attacker")
{ {
this.script.message(`Becomes lodged in the armour or flesh of the opponent. See @UUID[${this.item.uuid}]{${this.item.name}}.`, speaker : {alias : this.item.name}, {blind: true, whisper : ChatMessage.getWhisperRecipients("GM")}) this.script.message(`Becomes lodged in the armour or flesh of the opponent. See @UUID[${this.item.uuid}]{${this.item.name}}.`, {speaker : {alias : this.item.name}, blind: true, whisper : ChatMessage.getWhisperRecipients("GM")})
} }

View File

@@ -1,7 +1,7 @@
let test = await this.actor.setupCharacteristic("wp", {skipTargets: true, appendTitle : ` - ${this.effect.name}`}) let test = await this.actor.setupCharacteristic("wp", {skipTargets: true, appendTitle : ` - ${this.effect.name}`})
await Test.roll(); await test.roll();
// Kind of insane but whatever // Kind of insane but whatever
let opposedResult = Test.opposedMessages[0]?.system.opposedHandler?.resultMessage?.system.opposedTest?.result let opposedResult = test.opposedMessages[0]?.system.opposedHandler?.resultMessage?.system.opposedTest?.result
return opposedResult?.winner == "attacker"; return opposedResult?.winner == "attacker";

View File

@@ -1,6 +1,6 @@
if (args.test.characteristicKey == "wp") if (args.test.characteristicKey == "wp")
{ {
if (args.Test.Échoué) if (args.test.failed)
{ {
let item = await fromUuid("Compendium.wfrp4e-core.items.AGcJl5rHjkyIQBPP") let item = await fromUuid("Compendium.wfrp4e-core.items.AGcJl5rHjkyIQBPP")
let data = item.toObject(); let data = item.toObject();

View File

@@ -1,9 +1,9 @@
let location = this.item.system.location.key let location = this.item.system.location.key
let test = await this.actor.setupCharacteristic("dex", {context : {failure : `<strong>${this.effect.name}</strong>: Lâchez l'objet!`}, skipTargets: true, appendTitle : " - " + this.effect.name, fields : {difficulty : "average"}}) let test = await this.actor.setupCharacteristic("dex", {context : {failure : `<strong>${this.effect.name}</strong>: Lâchez l'objet!`}, skipTargets: true, appendTitle : " - " + this.effect.name, fields : {difficulty : "average"}})
await Test.roll(); await test.roll();
if (location && Test.Échoué) if (location && test.failed)
{ {
let dropped = this.item.system.weaponsAtLocation; let dropped = this.item.system.weaponsAtLocation;

View File

@@ -1,6 +1,6 @@
if (args.test.characteristicKey == "wp") if (args.test.characteristicKey == "wp")
{ {
if (args.Test.Échoué) if (args.test.failed)
{ {
this.actor.createEmbeddedDocuments("ActiveEffect", [game.wfrp4e.config.symptomEffects["malaise"]]) this.actor.createEmbeddedDocuments("ActiveEffect", [game.wfrp4e.config.symptomEffects["malaise"]])
this.script.message(`Test de FM échoué, <b>${this.actor.prototypeToken.name}</b> gains @Condition[Malaise] for [[1d10]] hours`, {whisper: ChatMessage.getWhisperRecipients("GM")}) this.script.message(`Test de FM échoué, <b>${this.actor.prototypeToken.name}</b> gains @Condition[Malaise] for [[1d10]] hours`, {whisper: ChatMessage.getWhisperRecipients("GM")})

View File

@@ -1,6 +1,6 @@
let test = await this.actor.setupSkill(game.i18n.localize("NAME.Cool"), {appendTitle : ` - ${this.effect.name}`, fields : {difficulty : "difficult", slBonus : -1 * this.effect.sourceTest.result.SL}}) let test = await this.actor.setupSkill(game.i18n.localize("NAME.Cool"), {appendTitle : ` - ${this.effect.name}`, fields : {difficulty : "difficult", slBonus : -1 * this.effect.sourceTest.result.SL}})
await Test.roll(); await test.roll();
if (Test.succeeded) if (test.succeeded)
{ {
this.script.notification(`Résistance à ${this.effect.name}`); this.script.notification(`Résistance à ${this.effect.name}`);
} }

View File

@@ -1,8 +1,8 @@
if (args.totalWoundLoss > 0) if (args.totalWoundLoss > 0)
{ {
args.actor.setupCharacteristic("t", {skipTargets: true, appendTitle : ` - ${this.effect.name}`, fields: { difficulty: "difficult" } }).then(async Test => { args.actor.setupCharacteristic("t", {skipTargets: true, appendTitle : ` - ${this.effect.name}`, fields: { difficulty: "difficult" } }).then(async Test => {
await Test.roll(); await test.roll();
if (Test.Échoué) if (test.failed)
{ {
await args.actor.addCondition("poisoned") await args.actor.addCondition("poisoned")
this.script.message(await args.actor.applyBasicDamage(3, {suppressMsg : true, damageType: game.wfrp4e.config.DAMAGE_TYPE.IGNORE_ALL })) this.script.message(await args.actor.applyBasicDamage(3, {suppressMsg : true, damageType: game.wfrp4e.config.DAMAGE_TYPE.IGNORE_ALL }))

View File

@@ -1,6 +1,6 @@
let test = await this.actor.setupCharacteristic("t", {skipTargets: true, appendTitle : ` - ${this.effect.name}`, fields : {difficulty : "hard"}}) let test = await this.actor.setupCharacteristic("t", {skipTargets: true, appendTitle : ` - ${this.effect.name}`, fields : {difficulty : "hard"}})
await Test.roll(); await test.roll();
if (Test.Échoué) if (test.failed)
{ {
let roll = await new Roll("1d10").roll({allowInteractive : false}); let roll = await new Roll("1d10").roll({allowInteractive : false});
roll.toMessage(this.script.getChatData()) roll.toMessage(this.script.getChatData())

View File

@@ -1,2 +1,2 @@
args.totalWoundLoss = Math.max(0, args.totalWoundLoss - 1) args.totalWoundLoss = Math.max(0, args.totalWoundLoss - 1)
args.modifiers.other.push({label : this.effect.name, value : -1) args.modifiers.other.push({label : this.effect.name, value : -1})

View File

@@ -1,8 +1,8 @@
let test = await this.actor.setupCharacteristic("t", {skipTargets: true, appendTitle : ` - ${this.effect.name}`, fields : {difficulty : "vhard"}}); let test = await this.actor.setupCharacteristic("t", {skipTargets: true, appendTitle : ` - ${this.effect.name}`, fields : {difficulty : "vhard"}});
await Test.roll(); await test.roll();
CorruptionMessageModel.createCorruptionMessage("minor", this.script.getChatData()) CorruptionMessageModel.createCorruptionMessage("minor", this.script.getChatData())
if (Test.Échoué) if (test.failed)
{ {
this.actor.addCondition("unconscious"); this.actor.addCondition("unconscious");
} }

View File

@@ -1,6 +1,6 @@
if (!this.item.name.includes("(") || this.item.system.tests.value.includes("(Sense)") || this.item.system.tests.value.toLowerCase().includes("(any)")) if (!this.item.name.includes("(") || this.item.system.tests.value.includes("(Sense)") || this.item.system.tests.value.toLowerCase().includes("(any)"))
{ {
let Tests = this.item.system.tests.value let tests = this.item.system.tests.value
let name = this.item.name let name = this.item.name
// If name already specifies, make sure Tests value reflects that // If name already specifies, make sure Tests value reflects that

2009
tools/check-tests-log.txt Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

111
tools/check-tests.js Normal file
View File

@@ -0,0 +1,111 @@
import fs from 'node:fs';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const SCRIPTS_DIR = path.join(__dirname, '..', 'scripts');
const LOG_FILE = path.join(__dirname, 'check-tests-log.txt');
const log = [];
function writeLog(message) {
console.log(message);
log.push(message);
}
function getAllJsFiles(dir) {
const files = [];
function traverse(currentDir) {
const entries = fs.readdirSync(currentDir, { withFileTypes: true });
for (const entry of entries) {
const fullPath = path.join(currentDir, entry.name);
if (entry.isDirectory()) {
traverse(fullPath);
} else if (entry.isFile() && entry.name.endsWith('.js')) {
files.push(fullPath);
}
}
}
traverse(dir);
return files;
}
function checkForTests(filePath) {
const content = fs.readFileSync(filePath, 'utf-8');
return content.includes('let Tests');
}
// Programme principal
writeLog('='.repeat(60));
writeLog('VÉRIFICATION DE "let Tests" DANS LES SCRIPTS');
writeLog('='.repeat(60));
writeLog(`Date: ${new Date().toISOString()}`);
writeLog(`Répertoire: ${SCRIPTS_DIR}\n`);
const allFiles = getAllJsFiles(SCRIPTS_DIR);
writeLog(`Total de fichiers trouvés: ${allFiles.length}\n`);
const filesWithTests = [];
const filesWithoutTests = [];
allFiles.forEach(filePath => {
const relativePath = path.relative(path.join(__dirname, '..'), filePath);
if (checkForTests(filePath)) {
filesWithTests.push(relativePath);
} else {
filesWithoutTests.push(relativePath);
}
});
// Afficher les résultats
writeLog('=== FICHIERS CONTENANT "let Tests" ===\n');
if (filesWithTests.length > 0) {
filesWithTests.forEach(file => {
writeLog(`${file}`);
});
} else {
writeLog('Aucun fichier trouvé.');
}
writeLog(`\nTotal: ${filesWithTests.length} fichier(s)\n`);
writeLog('='.repeat(60));
writeLog('=== FICHIERS NE CONTENANT PAS "let Tests" ===\n');
if (filesWithoutTests.length > 0) {
filesWithoutTests.forEach(file => {
writeLog(`${file}`);
});
} else {
writeLog('Aucun fichier trouvé.');
}
writeLog(`\nTotal: ${filesWithoutTests.length} fichier(s)\n`);
writeLog('='.repeat(60));
writeLog('RÉSUMÉ');
writeLog('='.repeat(60));
writeLog(`Fichiers avec "let Tests": ${filesWithTests.length}`);
writeLog(`Fichiers sans "let Tests": ${filesWithoutTests.length}`);
writeLog(`Total de fichiers analysés: ${allFiles.length}`);
writeLog('='.repeat(60));
// Sauvegarder le log
fs.writeFileSync(LOG_FILE, log.join('\n'), 'utf-8');
writeLog(`\nLog sauvegardé dans: ${LOG_FILE}`);
// Exporter les résultats en JSON
const results = {
date: new Date().toISOString(),
totalFiles: allFiles.length,
filesWithTests: filesWithTests,
filesWithoutTests: filesWithoutTests
};
const resultsFile = path.join(__dirname, 'check-tests-results.json');
fs.writeFileSync(resultsFile, JSON.stringify(results, null, 2), 'utf-8');
writeLog(`Résultats sauvegardés dans: ${resultsFile}`);