52 Commits

Author SHA1 Message Date
e9c0fbd818 Fix URL scheme
All checks were successful
Release Creation / build (release) Successful in 1m30s
2025-03-19 13:55:30 +01:00
aaabb7ed75 Correction sur XP, echec critique et tir réussi
All checks were successful
Release Creation / build (release) Successful in 53s
2025-03-18 20:38:30 +01:00
fee7a3a9fb Gestion opposition en combat melee 2025-03-11 20:16:26 +01:00
31517030f6 Gestion opposition en combat melee
All checks were successful
Release Creation / build (release) Successful in 39s
2025-03-11 20:10:06 +01:00
c5cbf2a6d1 Gestion du genre dans la creation de perso 2025-03-11 13:45:04 +01:00
a30f813d94 Fix genre 2025-03-10 16:56:25 +01:00
090f6be601 Fix genre 2025-03-10 16:56:10 +01:00
60db1f65e4 Prit fix sur equipement et armes d'hast 2025-03-10 15:52:37 +01:00
d532765d2b Correction sur creation PNJ
All checks were successful
Release Creation / build (release) Successful in 2m0s
2025-03-01 22:01:01 +01:00
b6016742ae Enable PNJ 2025-03-01 19:42:15 +01:00
761f95d6d9 Ajout comp libres
All checks were successful
Release Creation / build (release) Successful in 44s
2025-02-25 22:29:05 +01:00
c24f4fe502 Ajout comp libres
All checks were successful
Release Creation / build (release) Successful in 1m13s
2025-02-25 21:29:52 +01:00
caedcf5e21 Update release 2025-02-24 19:53:03 +01:00
fe0814e498 Conserve l'historique des réponses
All checks were successful
Release Creation / build (release) Successful in 1m26s
2025-02-22 22:44:00 +01:00
544f9f467a Import and fix helper pictures 2025-02-21 17:49:49 +01:00
ce5771f930 Import and fix helper pictures 2025-02-21 17:47:49 +01:00
93b8325bb9 Import and fix helper pictures
All checks were successful
Release Creation / build (release) Successful in 50s
2025-02-21 17:41:36 +01:00
48be65e7fd Add release action 2025-02-21 10:43:37 +01:00
a37ce76ab8 Add release action
All checks were successful
Release Creation / build (release) Successful in 1m3s
2025-02-21 10:40:14 +01:00
bbc046bc66 Release version 2025-02-19 21:13:14 +01:00
fd0864cea6 Release version 2025-02-19 21:10:44 +01:00
bf7a9f9ea5 Fix actions/tour 2025-02-13 22:42:56 +01:00
86dfa54314 Fix defense rolls 2025-02-06 10:23:38 +01:00
891a6647b7 Roll shields 2025-02-06 10:23:24 +01:00
5d9a218e04 Init, competences de base, fix creation de perso, etc 2025-02-04 21:25:08 +01:00
a0733dc049 Init, competences de base, fix creation de perso, etc 2025-02-04 21:24:47 +01:00
c32be6b24d Init, competences de base, fix creation de perso, etc 2025-02-04 21:20:54 +01:00
6f278ab8eb Minor fixes 2025-02-04 15:24:40 +01:00
b2ab6ffaa7 Various fixes and enhancements 2025-02-04 08:13:48 +01:00
94d26e971e Various fixes and enhancements 2025-02-04 08:13:26 +01:00
7eed052645 Various fixes and enhancements 2025-02-04 08:07:12 +01:00
00c1d02b6b Various fixes and enhancements 2025-02-03 23:02:39 +01:00
92396da997 Various fixes and enhancements 2025-02-03 23:00:59 +01:00
a72e671f75 First full step for character creation 2025-01-31 11:54:52 +01:00
6331ab9736 Update ! 2025-01-28 21:40:20 +01:00
4a346a4386 Minor fixes for education 2024-12-19 19:15:43 +01:00
b8de37f388 Update education + logo pause 2024-12-05 22:48:23 +01:00
4fd537c9ea Update education + logo pause 2024-12-05 22:46:48 +01:00
3a2dc7be63 Ajout de 8 questions 2024-12-05 16:23:49 +01:00
ff1252dcf5 Ajout de 8 questions 2024-12-05 16:15:16 +01:00
7a768c5426 Fix title 2024-10-27 11:51:08 +01:00
9b2016d069 Fix education + simples 2024-09-17 16:10:22 +02:00
5d843af069 Fix education + simples 2024-09-17 16:05:50 +02:00
b3655d011e Add new options for education 2024-09-16 18:37:41 +02:00
0d7c4323b5 Enhance armes+armures 2024-09-15 09:10:35 +02:00
029ad04e26 Enhance armes+armures 2024-09-13 22:14:21 +02:00
9c93134d1c Arme à distance 2024-07-10 22:59:38 +02:00
37d8957448 New version 2024-07-08 21:44:34 +02:00
629d369693 Ajout multiples pour le combat et ameliorations des items 2024-07-08 07:54:53 +02:00
10b7fcac09 Gestion des jets opposés 2024-06-06 17:17:04 +02:00
de195aff1e Gestion des jets opposés 2024-06-06 17:16:53 +02:00
82e7a170c2 Gestion des jets opposés 2024-06-06 17:16:40 +02:00
213 changed files with 2976 additions and 3499 deletions

View File

@ -0,0 +1,52 @@
name: Release Creation
on:
release:
types: [published]
jobs:
build:
runs-on: ubuntu-latest
steps:
- run: echo "💡 The ${{ gitea.repository }} repository will cloned to the runner."
#- uses: actions/checkout@v3
- uses: RouxAntoine/checkout@v3.5.4
# get part of the tag after the `v`
- name: Extract tag version number
id: get_version
uses: battila7/get-version-action@v2
# Substitute the Manifest and Download URLs in the module.json
- name: Substitute Manifest and Download Links For Versioned Ones
id: sub_manifest_link_version
uses: microsoft/variable-substitution@v1
with:
files: 'system.json'
env:
version: ${{steps.get_version.outputs.version-without-v}}
url: https://www.uberwald.me/gitea/${{gitea.repository}}
manifest: https://www.uberwald.me/gitea/${{gitea.repository}}/releases/download/latest/system.json
download: https://www.uberwald.me/gitea/${{gitea.repository}}/releases/download/${{github.event.release.tag_name}}/fvtt-te-deum-${{github.event.release.tag_name}}.zip
# Create a zip file with all files required by the module to add to the release
- run: |
apt update -y
apt install -y zip
- run: zip -r ./fvtt-te-deum-${{github.event.release.tag_name}}.zip system.json template.json README.md LICENSE.txt assets/ fonts/ images/ lang/ modules/ styles/ packs/ templates/ te-deum.mjs
- name: setup go
uses: https://github.com/actions/setup-go@v4
with:
go-version: '>=1.20.1'
- name: Use Go Action
id: use-go-action
uses: https://gitea.com/actions/release-action@main
with:
files: |-
./fvtt-te-deum-${{github.event.release.tag_name}}.zip
system.json
api_key: '${{secrets.ALLOW_PUSH_RELEASE}}'

View File

@ -1,4 +1,4 @@
Copyright 2023 Open Sesame Games Copyright 2025 Open Sesame Games
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

View File

