24 Commits
v12 ... 13.0.13

Author SHA1 Message Date
fc6bb7a4b1 CSS rework et autres améliorations
All checks were successful
Release Creation / build (release) Successful in 46s
2026-02-12 23:08:51 +01:00
f26130d208 CSS rework et autres améliorations 2026-02-12 23:05:22 +01:00
39da08d4cb CSS rework et autres améliorations 2026-02-12 23:04:37 +01:00
e639b6ae3e Fix rollData = 1
All checks were successful
Release Creation / build (release) Successful in 3m36s
2025-12-01 17:57:19 +01:00
8c247a8981 Echec automatique sur 1
All checks were successful
Release Creation / build (release) Successful in 49s
2025-11-21 21:36:27 +01:00
a09e1a1d95 Les compétences de base ne peuvent être supprimées
All checks were successful
Release Creation / build (release) Successful in 47s
2025-11-02 18:30:20 +01:00
787f88873a Les compétences de base ne peuvent être supprimées 2025-11-02 18:29:46 +01:00
ac481e0dd9 Various minot fixes
All checks were successful
Release Creation / build (release) Successful in 1m18s
2025-10-30 20:24:24 +00:00
375622d900 Add welcome message 2025-10-17 15:31:32 +02:00
3bc055cc1f Add welcome message 2025-10-17 15:28:15 +02:00
c97b7a4889 Correction sur blessures et actions restantes
All checks were successful
Release Creation / build (release) Successful in 53s
2025-10-16 22:59:32 +02:00
5d13500838 Fix sur combat + mains gauche
All checks were successful
Release Creation / build (release) Successful in 43s
2025-09-24 16:43:52 +02:00
d21515e1e3 Fix sur combat + mains gauche 2025-09-24 16:43:40 +02:00
78ef009465 Fix sur combat + mains gauche 2025-09-24 16:42:08 +02:00
e794611bf3 Gestion assistée pour les actions
All checks were successful
Release Creation / build (release) Successful in 46s
2025-09-24 15:11:58 +02:00
529a62045e Gestion assistée pour les actions 2025-09-24 15:09:00 +02:00
d462d22a0a Manye enhancements for combat
All checks were successful
Release Creation / build (release) Successful in 42s
2025-09-18 17:26:02 +02:00
710ee54531 Manye enhancements for combat 2025-09-18 17:24:42 +02:00
7994aa7db4 Fix savoir lors de la creation de perso
All checks were successful
Release Creation / build (release) Successful in 1m30s
2025-09-08 23:47:19 +02:00
5176b4ce87 Amelioration histoire creation de perso, CSS bouton et genre de la providence
All checks were successful
Release Creation / build (release) Successful in 56s
2025-07-20 11:21:08 +02:00
3d6f195fc2 Educcation fix + CSS v13
All checks were successful
Release Creation / build (release) Successful in 43s
2025-07-02 23:08:34 +02:00
3693d68c24 Correction sur les compétences de base
All checks were successful
Release Creation / build (release) Successful in 1m0s
2025-06-04 15:29:32 +02:00
16ccd2f3e1 Foundry v13 migration 2025-05-09 10:28:22 +02:00
631eb280ca Foundry v13 migration
All checks were successful
Release Creation / build (release) Successful in 55s
2025-05-09 10:26:29 +02:00
113 changed files with 4599 additions and 2732 deletions

54
.gitignore vendored Normal file
View File

@@ -0,0 +1,54 @@
# Dependencies
node_modules/
package-lock.json
# Build outputs
styles/tedeum.css
styles/*.css.map
# IDE & Editor files
.vscode/
.idea/
*.swp
*.swo
*~
.DS_Store
# System files
Thumbs.db
desktop.ini
# Logs
npm-debug.log*
yarn-debug.log*
yarn-error.log*
*.log
# Temporary files
*.tmp
*.temp
.cache/
# Environment variables
.env
.env.local
# Optional: Uncomment if you want to ignore pack database files
# These are usually committed for systems, but can be regenerated
# packs/**/*.ldb
# packs/**/LOG
# packs/**/LOG.old
# packs/**/MANIFEST-*
# packs/**/CURRENT
# Compiled source
dist/
build/
# OS generated files
.DS_Store
.DS_Store?
._*
.Spotlight-V100
.Trashes
ehthumbs.db

View File

@@ -1,3 +1,7 @@
# 13.0.0
- Support de Foundry v13
# 12.0.23 # 12.0.23
- Correction sur les jets réussie en tir - Correction sur les jets réussie en tir

View File

@@ -1,25 +1,17 @@
var gulp = require('gulp'); var gulp = require('gulp');
var less = require('gulp-less');
var postcss = require('gulp-postcss'); var postcss = require('gulp-postcss');
var autoprefixer = require('autoprefixer'); var autoprefixer = require('autoprefixer');
var cssnext = require('postcss-preset-env');
var precss = require('precss');
gulp.task('css', function () { gulp.task('css', function () {
return gulp.src('./less/*.less')
var processors = [ .pipe(less())
autoprefixer, .pipe(postcss([autoprefixer]))
cssnext,
precss
];
return gulp.src('./postcss/*.css')
.pipe(postcss(processors))
.pipe(gulp.dest('./styles')); .pipe(gulp.dest('./styles'));
}); });
gulp.task('watch', function () {
gulp.watch('./less/*.less', gulp.series('css'));
});
function watchUpdates() { gulp.task('default', gulp.series('css'));
gulp.watch('./postcss/*.css', css);
}

BIN
images/icons/xpplus1.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

2071
less/tedeum.less Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -6,7 +6,7 @@
import { TeDeumUtility } from "../common/tedeum-utility.js"; import { TeDeumUtility } from "../common/tedeum-utility.js";
/* -------------------------------------------- */ /* -------------------------------------------- */
export class TeDeumActorPJSheet extends ActorSheet { export class TeDeumActorPJSheet extends foundry.appv1.sheets.ActorSheet {
/** @override */ /** @override */
static get defaultOptions() { static get defaultOptions() {
@@ -15,7 +15,7 @@ export class TeDeumActorPJSheet extends ActorSheet {
classes: ["fvtt-te-deum", "sheet", "actor"], classes: ["fvtt-te-deum", "sheet", "actor"],
template: "systems/fvtt-te-deum/templates/actors/actor-sheet.hbs", template: "systems/fvtt-te-deum/templates/actors/actor-sheet.hbs",
width: 860, width: 860,
height:680, height: 680,
tabs: [{ navSelector: ".sheet-tabs", contentSelector: ".sheet-body", initial: "skills" }], tabs: [{ navSelector: ".sheet-tabs", contentSelector: ".sheet-body", initial: "skills" }],
dragDrop: [{ dragSelector: ".item-list .item", dropSelector: null }], dragDrop: [{ dragSelector: ".item-list .item", dropSelector: null }],
editScore: true editScore: true
@@ -56,10 +56,10 @@ export class TeDeumActorPJSheet extends ActorSheet {
nbArmuresLourdes: this.actor.getNbArmuresLourdesActuel(), nbArmuresLourdes: this.actor.getNbArmuresLourdesActuel(),
santeModifier: this.actor.getSanteModifier(), santeModifier: this.actor.getSanteModifier(),
educations: this.actor.getEducations(), educations: this.actor.getEducations(),
description: await TextEditor.enrichHTML(this.object.system.description, { async: true }), description: await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.object.system.description, { async: true }),
equipmentfree: await TextEditor.enrichHTML(this.object.system.equipmentfree, { async: true }), equipmentfree: await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.object.system.equipmentfree, { async: true }),
notes: await TextEditor.enrichHTML(this.object.system.notes, { async: true }), notes: await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.object.system.notes, { async: true }),
histoire: await TextEditor.enrichHTML(this.object.system.histoire, { async: true }), histoire: await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.object.system.histoire, { async: true }),
options: this.options, options: this.options,
owner: this.document.isOwner, owner: this.document.isOwner,
editScore: this.options.editScore, editScore: this.options.editScore,
@@ -67,7 +67,6 @@ export class TeDeumActorPJSheet extends ActorSheet {
} }
this.formData = formData; this.formData = formData;
console.log("PC : ", formData, this.object);
return formData; return formData;
} }
@@ -80,7 +79,7 @@ export class TeDeumActorPJSheet extends ActorSheet {
// Everything below here is only needed if the sheet is editable // Everything below here is only needed if the sheet is editable
if (!this.options.editable) return; if (!this.options.editable) return;
html.bind("keydown", function(e) { // Ignore Enter in actores sheet html.bind("keydown", function (e) { // Ignore Enter in actores sheet
if (e.keyCode === 13) return false; if (e.keyCode === 13) return false;
}); });
@@ -88,7 +87,7 @@ export class TeDeumActorPJSheet extends ActorSheet {
html.find('.item-edit').click(ev => { html.find('.item-edit').click(ev => {
const li = $(ev.currentTarget).parents(".item-id") const li = $(ev.currentTarget).parents(".item-id")
let itemId = li.data("item-id") let itemId = li.data("item-id")
const item = this.actor.items.get( itemId ); const item = this.actor.items.get(itemId);
item.sheet.render(true); item.sheet.render(true);
}); });
// Delete Inventory Item // Delete Inventory Item
@@ -100,16 +99,20 @@ export class TeDeumActorPJSheet extends ActorSheet {
let dataType = $(ev.currentTarget).data("type") let dataType = $(ev.currentTarget).data("type")
this.actor.createEmbeddedDocuments('Item', [{ name: "Nouveau " + dataType, type: dataType }], { renderSheet: true }) this.actor.createEmbeddedDocuments('Item', [{ name: "Nouveau " + dataType, type: dataType }], { renderSheet: true })
}) })
html.find('.blessure-add').click(ev => {
let dataType = $(ev.currentTarget).data("type")
this.actor.createEmbeddedDocuments('Item', [{ name: "Nouvelle " + dataType, type: dataType, system: { typeBlessure: "estafilade", localisation: "corps", value: 0, appliquee: true, description: "" } }], { renderSheet: true })
})
html.find('.competence-add').click(ev => { html.find('.competence-add').click(ev => {
let dataType = $(ev.currentTarget).data("type") let dataType = $(ev.currentTarget).data("type")
let caracKey = $(ev.currentTarget).data("carac-key") let caracKey = $(ev.currentTarget).data("carac-key")
this.actor.createEmbeddedDocuments('Item', [{ name: "Nouvelle " + dataType, type: dataType, system: {caracteristique: caracKey} }], { renderSheet: true }) this.actor.createEmbeddedDocuments('Item', [{ name: "Nouvelle " + dataType, type: dataType, system: { caracteristique: caracKey } }], { renderSheet: true })
}) })
html.find('.subactor-edit').click(ev => { html.find('.subactor-edit').click(ev => {
const li = $(ev.currentTarget).parents(".item"); const li = $(ev.currentTarget).parents(".item");
let actorId = li.data("actor-id"); let actorId = li.data("actor-id");
let actor = game.actors.get( actorId ); let actor = game.actors.get(actorId);
actor.sheet.render(true); actor.sheet.render(true);
}); });
@@ -120,12 +123,12 @@ export class TeDeumActorPJSheet extends ActorSheet {
}); });
html.find('.quantity-minus').click(event => { html.find('.quantity-minus').click(event => {
const li = $(event.currentTarget).parents(".item"); const li = $(event.currentTarget).parents(".item");
this.actor.incDecQuantity( li.data("item-id"), -1 ); this.actor.incDecQuantity(li.data("item-id"), -1);
} ); });
html.find('.quantity-plus').click(event => { html.find('.quantity-plus').click(event => {
const li = $(event.currentTarget).parents(".item"); const li = $(event.currentTarget).parents(".item");
this.actor.incDecQuantity( li.data("item-id"), +1 ); this.actor.incDecQuantity(li.data("item-id"), +1);
} ); });
html.find('.roll-competence').click((event) => { html.find('.roll-competence').click((event) => {
let compId = $(event.currentTarget).data("comp-id") let compId = $(event.currentTarget).data("comp-id")
@@ -147,13 +150,13 @@ export class TeDeumActorPJSheet extends ActorSheet {
}); });
html.find('.item-equip').click(ev => { html.find('.item-equip').click(ev => {
const li = $(ev.currentTarget).parents(".item"); const li = $(ev.currentTarget).parents(".item");
this.actor.equipItem( li.data("item-id") ); this.actor.equipItem(li.data("item-id"));
this.render(true); this.render(true);
}); });
html.find('.update-field').change(ev => { html.find('.update-field').change(ev => {
const fieldName = $(ev.currentTarget).data("field-name"); const fieldName = $(ev.currentTarget).data("field-name");
let value = Number(ev.currentTarget.value); let value = Number(ev.currentTarget.value);
this.actor.update( { [`${fieldName}`]: value } ); this.actor.update({ [`${fieldName}`]: value });
}); });
} }

View File

