diff --git a/icons/sante/blessure-mort.webp b/icons/sante/blessure-mort.webp
new file mode 100644
index 00000000..21294caf
Binary files /dev/null and b/icons/sante/blessure-mort.webp differ
diff --git a/icons/sante/blessure-soins.webp b/icons/sante/blessure-soins.webp
new file mode 100644
index 00000000..a8c317d7
Binary files /dev/null and b/icons/sante/blessure-soins.webp differ
diff --git a/icons/sante/blessure.webp b/icons/sante/blessure.webp
new file mode 100644
index 00000000..f3901608
Binary files /dev/null and b/icons/sante/blessure.webp differ
diff --git a/icons/sante/eraflure.webp b/icons/sante/eraflure.webp
new file mode 100644
index 00000000..fc3b4a10
Binary files /dev/null and b/icons/sante/eraflure.webp differ
diff --git a/icons/sante/mort.webp b/icons/sante/mort.webp
new file mode 100644
index 00000000..7bbe0626
Binary files /dev/null and b/icons/sante/mort.webp differ
diff --git a/lang/fr.json b/lang/fr.json
index f8cf04e8..a671f680 100644
--- a/lang/fr.json
+++ b/lang/fr.json
@@ -7,47 +7,48 @@
"TypeVehicule": "Véhicule"
},
"ITEM": {
- "TypeObjet": "Objet",
- "TypeGemme": "Gemme",
- "TypeCompetence": "Compétence",
- "TypeCompetencecreature": "Compétence de créature",
- "TypeMaladie": "Maladie",
- "TypePoison": "Poison",
- "TypeNombreastral": "Nombre astral",
- "TypeTarot": "Carte de tarot",
- "TypeCasetmr": "TMR spéciale",
- "TypeRencontre": "Rencontre TMR",
- "TypeMunition": "Munition",
- "TypeMonnaie": "Monnaie",
- "TypeHerbe": "Herbe",
- "TypePlante": "Plante",
- "TypeIngredient": "Ingrédient",
- "TypeFaune": "Faune",
- "TypeLivre": "Livre",
- "TypePotion": "Potion",
"TypeArme": "Arme",
"TypeArmure": "Armure",
- "TypeConteneur": "Conteneur",
- "TypeNourritureboisson": "Nourriture & boisson",
- "TypeService": "Service",
+ "TypeBlessure": "Blessure",
+ "TypeCasetmr": "TMR spéciale",
"TypeChant": "Chant",
+ "TypeCompetence": "Compétence",
+ "TypeCompetencecreature": "Compétence de créature",
+ "TypeConteneur": "Conteneur",
"TypeDanse": "Danse",
- "TypeMusique": "Musique",
- "TypeOeuvre": "Oeuvre",
- "TypeTache": "Tâche",
+ "TypeExtraitpoetique": "Extrait poetique",
+ "TypeFaune": "Faune",
+ "TypeGemme": "Gemme",
+ "TypeHerbe": "Herbe",
+ "TypeIngredient": "Ingrédient",
"TypeJeu": "Jeu",
+ "TypeLivre": "Livre",
+ "TypeMaladie": "Maladie",
+ "TypeMeditation": "Méditation",
+ "TypeMonnaie": "Monnaie",
+ "TypeMunition": "Munition",
+ "TypeMusique": "Musique",
+ "TypeNombreastral": "Nombre astral",
+ "TypeNourritureboisson": "Nourriture & boisson",
+ "TypeObjet": "Objet",
+ "TypeOeuvre": "Oeuvre",
+ "TypeOmbre": "Ombre de Thanatos",
+ "TypePlante": "Plante",
+ "TypePoison": "Poison",
+ "TypePossession": "Possession",
+ "TypePotion": "Potion",
+ "TypeQueue": "Queue de Dragon",
"TypeRecettealchimique": "Recette alchimique",
"TypeRecettecuisine": "Recette de cuisine",
- "TypeSort": "Sort",
- "TypeMeditation": "Méditation",
+ "TypeRencontre": "Rencontre TMR",
+ "TypeService": "Service",
"TypeSignedraconique": "Signe draconique",
- "TypeQueue": "Queue de Dragon",
- "TypeOmbre": "Ombre de Thanatos",
- "TypeSouffle": "Souffle de Dragon",
- "TypeTete": "Tête de Dragon",
- "TypePossession": "Possession",
+ "TypeSort": "Sort",
"TypeSortreserve": "Sort en réserve",
- "TypeExtraitpoetique": "Extrait poetique"
+ "TypeSouffle": "Souffle de Dragon",
+ "TypeTache": "Tâche",
+ "TypeTarot": "Carte de tarot",
+ "TypeTete": "Tête de Dragon"
},
"EFFECT": {
"StatusStunned": "Sonné",
diff --git a/module/actor-sheet.js b/module/actor-sheet.js
index 7103aeff..00f2fa96 100644
--- a/module/actor-sheet.js
+++ b/module/actor-sheet.js
@@ -13,6 +13,7 @@ import { STATUSES } from "./settings/status-effects.js";
import { MAINS_DIRECTRICES } from "./actor.js";
import { RdDBaseActorSheet } from "./actor/base-actor-sheet.js";
import { RdDItem } from "./item.js";
+import { RdDItemBlessure } from "./item/blessure.js";
/* -------------------------------------------- */
/**
@@ -151,42 +152,31 @@ export class RdDActorSheet extends RdDBaseActorSheet {
this.html.find('.creer-tache').click(async event => {
this.createEmptyTache();
});
- this.html.find('.creer-tache-blessure-legere').click(async event => {
- this.actor.createTacheBlessure('legere');
- });
- this.html.find('.creer-tache-blessure-grave').click(async event => {
- this.actor.createTacheBlessure('grave');
- });
- this.html.find('.creer-tache-blessure-critique').click(async event => {
- this.actor.createTacheBlessure('critique');
- });
+ this.html.find('.creer-tache-blessure-legere').click(async event => RdDItemBlessure.createTacheSoinBlessure(this.actor, 2));
+ this.html.find('.creer-tache-blessure-grave').click(async event => RdDItemBlessure.createTacheSoinBlessure(this.actor, 4));
+ this.html.find('.creer-tache-blessure-critique').click(async event => RdDItemBlessure.createTacheSoinBlessure(this.actor, 6));
+ this.html.find('.creer-blessure-legere').click(async event => RdDItemBlessure.createBlessure(this.actor, 2));
+ this.html.find('.creer-blessure-grave').click(async event => RdDItemBlessure.createBlessure(this.actor, 4));
+ this.html.find('.creer-blessure-critique').click(async event => RdDItemBlessure.createBlessure(this.actor, 6));
this.html.find('.creer-une-oeuvre').click(async event => {
this.selectTypeOeuvreToCreate();
});
- // Blessure control
- this.html.find('.blessure-control').click(async event => {
- const tr = this.html.find(event.currentTarget).parents(".item");
- let btype = tr.data("blessure-type");
- let index = tr.data('blessure-index');
- let active = this.html.find(event.currentTarget).data('blessure-active');
- //console.log(btype, index, active);
- await this.actor.manageBlessureFromSheet(btype, index, active);
+ this.html.find('.blessure-premierssoins-done').change(async event => {
+ const blessure = this.getBlessure(event);
+ await blessure?.setSoinsBlessure({ premierssoins: { done: event.currentTarget.checked } });
});
-
- // Blessure data
- this.html.find('.blessure-soins').change(async event => {
- const tr = this.html.find(event.currentTarget).parents(".item");
- let btype = tr.data('blessure-type');
- let index = tr.data('blessure-index');
- let psoins = tr.find('.blessure-premiers_soins').val();
- let pcomplets = tr.find('.blessure-soins_complets').val();
- let jours = tr.find('.blessure-jours').val();
- let loc = tr.find('.blessure-localisation').val();
- let psdone = tr.find('.blessure-psdone:checked').val();
- let scdone = tr.find('.blessure-scdone:checked').val();
- console.log(btype, index, psoins, pcomplets, jours, loc, psdone, scdone);
- await this.actor.setDataBlessureFromSheet(btype, index, psoins, pcomplets, jours, loc, psdone, scdone);
+ this.html.find('.blessure-soinscomplets-done').change(async event => {
+ const blessure = this.getBlessure(event);
+ await blessure?.setSoinsBlessure({ soinscomplets: { done: event.currentTarget.checked } })
+ });
+ this.html.find('.blessure-premierssoins-bonus').change(async event => {
+ const blessure = this.getBlessure(event);
+ await blessure?.setSoinsBlessure({ premierssoins: { bonus: Number(event.currentTarget.value) } })
+ });
+ this.html.find('.blessure-soinscomplets-bonus').change(async event => {
+ const blessure = this.getBlessure(event);
+ await blessure?.setSoinsBlessure({ soinscomplets: { bonus: Number(event.currentTarget.value) } })
});
// Equip Inventory Item
@@ -426,6 +416,12 @@ export class RdDActorSheet extends RdDBaseActorSheet {
});
}
+ getBlessure(event) {
+ const itemId = this.html.find(event.currentTarget).parents(".item-blessure").data('item-id');
+ const blessure = this.actor.getItem(itemId, 'blessure');
+ return blessure;
+ }
+
isCompetenceAffichable(competence) {
return !this.options.showCompNiveauBase || !RdDItemCompetence.isNiveauBase(competence);
}
diff --git a/module/actor.js b/module/actor.js
index 0a005dc1..f51ae2aa 100644
--- a/module/actor.js
+++ b/module/actor.js
@@ -26,7 +26,7 @@ import { DialogConsommer } from "./dialog-item-consommer.js";
import { DialogFabriquerPotion } from "./dialog-fabriquer-potion.js";
import { RollDataAjustements } from "./rolldata-ajustements.js";
import { RdDPossession } from "./rdd-possession.js";
-import { ENTITE_BLURETTE, ENTITE_INCARNE, ENTITE_NONINCARNE, SHOW_DICE, SYSTEM_RDD, SYSTEM_SOCKET_ID } from "./constants.js";
+import { ENTITE_INCARNE, ENTITE_NONINCARNE, SHOW_DICE, SYSTEM_RDD, SYSTEM_SOCKET_ID } from "./constants.js";
import { RdDConfirm } from "./rdd-confirm.js";
import { DialogValidationEncaissement } from "./dialog-validation-encaissement.js";
import { RdDRencontre } from "./item/rencontre.js";
@@ -34,8 +34,8 @@ import { Targets } from "./targets.js";
import { DialogRepos } from "./sommeil/dialog-repos.js";
import { RdDBaseActor } from "./actor/base-actor.js";
import { RdDTimestamp } from "./rdd-timestamp.js";
-import { RdDItemTache } from "./item-tache.js";
-import { APP_ASTROLOGIE_REFRESH, AppAstrologie } from "./sommeil/app-astrologie.js";
+import { RdDItemBlessure } from "./item/blessure.js";
+import { AppAstrologie } from "./sommeil/app-astrologie.js";
const POSSESSION_SANS_DRACONIC = {
img: 'systems/foundryvtt-reve-de-dragon/icons/entites/possession.webp',
@@ -46,7 +46,6 @@ const POSSESSION_SANS_DRACONIC = {
}
};
-const PAS_DE_BLESSURE = { "active": false, "psdone": false, "scdone": false, "premiers_soins": 0, "soins_complets": 0, "jours": 0, "loc": "" };
export const MAINS_DIRECTRICES = ['Droitier', 'Gaucher', 'Ambidextre']
/* -------------------------------------------- */
@@ -332,34 +331,42 @@ export class RdDActor extends RdDBaseActor {
/* -------------------------------------------- */
async roll() {
- const carac = mergeObject(
- duplicate(this.system.carac),
+ const carac = mergeObject(duplicate(this.system.carac),
{
'reve-actuel': this.getCaracReveActuel(),
'chance-actuelle': this.getCaracChanceActuelle()
});
- let rollData = {
- carac: carac,
- selectedCarac: carac.apparence,
- selectedCaracName: 'apparence',
- competences: this.itemTypes['competence']
- };
+ await this._openRollDialog({
+ name: `jet-${this.id}`,
+ label: `Jet de ${this.name}`,
+ template: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll.html',
+ rollData: {
+ carac: carac,
+ selectedCarac: carac.apparence,
+ selectedCaracName: 'apparence',
+ competences: this.itemTypes['competence']
+ },
+ callbackAction: r => this.$onRollCaracResult(r)
+ });
+ }
+
+ async _openRollDialog({ name, label, template, rollData, callbackAction }) {
const dialog = await RdDRoll.create(this, rollData,
- { html: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll.html' },
+ { html: template },
{
- name: `jet-${this.id}`,
- label: `Jet de ${this.name}`,
+ name: name,
+ label: label,
callbacks: [
this.createCallbackExperience(),
this.createCallbackAppelAuMoral(),
- { action: r => this._onRollCaracResult(r) }
+ { action: callbackAction }
]
- }
- );
+ });
dialog.render(true);
}
+
async prepareChateauDormant(consigne) {
if (consigne.ignorer) {
return;
@@ -395,7 +402,7 @@ export class RdDActor extends RdDBaseActor {
}
await this._recupereChance();
await this.transformerStress();
- this.bonusRecuperationPotion = 0; // Reset potion
+ await this.setBonusPotionSoin(0);
}
await this.resetInfoSommeil()
ChatMessage.create(message);
@@ -406,11 +413,8 @@ export class RdDActor extends RdDBaseActor {
const maladiesPoisons = this._maladiePoisons(message);
const isMaladeEmpoisonne = maladiesPoisons.length > 0;
this._messageRecuperationMaladiePoisons(maladiesPoisons, message);
- const blessures = duplicate(this.system.blessures);
- await this._recupererBlessures(message, "legere", blessures.legeres.liste.filter(b => b.active), [], isMaladeEmpoisonne);
- await this._recupererBlessures(message, "grave", blessures.graves.liste.filter(b => b.active), blessures.legeres.liste, isMaladeEmpoisonne);
- await this._recupererBlessures(message, "critique", blessures.critiques.liste.filter(b => b.active), blessures.graves.liste, isMaladeEmpoisonne);
- await this.update({ "system.blessures": blessures });
+
+ await this._recuperationBlessures(message, isMaladeEmpoisonne);
await this._recupererVie(message, isMaladeEmpoisonne);
}
@@ -452,7 +456,7 @@ export class RdDActor extends RdDBaseActor {
await this._recupereChance();
await this.transformerStress();
await this.retourSeuilDeReve(message);
- this.bonusRecuperationPotion = 0; // Reset potion
+ await this.setBonusPotionSoin(0);
await this.retourSust(message);
await this.verifierPotionsEnchantees();
if (message.content != "") {
@@ -515,65 +519,36 @@ export class RdDActor extends RdDBaseActor {
}
/* -------------------------------------------- */
- async _recupererBlessures(message, type, liste, moindres, isMaladeEmpoisonne) {
- if (!this.bonusRecuperationPotion) this.bonusRecuperationPotion = 0;
- let count = 0;
- const definitions = RdDUtility.getDefinitionsBlessures();
- let definition = definitions.find(d => d.type == type);
- for (let blessure of liste) {
- if (blessure.jours >= definition.facteur) {
- let rolled = await this._jetRecuperationConstitution(Misc.toInt(blessure.soins_complets) + this.bonusRecuperationPotion, message);
- blessure.soins_complets = 0;
- if (!isMaladeEmpoisonne && rolled.isSuccess && this._retrograderBlessure(type, blessure, moindres)) {
- message.content += ` -- une blessure ${type} cicatrise`;
- count++;
- }
- else if (rolled.isETotal) {
- message.content += ` -- une blessure ${type} s'infecte (temps de guérison augmenté de ${definition.facteur} jours, perte de vie)`;
- blessure.jours = 0;
- await this.santeIncDec("vie", -1);
- }
- else {
- blessure.jours++;
- message.content += ` -- une blessure ${type} reste stable`;
- }
- }
- else {
- blessure.jours++;
- }
- }
+ async _recuperationBlessures(message, isMaladeEmpoisonne) {
+ const timestamp = game.system.rdd.calendrier.getTimestamp()
+ const blessures = this.filterItems(it => it.gravite > 0, 'blessure').sort(Misc.ascending(it => it.system.gravite))
+
+ Promise.all(blessures.map(b => b.recuperationBlessure({
+ actor: this,
+ timestamp,
+ message,
+ isMaladeEmpoisonne,
+ blessures
+ })));
+ await this.supprimerBlessures(filterToDelete);
}
- /* -------------------------------------------- */
- _retrograderBlessure(type, blessure, blessuresMoindres) {
- if (type != "legere") {
- let retrograde = blessuresMoindres.find(b => !b.active);
- if (!retrograde) {
- return false;
- }
- mergeObject(retrograde, { "active": true, "psdone": blessure.psdone, "scdone": blessure.scdone, "premiers_soins": 0, "soins_complets": 0, "jours": 0, "loc": blessure.loc });
- }
- this._supprimerBlessure(blessure);
- return true;
- }
-
- /* -------------------------------------------- */
- _supprimerBlessure(blessure) {
- mergeObject(blessure, PAS_DE_BLESSURE);
+ async supprimerBlessures(filterToDelete) {
+ const toDelete = this.filterItems(filterToDelete, 'blessure')
+ .map(it => it.id);
+ await this.deleteEmbeddedDocuments('Item', toDelete);
}
/* -------------------------------------------- */
async _recupererVie(message, isMaladeEmpoisonne) {
const tData = this.system
- let blessures = [].concat(tData.blessures.legeres.liste).concat(tData.blessures.graves.liste).concat(tData.blessures.critiques.liste);
- let nbBlessures = blessures.filter(b => b.active);
+ let blessures = this.filterItems(it => it.system.gravite > 0, 'blessure');
+ if (blessures.length > 0) {
+ return
+ }
let vieManquante = tData.sante.vie.max - tData.sante.vie.value;
- if (nbBlessures == 0 && vieManquante > 0) {
- let bonusSoins = 0;
- for (let b of blessures) {
- bonusSoins = Math.max(bonusSoins, Misc.toInt(b.soins_complets));
- }
- let rolled = await this._jetRecuperationConstitution(bonusSoins, message)
+ if (vieManquante > 0) {
+ let rolled = await this.jetRecuperationConstitution(bonusSoins, message)
if (!isMaladeEmpoisonne && rolled.isSuccess) {
const gain = Math.min(rolled.isPart ? 2 : 1, vieManquante);
message.content += " -- récupération de vie: " + gain;
@@ -590,7 +565,7 @@ export class RdDActor extends RdDBaseActor {
}
/* -------------------------------------------- */
- async _jetRecuperationConstitution(bonusSoins, message = undefined) {
+ async jetRecuperationConstitution(bonusSoins, message = undefined) {
let difficulte = Misc.toInt(bonusSoins) + Math.min(0, this.system.sante.vie.value - this.system.sante.vie.max);
let rolled = await RdDResolutionTable.roll(this.system.carac.constitution.value, difficulte);
if (message) {
@@ -615,17 +590,13 @@ export class RdDActor extends RdDBaseActor {
const updates = {
'system.sante.endurance.value': this.system.sante.endurance.max
};
- if (!this.isEntite([ENTITE_INCARNE, ENTITE_BLURETTE])) {
- if (this.system.blessures) {
- updates['system.blessures.legeres.liste'] = [PAS_DE_BLESSURE, PAS_DE_BLESSURE, PAS_DE_BLESSURE, PAS_DE_BLESSURE, PAS_DE_BLESSURE];
- updates['system.blessures.graves.liste'] = [PAS_DE_BLESSURE, PAS_DE_BLESSURE];
- updates['system.blessures.critiques.liste'] = [PAS_DE_BLESSURE];
- }
+ if (this.isPersonnage() || this.isCreature()) {
+ await this.supprimerBlessures(it => true);
updates['system.sante.vie.value'] = this.system.sante.vie.max;
updates['system.sante.fatigue.value'] = 0;
- if (this.isPersonnage()) {
- updates['system.compteurs.ethylisme'] = { value: 1, nb_doses: 0, jet_moral: false };
- }
+ }
+ if (this.isPersonnage()) {
+ updates['system.compteurs.ethylisme'] = { value: 1, nb_doses: 0, jet_moral: false };
}
await this.update(updates);
await this.removeEffects(e => e.flags.core.statusId !== STATUSES.StatusDemiReve);
@@ -1139,35 +1110,31 @@ export class RdDActor extends RdDBaseActor {
}
/* -------------------------------------------- */
- computeResumeBlessure(blessures = undefined) {
- blessures = blessures ?? this.system.blessures;
- if (!blessures) {
- return "Pas de blessures possibles";
- }
- let nbLegeres = this.countBlessures(blessures.legeres.liste);
- let nbGraves = this.countBlessures(blessures.graves.liste);
- let nbCritiques = this.countBlessures(blessures.critiques.liste);
+ computeResumeBlessure() {
+ const blessures = this.filterItems(it => it.system.gravite > 0, 'blessure')
- let resume = "Blessures:";
- if (nbCritiques > 0 || nbGraves > 0 || nbLegeres > 0) {
- if (nbLegeres > 0) {
- resume += " " + nbLegeres + " légère" + (nbLegeres > 1 ? "s" : "");
- }
- if (nbGraves > 0) {
- if (nbLegeres > 0)
- resume += ",";
- resume += " " + nbGraves + " grave" + (nbGraves > 1 ? "s" : "");
- }
- if (nbCritiques > 0) {
- if (nbGraves > 0 || nbLegeres > 0)
- resume += ",";
- resume += " une CRITIQUE !";
- }
- return resume;
- }
- else {
+ const nbLegeres = blessures.filter(it => it.isLegere()).length;
+ const nbGraves = blessures.filter(it => it.isGrave()).length;
+ const nbCritiques = blessures.filter(it => it.isCritique()).length;
+
+ if (nbLegeres + nbGraves + nbCritiques == 0) {
return "Aucune blessure";
}
+ let resume = "Blessures:";
+ if (nbLegeres > 0) {
+ resume += " " + nbLegeres + " légère" + (nbLegeres > 1 ? "s" : "");
+ }
+ if (nbGraves > 0) {
+ if (nbLegeres > 0)
+ resume += ",";
+ resume += " " + nbGraves + " grave" + (nbGraves > 1 ? "s" : "");
+ }
+ if (nbCritiques > 0) {
+ if (nbGraves > 0 || nbLegeres > 0)
+ resume += ",";
+ resume += " une CRITIQUE !";
+ }
+ return resume;
}
recompute() {
@@ -1376,11 +1343,11 @@ export class RdDActor extends RdDBaseActor {
ChatMessage.create({ content: `${this.name} n'est plus ${Misc.lowerFirst(game.i18n.localize(effect.system.label))} !` });
}
}
- if (this.type == 'personnage') {
- // Gestion blessure graves : -1 pt endurance
- let nbGraves = this.countBlessuresNonSoigneeByName('graves');
+ if (this.isPersonnage() || this.isCreature()) {
+ const nbGraves = this.filterItems(it => it.isGrave(), 'blessure').length
if (nbGraves > 0) {
- await this.santeIncDec("endurance", -1);
+ // Gestion blessure graves : -1 pt endurance par blessure grave
+ await this.santeIncDec("endurance", - nbGraves);
}
}
}
@@ -1411,20 +1378,8 @@ export class RdDActor extends RdDBaseActor {
}
/* -------------------------------------------- */
- countBlessures(blessuresListe) {
- return blessuresListe.filter(b => b.active).length
- }
- /* -------------------------------------------- */
- countBlessuresByName(name) {
- return this.countBlessures(this.system.blessures[name].liste);
- }
-
- countBlessuresNonSoigneeByName(name) {
- if (this.system.blessures) {
- let blessures = this.system.blessures[name].liste;
- return blessures.filter(b => b.active && !b.psdone).length;
- }
- return 0;
+ countBlessures(filter = it => !it.isContusion()) {
+ return this.filterItems(filter, 'blessure').length
}
/* -------------------------------------------- */
@@ -1575,40 +1530,15 @@ export class RdDActor extends RdDBaseActor {
/* -------------------------------------------- */
_computeEnduranceMax() {
- let blessures = this.system.blessures;
- let diffVie = this.system.sante.vie.max - this.system.sante.vie.value;
- let maxEndVie = this.system.sante.endurance.max - (diffVie * 2);
- let nbGraves = this.countBlessures(blessures.graves.liste);
- let nbCritiques = this.countBlessures(blessures.critiques.liste);
- let maxEndGraves = Math.floor(this.system.sante.endurance.max / (2 * nbGraves));
- let maxEndCritiques = nbCritiques > 0 ? 1 : this.system.sante.endurance.max;
+ const diffVie = this.system.sante.vie.max - this.system.sante.vie.value;
+ const maxEndVie = this.system.sante.endurance.max - (diffVie * 2);
+ const nbGraves = this.countBlessures(it => it.isGraves()) > 0
+ const nbCritiques = this.countBlessures(it => it.isCritique()) > 0
+ const maxEndGraves = Math.floor(this.system.sante.endurance.max / (2 * nbGraves));
+ const maxEndCritiques = nbCritiques > 0 ? 1 : this.system.sante.endurance.max;
return Math.max(0, Math.min(maxEndVie, maxEndGraves, maxEndCritiques));
}
- /* -------------------------------------------- */
- async manageBlessureFromSheet(gravite, index) {
- let listBlessures = duplicate(this.system.blessures);
- let blessure = listBlessures[gravite + "s"].liste[index];
- blessure.active = !blessure.active;
- if (!blessure.active) {
- this._supprimerBlessure(blessure);
- }
- await this.update({ 'system.blessures': listBlessures });
- }
-
- /* -------------------------------------------- */
- async setDataBlessureFromSheet(gravite, index, psoins, pcomplets, jours, loc, psdone, scdone) {
- let listBlessures = duplicate(this.system.blessures);
- let blessure = listBlessures[gravite + "s"].liste[index];
- blessure.psdone = psdone;
- blessure.scdone = scdone;
- blessure.premiers_soins = psoins;
- blessure.soins_complets = pcomplets;
- blessure.jours = jours;
- blessure.loc = loc;
- await this.update({ 'system.blessures': listBlessures });
- }
-
/* -------------------------------------------- */
async jetDeMoral(situation, messageReussi = undefined, messageManque = undefined) {
const jetMoral = await this._jetDeMoral(situation);
@@ -1795,7 +1725,7 @@ export class RdDActor extends RdDBaseActor {
async _surmonterExotisme(item) {
const exotisme = Math.min(item.system.exotisme, item.system.qualite, 0);
if (exotisme < 0) {
- const rolled = await this.rollCaracCompetence('volonte', 'cuisine', exotisme, { title: `tente de surmonter l'exotisme de ${item.name}` });
+ const rolled = await this.doRollCaracCompetence('volonte', 'cuisine', exotisme, { title: `tente de surmonter l'exotisme de ${item.name}` });
return rolled.isSuccess;
}
return true;
@@ -1803,7 +1733,7 @@ export class RdDActor extends RdDBaseActor {
/* -------------------------------------------- */
async apprecier(carac, compName, qualite, title) {
- const rolled = await this.rollCaracCompetence(carac, compName, qualite, { title: title, apprecier: true });
+ const rolled = await this.doRollCaracCompetence(carac, compName, qualite, { title: title, apprecier: true });
if (rolled?.isSuccess) {
await this.jetDeMoral('heureux');
}
@@ -2089,22 +2019,21 @@ export class RdDActor extends RdDBaseActor {
}
/* -------------------------------------------- */
- filterSortList(sortList, coord) {
+ $filterSortList(sortList, coord) {
let tmr = TMRUtility.getTMR(coord);
- let letfilteredList = []
+ let filtered = []
for (let sort of sortList) {
if (sort.system.caseTMR.toLowerCase().includes('variable')) {
- letfilteredList.push(sort);
+ filtered.push(sort);
} else if (sort.system.caseTMRspeciale.toLowerCase().includes('variable')) {
- letfilteredList.push(sort);
+ filtered.push(sort);
} else if (sort.system.caseTMR.toLowerCase() == tmr.type) {
- letfilteredList.push(sort);
+ filtered.push(sort);
} else if (sort.system.caseTMR.toLowerCase().includes('special') && sort.system.caseTMRspeciale.toLowerCase().includes(coord.toLowerCase())) {
- letfilteredList.push(sort);
+ filtered.push(sort);
}
}
-
- return letfilteredList;
+ return filtered;
}
/* -------------------------------------------- */
@@ -2136,52 +2065,39 @@ export class RdDActor extends RdDBaseActor {
/* -------------------------------------------- */
async rollUnSort(coord) {
- let sortList = duplicate(this.getSortList()); // Duplication car les pts de reve sont modifiés dans le sort
- if (!sortList || sortList.length == 0) {
- ui.notifications.info("Aucun sort disponible!");
- return;
- }
- sortList = this.filterSortList(sortList, coord);
- if (!sortList || sortList.length == 0) {
- ui.notifications.info("Aucun sort disponible pour cette case !");
- return;
- }
if (EffetsDraconiques.isSortImpossible(this)) {
ui.notifications.error("Une queue ou un souffle vous empèche de lancer de sort!");
return;
}
+ // Duplication car les pts de reve sont modifiés dans le sort
+ let sorts = duplicate(this.$filterSortList(this.getSortList(), coord));
+ if (sorts.length == 0) {
+ ui.notifications.info(`Aucun sort disponible en ${TMRUtility.getTMR(coord).label} !`);
+ return;
+ }
if (this.currentTMR) this.currentTMR.minimize(); // Hide
- let draconicList = this.computeDraconicAndSortIndex(sortList);
+ const draconicList = this.computeDraconicAndSortIndex(sorts);
const reve = duplicate(this.system.carac.reve);
- let rollData = {
- carac: { 'reve': reve },
- forceCarac: { 'reve': reve },
- selectedCarac: reve,
- draconicList: draconicList,
- competence: draconicList[0],
- sortList: sortList,
- selectedSort: sortList[0],
- tmr: TMRUtility.getTMR(coord),
- diffLibre: RdDItemSort.getDifficulte(sortList[0], -7), // Per default at startup
- coutreve: Array(30).fill().map((item, index) => 1 + index),
- }
- const dialog = await RdDRoll.create(this, rollData,
- {
- html: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-sort.html',
- close: html => { this.currentTMR.maximize() } // Re-display TMR
+ await this._openRollDialog({
+ name: 'lancer-un-sort',
+ label: 'Lancer un sort',
+ template: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-sort.html',
+ rollData: {
+ carac: { 'reve': reve },
+ forceCarac: { 'reve': reve },
+ selectedCarac: reve,
+ draconicList: draconicList,
+ competence: draconicList[0],
+ sortList: sorts,
+ selectedSort: sorts[0],
+ tmr: TMRUtility.getTMR(coord),
+ diffLibre: RdDItemSort.getDifficulte(sorts[0], -7), // Per default at startup
+ coutreve: Array(30).fill().map((item, index) => 1 + index),
},
- {
- name: 'lancer-un-sort',
- label: 'Lancer un sort',
- callbacks: [
- this.createCallbackExperience(),
- { action: r => this._rollUnSortResult(r) }
- ]
- }
- );
- dialog.render(true);
+ callbackAction: r => this._rollUnSortResult(r)
+ });
}
/* -------------------------------------------- */
@@ -2288,34 +2204,34 @@ export class RdDActor extends RdDBaseActor {
/* -------------------------------------------- */
async rollCarac(caracName, jetResistance = undefined) {
- let rollData = {
- selectedCarac: this.getCaracByName(caracName),
- competences: this.itemTypes['competence'],
- jetResistance: jetResistance ? caracName : undefined
- };
-
- const dialog = await RdDRoll.create(this, rollData,
- { html: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-carac.html' },
- {
- name: 'jet-' + caracName,
- label: 'Jet ' + Grammar.apostrophe('de', rollData.selectedCarac.label),
- callbacks: [
- this.createCallbackExperience(),
- this.createCallbackAppelAuMoral(),
- { action: r => this._onRollCaracResult(r) }
- ]
- }
- );
- dialog.render(true);
+ await this._openRollDialog({
+ name: 'jet-' + caracName,
+ label: 'Jet ' + Grammar.apostrophe('de', rollData.selectedCarac.label),
+ template: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-carac.html',
+ rollData: {
+ selectedCarac: this.getCaracByName(caracName),
+ competences: this.itemTypes['competence'],
+ jetResistance: jetResistance ? caracName : undefined
+ },
+ callbackAction: r => this.$onRollCaracResult(r)
+ });
}
/* -------------------------------------------- */
- async _onRollCaracResult(rollData) {
+ async $onRollCaracResult(rollData) {
// Final chat message
await RdDResolutionTable.displayRollData(rollData, this, 'chat-resultat-general.html');
}
- async rollCaracCompetence(caracName, compName, diff, options = { title: "", apprecier: false }) {
+ /**
+ * Méthode pour faire un jet prédéterminer sans ouvrir la fenêtre de dialogue
+ * @param {*} caracName
+ * @param {*} compName
+ * @param {*} diff
+ * @param {*} options
+ * @returns
+ */
+ async doRollCaracCompetence(caracName, compName, diff, options = { title: "", apprecier: false }) {
const carac = this.getCaracByName(caracName);
if (!carac) {
ui.notifications.warn(`${this.name} n'a pas de caractéristique correspondant à ${caracName}`)
@@ -2374,24 +2290,22 @@ export class RdDActor extends RdDBaseActor {
// Transformer la competence de créature
RdDItemCompetenceCreature.setRollDataCreature(rollData)
}
- console.log("rollCompetence !!!", rollData);
- const dialog = await RdDRoll.create(this, rollData,
- { html: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-competence.html' },
- {
- name: 'jet-competence',
- label: 'Jet ' + Grammar.apostrophe('de', rollData.competence.name),
- callbacks: [
- this.createCallbackExperience(),
- this.createCallbackAppelAuMoral(),
- { action: r => this.$onRollCompetence(r) }
- ]
- });
- dialog.render(true);
+
+ await this._openRollDialog({
+ name: 'jet-competence',
+ label: 'Jet ' + Grammar.apostrophe('de', rollData.competence.name),
+ template: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-competence.html',
+ rollData: rollData,
+ callbackAction: r => this.$onRollCompetence(r, options)
+ });
}
/* -------------------------------------------- */
- async $onRollCompetence(rollData) {
+ async $onRollCompetence(rollData, options) {
await RdDResolutionTable.displayRollData(rollData, this, 'chat-resultat-competence.html')
+ if (options?.onRollAutomate) {
+ options.onRollAutomate(rollData);
+ }
}
/* -------------------------------------------- */
@@ -2419,47 +2333,67 @@ export class RdDActor extends RdDBaseActor {
return tachesExistantes.length > 0 ? tachesExistantes[0] : undefined;
}
- async createTacheBlessure(gravite) {
- const tache = RdDItemTache.prepareTacheSoin(gravite)
- if (tache) {
- await this.createEmbeddedDocuments('Item', [tache], { renderSheet: false });
+ blessuresASoigner() {
+ // TODO or not TODO: filtrer les blessures poour lesquels on ne peut plus faire de premiers soins?
+ return this.filterItems(it => it.system.gravite > 0 && it.system.gravite <= 6 && !(it.system.premierssoins.done && it.system.soinscomplets.done), 'blessure')
+ }
+
+ async getTacheBlessure(blesse, blessure) {
+ const gravite = blessure?.system.gravite ?? 0;
+ if (gravite > 0) {
+ const tache = this.listItems('tache').find(it => it.system.itemId == blessure.id)
+ ?? await RdDItemBlessure.createTacheSoinBlessure(this, gravite);
+ await blessure?.updateTacheSoinBlessure(tache);
+ return tache
}
+ return undefined;
+ }
+
+ async rollCaracCompetence(caracName, compName, diff, options = { title: "" }) {
+ const competence = this.getCompetence(compName);
+ await this._openRollDialog({
+ name: 'jet-competence',
+ label: 'Jet ' + Grammar.apostrophe('de', competence.name),
+ template: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-competence.html',
+ rollData: {
+ alias: this.name,
+ carac: this.system.carac,
+ selectedCarac: this.getCaracByName(caracName),
+ selectedCaracName: caracName,
+ diffLibre: diff,
+ competence: competence,
+ show: { title: options?.title ?? '' }
+ },
+ callbackAction: r => this.$onRollCompetence(r, options)
+ });
}
/* -------------------------------------------- */
- async rollTache(id) {
+ async rollTache(id, options = {}) {
const tacheData = this.getTache(id)
const compData = this.getCompetence(tacheData.system.competence)
compData.system.defaut_carac = tacheData.system.carac; // Patch !
- let rollData = {
- competence: compData,
- tache: tacheData,
- diffLibre: tacheData.system.difficulte,
- diffConditions: 0,
- use: { libre: false, conditions: true },
- carac: {}
- };
- rollData.carac[tacheData.system.carac] = duplicate(this.system.carac[tacheData.system.carac]); // Single carac
-
- console.log("rollTache !!!", rollData);
-
- const dialog = await RdDRoll.create(this, rollData,
- { html: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-competence.html' },
- {
- name: 'jet-competence',
- label: 'Jet de Tâche ' + tacheData.name,
- callbacks: [
- this.createCallbackExperience(),
- this.createCallbackAppelAuMoral(),
- { action: r => this._tacheResult(r) }
- ]
- });
- dialog.render(true);
+ await this._openRollDialog({
+ name: 'jet-competence',
+ label: 'Jet de Tâche ' + tacheData.name,
+ template: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-competence.html',
+ rollData: {
+ competence: compData,
+ tache: tacheData,
+ diffLibre: tacheData.system.difficulte,
+ diffConditions: 0,
+ use: { libre: false, conditions: true },
+ carac: {
+ [tacheData.system.carac]: duplicate(this.system.carac[tacheData.system.carac])
+ }
+ },
+ callbackAction: r => this._tacheResult(r, options)
+ });
}
/* -------------------------------------------- */
- async _tacheResult(rollData) {
+ async _tacheResult(rollData, options) {
// Mise à jour de la tache
rollData.appliquerFatigue = ReglesOptionelles.isUsing("appliquer-fatigue");
rollData.tache = duplicate(rollData.tache);
@@ -2478,10 +2412,13 @@ export class RdDActor extends RdDBaseActor {
this.santeIncDec("fatigue", rollData.tache.system.fatigue);
await RdDResolutionTable.displayRollData(rollData, this, 'chat-resultat-tache.html');
+ if (options?.onRollAutomate) {
+ options.onRollAutomate(rollData);
+ }
}
/* -------------------------------------------- */
- async _rollArt(artData, selected, oeuvre, callBackResult = r => this._resultArt(r)) {
+ async _rollArt(artData, selected, oeuvre, callbackAction = r => this._resultArt(r)) {
oeuvre.system.niveau = oeuvre.system.niveau ?? 0;
mergeObject(artData,
{
@@ -2499,18 +2436,14 @@ export class RdDActor extends RdDBaseActor {
artData.forceCarac = {};
artData.forceCarac[selected] = duplicate(this.system.carac[selected]);
}
- const dialog = await RdDRoll.create(this, artData,
- { html: `systems/foundryvtt-reve-de-dragon/templates/dialog-roll-${oeuvre.type}.html` },
- {
- name: `jet-${artData.art}`,
- label: `${artData.verbe} ${oeuvre.name}`,
- callbacks: [
- this.createCallbackExperience(),
- this.createCallbackAppelAuMoral(),
- { action: r => callBackResult(r) }
- ]
- });
- dialog.render(true);
+
+ await this._openRollDialog({
+ name: `jet-${artData.art}`,
+ label: `${artData.verbe} ${oeuvre.name}`,
+ template: `systems/foundryvtt-reve-de-dragon/templates/dialog-roll-${oeuvre.type}.html`,
+ rollData: artData,
+ callbackAction: callbackAction
+ });
}
/* -------------------------------------------- */
@@ -2779,24 +2712,17 @@ export class RdDActor extends RdDBaseActor {
/* -------------------------------------------- */
async rollAppelChance(onSuccess = () => { }, onEchec = () => { }) {
- // Stocke si utilisation de la chance
- let rollData = { selectedCarac: this.getCaracByName('chance-actuelle'), surprise: '' };
- const dialog = await RdDRoll.create(this, rollData,
- { html: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-carac.html' },
- {
- name: 'appelChance',
- label: 'Appel à la chance',
- callbacks: [
- this.createCallbackExperience(),
- { action: r => this._appelChanceResult(r, onSuccess, onEchec) },
- ]
- }
- );
- dialog.render(true);
+ await this._openRollDialog({
+ name: 'appelChance',
+ label: 'Appel à la chance',
+ template: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-carac.html',
+ rollData: { selectedCarac: this.getCaracByName('chance-actuelle'), surprise: '' },
+ callbackAction: r => this._appelChanceResult(r, onSuccess, onEchec)
+ });
}
/* -------------------------------------------- */
- async _appelChanceResult(rollData, onSuccess = () => { }, onEchec = () => { }) {
+ async _appelChanceResult(rollData, onSuccess, onEchec) {
await RdDResolutionTable.displayRollData(rollData, this, 'chat-resultat-appelchance.html')
if (rollData.rolled.isSuccess) {
await this.setFlag(SYSTEM_RDD, 'utilisationChance', true);
@@ -3106,7 +3032,77 @@ export class RdDActor extends RdDBaseActor {
}
RdDCombat.rddCombatTarget(target, this).attaque(competence, arme);
})
+ }
+ async rollSoins(blesse, blessureId) {
+ const blessure = blesse.blessuresASoigner().find(it => it.id == blessureId);
+ if (blessure) {
+ if (!blessure.system.premierssoins.done) {
+ const tache = await this.getTacheBlessure(blesse, blessure);
+ return await this.rollTache(tache.id, {
+ onRollAutomate: async r => blesse.onRollTachePremiersSoins(blessureId, r)
+ });
+ }
+ if (!blessure.system.soinscomplets.done) {
+ const diff = blessure.system.difficulte + (blessure.system.premierssoins.bonus ?? 0);
+ return await this.rollCaracCompetence("dexterite", "Chirurgie", diff, {
+ title: "Soins complets",
+ onRollAutomate: r => blesse.onRollSoinsComplets(blessureId, r)
+ })
+ }
+ }
+ }
+
+ async onRollTachePremiersSoins(blessureId, rollData) {
+ if (!this.isOwner) {
+ return RdDBaseActor.remoteActorCall({ actorId: this.id, method: 'onRollTachePremiersSoins', args: [blessureId, rollData] });
+ }
+ const blessure = this.getItem(blessureId, 'blessure')
+ console.log('TODO update blessure', this, blessureId, rollData, rollData.tache);
+ if (blessure && !blessure.system.premierssoins.done) {
+ const tache = rollData.tache;
+ if (rollData.rolled.isETotal) {
+ await blessure.update({
+ 'system.difficulte': blessure.system.difficulte - 1,
+ 'system.premierssoins.tache': Math.max(0, tache.system.points_de_tache_courant)
+ })
+ }
+ else {
+ const bonus = tache.system.points_de_tache_courant - tache.system.points_de_tache
+ await blessure.update({
+ 'system.premierssoins': {
+ done: (bonus >= 0),
+ bonus: Math.max(0, bonus),
+ tache: Math.max(0, tache.system.points_de_tache_courant)
+ }
+ })
+ if (bonus >= 0) {
+ await this.deleteEmbeddedDocuments('Item', [tache.id])
+ }
+ }
+ }
+ }
+
+ async onRollSoinsComplets(blessureId, rollData) {
+ if (!this.isOwner) {
+ return RdDBaseActor.remoteActorCall({ actorId: this.id, method: 'onRollSoinsComplets', args: [blessureId, rollData] });
+ }
+ const blessure = this.getItem(blessureId, 'blessure')
+ if (blessure && blessure.system.premierssoins.done && !blessure.system.soinscomplets.done) {
+ // TODO: update de la blessure: passer par le MJ!
+ if (rollData.rolled.isETotal) {
+ await blessure.setSoinsBlessure({
+ difficulte: blessure.system.difficulte - 1,
+ premierssoins: { done: false, bonus: 0 }, soinscomplets: { done: false, bonus: 0 },
+ })
+ }
+ else {
+ // soins complets finis
+ await blessure.setSoinsBlessure({
+ soinscomplets: { done: true, bonus: Math.max(0, rollData.rolled.ptTache) },
+ })
+ }
+ }
}
/* -------------------------------------------- */
@@ -3236,11 +3232,11 @@ export class RdDActor extends RdDBaseActor {
async _appliquerEncaissement(encaissement, show) {
let santeOrig = duplicate(this.system.sante);
- this.ajouterBlessure(encaissement); // Will upate the result table
+ const blessure = await this.ajouterBlessure(encaissement); // Will upate the result table
const perteVie = this.isEntite()
? { newValue: 0 }
: await this.santeIncDec("vie", -encaissement.vie);
- const perteEndurance = await this.santeIncDec("endurance", -encaissement.endurance, encaissement.critiques > 0);
+ const perteEndurance = await this.santeIncDec("endurance", -encaissement.endurance, blessure?.isCritique());
mergeObject(encaissement, {
alias: this.name,
@@ -3250,6 +3246,7 @@ export class RdDActor extends RdDBaseActor {
jetEndurance: perteEndurance.jetEndurance,
endurance: santeOrig.endurance.value - perteEndurance.newValue,
vie: this.isEntite() ? 0 : (santeOrig.vie.value - perteVie.newValue),
+ blessure: blessure,
show: show ?? {}
});
@@ -3269,73 +3266,33 @@ export class RdDActor extends RdDBaseActor {
}
/* -------------------------------------------- */
- ajouterBlessure(encaissement) {
- if (this.type == 'entite') return; // Une entité n'a pas de blessures
- if (encaissement.legeres + encaissement.graves + encaissement.critiques == 0) return;
-
+ async ajouterBlessure(encaissement) {
+ if (this.isEntite()) return; // Une entité n'a pas de blessures
+ if (encaissement.gravite < 0) return;
+ if (encaissement.gravite > 0) {
+ while (this.countBlessures(it => it.system.gravite == encaissement.gravite) >= RdDItemBlessure.maxBlessures(encaissement.gravite) && encaissement.gravite <= 6) {
+ // Aggravation
+ encaissement.gravite += 2
+ if (encaissement.gravite > 2) {
+ encaissement.vie += 2;
+ }
+ }
+ }
const endActuelle = Number(this.system.sante.endurance.value);
- let blessures = duplicate(this.system.blessures);
-
- let count = encaissement.legeres;
- // Manage blessures
- while (count > 0) {
- let legere = blessures.legeres.liste.find(it => !it.active);
- if (legere) {
- this._setBlessure(legere, encaissement);
- count--;
- }
- else {
- encaissement.graves += count;
- encaissement.legeres -= count;
- break;
- }
+ const blessure = await RdDItemBlessure.createBlessure(this, encaissement.gravite, encaissement.dmg.loc.label);
+ if (blessure.isCritique()) {
+ encaissement.endurance = endActuelle;
}
- count = encaissement.graves;
- while (count > 0) {
- let grave = blessures.graves.liste.find(it => !it.active);
- if (grave) {
- this._setBlessure(grave, encaissement);
- count--;
- }
- else {
- encaissement.critiques += count;
- encaissement.graves -= count;
- encaissement.endurance = endActuelle;
- encaissement.vie = 4;
- break;
- }
+ if (blessure.isMort()) {
+ this.setEffect(STATUSES.StatusComma, true);
+ encaissement.mort = true;
+ ChatMessage.create({
+ content: `
+ ${this.name} vient de succomber à une seconde blessure critique ! Que les Dragons gardent son Archétype en paix !`
+ });
}
-
- count = encaissement.critiques;
- while (count > 0) {
- let critique = blessures.critiques.liste[0];
- if (!critique.active) {
- this._setBlessure(critique, encaissement);
- count--;
- } else {
- // TODO: status effect dead
- this.setEffect(STATUSES.StatusComma, true);
- ChatMessage.create({
- content: `
- ${this.name} vient de succomber à une seconde blessure critique ! Que les Dragons gardent son Archétype en paix !`
- });
- encaissement.critiques -= count;
- encaissement.mort = true;
- break;
- }
- }
-
- encaissement.endurance = Math.max(encaissement.endurance, -endActuelle);
- this.update({ "system.blessures": blessures });
- }
-
- /* -------------------------------------------- */
- _setBlessure(blessure, encaissement) {
- blessure.active = true;
- blessure.psdone = false;
- blessure.scdone = false;
- blessure.loc = encaissement.locName;
+ return blessure;
}
/* -------------------------------------------- */
@@ -3568,42 +3525,28 @@ export class RdDActor extends RdDBaseActor {
/* -------------------------------------------- */
async buildPotionGuerisonList(pointsGuerison) {
- let pointsGuerisonInitial = pointsGuerison;
- let myData = this.system;
- const blessures = duplicate(myData.blessures);
- let guerisonData = { list: [], pointsConsommes: 0 }
-
- console.log(blessures);
- for (let critique of blessures.critiques.liste) {
- if (critique.active && pointsGuerison >= 6) {
- pointsGuerison -= 6;
- critique.active = false;
- guerisonData.list.push("1 Blessure Critique (6 points)");
+ const pointsGuerisonInitial = pointsGuerison;
+ const blessures = this.filterItems(it => it.isLegere() || it.isGrave() || it.isCritique()).sort(Misc.descending(it => it.system.gravite))
+ const ids = []
+ const guerisonData = { list: [], pointsConsommes: 0 }
+ for (let blessure of blessures) {
+ if (pointsGuerison >= blessure.system.gravite) {
+ pointsGuerison -= blessure.system.gravite;
+ guerisonData.list.push(`1 Blessure ${blessure.system.labelGravite} (${blessure.system.gravite} points)`);
+ ids.push(blessure.id)
}
}
- for (let grave of blessures.graves.liste) {
- if (grave.active && pointsGuerison >= 4) {
- pointsGuerison -= 4;
- grave.active = false;
- guerisonData.list.push("1 Blessure Grave (4 points)");
- }
+ if (ids.length > 0) {
+ await this.supprimerBlessures(it => ids.includes(it.id));
}
- for (let legere of blessures.legeres.liste) {
- if (legere.active && pointsGuerison >= 2) {
- pointsGuerison -= 2;
- legere.active = false;
- guerisonData.list.push("1 Blessure Légère (2 points)");
- }
+ if (blessures.length == ids.length) {
+ let pvManquants = this.system.sante.vie.max - this.system.sante.vie.value;
+ let pvSoignees = Math.min(pvManquants, Math.floor(pointsGuerison / 2));
+ pointsGuerison -= pvSoignees * 2;
+ guerisonData.list.push(pvSoignees + " Points de Vie soignés");
+ await this.santeIncDec('vie', +pvSoignees, false);
}
- await this.update({ "system.blessures": blessures });
-
- let pvManquants = myData.sante.vie.max - myData.sante.vie.value;
- let pvSoignees = Math.min(pvManquants, Math.floor(pointsGuerison / 2));
- pointsGuerison -= pvSoignees * 2;
- guerisonData.list.push(pvSoignees + " Points de Vie soignés");
- await this.santeIncDec('vie', +pvSoignees, false);
guerisonData.pointsConsommes = pointsGuerisonInitial - pointsGuerison;
-
return guerisonData;
}
@@ -3622,7 +3565,7 @@ export class RdDActor extends RdDBaseActor {
}
}
if (!potionData.system.magique || potionData.rolled.isSuccess) {
- this.bonusRecuperationPotion = potionData.system.herbeBonus;
+ await this.setBonusPotionSoin(potionData.system.herbeBonus);
}
ChatMessage.create({
whisper: ChatUtility.getWhisperRecipientsAndGMs(this.name),
@@ -3630,6 +3573,10 @@ export class RdDActor extends RdDBaseActor {
});
}
+ async setBonusPotionSoin(bonus) {
+ await this.update({ 'sante.bonusPotion': bonus });
+ }
+
/* -------------------------------------------- */
async consommerPotionRepos(potionData) {
potionData.alias = this.name;
diff --git a/module/actor/base-actor-sheet.js b/module/actor/base-actor-sheet.js
index 9ac21339..11429c01 100644
--- a/module/actor/base-actor-sheet.js
+++ b/module/actor/base-actor-sheet.js
@@ -78,6 +78,7 @@ export class RdDBaseActorSheet extends ActorSheet {
/* -------------------------------------------- */
static filterItemsPerTypeForSheet(formData, itemTypes) {
+ formData.blessures = Misc.arrayOrEmpty(itemTypes['blessure']);
formData.recettescuisine = Misc.arrayOrEmpty(itemTypes['recettecuisine']);
formData.recettesAlchimiques = Misc.arrayOrEmpty(itemTypes['recettealchimique']);
formData.maladies = Misc.arrayOrEmpty(itemTypes['maladie']);
diff --git a/module/actor/base-actor.js b/module/actor/base-actor.js
index 6c838523..769bc76e 100644
--- a/module/actor/base-actor.js
+++ b/module/actor/base-actor.js
@@ -21,7 +21,6 @@ export class RdDBaseActor extends Actor {
Hooks.on("updateActor", (actor, change, options, actorId) => actor.onUpdateActor(change, options, actorId));
}
-
static onSocketMessage(sockmsg) {
switch (sockmsg.msg) {
case "msg_remote_actor_call":
diff --git a/module/item-tache.js b/module/item-tache.js
deleted file mode 100644
index f17bb9af..00000000
--- a/module/item-tache.js
+++ /dev/null
@@ -1,18 +0,0 @@
-const BASE_TACHE_SOIN_BLESSURE = { type: "tache", img: 'systems/foundryvtt-reve-de-dragon/icons/competence_chirurgie.webp', system: { carac: "dexterite", competence: "Chirurgie", periodicite: "1 round", fatigue: 0, } }
-const TACHES_SOIN_BLESSURE = {
- 'critique': { name: 'Blessure critique', system: { difficulte: -6, points_de_tache: 6 } },
- 'grave': { name: 'Blessure grave', system: { difficulte: -4, points_de_tache: 4 } },
- 'legere': { name: 'Blessure légère', system: { difficulte: -2, points_de_tache: 2 } },
-}
-
-export class RdDItemTache extends Item {
-
- static prepareTacheSoin(gravite) {
- const blessure = TACHES_SOIN_BLESSURE[gravite]
- if (blessure) {
- return mergeObject(duplicate(BASE_TACHE_SOIN_BLESSURE), blessure)
- }
- ui.notifications.warn(`Pas de tâche de soins pour une blessure ${gravite}`)
- return undefined;
- }
-}
\ No newline at end of file
diff --git a/module/item.js b/module/item.js
index 74b59594..bc1248a5 100644
--- a/module/item.js
+++ b/module/item.js
@@ -31,9 +31,9 @@ const typesInventaire = {
const typesObjetsOeuvres = ["oeuvre", "recettecuisine", "musique", "chant", "danse", "jeu"]
const typesObjetsDraconiques = ["queue", "ombre", "souffle", "tete", "signedraconique", "sortreserve", "rencontre"]
const typesObjetsConnaissance = ["meditation", "recettealchimique", "sort"]
-const typesObjetsEffet = ["possession", "poison", "maladie"]
+const typesObjetsEffet = ["possession", "poison", "maladie", "blessure"]
const typesObjetsCompetence = ["competence", "competencecreature"]
-const typesObjetsTemporels = ["poison", "maladie", "queue", "ombre", "souffle", "signedraconique", "rencontre"]
+const typesObjetsTemporels = ["blessure", "poison", "maladie", "queue", "ombre", "souffle", "signedraconique", "rencontre"]
const typesEnvironnement = typesInventaireMateriel;
const encBrin = 0.00005; // un brin = 1 décigramme = 1/10g = 1/10000kg = 1/20000 enc
const encPepin = 0.0007; /* un pépin de gemme = 1/10 cm3 = 1/1000 l = 3.5/1000 kg = 7/2000 kg = 7/1000 enc
@@ -176,6 +176,7 @@ export class RdDItem extends Item {
isBoisson() { return this.isNourritureBoisson() && this.system.boisson; }
isAlcool() { return this.isNourritureBoisson() && this.system.boisson && this.system.alcoolise; }
isHerbeAPotion() { return this.type == 'herbe' && (this.system.categorie == 'Soin' || this.system.categorie == 'Repos'); }
+ isBlessure() { return this.type == 'blessure' }
isPresentDansMilieux(milieux) {
return this.getEnvironnements(milieux).length > 0
diff --git a/module/item/blessure.js b/module/item/blessure.js
new file mode 100644
index 00000000..2c59a9be
--- /dev/null
+++ b/module/item/blessure.js
@@ -0,0 +1,177 @@
+import { RdDItem } from "../item.js";
+import { Misc } from "../misc.js";
+import { RdDTimestamp } from "../rdd-timestamp.js";
+
+const BASE_TACHE_SOIN_BLESSURE = {
+ type: "tache",
+ img: 'systems/foundryvtt-reve-de-dragon/icons/competence_chirurgie.webp',
+ system: { carac: "dexterite", competence: "Chirurgie", periodicite: "1 round", fatigue: 0, }
+}
+const TACHES_SOIN_BLESSURE = {
+ 6: { name: 'Blessure critique', system: { difficulte: -6, points_de_tache: 6 } },
+ 4: { name: 'Blessure grave', system: { difficulte: -4, points_de_tache: 4 } },
+ 2: { name: 'Blessure légère', system: { difficulte: -2, points_de_tache: 2 } },
+}
+
+const definitionsBlessures = [
+ { type: "contusion", gravite: 0, labelGravite: 'Contusion/éraflure', max: 100, icon: "systems/foundryvtt-reve-de-dragon/icons/sante/eraflure.webp" },
+ { type: "legere", gravite: 2, labelGravite: 'Légère', max: 5, icon: "systems/foundryvtt-reve-de-dragon/icons/sante/blessure.webp" },
+ { type: "grave", gravite: 4, labelGravite: 'Grave', max: 2, icon: "systems/foundryvtt-reve-de-dragon/icons/sante/blessure.webp" },
+ { type: "critique", gravite: 6, labelGravite: 'Critique', max: 1, icon: "systems/foundryvtt-reve-de-dragon/icons/sante/blessure.webp" },
+ { type: "mort", gravite: 8, labelGravite: 'Mort', max: 1, icon: "systems/foundryvtt-reve-de-dragon/icons/sante/mort.webp" }
+]
+
+export class RdDItemBlessure extends RdDItem {
+
+ static get defaultIcon() {
+ return "systems/foundryvtt-reve-de-dragon/icons/sante/blessure.webp";
+ }
+
+ prepareDerivedData() {
+ super.prepareDerivedData();
+ this.system.labelGravite = this.getLabelGravite()
+ }
+
+ static prepareTacheSoin(gravite) {
+ const tache = TACHES_SOIN_BLESSURE[gravite]
+ if (!tache) {
+ ui.notifications.warn(`Pas de tâche de soins pour une blessure ${gravite}`)
+ return undefined;
+ }
+ return mergeObject(duplicate(BASE_TACHE_SOIN_BLESSURE), tache)
+ }
+ static async createBlessure(actor, gravite, localisation = '') {
+ const definition = RdDItemBlessure.getDefinition(gravite)
+ const blessure = {
+ name: definition.labelGravite,
+ type: 'blessure',
+ img: definition.icon,
+ system: {
+ gravite: gravite,
+ difficulte: - gravite,
+ localisation: localisation
+ }
+ }
+
+ const blessures = await actor.createEmbeddedDocuments('Item', [blessure])
+ return blessures[0]
+ }
+
+ static async createTacheSoinBlessure(actor, gravite) {
+ const tache = RdDItemBlessure.prepareTacheSoin(gravite)
+ if (tache) {
+ const taches = await actor.createEmbeddedDocuments('Item', [tache], { renderSheet: false });
+ return taches[0];
+ }
+ return undefined
+ }
+
+ async updateTacheSoinBlessure(tache) {
+ if (tache) {
+ await tache.update({
+ system: {
+ itemId: this.id,
+ difficulte: Math.min(this.system.difficulte, tache.system.difficulte),
+ points_de_tache_courant: Math.max(0, this.system.premierssoins.tache)
+ }
+ });
+ }
+ }
+
+ async setSoinsBlessure(systemUpdate = {}) {
+ systemUpdate = mergeObject(systemUpdate, this.system, { overwrite: false }),
+ systemUpdate.soinscomplets.done = systemUpdate.premierssoins.done && systemUpdate.soinscomplets.done
+ await this.update({
+ img: this.getImgSoins(systemUpdate.gravite, systemUpdate.soinscomplets.done),
+ system: systemUpdate
+ });
+ }
+
+ async recuperationBlessure({ actor, timestamp, message, isMaladeEmpoisonne, blessures }) {
+ if (this.parent != actor || actor == undefined) {
+ return;
+ }
+ if (new RdDTimestamp(this.system.fin).isAfterIndexDate(timestamp)) {
+ // attente periode
+ return
+ }
+ if (this.system.gravite > 0) {
+ const update = { premierssoins: { bonus: 0 }, soinscomplets: { bonus: 0 } }
+ const gravite = this.system.gravite;
+ const graviteMoindre = gravite - 2;
+ const moindres = blessures.filter(it => it.system.gravite == graviteMoindre, 'blessures').length
+ const labelGravite = RdDItemBlessure.getLabelGravite(gravite);
+
+ let rolled = await actor.jetRecuperationConstitution(Misc.toInt(this.system.soinscomplets.bonus) + actor.system.sante.bonusPotion, message);
+
+ if (rolled.isETotal) {
+ message.content += ` -- une blessure ${labelGravite} s'infecte (temps de guérison augmenté de ${definition.facteur} jours, perte de vie)`;
+ mergeObject(update, { fin: { indexDate: timestamp.addJours(gravite).indexDate } });
+ await actor.santeIncDec("vie", -1);
+ }
+ else {
+ if (!isMaladeEmpoisonne && rolled.isSuccess && this.peutRetrograder(graviteMoindre, moindres)) {
+ message.content += ` -- une blessure ${labelGravite} cicatrise`;
+ mergeObject(update, { gravite: graviteMoindre, fin: { indexDate: timestamp.addJours(graviteMoindre).indexDate } });
+ }
+ else {
+ message.content += ` -- une blessure ${labelGravite} reste stable`;
+ }
+ }
+ await this.update(update);
+ }
+ }
+
+ peutRetrograder(graviteMoindre, moindres) {
+ return moindres < RdDItemBlessure.getDefinition(graviteMoindre).max
+ }
+
+ async calculerFinPeriodeTemporel(debut) {
+ return await debut.nouveauJour().addJours(this.system.gravite);
+ }
+
+ async onFinPeriode(oldTimestamp, newTimestamp) {
+ if (this.system.gravite <= 0) {
+ await super.onFinPeriode(oldTimestamp, newTimestamp)
+ }
+ }
+
+ getImgSoins(gravite, soins) {
+ let img = 'blessure'
+ if (gravite > 6) {
+ img = 'mort'
+ }
+ if (gravite <= 0) {
+ img = 'eraflure'
+ }
+ return `systems/foundryvtt-reve-de-dragon/icons/sante/${soins ? 'blessure-soins' : img}.webp`
+ }
+
+ getLabelGravite() {
+ return RdDItemBlessure.getDefinition(this.system.gravite).labelGravite
+ }
+
+ static getDefinition(gravite) {
+ return definitionsBlessures.sort(Misc.ascending(it => it.gravite))
+ .find(it => it.gravite >= gravite);
+ }
+ static maxBlessures(gravite) {
+ return RdDItemBlessure.getDefinition(gravite).max
+ }
+
+ isContusion() {
+ return this.system.gravite <= 0
+ }
+ isLegere() {
+ return this.system.gravite > 0 && this.system.gravite <= 2
+ }
+ isGrave() {
+ return this.system.gravite > 2 && this.system.gravite <= 4
+ }
+ isCritique() {
+ return this.system.gravite > 4 && this.system.gravite <= 6
+ }
+ isMort() {
+ return this.system.gravite > 6
+ }
+}
diff --git a/module/item/sheet-blessure.js b/module/item/sheet-blessure.js
new file mode 100644
index 00000000..cbab7ad8
--- /dev/null
+++ b/module/item/sheet-blessure.js
@@ -0,0 +1,29 @@
+import { RdDItemSheet } from "../item-sheet.js";
+
+export class RdDBlessureItemSheet extends RdDItemSheet {
+
+ static get ITEM_TYPE() { return "blessure" };
+
+ async getData() {
+ const formData = await super.getData();
+ formData.disabled = formData.options.isGM || formData.options.isOwned ? '' : 'disabled';
+ return formData;
+ }
+
+ activateListeners(html) {
+ super.activateListeners(html);
+
+ if (!this.options.editable) return;
+
+ this.html.find('[name="premierssoins-done"]').change(async event => {
+ await this.item.setSoinsBlessure({ premierssoins: { done: event.currentTarget.checked } });
+ });
+ this.html.find('[name="soinscomplets-done"]').change(async event => {
+ await this.item.setSoinsBlessure({ soinscomplets: { done: event.currentTarget.checked } })
+ });
+ this.html.find('[name="system-gravite"]').change(async event => {
+ const gravite = Number(event.currentTarget.value)
+ await this.item.setSoinsBlessure({ gravite: gravite, difficulte: - gravite })
+ });
+ }
+}
diff --git a/module/migrations.js b/module/migrations.js
index 8b97047c..b1d3513f 100644
--- a/module/migrations.js
+++ b/module/migrations.js
@@ -416,6 +416,49 @@ class _10_5_0_UpdatePeriodicite extends Migration {
}
}
+class _10_7_0_MigrationBlessures extends Migration {
+ get code() { return "migration-blessures"; }
+ get version() { return "10.7.0"; }
+
+ async migrate() {
+ const timestamp = game.system.rdd.calendrier.getTimestamp()
+ await Promise.all(game.actors.filter(it => it.isPersonnage() || it.isCreature())
+ .map(async (actor) => {
+ const legeres = actor.system.blessures?.legeres.liste.filter(it => it.active).map(it => this.creerBlessure(2, 'légère', it, timestamp)) ?? [];
+ const graves = actor.system.blessures?.graves.liste.filter(it => it.active).map(it => this.creerBlessure(4, 'grave', it, timestamp)) ?? [];
+ const critiques = actor.system.blessures?.critiques.liste.filter(it => it.active).map(it => this.creerBlessure(6, 'critique', it, timestamp));
+ const blessures = legeres.concat(graves).concat(critiques);
+ if (blessures.length > 0) {
+ await actor.createEmbeddedDocuments("Item", blessures);
+ }
+ await actor.update({
+ 'system.blessures.legeres.liste': [],
+ 'system.blessures.graves.liste': [],
+ 'system.blessures.critiques.liste': []
+ })
+ }));
+ }
+ creerBlessure(gravite, graviteTexte, blessure, timestamp) {
+ const dateBlessure = timestamp.addJours(-blessure.jours);
+ const datePremiereRecup = dateBlessure.addJours(gravite);
+ return {
+ name: `Blessure ${graviteTexte}`,
+ type: 'blessure',
+ img: `systems/foundryvtt-reve-de-dragon/icons/sante/blessure${blessure.psdone ? '-soins' : ''}.webp`,
+ system: {
+ gravite: gravite,
+ difficulte: -gravite,
+ debut: { indexDate: dateBlessure.indexDate, indexMinute: 0 },
+ fin: { indexDate: datePremiereRecup.indexDate, indexMinute: 0 },
+ premierssoins: { done: blessure.psdone, bonus: blessure.premiers_soins },
+ soinscomplets: { done: blessure.scdone, bonus: blessure.soins_complets },
+ localisation: blessure.localisation,
+ jours: blessure.jours
+ }
+ }
+ }
+}
+
export class Migrations {
static getMigrations() {
return [
@@ -431,6 +474,7 @@ export class Migrations {
new _10_3_17_Monnaies(),
new _10_4_6_ServicesEnCommerces(),
new _10_5_0_UpdatePeriodicite(),
+ new _10_7_0_MigrationBlessures(),
];
}
@@ -447,7 +491,7 @@ export class Migrations {
migrate() {
const currentVersion = game.settings.get(SYSTEM_RDD, "systemMigrationVersion");
if (isNewerVersion(game.system.version, currentVersion)) {
- //if (true) { /* comment previous and uncomment here to test before upgrade */
+ //if (true) { /* comment previous and uncomment here to test before upgrade */
const migrations = Migrations.getMigrations().filter(m => isNewerVersion(m.version, currentVersion));
if (migrations.length > 0) {
migrations.sort((a, b) => this.compareVersions(a, b));
diff --git a/module/rdd-bonus.js b/module/rdd-bonus.js
index 25bbdb3e..2516b0ff 100644
--- a/module/rdd-bonus.js
+++ b/module/rdd-bonus.js
@@ -28,7 +28,7 @@ export class RdDBonus {
}
/* -------------------------------------------- */
- static dmg(rollData, dmgActor, isCauchemar = false) {
+ static dmg(rollData, dmgActor, isEntiteIncarnee = false) {
let dmg = { total: 0 };
if (rollData.arme && rollData.arme.name.toLowerCase() == "esquive") {
// Specific case management
@@ -41,7 +41,7 @@ export class RdDBonus {
dmg.dmgSurprise = RdDBonus.dmgBonus(rollData.ajustements?.attaqueDefenseurSurpris.used);
dmg.dmgActor = rollData.selectedCarac ? RdDBonus._dmgPerso(dmgActor, rollData.selectedCarac.label, dmg.dmgArme) : 0;
dmg.total = dmg.dmgSurprise + dmg.dmgTactique + dmg.dmgArme + dmg.dmgActor + dmg.dmgParticuliere;
- dmg.mortalite = RdDBonus._calculMortalite(rollData, isCauchemar)
+ dmg.mortalite = RdDBonus._calculMortalite(rollData, isEntiteIncarnee)
}
return dmg;
}
@@ -62,11 +62,8 @@ export class RdDBonus {
}
/* -------------------------------------------- */
- static _calculMortalite(rollData, isCauchemar) {
- if (isCauchemar) {
- return "cauchemar";
- }
- return isCauchemar ? "cauchemar"
+ static _calculMortalite(rollData, isEntiteIncarnee) {
+ return isEntiteIncarnee ? "entiteincarnee"
: rollData.dmg?.mortalite
?? rollData.arme?.system.mortalite
?? "mortel";
diff --git a/module/rdd-calendrier.js b/module/rdd-calendrier.js
index 0053d319..03fb26a5 100644
--- a/module/rdd-calendrier.js
+++ b/module/rdd-calendrier.js
@@ -45,6 +45,14 @@ export class RdDCalendrier extends Application {
Hooks.on('updateSetting', async (setting, update, options, id) => this.onUpdateSetting(setting, update, options, id));
}
+ display() {
+ let templatePath = "systems/foundryvtt-reve-de-dragon/templates/calendar-template.html";
+ renderTemplate(templatePath, {}).then(html => {
+ this.render(true);
+ });
+ return this;
+ }
+
async onUpdateSetting(setting, update, options, id) {
if (setting.key == SYSTEM_RDD + '.' + WORLD_TIMESTAMP_SETTING) {
this.timestamp = RdDTimestamp.getWorldTime();
diff --git a/module/rdd-combat.js b/module/rdd-combat.js
index 904384d6..435be56d 100644
--- a/module/rdd-combat.js
+++ b/module/rdd-combat.js
@@ -1295,13 +1295,8 @@ export class RdDCombat {
blessuresStatus: actor.computeResumeBlessure(),
SConst: actor.getSConst(),
actorId: actor.id,
- isGrave: false,
- isCritique: false
- }
- if (actor.countBlessuresNonSoigneeByName("critiques") > 0) { // Pour éviter le cumul grave + critique
- formData.isCritique = true;
- } else if (actor.countBlessuresNonSoigneeByName("graves") > 0) {
- formData.isGrave = true;
+ isGrave: actor.countBlessures(it => it.isGraves()) > 0,
+ isCritique: actor.countBlessures(it => it.isCritique()) > 0
}
ChatUtility.createChatWithRollMode(actor.name, {
diff --git a/module/rdd-commands.js b/module/rdd-commands.js
index ebab970a..74dd1e61 100644
--- a/module/rdd-commands.js
+++ b/module/rdd-commands.js
@@ -332,7 +332,7 @@ export class RdDCommands {
let competence = length > 1 ? actors[0].getCompetence(Misc.join(params.slice(1, length), ' ')) : { name: undefined };
if (competence) {
for (let actor of actors) {
- await actor.rollCaracCompetence(caracName, competence.name, diff);
+ await actor.doRollCaracCompetence(caracName, competence.name, diff);
}
}
return;
diff --git a/module/rdd-main.js b/module/rdd-main.js
index 81f12111..73cf5d55 100644
--- a/module/rdd-main.js
+++ b/module/rdd-main.js
@@ -36,6 +36,7 @@ import { RdDActorVehiculeSheet } from "./actor-vehicule-sheet.js";
import { RdDActorEntiteSheet } from "./actor-entite-sheet.js";
import { RdDItem } from "./item.js";
+import { RdDItemBlessure } from "./item/blessure.js";
import { RdDItemService } from "./item/service.js";
import { RdDItemMaladie } from "./item/maladie.js";
import { RdDItemPoison } from "./item/poison.js";
@@ -46,6 +47,7 @@ import { RdDItemSouffle } from "./item/souffle.js";
import { RdDRencontre } from "./item/rencontre.js";
import { RdDItemSheet } from "./item-sheet.js";
+import { RdDBlessureItemSheet } from "./item/sheet-blessure.js";
import { RdDServiceItemSheet } from "./item/sheet-service.js";
import { RdDRencontreItemSheet } from "./item/sheet-rencontre.js";
import { RdDHerbeItemSheet } from "./item/sheet-herbe.js";
@@ -74,21 +76,22 @@ export class SystemReveDeDragon {
this.RdDUtility = RdDUtility;
this.RdDHotbar = RdDHotbar;
this.itemClasses = {
- service: RdDItemService,
+ blessure: RdDItemBlessure,
maladie: RdDItemMaladie,
+ ombre: RdDItemOmbre,
poison: RdDItemPoison,
queue: RdDItemQueue,
- ombre: RdDItemOmbre,
- souffle: RdDItemSouffle,
+ rencontre: RdDRencontre,
+ service: RdDItemService,
signedraconique: RdDItemSigneDraconique,
- rencontre: RdDRencontre
+ souffle: RdDItemSouffle,
}
this.actorClasses = {
+ commerce: RdDCommerce,
creature: RdDActor,
entite: RdDActor,
personnage: RdDActor,
vehicule: RdDActor,
- commerce: RdDCommerce,
}
}
@@ -157,6 +160,7 @@ export class SystemReveDeDragon {
RdDItemSheet.register(RdDPlanteItemSheet);
RdDItemSheet.register(RdDIngredientItemSheet);
RdDItemSheet.register(RdDServiceItemSheet);
+ RdDItemSheet.register(RdDBlessureItemSheet);
Items.registerSheet(SYSTEM_RDD, RdDItemInventaireSheet, {
types: [
@@ -276,8 +280,8 @@ export class SystemReveDeDragon {
let sidebar = document.getElementById("sidebar");
sidebar.style.width = "min-content";
}
-
if (Misc.isUniqueConnectedGM()) {
+ game.system.rdd.calendrier = new RdDCalendrier();
new Migrations().migrate();
}
@@ -286,13 +290,7 @@ export class SystemReveDeDragon {
RdDDice.onReady();
/* -------------------------------------------- */
/* Affiche/Init le calendrier */
- let calendrier = new RdDCalendrier();
- let templatePath = "systems/foundryvtt-reve-de-dragon/templates/calendar-template.html";
- let templateData = {};
- renderTemplate(templatePath, templateData).then(html => {
- calendrier.render(true);
- });
- game.system.rdd.calendrier = calendrier; // Reference;
+ game.system.rdd.calendrier = new RdDCalendrier().display();
// Avertissement si joueur sans personnage
if (!game.user.isGM && game.user.character == undefined) {
diff --git a/module/rdd-roll-encaisser.js b/module/rdd-roll-encaisser.js
index 4d98e413..a9fc2d84 100644
--- a/module/rdd-roll-encaisser.js
+++ b/module/rdd-roll-encaisser.js
@@ -30,9 +30,9 @@ export class RdDEncaisser extends Dialog {
};
}
else if (actor.isEntite([ENTITE_BLURETTE, ENTITE_INCARNE])) {
- dialogConf.default = "cauchemar"
+ dialogConf.default = "entiteincarnee"
dialogConf.buttons = {
- "cauchemar": { label: "Cauchemar", callback: html => this.performEncaisser("cauchemar") }
+ "entiteincarnee": { label: "Entité incarnée", callback: html => this.performEncaisser("entiteincarnee") }
}
}
@@ -70,7 +70,6 @@ export class RdDEncaisser extends Dialog {
total: Number(this.modifier),
ajustement: Number(this.modifier),
encaisserSpecial: this.encaisserSpecial,
- loc: { result: 0, label: "" },
mortalite: mortalite
}
});
diff --git a/module/rdd-sheet-utility.js b/module/rdd-sheet-utility.js
index da9732cb..28bca225 100644
--- a/module/rdd-sheet-utility.js
+++ b/module/rdd-sheet-utility.js
@@ -9,7 +9,7 @@ export class RdDSheetUtility {
: document.getUserLevel(game.user);
mergeObject(options, {
isGM: game.user.isGM,
- isOwned: document.parent,
+ isOwned: document.parent ? true : false,
editable: editable,
cssClass: editable ? "editable" : "locked",
isLimited: userRightLevel >= CONST.DOCUMENT_OWNERSHIP_LEVELS.LIMITED,
diff --git a/module/rdd-token-hud.js b/module/rdd-token-hud.js
index 6d29ecab..12dcaf4d 100644
--- a/module/rdd-token-hud.js
+++ b/module/rdd-token-hud.js
@@ -2,6 +2,7 @@
import { HtmlUtility } from "./html-utility.js";
import { Misc } from "./misc.js";
import { RdDCombatManager } from "./rdd-combat.js";
+import { Targets } from "./targets.js";
/* -------------------------------------------- */
export class RdDTokenHud {
@@ -18,29 +19,39 @@ export class RdDTokenHud {
}
/* -------------------------------------------- */
- static async addExtensionHud(app, html, tokenId) {
+ static async addExtensionHud(app, html, tokenId, isCombat) {
let token = canvas.tokens.get(tokenId);
let actor = token.actor;
- let combatant = game.combat.combatants.find(c => c.tokenId == tokenId);
- if (! (combatant?.actor) ) {
+ app.hasExtension = true;
+ // soins
+ await RdDTokenHud.addExtensionHudSoins(html, actor);
+
+ if (isCombat) {
+ let combatant = game.combat.combatants.find(c => c.tokenId == tokenId);
+ if (!(combatant?.actor)) {
ui.notifications.warn(`Le combatant ${token.name} n'est pas associé à un acteur, impossible de déterminer ses actions de combat!`)
return;
+ }
+ let actions = RdDCombatManager.listActionsCombat(combatant);
+ // initiative
+ await RdDTokenHud.addExtensionHudInit(html, combatant, actions);
+ // combat
+ await RdDTokenHud.addExtensionHudCombat(html, combatant, actions);
}
- app.hasExtension = true;
- let actionsCombat = RdDCombatManager.listActionsCombat(combatant);
+
+ }
+
+ static async addExtensionHudInit(html, combatant, actions) {
const hudData = {
- combatant: combatant,
- actions: actionsCombat,
+ combatant, actions,
commandes: [
{ name: "Autre action", command: 'autre' },
- { name: 'Initiative +1', command: 'inc', value: 0.01 },
+ { name: 'Initiative +1', command: 'inc', value: 0.01 },
{ name: 'Initiative -1', command: 'dec', value: -0.01 }]
};
-
const controlIconCombat = html.find('.control-icon[data-action=combat]');
- // initiative
await RdDTokenHud._configureSubMenu(controlIconCombat,
'systems/foundryvtt-reve-de-dragon/templates/hud-actor-init.html',
hudData,
@@ -51,48 +62,70 @@ export class RdDTokenHud {
RdDTokenHud._initiativeCommand(initCommand, combatantId);
} else {
let index = event.currentTarget.attributes['data-action-index'].value;
- let action = actionsCombat[index];
+ let action = hudData.actions[index];
RdDCombatManager.rollInitiativeAction(combatantId, action);
- }
+ }
});
+ }
+ static async addExtensionHudCombat(html, combatant, actions) {
+ const hudData = { combatant, actions, commandes: [] };
const controlIconTarget = html.find('.control-icon[data-action=target]');
- // combat
await RdDTokenHud._configureSubMenu(controlIconTarget, 'systems/foundryvtt-reve-de-dragon/templates/hud-actor-attaque.html', hudData,
(event) => {
const actionIndex = event.currentTarget.attributes['data-action-index']?.value;
- const action = actionsCombat[actionIndex];
+ const action = hudData.actions[actionIndex];
if (action.action == 'conjurer') {
- actor.conjurerPossession(actor.getPossession(action.system.possessionid));
+ const possession = combatant.actor.getPossession(action.system.possessionid);
+ combatant.actor.conjurerPossession(possession);
}
else {
- actor.rollArme(action);
+ combatant.actor.rollArme(action);
}
});
}
+ static async addExtensionHudSoins(html, sourceActor) {
+ const target = Targets.getTarget({ warn: false });
+ if (target?.actor) {
+ const hudSoins = { blessures: target.actor.blessuresASoigner() ?? [] };
+ if (hudSoins.blessures.length > 0) {
+ // soins
+ const controlIconTarget = html.find('.control-icon[data-action=combat]');
+ await RdDTokenHud._configureSubMenu(controlIconTarget,
+ 'systems/foundryvtt-reve-de-dragon/templates/hud-actor-soins.hbs',
+ hudSoins,
+ (event) => {
+ const blessureId = event.currentTarget.attributes['data-blessure-id']?.value;
+ sourceActor.rollSoins(target.actor, blessureId)
+ });
+ }
+ }
+ }
+
static _initiativeCommand(initCommand, combatantId) {
switch (initCommand) {
case 'inc': return RdDCombatManager.incDecInit(combatantId, 0.01);
case 'dec': return RdDCombatManager.incDecInit(combatantId, -0.01);
- case 'autre': return RdDCombatManager.rollInitiativeAction(combatantId,
+ case 'autre': return RdDCombatManager.rollInitiativeAction(combatantId,
{ name: "Autre action", action: 'autre', system: { initOnly: true, competence: "Autre action" } });
}
}
/* -------------------------------------------- */
static async addTokenHudExtensions(app, html, tokenId) {
- const controlIconCombat = html.find('.control-icon[data-action=combat]');
- controlIconCombat.click(event => {
- if (event.currentTarget.className.includes('active')) {
- RdDTokenHud.removeExtensionHud(app, html, tokenId);
- } else {
- setTimeout(function () { RdDTokenHud.addExtensionHud(app, html, tokenId) }, 200);
- }
- });
+ const controlIconCombat = html.find('.control-icon[data-action=combat]');
+ if (controlIconCombat.length > 0) {
+ controlIconCombat.click(event => {
+ if (event.currentTarget.className.includes('active')) {
+ RdDTokenHud.removeExtensionHud(app, html, tokenId);
+ } else {
+ setTimeout(() => RdDTokenHud.addExtensionHud(app, html, tokenId), 200);
+ }
+ });
- if (controlIconCombat.length>0 && controlIconCombat[0].className.includes('active')) {
- RdDTokenHud.addExtensionHud(app, html, tokenId);
+ const isCombat = controlIconCombat[0].className.includes('active');
+ RdDTokenHud.addExtensionHud(app, html, tokenId, isCombat);
}
}
@@ -100,9 +133,9 @@ export class RdDTokenHud {
static async _configureSubMenu(insertionPoint, template, hudData, onMenuItem) {
const hud = $(await renderTemplate(template, hudData));
const list = hud.find('div.rdd-hud-list');
-
+
RdDTokenHud._toggleHudListActive(hud, list);
-
+
hud.find('img.rdd-hud-togglebutton').click(event => RdDTokenHud._toggleHudListActive(hud, list));
list.find('.rdd-hud-menu').click(onMenuItem);
diff --git a/module/rdd-utility.js b/module/rdd-utility.js
index 460b96bb..55e968de 100644
--- a/module/rdd-utility.js
+++ b/module/rdd-utility.js
@@ -19,7 +19,7 @@ import { RdDRaretes } from "./item/raretes.js";
/* -------------------------------------------- */
// This table starts at 0 -> niveau -10
const carac_array = ["taille", "apparence", "constitution", "force", "agilite", "dexterite", "vue", "ouie", "odoratgout", "volonte", "intellect", "empathie", "reve", "chance", "melee", "tir", "lancer", "derobee"];
-const difficultesLibres = Misc.intArray(0, -11);
+const difficultesLibres = Misc.intArray(0, -11);
const ajustementsConditions = Misc.intArray(-10, 11);
const ajustementsEncaissement = Misc.intArray(-10, 26);
@@ -66,38 +66,31 @@ const fatigueMarche = {
"tresdifficile": { "4": 4, "6": 6 }
}
-/* -------------------------------------------- */
-const definitionsBlessures = [
- { type: "legere", facteur: 2 },
- { type: "grave", facteur: 4 },
- { type: "critique", facteur: 6 }
-]
-
/* -------------------------------------------- */
const nomEthylisme = ["Emeché", "Gris", "Pinté", "Pas frais", "Ivre", "Bu", "Complètement fait", "Ivre mort"];
/* -------------------------------------------- */
const definitionsEncaissement = {
"mortel": [
- { minimum: undefined, maximum: 0, endurance: "0", vie: "0", eraflures: 0, legeres: 0, graves: 0, critiques: 0 },
- { minimum: 1, maximum: 10, endurance: "1d4", vie: "0", eraflures: 1, legeres: 0, graves: 0, critiques: 0 },
- { minimum: 11, maximum: 15, endurance: "1d6", vie: "0", eraflures: 0, legeres: 1, graves: 0, critiques: 0 },
- { minimum: 16, maximum: 19, endurance: "2d6", vie: "2", eraflures: 0, legeres: 0, graves: 1, critiques: 0 },
- { minimum: 20, maximum: undefined, endurance: "100", vie: "4 + @over20", eraflures: 0, legeres: 0, graves: 0, critiques: 1 },
+ { minimum: undefined, maximum: 0, endurance: "0", vie: "0", gravite: -1},
+ { minimum: 1, maximum: 10, endurance: "1d4", vie: "0", gravite: 0},
+ { minimum: 11, maximum: 15, endurance: "1d6", vie: "0", gravite: 2},
+ { minimum: 16, maximum: 19, endurance: "2d6", vie: "2", gravite: 4},
+ { minimum: 20, maximum: undefined, endurance: "100", vie: "4 + @over20", gravite: 6},
],
"non-mortel": [
- { minimum: undefined, maximum: 0, endurance: "0", vie: "0", eraflures: 0, legeres: 0, graves: 0, critiques: 0 },
- { minimum: 1, maximum: 10, endurance: "1d4", vie: "0", eraflures: 1, legeres: 0, graves: 0, critiques: 0 },
- { minimum: 11, maximum: 15, endurance: "1d6", vie: "0", eraflures: 1, legeres: 0, graves: 0, critiques: 0 },
- { minimum: 16, maximum: 19, endurance: "2d6", vie: "0", eraflures: 0, legeres: 1, graves: 0, critiques: 0 },
- { minimum: 20, maximum: undefined, endurance: "100", vie: "0", eraflures: 0, legeres: 1, graves: 0, critiques: 0 },
+ { minimum: undefined, maximum: 0, endurance: "0", vie: "0", gravite: -1},
+ { minimum: 1, maximum: 10, endurance: "1d4", vie: "0", gravite: 0 },
+ { minimum: 11, maximum: 15, endurance: "1d6", vie: "0", gravite: 0 },
+ { minimum: 16, maximum: 19, endurance: "2d6", vie: "0", gravite: 2 },
+ { minimum: 20, maximum: undefined, endurance: "100", vie: "0", gravite: 2 },
],
- "cauchemar": [
- { minimum: undefined, maximum: 0, endurance: "0", vie: "0", eraflures: 0, legeres: 0, graves: 0, critiques: 0 },
- { minimum: 1, maximum: 10, endurance: "1d4", vie: "0", eraflures: 1, legeres: 0, graves: 0, critiques: 0 },
- { minimum: 11, maximum: 15, endurance: "1d6", vie: "0", eraflures: 1, legeres: 0, graves: 0, critiques: 0 },
- { minimum: 16, maximum: 19, endurance: "2d6", vie: "0", eraflures: 1, legeres: 0, graves: 0, critiques: 0 },
- { minimum: 20, maximum: undefined, endurance: "3d6 + @over20", vie: "0", eraflures: 1, legeres: 0, graves: 0, critiques: 0 },
+ "entiteincarnee": [
+ { minimum: undefined, maximum: 0, endurance: "0", vie: "0", gravite: -1},
+ { minimum: 1, maximum: 10, endurance: "1d4", vie: "0", gravite: 0},
+ { minimum: 11, maximum: 15, endurance: "1d6", vie: "0", gravite: 0 },
+ { minimum: 16, maximum: 19, endurance: "2d6", vie: "0", gravite: 0 },
+ { minimum: 20, maximum: undefined, endurance: "3d6 + @over20", vie: "0", gravite: 0 },
]
};
@@ -139,7 +132,7 @@ export class RdDUtility {
'systems/foundryvtt-reve-de-dragon/templates/actor/xp-competences.html',
'systems/foundryvtt-reve-de-dragon/templates/actor/combat.html',
'systems/foundryvtt-reve-de-dragon/templates/actor/blessures.html',
- 'systems/foundryvtt-reve-de-dragon/templates/actor/blessure.html',
+ 'systems/foundryvtt-reve-de-dragon/templates/actor/blessure.hbs',
'systems/foundryvtt-reve-de-dragon/templates/actor/maladies-poisons.html',
'systems/foundryvtt-reve-de-dragon/templates/actor/possessions.html',
'systems/foundryvtt-reve-de-dragon/templates/actor/taches.html',
@@ -276,7 +269,8 @@ export class RdDUtility {
Handlebars.registerHelper('computeResolutionChances', (row, col) => RdDResolutionTable.computeChances(row, col));
Handlebars.registerHelper('upperFirst', str => Misc.upperFirst(str ?? 'Null'));
Handlebars.registerHelper('lowerFirst', str => Misc.lowerFirst(str ?? 'Null'));
- Handlebars.registerHelper('upper', str => str?.toUpperCase() ?? 'NULL');
+ Handlebars.registerHelper('upper', str => str?.toUpperCase() ?? '');
+ Handlebars.registerHelper('lowercase', str => str?.toLowerCase() ?? '');
Handlebars.registerHelper('le', str => Grammar.articleDetermine(str));
Handlebars.registerHelper('apostrophe', (article, str) => Grammar.apostrophe(article, str));
Handlebars.registerHelper('un', str => Grammar.articleIndetermine(str));
@@ -472,10 +466,6 @@ export class RdDUtility {
return ajustementsEncaissement;
}
- static getDefinitionsBlessures() {
- return definitionsBlessures;
- }
-
/* -------------------------------------------- */
static getSegmentsFatigue(maxEnd) {
maxEnd = Math.max(maxEnd, 1);
@@ -616,17 +606,10 @@ export class RdDUtility {
encaissement.dmg.loc.label = encaissement.dmg.loc.label ?? 'Corps;';
encaissement.roll = roll;
encaissement.armure = armure;
+ encaissement.penetration = rollData.arme?.system.penetration ?? 0;
encaissement.total = jetTotal;
encaissement.vie = await RdDUtility._evaluatePerte(encaissement.vie, over20);
encaissement.endurance = await RdDUtility._evaluatePerte(encaissement.endurance, over20);
- encaissement.penetration = rollData.arme?.system.penetration ?? 0;
- encaissement.blessures = (
- encaissement.critiques > 0 ? "Critique" :
- encaissement.graves > 0 ? "Grave" :
- encaissement.legeres > 0 ? "Légère" :
- encaissement.eraflures > 0 ? "Contusions/Eraflures" :
- 'Aucune'
- );
return encaissement;
}
diff --git a/module/targets.js b/module/targets.js
index f975a60d..7217bea1 100644
--- a/module/targets.js
+++ b/module/targets.js
@@ -39,18 +39,18 @@ export class Targets {
}
}
- static getTarget() {
+ static getTarget(options = { warn: true }) {
const targets = Targets.listTargets();
switch (targets.length) {
case 1:
return targets[0];
case 0:
- ui.notifications.warn("Vous devez choisir une cible à attaquer!");
+ if (options.warn) ui.notifications.warn("Vous devez choisir une cible à attaquer!");
break;
default:
- ui.notifications.warn("Vous devez choisir une cible (et une seule) à attaquer!");
- return;
+ if (options.warn) ui.notifications.warn("Vous devez choisir une cible (et une seule) à attaquer!");
}
+ return undefined;
}
}
\ No newline at end of file
diff --git a/styles/simple.css b/styles/simple.css
index 01c3c55b..f5144534 100644
--- a/styles/simple.css
+++ b/styles/simple.css
@@ -186,7 +186,7 @@ i:is(.fas, .far) {
}
.system-foundryvtt-reve-de-dragon .sheet-header :is(.header-compteurs,.header-etats,.profile-img, .profile-img-token){
- padding: 0 3%;
+ padding: 0 0.4rem;
}
.system-foundryvtt-reve-de-dragon .sheet-header :is(.profile-img, .profile-img-token) {
@@ -213,11 +213,13 @@ i:is(.fas, .far) {
}
.system-foundryvtt-reve-de-dragon .sheet-header .header-compteurs {
+ width: calc(60% - 110px - 1rem);
text-align: right;
max-width: fit-content;
}
.system-foundryvtt-reve-de-dragon .sheet-header div.header-etats {
+ width: calc(40% - 32px - 1rem);
height: 48px;
max-width: fit-content;
flex: initial;
@@ -426,6 +428,7 @@ span.equipement-detail-buttons {
justify-content: center;
text-align: left;
}
+
.blessure-control {
flex-grow: 1;
flex-direction: row;
@@ -457,14 +460,17 @@ input:is(.blessure-premiers_soins, .blessure-soins_complets) {
.blessure-inactive {
color:rgba(150, 150, 150, 0.4);
}
+.blessure-active-2,
.blessure-active-legere {
color:rgba(60, 60, 60, 0.9);
text-shadow: 1px 1px 4px rgba(60, 60, 60, 1);
}
+.blessure-active-4,
.blessure-active-grave {
color: rgba(218, 126, 21, 0.9);
text-shadow: 1px 1px 4px rgba(60, 60, 60, 1);
}
+.blessure-active-6,
.blessure-active-critique {
color: rgba(173, 36, 26, 0.9);
text-shadow: 1px 1px 4px rgba(60, 60, 60, 1);
@@ -1386,27 +1392,36 @@ table.table-nombres-astraux tr:hover {
}
/* ======================================== */
-.tokenhudext {
+.token-hud-ext {
display: flex;
flex: 0 !important;
font-family: CaslonPro;
font-weight: 600;
}
-.tokenhudext.left {
+.token-hud-ext.left {
justify-content: flex-start;
flex-direction: column;
position: absolute;
top: 2.75rem;
right: 4rem;
}
-.tokenhudext.right {
+.token-hud-ext.soins {
+ justify-content: flex-start;
+ flex-direction: column;
+ position: absolute;
+ top: 13.2rem;
+ left: -5rem;
+ max-width: 8.5rem
+}
+
+.token-hud-ext.right {
justify-content: flex-start;
flex-direction: column;
position: absolute;
top: 2.75rem;
left: 4rem;
}
-.control-icon.tokenhudicon {
+.control-icon.token-hud-icon {
width: fit-content;
height: fit-content;
min-width: 6rem;
@@ -1415,7 +1430,7 @@ table.table-nombres-astraux tr:hover {
line-height: 1rem;
margin: 0.2rem;
}
-.control-icon.tokenhudicon.right {
+.control-icon.token-hud-icon.right {
margin-left: 8px;
}
.rdd-hud-menu label {
diff --git a/system.json b/system.json
index 9d83c073..805704df 100644
--- a/system.json
+++ b/system.json
@@ -1,8 +1,8 @@
{
"id": "foundryvtt-reve-de-dragon",
"title": "Rêve de Dragon",
- "version": "10.6.25",
- "download": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/archive/foundryvtt-reve-de-dragon-10.6.25.zip",
+ "version": "10.7.0",
+ "download": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/archive/foundryvtt-reve-de-dragon-10.7.0.zip",
"manifest": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/raw/v10/system.json",
"compatibility": {
"minimum": "10",
diff --git a/template.json b/template.json
index 52543e5f..a58c064c 100644
--- a/template.json
+++ b/template.json
@@ -179,23 +179,8 @@
"value": 10,
"label": "Endurance",
"derivee": false
- }
- },
- "blessures": {
- "legeres": {
- "liste": [ { "active": false, "psdone": false, "premiers_soins": -1, "scdone": false, "soins_complets": -1, "jours": 0, "localisation": "" },
- { "active": false, "psdone": false, "premiers_soins": -1, "scdone": false, "soins_complets": -1, "jours": 0, "localisation": "" },
- { "active": false, "psdone": false, "premiers_soins": -1, "scdone": false, "soins_complets": -1, "jours": 0, "localisation": "" },
- { "active": false, "psdone": false, "premiers_soins": -1, "scdone": false, "soins_complets": -1, "jours": 0, "localisation": "" },
- { "active": false, "psdone": false, "premiers_soins": -1, "scdone": false, "soins_complets": -1, "jours": 0, "localisation": "" } ]
},
- "graves": {
- "liste": [ { "active": false, "psdone": false, "premiers_soins": -1, "scdone": false, "soins_complets": -1, "jours": 0, "localisation": "" },
- { "active": false, "psdone": false, "premiers_soins": -1, "scdone": false, "soins_complets": -1, "jours": 0, "localisation": "" } ]
- },
- "critiques": {
- "liste": [ { "active": false, "psdone": false, "premiers_soins": -1, "scdone": false, "soins_complets": -1, "jours": 0, "localisation": "" } ]
- }
+ "bonusPotion": 0
},
"attributs": {
"plusdom": {
@@ -380,23 +365,8 @@
"value": 0,
"label": "Fatigue",
"derivee": true
- }
- },
- "blessures": {
- "legeres": {
- "liste": [ { "active": false, "premiers_soins": 0, "soins_complets": 0, "jours": 0, "localisation": "" },
- { "active": false, "premiers_soins": 0, "soins_complets": 0, "jours": 0, "localisation": "" },
- { "active": false, "premiers_soins": 0, "soins_complets": 0, "jours": 0, "localisation": "" },
- { "active": false, "premiers_soins": 0, "soins_complets": 0, "jours": 0, "localisation": "" },
- { "active": false, "premiers_soins": 0, "soins_complets": 0, "jours": 0, "localisation": "" } ]
},
- "graves": {
- "liste": [ { "active": false, "premiers_soins": 0, "soins_complets": 0, "jours": 0, "localisation": "" },
- { "active": false, "premiers_soins": 0, "soins_complets": 0, "jours": 0, "localisation": "" } ]
- },
- "critiques": {
- "liste": [ { "active": false, "premiers_soins": 0, "soins_complets": 0, "jours": 0, "localisation": "" } ]
- }
+ "bonusPotion": 0
},
"attributs": {
"sconst": {
@@ -567,7 +537,7 @@
"monnaie", "nourritureboisson", "gemme",
"service",
"meditation", "rencontre", "queue", "ombre", "souffle", "tete", "casetmr", "signedraconique", "sort", "sortreserve",
- "nombreastral", "tache", "maladie", "poison", "possession",
+ "nombreastral", "tache", "blessure", "maladie", "poison", "possession",
"tarot", "extraitpoetique"
],
"templates": {
@@ -636,6 +606,22 @@
"compteur": 0,
"date": 0
},
+ "blessure": {
+ "templates": ["temporel"],
+ "gravite": 0,
+ "difficulte": 0,
+ "premierssoins": {
+ "tache": 0,
+ "done": false,
+ "bonus": 0
+ },
+ "soinscomplets": {
+ "done": false,
+ "bonus": 0
+ },
+ "localisation": "",
+ "jours": 0
+ },
"maladie": {
"templates": ["description", "temporel"],
"identifie": false,
@@ -833,7 +819,8 @@
"points_de_tache_courant": 0,
"nb_jet_echec": 0,
"nb_jet_succes": 0,
- "cacher_points_de_tache": false
+ "cacher_points_de_tache": false,
+ "itemId": ""
},
"sort": {
"templates": ["description"],
diff --git a/templates/actor/blessure.hbs b/templates/actor/blessure.hbs
new file mode 100644
index 00000000..16d9bc12
--- /dev/null
+++ b/templates/actor/blessure.hbs
@@ -0,0 +1,38 @@
+