@ -1,37 +1,26 @@
# Te Deum Pour Un Massacre for FoundryVTT (French RPG, Open Sesam Games, Official) # Système Foundry pour Te Deum pour un Massacre (French RPG, Open Sesame Games, Official)
This is a base game system with functionnal character sheets for the game Te Deum.
You can join the kickstarter and obtain the base books here : https://www.kickstarter.com/projects/osg-us/ecryme
# System overview
The game system in Foundry offers the following features :
- PC/NPC sheet
- Skill rolls
- Cephaly rolls (with Anency support)
- Confrontation management, with detailed result in the chat card
- Weapon rolls
- Trait management, with Spleen and Ideal also.
- Compendiums of items for the game
![System Snapshot](https://www.lahiette.com/leratierbretonnien/wp-content/uploads/2023/08/ecryme_snapshot_01.webp "System Snapshot")
This is a base game system with functionnal character sheets for the game Te Deum pour un massacre.
# Contributions # Contributions
- Original code realised by Uberwald (https://www.uberwald.me/) - Original code realised by Uberwald (https://www.uberwald.me/)
Snapshot of the system :
![Alt text](https://www.lahiette.com/leratierbretonnien/wp-content/uploads/2025/02/tedeum_snapshot.webp "a title")
# Copyright mentions # Copyright mentions
Copyright 2023 Open Sesame Games Copyright 2025 Open Sesame Games
All rights reserved All rights reserved
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Te Deum pour un massacre is a game written by Jean-Philippe Jaworski. The author retains his moral rights regarding this work in both print and digital formats.
# Requests or Problems # Requests or Problems
Please report any requests or problems you have at contact@open-sesame.games Please report any requests or problems you have at contact@open-sesame.games

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 171 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 107 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

View File

@ -0,0 +1,25 @@
# 12.0.23
- Correction sur les jets réussie en tir
- Correction sur le dés négatif pour les échecs critiques
- Correction sur l'XP et édition de l'XP en mode MJ
# 12.0.22
- Correction pour les armes d'hast
- Correction sur la zone libre d'équipement
- Bouton + pour créer un équipement à nouveau opérationnel
- Modification de la gestion des jets en combat, avec gestion opposition ou degats immédiats
- Gestion du genre dans la création de personnage
# 12.0.21
- Creation de PNJ OK
# 12.0.20
- Corrections sur la création de perso
# 12.0.19
- Initial release !

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

BIN
images/icons/blessure.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

BIN
images/icons/maladie.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

BIN
images/icons/simple.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

BIN
images/ui/femme_gauche.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 160 KiB

BIN
images/ui/homme_droit.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 288 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 720 KiB

View File

@ -1,175 +1,20 @@
{ {
"TYPES": { "TYPES": {
"Actor":{ "Actor":{
"pc": "Personnage Joueur", "pj": "Personnage Joueur",
"npc": "Personnage Non Joueur", "pnj": "Personnage Non Joueur"
"annency": "Anence"
}, },
"Item": { "Item": {
"trait": "Trait", "competence": "Competence",
"weapon": "Arme", "arme": "Arme",
"equipment": "Equipement", "equipement": "Equipement",
"maneuver": "Manoeuvre", "armure": "Armure",
"specialization": "Spécialisation" "grace": "Grace",
} "origine": "Origine",
}, "education": "Education",
"ECRY": { "blessure": "Blessure",
"settings": { "maladie": "Maladie",
"cogs": "Engrenages", "simple": "Simple"
"cephaly": "Céphalie",
"boheme": "Bohême",
"amertume": "Amertume",
"gamelevel": "Niveau de jeu"
},
"chat": {
"formula": "Formule",
"difficulty": "Difficulté",
"dicesum": "Dés",
"result": "Resultat",
"margin": "Marge",
"success": "Succés!",
"failure": "Echec!",
"specialization": "Spécialisation",
"traitbonus": "Trait bonus",
"traitmalus": "Trait malus",
"bonusmalustraits": "Bonus/Malus des Traits",
"spectranscend": "Dépassement de soi : ",
"confrontselected": "Confrontation selectionnée",
"sentogm": "La confrontation a été envoyée au MJ"
},
"rule": {
"cephaly-success-12": "Durée : 1 scène - Impact : Superficiel - Bonus : 1 - Elegie : 1",
"cephaly-success-4": "Durée : 1 semaine - Impact : Léger - Bonus : 2 - Elegie : 2",
"cephaly-success-6": "Durée : 1 mois - Impact : Grave - Bonus : 3 - Elegie : 3",
"cephaly-success-8": "Durée : 1 année - Impact : Majeur - Bonus : 4 - Elegie : 4",
"cephaly-success-10": "Durée : Permanent - Impact : Mort - Bonus : 5 - Elegie : 5",
"cephaly-failure-2": "Durée : 1 scène - Impact : Superficiel - Malus : 1 - Symptôme non visible et sans gravité - Altération bégigne difficilement repérable",
"cephaly-failure-4": "Durée : 1 semaine - Impact : Léger - Malus : 2 - Symptôme visible non incapacitant - Altération repérable",
"cephaly-failure-6": "Durée : 1 mois - Impact : Grave - Malus : 3 - Symptôme incapacitant - Altération repérable et fâcheuse",
"cephaly-failure-8": "Durée : 1 année - Impact : Majeur - Malus : 4 - Symptôme très incapacitant - Altération dangereuse",
"cephaly-failure-10": "Durée : Permanent - Impact : Mort/Folie - Malus : 5 - Symptôme spectaculaire et repoussant - Altération dangereuse globalement"
},
"warn": {
"notenoughdice": "L'Accomplissement et la Préservation doivent avoir 2 dés chacun"
},
"ui": {
"equipmentfree": "Equipements (saisie libre)",
"traitType": "Type de trait",
"niveauTrait": "Niveau du trait",
"effect": "Incidence",
"weight": "Poids",
"cost": "Prix",
"costUnit": "Unité",
"ingot": "Lingot",
"ingotin": "Lingotin",
"goldcoin": "Pièce d'or",
"lige": "Lige",
"hurle": "Hurle",
"coin": "Sous",
"notes": "Notes",
"bio": "Bio",
"bionotes": "Bio&Notes",
"skills": "Compétences",
"traits": "Traits",
"equipment": "Equipement",
"physical": "Physiques",
"mental": "Mentales",
"social": "Sociales",
"athletics": "Athlétisme",
"driving": "Conduite",
"fencing": "Escrime",
"brawling": "Pugilat",
"shooting": "Tir",
"anthropomecanology": "Anthropo-Mécanologie",
"ecrymology": "Écrymologie",
"traumatology": "Traumatologie",
"traversology": "Traversologie",
"urbatechnology": "Urbatechnologie",
"quibbling": "Argutie",
"creativity": "Créativité",
"loquacity": "Faconde",
"guile": "Maraude",
"performance" :"Représentation",
"skill": "Compétence",
"troublesome": "Malaisé",
"occasional": "Peu frequent",
"difficult": "Difficile",
"uncommon": "Atypique",
"verydifficult": "Très difficile",
"rare": "Rare",
"extremdifficult": "Extrêmement difficile",
"veryrare": "Très rare",
"increddifficult": "Incroyable",
"exceptrare": "Exceptionnel",
"none": "Aucun",
"roll": "Lancer les dés !",
"cancel": "Annuler",
"rolltitle": "Ou l'on teste ses compétences",
"spec": "Spécialisation",
"traitbonus": "Traits bonus",
"traitmalus": "Traits malus",
"applyideal": "Utiliser l'idéal",
"applyspleen": "Utiliser le spleen",
"skilltranscendence": "Dépassement de soi",
"confrontation": "Confrontation",
"rollnormal": "Normal (4d6)",
"rollspleen": "Avec le Spleen (5d6, 4 plus bas conservés)",
"rollideal": "Avec l'Idéal (5d6, 4 plus haut conservés)",
"superficial": "Superficiel",
"light": "Léger",
"serious": "Grave",
"major": "Majeur",
"impactType": "Type d'Impact",
"impactLevel": "Niveau d'impact",
"impactphysical": "Physique",
"impactmental": "Mental",
"impactsocial": "Social",
"impactmalus": "Malus d'Impact",
"ongoingconfront": "Confrontations en cours",
"confront":"Confrontation",
"launchconfront": "Lancer la confrontation",
"execution": "Accomplissement",
"preservation": "Préservation",
"dicepool": "Dés disponibles",
"selectconfront": "Sélectionner pour la Confrontation",
"transcendapply": "Appliquer la Transcendence à ",
"healthcombat": "Santé&Combat",
"name": "Nom",
"weapons": "Armes",
"weapon": "Arme",
"melee": "Mêlée",
"ranged": "A Distance",
"weapontype": "Type d'arme",
"type": "Type",
"applyimpact": "Appliquer l'impact",
"applybonus": "Appliquer le bonus",
"bonuspool": "Bonus disponibles",
"cephaly": "Cephalie",
"elegy": "Elégie",
"entelechy": "Entéléchie",
"mekany": "Mekanë",
"psyche": "Psyché",
"scoria": "Scorie",
"cephalydifficulty": "Difficulté de la Céphalie",
"maneuvers": "Manoeuvres",
"annency": "Anence",
"iscollective": "Collective",
"ismultiple": "Multiple",
"description": "Description",
"location": "Lieu",
"characters": "Personnages",
"enhancements": "Améliorations",
"oniricform": "Forme Onorique (Bohême)",
"ideals": "Idéaux",
"politic": "Idéaux politiques",
"boheme": "Bohême",
"annencybonus": "Bonus d'Anence",
"bornplace": "Lieu de naissance",
"residence": "Résidence",
"origin": "Origine",
"childhood": "Enfance",
"bonus": "Bonus"
} }
} }
} }

View File

@ -11,7 +11,7 @@ export class TeDeumActorPJSheet extends ActorSheet {
/** @override */ /** @override */
static get defaultOptions() { static get defaultOptions() {
return mergeObject(super.defaultOptions, { return foundry.utils.mergeObject(super.defaultOptions, {
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,
@ -33,18 +33,32 @@ export class TeDeumActorPJSheet extends ActorSheet {
name: this.actor.name, name: this.actor.name,
editable: this.isEditable, editable: this.isEditable,
cssClass: this.isEditable ? "editable" : "locked", cssClass: this.isEditable ? "editable" : "locked",
system: duplicate(this.object.system), system: foundry.utils.duplicate(this.object.system),
limited: this.object.limited, limited: this.object.limited,
competences: this.actor.getCompetences(), competences: this.actor.getCompetences(),
config: duplicate(game.system.tedeum.config), config: foundry.utils.duplicate(game.system.tedeum.config),
armes: this.actor.getArmes(), armes: this.actor.getArmes(),
caracList: this.actor.prepareCaracteristiques(), caracList: this.actor.prepareCaracteristiques(),
providence: this.actor.prepareProvidence(), providence: this.actor.prepareProvidence(),
arbreCompetences: this.actor.prepareArbreCompetences(), arbreCompetences: this.actor.prepareArbreCompetences(),
equipements: this.actor.getEquipements(), equipements: this.actor.getEquipements(),
armures: this.actor.getArmures(),
graces: this.actor.getGraces(), graces: this.actor.getGraces(),
blessures: this.actor.getBlessures(),
maladies: this.actor.getMaladies(),
poisons: this.actor.getPoisons(),
combat: this.actor.prepareCombat(),
bonusDegats: this.actor.getBonusDegats(),
nbActions: this.actor.getNbActions(),
initiative: this.actor.getInitiative(),
pointsArmuresLourdes: this.actor.getNbArmures(),
nbArmuresLourdes: this.actor.getNbArmuresLourdesActuel(),
santeModifier: this.actor.getSanteModifier(),
educations: this.actor.getEducations(),
description: await TextEditor.enrichHTML(this.object.system.description, { async: true }), description: await TextEditor.enrichHTML(this.object.system.description, { async: true }),
equipmentfree: await TextEditor.enrichHTML(this.object.system.equipmentfree, { async: true }),
notes: await TextEditor.enrichHTML(this.object.system.notes, { async: true }), notes: await TextEditor.enrichHTML(this.object.system.notes, { async: true }),
histoire: await TextEditor.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,
@ -115,6 +129,11 @@ export class TeDeumActorPJSheet extends ActorSheet {
const armeId = $(event.currentTarget).data("arme-id") const armeId = $(event.currentTarget).data("arme-id")
this.actor.rollArme(armeId) this.actor.rollArme(armeId)
}); });
html.find('.roll-degats').click((event) => {
const armeId = $(event.currentTarget).data("arme-id")
this.actor.rollDegatsArme(armeId)
});
html.find('.lock-unlock-sheet').click((event) => { html.find('.lock-unlock-sheet').click((event) => {
this.options.editScore = !this.options.editScore; this.options.editScore = !this.options.editScore;

View File

@ -34,12 +34,24 @@ export class TeDeumActor extends Actor {
return actor; return actor;
} }
if (data.type == 'pj' || data.type == 'pnj') {
const skills = await TeDeumUtility.loadCompendium("fvtt-te-deum.competences")
data.items = data.items || []
for (let skill of skills) {
if (skill.system.isBase || skill.system.score == 1) {
data.items.push(skill.toObject())
}
}
}
return super.create(data, options); return super.create(data, options);
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
async prepareData() { async prepareData() {
super.prepareData() super.prepareData()
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
@ -52,7 +64,71 @@ export class TeDeumActor extends Actor {
super._preUpdate(changed, options, user); super._preUpdate(changed, options, user);
} }
getCompetenceScore(compName) {
let competence = this.items.find(item => item.type == "competence" && item.name.toLowerCase() == compName.toLowerCase())
if (competence) {
return competence.system.score
}
return 0
}
/* -------------------------------------------- */
_onUpdate(changed, options, userId) {
let updates = []
let memoriser = this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "mémoriser")
let newScore = this.getCommonBaseValue(this.system.caracteristiques.adresse.value)
if (memoriser && memoriser?.system.score != newScore) {
updates.push({ _id: memoriser.id, "system.score": Number(newScore) })
}
let perception = this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "perception")
newScore = this.getCommonBaseValue(this.system.caracteristiques.sensibilite.value)
if (perception && perception.system.score != newScore) {
updates.push({ _id: perception.id, "system.score": Number(newScore) })
}
let charme = this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "charme")
newScore = this.getCommonBaseValue(this.system.caracteristiques.entregent.value)
if (charme && charme?.system.score != newScore) {
updates.push({ _id: charme.id, "system.score": Number(newScore) })
}
let endurance = this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "endurance")
newScore = this.getCommonBaseValue(this.system.caracteristiques.complexion.value)
if (endurance && endurance?.system.score != newScore) {
updates.push({ _id: endurance.id, "system.score": Number(newScore) })
}
let course = this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "course")
newScore = this.getCommonBaseValue(this.system.caracteristiques.adresse.value)
if (course && course?.system.score != newScore) {
updates.push({ _id: course.id, "system.score": Number(newScore) })
}
let initiative = this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "initiative")
newScore = this.getCommonBaseValue(this.system.caracteristiques.adresse.value)
if (initiative && initiative?.system.score != 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")
newScore = this.getCommonBaseValue(this.system.caracteristiques.puissance.value)
if (effort && effort?.system.score != newScore) {
updates.push({ _id: effort.id, "system.score": Number(newScore) })
}
if (updates.length > 0) {
this.updateEmbeddedDocuments('Item', updates)
}
}
/* -------------------------------------------- */ /* -------------------------------------------- */
async _preCreate(data, options, user) { async _preCreate(data, options, user) {
await super._preCreate(data, options, user); await super._preCreate(data, options, user);
@ -65,6 +141,13 @@ export class TeDeumActor extends Actor {
this.updateSource({ prototypeToken }); this.updateSource({ prototypeToken });
} }
/* -------------------------------------------- */
getCommonBaseValue(value) {
return game.system.tedeum.config.COMMON_VALUE[value]?.value || 0
}
getInitiative() {
return game.system.tedeum.config.COMMON_VALUE[this.system.caracteristiques.adresse.value]?.value || 0
}
/* -------------------------------------------- */ /* -------------------------------------------- */
getBonusDegats() { getBonusDegats() {
return game.system.tedeum.config.BONUS_DEGATS[this.system.caracteristiques.puissance.value] return game.system.tedeum.config.BONUS_DEGATS[this.system.caracteristiques.puissance.value]
@ -76,51 +159,143 @@ export class TeDeumActor extends Actor {
getNbActions() { getNbActions() {
return game.system.tedeum.config.ACTIONS_PAR_TOUR[this.system.caracteristiques.adresse.value] return game.system.tedeum.config.ACTIONS_PAR_TOUR[this.system.caracteristiques.adresse.value]
} }
getInitiative() {
return game.system.tedeum.config.ACTIONS_PAR_TOUR[this.system.caracteristiques.adresse.value]
}
getNbArmuresLourdesActuel() {
let armures = this.getArmures()
let nb = 0
for (let armure of armures) {
if (armure.system.equipe) {
nb += armure.system.coutArmureLourde
}
}
return nb
}
/* -------------------------------------------- */
getEducations() {
let educations = this.items.filter(item => item.type == 'education')
return educations
}
/* -------------------------------------------- */ /* -------------------------------------------- */
getCompetences() { getCompetences() {
let comp = duplicate(this.items.filter(item => item.type == 'competence') || []) let comp = foundry.utils.duplicate(this.items.filter(item => item.type == 'competence') || [])
return comp; return comp;
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
getGraces() { getGraces() {
let comp = duplicate(this.items.filter(item => item.type == 'grace') || []) let comp = foundry.utils.duplicate(this.items.filter(item => item.type == 'grace') || [])
TeDeumUtility.sortArrayObjectsByName(comp) TeDeumUtility.sortArrayObjectsByName(comp)
return comp; return comp;
} }
getArmes() { getArmes() {
let comp = duplicate(this.items.filter(item => item.type == 'arme') || []) let comp = foundry.utils.duplicate(this.items.filter(item => item.type == 'arme') || [])
TeDeumUtility.sortArrayObjectsByName(comp) TeDeumUtility.sortArrayObjectsByName(comp)
return comp; return comp;
} }
getEquipements() { getEquipements() {
let comp = duplicate(this.items.filter(item => item.type == 'equipement') || []) let comp = foundry.utils.duplicate(this.items.filter(item => item.type == 'equipement') || [])
TeDeumUtility.sortArrayObjectsByName(comp) TeDeumUtility.sortArrayObjectsByName(comp)
return comp; return comp;
} }
getArmures() { getArmures() {
let comp = duplicate(this.items.filter(item => item.type == 'armure') || []) let comp = foundry.utils.duplicate(this.items.filter(item => item.type == 'armure') || [])
TeDeumUtility.sortArrayObjectsByName(comp)
return comp;
}
getBlessures() {
let comp = foundry.utils.duplicate(this.items.filter(item => item.type == 'blessure') || [])
for (let c of comp) {
let blessDef = game.system.tedeum.config.blessures[c.system.typeBlessure]
c.malus = blessDef.modifier
}
TeDeumUtility.sortArrayObjectsByName(comp)
return comp;
}
getMaladies() {
let comp = foundry.utils.duplicate(this.items.filter(item => item.type == 'maladie') || [])
for (let c of comp) {
c.malus = "N/A"
if (c.system.appliquee) {
let malDef = game.system.tedeum.config.virulence[c.system.virulence]
c.malus = malDef.modifier
}
}
TeDeumUtility.sortArrayObjectsByName(comp)
return comp;
}
getPoisons() {
let comp = foundry.utils.duplicate(this.items.filter(item => item.type == 'poison') || [])
for (let c of comp) {
c.malus = "N/A"
if (c.system.appliquee) {
let poisDef = game.system.tedeum.config.virulencePoison[c.system.virulence]
c.malus = poisDef.modifier
}
}
TeDeumUtility.sortArrayObjectsByName(comp) TeDeumUtility.sortArrayObjectsByName(comp)
return comp; return comp;
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
calculMalusBlessures() { getSanteModifier() {
let modifierBlessures = 0 let comp = foundry.utils.duplicate(this.items.filter(item => item.type == 'maladie') || [])
let nbBlessures = 0 let modTotal = 0
// Cumul des malus de blessures for (let c of comp) {
for (let locKey in this.system.localisation) { if (c.system.appliquee) {
let loc = this.system.localisation[locKey] let maladieDef = game.system.tedeum.config.virulence[c.system.virulence]
let bDef = game.system.tedeum.config.blessures[loc.blessures] modTotal += maladieDef.modifier
modifierBlessures += bDef.modifier }
nbBlessures += bDef.count }
let simples = foundry.utils.duplicate(this.items.filter(item => item.type == 'simple') || [])
for (let c of simples) {
if (c.system.appliquee) {
let simpleDef = game.system.tedeum.config.virulencePoison[c.system.virulence]
modTotal += simpleDef.modifier
}
}
let blessures = foundry.utils.duplicate(this.items.filter(item => item.type == 'blessure') || [])
for (let c of blessures) {
let blessDef = game.system.tedeum.config.blessures[c.system.typeBlessure]
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 endurance = this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "endurance")
if ( nbBlessures > endurance.system.score) { if (blessures.length > endurance.system.score) {
modifierBlessures += -1 modTotal += -1
} }
return modifierBlessures return modTotal
}
/* -------------------------------------------- */
async appliquerDegats(rollData) {
let combat = this.prepareCombat()
rollData.defenderName = this.name
let touche = combat[rollData.loc.id].touche
if (rollData.degats > 0 && rollData.degats > touche) {
let diff = rollData.degats - touche
for (let bId in game.system.tedeum.config.blessures) {
let blessure = game.system.tedeum.config.blessures[bId]
if (diff >= blessure.degatsMin && diff <= blessure.degatsMax) {
// Create a new blessure object
let blessureObj = {
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
this.createEmbeddedDocuments('Item', [blessureObj]);
}
}
}
// Display the relevant chat message
let msg = await TeDeumUtility.createChatWithRollMode(rollData.alias, {
content: await renderTemplate(`systems/fvtt-te-deum/templates/chat/chat-blessure-result.hbs`, rollData)
})
await msg.setFlag("world", "te-deum-rolldata", rollData)
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
@ -135,10 +310,11 @@ export class TeDeumActor extends Actor {
/* -------------------------------------------- */ /* -------------------------------------------- */
prepareCaracteristiques() { prepareCaracteristiques() {
let carac = foundry.utils.deepClone(this.system.caracteristiques) let carac = foundry.utils.deepClone(this.system.caracteristiques)
for (let key in carac) { for (let key in carac) {
let c = carac[key] let c = carac[key]
this.updateCarac(c, key) this.updateCarac(c, key)
c.description = game.system.tedeum.config.caracteristiques[key].description
} }
return carac return carac
} }
@ -146,22 +322,51 @@ export class TeDeumActor extends Actor {
prepareProvidence() { prepareProvidence() {
let providence = foundry.utils.deepClone(this.system.providence) let providence = foundry.utils.deepClone(this.system.providence)
providence.name = "Providence" providence.name = "Providence"
providence.qualite = game.system.tedeum.config.providence[providence.value].labelM providence.qualite = game.system.tedeum.config.providence[providence.value].labelM
providence.dice = game.system.tedeum.config.providence[providence.value].diceValue providence.dice = game.system.tedeum.config.providence[providence.value].diceValue
providence.description = "La Providence représente la Volonté Divine à l'œuvre pour guider ou sauver un être humain. Les PJ montent dans léchelle de la Providence en menant à bien leurs missions et en se montrant vertueux. Les points de Providence peuvent servir à augmenter temporairement une caractéris- tique, à modifier la gravité d'une blessure, et à résister au vieillissement. Chaque person- nage commence avec un score initial de 1 en Providence (au niveau Pauvre pécheur)."
return providence return providence
} }
/* -------------------------------------------- */
prepareCombat() {
let combatLoc = foundry.utils.deepClone(this.system.localisation)
for (let key in combatLoc) {
combatLoc[key] = foundry.utils.mergeObject(combatLoc[key], game.system.tedeum.config.LOCALISATION[key])
combatLoc[key].armures = []
combatLoc[key].blessures = []
combatLoc[key].protectionTotal = 0
let armures = this.getArmures()
for (let armure of armures) {
if (armure.system.equipe && armure.system.localisation[key].protege) {
combatLoc[key].armures.push(armure)
combatLoc[key].protectionTotal += armure.system.protection
}
}
let blessures = this.getBlessures()
for (let blessure of blessures) {
if (blessure.system.localisation == key) {
combatLoc[key].blessures.push(blessure)
}
}
let endurance = this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "endurance")
combatLoc[key].endurance = endurance.system.score + game.system.tedeum.config.LOCALISATION[key].locMod
combatLoc[key].touche = combatLoc[key].endurance + combatLoc[key].protectionTotal
}
return combatLoc
}
/* -------------------------------------------- */ /* -------------------------------------------- */
modifyProvidence(value) { modifyProvidence(value) {
let providence = foundry.utils.duplicate(this.system.providence) let providence = foundry.utils.duplicate(this.system.providence)
providence.value = Math.min(Math.max(providence.value + value, 0), 6) providence.value = Math.min(Math.max(providence.value + value, 0), 6)
this.update( { "system.providence": providence } ) this.update({ "system.providence": providence })
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
modifyXP(key, value) { async modifyXP(key, value) {
let xp = this.system.caracteristiques[key].experience let xp = this.system.caracteristiques[key].experience
xp = Math.max(xp + value, 0) xp = Math.max(xp + value, 0)
this.update( { [`system.caracteristiques.${key}.experience`]: xp } ) await this.update({ [`system.caracteristiques.${key}.experience`]: xp })
this.sheet?.render(true)
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
@ -174,7 +379,8 @@ export class TeDeumActor extends Actor {
let caracDice = game.system.tedeum.config.descriptionValeur[this.system.caracteristiques[c.system.caracteristique].value].dice let caracDice = game.system.tedeum.config.descriptionValeur[this.system.caracteristiques[c.system.caracteristique].value].dice
c.system.formula = caracDice + "+" + c.system.score c.system.formula = caracDice + "+" + c.system.score
}) })
return foundry.utils.deepClone( comp || {} ) comp = comp.sort((a, b) => a.name.localeCompare(b.name))
return foundry.utils.deepClone(comp || {})
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
@ -192,7 +398,7 @@ export class TeDeumActor extends Actor {
getItemById(id) { getItemById(id) {
let item = this.items.find(item => item.id == id); let item = this.items.find(item => item.id == id);
if (item) { if (item) {
item = duplicate(item) item = foundry.utils.duplicate(item)
} }
return item; return item;
} }
@ -200,29 +406,58 @@ export class TeDeumActor extends Actor {
/* -------------------------------------------- */ /* -------------------------------------------- */
async equipItem(itemId) { async equipItem(itemId) {
let item = this.items.find(item => item.id == itemId) let item = this.items.find(item => item.id == itemId)
if (item?.system) { if (!this.checkArmure(item)) {
if (item.type == "armure") { return
let armor = this.items.find(item => item.id != itemId && item.type == "armor" && item.system.equipped) }
if (armor) { let update = { _id: item.id, "system.equipe": !item.system.equipe };
ui.notifications.warn("You already have an armor equipped!") await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
return }
/* ------------------------------------------- */
checkArmure(item) {
if (item.type != "armure") {
return true
}
if (item.system.equipe) {
return true
}
let nbArmuresLourdes = this.getNbArmuresLourdesActuel()
if (nbArmuresLourdes + item.system.coutArmureLourde > this.getNbArmures().value) {
ui.notifications.warn("Impossible d'équiper cette armure, nombre d'armures lourdes maximum atteint")
return false
}
// Loop thru localisation
let armures = this.getArmures()
for (let loc in item.system.localisation) {
if (item.system.localisation[loc].protege) {
for (let armure of armures) {
if (armure.system.equipe && armure.system.localisation[loc].protege) {
let flag = true
//console.log("Check armure", armure, item)=
if (item.system.typeArmure == "cuir") {
flag = armure.system.superposableCuir
}
if (item.system.typeArmure == "maille") {
flag = armure.system.superposableMaille
}
if (item.system.typeArmure == "plate") {
flag = armure.system.superposablePlate
}
if (!flag) {
ui.notifications.warn("Impossible d'équiper cette armure, non superposable")
return flag
}
}
} }
} }
if (item.type == "shield") { return true
let shield = this.items.find(item => item.id != itemId && item.type == "shield" && item.system.equipped)
if (shield) {
ui.notifications.warn("You already have a shield equipped!")
return
}
}
let update = { _id: item.id, "system.equipped": !item.system.equipped };
await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
} }
} }
/* ------------------------------------------- */ /* ------------------------------------------- */
async buildContainerTree() { async buildContainerTree() {
let equipments = duplicate(this.items.filter(item => item.type == "equipment") || []) let equipments = foundry.utils.duplicate(this.items.filter(item => item.type == "equipment") || [])
for (let equip1 of equipments) { for (let equip1 of equipments) {
if (equip1.system.iscontainer) { if (equip1.system.iscontainer) {
equip1.system.contents = [] equip1.system.contents = []
@ -278,10 +513,13 @@ export class TeDeumActor extends Actor {
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
getInitiativeScore(combatId, combatantId) { getInitiativeScore() {
let init = Math.floor((this.system.attributs.physique.value + this.system.attributs.habilite.value) / 2) let initiative = this.items.find(it => it.type == "competence" && it.name.toLowerCase() == "initiative")
let subValue = new Roll("1d20").roll({ async: false }) if (initiative) {
return init + (subValue.total / 100) return initiative.system.score
}
ui.notifications.warn("Impossible de trouver la compétence Initiative pour l'acteur " + this.name)
return -1;
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
@ -308,7 +546,7 @@ export class TeDeumActor extends Actor {
} }
} }
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
getCommonRollData() { getCommonRollData() {
let rollData = TeDeumUtility.getBasicRollData() let rollData = TeDeumUtility.getBasicRollData()
@ -317,7 +555,7 @@ export class TeDeumActor extends Actor {
rollData.actorId = this.id rollData.actorId = this.id
rollData.img = this.img rollData.img = this.img
rollData.providence = this.prepareProvidence() rollData.providence = this.prepareProvidence()
rollData.malusBlessures = this.calculMalusBlessures() rollData.santeModifier = this.getSanteModifier()
return rollData return rollData
} }
@ -325,12 +563,12 @@ export class TeDeumActor extends Actor {
/* -------------------------------------------- */ /* -------------------------------------------- */
getCommonCompetence(compId) { getCommonCompetence(compId) {
let rollData = this.getCommonRollData() let rollData = this.getCommonRollData()
let competence = duplicate(this.items.find(it => it.type =="competence" && it.id == compId)) let competence = foundry.utils.duplicate(this.items.find(it => it.type == "competence" && it.id == compId))
rollData.competence = competence rollData.competence = competence
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.img = competence.img rollData.img = competence.img
@ -345,17 +583,68 @@ export class TeDeumActor extends Actor {
this.startRoll(rollData).catch("Error on startRoll") this.startRoll(rollData).catch("Error on startRoll")
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
rollArme(armeId) { async rollDegatsArme(armeId) {
let weapon = this.items.get(armeId) let weapon = this.items.get(armeId)
if (weapon) { if (weapon) {
weapon = duplicate(weapon) let bDegats = 0
if ( weapon.system.typeArme == "melee" ) {
bDegats = this.getBonusDegats()
}
let formula = weapon.system.degats + "+" + bDegats.value
let degatsRoll = await new Roll(formula).roll()
await TeDeumUtility.showDiceSoNice(degatsRoll, game.settings.get("core", "rollMode") )
let rollData = this.getCommonRollData()
rollData.mode = "degats"
rollData.formula = formula
rollData.arme = foundry.utils.duplicate(weapon)
rollData.degatsRoll = foundry.utils.duplicate(degatsRoll)
rollData.degats = degatsRoll.total
let msg = await TeDeumUtility.createChatWithRollMode(rollData.alias, {
content: await renderTemplate(`systems/fvtt-te-deum/templates/chat/chat-degats-result.hbs`, rollData)
})
await msg.setFlag("world", "te-deum-rolldata", rollData)
console.log("Rolldata result", rollData)
}
}
/* -------------------------------------------- */
rollArme(armeId, compName = undefined) {
let weapon = this.items.get(armeId)
if (weapon) {
weapon = foundry.utils.duplicate(weapon)
let rollData = this.getCommonRollData() let rollData = this.getCommonRollData()
rollData.mode = "arme" rollData.mode = "arme"
rollData.isTir = weapon.system.typeArme == "tir"
rollData.arme = weapon rollData.arme = weapon
rollData.img = weapon.img rollData.img = weapon.img
rollData.title = weapon.name rollData.title = weapon.name
rollData.porteeTir = "courte"
rollData.porteeLabel = game.system.tedeum.config.ARME_PORTEES.courte.label
rollData.isViser = false
rollData.isMouvement = false
// Display warning if not target defined
if (!rollData.defenderTokenId) {
ui.notifications.warn("Vous attaquez avec une arme : afin de bénéficier des automatisations, il est conseillé de selectionner une cible")
}
// Setup competence + carac
if (!compName) {
let compIdx = weapon.system.competence
compName = game.system.tedeum.config.armeCompetences[compIdx]?.label
}
let competence = this.items.find(item => item.type == "competence" && item.name.toLowerCase() == compName.toLowerCase())
if (competence) {
rollData.competence = competence
let c = foundry.utils.duplicate(this.system.caracteristiques[competence.system.caracteristique])
this.updateCarac(c, competence.system.caracteristique)
rollData.carac = c
} else {
ui.notifications.warn("Impossible de trouver la compétence " + compName)
return
}
this.startRoll(rollData).catch("Error on startRoll") this.startRoll(rollData).catch("Error on startRoll")
} else { } else {
ui.notifications.warn("Impossible de trouver l'arme concernée ") ui.notifications.warn("Impossible de trouver l'arme concernée ")

View File

@ -0,0 +1,625 @@
import { TeDeumUtility } from "../common/tedeum-utility.js";
import { TeDeumActor } from "../actors/tedeum-actor.js";
export class TeDeumCharacterCreator {
/*--------------------------------------------*/
async init() {
this.stages = {}
this.currentStage = "origineSociale"
this.sex = undefined
this.origineSociale = undefined
this.religion = undefined
this.caracBonus = {}
this.competenceBonus = {}
this.suiviReponses = []
this.competences = TeDeumUtility.getCompetencesForDropDown()
for (let k in game.system.tedeum.config.caracteristiques) {
this.caracBonus[k] = { value: 0 }
}
for (let stage in game.system.tedeum.config.etapesEducation) {
this.stages[stage] = { selectedItem: null, items: [] }
}
const educations = await TeDeumUtility.loadCompendium("fvtt-te-deum.education")
for (let edu of educations) {
this.stages[edu.system.etape].items.push(edu)
}
this.processStage()
}
/*--------------------------------------------*/
increaseCompetence(compName) {
if (compName === "" || compName == undefined || compName == "undefined") { return }
compName = compName.toLowerCase()
if (!this.competenceBonus[compName]) {
this.competenceBonus[compName] = { value: 1 }
} else {
this.competenceBonus[compName].value += 1
}
}
/*--------------------------------------------*/
processReponses(question) {
let fullResponses = []
for (let key in question.reponses) {
let response = question.reponses[key]
fullResponses.push({ id: key, label: `${response.reponse} (${TeDeumUtility.upperFirst( response.compName)} +1)` })
}
return fullResponses
}
/*--------------------------------------------*/
processReponsesRadio(question) {
let fullResponses = {}
let selected = true
for (let key in question.reponses) {
let response = question.reponses[key]
if (response.toSelect) {
fullResponses[key] = { label: `${response.reponse}`, competences: response.compList, selected }
} else {
fullResponses[key] = { label: `${response.reponse} (${response.compName} +1)`, selected }
}
selected = false
}
return fullResponses
}
/*--------------------------------------------*/
async askStageName(context) {
const content = await renderTemplate("systems/fvtt-te-deum/templates/dialogs/character-creator-select-stage-name.hbs", context)
const choiceResult = await foundry.applications.api.DialogV2.wait({
window: { title: context.title },
classes: ["fvtt-te-deum"],
content,
buttons: [
{
label: context.label,
callback: (event, button, dialog) => {
const output = Array.from(button.form.elements).reduce((obj, input) => {
if (input.name) obj[input.name] = input.value
return obj
}, {})
return output
},
},
],
actions: {
},
rejectClose: false, // Click on Close button will not launch an error
render: (event, dialog) => {
$(".stage-selector").change(event => {
let stageId = event.target.value
let stage = context.choices.find(item => item.id === stageId)
let link = `<a class="content-link" draggable="true" data-link=""
data-uuid="Compendium.fvtt-te-deum.education.Item.${stageId}" data-id="${stageId}" data-type="Item"
data-pack="fvtt-te-deum.education" data-tooltip="Education Objet"><i class="fas fa-suitcase"></i>${stage.name}</a>`
$(".stage-main-details").html(`Voir le détail : ${link}`)
})
document.getElementById("stage-selector").dispatchEvent(new Event('change'))
}
})
return choiceResult
}
/*--------------------------------------------*/
processCompetences(compList) {
for (let compName in compList) {
this.increaseCompetence(compName)
}
}
/*--------------------------------------------*/
async askQuestionnaire(stage, context) {
context.subtitle = "Questionnaire"
for (let key in stage.system.questionnaire) {
let question = stage.system.questionnaire[key]
if (question.question === "") { break }
context.question = question.question
context.responses = this.processReponses(question)
context.responsesRadio = this.processReponsesRadio(question)
context.competences = {}
context.responseKey = "reponse1" // By default
const content = await renderTemplate("systems/fvtt-te-deum/templates/dialogs/character-creator-select-questions.hbs", context)
const choiceResult = await foundry.applications.api.DialogV2.wait({
window: { title: context.title },
classes: ["fvtt-te-deum"],
content,
buttons: [
{
label: context.label,
callback: (event, button, dialog) => {
const output = Array.from(button.form.elements).reduce((obj, input) => {
if (input.name) obj[input.name] = input.value
return obj
}, {})
return output
},
},
],
actions: {
},
rejectClose: false, // Click on Close button will not launch an error
render: (event, dialog) => {
$(".questionnaire-radio").click(event => {
let responseKey = $(event.target).data("response-key")
context.responseKey = responseKey
})
$(".questionnaire-select-competence").change(event => {
// Get the responseKey data
let responseKey = $(event.target).data("response-key")
let compName = event.target.value
console.log("Questionnaire Change", responseKey, compName)
context.competences[responseKey] = compName.toLowerCase()
})
}
})
if (choiceResult == null) {
this.currentStage = "cancelled"
return
}
let selectedResponse = question.reponses[context.responseKey]
let compName = context.competences[context.responseKey] || selectedResponse.compName
this.increaseCompetence(compName)
this.suiviReponses.push({ etape: stage.name, question: question.question, reponse: selectedResponse.reponse, compName: compName })
}
}
/*------------- -------------------------------*/
async askCompetences(stage, context) {
context.subtitle = "Choix des Compétences"
context.fixedCompetences = {}
context.selectCompetences = {}
for (let compKey in stage.system.competences) {
let comp = stage.system.competences[compKey]
if (comp.valid && comp.compName !== "") {
if (comp.toSelect) {
context.hasSelectCompetences = true
context.selectCompetences[comp.compName] = TeDeumUtility.upperFirst(comp.compName)
} else {
context.fixedCompetences[comp.compName] = TeDeumUtility.upperFirst(comp.compName)
}
}
}
const content = await renderTemplate("systems/fvtt-te-deum/templates/dialogs/character-creator-select-competences.hbs", context)
const choiceResult = await foundry.applications.api.DialogV2.wait({
window: { title: context.title },
classes: ["fvtt-te-deum"],
content,
buttons: [
{
label: context.label,
callback: (event, button, dialog) => {
const output = Array.from(button.form.elements).reduce((obj, input) => {
if (input.name) obj[input.name] = input.value
return obj
}, {})
return output
},
},
],
actions: {
},
rejectClose: false, // Click on Close button will not launch an error
render: (event, dialog) => {
}
})
if (choiceResult == null) {
this.currentStage = "cancelled"
return
}
context.fixedCompetences[choiceResult.selectedCompetence] = choiceResult.selectedCompetence
this.processCompetences(context.fixedCompetences)
// Handle specific case when multiple skills can be selected (ie compagnon case)
if ( stage.system.hasCompetencesOpt ) {
context.fixedCompetences = []
context.hasSelectCompetences = true
for (let i = 0; i < stage.system.competencesOptNumber; i++) {
context.competences = {}
context.selectCompetences = {}
for (let compKey in stage.system.competencesOpt) {
let comp = stage.system.competencesOpt[compKey]
if (comp.compName !== "") {
context.selectCompetences[comp.compName] = TeDeumUtility.upperFirst(comp.compName)
}
}
const content = await renderTemplate("systems/fvtt-te-deum/templates/dialogs/character-creator-select-competences.hbs", context)
const choiceResult = await foundry.applications.api.DialogV2.wait({
window: { title: context.title },
classes: ["fvtt-te-deum"],
content,
buttons: [
{
label: context.label,
callback: (event, button, dialog) => {
const output = Array.from(button.form.elements).reduce((obj, input) => {
if (input.name) obj[input.name] = input.value
return obj
}, {})
return output
},
},
],
actions: {
},
rejectClose: false, // Click on Close button will not launch an error
render: (event, dialog) => {
}
})
if (choiceResult == null) {
this.currentStage = "cancelled"
return
}
context.fixedCompetences[choiceResult.selectedCompetence] = choiceResult.selectedCompetence
this.processCompetences(context.fixedCompetences)
}
}
}
/*------------- -------------------------------*/
async askCarac(stage, context) {
context.subtitle = "Choix des Caractéristiques"
let selected = []
for (let i = 0; i < stage.system.nbChoixCarac; i++) {
context.caracList = []
for (let caracKey in stage.system.caracteristiques) {
let carac = stage.system.caracteristiques[caracKey]
if (selected.includes(carac.caracId)) { continue }
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 choiceResult = await foundry.applications.api.DialogV2.wait({
window: { title: context.title },
classes: ["fvtt-te-deum"],
content,
buttons: [
{
label: context.label,
callback: (event, button, dialog) => {
const output = Array.from(button.form.elements).reduce((obj, input) => {
if (input.name) obj[input.name] = input.value
return obj
}, {})
return output
},
},
],
actions: {
},
rejectClose: false, // Click on Close button will not launch an error
render: (event, dialog) => {
}
})
if (choiceResult == null) {
this.currentStage = "cancelled"
return
}
this.caracBonus[choiceResult.carac].value += 1
selected.push(choiceResult.carac)
}
}
/*--------------------------------------------*/
async renderOrigineSociale(stage) {
let context = {
title: "Création de personnage",
subtitle: "Origine Sociale",
sexeChoice: { "Homme": "Homme", "Femme": "Femme" },
religionChoice: { "catholique": "Catholique", "protestante": "Protestante" },
origineChoice: game.system.tedeum.config.origineSociale
}
const content = await renderTemplate("systems/fvtt-te-deum/templates/dialogs/character-creator-origine.hbs", context)
const label = "Valider le choix de l'Origine Sociale"
const choiceResult = await foundry.applications.api.DialogV2.wait({
window: { title: context.title },
classes: ["fvtt-te-deum"],
content,
buttons: [
{
label: label,
callback: (event, button, dialog) => {
const output = Array.from(button.form.elements).reduce((obj, input) => {
if (input.name) obj[input.name] = input.value
return obj
}, {})
return output
},
},
],
actions: {
},
rejectClose: false, // Click on Close button will not launch an error
render: (event, dialog) => { }
})
if (choiceResult == null) {
this.currentStage = "cancelled"
return
}
this.sexe = choiceResult.sexe
this.religion = choiceResult.religion
this.origineSociale = foundry.utils.duplicate(game.system.tedeum.config.origineSociale[choiceResult.origineSociale])
for (let key in this.origineSociale.caracteristiques) {
this.caracBonus[key].value += this.origineSociale.caracteristiques[key]
}
this.currentStage = "pouponniere"
}
/*--------------------------------------------*/
async renderPouponniere(stage) {
// Filter available pouponniere from origineSociale
let pouponniereItems = stage.items.filter(item => item.system.accessible[this.origineSociale.id].isaccessible)
let context = {
title: "Création de personnage - La Pouponnière",
subtitle: "Choix de la Pouponnière",
label: "Valider le choix de la Pouponnière",
hasGenre: false,
choices: pouponniereItems,
caracBonus: this.caracBonus,
competenceBonus: this.competenceBonus
}
let choiceResult = await this.askStageName(context)
if (choiceResult == null) {
this.currentStage = "cancelled"
return
}
this.pouponniere = foundry.utils.duplicate(stage.items.find(item => item.id === choiceResult.selectedItem))
context.title = `La Pouponnière - ${this.pouponniere.name}`
TeDeumUtility.prepareEducationContent(this.pouponniere);
context.label = "Valider l'augmentation de caracteristique"
await this.askCarac(this.pouponniere, context)
context.label = "Valider l'augmentation de compétences"
await this.askCompetences(this.pouponniere, context)
context.label = "Valider cette réponse"
await this.askQuestionnaire(this.pouponniere, context)
this.currentStage = "petitsgrimauds"
}
/*--------------------------------------------*/
async renderPetitsGrimauds(stage) {
// Filter available pouponniere from origineSociale
let grimaudsItems = stage.items.filter(item => item.system.accessible[this.origineSociale.id].isaccessible && (item.system.genre === this.sexe || item.system.genre === "Mixte"))
let context = {
title: "Les Petits Grimauds",
label: "Valider le choix des Petits Grimauds",
hasGenre: true,
choices: grimaudsItems,
caracBonus: this.caracBonus,
competenceBonus: this.competenceBonus
}
let choiceResult = await this.askStageName(context)
if (choiceResult == null) {
this.currentStage = "cancelled"
return
}
this.grimauds = foundry.utils.duplicate(stage.items.find(item => item.id === choiceResult.selectedItem))
context.title = `LesPetits Grimauds - ${this.grimauds.name}`
TeDeumUtility.prepareEducationContent(this.grimauds);
context.label = "Valider l'augmentation de caracteristique"
await this.askCarac(this.grimauds, context)
context.label = "Valider l'augmentation de compétences"
await this.askCompetences(this.grimauds, context)
context.label = "Valider cette réponse"
await this.askQuestionnaire(this.grimauds, context)
this.currentStage = "rosevie"
}
/*--------------------------------------------*/
async renderRosesDeLaVie(stage) {
// Filter available pouponniere from origineSociale
let rosesItems = stage.items.filter(item => item.system.accessible[this.origineSociale.id].isaccessible && (item.system.genre === this.sexe || item.system.genre === "Mixte"))
let context = {
title: "Création de personnage - Les Roses de la Vie",
label: "Valider le choix des Roses de la Vie",
choices: rosesItems,
hasGenre: true,
caracBonus: this.caracBonus,
competenceBonus: this.competenceBonus
}
let choiceResult = await this.askStageName(context)
if (choiceResult == null) {
this.currentStage = "cancelled"
return
}
this.roses = foundry.utils.duplicate(stage.items.find(item => item.id === choiceResult.selectedItem))
context.title = `Les Roses de la Vie - ${this.roses.name}`
TeDeumUtility.prepareEducationContent(this.roses);
context.label = "Valider l'augmentation de caracteristique"
await this.askCarac(this.roses, context)
context.label = "Valider l'augmentation de compétences"
await this.askCompetences(this.roses, context)
context.label = "Valider cette réponse"
await this.askQuestionnaire(this.roses, context)
this.currentStage = "ageviril"
}
/*--------------------------------------------*/
async renderAgeViril(stage) {
let virilDebouche = this.roses.system.debouches
let ageVirilItems = []
for (let key in virilDebouche) {
let debouche = virilDebouche[key]
if (debouche.debouche === "") { continue }
let deboucheItem = stage.items.find(item => item.name.toLowerCase().includes(debouche.debouche.toLowerCase()))
if (deboucheItem) {
ageVirilItems.push(deboucheItem)
} else {
console.log(`Debouche ${debouche.debouche} not found !`)
}
}
let context = {
title: "Création de personnage - L'Age Viril",
label: "Valider le choix de l'Age Viril",
choices: ageVirilItems,
hasGenre: false,
caracBonus: this.caracBonus,
competenceBonus: this.competenceBonus
}
let choiceResult = await this.askStageName(context)
if (choiceResult == null) {
this.currentStage = "cancelled"
return
}
this.ageViril = foundry.utils.duplicate(stage.items.find(item => item.id === choiceResult.selectedItem))
context.title = `L'Age Viril - ${this.ageViril.name}`
TeDeumUtility.prepareEducationContent(this.ageViril);
context.label = "Valider l'augmentation de caracteristique"
await this.askCarac(this.ageViril, context)
context.label = "Valider l'augmentation de compétences"
await this.askCompetences(this.ageViril, context)
this.currentStage = "finished"
}
/*--------------------------------------------*/
async processStage() {
while (this.currentStage !== "finished") {
let stage = this.stages[this.currentStage]
switch (this.currentStage) {
case "origineSociale":
await this.renderOrigineSociale(stage)
break
case "pouponniere":
await this.renderPouponniere(stage)
break
case "petitsgrimauds":
await this.renderPetitsGrimauds(stage)
break
case "rosevie":
await this.renderRosesDeLaVie(stage)
break
case "ageviril":
await this.renderAgeViril(stage)
break
case "cancelled":
return
break
}
}
console.log("Carac Bonus", this.caracBonus)
console.log("Competence Bonus", this.competenceBonus)
let actor = await TeDeumActor.create({name: "Nouveau personnage", type: "pj"})
let updates = {}
for (let key in this.caracBonus) {
updates[`system.caracteristiques.${key}.value`] = Number(this.caracBonus[key].value)+1
}
updates['system.genre'] = this.sexe
updates['system.religion'] = TeDeumUtility.upperFirst(this.religion)
updates['system.statutocial'] = this.origineSociale.label
updates['system.equipmentfree'] = this.ageViril.system.trousseau
actor.update( updates);
// Process competences : increase know skills
let updateComp = []
let toAdd = []
for (let compName in this.competenceBonus) {
let comp = actor.items.find( i => i.type == "competence" && i.name.toLowerCase() === compName.toLowerCase())
if (comp) {
updateComp.push({ _id: comp._id, "system.score": this.competenceBonus[compName].value })
} else {
toAdd.push( compName)
}
}
actor.updateEmbeddedDocuments("Item", updateComp)
// Process adding skills
let compendiumSkill = TeDeumUtility.getCompetences()
let compToAdd = [ this.pouponniere, this.grimauds, this.roses, this.ageViril ]
for (let compName of toAdd) {
let comp = compendiumSkill.find( i => i.name.toLowerCase() === compName.toLowerCase())
comp.system.score = this.competenceBonus[compName].value
compToAdd.push(comp)
}
await actor.createEmbeddedDocuments('Item', compToAdd)
let newArgent = this.origineSociale.cagnotte * this.ageViril.system.cagnotteMultiplier
newArgent /= this.ageViril.system.cagnotteDivider
await actor.update({ [`system.fortune.${this.origineSociale.cagnotteUnit}`]: newArgent})
let histoire = ""
for (let reponse of this.suiviReponses) {
histoire += `<p>${reponse.question}<br>${reponse.reponse} (${reponse.compName})</p>`
}
await actor.update({ "system.histoire": histoire})
actor.render(true)
context.pointsCompetence = {
"savoir": { score: actor.getCompetenceScore("Mémoriser"), label: "Savoir" },
"sensibilite": { score: actor.getCompetenceScore("Perception"), label: "Sensibilité" },
"entregent": { score: actor.getCompetenceScore("Charme"), label: "Entregent" },
"puissance": { score: actor.getCompetenceScore("Effort"), label: "Puissance" },
"complexion": { score: actor.getCompetenceScore("Endurance"), label: "Complexion" },
"adresse": { score: actor.getCompetenceScore("Initiative"), label: "Adresse" },
}
const content = await renderTemplate("systems/fvtt-te-deum/templates/dialogs/character-creator-finished.hbs", context)
const label = "Terminer"
const choiceResult = await foundry.applications.api.DialogV2.wait({
window: { title: context.title },
classes: ["fvtt-te-deum"],
content,
buttons: [
{
label: label,
callback: (event, button, dialog) => {
const output = Array.from(button.form.elements).reduce((obj, input) => {
if (input.name) obj[input.name] = input.value
return obj
}, {})
return output
},
},
],
actions: {
},
rejectClose: false, // Click on Close button will not launch an error
render: (event, dialog) => { }
})
}
}

View File

@ -5,21 +5,17 @@ export class TeDeumCombat extends Combat {
/* -------------------------------------------- */ /* -------------------------------------------- */
async rollInitiative(ids, formula = undefined, messageOptions = {} ) { async rollInitiative(ids, formula = undefined, messageOptions = {} ) {
//console.log("Roll INIT !")
ids = typeof ids === "string" ? [ids] : ids; ids = typeof ids === "string" ? [ids] : ids;
for (let cId = 0; cId < ids.length; cId++) { for (let cId of ids) {
const c = this.combatants.get(ids[cId]); const c = this.combatants.get(cId);
let id = c._id || c.id; let initBonus = c.actor ? c.actor.getInitiativeScore( this.id, cId ) : -1;
let initBonus = c.actor ? c.actor.getInitiativeScore( this.id, id ) : -1; await this.updateEmbeddedDocuments("Combatant", [ { _id: cId, initiative: initBonus } ]);
await this.updateEmbeddedDocuments("Combatant", [ { _id: id, initiative: initBonus } ]);
} }
return this; return this;
} }
/* -------------------------------------------- */
_onUpdate(changed, options, userId) {
}
/* -------------------------------------------- */ /* -------------------------------------------- */
static async checkTurnPosition() { static async checkTurnPosition() {
while (game.combat.turn > 0) { while (game.combat.turn > 0) {

View File

@ -4,35 +4,35 @@ 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 },
{ 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, id: "pieddroit", nbArmure: 1 }, "pieddroit": { label: "Pied Droit", value: 1, locMod: 0, id: "pieddroit", nbArmure: 1, score: { min: 1, max: 1 }, coord: { top: 500, left: 0 } },
"jambedroite": { label: "Jambe Droite", value: 1, id: "jambedroite", nbArmure: 1 }, "jambedroite": { label: "Jambe Droite", value: 1, locMod: -1, id: "jambedroite", nbArmure: 1, score: { min: 3, max: 4 }, coord: { top: 400, left: 100 } },
"jambegauche": { label: "Jambe Gauche", value: 1, id: "jambegauche", nbArmure: 1 }, "jambegauche": { label: "Jambe Gauche", value: 1, locMod: -1, id: "jambegauche", nbArmure: 1, score: { min: 5, max: 6 }, coord: { top: 400, left: 300 } },
"piedgauche": { label: "Pied Gauche", value: 1, id: "piedgauche", nbArmure: 1 }, "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, id: "piedgauche", nbArmure: 1 }, "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, id: "maindroite", nbArmure: 1 }, "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, id: "maingauche", nbArmure: 1 }, "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, id: "brasdroit", nbArmure: 2 }, "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, id: "brasgauche", nbArmure: 2 }, "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", nbArmure: 2 }, "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", nbArmure: 2 },
}, },
ARME_SPECIFICITE: { ARME_SPECIFICITE: {
"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 },
"peutlancer": { label: "Peut être lancée", id: "peutlancer", melee: true, tir: false}, "peutlancer": { label: "Peut être lancée", id: "peutlancer", melee: true, tir: false },
"pasboutportant": { label: "Inutilisable à bout portant", id: "pasboutportant", melee: false, tir: true}, "pasboutportant": { label: "Inutilisable à bout portant", id: "pasboutportant", melee: false, tir: true },
"rechargearquebusade": { label: "Retrancher l'Arquebusade au temps de recharge", id: "rechargearquebusade", melee: false, tir: true },
"mitraille": { label: "Mitraille", id: "mitraille", melee: false, tir: true }, "mitraille": { label: "Mitraille", id: "mitraille", melee: false, tir: true },
"degatscharge": { label: "Dégâts accrus à la charge", id: "degatscharge", melee: true, tir: false }, "degatscharge": { label: "Dégâts accrus à la charge", id: "degatscharge", melee: true, tir: false },
"crochecavalier": { label: "Croche-cavalier", id: "crochecavalier", melee: true, tir: false }, "crochecavalier": { label: "Croche-cavalier", id: "crochecavalier", melee: true, tir: false },
@ -43,18 +43,23 @@ export const TEDEUM_CONFIG = {
}, },
ARME_PORTEES: { ARME_PORTEES: {
"brulepourpoint": { label: "Brûle-pourpoint", difficulty: "facile", id: "brulepourpoint"}, "brulepourpoint": { label: "Brûle-pourpoint", difficulty: "facile", id: "brulepourpoint" },
"courte": { label: "Courte", difficulty: "pardefaut", id: "courte"}, "courte": { label: "Courte", difficulty: "pardefaut", id: "courte" },
"moyenne": { label: "Moyenne", difficulty: "difficile", id: "moyenne"}, "moyenne": { label: "Moyenne", difficulty: "difficile", id: "moyenne" },
"longue": { label: "Longue", difficulty: "perilleux", id: "longue"}, "longue": { label: "Longue", difficulty: "perilleux", id: "longue" },
"extreme": { label: "Extrême", difficulty: "desespere", id: "extreme"}, "extreme": { label: "Extrême", difficulty: "desespere", id: "extreme" },
},
genre: {
Homme: { label: "Homme", value: "Homme" },
Femme: { label: "Femme", value: "Femme" }
}, },
descriptionValeurOdd: { descriptionValeurOdd: {
1: { valeur: 1, qualite: "Mauvais", dice: "d4", negativeDice: "d20", savoir: "Sot", sensibilite: "Obtus", entregent: "Rustaud", puissance: "Menu", complexion: "Anémique", adresse: "Empesé" }, 1: { valeur: 1, qualite: "Mauvais", dice: "d4", negativeDice: "d20", savoir: "Sot", sensibilite: "Obtus", entregent: "Rustaud", puissance: "Menu", complexion: "Anémique", adresse: "Empesé" },
2: { valeur: 2, qualite: "Médiocre", dice: "d6", negativeDice: "d12", savoir: "Limité", sensibilite: "Etriqué", entregent: "Frustre", puissance: "Délicat", complexion: "Languide", adresse: "Gauche" }, 2: { valeur: 2, qualite: "Médiocre", dice: "d6", negativeDice: "d12", savoir: "Limité", sensibilite: "Etriqué", entregent: "Frustre", puissance: "Délicat", complexion: "Languide", adresse: "Gauche" },
3: { valeur: 3, qualite: "Correct", dice: "d8", negativeDice: "d10", savoir: "Mêlé", sensibilite: "Ouvert", entregent: "Badin", puissance: "Membru", complexion: "Dispos", adresse: "Ingambe" }, 3: { valeur: 3, qualite: "Correct", dice: "d8", negativeDice: "d10", savoir: "Mêlé", sensibilite: "Ouvert", entregent: "Badin", puissance: "Membru", complexion: "Dispos", adresse: "Ingambe" },
4: { valeur: 4, qualite: "Bon", dice: "d10", negativeDice: "d8", savoir: "Lettré", sensibilite: "Fin", entregent: "Disert", puissance: "Vigoureux", complexion: "Gaillard", adresse: "Leste" }, 4: { valeur: 4, qualite: "Bon", dice: "d10", negativeDice: "d8", savoir: "Lettré", sensibilite: "Fin", entregent: "Disert", puissance: "Vigoureux", complexion: "Gaillard", adresse: "Leste" },
5: { valeur: 5, qualite: "Bon", dice: "d10", negativeDice: "d8", savoir: "Lettré", sensibilite: "Fin", entregent: "Disert", puissance: "Vigoureux", complexion: "Gaillard", adresse: "Leste" }, 5: { valeur: 5, qualite: "Bon", dice: "d10", negativeDice: "d8", savoir: "Lettré", sensibilite: "Fin", entregent: "Disert", puissance: "Vigoureux", complexion: "Gaillard", adresse: "Leste" },
6: { valeur: 6, qualite: "Bon", dice: "d10", negativeDice: "d8", savoir: "Lettré", sensibilite: "Fin", entregent: "Disert", puissance: "Vigoureux", complexion: "Gaillard", adresse: "Leste" }, 6: { valeur: 6, qualite: "Bon", dice: "d10", negativeDice: "d8", savoir: "Lettré", sensibilite: "Fin", entregent: "Disert", puissance: "Vigoureux", complexion: "Gaillard", adresse: "Leste" },
7: { valeur: 7, qualite: "Excellent", dice: "d12", negativeDice: "d6", savoir: "Docte", sensibilite: "Subtil", entregent: "Galant", puissance: "Musculeux", complexion: "Sanguin", adresse: "Preste" }, 7: { valeur: 7, qualite: "Excellent", dice: "d12", negativeDice: "d6", savoir: "Docte", sensibilite: "Subtil", entregent: "Galant", puissance: "Musculeux", complexion: "Sanguin", adresse: "Preste" },
@ -72,23 +77,28 @@ export const TEDEUM_CONFIG = {
5: { valeur: 5, qualite: "Excellent", dice: "d12", negativeDice: "d6", savoir: "Docte", sensibilite: "Subtil", entregent: "Galant", puissance: "Musculeux", complexion: "Sanguin", adresse: "Preste" }, 5: { valeur: 5, qualite: "Excellent", dice: "d12", negativeDice: "d6", savoir: "Docte", sensibilite: "Subtil", entregent: "Galant", puissance: "Musculeux", complexion: "Sanguin", adresse: "Preste" },
6: { valeur: 6, qualite: "Admirable", dice: "d20", negativeDice: "d4", savoir: "Humaniste", sensibilite: "Spirituel", entregent: "Sémillant", puissance: "Hercule", complexion: "Aguerri", adresse: "Alerte" }, 6: { valeur: 6, qualite: "Admirable", dice: "d20", negativeDice: "d4", savoir: "Humaniste", sensibilite: "Spirituel", entregent: "Sémillant", puissance: "Hercule", complexion: "Aguerri", adresse: "Alerte" },
}, },
diceValeur: [ "d4", "d6", "d8", "d10", "d12", "d20" ], diceValeur: ["d4", "d6", "d8", "d10", "d12", "d20"],
degatsArmure : { degatsArmure: {
sansarmure : { label: "Sans armure"}, sansarmure: { label: "Sans armure" },
cuir : { label: "Cuir"}, cuir: { label: "Cuir" },
plates : { label: "Plates"}, plates: { label: "Plates" },
mailles : { label: "Mailles"}, mailles: { label: "Mailles" },
}, },
caracteristiques: { caracteristiques: {
savoir: { id: "savoir", value: "savoir", label: "Savoir" }, 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é" }, 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" }, 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" }, 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." },
puissance: { id: "puissance", value: "puissance", label: "Puissance" }, puissance: { id: "puissance", value: "puissance", label: "Puissance", description: "Cette caractéristique correspond à la force physique du personnage. Elle permet d'évaluer la compétence de base Effort, le bonus de dégâts au corps à corps, ainsi que le nombre de pièces d'armure lourde qu'un per- sonnage peut endosser sans être trop ralenti." },
adresse: { id: "adresse", value: "adresse", label: "Adresse" }, 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: {
courte: { courte: { malus: 0 }, moyenne: { malus: -1 }, longue: { malus: -2 }, treslongue: { malus: 0, esquive: 2 } },
moyenne: { courte: { malus: 0 }, moyenne: { malus: 0 }, longue: { malus: -1 }, treslongue: { malus: 0, esquive: 2 } },
longue: { courte: { malus: -2 }, moyenne: { malus: -1 }, longue: { malus: 0 }, treslongue: { malus: -1, esquive: 1 } },
treslongue: { courte: { malus: 0, esquive: 2 }, moyenne: { malus: 0, esquive: 2 }, longue: { malus: 0, esquive: 1 }, treslongue: { 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" },
{ labelM: "Pauvre pêcheur", labelF: "Pauvre pêcheresse", value: 1, diceValue: "d4" }, { labelM: "Pauvre pêcheur", labelF: "Pauvre pêcheresse", value: 1, diceValue: "d4" },
@ -98,16 +108,25 @@ export const TEDEUM_CONFIG = {
{ labelM: "Oint du Seigneur", labelF: "Ointe du Seigneur", value: 5, diceValue: "d12" }, { labelM: "Oint du Seigneur", labelF: "Ointe du Seigneur", value: 5, diceValue: "d12" },
{ labelM: "Dans la main de Dieu", labelF: "Dans la main de Dieu", value: 6, diceValue: "d20" }, { labelM: "Dans la main de Dieu", labelF: "Dans la main de Dieu", value: 6, diceValue: "d20" },
], ],
armureTypes: {
cuir: { label: "Cuir", value: "cuir" },
maille: { label: "Maille", value: "maille" },
plate: { label: "Plate", value: "plate" },
},
armeTypes: { armeTypes: {
melee: { label: "Mêlée", value: "melee" }, melee: { label: "Mêlée", value: "melee" },
tir: { label: "Tir", value: "tir" } tir: { label: "Tir", value: "tir" }
}, },
genreEducation: {
"homme": { label: "Homme", value: "Homme" },
"femme": { label: "Femme", value: "Femme" },
"mixte": { label: "Mixte", value: "Mixte" }
},
armeAllonges: { armeAllonges: {
courte: { label: "Courte", value: "courte" }, courte: { label: "Courte", value: "courte" },
moyenne: { label: "Moyenne", value: "moyenne" }, moyenne: { label: "Moyenne", value: "moyenne" },
longue: { label: "Longue", value: "longue" }, longue: { label: "Longue", value: "longue" },
treslongue: { label: "Très longue", value: "treslongue"} treslongue: { label: "Très longue", value: "treslongue" }
}, },
armeCompetences: { armeCompetences: {
bagarre: { label: "Bagarre", value: "bagarre" }, bagarre: { label: "Bagarre", value: "bagarre" },
@ -118,14 +137,20 @@ export const TEDEUM_CONFIG = {
archerie: { label: "Archerie", value: "archerie" }, archerie: { label: "Archerie", value: "archerie" },
arquebusade: { label: "Arquebusade", value: "arquebusade" } arquebusade: { label: "Arquebusade", value: "arquebusade" }
}, },
competencesRecharge: {
aucune: { label: "Aucune", value: "aucune" },
archerie: { label: "Archerie", value: "archerie" },
arquebusade: { label: "Arquebusade", value: "arquebusade" }
},
difficulte: { difficulte: {
routine: { label: "Routine", value: 3 }, aucune: { label: "Aucune", key: "aucune", value: 0 },
facile: { label: "Facile", value: 5 }, routine: { label: "Routine", key: "routine", value: 3 },
pardefaut: { label: "Par Défaut", value: 7 }, facile: { label: "Facile", key: "facile", value: 5 },
malaise: { label: "Malaisé", value: 9 }, pardefaut: { label: "Par Défaut", key: "pardefaut", value: 7 },
difficile: { label: "difficile", value: 11 }, malaise: { label: "Malaisé", key: "malaise", value: 9 },
perilleux: { label: "Perilleux", value: 13 }, difficile: { label: "Difficile", key: "difficile", value: 11 },
desespere: { label: "Désespéré", value: 15 } perilleux: { label: "Perilleux", key: "perilleux", value: 13 },
desespere: { label: "Désespéré", key: "desespere", value: 15 }
}, },
monnaie: { monnaie: {
denier: { label: "Deniers", id: "denier", value: 1 }, denier: { label: "Deniers", id: "denier", value: 1 },
@ -133,37 +158,57 @@ export const TEDEUM_CONFIG = {
livre: { label: "Livres", id: "livre", value: 100 } livre: { label: "Livres", id: "livre", value: 100 }
}, },
etapesEducation: { etapesEducation: {
pouponniere: { label: "La Pouponnière", value: "pouponniere", agemin: 0, agemax: 6, nbCompetences: 2, nbCaracteristiques: 3, hasQuestionnaire: true, hasMultiplier: false }, pouponniere: { label: "La Pouponnière", value: "pouponniere", agemin: 0, agemax: 6, nbCompetences: 2, nbCaracteristiques: 3, hasGenre: false, hasQuestionnaire: true, hasDebouches: false, hasMultiplier: false, canCompetencesOpt: false },
petitsgrimauds: { label: "La classe des Petits Grimauds", value: "petitsgrimauds", agemin: 7, agemax: 12,nbCompetences: 2, nbCaracteristiques: 3, hasQuestionnaire: true, hasMultiplier: false }, petitsgrimauds: { label: "La classe des Petits Grimauds", value: "petitsgrimauds", agemin: 7, agemax: 12, nbCompetences: 10, hasGenre: true, nbCaracteristiques: 3, hasDebouches: false, hasQuestionnaire: true, hasMultiplier: false, canCompetencesOpt: false },
rosevie: { label: "Les Roses de la Vie", value: "rosevie", agemin: 13, agemax: 16, nbCompetences: 2, nbCaracteristiques: 3, hasQuestionnaire: true, hasMultiplier: false }, rosevie: { label: "Les Roses de la Vie", value: "rosevie", agemin: 13, agemax: 16, nbCompetences: 2, nbCaracteristiques: 3, hasGenre: true, hasQuestionnaire: true, hasDebouches: true, hasMultiplier: false, canCompetencesOpt: false },
ageviril: { label: "L'Age Viril", value: "ageviril", agemin: 17, agemax: 17, nbCompetences: 9, nbCaracteristiques: 2, hasQuestionnaire: false, hasMultiplier: true }, ageviril: { label: "L'Age Viril", value: "ageviril", agemin: 17, agemax: 17, nbCompetences: 9, nbCaracteristiques: 2, hasGenre: false, hasQuestionnaire: false, hasDebouches: false, hasMultiplier: true, canCompetencesOpt: true },
}, },
origineSociale: { origineSociale: {
noblesseepee: { label: "Noblesse d'épée", id: "noblesseepee", value: 1 }, noblesseepee: { label: "Noblesse d'épée", id: "noblesseepee", caracteristiques: { entregent: 1, puissance: 1 }, cagnotte: 10, cagnotteUnit: "livres", value: 1 },
noblessecloche: { label: "Noblesse de cloche", id: "noblessecloche", value: 2 }, noblessecloche: { label: "Noblesse de cloche", id: "noblessecloche", caracteristiques: { entregent: 1, savoir: 1 }, cagnotte: 50, cagnotteUnit: "livres", value: 2 },
hautenoblesse: { label: "Haute noblesse (Illégitime)", id: "hautenoblesse", value: 3 }, hautenoblesse: { label: "Haute noblesse (Illégitime)", id: "hautenoblesse", caracteristiques: { complexion: 1, puissance: 1 }, cagnotte: 20, cagnotteUnit: "livres", value: 3 },
hautebourgeoisie: { label: "Haute bourgeoisie", id: "hautebourgeoisie", value: 4 }, hautebourgeoisie: { label: "Haute bourgeoisie", id: "hautebourgeoisie", caracteristiques: { savoir: 1, sensibilite: 1 }, cagnotte: 60, cagnotteUnit: "livres", value: 4 },
petitebourgeoisie: { label: "Petite bourgeoisie (Marchands)", id: "petitebourgeoisie", value: 5 }, petitebourgeoisie: { label: "Petite bourgeoisie (Marchands)", caracteristiques: { entregent: 1, sensibilite: 1 }, cagnotte: 20, cagnotteUnit: "livres", id: "petitebourgeoisie", value: 5 },
artisan: { label: "Artisans", id: "artisan", value: 6 }, artisan: { label: "Artisans", id: "artisan", caracteristiques: { adresse: 1, sensibilite: 1 }, cagnotte: 10, cagnotteUnit: "livres", value: 6 },
laboureur: { label: "Laboureurs", id: "laboureur", value: 7 }, laboureur: { label: "Laboureurs", id: "laboureur", caracteristiques: { entregent: 1, complexion: 1 }, cagnotte: 10, cagnotteUnit: "livres", value: 7 },
domesticite: { label: "Domesticité", id: "domesticite", value: 8 }, domesticite: { label: "Domesticité", id: "domesticite", caracteristiques: { entregent: 1, adresse: 1 }, cagnotte: 2, cagnotteUnit: "sous", value: 8 },
paysannerie: { label: "Paysannerie", id: "paysannerie", value: 9 }, paysannerie: { label: "Paysannerie", id: "paysannerie", caracteristiques: { puissance: 1, complexion: 1 }, cagnotte: 1, cagnotteUnit: "sous", value: 9 },
gueux: { label: "Gueux", id: "gueux", value: 10 }, gueux: { label: "Gueux", id: "gueux", caracteristiques: { adresse: 1, complexion: 1 }, cagnotte: 4, cagnotteUnit: "deniers", value: 10 },
}, },
bonusMalus: [ bonusMalus: [
{ value: "-2", label: "-2 niveaux" }, { value: "-2", label: "-2 niveaux" },
{ value: "-1", label: "-1 niveau" }, { value: "-1", label: "-1 niveau" },
{ value: "0", label: "Aucun" }, { value: "0", label: "Aucun" },
{ value: "1", label: "+1 niveau" }, { value: "1", label: "+1 niveau" },
{ value: "2", label: "+2 niveaux" } { value: "2", label: "+2 niveaux" }
], ],
blessures: [ blessures: {
{ value: 0, label: "Indemne", degatsMax: -1, count: 0, modifier: 0 }, indemne: { value: 0, label: "Indemne", key: "indemne", degatsMax: -1, count: 0, modifier: 0 },
{ value: 1, label: "Estafilade/Contusion", degatsMax: 2, count: 1, modifier: 0 }, estafilade: { value: 1, label: "Estafilade", key: "estafilade", degatsMin: 0, degatsMax: 2, count: 1, modifier: 0 },
{ value: 2, label: "Plaie", degatsMax: 4, count: 1, modifier: -1 }, plaie: { value: 2, label: "Plaie", key: "plaie", degatsMin: 3, degatsMax: 4, count: 1, modifier: -1 },
{ value: 3, label: "Plaie béante", degatsMax: 6, count: 1, modifier: -2 }, plaiebeante: { value: 3, label: "Plaie béante", key: "plaiebeante", degatsMin: 5, degatsMax: 6, count: 1, modifier: -2 },
{ value: 4, label: "Plaie atroce", degatsMax: 6, count: 1, horsCombat: true, modifier: -12 }, plaieatroce: { value: 4, label: "Plaie atroce", key: "plaieatroce", degatsMin: 7, degatsMax: 8, count: 1, horsCombat: true, modifier: -12 },
{ value: 5, label: "Tué net", degatsMax: 100, count: 1, horsCombat: true, mort: true, modifier: -12 } tunenet: { value: 5, label: "Tué net", key: "tuenet", degatsMin: 9, degatsMax: 100, count: 1, horsCombat: true, mort: true, modifier: -12 }
] },
virulence: {
aucune: { label: "Aucune", value: "aucune", modifier: 0 },
fatigue: { label: "Fatigue", value: "fatigue", modifier: 0 },
epuisement: { label: "Epuisement", value: "epuisement", modifier: -1 },
souffrance: { label: "Souffrance", value: "souffrance", modifier: -2 },
agonie: { label: "Agonie", value: "agonie", modifier: -3 }
},
fievre: {
aucune: { label: "Aucune", value: "aucune" },
legere: { label: "Légère", value: "legere" },
forte: { label: "Forte", value: "forte" },
grave: { label: "Grave", value: "grave" }
},
virulencePoison: {
aucune: { label: "Aucune", value: "aucune", modifier: 0 },
nausee: { label: "Nausées & Vertiges", value: "nausee", modifier: 0 },
inflammation: { label: "Inflammations & Vomissements", value: "inflammation", modifier: -1 },
elancement: { label: "Elancements & Hémorragies", value: "elancement", modifier: -2 },
convulsion: { label: "Convulsions & Délire hallucinatoire", value: "convulsion", modifier: -3 },
mort: { label: "Inconscience & Mort", value: "mort", modifier: -12 }
}
} }

View File

@ -5,7 +5,28 @@ export class TeDeumUtility {
/* -------------------------------------------- */ /* -------------------------------------------- */
static async init() { static async init() {
CONFIG.Actor.compendiumBanner = "systems/fvtt-te-deum/images/ui/compendium_banner.webp"
CONFIG.Item.compendiumBanner = "systems/fvtt-te-deum/images/ui/compendium_banner.webp"
CONFIG.Scene.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.Adventure.compendiumBanner = "systems/fvtt-te-deum/images/ui/compendium_banner.webp"
Hooks.on('renderChatLog', (log, html, data) => TeDeumUtility.chatListeners(html)); Hooks.on('renderChatLog', (log, html, data) => TeDeumUtility.chatListeners(html));
Hooks.on("renderActorDirectory", (app, html, data) => {
if (game.user.can('ACTOR_CREATE')) {
const button = document.createElement('button');
button.style.width = '90%';
button.innerHTML = 'Créer un Personnage'
button.addEventListener('click', () => {
let cr = new game.system.tedeum.TeDeumCharacterCreator();
cr.init()
})
html.find('.header-actions').after(button)
}
})
//Hooks.on("getChatLogEntryContext", (html, options) => TeDeumUtility.chatMenuManager(html, options)); //Hooks.on("getChatLogEntryContext", (html, options) => TeDeumUtility.chatMenuManager(html, options));
} }
@ -46,20 +67,27 @@ export class TeDeumUtility {
accum += block.fn(i); accum += block.fn(i);
return accum; return accum;
}) })
Handlebars.registerHelper('getConfigLabel', function (configName, key) { Handlebars.registerHelper('getConfigLabel', function (configName, key) {
//console.log("getConfigLabel", configName, key)
return game.system.tedeum.config[configName][key].label
})
Handlebars.registerHelper('getConfigLabelArray', function (configName, key) {
//console.log("getConfigLabel", configName, key) //console.log("getConfigLabel", configName, key)
return game.system.tedeum.config[configName][key].label return game.system.tedeum.config[configName][key].label
}) })
Handlebars.registerHelper('isSpecArmeType', function (key, armeType) { Handlebars.registerHelper('isSpecArmeType', function (key, armeType) {
return game.system.tedeum.config.ARME_SPECIFICITE[key][armeType] return game.system.tedeum.config.ARME_SPECIFICITE[key][armeType]
}) })
Handlebars.registerHelper('getConfigLabelWithGender', function (configName, key, genderKey) { Handlebars.registerHelper('getConfigLabelWithGender', function (configName, key, genderKey) {
return game.system.tedeum.config[configName][key]["label"+genderKey] return game.system.tedeum.config[configName][key]["label" + genderKey]
}) })
Handlebars.registerHelper('getCaracDescription', function (key, value) { Handlebars.registerHelper('getCaracDescription', function (key, value) {
return game.system.tedeum.config.descriptionValeur[Number(value)][key] return game.system.tedeum.config.descriptionValeur[Number(value)][key]
}) })
Handlebars.registerHelper('getEducationEtape', function (key) {
return game.system.tedeum.config.etapesEducation[key].label
})
Handlebars.registerHelper('isGM', function () { Handlebars.registerHelper('isGM', function () {
return game.user.isGM return game.user.isGM
@ -70,7 +98,35 @@ export class TeDeumUtility {
this.competences = competences.map(i => i.toObject()) this.competences = competences.map(i => i.toObject())
this.competencesList = {} this.competencesList = {}
for (let i of this.competences) { for (let i of this.competences) {
this.competencesList[i.name.toLowerCase()] = {name:i.name, id: i._id} this.competencesList[i.name.toLowerCase()] = { name: i.name, id: i._id }
}
this.competencesList = Object.entries(this.competencesList).sort().reduce((o, [k, v]) => (o[k] = v, o), {})
}
/* -------------------------------------------- */
static async importDefaultScene() {
let exists = game.scenes.find(j => j.name == "Te Deum");
if (!exists) {
const scenes = await TeDeumUtility.loadCompendium("fvtt-te-deum.scenes")
let newDocuments = scenes.filter(i => i.name == "Te Deum");
if (newDocuments) {
await game.scenes.documentClass.create(newDocuments);
game.scenes.find(i => i.name == "Te Deum").activate();
}
}
}
/* -------------------------------------------- */
static welcomeMessage() {
if (game.user.isGM) {
ChatMessage.create({
user: game.user.id,
whisper: [game.user.id],
content: `<div id="chat-welcome welcome-message-tedeum"><span class="rdd-roll-part">
<strong>Bienvenu dans Te Deum Pour Un Massacre !</strong>
<div class="chat-welcome">Ce système vous est proposé par Open Sesame Games.<br>
Vous trouverez de l'aide dans @UUID[Compendium.fvtt-te-deum.aides.JournalEntry.uNwJgi4kXBCiZmAH]{Aide pour Te Deum}<br>
ainsi que sur le Discord de Foundry FR : https://discord.gg/pPSDNJk</div>` });
} }
} }
@ -85,22 +141,26 @@ export class TeDeumUtility {
/*-------------------------------------------- */ /*-------------------------------------------- */
static prepareEducationContent(formData) { static prepareEducationContent(formData) {
let nbCompetences = game.system.tedeum.config.etapesEducation[formData.system.etape].nbCompetences let etape = game.system.tedeum.config.etapesEducation[formData.system.etape]
let nbCompetences = etape.nbCompetences
for (let key in formData.system.competences) { for (let key in formData.system.competences) {
formData.system.competences[key].valid = false formData.system.competences[key].valid = false
} }
for (let i = 1; i <= nbCompetences; i++) { for (let i = 1; i <= nbCompetences; i++) {
formData.system.competences[`comp${i}`].valid = true formData.system.competences[`comp${i}`].valid = true
} }
let nbCaracteristiques = game.system.tedeum.config.etapesEducation[formData.system.etape].nbCaracteristiques let nbCaracteristiques = etape.nbCaracteristiques
for (let key in formData.system.caracteristiques) { for (let key in formData.system.caracteristiques) {
formData.system.caracteristiques[key].valid = false formData.system.caracteristiques[key].valid = false
} }
for (let i = 1; i <= nbCaracteristiques; i++) { for (let i = 1; i <= nbCaracteristiques; i++) {
formData.system.caracteristiques[`carac${i}`].valid = true formData.system.caracteristiques[`carac${i}`].valid = true
} }
formData.hasQuestionnaire = game.system.tedeum.config.etapesEducation[formData.system.etape].hasQuestionnaire; formData.hasQuestionnaire = etape.hasQuestionnaire;
formData.hasMultiplier = game.system.tedeum.config.etapesEducation[formData.system.etape].hasMultiplier; formData.hasMultiplier = etape.hasMultiplier;
formData.hasDebouches = etape.hasDebouches;
formData.canCompetencesOpt = etape.canCompetencesOpt;
formData.hasGenre = etape.hasGenre;
} }
/*-------------------------------------------- */ /*-------------------------------------------- */
@ -133,45 +193,82 @@ export class TeDeumUtility {
return actor return actor
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
static async manageOpposition(rollData) {
if (!this.currentOpposition) {
// Store rollData as current GM opposition
this.currentOpposition = rollData
ui.notifications.info("Opposition démarrée avec " + rollData.alias);
} else {
// Perform the opposition
let isAttackWinner = true
let rWinner = this.currentOpposition
let rLooser = rollData
if (rWinner.total < rLooser.total) {
rWinner = rollData
rLooser = this.currentOpposition
isAttackWinner = false
}
this.currentOpposition = undefined // Reset opposition
let oppositionData = {
winner: rWinner,
looser: rLooser
}
let msg = await this.createChatWithRollMode(rollData.alias, {
content: await renderTemplate(`systems/fvtt-te-deum/templates/chat/chat-opposition-result.hbs`, oppositionData)
})
await msg.setFlag("world", "te-deum-rolldata", rollData)
// 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) {
this.appliquerDegats(rWinner)
}
console.log("Rolldata result", rollData)
}
}
/* -------------------------------------------- */ /* -------------------------------------------- */
static async appliquerDegats(rollData) {
await this.processAttaqueMelee(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é")
}
}
/* -------------------------------------------- */ /* -------------------------------------------- */ /* -------------------------------------------- */ /* -------------------------------------------- */
static async chatListeners(html) { static async chatListeners(html) {
html.on("click", '.button-select-confront', 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")
ui.notifications.info( game.i18n.localize("ECRY.chat.confrontselect")) if (rollData) {
TeDeumUtility.manageConfrontation(rollData) TeDeumUtility.manageOpposition(rollData, messageId)
}
}) })
html.on("click", '.button-apply-cephaly-difficulty', 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")
let difficulty = $("#" + rollData.rollId + "-cephaly-difficulty").val() if (rollData) {
TeDeumUtility.manageCephalyDifficulty(rollData, difficulty) TeDeumUtility.appliquerDegats(rollData, messageId)
}
}) })
html.on("click", '.button-apply-impact', event => {
let messageId = TeDeumUtility.findChatMessageId(event.currentTarget)
let message = game.messages.get(messageId)
let actor = game.actors.get($(event.currentTarget).data("actor-id"))
actor.modifyImpact($(event.currentTarget).data("impact-type"), $(event.currentTarget).data("impact"), 1)
})
html.on("click", '.button-apply-bonus', event => {
let messageId = TeDeumUtility.findChatMessageId(event.currentTarget)
let message = game.messages.get(messageId)
let actor = game.actors.get($(event.currentTarget).data("actor-id"))
actor.modifyConfrontBonus($(event.currentTarget).data("bonus"))
})
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
static async preloadHandlebarsTemplates() { static async preloadHandlebarsTemplates() {
const templatePaths = [ const templatePaths = [
'systems/fvtt-te-deum/templates/actors/editor-notes-gm.hbs', 'systems/fvtt-te-deum/templates/actors/editor-notes-gm.hbs',
'systems/fvtt-te-deum/templates/items/partial-item-nav.hbs', 'systems/fvtt-te-deum/templates/items/partial-item-nav.hbs',
'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'
] ]
return loadTemplates(templatePaths); return loadTemplates(templatePaths);
} }
@ -248,7 +345,7 @@ export class TeDeumUtility {
console.log("SOCKET MESSAGE", msg) console.log("SOCKET MESSAGE", msg)
if (msg.name == "msg_gm_chat_message") { if (msg.name == "msg_gm_chat_message") {
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 renderTemplate(msg.data.template, rollData),
whisper: game.user.id whisper: game.user.id
@ -340,10 +437,11 @@ export class TeDeumUtility {
} }
} }
if (rollData.diceSum == 1) { if (rollData.diceSum == 1) {
let critiqueRoll = await new Roll(rollData.carac.negativeDice).roll() let critiqueRoll = await new Roll(rollData.carac.negativeDice)
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)
if (critiqueRoll.total > rollData.competence.score) { if (critiqueRoll.total > rollData.competence.system.score) {
rollData.isEchecCritique = true rollData.isEchecCritique = true
} }
} }
@ -352,15 +450,27 @@ export class TeDeumUtility {
/* -------------------------------------------- */ /* -------------------------------------------- */
static modifyDice(dice, bonusMalus) { static modifyDice(dice, bonusMalus) {
let newIndex = game.system.tedeum.config.diceValeur.indexOf(dice) + Number(bonusMalus) let newIndex = game.system.tedeum.config.diceValeur.indexOf(dice) + Number(bonusMalus)
if (newIndex < 0) {
ui.notifications.error("Vos blessures ou maladies vous empêchent de réaliser cette action, vous êtes trop faibles")
return undefined
}
newIndex = Math.min(Math.max(newIndex, 0), game.system.tedeum.config.diceValeur.length - 1) newIndex = Math.min(Math.max(newIndex, 0), game.system.tedeum.config.diceValeur.length - 1)
return game.system.tedeum.config.diceValeur[newIndex] return game.system.tedeum.config.diceValeur[newIndex]
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
static computeRollFormula(rollData, actor, isConfrontation = false) { static computeRollFormula(rollData, actor, isConfrontation = false) {
let diceFormula = "" let diceFormula = ""
if (rollData.competence) { if (rollData.competence) {
let diceBase = this.modifyDice(rollData.carac.dice, rollData.bonusMalus+rollData.malusBlessures) let localModifier = 0
if (rollData.isViser) {
localModifier += 1
}
if (rollData.isMouvement) {
localModifier -= 1
}
let diceBase = this.modifyDice(rollData.carac.dice, localModifier + Number(rollData.bonusMalus) + rollData.santeModifier)
if (!diceBase) return;
diceFormula = diceBase + "x + " + rollData.competence.system.score diceFormula = diceBase + "x + " + rollData.competence.system.score
} }
if (rollData.enableProvidence) { if (rollData.enableProvidence) {
@ -369,17 +479,59 @@ export class TeDeumUtility {
return diceFormula return diceFormula
} }
/* -------------------------------------------- */
static async getLocalisation(rollData) {
let locRoll = await new Roll("1d20").roll()
await this.showDiceSoNice(locRoll, game.settings.get("core", "rollMode"))
rollData.locRoll = foundry.utils.duplicate(locRoll)
for (let key in game.system.tedeum.config.LOCALISATION) {
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
}
}
}
/* -------------------------------------------- */
static async processAttaqueMelee(rollData) {
await this.getLocalisation(rollData)
let actor = game.actors.get(rollData.actorId)
let bDegats = actor.getBonusDegats()
let degatsRoll = await new Roll(rollData.arme.system.degats + "+" + bDegats.value).roll()
await this.showDiceSoNice(degatsRoll, game.settings.get("core", "rollMode"))
rollData.degatsRoll = foundry.utils.duplicate(degatsRoll)
rollData.degats = degatsRoll.total
}
/* -------------------------------------------- */
static async processAttaqueDistance(rollData) {
if (rollData.arme?.system.typeArme != "tir") {
return
}
if (rollData.isSuccess) {
// Roll the location
await this.getLocalisation(rollData)
// Now the degats
let degatsRoll = await new Roll(rollData.arme.system.degats).roll()
await this.showDiceSoNice(rollData.locRoll, game.settings.get("core", "rollMode"))
rollData.degatsRoll = foundry.utils.duplicate(degatsRoll)
rollData.degats = degatsRoll.total
}
}
/* -------------------------------------------- */ /* -------------------------------------------- */
static async rollTeDeum(rollData) { static async rollTeDeum(rollData) {
let actor = game.actors.get(rollData.actorId) let actor = game.actors.get(rollData.actorId)
// Fix difficulty // Fix difficulty
if (!rollData.difficulty || rollData.difficulty == "-") { if (!rollData.difficulty || rollData.difficulty == "-") {
rollData.difficulty = 7 rollData.difficulty = "pardefaut"
} }
rollData.difficulty = game.system.tedeum.config.difficulte[rollData.difficulty].value rollData.difficulty = game.system.tedeum.config.difficulte[rollData.difficulty].value
let diceFormula = this.computeRollFormula(rollData, actor) let diceFormula = this.computeRollFormula(rollData, actor)
if (!diceFormula) return;
console.log("RollData", rollData, diceFormula)
// Performs roll // Performs roll
let myRoll = await new Roll(diceFormula).roll() let myRoll = await new Roll(diceFormula).roll()
@ -391,6 +543,8 @@ export class TeDeumUtility {
await this.computeResults(rollData) await this.computeResults(rollData)
await this.processAttaqueDistance(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 renderTemplate(`systems/fvtt-te-deum/templates/chat/chat-generic-result.hbs`, rollData)
}) })
@ -471,7 +625,7 @@ export class TeDeumUtility {
} }
return array; return array;
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
static async createChatMessage(name, rollMode, chatOptions) { static async createChatMessage(name, rollMode, chatOptions) {
switch (rollMode) { switch (rollMode) {
@ -493,15 +647,15 @@ export class TeDeumUtility {
/* -------------------------------------------- */ /* -------------------------------------------- */
static getBasicRollData() { static getBasicRollData() {
let rollData = { let rollData = {
rollId: randomID(16), rollId: foundry.utils.randomID(16),
type: "roll-data", type: "roll-data",
rollMode: game.settings.get("core", "rollMode"), rollMode: game.settings.get("core", "rollMode"),
difficulty: "pardefaut", difficulty: "pardefaut",
bonusMalus : "0", bonusMalus: "0",
isReroll : false, isReroll: false,
enableProvidence : false, enableProvidence: false,
malusBlessures: 0, malusBlessures: 0,
config: duplicate(game.system.tedeum.config) config: foundry.utils.duplicate(game.system.tedeum.config)
} }
TeDeumUtility.updateWithTarget(rollData) TeDeumUtility.updateWithTarget(rollData)
return rollData return rollData

View File

@ -34,11 +34,14 @@ export class TeDeumArmeSchema extends foundry.abstract.TypeDataModel {
}); });
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.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, min: 0 });
schema.degats = new fields.StringField({ required: false, blank: true, initial: undefined }); schema.degats = new fields.StringField({ required: false, blank: true, initial: "0" });
schema.degatscrosse = new fields.StringField({ required: false, blank: true, initial: "0" });
let comp = [] let comp = []
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);
@ -48,7 +51,9 @@ export class TeDeumArmeSchema extends foundry.abstract.TypeDataModel {
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.description = new fields.HTMLField({ required: true, blank: true }); schema.description = new fields.HTMLField({ required: true, blank: true });
return schema; return schema;

View File

@ -6,6 +6,8 @@ export class TeDeumArmureSchema extends foundry.abstract.TypeDataModel {
const schema = {}; const schema = {};
schema.typeArmure = new fields.StringField({required: true, choices: ["cuir", "maille", "plate"], initial: "cuir"});
schema.localisation = new fields.SchemaField( schema.localisation = new fields.SchemaField(
Object.values(game.system.tedeum.config.LOCALISATION).reduce((obj, loc) => { Object.values(game.system.tedeum.config.LOCALISATION).reduce((obj, loc) => {
obj[loc.id] = new fields.SchemaField({ obj[loc.id] = new fields.SchemaField({
@ -15,10 +17,18 @@ export class TeDeumArmureSchema extends foundry.abstract.TypeDataModel {
}, {}) }, {})
); );
schema.coutArmureLourde = new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 });
schema.superposableCuir = new fields.BooleanField({initial: false});
schema.superposableMaille = new fields.BooleanField({initial: false});
schema.superposablePlate = new fields.BooleanField({initial: false});
schema.protection = new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }); schema.protection = new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 });
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.description = new fields.HTMLField({ required: true, blank: true }); schema.description = new fields.HTMLField({ required: true, blank: true });

View File

@ -0,0 +1,14 @@
export class TeDeumBlessureSchema extends foundry.abstract.TypeDataModel {
static defineSchema() {
const fields = foundry.data.fields;
const requiredInteger = { required: true, nullable: false, integer: true };
const schema = {};
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.description = new fields.HTMLField({ required: true, blank: true });
return schema;
}
}

View File

@ -14,35 +14,68 @@ export class TeDeumEducationSchema extends foundry.abstract.TypeDataModel {
return obj; return obj;
}, {}) }, {})
); );
schema.genre = new fields.StringField({required: true, initial: "Homme", choices: ["masculin", "mixte", "Homme", "Femme", "Mixte"]});
schema.nbChoixCarac = new fields.NumberField({ ...requiredInteger, initial: 1, min: 1 });
schema.caracteristiques = new fields.SchemaField(Array.fromRange(3, 1).reduce((caracs, i) => { schema.caracteristiques = new fields.SchemaField(Array.fromRange(3, 1).reduce((caracs, i) => {
caracs[`carac${i}`] = new fields.SchemaField({ caracs[`carac${i}`] = new fields.SchemaField({
caracId: new fields.StringField({ required: true, blank: false, initial: "entregent" }) caracId: new fields.StringField({ required: true, blank: false, initial: "entregent" })
}); });
return caracs; return caracs;
}, {})); }, {}));
schema.competences = new fields.SchemaField(Array.fromRange(9, 1).reduce((comps, i) => {
schema.competences = new fields.SchemaField(Array.fromRange(10, 1).reduce((comps, i) => {
comps[`comp${i}`] = new fields.SchemaField({
compName: new fields.StringField({ required: true, blank: true, initial: "" }),
toSelect: new fields.BooleanField({ initial: false })
});
return comps;
}, {}));
schema.hasCompetencesOpt = new fields.BooleanField({initial: false})
schema.competencesOptNumber = new fields.NumberField({ ...requiredInteger, initial: 1, min:0 })
schema.competencesOpt = new fields.SchemaField(Array.fromRange(14, 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: "" })
}); });
return comps; return comps;
}, {})); }, {}));
schema.questionnaire = new fields.SchemaField(Array.fromRange(4, 1).reduce((questions, i) => {
schema.questionnaire = new fields.SchemaField(Array.fromRange(8, 1).reduce((questions, i) => {
questions[`question${i}`] = new fields.SchemaField({ questions[`question${i}`] = new fields.SchemaField({
question: new fields.StringField({ required: true, blank: true, initial: "" }), question: new fields.StringField({ required: true, blank: true, initial: "" }),
reponses: new fields.SchemaField( Array.fromRange(6, 1).reduce((resp, i) => { reponses: new fields.SchemaField( Array.fromRange(6, 1).reduce((resp, i) => {
resp[`reponse${i}`] = new fields.SchemaField({ resp[`reponse${i}`] = new fields.SchemaField({
num: new fields.NumberField({ ...requiredInteger, initial: i, min:i }), num: new fields.NumberField({ ...requiredInteger, initial: i, min:i }),
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 }),
compList: new fields.SchemaField(Array.fromRange(10, 1).reduce((comps, i) => {
comps[`comp${i}`] = new fields.SchemaField({
compName: new fields.StringField({ required: true, blank: true, initial: "" }),
});
return comps;
}, {}))
}); });
return resp; return resp;
}, {})) }, {}))
}); });
return questions; return questions;
}, {})); }, {}));
schema.debouches = new fields.SchemaField(Array.fromRange(24, 1).reduce((debouches, i) => {
debouches[`debouche${i}`] = new fields.SchemaField({
debouche: new fields.StringField({ required: true, blank: true, initial: "" })
})
return debouches;
}, {}));
schema.cagnotteMultiplier = new fields.NumberField({ ...requiredDouble, initial: 1.0, min: 0 }); schema.cagnotteMultiplier = new fields.NumberField({ ...requiredDouble, initial: 1.0, min: 0 });
schema.cagnotteDivider = new fields.NumberField({ ...requiredDouble, initial: 1.0, min: 0 });
schema.description = new fields.HTMLField({ required: true, blank: true }); schema.description = new fields.HTMLField({ required: true, blank: true });
schema.trousseau = new fields.StringField({ required: true, blank: true, initial: "" });
return schema; return schema;
} }

View File

@ -0,0 +1,18 @@
export class TeDeumMaladieSchema extends foundry.abstract.TypeDataModel {
static defineSchema() {
const fields = foundry.data.fields;
const requiredInteger = { required: true, nullable: false, integer: true };
const schema = {};
schema.transmission = new fields.HTMLField({ required: true, blank: true });
schema.difficulteEndurance = new fields.StringField({required:true, initial:"routine"});
schema.virulence = new fields.StringField({required: true, choices: ["fatigue", "epuisement", "souffrance", "agonie"], initial: "fatigue"});
schema.fievre = new fields.StringField({required: true, choices: ["aucune", "legere", "forte", "grave"], initial: "aucune"});
schema.symptomes = new fields.HTMLField({ required: true, blank: true });
schema.appliquee = new fields.BooleanField({initial: false}),
schema.description = new fields.HTMLField({ required: true, blank: true });
return schema;
}
}

View File

@ -23,7 +23,9 @@ export class TeDeumPJSchema extends foundry.abstract.TypeDataModel {
schema.localisation = new fields.SchemaField( schema.localisation = new fields.SchemaField(
Object.values(game.system.tedeum.config.LOCALISATION).reduce((obj, loc) => { Object.values(game.system.tedeum.config.LOCALISATION).reduce((obj, loc) => {
obj[loc.id] =new fields.SchemaField({ obj[loc.id] = new fields.SchemaField({
armure: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0, max: 20 }),
touche: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0, max: 20 }),
blessures: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0, max: 20 }) blessures: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0, max: 20 })
}); });
return obj; return obj;
@ -31,7 +33,7 @@ export class TeDeumPJSchema extends foundry.abstract.TypeDataModel {
); );
schema.fortune = new fields.SchemaField({ schema.fortune = new fields.SchemaField({
"ecu": new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }), "ecus": new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }),
"livres": new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }) , "livres": new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }) ,
"sous": new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }) , "sous": new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }) ,
"deniers": new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }) "deniers": new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 })
@ -39,14 +41,18 @@ export class TeDeumPJSchema extends foundry.abstract.TypeDataModel {
schema.description = new fields.HTMLField({required: true, blank: true}); schema.description = new fields.HTMLField({required: true, blank: true});
schema.connaissances = new fields.HTMLField({required: true, blank: true}); schema.connaissances = new fields.HTMLField({required: true, blank: true});
schema.histoire = new fields.HTMLField({required: true, blank: true});
schema.vetements = new fields.HTMLField({required: true, blank: true}); schema.vetements = new fields.HTMLField({required: true, blank: true});
//schema.descriptiongraces = new fields.HTMLField({required: true, blank: true}); schema.equipmentfree = new fields.HTMLField({required: true, blank: true});
schema.genre = new fields.StringField({required: true, choices: ["Homme", "Femme"], initial: "Femme"});
schema.genre = new fields.StringField({required: true, choices: game.system.tedeum.config.genre, initial: "Femme"});
schema.age = new fields.StringField({ required: false, blank: true, initial: undefined }); schema.age = new fields.StringField({ required: false, blank: true, initial: undefined });
schema.statutocial = new fields.StringField({ required: false, blank: true, initial: undefined }); schema.statutocial = new fields.StringField({ required: false, blank: true, initial: undefined });
schema.chargestitre = new fields.StringField({ required: false, blank: true, initial: undefined }); schema.chargestitre = new fields.StringField({ required: false, blank: true, initial: undefined });
schema.charges = new fields.StringField({ required: false, blank: true, initial: undefined }); schema.charges = new fields.StringField({ required: false, blank: true, initial: undefined });
schema.religion = new fields.StringField({ required: false, blank: true, initial: undefined });
schema.lieunaissance = new fields.StringField({ required: false, blank: true, initial: undefined });
return schema; return schema;
} }
} }

View File

@ -0,0 +1,20 @@
export class TeDeumMaladieSchema extends foundry.abstract.TypeDataModel {
static defineSchema() {
const fields = foundry.data.fields;
const requiredInteger = { required: true, nullable: false, integer: true };
const schema = {};
schema.difficulteEndurance = new fields.StringField({required:true, initial:"aucun"});
schema.virulence = new fields.StringField({required: true, choices: ["nausee", "inflammation", "elancement", "convulsion", "mort"], initial: "aucune"});
schema.vertus = new fields.HTMLField({ required: true, blank: true });
schema.toxicite = new fields.HTMLField({ required: true, blank: true });
schema.appliquee = new fields.BooleanField({initial: false}),
schema.prix = new fields.NumberField({ ...requiredDouble, initial: 0, min: 0 });
schema.monnaie = new fields.StringField({ required: true, blank: false, initial: "denier" });
schema.description = new fields.HTMLField({ required: true, blank: true });
return schema;
}
}

View File

@ -69,6 +69,18 @@ export class TeDeumRollDialog extends Dialog {
html.find('#roll-enable-providence').change((event) => { html.find('#roll-enable-providence').change((event) => {
this.rollData.enableProvidence = event.currentTarget.checked this.rollData.enableProvidence = event.currentTarget.checked
}) })
html.find('#roll-portee-tir').change((event) => {
this.rollData.porteeTir = event.currentTarget.value
this.rollData.difficulty = game.system.tedeum.config.ARME_PORTEES[this.rollData.porteeTir].difficulty
this.rollData.porteeLabel = game.system.tedeum.config.ARME_PORTEES[this.rollData.porteeTir].label
})
html.find('#roll-tir-viser').change((event) => {
this.rollData.isViser = event.currentTarget.checked
})
html.find('#roll-tir-mouvement').change((event) => {
this.rollData.isMouvement = event.currentTarget.checked
})
} }

View File

@ -8,7 +8,7 @@ export class TeDeumItemSheet extends ItemSheet {
/** @override */ /** @override */
static get defaultOptions() { static get defaultOptions() {
return mergeObject(super.defaultOptions, { return foundry.utils.mergeObject(super.defaultOptions, {
classes: ["fvtt-te-deum", "sheet", "item"], classes: ["fvtt-te-deum", "sheet", "item"],
template: "systems/fvtt-te-deum/templates/item-sheet.hbs", template: "systems/fvtt-te-deum/templates/item-sheet.hbs",
dragDrop: [{ dragSelector: null, dropSelector: null }], dragDrop: [{ dragSelector: null, dropSelector: null }],
@ -43,8 +43,8 @@ export class TeDeumItemSheet extends ItemSheet {
name: this.object.name, name: this.object.name,
editable: this.isEditable, editable: this.isEditable,
cssClass: this.isEditable ? "editable" : "locked", cssClass: this.isEditable ? "editable" : "locked",
system: duplicate(this.object.system), system: foundry.utils.duplicate(this.object.system),
config: duplicate(game.system.tedeum.config), config: foundry.utils.duplicate(game.system.tedeum.config),
competences: TeDeumUtility.getCompetencesForDropDown(), competences: TeDeumUtility.getCompetencesForDropDown(),
limited: this.object.limited, limited: this.object.limited,
options: this.options, options: this.options,

View File

@ -7,6 +7,9 @@ export const defaultItemImg = {
competence: "systems/fvtt-te-deum/images/icons/competence.webp", competence: "systems/fvtt-te-deum/images/icons/competence.webp",
education: "systems/fvtt-te-deum/images/icons/education.webp", education: "systems/fvtt-te-deum/images/icons/education.webp",
grace: "systems/fvtt-te-deum/images/icons/grace.webp", grace: "systems/fvtt-te-deum/images/icons/grace.webp",
blessure: "systems/fvtt-te-deum/images/icons/blessure.webp",
maladie: "systems/fvtt-te-deum/images/icons/maladie.webp",
simple: "systems/fvtt-te-deum/images/icons/simple.webp",
} }
/** /**

View File

@ -19,12 +19,15 @@ import { TeDeumEquipementSchema } from "./data/tedeum-schema-equipement.js";
import { TeDeumOrigineSchema } from "./data/tedeum-schema-origine.js"; import { TeDeumOrigineSchema } from "./data/tedeum-schema-origine.js";
import { TeDeumEducationSchema } from "./data/tedeum-schema-education.js"; import { TeDeumEducationSchema } from "./data/tedeum-schema-education.js";
import { TeDeumGraceSchema } from "./data/tedeum-schema-grace.js"; import { TeDeumGraceSchema } from "./data/tedeum-schema-grace.js";
import { TeDeumBlessureSchema } from "./data/tedeum-schema-blessure.js";
import { TeDeumMaladieSchema } from "./data/tedeum-schema-maladie.js";
import { TeDeumItem } from "./items/tedeum-item.js"; import { TeDeumItem } from "./items/tedeum-item.js";
import { TeDeumItemSheet } from "./items/tedeum-item-sheet.js"; import { TeDeumItemSheet } from "./items/tedeum-item-sheet.js";
import { TeDeumHotbar } from "./app/tedeum-hotbar.js" import { TeDeumHotbar } from "./app/tedeum-hotbar.js"
import { TeDeumCombat } from "./app/tedeum-combat.js"; import { TeDeumCombat } from "./app/tedeum-combat.js";
import { TeDeumCharacterCreator } from "./app/tedeum-character-creator.js"
import { TeDeumUtility } from "./common/tedeum-utility.js"; import { TeDeumUtility } from "./common/tedeum-utility.js";
import { TEDEUM_CONFIG } from "./common/tedeum-config.js"; import { TEDEUM_CONFIG } from "./common/tedeum-config.js";
@ -40,6 +43,7 @@ Hooks.once("init", async function () {
game.system.tedeum = { game.system.tedeum = {
config: TEDEUM_CONFIG, config: TEDEUM_CONFIG,
TeDeumCharacterCreator,
TeDeumHotbar TeDeumHotbar
} }
console.log(`Initializing TeDeum RPG 2`); console.log(`Initializing TeDeum RPG 2`);
@ -57,7 +61,7 @@ Hooks.once("init", async function () {
TeDeumUtility.onSocketMesssage(data) TeDeumUtility.onSocketMesssage(data)
}); });
//CONFIG.Combat.documentClass = TeDeumCombat CONFIG.Combat.documentClass = TeDeumCombat
CONFIG.Actor.documentClass = TeDeumActor; CONFIG.Actor.documentClass = TeDeumActor;
CONFIG.Item.documentClass = TeDeumItem CONFIG.Item.documentClass = TeDeumItem
CONFIG.Actor.dataModels = { CONFIG.Actor.dataModels = {
@ -71,7 +75,9 @@ Hooks.once("init", async function () {
armure: TeDeumArmureSchema, armure: TeDeumArmureSchema,
origine: TeDeumOrigineSchema, origine: TeDeumOrigineSchema,
education: TeDeumEducationSchema, education: TeDeumEducationSchema,
grace: TeDeumGraceSchema grace: TeDeumGraceSchema,
blessure: TeDeumBlessureSchema,
maladie: TeDeumMaladieSchema,
}; };
console.log("TeDeum RPG | Ready"); console.log("TeDeum RPG | Ready");
@ -86,16 +92,6 @@ Hooks.once("init", async function () {
TeDeumUtility.init() TeDeumUtility.init()
}); });
/* -------------------------------------------- */
function welcomeMessage() {
if (game.user.isGM) {
ChatMessage.create({
user: game.user.id,
whisper: [game.user.id],
content: `<div id="welcome-message-tedeum"><span class="rdd-roll-part">
<strong>Bienvenu dans Te Deum Pour Un Massacre !</strong>` });
}
}
/* -------------------------------------------- */ /* -------------------------------------------- */
/* Foundry VTT Initialization */ /* Foundry VTT Initialization */
@ -119,7 +115,8 @@ Hooks.once("ready", function () {
) )
TeDeumUtility.ready(); TeDeumUtility.ready();
welcomeMessage(); TeDeumUtility.importDefaultScene()
TeDeumUtility.welcomeMessage();
}) })

BIN
packs/aides/000072.ldb Normal file

Binary file not shown.

1
packs/aides/CURRENT Normal file
View File

@ -0,0 +1 @@
MANIFEST-000081

7
packs/aides/LOG Normal file
View File

@ -0,0 +1,7 @@
2025/03/18-20:02:55.715587 7fbe66ffd6c0 Recovering log #79
2025/03/18-20:02:55.727775 7fbe66ffd6c0 Delete type=3 #77
2025/03/18-20:02:55.727902 7fbe66ffd6c0 Delete type=0 #79
2025/03/18-20:34:57.401764 7fbe663ff6c0 Level-0 table #84: started
2025/03/18-20:34:57.401796 7fbe663ff6c0 Level-0 table #84: 0 bytes OK
2025/03/18-20:34:57.408016 7fbe663ff6c0 Delete type=0 #82
2025/03/18-20:34:57.415964 7fbe663ff6c0 Manual compaction at level-0 from '!journal!uNwJgi4kXBCiZmAH' @ 72057594037927935 : 1 .. '!journal.pages!uNwJgi4kXBCiZmAH.onhNU0mXhOpdNZJF' @ 0 : 0; will stop at (end)

7
packs/aides/LOG.old Normal file
View File

@ -0,0 +1,7 @@
2025/03/11-18:04:31.143055 7f24c6ffd6c0 Recovering log #75
2025/03/11-18:04:31.153035 7f24c6ffd6c0 Delete type=3 #73
2025/03/11-18:04:31.153146 7f24c6ffd6c0 Delete type=0 #75
2025/03/11-18:27:51.833675 7f24c4bff6c0 Level-0 table #80: started
2025/03/11-18:27:51.833743 7f24c4bff6c0 Level-0 table #80: 0 bytes OK
2025/03/11-18:27:51.840981 7f24c4bff6c0 Delete type=0 #78
2025/03/11-18:27:51.853984 7f24c4bff6c0 Manual compaction at level-0 from '!journal!uNwJgi4kXBCiZmAH' @ 72057594037927935 : 1 .. '!journal.pages!uNwJgi4kXBCiZmAH.onhNU0mXhOpdNZJF' @ 0 : 0; will stop at (end)

BIN
packs/aides/MANIFEST-000081 Normal file

Binary file not shown.

View File

View File

View File

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
packs/armes/000174.ldb Normal file

Binary file not shown.

0
packs/armes/000185.log Normal file
View File

1
packs/armes/CURRENT Normal file
View File

@ -0,0 +1 @@
MANIFEST-000183

0
packs/armes/LOCK Normal file
View File

7
packs/armes/LOG Normal file
View File

@ -0,0 +1,7 @@
2025/03/18-20:02:55.593062 7fbe67fff6c0 Recovering log #181
2025/03/18-20:02:55.605860 7fbe67fff6c0 Delete type=3 #179
2025/03/18-20:02:55.605967 7fbe67fff6c0 Delete type=0 #181
2025/03/18-20:34:57.329715 7fbe663ff6c0 Level-0 table #186: started
2025/03/18-20:34:57.329814 7fbe663ff6c0 Level-0 table #186: 0 bytes OK
2025/03/18-20:34:57.336235 7fbe663ff6c0 Delete type=0 #184
2025/03/18-20:34:57.356288 7fbe663ff6c0 Manual compaction at level-0 from '!folders!InCQeTRdT5jXMX82' @ 72057594037927935 : 1 .. '!items!wxIHkrq98eQ3cOvp' @ 0 : 0; will stop at (end)

7
packs/armes/LOG.old Normal file
View File

@ -0,0 +1,7 @@
2025/03/11-18:04:31.045395 7f24c5ffb6c0 Recovering log #177
2025/03/11-18:04:31.056356 7f24c5ffb6c0 Delete type=3 #175
2025/03/11-18:04:31.056467 7f24c5ffb6c0 Delete type=0 #177
2025/03/11-18:27:51.772304 7f24c4bff6c0 Level-0 table #182: started
2025/03/11-18:27:51.772338 7f24c4bff6c0 Level-0 table #182: 0 bytes OK
2025/03/11-18:27:51.778305 7f24c4bff6c0 Delete type=0 #180
2025/03/11-18:27:51.798039 7f24c4bff6c0 Manual compaction at level-0 from '!folders!InCQeTRdT5jXMX82' @ 72057594037927935 : 1 .. '!items!wxIHkrq98eQ3cOvp' @ 0 : 0; will stop at (end)

BIN
packs/armes/MANIFEST-000183 Normal file

Binary file not shown.

View File

View File

View File

View File

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
packs/armures/000174.ldb Normal file

Binary file not shown.

0
packs/armures/000185.log Normal file
View File

1
packs/armures/CURRENT Normal file
View File

@ -0,0 +1 @@
MANIFEST-000183

0
packs/armures/LOCK Normal file
View File

7
packs/armures/LOG Normal file
View File

@ -0,0 +1,7 @@
2025/03/18-20:02:55.610587 7fbe66ffd6c0 Recovering log #181
2025/03/18-20:02:55.621230 7fbe66ffd6c0 Delete type=3 #179
2025/03/18-20:02:55.621425 7fbe66ffd6c0 Delete type=0 #181
2025/03/18-20:34:57.336450 7fbe663ff6c0 Level-0 table #186: started
2025/03/18-20:34:57.336506 7fbe663ff6c0 Level-0 table #186: 0 bytes OK
2025/03/18-20:34:57.343480 7fbe663ff6c0 Delete type=0 #184
2025/03/18-20:34:57.356316 7fbe663ff6c0 Manual compaction at level-0 from '!folders!2wTJBj3dicRKzNOE' @ 72057594037927935 : 1 .. '!items!ufvhWG5V8pX0qrtR' @ 0 : 0; will stop at (end)

7
packs/armures/LOG.old Normal file
View File

@ -0,0 +1,7 @@
2025/03/11-18:04:31.059498 7f24c6ffd6c0 Recovering log #177
2025/03/11-18:04:31.068855 7f24c6ffd6c0 Delete type=3 #175
2025/03/11-18:04:31.068919 7f24c6ffd6c0 Delete type=0 #177
2025/03/11-18:27:51.778439 7f24c4bff6c0 Level-0 table #182: started
2025/03/11-18:27:51.778466 7f24c4bff6c0 Level-0 table #182: 0 bytes OK
2025/03/11-18:27:51.784375 7f24c4bff6c0 Delete type=0 #180
2025/03/11-18:27:51.798058 7f24c4bff6c0 Manual compaction at level-0 from '!folders!2wTJBj3dicRKzNOE' @ 72057594037927935 : 1 .. '!items!ufvhWG5V8pX0qrtR' @ 0 : 0; will stop at (end)

Binary file not shown.

View File

View File

View File

View File

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

View File

@ -1 +1 @@
MANIFEST-000097 MANIFEST-000180

View File

@ -1,8 +1,7 @@
2024/06/04-21:04:01.195163 7f1e64e006c0 Recovering log #94 2025/03/18-20:02:55.575835 7fbe677fe6c0 Recovering log #178
2024/06/04-21:04:01.205547 7f1e64e006c0 Delete type=3 #92 2025/03/18-20:02:55.586561 7fbe677fe6c0 Delete type=3 #176
2024/06/04-21:04:01.205638 7f1e64e006c0 Delete type=0 #94 2025/03/18-20:02:55.586685 7fbe677fe6c0 Delete type=0 #178
2024/06/04-21:04:48.464146 7f1e5da006c0 Level-0 table #100: started 2025/03/18-20:34:57.343590 7fbe663ff6c0 Level-0 table #183: started
2024/06/04-21:04:48.464176 7f1e5da006c0 Level-0 table #100: 0 bytes OK 2025/03/18-20:34:57.343614 7fbe663ff6c0 Level-0 table #183: 0 bytes OK
2024/06/04-21:04:48.500422 7f1e5da006c0 Delete type=0 #98 2025/03/18-20:34:57.349686 7fbe663ff6c0 Delete type=0 #181
2024/06/04-21:04:48.500602 7f1e5da006c0 Manual compaction at level-0 from '!folders!4OPhigzcPv46qbWW' @ 72057594037927935 : 1 .. '!items!zwC0H39ar5Pl1l92' @ 0 : 0; will stop at (end) 2025/03/18-20:34:57.356337 7fbe663ff6c0 Manual compaction at level-0 from '!folders!4OPhigzcPv46qbWW' @ 72057594037927935 : 1 .. '!items!yx4k7lQHGcom99mk' @ 0 : 0; will stop at (end)
2024/06/04-21:04:48.500619 7f1e5da006c0 Manual compaction at level-1 from '!folders!4OPhigzcPv46qbWW' @ 72057594037927935 : 1 .. '!items!zwC0H39ar5Pl1l92' @ 0 : 0; will stop at (end)

View File

@ -1,15 +1,7 @@
2024/06/02-20:22:04.658032 7f2f302006c0 Recovering log #90 2025/03/11-18:04:31.031690 7f24c57fa6c0 Recovering log #174
2024/06/02-20:22:04.712047 7f2f302006c0 Delete type=3 #88 2025/03/11-18:04:31.041244 7f24c57fa6c0 Delete type=3 #172
2024/06/02-20:22:04.712099 7f2f302006c0 Delete type=0 #90 2025/03/11-18:04:31.041294 7f24c57fa6c0 Delete type=0 #174
2024/06/02-20:58:31.396230 7f2f2ee006c0 Level-0 table #95: started 2025/03/11-18:27:51.791921 7f24c4bff6c0 Level-0 table #179: started
2024/06/02-20:58:31.399756 7f2f2ee006c0 Level-0 table #95: 28482 bytes OK 2025/03/11-18:27:51.791971 7f24c4bff6c0 Level-0 table #179: 0 bytes OK
2024/06/02-20:58:31.406774 7f2f2ee006c0 Delete type=0 #93 2025/03/11-18:27:51.797892 7f24c4bff6c0 Delete type=0 #177
2024/06/02-20:58:31.406940 7f2f2ee006c0 Manual compaction at level-0 from '!folders!4OPhigzcPv46qbWW' @ 72057594037927935 : 1 .. '!items!zwC0H39ar5Pl1l92' @ 0 : 0; will stop at (end) 2025/03/11-18:27:51.798085 7f24c4bff6c0 Manual compaction at level-0 from '!folders!4OPhigzcPv46qbWW' @ 72057594037927935 : 1 .. '!items!yx4k7lQHGcom99mk' @ 0 : 0; will stop at (end)
2024/06/02-20:58:31.406967 7f2f2ee006c0 Manual compaction at level-1 from '!folders!4OPhigzcPv46qbWW' @ 72057594037927935 : 1 .. '!items!zwC0H39ar5Pl1l92' @ 0 : 0; will stop at '!items!zwC0H39ar5Pl1l92' @ 390 : 1
2024/06/02-20:58:31.406972 7f2f2ee006c0 Compacting 1@1 + 1@2 files
2024/06/02-20:58:31.410472 7f2f2ee006c0 Generated table #96@1: 113 keys, 15164 bytes
2024/06/02-20:58:31.410495 7f2f2ee006c0 Compacted 1@1 + 1@2 files => 15164 bytes
2024/06/02-20:58:31.416350 7f2f2ee006c0 compacted to: files[ 0 0 1 0 0 0 0 ]
2024/06/02-20:58:31.416439 7f2f2ee006c0 Delete type=2 #5
2024/06/02-20:58:31.416583 7f2f2ee006c0 Delete type=2 #95
2024/06/02-20:58:31.416682 7f2f2ee006c0 Manual compaction at level-1 from '!items!zwC0H39ar5Pl1l92' @ 390 : 1 .. '!items!zwC0H39ar5Pl1l92' @ 0 : 0; will stop at (end)

Binary file not shown.

Binary file not shown.

View File

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