@@ -34,7 +34,7 @@ export class TeDeumActor extends Actor {
return actor; return actor;
} }
if (data.type == 'pj' || data.type == 'pnj') { if (data.type == 'pj' || data.type == 'pnj') {
const skills = await TeDeumUtility.loadCompendium("fvtt-te-deum.competences") const skills = await TeDeumUtility.loadCompendium("fvtt-te-deum.competences")
data.items = data.items || [] data.items = data.items || []
for (let skill of skills) { for (let skill of skills) {
@@ -65,14 +65,43 @@ export class TeDeumActor extends Actor {
super._preUpdate(changed, options, user); super._preUpdate(changed, options, user);
} }
/* -------------------------------------------- */
getCompetenceScore(compName) { getCompetenceScore(compName) {
let competence = this.items.find(item => item.type == "competence" && item.name.toLowerCase() == compName.toLowerCase()) let competence = this.items.find(item => item.type == "competence" && item.name.toLowerCase() == compName.toLowerCase())
if (competence) { if (competence) {
if (competence.system.isBase) {
return this.system.caracteristiques[competence.system.caracteristique].value
}
return competence.system.score return competence.system.score
} }
return 0 return 0
} }
/* -------------------------------------------- */
getMeilleureCompetenceMainGauche(comp) {
let compScore = this.getCompetenceScore(comp.name)
let mainGaucheScore = this.getCompetenceScore("main gauche")
if (mainGaucheScore < compScore) {
ui.notifications.info(`${this.name} : Utilisation de la compétence Main Gauche au lieu de ${comp.name}`)
let mainGaucheComp = this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "main gauche")
if (!mainGaucheComp) {
// Create a fake competence object
mainGaucheComp = foundry.utils.duplicate(comp)
mainGaucheComp.name = "Main Gauche"
mainGaucheComp.system.isBase = false
mainGaucheComp.system.score = 0
mainGaucheComp.system.caracteristique = "adresse"
mainGaucheComp.system.description = "Compétence Main Gauche (automatique)"
mainGaucheComp.system.isMainGauche = true
return mainGaucheComp
} else {
return mainGaucheComp
}
} else {
return comp
}
}
/* -------------------------------------------- */ /* -------------------------------------------- */
_onUpdate(changed, options, userId) { _onUpdate(changed, options, userId) {
let updates = [] let updates = []
@@ -112,12 +141,6 @@ export class TeDeumActor extends Actor {
updates.push({ _id: initiative.id, "system.score": Number(newScore) }) updates.push({ _id: initiative.id, "system.score": Number(newScore) })
} }
let actionsTour = this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "actions/tour")
newScore = this.getCommonBaseValue(this.system.caracteristiques.adresse.value)
if (actionsTour && actionsTour?.system.score != newScore) {
updates.push({ _id: actionsTour.id, "system.score": Number(newScore) })
}
let effort = this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "effort") let effort = this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "effort")
newScore = this.getCommonBaseValue(this.system.caracteristiques.puissance.value) newScore = this.getCommonBaseValue(this.system.caracteristiques.puissance.value)
if (effort && effort?.system.score != newScore) { if (effort && effort?.system.score != newScore) {
@@ -147,7 +170,7 @@ export class TeDeumActor extends Actor {
getCommonBaseValue(value) { getCommonBaseValue(value) {
return game.system.tedeum.config.COMMON_VALUE[value]?.value || 0 return game.system.tedeum.config.COMMON_VALUE[value]?.value || 0
} }
getInitiative() { getInitiativeValue() {
return game.system.tedeum.config.COMMON_VALUE[this.system.caracteristiques.adresse.value]?.value || 0 return game.system.tedeum.config.COMMON_VALUE[this.system.caracteristiques.adresse.value]?.value || 0
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
@@ -155,6 +178,24 @@ export class TeDeumActor extends Actor {
return game.system.tedeum.config.BONUS_DEGATS[this.system.caracteristiques.puissance.value] return game.system.tedeum.config.BONUS_DEGATS[this.system.caracteristiques.puissance.value]
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
getAttaqueBonusDegats(rollData = undefined) {
let base = game.system.tedeum.config.BONUS_DEGATS[this.system.caracteristiques.puissance.value].value
let additionalBonus = 0
if (rollData) {
// Spécificité armes naturelle avec gantelet
if (rollData?.arme?.system.specificites?.poing?.hasSpec && this.items.find(item => item.type == "armure" && item.name.toLowerCase() == "gantelet" && item.system.equipe)) {
additionalBonus += 1
rollData.gantelet = true
}
if (rollData.isChargeAPied) {
additionalBonus += this.getCompetenceScore("course")
} else if (rollData.isChargeACheval) {
additionalBonus += this.getCompetenceScore("equitation")
}
}
return base + additionalBonus
}
/* -------------------------------------------- */
getNbArmures() { getNbArmures() {
return game.system.tedeum.config.MAX_ARMURES_LOURDES[this.system.caracteristiques.puissance.value] return game.system.tedeum.config.MAX_ARMURES_LOURDES[this.system.caracteristiques.puissance.value]
} }
@@ -266,41 +307,105 @@ export class TeDeumActor extends Actor {
modTotal += blessDef.modifier modTotal += blessDef.modifier
} }
// Si le nombre de blessures est supérieur au score d'endurance, alors malus supplémentaire // Si le nombre de blessures est supérieur au score d'endurance, alors malus supplémentaire
let endurance = this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "endurance") let enduranceScore = this.getCompetenceScore("endurance")
if (blessures.length > endurance.system.score) { if (blessures.length > enduranceScore) {
modTotal += -1 modTotal += -1
} }
return modTotal return modTotal
} }
/* -------------------------------------------- */
async appliquerBlessure(blessureId, locId, comment = "") {
let blessure = game.system.tedeum.config.blessures[blessureId]
if (!blessure) {
ui.notifications.warn("Type de blessure inconnu : " + blessureId)
console.error("Type de blessure inconnu : " + blessureId)
return
}
// Create a new blessure object
let blessureObj = {
name: blessure.label,
type: "blessure",
system: {
typeBlessure: blessureId,
localisation: locId || "maindroite",
value: blessure.value,
appliquee: true,
description: comment,
}
}
this.createEmbeddedDocuments('Item', [blessureObj]);
}
/* -------------------------------------------- */
getArmorDegatsModifier(rollData, combat) {
let loc = combat[rollData.loc.id]
// Sans armure
if (loc.armures.length == 0) {
return rollData.arme.system.degatsArmure.sansarmure
}
// Avec armure de cuir
if (loc.armures.find(a => a.system.typeArmure == "cuir")) {
return rollData.arme.system.degatsArmure.cuir
}
// Avec armure de maille
if (loc.armures.find(a => a.system.typeArmure == "maille")) {
return rollData.arme.system.degatsArmure.mailles
}
// Avec armure de plate
if (loc.armures.find(a => a.system.typeArmure == "plate")) {
return rollData.arme.system.degatsArmure.plates
}
return 0
}
/* -------------------------------------------- */ /* -------------------------------------------- */
async appliquerDegats(rollData) { async appliquerDegats(rollData) {
let combat = this.prepareCombat() let combat = this.prepareCombat()
rollData.defenderName = this.name rollData.defenderName = this.name
let touche = combat[rollData.loc.id].touche let touche = combat[rollData.loc.id].touche
let armorDegatModifier = this.getArmorDegatsModifier(rollData, combat)
rollData.degats += armorDegatModifier
rollData.armorDegatModifier = armorDegatModifier
let blessureId = "indemne"
if (rollData.degats > 0 && rollData.degats > touche) { if (rollData.degats > 0 && rollData.degats > touche) {
let diff = rollData.degats - touche let diff = rollData.degats - touche
for (let bId in game.system.tedeum.config.blessures) { for (let bId in game.system.tedeum.config.blessures) {
let blessure = game.system.tedeum.config.blessures[bId] let blessure = game.system.tedeum.config.blessures[bId]
if (diff >= blessure.degatsMin && diff <= blessure.degatsMax) { if (diff >= blessure.degatsMin && diff <= blessure.degatsMax) {
// Create a new blessure object if (rollData.isReussiteCritique) {
let blessureObj = { bId = game.system.tedeum.config.blessuresOrder[blessure.value + 1]
name: blessure.label,
type: "blessure",
system: {
typeBlessure: bId,
localisation: rollData.loc.id,
appliquee: true,
description: "Blessure infligée par un coup de " + rollData.arme.name + " de " + rollData.alias,
}
} }
rollData.blessure = blessureObj blessureId = bId
this.createEmbeddedDocuments('Item', [blessureObj]); break
} }
} }
} }
if (rollData.isReussiteCritique && blessureId == "indemne") { // Critical success without degats => lightest blessure
blessureId = "estafilade"
}
console.log("Appliquer dégats", rollData, combat, blessureId)
if (blessureId != "indemne") {
let blessure = game.system.tedeum.config.blessures[blessureId]
// Create a new blessure object
let blessureObj = {
name: blessure.label,
type: "blessure",
system: {
typeBlessure: blessureId,
localisation: rollData.loc.id,
value: blessure.value,
appliquee: true,
description: "Blessure infligée par un coup de " + rollData.arme.name + " de " + rollData.alias,
}
}
rollData.blessure = blessureObj
rollData.touche = touche
this.createEmbeddedDocuments('Item', [blessureObj]);
}
// Display the relevant chat message // Display the relevant chat message
let msg = await TeDeumUtility.createChatWithRollMode(rollData.alias, { let msg = await TeDeumUtility.createChatWithRollMode(rollData.alias, {
content: await renderTemplate(`systems/fvtt-te-deum/templates/chat/chat-blessure-result.hbs`, rollData) content: await foundry.applications.handlebars.renderTemplate(`systems/fvtt-te-deum/templates/chat/chat-blessure-result.hbs`, rollData)
}) })
await msg.setFlag("world", "te-deum-rolldata", rollData) await msg.setFlag("world", "te-deum-rolldata", rollData)
} }
@@ -334,7 +439,7 @@ export class TeDeumActor extends Actor {
let providence = foundry.utils.deepClone(this.system.providence) let providence = foundry.utils.deepClone(this.system.providence)
providence.name = "Providence" providence.name = "Providence"
if (this.system.genre.toLowerCase() == "homme") { if (this.system.genre.toLowerCase() == "homme") {
providence.qualite = game.system.tedeum.config.providence[providence.value].labelH providence.qualite = game.system.tedeum.config.providence[providence.value].labelM
} else { } else {
providence.qualite = game.system.tedeum.config.providence[providence.value].labelF providence.qualite = game.system.tedeum.config.providence[providence.value].labelF
} }
@@ -382,6 +487,7 @@ export class TeDeumActor extends Actor {
xp = Math.max(xp + value, 0) xp = Math.max(xp + value, 0)
await this.update({ [`system.caracteristiques.${key}.experience`]: xp }) await this.update({ [`system.caracteristiques.${key}.experience`]: xp })
this.sheet?.render(true) this.sheet?.render(true)
ui.notifications.info(`+${value} XP en ${game.system.tedeum.config.caracteristiques[key].label}`)
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
@@ -454,7 +560,7 @@ export class TeDeumActor extends Actor {
flag = armure.system.superposableCuir flag = armure.system.superposableCuir
} }
if (item.system.typeArmure == "maille") { if (item.system.typeArmure == "maille") {
flag = armure.system.superposableMaille flag = armure.system.superposableMaille
} }
if (item.system.typeArmure == "plate") { if (item.system.typeArmure == "plate") {
flag = armure.system.superposablePlate flag = armure.system.superposablePlate
@@ -529,12 +635,16 @@ export class TeDeumActor extends Actor {
/* -------------------------------------------- */ /* -------------------------------------------- */
getInitiativeScore() { getInitiativeScore() {
let initiative = this.items.find(it => it.type == "competence" && it.name.toLowerCase() == "initiative") let initiative = this.getInitiativeValue()
if (initiative) { // Vérifie les armes avec bonus d'initiative
return initiative.system.score let armes = this.getArmes()
for (let arme of armes) {
if (arme.system.equipe && Number(arme.system.initiativeBonus) && Number(arme.system.initiativeBonus) != 0) {
ui.notifications.info("L'arme " + arme.name + " vous confère un bonus d'initiative de " + arme.system.initiativeBonus)
initiative += arme.system.initiativeBonus
}
} }
ui.notifications.warn("Impossible de trouver la compétence Initiative pour l'acteur " + this.name) return initiative
return -1;
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
@@ -595,6 +705,7 @@ export class TeDeumActor extends Actor {
let rollData = this.getCommonCompetence(compId) let rollData = this.getCommonCompetence(compId)
rollData.mode = "competence" rollData.mode = "competence"
rollData.title = rollData.competence.name rollData.title = rollData.competence.name
rollData.compScore = rollData.competence.system.isBase ? this.system.caracteristiques[rollData.competence.system.caracteristique].value : rollData.competence.system.score
this.startRoll(rollData).catch("Error on startRoll") this.startRoll(rollData).catch("Error on startRoll")
} }
@@ -602,13 +713,13 @@ export class TeDeumActor extends Actor {
async rollDegatsArme(armeId) { async rollDegatsArme(armeId) {
let weapon = this.items.get(armeId) let weapon = this.items.get(armeId)
if (weapon) { if (weapon) {
let bDegats = 0 let bDegats = { value: 0 }
if ( weapon.system.typeArme == "melee" ) { if (weapon.system.typeArme == "melee") {
bDegats = this.getBonusDegats() bDegats = this.getBonusDegats()
} }
let formula = weapon.system.degats + "+" + bDegats.value let formula = weapon.system.degats + "+" + bDegats.value
let degatsRoll = await new Roll(formula).roll() let degatsRoll = await new Roll(formula).roll()
await TeDeumUtility.showDiceSoNice(degatsRoll, game.settings.get("core", "rollMode") ) await TeDeumUtility.showDiceSoNice(degatsRoll, game.settings.get("core", "rollMode"))
let rollData = this.getCommonRollData() let rollData = this.getCommonRollData()
rollData.mode = "degats" rollData.mode = "degats"
rollData.formula = formula rollData.formula = formula
@@ -617,7 +728,7 @@ export class TeDeumActor extends Actor {
rollData.degats = degatsRoll.total rollData.degats = degatsRoll.total
let msg = await TeDeumUtility.createChatWithRollMode(rollData.alias, { let msg = await TeDeumUtility.createChatWithRollMode(rollData.alias, {
content: await renderTemplate(`systems/fvtt-te-deum/templates/chat/chat-degats-result.hbs`, rollData) content: await foundry.applications.handlebars.renderTemplate(`systems/fvtt-te-deum/templates/chat/chat-degats-result.hbs`, rollData)
}) })
await msg.setFlag("world", "te-deum-rolldata", rollData) await msg.setFlag("world", "te-deum-rolldata", rollData)
console.log("Rolldata result", rollData) console.log("Rolldata result", rollData)
@@ -653,9 +764,14 @@ export class TeDeumActor extends Actor {
let competence = this.items.find(item => item.type == "competence" && item.name.toLowerCase() == compName.toLowerCase()) let competence = this.items.find(item => item.type == "competence" && item.name.toLowerCase() == compName.toLowerCase())
if (competence) { if (competence) {
rollData.competence = competence rollData.competence = competence
rollData.compScore = rollData.competence.system.isBase ? this.system.caracteristiques[rollData.competence.system.caracteristique].value : rollData.competence.system.score
let c = foundry.utils.duplicate(this.system.caracteristiques[competence.system.caracteristique]) let c = foundry.utils.duplicate(this.system.caracteristiques[competence.system.caracteristique])
this.updateCarac(c, competence.system.caracteristique) this.updateCarac(c, competence.system.caracteristique)
rollData.carac = c rollData.carac = c
rollData.allongeLabel = game.system.tedeum.config.armeAllonges[weapon.system.allonge].label
rollData.allongeId = "courte"
rollData.allonges = foundry.utils.duplicate(game.system.tedeum.config.allonges[weapon.system.allonge])
} else { } else {
ui.notifications.warn("Impossible de trouver la compétence " + compName) ui.notifications.warn("Impossible de trouver la compétence " + compName)
return return

View File

@@ -6,13 +6,14 @@ export class TeDeumCharacterCreator {
async init() { async init() {
this.stages = {} this.stages = {}
this.currentStage = "origineSociale" this.currentStage = "origineSociale"
this.sex = undefined this.sexe = undefined
this.origineSociale = undefined this.origineSociale = undefined
this.religion = undefined this.religion = undefined
this.caracBonus = {} this.caracBonus = {}
this.competenceBonus = {} this.competenceBonus = {}
this.suiviReponses = [] this.suiviReponses = []
this.competences = TeDeumUtility.getCompetencesForDropDown() this.competences = TeDeumUtility.getCompetencesForDropDown()
this.choiceSummary = {}
for (let k in game.system.tedeum.config.caracteristiques) { for (let k in game.system.tedeum.config.caracteristiques) {
this.caracBonus[k] = { value: 0 } this.caracBonus[k] = { value: 0 }
@@ -39,6 +40,7 @@ export class TeDeumCharacterCreator {
} else { } else {
this.competenceBonus[compName].value += 1 this.competenceBonus[compName].value += 1
} }
this.choiceSummary[this.currentStage].competences[compName] = 1
} }
/*--------------------------------------------*/ /*--------------------------------------------*/
@@ -69,7 +71,7 @@ export class TeDeumCharacterCreator {
/*--------------------------------------------*/ /*--------------------------------------------*/
async askStageName(context) { async askStageName(context) {
const content = await renderTemplate("systems/fvtt-te-deum/templates/dialogs/character-creator-select-stage-name.hbs", context) const content = await foundry.applications.handlebars.renderTemplate("systems/fvtt-te-deum/templates/dialogs/character-creator-select-stage-name.hbs", context)
const choiceResult = await foundry.applications.api.DialogV2.wait({ const choiceResult = await foundry.applications.api.DialogV2.wait({
window: { title: context.title }, window: { title: context.title },
classes: ["fvtt-te-deum"], classes: ["fvtt-te-deum"],
@@ -116,6 +118,7 @@ export class TeDeumCharacterCreator {
/*--------------------------------------------*/ /*--------------------------------------------*/
async askQuestionnaire(stage, context) { async askQuestionnaire(stage, context) {
context.subtitle = "Questionnaire" context.subtitle = "Questionnaire"
this.choiceSummary[this.currentStage].questionnaire = {}
for (let key in stage.system.questionnaire) { for (let key in stage.system.questionnaire) {
let question = stage.system.questionnaire[key] let question = stage.system.questionnaire[key]
@@ -127,7 +130,7 @@ export class TeDeumCharacterCreator {
context.competences = {} context.competences = {}
context.responseKey = "reponse1" // By default context.responseKey = "reponse1" // By default
const content = await renderTemplate("systems/fvtt-te-deum/templates/dialogs/character-creator-select-questions.hbs", context) const content = await foundry.applications.handlebars.renderTemplate("systems/fvtt-te-deum/templates/dialogs/character-creator-select-questions.hbs", context)
const choiceResult = await foundry.applications.api.DialogV2.wait({ const choiceResult = await foundry.applications.api.DialogV2.wait({
window: { title: context.title }, window: { title: context.title },
classes: ["fvtt-te-deum"], classes: ["fvtt-te-deum"],
@@ -170,13 +173,14 @@ export class TeDeumCharacterCreator {
let compName = context.competences[context.responseKey] || selectedResponse.compName let compName = context.competences[context.responseKey] || selectedResponse.compName
this.increaseCompetence(compName) this.increaseCompetence(compName)
this.suiviReponses.push({ etape: stage.name, question: question.question, reponse: selectedResponse.reponse, compName: compName }) this.suiviReponses.push({ key: this.currentStage, etape: stage.name, question: question.question, reponse: selectedResponse.reponse, compName: compName })
} }
} }
/*------------- -------------------------------*/ /*------------- -------------------------------*/
async askCompetences(stage, context) { async askCompetences(stage, context) {
context.subtitle = "Choix des Compétences" context.subtitle = "Choix des Compétences"
this.choiceSummary[this.currentStage].competences = {}
context.fixedCompetences = {} context.fixedCompetences = {}
context.selectCompetences = {} context.selectCompetences = {}
@@ -192,7 +196,7 @@ export class TeDeumCharacterCreator {
} }
} }
const content = await renderTemplate("systems/fvtt-te-deum/templates/dialogs/character-creator-select-competences.hbs", context) const content = await foundry.applications.handlebars.renderTemplate("systems/fvtt-te-deum/templates/dialogs/character-creator-select-competences.hbs", context)
const choiceResult = await foundry.applications.api.DialogV2.wait({ const choiceResult = await foundry.applications.api.DialogV2.wait({
window: { title: context.title }, window: { title: context.title },
classes: ["fvtt-te-deum"], classes: ["fvtt-te-deum"],
@@ -236,7 +240,7 @@ export class TeDeumCharacterCreator {
} }
} }
const content = await renderTemplate("systems/fvtt-te-deum/templates/dialogs/character-creator-select-competences.hbs", context) const content = await foundry.applications.handlebars.renderTemplate("systems/fvtt-te-deum/templates/dialogs/character-creator-select-competences.hbs", context)
const choiceResult = await foundry.applications.api.DialogV2.wait({ const choiceResult = await foundry.applications.api.DialogV2.wait({
window: { title: context.title }, window: { title: context.title },
classes: ["fvtt-te-deum"], classes: ["fvtt-te-deum"],
@@ -273,6 +277,10 @@ export class TeDeumCharacterCreator {
/*------------- -------------------------------*/ /*------------- -------------------------------*/
async askCarac(stage, context) { async askCarac(stage, context) {
context.subtitle = "Choix des Caractéristiques" context.subtitle = "Choix des Caractéristiques"
this.choiceSummary[this.currentStage] = {
caracBonus : {},
competences : {}
}
let selected = [] let selected = []
for (let i = 0; i < stage.system.nbChoixCarac; i++) { for (let i = 0; i < stage.system.nbChoixCarac; i++) {
@@ -283,7 +291,7 @@ export class TeDeumCharacterCreator {
context.caracList.push(game.system.tedeum.config.caracteristiques[carac.caracId]) context.caracList.push(game.system.tedeum.config.caracteristiques[carac.caracId])
} }
const content = await renderTemplate("systems/fvtt-te-deum/templates/dialogs/character-creator-select-carac.hbs", context) const content = await foundry.applications.handlebars.renderTemplate("systems/fvtt-te-deum/templates/dialogs/character-creator-select-carac.hbs", context)
const choiceResult = await foundry.applications.api.DialogV2.wait({ const choiceResult = await foundry.applications.api.DialogV2.wait({
window: { title: context.title }, window: { title: context.title },
classes: ["fvtt-te-deum"], classes: ["fvtt-te-deum"],
@@ -312,6 +320,7 @@ export class TeDeumCharacterCreator {
} }
this.caracBonus[choiceResult.carac].value += 1 this.caracBonus[choiceResult.carac].value += 1
selected.push(choiceResult.carac) selected.push(choiceResult.carac)
this.choiceSummary[this.currentStage].caracBonus[choiceResult.carac] = 1
} }
} }
@@ -325,7 +334,7 @@ export class TeDeumCharacterCreator {
origineChoice: game.system.tedeum.config.origineSociale origineChoice: game.system.tedeum.config.origineSociale
} }
const content = await renderTemplate("systems/fvtt-te-deum/templates/dialogs/character-creator-origine.hbs", context) const content = await foundry.applications.handlebars.renderTemplate("systems/fvtt-te-deum/templates/dialogs/character-creator-origine.hbs", context)
const label = "Valider le choix de l'Origine Sociale" const label = "Valider le choix de l'Origine Sociale"
const choiceResult = await foundry.applications.api.DialogV2.wait({ const choiceResult = await foundry.applications.api.DialogV2.wait({
window: { title: context.title }, window: { title: context.title },
@@ -360,6 +369,12 @@ export class TeDeumCharacterCreator {
for (let key in this.origineSociale.caracteristiques) { for (let key in this.origineSociale.caracteristiques) {
this.caracBonus[key].value += this.origineSociale.caracteristiques[key] this.caracBonus[key].value += this.origineSociale.caracteristiques[key]
} }
this.choiceSummary['origineSociale'] = {
sexe: this.sexe,
religion: this.religion,
origineSociale: this.origineSociale.label,
caracBonus: this.caracBonus,
}
this.currentStage = "pouponniere" this.currentStage = "pouponniere"
} }
@@ -388,6 +403,7 @@ export class TeDeumCharacterCreator {
this.pouponniere = foundry.utils.duplicate(stage.items.find(item => item.id === choiceResult.selectedItem)) this.pouponniere = foundry.utils.duplicate(stage.items.find(item => item.id === choiceResult.selectedItem))
context.title = `La Pouponnière - ${this.pouponniere.name}` context.title = `La Pouponnière - ${this.pouponniere.name}`
TeDeumUtility.prepareEducationContent(this.pouponniere); TeDeumUtility.prepareEducationContent(this.pouponniere);
this.choiceSummary['pouponniere'] = {}
context.label = "Valider l'augmentation de caracteristique" context.label = "Valider l'augmentation de caracteristique"
await this.askCarac(this.pouponniere, context) await this.askCarac(this.pouponniere, context)
@@ -581,8 +597,36 @@ export class TeDeumCharacterCreator {
await actor.update({ [`system.fortune.${this.origineSociale.cagnotteUnit}`]: newArgent}) await actor.update({ [`system.fortune.${this.origineSociale.cagnotteUnit}`]: newArgent})
let histoire = "" let histoire = ""
for (let reponse of this.suiviReponses) { for ( let key in this.choiceSummary) {
histoire += `<p>${reponse.question}<br>${reponse.reponse} (${reponse.compName})</p>` let stageSummary = this.choiceSummary[key]
if (stageSummary.sexe) {
histoire += `<h3>Origine Sociale</h3>`
histoire += `<p>${stageSummary.sexe} - ${stageSummary.religion} - ${stageSummary.origineSociale}</p>`
} else {
histoire += `<h3>${game.system.tedeum.config.etapesEducation[key].label}</h3>`
}
if (stageSummary.caracBonus) {
histoire += `<p><strong>Caractéristiques : </strong><ul>`
for (let caracKey in stageSummary.caracBonus) {
histoire += `<li>${TeDeumUtility.upperFirst(caracKey)} +1</li>`
}
histoire += `</ul></p>`
}
if (stageSummary.competences) {
histoire += `<p><strong>Compétences : </strong><ul>`
for (let compName in stageSummary.competences) {
histoire += `<li>${TeDeumUtility.upperFirst(compName)} +1</li>`
}
histoire += `</ul></p>`
}
let questions = this.suiviReponses.filter( r => r.key === key)
if (questions.length > 0) {
histoire += `<p><strong>Réponses au questionnaire : </strong><ul>`
for (let question of questions) {
histoire += `<li>${question.question} : <i>${question.reponse}</i> (${TeDeumUtility.upperFirst(question.compName)}+1)</li>`
}
histoire += `</ul></p>`
}
} }
await actor.update({ "system.histoire": histoire}) await actor.update({ "system.histoire": histoire})
actor.render(true) actor.render(true)
@@ -596,7 +640,7 @@ export class TeDeumCharacterCreator {
"adresse": { score: actor.getCompetenceScore("Initiative"), label: "Adresse" }, "adresse": { score: actor.getCompetenceScore("Initiative"), label: "Adresse" },
} }
const content = await renderTemplate("systems/fvtt-te-deum/templates/dialogs/character-creator-finished.hbs", context) const content = await foundry.applications.handlebars.renderTemplate("systems/fvtt-te-deum/templates/dialogs/character-creator-finished.hbs", context)
const label = "Terminer" const label = "Terminer"
const choiceResult = await foundry.applications.api.DialogV2.wait({ const choiceResult = await foundry.applications.api.DialogV2.wait({
window: { title: context.title }, window: { title: context.title },

View File

@@ -4,18 +4,42 @@ import { TeDeumUtility } from "../common/tedeum-utility.js";
export class TeDeumCombat extends Combat { export class TeDeumCombat extends Combat {
/* -------------------------------------------- */ /* -------------------------------------------- */
async rollInitiative(ids, formula = undefined, messageOptions = {} ) { async rollInitiative(ids, formula = undefined, messageOptions = {}) {
//console.log("Roll INIT !") //console.log("Roll INIT !")
ids = typeof ids === "string" ? [ids] : ids; ids = typeof ids === "string" ? [ids] : ids;
for (let cId of ids) { for (let cId of ids) {
const c = this.combatants.get(cId); const c = this.combatants.get(cId);
let initBonus = c.actor ? c.actor.getInitiativeScore( this.id, cId ) : -1; let initBonus = c.actor ? c.actor.getInitiativeScore(this.id, cId) : -1;
await this.updateEmbeddedDocuments("Combatant", [ { _id: cId, initiative: initBonus } ]); console.log("Init Bonus : ", c.name, initBonus)
await this.updateEmbeddedDocuments("Combatant", [{ _id: cId, initiative: initBonus }]);
} }
return this; return this;
} }
/* -------------------------------------------- */
async modifyAction(combatantId, delta, isMainGauche = false) {
let combatant = this.combatants.get(combatantId)
if (!combatant) return;
let ca = combatant.getFlag("world", "available-actions")
if (!ca) {
ca = { nbActions: 1, nbActionsMainGauche: 0 }
}
if (isMainGauche) {
ca.nbActionsMainGauche += delta
} else {
ca.nbActions += delta
}
if (ca.nbActionsMainGauche < 0) ca.nbActionsMainGauche = 0
if (ca.nbActions < 0) ca.nbActions = 0
console.log("Modify Action : ", combatant.name, ca)
if (game.user.isGM) {
await TeDeumUtility.updateCombatantActions(combatant, ca)
} else {
game.socket.emit("system.fvtt-te-deum", { msg: "msg_modify_combat_action", data: { combatantId: combatantId, ca: ca } })
}
}
/* -------------------------------------------- */ /* -------------------------------------------- */
static async checkTurnPosition() { static async checkTurnPosition() {
while (game.combat.turn > 0) { while (game.combat.turn > 0) {

View File

@@ -4,30 +4,46 @@ export const SYSTEM_ID = "fvtt-te-deum";
export const TEDEUM_CONFIG = { export const TEDEUM_CONFIG = {
BONUS_DEGATS: [{}, { label: "1d4", value: -2 }, { label: "1d6", value: -1 }, { label: "1d8", value: 0 }, BONUS_DEGATS: [{}, { label: "1d4", value: -2 }, { label: "1d6", value: -1 }, { label: "1d8", value: 0 },
{ label: "1d10", value: 1 }, { label: "1d12", value: 2 }, { label: "1d20", value: 3 }], { label: "1d10", value: 1 }, { label: "1d12", value: 2 }, { label: "1d20", value: 3 }],
MAX_ARMURES_LOURDES: [{}, { value: 1 }, { value: 3 }, { value: 5 }, MAX_ARMURES_LOURDES: [{}, { value: 1 }, { value: 3 }, { value: 5 },
{ value: 7 }, { value: 9 }, { value: 11 }], { value: 7 }, { value: 9 }, { value: 11 }],
ACTIONS_PAR_TOUR: [{}, { value: 1 }, { value: 2 }, { value: 2 }, ACTIONS_PAR_TOUR: [{}, { value: 1 }, { value: 2 }, { value: 2 },
{ value: 3 }, { value: 3 }, { value: 4 }], { value: 3 }, { value: 3 }, { value: 4 }],
COMMON_VALUE: [{}, { value: 1 }, { value: 2 }, { value: 3 }, COMMON_VALUE: [{}, { value: 1 }, { value: 2 }, { value: 3 },
{ value: 4 }, { value: 5 }, { value: 6 }], { value: 4 }, { value: 5 }, { value: 6 }],
COUT_XP: [{}, { value: 10 }, { value: 10 }, { value: 10 }, COUT_XP: [{}, { value: 10 }, { value: 10 }, { value: 10 },
{ value: 10 }, { value: 30 }, { value: 50 }], { value: 10 }, { value: 30 }, { value: 50 }],
LOCALISATION: { LOCALISATION: {
"pieddroit": { label: "Pied Droit", value: 1, locMod: 0, id: "pieddroit", nbArmure: 1, score: { min: 1, max: 1 }, coord: { top: 500, left: 0 } }, "pieddroit": { label: "Pied Droit", value: 1, locMod: 0, id: "pieddroit", categorie: "pied", nbArmure: 1, score: { min: 1, max: 1 }, coord: { top: 500, left: 0 } },
"jambedroite": { label: "Jambe Droite", value: 1, locMod: -1, id: "jambedroite", nbArmure: 1, score: { min: 3, max: 4 }, coord: { top: 400, left: 100 } }, "jambedroite": { label: "Jambe Droite", value: 1, locMod: -1, id: "jambedroite", categorie: "jambe", nbArmure: 1, score: { min: 3, max: 4 }, coord: { top: 400, left: 100 } },
"jambegauche": { label: "Jambe Gauche", value: 1, locMod: -1, id: "jambegauche", nbArmure: 1, score: { min: 5, max: 6 }, coord: { top: 400, left: 300 } }, "jambegauche": { label: "Jambe Gauche", value: 1, locMod: -1, id: "jambegauche", categorie: "jambe", nbArmure: 1, score: { min: 5, max: 6 }, coord: { top: 400, left: 300 } },
"piedgauche": { label: "Pied Gauche", value: 1, locMod: 0, id: "piedgauche", nbArmure: 1, score: { min: 2, max: 2 }, coord: { top: 500, left: 400 } }, "piedgauche": { label: "Pied Gauche", value: 1, locMod: 0, id: "piedgauche", categorie: "pied", nbArmure: 1, score: { min: 2, max: 2 }, coord: { top: 500, left: 400 } },
"maindroite": { label: "Main Droite", value: 1, locMod: 0, id: "maindroite", nbArmure: 1, score: { min: 7, max: 7 }, coord: { top: 0, left: 0 } }, "maindroite": { label: "Main Droite", value: 1, locMod: 0, id: "maindroite", categorie: "main", nbArmure: 1, score: { min: 7, max: 7 }, coord: { top: 0, left: 0 } },
"maingauche": { label: "Main Gauche", value: 1, locMod: 0, id: "maingauche", nbArmure: 1, score: { min: 8, max: 8 }, coord: { top: 0, left: 400 } }, "maingauche": { label: "Main Gauche", value: 1, locMod: 0, id: "maingauche", categorie: "main", nbArmure: 1, score: { min: 8, max: 8 }, coord: { top: 0, left: 400 } },
"brasdroit": { label: "Bras Droit", value: 1, locMod: -1, id: "brasdroit", nbArmure: 2, score: { min: 9, max: 10 }, coord: { top: 200, left: 0 } }, "brasdroit": { label: "Bras Droit", value: 1, locMod: -1, id: "brasdroit", categorie: "bras", nbArmure: 2, score: { min: 9, max: 10 }, coord: { top: 200, left: 0 } },
"brasgauche": { label: "Bras Gauche", value: 1, locMod: -1, id: "brasgauche", nbArmure: 2, score: { min: 11, max: 12 }, coord: { top: 200, left: 400 } }, "brasgauche": { label: "Bras Gauche", value: 1, locMod: -1, id: "brasgauche", categorie: "bras", nbArmure: 2, score: { min: 11, max: 12 }, coord: { top: 200, left: 400 } },
"corps": { label: "Corps", value: 1, id: "corps", locMod: -2, nbArmure: 2, score: { min: 13, max: 17 }, coord: { top: 200, left: 200 } }, "corps": { label: "Corps", value: 1, id: "corps", categorie: "corps", locMod: -2, nbArmure: 2, score: { min: 13, max: 17 }, coord: { top: 200, left: 200 } },
"tete": { label: "Tête", value: 1, id: "tete", locMod: -2, nbArmure: 2, score: { min: 18, max: 20 }, coord: { top: 0, left: 200 } }, "tete": { label: "Tête", value: 1, id: "tete", categorie: "tete", locMod: -2, nbArmure: 2, score: { min: 18, max: 20 }, coord: { top: 0, left: 200 } },
},
ATTAQUE_CIBLEES: {
"aucune": { label: "Aucune", id: "aucune", locMod: 0, description: "Attaque non ciblée" },
"pieddroit": { label: "Pied Droit", id: "pieddroit", locMod: 0, description: "Attaque ciblée sur le pied droit" },
"jambedroite": { label: "Jambe Droite", id: "jambedroite", locMod: -1, description: "Attaque ciblée sur la jambe droite" },
"jambegauche": { label: "Jambe Gauche", id: "jambegauche", locMod: -1, description: "Attaque ciblée sur la jambe gauche" },
"piedgauche": { label: "Pied Gauche", id: "piedgauche", locMod: 0, description: "Attaque ciblée sur le pied gauche" },
"maindroite": { label: "Main Droite", id: "maindroite", locMod: 0, description: "Attaque ciblée sur la main droite" },
"maingauche": { label: "Main Gauche", id: "maingauche", locMod: 0, description: "Attaque ciblée sur la main gauche" },
"brasdroit": { label: "Bras Droit", id: "brasdroit", locMod: -1, description: "Attaque ciblée sur le bras droit" },
"brasgauche": { label: "Bras Gauche", id: "brasgauche", locMod: -1, description: "Attaque ciblée sur le bras gauche" },
"corps": { label: "Corps", id: "corps", locMod: -2, description: "Attaque ciblée sur le corps" },
"tete": { label: "Tête", id: "tete", locMod: -2, description: "Attaque ciblée sur la tête" },
}, },
ARME_SPECIFICITE: { ARME_SPECIFICITE: {
"poing": { label: "Poings", id: "poing", melee: true, tir: false },
"pied": { label: "Pieds", id: "pied", melee: true, tir: false },
"encombrante": { label: "Encombrante", id: "encombrante", melee: true, tir: true }, "encombrante": { label: "Encombrante", id: "encombrante", melee: true, tir: true },
"maintiendistance": { label: "Maintien à distance", id: "maintiendistance", melee: true, tir: false }, "maintiendistance": { label: "Maintien à distance", id: "maintiendistance", melee: true, tir: false },
"coupassomant": { label: "Coup assomant", id: "coupassomant", melee: true, tir: false }, "coupassomant": { label: "Coup assomant", id: "coupassomant", melee: true, tir: false },
@@ -43,11 +59,11 @@ export const TEDEUM_CONFIG = {
}, },
ARME_PORTEES: { ARME_PORTEES: {
"brulepourpoint": { label: "Brûle-pourpoint", difficulty: "facile", id: "brulepourpoint" }, "brulepourpoint": { label: "Brûle-pourpoint (5)", difficulty: "facile", id: "brulepourpoint" },
"courte": { label: "Courte", difficulty: "pardefaut", id: "courte" }, "courte": { label: "Courte (7)", difficulty: "pardefaut", id: "courte" },
"moyenne": { label: "Moyenne", difficulty: "difficile", id: "moyenne" }, "moyenne": { label: "Moyenne (11)", difficulty: "difficile", id: "moyenne" },
"longue": { label: "Longue", difficulty: "perilleux", id: "longue" }, "longue": { label: "Longue (13)", difficulty: "perilleux", id: "longue" },
"extreme": { label: "Extrême", difficulty: "desespere", id: "extreme" }, "extreme": { label: "Extrême (15)", difficulty: "desespere", id: "extreme" },
}, },
genre: { genre: {
@@ -94,7 +110,7 @@ export const TEDEUM_CONFIG = {
}, },
caracteristiques: { caracteristiques: {
savoir: { id: "savoir", value: "savoir", label: "Savoir", description:"Cette caractéristique correspond à la capacité d'abstraction intellectuelle ainsi qu'à la culture générale du personnage. Elle permet d'évaluer la compétence de base Mémoriser." }, savoir: { id: "savoir", value: "savoir", label: "Savoir", description: "Cette caractéristique correspond à la capacité d'abstraction intellectuelle ainsi qu'à la culture générale du personnage. Elle permet d'évaluer la compétence de base Mémoriser." },
sensibilite: { id: "sensibilite", value: "sensibilite", label: "Sensibilité", description: "Cette caractéristique correspond à l'ouverture du personnage sur le monde. Elle englobe l'altruisme, la spiritualité et la créativité du personnage. Elle permet d'évaluer la compétence de base Perception." }, sensibilite: { id: "sensibilite", value: "sensibilite", label: "Sensibilité", description: "Cette caractéristique correspond à l'ouverture du personnage sur le monde. Elle englobe l'altruisme, la spiritualité et la créativité du personnage. Elle permet d'évaluer la compétence de base Perception." },
entregent: { id: "entregent", value: "entregent", label: "Entregent", description: "Cette caractéristique correspond à l'ensemble des prédispositions sociales du personnage. Elle englobe le charisme et le respect des usages. Elle permet d'évaluer la compétence de base Charme." }, entregent: { id: "entregent", value: "entregent", label: "Entregent", description: "Cette caractéristique correspond à l'ensemble des prédispositions sociales du personnage. Elle englobe le charisme et le respect des usages. Elle permet d'évaluer la compétence de base Charme." },
complexion: { id: "complexion", value: "complexion", label: "Complexion", description: "Cette caractéristique permet d'évaluer la santé et la résistance physique du per- sonnage. Elle permet de calculer la com- pétence de base Endurance, capitale dans la résolution des blessures, la résistance à la douleur, au poison et aux maladies." }, complexion: { id: "complexion", value: "complexion", label: "Complexion", description: "Cette caractéristique permet d'évaluer la santé et la résistance physique du per- sonnage. Elle permet de calculer la com- pétence de base Endurance, capitale dans la résolution des blessures, la résistance à la douleur, au poison et aux maladies." },
@@ -102,10 +118,10 @@ export const TEDEUM_CONFIG = {
adresse: { id: "adresse", value: "adresse", label: "Adresse", description: "Cette caractéristique correspond à la rapidité et la dextérité du personnage. Elle livre le nombre d'actions qu'un personnage peut accomplir en un tour de combat et permet d'évaluer les compétences de base Initiative & Course." }, adresse: { id: "adresse", value: "adresse", label: "Adresse", description: "Cette caractéristique correspond à la rapidité et la dextérité du personnage. Elle livre le nombre d'actions qu'un personnage peut accomplir en un tour de combat et permet d'évaluer les compétences de base Initiative & Course." },
}, },
allonges: { allonges: {
courte: { courte: { malus: 0 }, moyenne: { malus: -1 }, longue: { malus: -2 }, treslongue: { malus: 0, esquive: 2 } }, courte: { courte: { label: "Courte (0)", malus: 0 }, moyenne: { label: "Moyenne (-1)", malus: -1 }, longue: { label: "Longue (-2)", malus: -2 }, treslongue: { label: "Très longue (0, 2 Esquives)", malus: 0, esquive: 2 } },
moyenne: { courte: { malus: 0 }, moyenne: { malus: 0 }, longue: { malus: -1 }, treslongue: { malus: 0, esquive: 2 } }, moyenne: { courte: { label: "Courte (0)", malus: 0 }, moyenne: { label: "Moyenne (0)", malus: 0 }, longue: { label: "Longue (-1)", malus: -1 }, treslongue: { label: "Très longue (0, 2 Esquives)", malus: 0, esquive: 2 } },
longue: { courte: { malus: -2 }, moyenne: { malus: -1 }, longue: { malus: 0 }, treslongue: { malus: -1, esquive: 1 } }, longue: { courte: { label: "Courte (-2)", malus: -2 }, moyenne: { label: "Moyenne (-1)", malus: -1 }, longue: { label: "Longue (0)", malus: 0 }, treslongue: { label: "Très longue (-1, 2 Esquives)", malus: -1, esquive: 1 } },
treslongue: { courte: { malus: 0, esquive: 2 }, moyenne: { malus: 0, esquive: 2 }, longue: { malus: 0, esquive: 1 }, treslongue: { malus: 0 } }, treslongue: { courte: { label: "Courte (0, 2 Esquives)", malus: 0, esquive: 2 }, moyenne: { label: "Moyenne (0, 2 Esquives)", malus: 0, esquive: 2 }, longue: { label: "Longue (0, 1 Esquive)", malus: 0, esquive: 1 }, treslongue: { label: "Très longue (0)", malus: 0 } },
}, },
providence: [ providence: [
{ labelM: "Brebis égarée", labelF: "Brebis égarée", value: 0, diceValue: "0" }, { labelM: "Brebis égarée", labelF: "Brebis égarée", value: 0, diceValue: "0" },
@@ -152,13 +168,13 @@ export const TEDEUM_CONFIG = {
}, },
difficulte: { difficulte: {
aucune: { label: "Aucune", key: "aucune", value: 0 }, aucune: { label: "Aucune", key: "aucune", value: 0 },
routine: { label: "Routine", key: "routine", value: 3 }, routine: { label: "Routine (3)", key: "routine", value: 3 },
facile: { label: "Facile", key: "facile", value: 5 }, facile: { label: "Facile (5)", key: "facile", value: 5 },
pardefaut: { label: "Par Défaut", key: "pardefaut", value: 7 }, pardefaut: { label: "Par Défaut (7)", key: "pardefaut", value: 7 },
malaise: { label: "Malaisé", key: "malaise", value: 9 }, malaise: { label: "Malaisé (9)", key: "malaise", value: 9 },
difficile: { label: "Difficile", key: "difficile", value: 11 }, difficile: { label: "Difficile (11)", key: "difficile", value: 11 },
perilleux: { label: "Perilleux", key: "perilleux", value: 13 }, perilleux: { label: "Perilleux (13)", key: "perilleux", value: 13 },
desespere: { label: "Désespéré", key: "desespere", value: 15 } desespere: { label: "Désespéré (15)", key: "desespere", value: 15 }
}, },
monnaie: { monnaie: {
denier: { label: "Deniers", id: "denier", value: 1 }, denier: { label: "Deniers", id: "denier", value: 1 },
@@ -195,13 +211,14 @@ export const TEDEUM_CONFIG = {
{ value: "1", label: "+1 niveau" }, { value: "1", label: "+1 niveau" },
{ value: "2", label: "+2 niveaux" } { value: "2", label: "+2 niveaux" }
], ],
blessuresOrder: ["indemne", "estafilade", "plaie", "plaiebeante", "plaieatroce", "tuenet", "tuenet", "tuenet", "tuenet", "tuenet"],
blessures: { blessures: {
indemne: { value: 0, label: "Indemne", key: "indemne", degatsMax: -1, count: 0, modifier: 0 }, indemne: { value: 0, label: "Indemne", key: "indemne", degatsMax: -1, count: 0, modifier: 0 },
estafilade: { value: 1, label: "Estafilade", key: "estafilade", degatsMin: 0, degatsMax: 2, count: 1, modifier: 0 }, estafilade: { value: 1, label: "Estafilade", key: "estafilade", degatsMin: 0, degatsMax: 2, count: 1, modifier: 0 },
plaie: { value: 2, label: "Plaie", key: "plaie", degatsMin: 3, degatsMax: 4, count: 1, modifier: -1 }, plaie: { value: 2, label: "Plaie", key: "plaie", degatsMin: 3, degatsMax: 4, count: 1, modifier: -1 },
plaiebeante: { value: 3, label: "Plaie béante", key: "plaiebeante", degatsMin: 5, degatsMax: 6, count: 1, modifier: -2 }, plaiebeante: { value: 3, label: "Plaie béante", key: "plaiebeante", degatsMin: 5, degatsMax: 6, count: 1, modifier: -2 },
plaieatroce: { value: 4, label: "Plaie atroce", key: "plaieatroce", degatsMin: 7, degatsMax: 8, count: 1, horsCombat: true, modifier: -12 }, plaieatroce: { value: 4, label: "Plaie atroce", key: "plaieatroce", degatsMin: 7, degatsMax: 8, count: 1, horsCombat: true, modifier: -12 },
tunenet: { value: 5, label: "Tué net", key: "tuenet", degatsMin: 9, degatsMax: 100, count: 1, horsCombat: true, mort: true, modifier: -12 } tuenet: { value: 5, label: "Tué net", key: "tuenet", degatsMin: 9, degatsMax: 100, count: 1, horsCombat: true, mort: true, modifier: -100 }
}, },
virulence: { virulence: {
aucune: { label: "Aucune", value: "aucune", modifier: 0 }, aucune: { label: "Aucune", value: "aucune", modifier: 0 },

View File

@@ -1,6 +1,8 @@
/* -------------------------------------------- */ /* -------------------------------------------- */
/* -------------------------------------------- */ /* -------------------------------------------- */
const ECRYME_WELCOME_MESSAGE_URL = "https://www.uberwald.me/gitea/public/fvtt-te-deum/raw/branch/main/welcome-message-tedeum.html"
export class TeDeumUtility { export class TeDeumUtility {
/* -------------------------------------------- */ /* -------------------------------------------- */
@@ -12,22 +14,65 @@ export class TeDeumUtility {
CONFIG.JournalEntry.compendiumBanner = "systems/fvtt-te-deum/images/ui/compendium_banner.webp" CONFIG.JournalEntry.compendiumBanner = "systems/fvtt-te-deum/images/ui/compendium_banner.webp"
CONFIG.Macro.compendiumBanner = "systems/fvtt-te-deum/images/ui/compendium_banner.webp" CONFIG.Macro.compendiumBanner = "systems/fvtt-te-deum/images/ui/compendium_banner.webp"
CONFIG.Adventure.compendiumBanner = "systems/fvtt-te-deum/images/ui/compendium_banner.webp" CONFIG.Adventure.compendiumBanner = "systems/fvtt-te-deum/images/ui/compendium_banner.webp"
}
static installHooks() {
Hooks.on('renderChatLog', (log, html, data) => TeDeumUtility.chatListeners(html)); Hooks.on('renderChatLog', (log, html, data) => TeDeumUtility.chatListeners(html));
Hooks.on("renderActorDirectory", (app, html, data) => { Hooks.on("renderActorDirectory", (app, html, data) => {
if (game.user.can('ACTOR_CREATE')) { if (game.user.can('ACTOR_CREATE')) {
const button = document.createElement('button'); const button = document.createElement('button');
button.style.width = '90%'; button.style.width = '60%';
button.classList.add('tedeum-create-character');
button.innerHTML = 'Créer un Personnage' button.innerHTML = 'Créer un Personnage'
button.addEventListener('click', () => { button.addEventListener('click', () => {
let cr = new game.system.tedeum.TeDeumCharacterCreator(); let cr = new game.system.tedeum.TeDeumCharacterCreator();
cr.init() cr.init()
}) })
html.find('.header-actions').after(button) $(html).find('.header-actions').after(button)
} }
}) })
//Hooks.on("getChatLogEntryContext", (html, options) => TeDeumUtility.chatMenuManager(html, options));
Hooks.on("combatStart", async (combat, updateData, options) => {
this.resetCombatActions(combat)
});
Hooks.on("combatRound", (combat, updateData, updateOptions) => {
// List all actors related to combatant
if (game.user.isGM) {
this.resetCombatActions(combat)
}
})
Hooks.on("getCombatTrackerContextOptions", (html, options) => {
console.log("Get Combat Tracker Context", html, options)
this.pushCombatOptions(html, options);
});
}
/* -------------------------------------------- */
static pushCombatOptions(html, options) {
options.push({ name: "Actions +1", condition: true, icon: '<i class="fas fa-plus"></i>', callback: target => { game.combat.modifyAction($(target).data('combatant-id'), 1); } })
options.push({ name: "Actions -1", condition: true, icon: '<i class="fas fa-minus"></i>', callback: target => { game.combat.modifyAction($(target).data('combatant-id'), -1); } })
options.push({ name: "Actions MG +1", condition: true, icon: '<i class="fas fa-plus"></i>', callback: target => { game.combat.modifyAction($(target).data('combatant-id'), 1, true); } })
options.push({ name: "Actions MG -1", condition: true, icon: '<i class="fas fa-minus"></i>', callback: target => { game.combat.modifyAction($(target).data('combatant-id'), -1, true); } })
}
/* -------------------------------------------- */
static async resetCombatActions(combat) {
if (game.user.isGM) {
for (let c of combat.combatants) {
let actor = game.actors.get(c.actorId)
if (actor) {
let nbActions = actor.getNbActions()?.value || 0
let isMainGauche = (actor.getCompetenceScore("Main gauche") > 0)
let nbActionsMainGauche = isMainGauche ? nbActions : 0
await c.setFlag("world", "available-actions", { nbActions, nbActionsMainGauche })
await c.update({ name: `${c.token.name} (${nbActions} / ${nbActionsMainGauche})` })
}
}
}
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
@@ -126,14 +171,25 @@ export class TeDeumUtility {
/* -------------------------------------------- */ /* -------------------------------------------- */
static welcomeMessage() { static welcomeMessage() {
if (game.user.isGM) { if (game.user.isGM) {
ChatMessage.create({ // Try to fetch the welcome message from the github repo "welcome-message-ecryme.html"
user: game.user.id, fetch(ECRYME_WELCOME_MESSAGE_URL)
whisper: [game.user.id], .then(response => response.text())
content: `<div id="chat-welcome welcome-message-tedeum"><span class="rdd-roll-part"> .then(html => {
<strong>Bienvenu dans Te Deum Pour Un Massacre !</strong> console.log("Fetched welcome message:", html);
<div class="chat-welcome">Ce système vous est proposé par Open Sesame Games.<br> ChatMessage.create({
Vous trouverez de l'aide dans @UUID[Compendium.fvtt-te-deum.aides.JournalEntry.uNwJgi4kXBCiZmAH]{Aide pour Te Deum}<br> user: game.user.id,
ainsi que sur le Discord de Foundry FR : https://discord.gg/pPSDNJk</div>` }); whisper: [game.user.id],
content: html
});
})
.catch(error => {
console.error("Error fetching welcome message:", error);
ChatMessage.create({
user: game.user.id,
whisper: [game.user.id],
content: "<b>Bienvenue dans Ecryme RPG !</b><br>Visitez le site officiel pour plus d'informations."
});
});
} }
} }
@@ -200,7 +256,7 @@ export class TeDeumUtility {
return actor return actor
} }
/* -------------------------------------------- */ /* -------------------------------------------- */ /* -------------------------------------------- */
static async manageOpposition(rollData) { static async manageOpposition(rollData) {
if (!this.currentOpposition) { if (!this.currentOpposition) {
// Store rollData as current GM opposition // Store rollData as current GM opposition
@@ -209,29 +265,47 @@ export class TeDeumUtility {
} else { } else {
// Perform the opposition // Perform the opposition
let isAttackWinner = true let isAttackWinner = true
let rWinner = this.currentOpposition let rWinner, rLooser
let rLooser = rollData if (this.currentOpposition.total <= rollData.total) {
if (rWinner.total < rLooser.total) { rWinner = foundry.utils.duplicate(rollData)
rWinner = rollData rLooser = foundry.utils.duplicate(this.currentOpposition)
rLooser = this.currentOpposition
isAttackWinner = false isAttackWinner = false
} else {
rWinner = foundry.utils.duplicate(this.currentOpposition)
rLooser = foundry.utils.duplicate(rollData)
isAttackWinner = true
} }
this.currentOpposition = undefined // Reset opposition this.currentOpposition = undefined // Reset opposition
let oppositionData = { let oppositionData = {
winner: rWinner, winner: rWinner,
looser: rLooser looser: rLooser
} }
// Update difficulty
rWinner.difficulty = rLooser.total
rLooser.difficulty = rWinner.total
await this.computeResults(rWinner)
await this.computeResults(rLooser)
// Auto XP management when opposed
if (rWinner.isReussiteCritique) {
let actor = this.getActorFromRollData(rWinner)
actor.modifyXP(rWinner.carac.key, 1)
}
if (rLooser.isEchecCritique) {
let actor = this.getActorFromRollData(rLooser)
actor.modifyXP(rLooser.carac.key, 1)
}
let msg = await this.createChatWithRollMode(rollData.alias, { let msg = await this.createChatWithRollMode(rollData.alias, {
content: await renderTemplate(`systems/fvtt-te-deum/templates/chat/chat-opposition-result.hbs`, oppositionData) content: await foundry.applications.handlebars.renderTemplate(`systems/fvtt-te-deum/templates/chat/chat-opposition-result.hbs`, oppositionData)
}) })
await msg.setFlag("world", "te-deum-rolldata", rollData) await msg.setFlag("world", "te-deum-rolldata", rollData)
// Si le gagnant est l'attaquant, appliquer les dégats sur la victime // Si le gagnant est l'attaquant, appliquer les dégats sur la victime
if ( isAttackWinner && rWinner.isSuccess && rWinner.mode == "arme" && rWinner.arme?.system.typeArme == "melee" && rWinner.defenderTokenId) { if (isAttackWinner && rWinner.isSuccess && rWinner.mode == "arme" && rWinner.arme?.system.typeArme == "melee" && rWinner.defenderTokenId) {
this.appliquerDegats(rWinner) await this.appliquerDegats(rWinner)
} }
console.log("Rolldata result", rollData) console.log("Opposition result", rollData, isAttackWinner, oppositionData)
} }
} }
@@ -241,7 +315,18 @@ export class TeDeumUtility {
let defenderToken = canvas.tokens.placeables.find(t => t.id == rollData.defenderTokenId) let defenderToken = canvas.tokens.placeables.find(t => t.id == rollData.defenderTokenId)
if (defenderToken) { if (defenderToken) {
let actor = defenderToken.actor let actor = defenderToken.actor
await actor.appliquerDegats(rollData) if (game.user.isGM || actor.isOwner) {
await actor.appliquerDegats(rollData)
} else {
// Send a socket message
game.socket.emit("system.fvtt-te-deum", { name: "msg_apply_damage", data: { rollData } });
}
// Attaque naturelle avec dégats inférieur à -2
if ((rollData?.arme?.system.specificites?.poing?.hasSpec || rollData?.arme?.system.specificites?.pied?.hasSpec) && rollData.degats < -2) {
let attacker = this.getActorFromRollData(rollData)
attacker.appliquerBlessure("estafilade", "maindroite", "Contusion suite à une attaque naturelle")
ui.notifications.info(`${attacker.name} subit 1 contusion en infligeant ${rollData.degats} dégâts à mains nues`)
}
} else { } else {
ui.notifications.error("Impossible de trouver la cible de l'attaque, aucun degats appliqué") ui.notifications.error("Impossible de trouver la cible de l'attaque, aucun degats appliqué")
} }
@@ -250,7 +335,7 @@ export class TeDeumUtility {
/* -------------------------------------------- */ /* -------------------------------------------- */ /* -------------------------------------------- */ /* -------------------------------------------- */
static async chatListeners(html) { static async chatListeners(html) {
html.on("click", '.chat-command-opposition', event => { $(html).on("click", '.chat-command-opposition', event => {
let messageId = TeDeumUtility.findChatMessageId(event.currentTarget) let messageId = TeDeumUtility.findChatMessageId(event.currentTarget)
let message = game.messages.get(messageId) let message = game.messages.get(messageId)
let rollData = message.getFlag("world", "te-deum-rolldata") let rollData = message.getFlag("world", "te-deum-rolldata")
@@ -258,7 +343,7 @@ export class TeDeumUtility {
TeDeumUtility.manageOpposition(rollData, messageId) TeDeumUtility.manageOpposition(rollData, messageId)
} }
}) })
html.on("click", '.chat-command-appliquer-degats', event => { $(html).on("click", '.chat-command-appliquer-degats', event => {
let messageId = TeDeumUtility.findChatMessageId(event.currentTarget) let messageId = TeDeumUtility.findChatMessageId(event.currentTarget)
let message = game.messages.get(messageId) let message = game.messages.get(messageId)
let rollData = message.getFlag("world", "te-deum-rolldata") let rollData = message.getFlag("world", "te-deum-rolldata")
@@ -266,6 +351,17 @@ export class TeDeumUtility {
TeDeumUtility.appliquerDegats(rollData, messageId) TeDeumUtility.appliquerDegats(rollData, messageId)
} }
}) })
$(html).on("click", '.chat-command-gain-xp', event => {
let messageId = TeDeumUtility.findChatMessageId(event.currentTarget)
let message = game.messages.get(messageId)
let rollData = message.getFlag("world", "te-deum-rolldata")
if (rollData) {
let actor = TeDeumUtility.getActorFromRollData(rollData)
actor.modifyXP(rollData.carac.key, 1)
// Hide this button
event.currentTarget.style.display = 'none';
}
})
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
@@ -277,7 +373,7 @@ export class TeDeumUtility {
'systems/fvtt-te-deum/templates/items/partial-item-description.hbs', 'systems/fvtt-te-deum/templates/items/partial-item-description.hbs',
'systems/fvtt-te-deum/templates/dialogs/partial-creator-status.hbs' 'systems/fvtt-te-deum/templates/dialogs/partial-creator-status.hbs'
] ]
return loadTemplates(templatePaths); return foundry.applications.handlebars.loadTemplates(templatePaths);
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
@@ -354,12 +450,34 @@ export class TeDeumUtility {
let rollData = msg.data.rollData let rollData = msg.data.rollData
if (game.user.isGM) { if (game.user.isGM) {
let chatMsg = await this.createChatMessage(rollData.alias, "blindroll", { let chatMsg = await this.createChatMessage(rollData.alias, "blindroll", {
content: await renderTemplate(msg.data.template, rollData), content: await foundry.applications.handlebars.renderTemplate(msg.data.template, rollData),
whisper: game.user.id whisper: game.user.id
}) })
chatMsg.setFlag("world", "tedeum-rolldata", rollData) chatMsg.setFlag("world", "tedeum-rolldata", rollData)
} }
} }
if (msg.name == "msg_modify_combat_action") {
if (game.user.isGM) {
let { combatantId, ca } = msg.data
let combatant = game.combat.combatants.get(combatantId)
if (combatant) {
console.log("sock - Modify Combat Action : ", combatant.name, ca)
await TeDeumUtility.updateCombatantActions(combatant, ca)
}
}
}
if (msg.name == "msg_apply_damage") {
if (game.user.isGM) {
let rollData = msg.data.rollData
let defenderToken = canvas.tokens.placeables.find(t => t.id == rollData.defenderTokenId)
if (defenderToken) {
let actor = defenderToken.actor
await actor.appliquerDegats(rollData)
} else {
ui.notifications.error("Impossible de trouver la cible de l'attaque, aucun degats appliqué")
}
}
}
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
@@ -445,9 +563,11 @@ export class TeDeumUtility {
} }
if (rollData.diceSum == 1) { if (rollData.diceSum == 1) {
let critiqueRoll = await new Roll(rollData.carac.negativeDice) let critiqueRoll = await new Roll(rollData.carac.negativeDice)
rollData.isSuccess = false
await critiqueRoll.evaluate() await critiqueRoll.evaluate()
await this.showDiceSoNice(critiqueRoll, game.settings.get("core", "rollMode")) await this.showDiceSoNice(critiqueRoll, game.settings.get("core", "rollMode"))
rollData.critiqueRoll = foundry.utils.duplicate(critiqueRoll) rollData.critiqueRoll = foundry.utils.duplicate(critiqueRoll)
rollData.critiqueTotal = critiqueRoll.total
if (critiqueRoll.total > rollData.competence.system.score) { if (critiqueRoll.total > rollData.competence.system.score) {
rollData.isEchecCritique = true rollData.isEchecCritique = true
} }
@@ -476,9 +596,18 @@ export class TeDeumUtility {
if (rollData.isMouvement) { if (rollData.isMouvement) {
localModifier -= 1 localModifier -= 1
} }
if (rollData.arme && rollData.allongeId) {
localModifier += rollData.allonges[rollData.allongeId].malus
rollData.allongeMalus = rollData.allonges[rollData.allongeId].malus
rollData.nbEsquives = rollData.allonges[rollData.allongeId]?.esquive || 0
}
if (rollData.attaqueCiblee && rollData.attaqueCiblee != "aucune") {
localModifier -= 1
rollData.loc = foundry.utils.duplicate(game.system.tedeum.config.LOCALISATION[rollData.attaqueCiblee])
}
let diceBase = this.modifyDice(rollData.carac.dice, localModifier + Number(rollData.bonusMalus) + rollData.santeModifier) let diceBase = this.modifyDice(rollData.carac.dice, localModifier + Number(rollData.bonusMalus) + rollData.santeModifier)
if (!diceBase) return; if (!diceBase) return;
diceFormula = diceBase + "x + " + rollData.competence.system.score diceFormula = diceBase + "x + " + rollData.compScore
} }
if (rollData.enableProvidence) { if (rollData.enableProvidence) {
diceFormula += " + " + rollData.providence.dice diceFormula += " + " + rollData.providence.dice
@@ -488,24 +617,30 @@ export class TeDeumUtility {
/* -------------------------------------------- */ /* -------------------------------------------- */
static async getLocalisation(rollData) { static async getLocalisation(rollData) {
let locRoll = await new Roll("1d20").roll() let locRoll
await this.showDiceSoNice(locRoll, game.settings.get("core", "rollMode")) if (rollData.loc) {
rollData.locRoll = foundry.utils.duplicate(locRoll) locRoll = await new Roll(String(rollData.loc.score.min)).roll()
for (let key in game.system.tedeum.config.LOCALISATION) { } else {
let loc = game.system.tedeum.config.LOCALISATION[key] locRoll = await new Roll("1d20").roll()
if (locRoll.total >= loc.score.min && locRoll.total <= loc.score.max) { await this.showDiceSoNice(locRoll, game.settings.get("core", "rollMode"))
rollData.loc = foundry.utils.duplicate(loc) for (let key in game.system.tedeum.config.LOCALISATION) {
break let loc = game.system.tedeum.config.LOCALISATION[key]
if (locRoll.total >= loc.score.min && locRoll.total <= loc.score.max) {
rollData.loc = foundry.utils.duplicate(loc)
break
}
} }
} }
rollData.locRoll = foundry.utils.duplicate(locRoll)
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
static async processAttaqueMelee(rollData) { static async processAttaqueMelee(rollData) {
await this.getLocalisation(rollData) await this.getLocalisation(rollData)
let actor = game.actors.get(rollData.actorId) let actor = game.actors.get(rollData.actorId)
let bDegats = actor.getBonusDegats() let bDegats = actor.getAttaqueBonusDegats(rollData)
let degatsRoll = await new Roll(rollData.arme.system.degats + "+" + bDegats.value).roll() rollData.degatsFormula = rollData.arme.system.degats + "+" + bDegats
let degatsRoll = await new Roll(rollData.degatsFormula).roll()
await this.showDiceSoNice(degatsRoll, game.settings.get("core", "rollMode")) await this.showDiceSoNice(degatsRoll, game.settings.get("core", "rollMode"))
rollData.degatsRoll = foundry.utils.duplicate(degatsRoll) rollData.degatsRoll = foundry.utils.duplicate(degatsRoll)
rollData.degats = degatsRoll.total rollData.degats = degatsRoll.total
@@ -521,12 +656,51 @@ export class TeDeumUtility {
await this.getLocalisation(rollData) await this.getLocalisation(rollData)
// Now the degats // Now the degats
let degatsRoll = await new Roll(rollData.arme.system.degats).roll() let degatsRoll = await new Roll(rollData.arme.system.degats).roll()
await this.showDiceSoNice(rollData.locRoll, game.settings.get("core", "rollMode")) await this.showDiceSoNice(degatsRoll, game.settings.get("core", "rollMode"))
rollData.degatsRoll = foundry.utils.duplicate(degatsRoll) rollData.degatsRoll = foundry.utils.duplicate(degatsRoll)
rollData.degats = degatsRoll.total rollData.degats = degatsRoll.total
} }
} }
/* -------------------------------------------- */
static async updateCombatantActions(combatant, ca) {
await combatant.setFlag("world", "available-actions", ca)
await combatant.update({ name: `${combatant.token.name} (${ca.nbActions} / ${ca.nbActionsMainGauche})` })
}
/* -------------------------------------------- */
static async manageCombatActions(actor, rollData) {
let combat = game.combats.active
if (!combat) return;
let combatant = combat.getCombatantByActor(actor)
if (!combatant) return;
let ca = combatant.getFlag("world", "available-actions")
if (!ca) return;
if (rollData.mode == "arme" && rollData.isMainGauche) {
if (ca.nbActionsMainGauche > 0) {
ca.nbActionsMainGauche -= 1
ca.nbActions = Math.max(ca.nbActions - 1, 0)
} else {
ui.notifications.error(`${actor.name} n'a plus d'actions disponibles à la main gauche pour ce round`)
}
}
if (ca.nbActions > 0) {
ca.nbActions -= 1
} else {
ui.notifications.error(`${actor.name} n'a plus d'actions disponibles pour ce round`)
}
console.log("Manage combat actions 1", actor.name, combatant)
if (game.user.isGM) {
await this.updateCombatantActions(combatant, ca)
} else {
// Send a socket message
game.socket.emit("system.fvtt-te-deum", { name: "msg_modify_combat_action", data: { combatantId: combatant.id, ca } });
}
rollData.hasActions = true
rollData.remainingActions = ca.nbActions
rollData.remainingActionsMainGauche = ca.nbActionsMainGauche
}
/* -------------------------------------------- */ /* -------------------------------------------- */
static async rollTeDeum(rollData) { static async rollTeDeum(rollData) {
@@ -536,6 +710,18 @@ export class TeDeumUtility {
rollData.difficulty = "pardefaut" rollData.difficulty = "pardefaut"
} }
rollData.difficulty = game.system.tedeum.config.difficulte[rollData.difficulty].value rollData.difficulty = game.system.tedeum.config.difficulte[rollData.difficulty].value
// Compute the real competence score
if (rollData.competence) {
if (rollData.isMainGauche) {
rollData.competence = actor.getMeilleureCompetenceMainGauche(rollData.competence)
}
if (rollData.competence.system.isBase) {
rollData.compScore = actor.system.caracteristiques[rollData.competence.system.caracteristique].value
} else {
rollData.compScore = rollData.competence.system.score
}
}
let diceFormula = this.computeRollFormula(rollData, actor) let diceFormula = this.computeRollFormula(rollData, actor)
if (!diceFormula) return; if (!diceFormula) return;
console.log("RollData", rollData, diceFormula) console.log("RollData", rollData, diceFormula)
@@ -552,8 +738,10 @@ export class TeDeumUtility {
await this.processAttaqueDistance(rollData) await this.processAttaqueDistance(rollData)
await this.manageCombatActions(actor, rollData)
let msg = await this.createChatWithRollMode(rollData.alias, { let msg = await this.createChatWithRollMode(rollData.alias, {
content: await renderTemplate(`systems/fvtt-te-deum/templates/chat/chat-generic-result.hbs`, rollData) content: await foundry.applications.handlebars.renderTemplate(`systems/fvtt-te-deum/templates/chat/chat-generic-result.hbs`, rollData)
}) })
await msg.setFlag("world", "te-deum-rolldata", rollData) await msg.setFlag("world", "te-deum-rolldata", rollData)
console.log("Rolldata result", rollData) console.log("Rolldata result", rollData)
@@ -562,10 +750,6 @@ export class TeDeumUtility {
if (rollData.enableProvidence) { if (rollData.enableProvidence) {
actor.modifyProvidence(-1) actor.modifyProvidence(-1)
} }
// Manage XP
if (rollData.isReussiteCritique || rollData.isEchecCritique) {
actor.modifyXP(rollData.carac.key, 1)
}
} }
/* -------------------------------------------- */ /* -------------------------------------------- */

View File

@@ -1,17 +1,17 @@
export class TeDeumArmeSchema extends foundry.abstract.TypeDataModel { export class TeDeumArmeSchema extends foundry.abstract.TypeDataModel {
static defineSchema() { static defineSchema() {
const fields = foundry.data.fields; const fields = foundry.data.fields;
const requiredInteger = { required: true, nullable: false, integer: true }; const requiredInteger = { required: true, nullable: false, integer: true };
const requiredDouble = { required: true, nullable: false, integer: false }; const requiredDouble = { required: true, nullable: false, integer: false };
const schema = {}; const schema = {};
schema.typeArme = new fields.StringField({required: true, choices: ["melee", "tir"], initial: "melee"}); schema.typeArme = new fields.StringField({ required: true, choices: ["melee", "tir"], initial: "melee" });
schema.allonge = new fields.StringField({required: true, choices: ["courte", "moyenne", "longue", "treslongue"], initial: "courte"}); schema.allonge = new fields.StringField({ required: true, choices: ["courte", "moyenne", "longue", "treslongue"], initial: "courte" });
schema.specificites = new fields.SchemaField( schema.specificites = new fields.SchemaField(
Object.values((game.system.tedeum.config.ARME_SPECIFICITE)).reduce((obj, spec) => { Object.values((game.system.tedeum.config.ARME_SPECIFICITE)).reduce((obj, spec) => {
obj[spec.id] = new fields.SchemaField({ obj[spec.id] = new fields.SchemaField({
hasSpec: new fields.BooleanField({initial: false}), hasSpec: new fields.BooleanField({ initial: false }),
}); });
return obj; return obj;
}, {}) }, {})
@@ -26,18 +26,18 @@ export class TeDeumArmeSchema extends foundry.abstract.TypeDataModel {
}, {}) }, {})
); );
schema.degatsArmure = new fields.SchemaField( { schema.degatsArmure = new fields.SchemaField({
sansarmure : new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }), sansarmure: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }),
cuir : new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }), cuir: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }),
plates : new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }), plates: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }),
mailles : new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }), mailles: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }),
}); });
schema.tempsRecharge = new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }); schema.tempsRecharge = new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 });
schema.competenceRecharge = new fields.StringField({ required: false, choices:["aucune", "archerie", "arquebusade"], initial: "aucune", blank: true }); schema.competenceRecharge = new fields.StringField({ required: false, choices: ["aucune", "archerie", "arquebusade"], initial: "aucune", blank: true });
schema.valeurEchecCritique = new fields.NumberField({ ...requiredInteger, initial: 1, min: 1 }); schema.valeurEchecCritique = new fields.NumberField({ ...requiredInteger, initial: 1, min: 1 });
schema.initiativeBonus = new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }); schema.initiativeBonus = new fields.NumberField({ ...requiredInteger, initial: 0 });
schema.degats = new fields.StringField({ required: false, blank: true, initial: "0" }); schema.degats = new fields.StringField({ required: false, blank: true, initial: "0" });
schema.degatscrosse = new fields.StringField({ required: false, blank: true, initial: "0" }); schema.degatscrosse = new fields.StringField({ required: false, blank: true, initial: "0" });
@@ -46,15 +46,15 @@ export class TeDeumArmeSchema extends foundry.abstract.TypeDataModel {
for (let key of Object.keys(game.system.tedeum.config.armeCompetences)) { for (let key of Object.keys(game.system.tedeum.config.armeCompetences)) {
comp.push(key); comp.push(key);
} }
schema.competence = new fields.StringField({ required: true, choices:comp, initial: "bagarre" }); schema.competence = new fields.StringField({ required: true, choices: comp, initial: "bagarre" });
schema.competence2 = new fields.StringField({ required: false, choices:comp, initial: "", blank: true }); schema.competence2 = new fields.StringField({ required: false, choices: comp, initial: "", blank: true });
schema.prix = new fields.NumberField({ ...requiredDouble, initial: 0, min: 0 }); schema.prix = new fields.NumberField({ ...requiredDouble, initial: 0, min: 0 });
schema.monnaie = new fields.StringField({ required: true, blank: false, initial: "denier" }); schema.monnaie = new fields.StringField({ required: true, blank: false, initial: "denier" });
schema.equipe = new fields.BooleanField({initial: false}), schema.equipe = new fields.BooleanField({ initial: false }),
schema.description = new fields.HTMLField({ required: true, blank: true }); schema.description = new fields.HTMLField({ required: true, blank: true });
return schema; return schema;
} }

View File

@@ -4,8 +4,9 @@ export class TeDeumBlessureSchema extends foundry.abstract.TypeDataModel {
const requiredInteger = { required: true, nullable: false, integer: true }; const requiredInteger = { required: true, nullable: false, integer: true };
const schema = {}; const schema = {};
schema.typeBlessure = new fields.StringField({required: true, choices: ["indemne", "estafilade", "plaie", "plaiebeante", "plaieatroce", "tuenet"], initial: "estafilade"}); schema.typeBlessure = new fields.StringField({ required: true, choices: ["indemne", "estafilade", "plaie", "plaiebeante", "plaieatroce", "tuenet"], initial: "estafilade" });
schema.localisation = new fields.StringField({required: true, choices: ["piedgauche", "pieddroit", "jambegauche", "jambedroite", "maingauche", "maindroite", "brasgauche", "brasdroit", "tete", "corps"], initial: "corps"}); schema.value = new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 })
schema.localisation = new fields.StringField({ required: true, choices: ["piedgauche", "pieddroit", "jambegauche", "jambedroite", "maingauche", "maindroite", "brasgauche", "brasdroit", "tete", "corps"], initial: "corps" });
schema.description = new fields.HTMLField({ required: true, blank: true }); schema.description = new fields.HTMLField({ required: true, blank: true });

View File

@@ -51,7 +51,7 @@ export class TeDeumEducationSchema extends foundry.abstract.TypeDataModel {
reponse: new fields.StringField({ required: true, blank: true, initial: "" }), reponse: new fields.StringField({ required: true, blank: true, initial: "" }),
compName: new fields.StringField({ required: true, blank: true, initial: "" }), compName: new fields.StringField({ required: true, blank: true, initial: "" }),
toSelect: new fields.BooleanField({ initial: false }), toSelect: new fields.BooleanField({ initial: false }),
compList: new fields.SchemaField(Array.fromRange(10, 1).reduce((comps, i) => { compList: new fields.SchemaField(Array.fromRange(16, 1).reduce((comps, i) => {
comps[`comp${i}`] = new fields.SchemaField({ comps[`comp${i}`] = new fields.SchemaField({
compName: new fields.StringField({ required: true, blank: true, initial: "" }), compName: new fields.StringField({ required: true, blank: true, initial: "" }),
}); });

View File

@@ -6,7 +6,7 @@ export class TeDeumRollDialog extends Dialog {
static async create(actor, rollData) { static async create(actor, rollData) {
let options = { classes: ["tedeum-roll-dialog"], width: 540, height: 'fit-content', 'z-index': 99999 } let options = { classes: ["tedeum-roll-dialog"], width: 540, height: 'fit-content', 'z-index': 99999 }
let html = await renderTemplate('systems/fvtt-te-deum/templates/dialogs/roll-dialog-generic.hbs', rollData); let html = await foundry.applications.handlebars.renderTemplate('systems/fvtt-te-deum/templates/dialogs/roll-dialog-generic.hbs', rollData);
return new TeDeumRollDialog(actor, rollData, html, options); return new TeDeumRollDialog(actor, rollData, html, options);
} }
@@ -43,7 +43,7 @@ export class TeDeumRollDialog extends Dialog {
/* -------------------------------------------- */ /* -------------------------------------------- */
async refreshDialog() { async refreshDialog() {
const content = await renderTemplate("systems/fvtt-te-deum/templates/dialogs/roll-dialog-generic.hbs", this.rollData) const content = await foundry.applications.handlebars.renderTemplate("systems/fvtt-te-deum/templates/dialogs/roll-dialog-generic.hbs", this.rollData)
this.data.content = content this.data.content = content
this.render(true) this.render(true)
} }
@@ -60,9 +60,18 @@ export class TeDeumRollDialog extends Dialog {
html.find('#bonusMalusPerso').change((event) => { html.find('#bonusMalusPerso').change((event) => {
this.rollData.bonusMalusPerso = Number(event.currentTarget.value) this.rollData.bonusMalusPerso = Number(event.currentTarget.value)
}) })
html.find('#roll-allonge').change((event) => {
this.rollData.allongeId = event.currentTarget.value
})
html.find('#roll-main-gauche').change((event) => {
this.rollData.isMainGauche = event.currentTarget.checked
})
html.find('#roll-difficulty').change((event) => { html.find('#roll-difficulty').change((event) => {
this.rollData.difficulty = String(event.currentTarget.value) || "pardefaut" this.rollData.difficulty = String(event.currentTarget.value) || "pardefaut"
}) })
html.find('#roll-attaque-ciblee').change((event) => {
this.rollData.attaqueCiblee = event.currentTarget.value || "0"
})
html.find('#roll-bonus-malus').change((event) => { html.find('#roll-bonus-malus').change((event) => {
this.rollData.bonusMalus = event.currentTarget.value || "0" this.rollData.bonusMalus = event.currentTarget.value || "0"
}) })
@@ -80,6 +89,12 @@ export class TeDeumRollDialog extends Dialog {
html.find('#roll-tir-mouvement').change((event) => { html.find('#roll-tir-mouvement').change((event) => {
this.rollData.isMouvement = event.currentTarget.checked this.rollData.isMouvement = event.currentTarget.checked
}) })
html.find('#roll-charge-a-pied').change((event) => {
this.rollData.isChargeAPied = event.currentTarget.checked
})
html.find('#roll-charge-a-cheval').change((event) => {
this.rollData.isChargeACheval = event.currentTarget.checked
})

View File

@@ -4,7 +4,7 @@ import { TeDeumUtility } from "../common/tedeum-utility.js";
* Extend the basic ItemSheet with some very simple modifications * Extend the basic ItemSheet with some very simple modifications
* @extends {ItemSheet} * @extends {ItemSheet}
*/ */
export class TeDeumItemSheet extends ItemSheet { export class TeDeumItemSheet extends foundry.appv1.sheets.ItemSheet {
/** @override */ /** @override */
static get defaultOptions() { static get defaultOptions() {
@@ -49,8 +49,8 @@ export class TeDeumItemSheet extends ItemSheet {
limited: this.object.limited, limited: this.object.limited,
options: this.options, options: this.options,
owner: this.document.isOwner, owner: this.document.isOwner,
description: await TextEditor.enrichHTML(this.object.system.description, { async: true }), description: await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.object.system.description, { async: true }),
notes: await TextEditor.enrichHTML(this.object.system.notes, { async: true }), notes: await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.object.system.notes, { async: true }),
isGM: game.user.isGM isGM: game.user.isGM
} }
@@ -59,7 +59,6 @@ export class TeDeumItemSheet extends ItemSheet {
} }
this.options.editable = !(this.object.origin == "embeddedItem"); this.options.editable = !(this.object.origin == "embeddedItem");
console.log("ITEM DATA", formData, this);
return formData; return formData;
} }
@@ -92,7 +91,7 @@ export class TeDeumItemSheet extends ItemSheet {
payload: chatData, payload: chatData,
}); });
renderTemplate('systems/fvtt-te-deum/templates/post-item.html', chatData).then(html => { foundry.applications.handlebars.renderTemplate('systems/fvtt-te-deum/templates/post-item.html', chatData).then(html => {
let chatOptions = TeDeumUtility.chatDataSetup(html); let chatOptions = TeDeumUtility.chatDataSetup(html);
ChatMessage.create(chatOptions) ChatMessage.create(chatOptions)
}); });
@@ -157,7 +156,7 @@ export class TeDeumItemSheet extends ItemSheet {
let itemType = li.data("item-type"); let itemType = li.data("item-type");
}); });
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
get template() { get template() {

View File

@@ -82,14 +82,16 @@ Hooks.once("init", async function () {
console.log("TeDeum RPG | Ready"); console.log("TeDeum RPG | Ready");
Actors.unregisterSheet("core", ActorSheet); foundry.documents.collections.Actors.unregisterSheet("core", foundry.appv1.sheets.ActorSheet);
Actors.registerSheet("fvtt-te-deum", TeDeumActorPJSheet, { types: ["pj"], makeDefault: true }); foundry.documents.collections.Actors.registerSheet("fvtt-te-deum", TeDeumActorPJSheet, { types: ["pj"], makeDefault: true });
Actors.registerSheet("fvtt-te-deum", TeDeumActorPJSheet, { types: ["pnj"], makeDefault: true }); foundry.documents.collections.Actors.registerSheet("fvtt-te-deum", TeDeumActorPJSheet, { types: ["pnj"], makeDefault: true });
Items.unregisterSheet("core", ItemSheet); foundry.documents.collections.Items.unregisterSheet("core", foundry.appv1.sheets.ItemSheet);
Items.registerSheet("fvtt-te-deum", TeDeumItemSheet, { makeDefault: true }); foundry.documents.collections.Items.registerSheet("fvtt-te-deum", TeDeumItemSheet, { makeDefault: true });
TeDeumUtility.init() TeDeumUtility.init()
TeDeumUtility.installHooks()
}); });
@@ -98,6 +100,7 @@ Hooks.once("init", async function () {
/* -------------------------------------------- */ /* -------------------------------------------- */
Hooks.once("ready", function () { Hooks.once("ready", function () {
// User warning // User warning
if (!game.user.isGM && game.user.character == undefined) { if (!game.user.isGM && game.user.character == undefined) {
ui.notifications.info("Attention ! Aucun personnage relié au joueur !"); ui.notifications.info("Attention ! Aucun personnage relié au joueur !");
@@ -107,10 +110,10 @@ Hooks.once("ready", function () {
}); });
} }
import("https://www.uberwald.me/fvtt_appcount/count-class-ready.js").then(moduleCounter=>{ import("https://www.uberwald.me/fvtt_appcount/count-class-ready.js").then(moduleCounter => {
console.log("ClassCounter loaded", moduleCounter) console.log("ClassCounter loaded", moduleCounter)
moduleCounter.ClassCounter.registerUsageCount() moduleCounter.ClassCounter.registerUsageCount()
}).catch(err=> }).catch(err =>
console.log("No stats available, giving up.") console.log("No stats available, giving up.")
) )
TeDeumUtility.ready(); TeDeumUtility.ready();
@@ -134,4 +137,3 @@ Hooks.on("chatMessage", (html, content, msg) => {
} }
return true; return true;
}); });

21
package.json Normal file
View File

@@ -0,0 +1,21 @@
{
"name": "fvtt-te-deum",
"version": "1.0.0",
"description": "Système Te Deum pour FoundryVTT",
"private": true,
"scripts": {
"build:css": "gulp css",
"watch:css": "gulp watch"
},
"devDependencies": {
"gulp": "^4.0.2",
"gulp-less": "^5.0.0",
"less": "^4.2.0",
"autoprefixer": "^10.4.20",
"gulp-postcss": "^9.0.1",
"postcss": "^8.4.49"
},
"keywords": ["foundry-vtt", "te-deum"],
"author": "",
"license": "ISC"
}

Binary file not shown.

BIN
packs/aides/000177.ldb Normal file

Binary file not shown.

View File

@@ -1 +1 @@
MANIFEST-000095 MANIFEST-000214

View File

@@ -1,7 +1,7 @@
2025/04/20-09:24:48.041836 7fa413fff6c0 Recovering log #93 2026/01/04-21:26:37.933804 7f93eb7fe6c0 Recovering log #212
2025/04/20-09:24:48.069770 7fa413fff6c0 Delete type=3 #91 2026/01/04-21:26:37.943801 7f93eb7fe6c0 Delete type=3 #210
2025/04/20-09:24:48.069934 7fa413fff6c0 Delete type=0 #93 2026/01/04-21:26:37.943854 7f93eb7fe6c0 Delete type=0 #212
2025/04/20-09:25:06.962777 7fa4127fc6c0 Level-0 table #98: started 2026/01/04-21:27:02.505234 7f93e9ffb6c0 Level-0 table #217: started
2025/04/20-09:25:06.962842 7fa4127fc6c0 Level-0 table #98: 0 bytes OK 2026/01/04-21:27:02.505262 7f93e9ffb6c0 Level-0 table #217: 0 bytes OK
2025/04/20-09:25:06.970328 7fa4127fc6c0 Delete type=0 #96 2026/01/04-21:27:02.512734 7f93e9ffb6c0 Delete type=0 #215
2025/04/20-09:25:06.988174 7fa4127fc6c0 Manual compaction at level-0 from '!journal!uNwJgi4kXBCiZmAH' @ 72057594037927935 : 1 .. '!journal.pages!uNwJgi4kXBCiZmAH.onhNU0mXhOpdNZJF' @ 0 : 0; will stop at (end) 2026/01/04-21:27:02.512909 7f93e9ffb6c0 Manual compaction at level-0 from '!journal!uNwJgi4kXBCiZmAH' @ 72057594037927935 : 1 .. '!journal.pages!uNwJgi4kXBCiZmAH.onhNU0mXhOpdNZJF' @ 0 : 0; will stop at (end)

View File

@@ -1,7 +1,7 @@
2025/04/11-23:06:48.405694 7f6df09f96c0 Recovering log #89 2025/12/20-18:12:56.443928 7f244d1ff6c0 Recovering log #208
2025/04/11-23:06:48.416695 7f6df09f96c0 Delete type=3 #87 2025/12/20-18:12:56.494058 7f244d1ff6c0 Delete type=3 #206
2025/04/11-23:06:48.416810 7f6df09f96c0 Delete type=0 #89 2025/12/20-18:12:56.494134 7f244d1ff6c0 Delete type=0 #208
2025/04/12-00:18:27.794309 7f6deabff6c0 Level-0 table #94: started 2025/12/20-18:36:44.261828 7f2436ffd6c0 Level-0 table #213: started
2025/04/12-00:18:27.794331 7f6deabff6c0 Level-0 table #94: 0 bytes OK 2025/12/20-18:36:44.261865 7f2436ffd6c0 Level-0 table #213: 0 bytes OK
2025/04/12-00:18:27.828514 7f6deabff6c0 Delete type=0 #92 2025/12/20-18:36:44.320648 7f2436ffd6c0 Delete type=0 #211
2025/04/12-00:18:27.828757 7f6deabff6c0 Manual compaction at level-0 from '!journal!uNwJgi4kXBCiZmAH' @ 72057594037927935 : 1 .. '!journal.pages!uNwJgi4kXBCiZmAH.onhNU0mXhOpdNZJF' @ 0 : 0; will stop at (end) 2025/12/20-18:36:44.320833 7f2436ffd6c0 Manual compaction at level-0 from '!journal!uNwJgi4kXBCiZmAH' @ 72057594037927935 : 1 .. '!journal.pages!uNwJgi4kXBCiZmAH.onhNU0mXhOpdNZJF' @ 0 : 0; will stop at (end)

Binary file not shown.

BIN
packs/aides/MANIFEST-000214 Normal file

Binary file not shown.

Binary file not shown.

BIN
packs/armes/000280.ldb Normal file

Binary file not shown.

View File

@@ -1 +1 @@
MANIFEST-000198 MANIFEST-000317

View File

@@ -1,7 +1,7 @@
2025/04/20-09:24:47.881295 7fa412ffd6c0 Recovering log #195 2026/01/04-21:26:37.828637 7f93eb7fe6c0 Recovering log #315
2025/04/20-09:24:47.897306 7fa412ffd6c0 Delete type=3 #193 2026/01/04-21:26:37.839103 7f93eb7fe6c0 Delete type=3 #313
2025/04/20-09:24:47.897426 7fa412ffd6c0 Delete type=0 #195 2026/01/04-21:26:37.839200 7f93eb7fe6c0 Delete type=0 #315
2025/04/20-09:25:06.915266 7fa4127fc6c0 Level-0 table #201: started 2026/01/04-21:27:02.452079 7f93e9ffb6c0 Level-0 table #320: started
2025/04/20-09:25:06.915317 7fa4127fc6c0 Level-0 table #201: 0 bytes OK 2026/01/04-21:27:02.452098 7f93e9ffb6c0 Level-0 table #320: 0 bytes OK
2025/04/20-09:25:06.922256 7fa4127fc6c0 Delete type=0 #199 2026/01/04-21:27:02.458511 7f93e9ffb6c0 Delete type=0 #318
2025/04/20-09:25:06.929081 7fa4127fc6c0 Manual compaction at level-0 from '!folders!InCQeTRdT5jXMX82' @ 72057594037927935 : 1 .. '!items!wxIHkrq98eQ3cOvp' @ 0 : 0; will stop at (end) 2026/01/04-21:27:02.458741 7f93e9ffb6c0 Manual compaction at level-0 from '!folders!InCQeTRdT5jXMX82' @ 72057594037927935 : 1 .. '!items!wxIHkrq98eQ3cOvp' @ 0 : 0; will stop at (end)

View File

@@ -1,14 +1,7 @@
2025/04/11-23:06:48.304335 7f6df11fa6c0 Recovering log #191 2025/12/20-18:12:56.039187 7f244d1ff6c0 Recovering log #311
2025/04/11-23:06:48.314473 7f6df11fa6c0 Delete type=3 #189 2025/12/20-18:12:56.089963 7f244d1ff6c0 Delete type=3 #309
2025/04/11-23:06:48.314529 7f6df11fa6c0 Delete type=0 #191 2025/12/20-18:12:56.090033 7f244d1ff6c0 Delete type=0 #311
2025/04/12-00:18:27.071344 7f6deabff6c0 Level-0 table #196: started 2025/12/20-18:36:43.701277 7f2436ffd6c0 Level-0 table #316: started
2025/04/12-00:18:27.085927 7f6deabff6c0 Level-0 table #196: 1371 bytes OK 2025/12/20-18:36:43.701303 7f2436ffd6c0 Level-0 table #316: 0 bytes OK
2025/04/12-00:18:27.118250 7f6deabff6c0 Delete type=0 #194 2025/12/20-18:36:43.756264 7f2436ffd6c0 Delete type=0 #314
2025/04/12-00:18:27.311443 7f6deabff6c0 Manual compaction at level-0 from '!folders!InCQeTRdT5jXMX82' @ 72057594037927935 : 1 .. '!items!wxIHkrq98eQ3cOvp' @ 0 : 0; will stop at '!items!GZ3Q17VzRvdlrtdF' @ 40 : 1 2025/12/20-18:36:43.812180 7f2436ffd6c0 Manual compaction at level-0 from '!folders!InCQeTRdT5jXMX82' @ 72057594037927935 : 1 .. '!items!wxIHkrq98eQ3cOvp' @ 0 : 0; will stop at (end)
2025/04/12-00:18:27.311451 7f6deabff6c0 Compacting 1@0 + 1@1 files
2025/04/12-00:18:27.331173 7f6deabff6c0 Generated table #197@0: 38 keys, 31023 bytes
2025/04/12-00:18:27.331200 7f6deabff6c0 Compacted 1@0 + 1@1 files => 31023 bytes
2025/04/12-00:18:27.373984 7f6deabff6c0 compacted to: files[ 0 1 0 0 0 0 0 ]
2025/04/12-00:18:27.374177 7f6deabff6c0 Delete type=2 #174
2025/04/12-00:18:27.374459 7f6deabff6c0 Delete type=2 #196
2025/04/12-00:18:27.426656 7f6deabff6c0 Manual compaction at level-0 from '!items!GZ3Q17VzRvdlrtdF' @ 40 : 1 .. '!items!wxIHkrq98eQ3cOvp' @ 0 : 0; will stop at (end)

Binary file not shown.

BIN
packs/armes/MANIFEST-000317 Normal file

Binary file not shown.

Binary file not shown.

BIN
packs/armures/000304.ldb Normal file

Binary file not shown.

View File

@@ -1 +1 @@
MANIFEST-000197 MANIFEST-000317

View File

@@ -1,7 +1,7 @@
2025/04/20-09:24:47.903860 7fa413fff6c0 Recovering log #195 2026/01/04-21:26:37.843261 7f93ea7fc6c0 Recovering log #315
2025/04/20-09:24:47.919442 7fa413fff6c0 Delete type=3 #193 2026/01/04-21:26:37.853735 7f93ea7fc6c0 Delete type=3 #313
2025/04/20-09:24:47.919592 7fa413fff6c0 Delete type=0 #195 2026/01/04-21:26:37.853805 7f93ea7fc6c0 Delete type=0 #315
2025/04/20-09:25:06.908159 7fa4127fc6c0 Level-0 table #200: started 2026/01/04-21:27:02.446245 7f93e9ffb6c0 Level-0 table #320: started
2025/04/20-09:25:06.908228 7fa4127fc6c0 Level-0 table #200: 0 bytes OK 2026/01/04-21:27:02.446262 7f93e9ffb6c0 Level-0 table #320: 0 bytes OK
2025/04/20-09:25:06.915011 7fa4127fc6c0 Delete type=0 #198 2026/01/04-21:27:02.452006 7f93e9ffb6c0 Delete type=0 #318
2025/04/20-09:25:06.929064 7fa4127fc6c0 Manual compaction at level-0 from '!folders!2wTJBj3dicRKzNOE' @ 72057594037927935 : 1 .. '!items!ufvhWG5V8pX0qrtR' @ 0 : 0; will stop at (end) 2026/01/04-21:27:02.458726 7f93e9ffb6c0 Manual compaction at level-0 from '!folders!2wTJBj3dicRKzNOE' @ 72057594037927935 : 1 .. '!items!ufvhWG5V8pX0qrtR' @ 0 : 0; will stop at (end)

View File

@@ -1,7 +1,7 @@
2025/04/11-23:06:48.318150 7f6df09f96c0 Recovering log #191 2025/12/20-18:12:56.095054 7f24377fe6c0 Recovering log #311
2025/04/11-23:06:48.328364 7f6df09f96c0 Delete type=3 #189 2025/12/20-18:12:56.148579 7f24377fe6c0 Delete type=3 #309
2025/04/11-23:06:48.328522 7f6df09f96c0 Delete type=0 #191 2025/12/20-18:12:56.148653 7f24377fe6c0 Delete type=0 #311
2025/04/12-00:18:27.192248 7f6deabff6c0 Level-0 table #196: started 2025/12/20-18:36:43.637340 7f2436ffd6c0 Level-0 table #316: started
2025/04/12-00:18:27.192320 7f6deabff6c0 Level-0 table #196: 0 bytes OK 2025/12/20-18:36:43.637367 7f2436ffd6c0 Level-0 table #316: 0 bytes OK
2025/04/12-00:18:27.261480 7f6deabff6c0 Delete type=0 #194 2025/12/20-18:36:43.701178 7f2436ffd6c0 Delete type=0 #314
2025/04/12-00:18:27.426624 7f6deabff6c0 Manual compaction at level-0 from '!folders!2wTJBj3dicRKzNOE' @ 72057594037927935 : 1 .. '!items!ufvhWG5V8pX0qrtR' @ 0 : 0; will stop at (end) 2025/12/20-18:36:43.812170 7f2436ffd6c0 Manual compaction at level-0 from '!folders!2wTJBj3dicRKzNOE' @ 72057594037927935 : 1 .. '!items!ufvhWG5V8pX0qrtR' @ 0 : 0; will stop at (end)

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -1 +1 @@
MANIFEST-000194 MANIFEST-000315

View File

@@ -1,7 +1,7 @@
2025/04/20-09:24:47.857871 7fa4137fe6c0 Recovering log #192 2026/01/04-21:26:37.813752 7f93eaffd6c0 Recovering log #313
2025/04/20-09:24:47.873833 7fa4137fe6c0 Delete type=3 #190 2026/01/04-21:26:37.823461 7f93eaffd6c0 Delete type=3 #311
2025/04/20-09:24:47.873948 7fa4137fe6c0 Delete type=0 #192 2026/01/04-21:26:37.823509 7f93eaffd6c0 Delete type=0 #313
2025/04/20-09:25:06.901277 7fa4127fc6c0 Level-0 table #197: started 2026/01/04-21:27:02.440062 7f93e9ffb6c0 Level-0 table #318: started
2025/04/20-09:25:06.901384 7fa4127fc6c0 Level-0 table #197: 0 bytes OK 2026/01/04-21:27:02.440091 7f93e9ffb6c0 Level-0 table #318: 0 bytes OK
2025/04/20-09:25:06.907939 7fa4127fc6c0 Delete type=0 #195 2026/01/04-21:27:02.446167 7f93e9ffb6c0 Delete type=0 #316
2025/04/20-09:25:06.929038 7fa4127fc6c0 Manual compaction at level-0 from '!folders!4OPhigzcPv46qbWW' @ 72057594037927935 : 1 .. '!items!yx4k7lQHGcom99mk' @ 0 : 0; will stop at (end) 2026/01/04-21:27:02.458712 7f93e9ffb6c0 Manual compaction at level-0 from '!folders!4OPhigzcPv46qbWW' @ 72057594037927935 : 1 .. '!items!yx4k7lQHGcom99mk' @ 0 : 0; will stop at (end)

View File

@@ -1,7 +1,7 @@
2025/04/11-23:06:48.289349 7f6debfff6c0 Recovering log #188 2025/12/20-18:12:55.979585 7f244c9fe6c0 Recovering log #309
2025/04/11-23:06:48.299353 7f6debfff6c0 Delete type=3 #186 2025/12/20-18:12:56.031769 7f244c9fe6c0 Delete type=3 #307
2025/04/11-23:06:48.299496 7f6debfff6c0 Delete type=0 #188 2025/12/20-18:12:56.031837 7f244c9fe6c0 Delete type=0 #309
2025/04/12-00:18:27.261661 7f6deabff6c0 Level-0 table #193: started 2025/12/20-18:36:43.574310 7f2436ffd6c0 Level-0 table #314: started
2025/04/12-00:18:27.261699 7f6deabff6c0 Level-0 table #193: 0 bytes OK 2025/12/20-18:36:43.574360 7f2436ffd6c0 Level-0 table #314: 0 bytes OK
2025/04/12-00:18:27.311309 7f6deabff6c0 Delete type=0 #191 2025/12/20-18:36:43.637222 7f2436ffd6c0 Delete type=0 #312
2025/04/12-00:18:27.426641 7f6deabff6c0 Manual compaction at level-0 from '!folders!4OPhigzcPv46qbWW' @ 72057594037927935 : 1 .. '!items!yx4k7lQHGcom99mk' @ 0 : 0; will stop at (end) 2025/12/20-18:36:43.812158 7f2436ffd6c0 Manual compaction at level-0 from '!folders!4OPhigzcPv46qbWW' @ 72057594037927935 : 1 .. '!items!yx4k7lQHGcom99mk' @ 0 : 0; will stop at (end)

Binary file not shown.

Binary file not shown.

View File

@@ -1 +1 @@
MANIFEST-000206 MANIFEST-000327

View File

@@ -1,7 +1,7 @@
2025/04/20-09:24:47.923568 7fa418ffa6c0 Recovering log #203 2026/01/04-21:26:37.858384 7f93eaffd6c0 Recovering log #325
2025/04/20-09:24:47.940475 7fa418ffa6c0 Delete type=3 #201 2026/01/04-21:26:37.868673 7f93eaffd6c0 Delete type=3 #323
2025/04/20-09:24:47.940632 7fa418ffa6c0 Delete type=0 #203 2026/01/04-21:26:37.868726 7f93eaffd6c0 Delete type=0 #325
2025/04/20-09:25:06.922414 7fa4127fc6c0 Level-0 table #209: started 2026/01/04-21:27:02.458878 7f93e9ffb6c0 Level-0 table #330: started
2025/04/20-09:25:06.922447 7fa4127fc6c0 Level-0 table #209: 0 bytes OK 2026/01/04-21:27:02.458920 7f93e9ffb6c0 Level-0 table #330: 0 bytes OK
2025/04/20-09:25:06.928838 7fa4127fc6c0 Delete type=0 #207 2026/01/04-21:27:02.465606 7f93e9ffb6c0 Delete type=0 #328
2025/04/20-09:25:06.929095 7fa4127fc6c0 Manual compaction at level-0 from '!folders!9PQi3Lv54rpcxavo' @ 72057594037927935 : 1 .. '!items!zGlRtP7zSnkjuuue' @ 0 : 0; will stop at (end) 2026/01/04-21:27:02.485393 7f93e9ffb6c0 Manual compaction at level-0 from '!folders!9PQi3Lv54rpcxavo' @ 72057594037927935 : 1 .. '!items!zGlRtP7zSnkjuuue' @ 0 : 0; will stop at (end)

View File

@@ -1,14 +1,7 @@
2025/04/11-23:06:48.331428 7f6deb7fe6c0 Recovering log #199 2025/12/20-18:12:56.154781 7f244c9fe6c0 Recovering log #321
2025/04/11-23:06:48.343033 7f6deb7fe6c0 Delete type=3 #197 2025/12/20-18:12:56.203650 7f244c9fe6c0 Delete type=3 #319
2025/04/11-23:06:48.343104 7f6deb7fe6c0 Delete type=0 #199 2025/12/20-18:12:56.206209 7f244c9fe6c0 Delete type=0 #321
2025/04/12-00:18:27.118439 7f6deabff6c0 Level-0 table #204: started 2025/12/20-18:36:43.812286 7f2436ffd6c0 Level-0 table #326: started
2025/04/12-00:18:27.137069 7f6deabff6c0 Level-0 table #204: 6892 bytes OK 2025/12/20-18:36:43.812329 7f2436ffd6c0 Level-0 table #326: 0 bytes OK
2025/04/12-00:18:27.191998 7f6deabff6c0 Delete type=0 #202 2025/12/20-18:36:43.867818 7f2436ffd6c0 Delete type=0 #324
2025/04/12-00:18:27.374641 7f6deabff6c0 Manual compaction at level-0 from '!folders!9PQi3Lv54rpcxavo' @ 72057594037927935 : 1 .. '!items!zGlRtP7zSnkjuuue' @ 0 : 0; will stop at '!items!eILBnECWQOFfkxIL' @ 443 : 1 2025/12/20-18:36:44.048015 7f2436ffd6c0 Manual compaction at level-0 from '!folders!9PQi3Lv54rpcxavo' @ 72057594037927935 : 1 .. '!items!zGlRtP7zSnkjuuue' @ 0 : 0; will stop at (end)
2025/04/12-00:18:27.374657 7f6deabff6c0 Compacting 1@0 + 1@1 files
2025/04/12-00:18:27.393149 7f6deabff6c0 Generated table #205@0: 71 keys, 263379 bytes
2025/04/12-00:18:27.393180 7f6deabff6c0 Compacted 1@0 + 1@1 files => 263379 bytes
2025/04/12-00:18:27.425988 7f6deabff6c0 compacted to: files[ 0 1 0 0 0 0 0 ]
2025/04/12-00:18:27.426166 7f6deabff6c0 Delete type=2 #186
2025/04/12-00:18:27.426484 7f6deabff6c0 Delete type=2 #204
2025/04/12-00:18:27.426669 7f6deabff6c0 Manual compaction at level-0 from '!items!eILBnECWQOFfkxIL' @ 443 : 1 .. '!items!zGlRtP7zSnkjuuue' @ 0 : 0; will stop at (end)

Binary file not shown.

Binary file not shown.

View File

Binary file not shown.

BIN
packs/graces/000279.ldb Normal file

Binary file not shown.

View File

@@ -1 +1 @@
MANIFEST-000197 MANIFEST-000316

View File

@@ -1,7 +1,7 @@
2025/04/20-09:24:47.948681 7fa4137fe6c0 Recovering log #194 2026/01/04-21:26:37.873703 7f93ebfff6c0 Recovering log #314
2025/04/20-09:24:47.965382 7fa4137fe6c0 Delete type=3 #192 2026/01/04-21:26:37.885324 7f93ebfff6c0 Delete type=3 #312
2025/04/20-09:24:47.965487 7fa4137fe6c0 Delete type=0 #194 2026/01/04-21:26:37.885427 7f93ebfff6c0 Delete type=0 #314
2025/04/20-09:25:06.935620 7fa4127fc6c0 Level-0 table #200: started 2026/01/04-21:27:02.433342 7f93e9ffb6c0 Level-0 table #319: started
2025/04/20-09:25:06.935652 7fa4127fc6c0 Level-0 table #200: 0 bytes OK 2026/01/04-21:27:02.433382 7f93e9ffb6c0 Level-0 table #319: 0 bytes OK
2025/04/20-09:25:06.942921 7fa4127fc6c0 Delete type=0 #198 2026/01/04-21:27:02.439918 7f93e9ffb6c0 Delete type=0 #317
2025/04/20-09:25:06.956261 7fa4127fc6c0 Manual compaction at level-0 from '!items!17mjvwS8R3B6LloG' @ 72057594037927935 : 1 .. '!items!zUYIVOuFpRur9aAR' @ 0 : 0; will stop at (end) 2026/01/04-21:27:02.458692 7f93e9ffb6c0 Manual compaction at level-0 from '!items!17mjvwS8R3B6LloG' @ 72057594037927935 : 1 .. '!items!zUYIVOuFpRur9aAR' @ 0 : 0; will stop at (end)

View File

@@ -1,14 +1,7 @@
2025/04/11-23:06:48.348395 7f6debfff6c0 Recovering log #190 2025/12/20-18:12:56.214726 7f2437fff6c0 Recovering log #310
2025/04/11-23:06:48.358966 7f6debfff6c0 Delete type=3 #188 2025/12/20-18:12:56.267981 7f2437fff6c0 Delete type=3 #308
2025/04/11-23:06:48.359028 7f6debfff6c0 Delete type=0 #190 2025/12/20-18:12:56.268051 7f2437fff6c0 Delete type=0 #310
2025/04/12-00:18:27.516559 7f6deabff6c0 Level-0 table #195: started 2025/12/20-18:36:43.756462 7f2436ffd6c0 Level-0 table #315: started
2025/04/12-00:18:27.532890 7f6deabff6c0 Level-0 table #195: 2579 bytes OK 2025/12/20-18:36:43.756507 7f2436ffd6c0 Level-0 table #315: 0 bytes OK
2025/04/12-00:18:27.581168 7f6deabff6c0 Delete type=0 #193 2025/12/20-18:36:43.812023 7f2436ffd6c0 Delete type=0 #313
2025/04/12-00:18:27.688801 7f6deabff6c0 Manual compaction at level-0 from '!items!17mjvwS8R3B6LloG' @ 72057594037927935 : 1 .. '!items!zUYIVOuFpRur9aAR' @ 0 : 0; will stop at '!items!o71YhfDj6rschyQM' @ 59 : 1 2025/12/20-18:36:43.812190 7f2436ffd6c0 Manual compaction at level-0 from '!items!17mjvwS8R3B6LloG' @ 72057594037927935 : 1 .. '!items!zUYIVOuFpRur9aAR' @ 0 : 0; will stop at (end)
2025/04/12-00:18:27.688816 7f6deabff6c0 Compacting 1@0 + 1@1 files
2025/04/12-00:18:27.707304 7f6deabff6c0 Generated table #196@0: 49 keys, 19688 bytes
2025/04/12-00:18:27.707343 7f6deabff6c0 Compacted 1@0 + 1@1 files => 19688 bytes
2025/04/12-00:18:27.739125 7f6deabff6c0 compacted to: files[ 0 1 0 0 0 0 0 ]
2025/04/12-00:18:27.739315 7f6deabff6c0 Delete type=2 #173
2025/04/12-00:18:27.739599 7f6deabff6c0 Delete type=2 #195
2025/04/12-00:18:27.828729 7f6deabff6c0 Manual compaction at level-0 from '!items!o71YhfDj6rschyQM' @ 59 : 1 .. '!items!zUYIVOuFpRur9aAR' @ 0 : 0; will stop at (end)

Binary file not shown.

Binary file not shown.

View File

View File

Binary file not shown.

BIN
packs/maladies/000279.ldb Normal file

Binary file not shown.

View File

@@ -1 +1 @@
MANIFEST-000197 MANIFEST-000316

View File

@@ -1,7 +1,7 @@
2025/04/20-09:24:47.972234 7fa412ffd6c0 Recovering log #194 2026/01/04-21:26:37.889654 7f93ea7fc6c0 Recovering log #314
2025/04/20-09:24:47.989602 7fa412ffd6c0 Delete type=3 #192 2026/01/04-21:26:37.899518 7f93ea7fc6c0 Delete type=3 #312
2025/04/20-09:24:47.989720 7fa412ffd6c0 Delete type=0 #194 2026/01/04-21:26:37.899583 7f93ea7fc6c0 Delete type=0 #314
2025/04/20-09:25:06.929262 7fa4127fc6c0 Level-0 table #200: started 2026/01/04-21:27:02.472063 7f93e9ffb6c0 Level-0 table #319: started
2025/04/20-09:25:06.929306 7fa4127fc6c0 Level-0 table #200: 0 bytes OK 2026/01/04-21:27:02.472086 7f93e9ffb6c0 Level-0 table #319: 0 bytes OK
2025/04/20-09:25:06.935454 7fa4127fc6c0 Delete type=0 #198 2026/01/04-21:27:02.478114 7f93e9ffb6c0 Delete type=0 #317
2025/04/20-09:25:06.956241 7fa4127fc6c0 Manual compaction at level-0 from '!items!1icaxIywAwDXQcMz' @ 72057594037927935 : 1 .. '!items!ysGehYm1VkMWrI22' @ 0 : 0; will stop at (end) 2026/01/04-21:27:02.485430 7f93e9ffb6c0 Manual compaction at level-0 from '!items!1icaxIywAwDXQcMz' @ 72057594037927935 : 1 .. '!items!ysGehYm1VkMWrI22' @ 0 : 0; will stop at (end)

View File

@@ -1,14 +1,7 @@
2025/04/11-23:06:48.361948 7f6df11fa6c0 Recovering log #190 2025/12/20-18:12:56.274845 7f24377fe6c0 Recovering log #310
2025/04/11-23:06:48.372204 7f6df11fa6c0 Delete type=3 #188 2025/12/20-18:12:56.318675 7f24377fe6c0 Delete type=3 #308
2025/04/11-23:06:48.372273 7f6df11fa6c0 Delete type=0 #190 2025/12/20-18:12:56.318757 7f24377fe6c0 Delete type=0 #310
2025/04/12-00:18:27.468730 7f6deabff6c0 Level-0 table #195: started 2025/12/20-18:36:43.935645 7f2436ffd6c0 Level-0 table #315: started
2025/04/12-00:18:27.487486 7f6deabff6c0 Level-0 table #195: 19996 bytes OK 2025/12/20-18:36:43.935673 7f2436ffd6c0 Level-0 table #315: 0 bytes OK
2025/04/12-00:18:27.516404 7f6deabff6c0 Delete type=0 #193 2025/12/20-18:36:43.994623 7f2436ffd6c0 Delete type=0 #313
2025/04/12-00:18:27.626078 7f6deabff6c0 Manual compaction at level-0 from '!items!1icaxIywAwDXQcMz' @ 72057594037927935 : 1 .. '!items!ysGehYm1VkMWrI22' @ 0 : 0; will stop at '!items!ysGehYm1VkMWrI22' @ 47 : 1 2025/12/20-18:36:44.048051 7f2436ffd6c0 Manual compaction at level-0 from '!items!1icaxIywAwDXQcMz' @ 72057594037927935 : 1 .. '!items!ysGehYm1VkMWrI22' @ 0 : 0; will stop at (end)
2025/04/12-00:18:27.626091 7f6deabff6c0 Compacting 1@0 + 1@1 files
2025/04/12-00:18:27.644729 7f6deabff6c0 Generated table #196@0: 17 keys, 11448 bytes
2025/04/12-00:18:27.644759 7f6deabff6c0 Compacted 1@0 + 1@1 files => 11448 bytes
2025/04/12-00:18:27.688168 7f6deabff6c0 compacted to: files[ 0 1 0 0 0 0 0 ]
2025/04/12-00:18:27.688361 7f6deabff6c0 Delete type=2 #173
2025/04/12-00:18:27.688608 7f6deabff6c0 Delete type=2 #195
2025/04/12-00:18:27.828710 7f6deabff6c0 Manual compaction at level-0 from '!items!ysGehYm1VkMWrI22' @ 47 : 1 .. '!items!ysGehYm1VkMWrI22' @ 0 : 0; will stop at (end)

Binary file not shown.

Binary file not shown.

View File

View File

View File

@@ -1 +1 @@
MANIFEST-000134 MANIFEST-000253

View File

@@ -1,7 +1,7 @@
2025/04/20-09:24:48.018535 7fa418ffa6c0 Recovering log #132 2026/01/04-21:26:37.919630 7f93ebfff6c0 Recovering log #251
2025/04/20-09:24:48.034352 7fa418ffa6c0 Delete type=3 #130 2026/01/04-21:26:37.930006 7f93ebfff6c0 Delete type=3 #249
2025/04/20-09:24:48.034446 7fa418ffa6c0 Delete type=0 #132 2026/01/04-21:26:37.930066 7f93ebfff6c0 Delete type=0 #251
2025/04/20-09:25:06.943076 7fa4127fc6c0 Level-0 table #137: started 2026/01/04-21:27:02.478265 7f93e9ffb6c0 Level-0 table #256: started
2025/04/20-09:25:06.943110 7fa4127fc6c0 Level-0 table #137: 0 bytes OK 2026/01/04-21:27:02.478296 7f93e9ffb6c0 Level-0 table #256: 0 bytes OK
2025/04/20-09:25:06.949678 7fa4127fc6c0 Delete type=0 #135 2026/01/04-21:27:02.485146 7f93e9ffb6c0 Delete type=0 #254
2025/04/20-09:25:06.956277 7fa4127fc6c0 Manual compaction at level-0 from '!scenes!FJXugdbkBpEJEdR6' @ 72057594037927935 : 1 .. '!scenes!FJXugdbkBpEJEdR6' @ 0 : 0; will stop at (end) 2026/01/04-21:27:02.485444 7f93e9ffb6c0 Manual compaction at level-0 from '!scenes!FJXugdbkBpEJEdR6' @ 72057594037927935 : 1 .. '!scenes!FJXugdbkBpEJEdR6' @ 0 : 0; will stop at (end)

View File

@@ -1,7 +1,7 @@
2025/04/11-23:06:48.390538 7f6deb7fe6c0 Recovering log #128 2025/12/20-18:12:56.387036 7f2437fff6c0 Recovering log #247
2025/04/11-23:06:48.400234 7f6deb7fe6c0 Delete type=3 #126 2025/12/20-18:12:56.440877 7f2437fff6c0 Delete type=3 #245
2025/04/11-23:06:48.400355 7f6deb7fe6c0 Delete type=0 #128 2025/12/20-18:12:56.440965 7f2437fff6c0 Delete type=0 #247
2025/04/12-00:18:27.426850 7f6deabff6c0 Level-0 table #133: started 2025/12/20-18:36:43.994753 7f2436ffd6c0 Level-0 table #252: started
2025/04/12-00:18:27.426889 7f6deabff6c0 Level-0 table #133: 0 bytes OK 2025/12/20-18:36:43.994783 7f2436ffd6c0 Level-0 table #252: 0 bytes OK
2025/04/12-00:18:27.468595 7f6deabff6c0 Delete type=0 #131 2025/12/20-18:36:44.047877 7f2436ffd6c0 Delete type=0 #250
2025/04/12-00:18:27.626052 7f6deabff6c0 Manual compaction at level-0 from '!scenes!FJXugdbkBpEJEdR6' @ 72057594037927935 : 1 .. '!scenes!FJXugdbkBpEJEdR6' @ 0 : 0; will stop at (end) 2025/12/20-18:36:44.048061 7f2436ffd6c0 Manual compaction at level-0 from '!scenes!FJXugdbkBpEJEdR6' @ 72057594037927935 : 1 .. '!scenes!FJXugdbkBpEJEdR6' @ 0 : 0; will stop at (end)

Binary file not shown.

Binary file not shown.

View File

View File

Binary file not shown.

BIN
packs/simples/000280.ldb Normal file

Binary file not shown.

View File

@@ -1 +1 @@
MANIFEST-000197 MANIFEST-000317

View File

@@ -1,7 +1,7 @@
2025/04/20-09:24:47.993946 7fa413fff6c0 Recovering log #194 2026/01/04-21:26:37.904069 7f93eaffd6c0 Recovering log #315
2025/04/20-09:24:48.011487 7fa413fff6c0 Delete type=3 #192 2026/01/04-21:26:37.914574 7f93eaffd6c0 Delete type=3 #313
2025/04/20-09:24:48.011668 7fa413fff6c0 Delete type=0 #194 2026/01/04-21:26:37.914647 7f93eaffd6c0 Delete type=0 #315
2025/04/20-09:25:06.949829 7fa4127fc6c0 Level-0 table #200: started 2026/01/04-21:27:02.465731 7f93e9ffb6c0 Level-0 table #320: started
2025/04/20-09:25:06.949863 7fa4127fc6c0 Level-0 table #200: 0 bytes OK 2026/01/04-21:27:02.465755 7f93e9ffb6c0 Level-0 table #320: 0 bytes OK
2025/04/20-09:25:06.956072 7fa4127fc6c0 Delete type=0 #198 2026/01/04-21:27:02.471938 7f93e9ffb6c0 Delete type=0 #318
2025/04/20-09:25:06.956290 7fa4127fc6c0 Manual compaction at level-0 from '!items!1bAL2MQVpVBd0c5Z' @ 72057594037927935 : 1 .. '!items!zs67k4sxCid6oTK3' @ 0 : 0; will stop at (end) 2026/01/04-21:27:02.485413 7f93e9ffb6c0 Manual compaction at level-0 from '!items!1bAL2MQVpVBd0c5Z' @ 72057594037927935 : 1 .. '!items!zs67k4sxCid6oTK3' @ 0 : 0; will stop at (end)

View File

@@ -1,14 +1,7 @@
2025/04/11-23:06:48.375560 7f6df09f96c0 Recovering log #190 2025/12/20-18:12:56.325650 7f244c9fe6c0 Recovering log #311
2025/04/11-23:06:48.386162 7f6df09f96c0 Delete type=3 #188 2025/12/20-18:12:56.379165 7f244c9fe6c0 Delete type=3 #309
2025/04/11-23:06:48.386247 7f6df09f96c0 Delete type=0 #190 2025/12/20-18:12:56.379237 7f244c9fe6c0 Delete type=0 #311
2025/04/12-00:18:27.581367 7f6deabff6c0 Level-0 table #195: started 2025/12/20-18:36:43.867925 7f2436ffd6c0 Level-0 table #316: started
2025/04/12-00:18:27.597317 7f6deabff6c0 Level-0 table #195: 4361 bytes OK 2025/12/20-18:36:43.867945 7f2436ffd6c0 Level-0 table #316: 0 bytes OK
2025/04/12-00:18:27.625802 7f6deabff6c0 Delete type=0 #193 2025/12/20-18:36:43.935523 7f2436ffd6c0 Delete type=0 #314
2025/04/12-00:18:27.739840 7f6deabff6c0 Manual compaction at level-0 from '!items!1bAL2MQVpVBd0c5Z' @ 72057594037927935 : 1 .. '!items!zs67k4sxCid6oTK3' @ 0 : 0; will stop at '!items!yf5aoqeuNknhABWX' @ 41 : 1 2025/12/20-18:36:44.048037 7f2436ffd6c0 Manual compaction at level-0 from '!items!1bAL2MQVpVBd0c5Z' @ 72057594037927935 : 1 .. '!items!zs67k4sxCid6oTK3' @ 0 : 0; will stop at (end)
2025/04/12-00:18:27.739867 7f6deabff6c0 Compacting 1@0 + 1@1 files
2025/04/12-00:18:27.757841 7f6deabff6c0 Generated table #196@0: 36 keys, 20777 bytes
2025/04/12-00:18:27.757871 7f6deabff6c0 Compacted 1@0 + 1@1 files => 20777 bytes
2025/04/12-00:18:27.793933 7f6deabff6c0 compacted to: files[ 0 1 0 0 0 0 0 ]
2025/04/12-00:18:27.794075 7f6deabff6c0 Delete type=2 #173
2025/04/12-00:18:27.794233 7f6deabff6c0 Delete type=2 #195
2025/04/12-00:18:27.828743 7f6deabff6c0 Manual compaction at level-0 from '!items!yf5aoqeuNknhABWX' @ 41 : 1 .. '!items!zs67k4sxCid6oTK3' @ 0 : 0; will stop at (end)

Binary file not shown.

Binary file not shown.

View File

View File

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -134,22 +134,22 @@
"license": "LICENSE.txt", "license": "LICENSE.txt",
"manifest": "https://www.uberwald.me/gitea/public/fvtt-te-deum/releases/download/latest/system.json", "manifest": "https://www.uberwald.me/gitea/public/fvtt-te-deum/releases/download/latest/system.json",
"compatibility": { "compatibility": {
"minimum": "12", "minimum": "13",
"verified": "12" "verified": "13"
}, },
"id": "fvtt-te-deum", "id": "fvtt-te-deum",
"primaryTokenAttribute": "secondary.health", "primaryTokenAttribute": "secondary.health",
"secondaryTokenAttribute": "secondary.delirium", "secondaryTokenAttribute": "secondary.delirium",
"socket": true, "socket": true,
"styles": [ "styles": [
"styles/tedeum.css" {
"src": "styles/tedeum.css"
}
], ],
"relationships": {
},
"title": "Te Deum pour Un Massacre, le Jeu de Rôles (Officiel)", "title": "Te Deum pour Un Massacre, le Jeu de Rôles (Officiel)",
"url": "https://www.uberwald.me/gitea/public/fvtt-te-deum", "url": "https://www.uberwald.me/gitea/public/fvtt-te-deum",
"version": "12.0.17", "version": "13.0.2",
"download": "https://www.uberwald.me/gitea/public/fvtt-te-deum/archive/fvtt-te-deum-v12.0.17.zip", "download": "https://www.uberwald.me/gitea/public/fvtt-te-deum/releases/download/13.0.1/fvtt-te-deum-13.0.2.zip",
"background": "systems/fvtt-te-deum/images/ui/tdeum_welcome_page_01.webp", "background": "systems/fvtt-te-deum/images/ui/tdeum_welcome_page_01.webp",
"flags": { "flags": {
"hotReload": { "hotReload": {

Some files were not shown because too many files have changed in this diff Show More