Merge pull request 'Quelques corrections mineures' (#800) from feature/v13-corrections into v13
Release Creation / build (release) Successful in 1m40s

Reviewed-on: https, #800
This commit was merged in pull request #800.
This commit is contained in:
2026-04-26 22:38:40 +02:00
57 changed files with 478 additions and 443 deletions
+8
View File
@@ -1,10 +1,18 @@
# 13.0 # 13.0
## 13.0.35 - Les travaux d'Illisys
- Correction du recul contre une entité de cauchemar (qui utilise le rêve comme force)
- Correction erreur lors de la suppression d'un objet d'un conteneur
- Meilleure gestion des messages publics/GM, en particulier pour les tirage dans les compendiums
- Filtrage des boutons pour les acteurs non personnages (pour éviter de faire manger l'auberge...)
## 13.0.34 - La saumuche d'Illysis ## 13.0.34 - La saumuche d'Illysis
- la qualité des "improvisations du moment" se base sur le niveau du cuisinier - la qualité des "improvisations du moment" se base sur le niveau du cuisinier
- l'appel au moral n'est pas affiché à l'ouverture d'une fenêtre de jets de sorts (ou de tâche intellectuelle) - l'appel au moral n'est pas affiché à l'ouverture d'une fenêtre de jets de sorts (ou de tâche intellectuelle)
- la difficulté variable de l'annulation de magie est bien prise en compte - la difficulté variable de l'annulation de magie est bien prise en compte
- correction erreur lors de la suppression d'un objet d'un conteneur
## 13.0.33 - L'ébriété d'Illysis ## 13.0.33 - L'ébriété d'Illysis
-6
View File
@@ -2499,12 +2499,6 @@ body {
background: #1e1914; background: #1e1914;
border: 1px solid #482e1c; border: 1px solid #482e1c;
} }
.system-foundryvtt-reve-de-dragon #players {
border-image: url(../assets/ui/footer-button.webp) 10 repeat;
border-image-width: 4px;
border-image-outset: 0px;
background: #1e1914;
}
.system-foundryvtt-reve-de-dragon #navigation #scene-list .scene.nav-item.active { .system-foundryvtt-reve-de-dragon #navigation #scene-list .scene.nav-item.active {
background: #482e1c; background: #482e1c;
} }
Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 198 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 136 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 136 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 126 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 210 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 147 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 104 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 65 KiB

After

Width:  |  Height:  |  Size: 184 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 184 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 149 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 155 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 177 KiB

-7
View File
@@ -1912,13 +1912,6 @@
border: 1px solid rgba(72, 46, 28, 1); border: 1px solid rgba(72, 46, 28, 1);
} }
#players {
border-image: url(../assets/ui/footer-button.webp) 10 repeat;
border-image-width: 4px;
border-image-outset: 0px;
background: rgba(30, 25, 20, 1);
}
#navigation #scene-list .scene.nav-item.active { #navigation #scene-list .scene.nav-item.active {
background: rgba(72, 46, 28, 1); background: rgba(72, 46, 28, 1);
} }
+2 -2
View File
@@ -51,7 +51,7 @@ export class RdDActorSheet extends RdDBaseActorSangSheet {
foundry.utils.mergeObject(formData.calc, { foundry.utils.mergeObject(formData.calc, {
surenc: this.actor.computeMalusSurEncombrement(), surenc: this.actor.computeMalusSurEncombrement(),
surprise: RdDBonus.find(this.actor.getSurprise(false)).label, surprise: RdDBonus.find(this.actor.getSurprise(false)).label,
resumeBlessures: this.actor.computeResumeBlessure(this.actor.system.blessures), blessures: this.actor.computeResumeBlessure(this.actor.system.blessures),
caracTotal: RdDCarac.computeTotal(this.actor.system.carac, this.actor.system.beaute), caracTotal: RdDCarac.computeTotal(this.actor.system.carac, this.actor.system.beaute),
caracTotalXp: RdDCarac.computeTotalXp(this.actor.system.carac, this.actor.system.beaute), caracTotalXp: RdDCarac.computeTotalXp(this.actor.system.carac, this.actor.system.beaute),
surEncombrementMessage: this.actor.isSurenc() ? "Sur-Encombrement!" : "", surEncombrementMessage: this.actor.isSurenc() ? "Sur-Encombrement!" : "",
@@ -279,7 +279,7 @@ export class RdDActorSheet extends RdDBaseActorSangSheet {
// On pts de reve change // On pts de reve change
this.html.find('.pointsreve-value').change(async event => await this.actor.update({ "system.reve.reve.value": event.currentTarget.value })) this.html.find('.pointsreve-value').change(async event => await this.actor.update({ "system.reve.reve.value": event.currentTarget.value }))
this.html.find('.seuil-reve-value').change(async event => await this.actor.setPointsDeSeuil(event.currentTarget.value)) this.html.find('.seuil-reve-value').change(async event => await this.actor.update({ "system.reve.seuil.value": event.currentTarget.value }))
this.html.find('.stress-test').click(async event => await this.actor.transformerStress()) this.html.find('.stress-test').click(async event => await this.actor.transformerStress())
this.html.find('.moral-malheureux').click(async event => await this.actor.jetDeMoral(MORAL.MALHEUREUX)) this.html.find('.moral-malheureux').click(async event => await this.actor.jetDeMoral(MORAL.MALHEUREUX))
+147 -202
View File
@@ -175,7 +175,7 @@ export class RdDActor extends RdDBaseActorSang {
} }
isForceInsuffisante(forceRequise) { isForceInsuffisante(forceRequise) {
const force = parseInt(this.system.carac.force.value) const force = parseInt(this.getForce())
return forceRequise > force return forceRequise > force
} }
@@ -418,7 +418,7 @@ export class RdDActor extends RdDBaseActorSang {
} }
async _recupereMoralChateauDormant(message) { async _recupereMoralChateauDormant(message) {
await this.update({ 'system.compteurs.bonmoments': [] }, { render: false }) await this.update({ 'system.compteurs.bonmoments': [] })
if (!ReglesOptionnelles.isUsing("recuperation-moral")) { return } if (!ReglesOptionnelles.isUsing("recuperation-moral")) { return }
@@ -498,14 +498,14 @@ export class RdDActor extends RdDBaseActorSang {
/* -------------------------------------------- */ /* -------------------------------------------- */
async remiseANeuf() { async remiseANeuf() {
await this.removeEffects(e => !e.statuses?.has(STATUSES.StatusDemiReve), { render: false }) await this.removeEffects(e => !e.statuses?.has(STATUSES.StatusDemiReve))
await this.supprimerBlessures(it => true, { render: false }) await this.supprimerBlessures(it => true)
await this.update({ await this.update({
'system.sante.endurance.value': this.system.sante.endurance.max, 'system.sante.endurance.value': this.system.sante.endurance.max,
'system.sante.vie.value': this.system.sante.vie.max, 'system.sante.vie.value': this.system.sante.vie.max,
'system.sante.fatigue.value': 0, 'system.sante.fatigue.value': 0,
'system.compteurs.ethylisme': { value: 1, nb_doses: 0, jet_moral: false } 'system.compteurs.ethylisme': { value: 1, nb_doses: 0, jet_moral: false }
}, { render: true }) })
await ChatMessage.create({ await ChatMessage.create({
whisper: ChatUtility.getOwners(this), whisper: ChatUtility.getOwners(this),
content: 'Remise à neuf de ' + this.name content: 'Remise à neuf de ' + this.name
@@ -689,8 +689,9 @@ export class RdDActor extends RdDBaseActorSang {
message.content += `<br>Vous n'avez bu que ${eauConsomme} doses de liquide pour une soif de ${sustNeeded}, vous avez soif! message.content += `<br>Vous n'avez bu que ${eauConsomme} doses de liquide pour une soif de ${sustNeeded}, vous avez soif!
La soif devrait vous faire ${perte} points d'endurance non récupérables, notez le cumul de côté et ajustez l'endurance`; La soif devrait vous faire ${perte} points d'endurance non récupérables, notez le cumul de côté et ajustez l'endurance`;
} }
await this.updateCompteurValue('sust', 0);
await this.updateCompteurValue('eau', 0); await this.update({ 'system.compteurs.sust.value': 0 });
await this.update({ 'system.compteurs.eau.value': 0 });
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
@@ -753,25 +754,25 @@ export class RdDActor extends RdDBaseActorSang {
updates[`system.compteurs.chance.value`] = to updates[`system.compteurs.chance.value`] = to
} }
} }
let selectedCarac = this.findCaracByName(caracName); let selectedCarac = this.findCaracByName(caracName)
const from = selectedCarac.value const from = selectedCarac.value
updates[`system.carac.${caracName}.value`] = to; updates[`system.carac.${caracName}.value`] = to
await this.update(updates, { noHook: true }); await this.update(updates, { noHook: true })
await ExperienceLog.add(this, XP_TOPIC.CARAC, from, to, caracName); await ExperienceLog.add(this, XP_TOPIC.CARAC, from, to, caracName)
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
async updateCaracXP(caracName, to) { async updateCaracXP(caracName, to) {
if (caracName == 'Taille') { if (caracName == 'Taille') {
return; return
} }
let selectedCarac = this.findCaracByName(caracName); let selectedCarac = this.findCaracByName(caracName);
if (!selectedCarac.derivee) { if (!selectedCarac.derivee) {
const from = Number(selectedCarac.xp); const from = Number(selectedCarac.xp)
await this.update({ [`system.carac.${caracName}.xp`]: to }); await this.update({ [`system.carac.${caracName}.xp`]: to })
await ExperienceLog.add(this, XP_TOPIC.XPCARAC, from, to, caracName); await ExperienceLog.add(this, XP_TOPIC.XPCARAC, from, to, caracName)
} }
this.checkCaracXP(caracName); this.checkCaracXP(caracName)
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
@@ -792,9 +793,9 @@ export class RdDActor extends RdDBaseActorSang {
} }
carac.xp = toXp; carac.xp = toXp;
carac.value = toValue; carac.value = toValue;
await this.update({ [`system.carac.${caracName}`]: carac }); await this.update({ [`system.carac.${caracName}`]: carac })
await ExperienceLog.add(this, XP_TOPIC.XPCARAC, fromXp, toXp, caracName); await ExperienceLog.add(this, XP_TOPIC.XPCARAC, fromXp, toXp, caracName)
await ExperienceLog.add(this, XP_TOPIC.CARAC, fromValue, toValue, caracName); await ExperienceLog.add(this, XP_TOPIC.CARAC, fromValue, toValue, caracName)
} }
} }
@@ -813,7 +814,7 @@ export class RdDActor extends RdDBaseActorSang {
await competence.update({ await competence.update({
"system.xp": toXp, "system.xp": toXp,
"system.niveau": toNiveau, "system.niveau": toNiveau,
}, { render: false }) })
await ExperienceLog.add(this, XP_TOPIC.XP, fromXp, toXp, competence.name); await ExperienceLog.add(this, XP_TOPIC.XP, fromXp, toXp, competence.name);
await ExperienceLog.add(this, XP_TOPIC.NIVEAU, fromNiveau, toNiveau, competence.name); await ExperienceLog.add(this, XP_TOPIC.NIVEAU, fromNiveau, toNiveau, competence.name);
} }
@@ -822,35 +823,35 @@ export class RdDActor extends RdDBaseActorSang {
async updateCompetenceStress(idOrName) { async updateCompetenceStress(idOrName) {
const competence = this.getCompetence(idOrName); const competence = this.getCompetence(idOrName);
if (!competence) { if (!competence) {
return; return
} }
const fromXp = competence.system.xp; const fromXp = competence.system.xp
const fromXpStress = this.system.compteurs.experience.value; const fromXpStress = this.system.compteurs.experience.value
const fromNiveau = Number(competence.system.niveau); const fromNiveau = Number(competence.system.niveau)
const xpSuivant = RdDItemCompetence.getCompetenceNextXp(fromNiveau); const xpSuivant = RdDItemCompetence.getCompetenceNextXp(fromNiveau)
const xpRequis = xpSuivant - fromXp; const xpRequis = xpSuivant - fromXp
if (fromXpStress <= 0 || fromNiveau >= competence.system.niveau_archetype) { if (fromXpStress <= 0 || fromNiveau >= competence.system.niveau_archetype) {
ui.notifications.info(`La compétence ne peut pas augmenter! ui.notifications.info(`La compétence ne peut pas augmenter!
stress disponible: ${fromXpStress} stress disponible: ${fromXpStress}
expérience requise: ${xpRequis} expérience requise: ${xpRequis}
niveau : ${fromNiveau} niveau : ${fromNiveau}
archétype : ${competence.system.niveau_archetype}`); archétype : ${competence.system.niveau_archetype}`)
return return
} }
const xpUtilise = Math.max(0, Math.min(fromXpStress, xpRequis)); const xpUtilise = Math.max(0, Math.min(fromXpStress, xpRequis))
const gainNiveau = (xpUtilise >= xpRequis || xpRequis <= 0) ? 1 : 0; const gainNiveau = (xpUtilise >= xpRequis || xpRequis <= 0) ? 1 : 0
const toNiveau = fromNiveau + gainNiveau; const toNiveau = fromNiveau + gainNiveau
const newXp = gainNiveau > 0 ? Math.max(fromXp - xpSuivant, 0) : (fromXp + xpUtilise); const newXp = gainNiveau > 0 ? Math.max(fromXp - xpSuivant, 0) : (fromXp + xpUtilise)
await competence.update({ await competence.update({
"system.xp": newXp, "system.xp": newXp,
"system.niveau": toNiveau, "system.niveau": toNiveau,
}, { render: false }) })
const toXpStress = Math.max(0, fromXpStress - xpUtilise); const toXpStress = Math.max(0, fromXpStress - xpUtilise)
await this.update({ "system.compteurs.experience.value": toXpStress }); await this.update({ "system.compteurs.experience.value": toXpStress })
await ExperienceLog.add(this, XP_TOPIC.TRANSFORM, fromXpStress, toXpStress, `Dépense stress`); await ExperienceLog.add(this, XP_TOPIC.TRANSFORM, fromXpStress, toXpStress, `Dépense stress`)
await ExperienceLog.add(this, XP_TOPIC.XP, fromXp, newXp, competence.name); await ExperienceLog.add(this, XP_TOPIC.XP, fromXp, newXp, competence.name)
await ExperienceLog.add(this, XP_TOPIC.NIVEAU, fromNiveau, toNiveau, competence.name); await ExperienceLog.add(this, XP_TOPIC.NIVEAU, fromNiveau, toNiveau, competence.name)
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
@@ -860,8 +861,8 @@ export class RdDActor extends RdDBaseActorSang {
const toNiveau = compValue ?? RdDItemCompetence.getNiveauBase(competence.system.categorie, competence.getCategories()); const toNiveau = compValue ?? RdDItemCompetence.getNiveauBase(competence.system.categorie, competence.getCategories());
this.notifyCompetencesTronc(competence, toNiveau); this.notifyCompetencesTronc(competence, toNiveau);
const fromNiveau = competence.system.niveau; const fromNiveau = competence.system.niveau;
await competence.update({ 'system.niveau': toNiveau }, { render: true }) await competence.update({ 'system.niveau': toNiveau })
await ExperienceLog.add(this, XP_TOPIC.NIVEAU, fromNiveau, toNiveau, competence.name, true); await ExperienceLog.add(this, XP_TOPIC.NIVEAU, fromNiveau, toNiveau, competence.name, true)
} }
} }
@@ -882,11 +883,13 @@ export class RdDActor extends RdDBaseActorSang {
async updateCompetenceXP(idOrName, toXp) { async updateCompetenceXP(idOrName, toXp) {
let competence = this.getCompetence(idOrName); let competence = this.getCompetence(idOrName);
if (competence) { if (competence) {
if (isNaN(toXp) || typeof (toXp) != 'number') toXp = 0; if (isNaN(toXp) || typeof (toXp) != 'number') {
const fromXp = competence.system.xp; toXp = 0
this.checkCompetenceXP(idOrName, toXp); }
await competence.update({ 'system.xp': toXp }, { render: false }) const fromXp = competence.system.xp
await ExperienceLog.add(this, XP_TOPIC.XP, fromXp, toXp, competence.name, true); this.checkCompetenceXP(idOrName, toXp)
await competence.update({ 'system.xp': toXp })
await ExperienceLog.add(this, XP_TOPIC.XP, fromXp, toXp, competence.name, true)
if (toXp > fromXp) { if (toXp > fromXp) {
RdDUtility.checkThanatosXP(competence) RdDUtility.checkThanatosXP(competence)
} }
@@ -897,10 +900,12 @@ export class RdDActor extends RdDBaseActorSang {
async updateCompetenceXPSort(idOrName, toXpSort) { async updateCompetenceXPSort(idOrName, toXpSort) {
let competence = this.getCompetence(idOrName); let competence = this.getCompetence(idOrName);
if (competence) { if (competence) {
if (isNaN(toXpSort) || typeof (toXpSort) != 'number') toXpSort = 0; if (isNaN(toXpSort) || typeof (toXpSort) != 'number') {
const fromXpSort = competence.system.xp_sort; toXpSort = 0
await competence.update({ 'system.xp_sort': toXpSort }, { render: false }) }
await ExperienceLog.add(this, XP_TOPIC.XPSORT, fromXpSort, toXpSort, competence.name, true); const fromXpSort = competence.system.xp_sort
await competence.update({ 'system.xp_sort': toXpSort })
await ExperienceLog.add(this, XP_TOPIC.XPSORT, fromXpSort, toXpSort, competence.name, true)
if (toXpSort > fromXpSort) { if (toXpSort > fromXpSort) {
RdDUtility.checkThanatosXP(competence) RdDUtility.checkThanatosXP(competence)
} }
@@ -917,25 +922,25 @@ export class RdDActor extends RdDBaseActorSang {
async deleteExperienceLog(from, count) { async deleteExperienceLog(from, count) {
if (from >= 0 && count > 0) { if (from >= 0 && count > 0) {
let expLog = foundry.utils.duplicate(this.system.experiencelog); let expLog = foundry.utils.duplicate(this.system.experiencelog)
expLog.splice(from, count); expLog.splice(from, count)
await this.update({ [`system.experiencelog`]: expLog }); await this.update({ [`system.experiencelog`]: expLog })
} }
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
async updateCompteurValue(fieldName, to) { async updateCompteurValue(fieldName, to) {
const from = this.system.compteurs[fieldName].value const from = this.system.compteurs[fieldName].value
await this.update({ [`system.compteurs.${fieldName}.value`]: to }); await this.update({ [`system.compteurs.${fieldName}.value`]: to })
await this.addStressExperienceLog(fieldName, from, to, fieldName, true); await this.addStressExperienceLog(fieldName, from, to, fieldName, true)
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
async addCompteurValue(fieldName, add, raison) { async addCompteurValue(fieldName, add, raison) {
let from = this.system.compteurs[fieldName].value; let from = this.system.compteurs[fieldName].value
const to = Number(from) + Number(add); const to = Number(from) + Number(add)
await this.update({ [`system.compteurs.${fieldName}.value`]: to }); await this.update({ [`system.compteurs.${fieldName}.value`]: to })
await this.addStressExperienceLog(fieldName, from, to, raison); await this.addStressExperienceLog(fieldName, from, to, raison)
} }
async addStressExperienceLog(topic, from, to, raison, manuel) { async addStressExperienceLog(topic, from, to, raison, manuel) {
@@ -948,35 +953,22 @@ export class RdDActor extends RdDBaseActorSang {
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
async distribuerStress(compteur, stress, motif) { async distribuerStress(compteur, valeur, motif) {
if (game.user.isGM && this.hasPlayerOwner) { if (game.user.isGM && this.hasPlayerOwner) {
switch (compteur) { switch (compteur) {
case 'stress': case 'experience': case 'stress': case 'experience':
await this.addCompteurValue(compteur, stress, motif); await this.addCompteurValue(compteur, valeur, motif);
const message = `${this.name} a reçu ${stress} points ${compteur == 'stress' ? "de stress" : "d'expérience"} (raison : ${motif})`; const message = `${this.name} a reçu ${valeur} points ${compteur == 'stress' ? "de stress" : "d'expérience"} (raison : ${motif})`;
ui.notifications.info(message); game.users.players.filter(player => this.testUserPermission(player, CONST.DOCUMENT_OWNERSHIP_LEVELS.OWNER))
game.users.players.filter(player => player.active && player.character?.id == this.id)
.forEach(player => ChatUtility.notifyUser(player.id, 'info', message)); .forEach(player => ChatUtility.notifyUser(player.id, 'info', message));
} }
} }
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
async updateAttributeValue(fieldName, fieldValue) { ethylisme() { return this.system.compteurs.ethylisme?.value ?? 1 }
await this.update({ [`system.attributs.${fieldName}.value`]: fieldValue }); malusEthylisme() { return Math.min(0, this.ethylisme()) }
} isAlcoolise() { return this.ethylisme() < 1 }
/* -------------------------------------------- */
ethylisme() {
return this.system.compteurs.ethylisme?.value ?? 1;
}
malusEthylisme() {
return Math.min(0, this.ethylisme())
}
isAlcoolise() {
return this.ethylisme() < 1
}
/* -------------------------------------------- */ /* -------------------------------------------- */
async actionRefoulement(item) { async actionRefoulement(item) {
@@ -997,15 +989,15 @@ export class RdDActor extends RdDBaseActorSang {
/* -------------------------------------------- */ /* -------------------------------------------- */
async ajouterRefoulement(value = 1, refouler) { async ajouterRefoulement(value = 1, refouler) {
let refoulement = this.system.reve.refoulement.value + value; let refoulement = this.system.reve.refoulement.value + value
const roll = new Roll("1d20"); const roll = new Roll("1d20")
await roll.evaluate(); await roll.evaluate()
await roll.toMessage({ flavor: `${this.name} refoule ${refouler} pour ${value} points de refoulement (total: ${refoulement})` }); await roll.toMessage({ flavor: `${this.name} refoule ${refouler} pour ${value} points de refoulement (total: ${refoulement})` })
if (roll.total <= refoulement) { if (roll.total <= refoulement) {
refoulement = 0; refoulement = 0
await this.ajouterSouffle({ chat: true }); await this.ajouterSouffle({ chat: true })
} }
await this.update({ "system.reve.refoulement.value": refoulement }); await this.update({ "system.reve.refoulement.value": refoulement })
return roll; return roll;
} }
@@ -1013,14 +1005,14 @@ export class RdDActor extends RdDBaseActorSang {
async ajouterSouffle(options = { chat: false }) { async ajouterSouffle(options = { chat: false }) {
let souffle = await RdDRollTables.getSouffle() let souffle = await RdDRollTables.getSouffle()
//souffle.id = undefined; //TBC //souffle.id = undefined; //TBC
await this.createEmbeddedDocuments('Item', [souffle]); await this.createEmbeddedDocuments('Item', [souffle])
if (options.chat) { if (options.chat) {
ChatMessage.create({ ChatMessage.create({
whisper: ChatUtility.getOwners(this), whisper: ChatUtility.getOwners(this),
content: this.name + " subit un Souffle de Dragon : " + souffle.name content: this.name + " subit un Souffle de Dragon : " + souffle.name
}); })
} }
return souffle; return souffle
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
@@ -1028,7 +1020,7 @@ export class RdDActor extends RdDBaseActorSang {
let queue; let queue;
if (this.system.reve.reve.thanatosused) { if (this.system.reve.reve.thanatosused) {
queue = await RdDRollTables.getOmbre(); queue = await RdDRollTables.getOmbre();
await this.update({ "system.reve.reve.thanatosused": false }); await this.update({ "system.reve.reve.thanatosused": false })
} }
else { else {
queue = await RdDRollTables.getQueue(); queue = await RdDRollTables.getQueue();
@@ -1038,7 +1030,7 @@ export class RdDActor extends RdDBaseActorSang {
ChatMessage.create({ ChatMessage.create({
whisper: ChatUtility.getOwners(this), whisper: ChatUtility.getOwners(this),
content: this.name + " subit une Queue de Dragon : " + queue.name content: this.name + " subit une Queue de Dragon : " + queue.name
}); })
} }
return queue; return queue;
} }
@@ -1161,26 +1153,17 @@ export class RdDActor extends RdDBaseActorSang {
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
async regainPointDeSeuil() { async recuperationSeuilReve() {
const seuil = Misc.toInt(this.system.reve.seuil.value); const value = Misc.toInt(this.system.reve.seuil.value);
const seuilMax = Misc.toInt(this.system.carac.reve.value) const max = Misc.toInt(this.system.carac.reve.value)
+ 2 * EffetsDraconiques.countAugmentationSeuil(this); + 2 * EffetsDraconiques.countAugmentationSeuil(this);
if (seuil < seuilMax) { if (value < max) {
await this.setPointsDeSeuil(Math.min(seuil + 1, seuilMax)); const nouveauSeuil = Math.min(value + 1, max);
await this.update({ "system.reve.seuil.value": nouveauSeuil });
} }
} }
/* -------------------------------------------- */
async setPointsDeSeuil(seuil) {
await this.update({ "system.reve.seuil.value": seuil });
}
/* -------------------------------------------- */
async setPointsDeChance(chance) {
await this.updateCompteurValue("chance", chance);
}
async jetEndurance(resteEndurance = undefined) { async jetEndurance(resteEndurance = undefined) {
const result = super.jetEndurance(resteEndurance); const result = super.jetEndurance(resteEndurance);
if (result.jetEndurance == 1) { if (result.jetEndurance == 1) {
@@ -1191,13 +1174,9 @@ export class RdDActor extends RdDBaseActorSang {
/* -------------------------------------------- */ /* -------------------------------------------- */
getSConst() { return RdDCarac.calculSConst(this.getConstitution()) } getSConst() { return RdDCarac.calculSConst(this.getConstitution()) }
async ajoutXpConstitution(xp) {
await this.update({ "system.carac.constitution.xp": Misc.toInt(this.system.carac.constitution.xp) + xp });
}
async _gainXpConstitutionJetEndurance() { async _gainXpConstitutionJetEndurance() {
await this.ajoutXpConstitution(1); // +1 XP ! await this.updateCaracXP('constitution', Misc.toInt(this.system.carac.constitution.xp) + 1)
return `${this.name} a obtenu 1 sur son Jet d'Endurance et a gagné 1 point d'Expérience en Constitution. Ce point d'XP a été ajouté automatiquement.`; return `${this.name} a obtenu 1 sur son Jet d'Endurance et a gagné 1 point d'Expérience en Constitution. Ce point d'XP a été ajouté automatiquement.`;
} }
@@ -1234,27 +1213,25 @@ export class RdDActor extends RdDBaseActorSang {
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
async moralIncDec(ajustementMoral, bonmoment = "") { async moralIncDec(ajustement, bonmoment = "") {
if (ajustementMoral != 0) { let moral = parseInt(this.system.compteurs.moral.value)
if (ajustementMoral > 0 && bonmoment != "" && bonmoment != undefined) { if (ajustement != 0) {
const bonmoments = [...this.system.compteurs.bonmoments, bonmoment] if (ajustement > 0 && bonmoment != "" && bonmoment != undefined) {
await this.update({ 'system.compteurs.bonmoments': bonmoments }, { render: false }) await this.update({ 'system.compteurs.bonmoments': [...this.system.compteurs.bonmoments, bonmoment] })
} }
const startMoral = parseInt(this.system.compteurs.moral.value) const moralTheorique = moral + ajustement
const moralTheorique = startMoral + ajustementMoral
if (moralTheorique > 3) { // exaltation if (moralTheorique > 3) { // exaltation
const ajoutExaltation = moralTheorique - 3 const exaltation = parseInt(this.system.compteurs.exaltation.value) + moralTheorique - 3
const exaltation = parseInt(this.system.compteurs.exaltation.value) + ajoutExaltation await this.update({ 'system.compteurs.exaltation.value': exaltation })
await this.updateCompteurValue('exaltation', exaltation)
} }
if (moralTheorique < -3) { // dissolution if (moralTheorique < -3) { // dissolution
const ajoutDissolution = -3 - moralTheorique const dissolution = parseInt(this.system.compteurs.dissolution.value) - 3 - moralTheorique
const dissolution = parseInt(this.system.compteurs.dissolution.value) + ajoutDissolution await this.update({ 'system.compteurs.dissolution.value': dissolution })
await this.updateCompteurValue('dissolution', dissolution)
} }
await this.updateCompteurValue('moral', Math.max(-3, Math.min(moralTheorique, 3))); moral = Math.max(-3, Math.min(moralTheorique, 3));
await this.update({ 'system.compteurs.moral.value': moral })
} }
return this.system.compteurs.moral.value; return moral
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
@@ -1386,7 +1363,7 @@ export class RdDActor extends RdDBaseActorSang {
async manger(item, doses, options = { diminuerQuantite: true }) { async manger(item, doses, options = { diminuerQuantite: true }) {
const sust = item.system.sust const sust = item.system.sust
if (sust > 0) { if (sust > 0) {
await this.updateCompteurValue('sust', RdDActor.$calculNewSust(this.system.compteurs.sust.value, sust, doses)); await this.update({ 'system.compteurs.sust.value': RdDActor.$calculNewSust(this.system.compteurs.sust.value, sust, doses) })
} }
await item.diminuerQuantite(doses, options); await item.diminuerQuantite(doses, options);
} }
@@ -1394,9 +1371,9 @@ export class RdDActor extends RdDBaseActorSang {
/* -------------------------------------------- */ /* -------------------------------------------- */
async boire(item, doses, options = { diminuerQuantite: true }) { async boire(item, doses, options = { diminuerQuantite: true }) {
const desaltere = item.system.desaltere; const eau = item.system.desaltere
if (desaltere > 0) { if (eau > 0) {
await this.updateCompteurValue('eau', RdDActor.$calculNewSust(this.system.compteurs.eau.value, desaltere, doses)); await this.update({ 'system.compteurs.eau.value': RdDActor.$calculNewSust(this.system.compteurs.eau.value, eau, doses) })
} }
if (item.isAlcool()) { if (item.isAlcool()) {
for (let i = 0; i < doses; i++) { for (let i = 0; i < doses; i++) {
@@ -1523,13 +1500,12 @@ export class RdDActor extends RdDBaseActorSang {
const toStress = Math.max(fromStress - stressRollData.perte - 1, 0); const toStress = Math.max(fromStress - stressRollData.perte - 1, 0);
const fromXpSress = Number(this.system.compteurs.experience.value); const fromXpSress = Number(this.system.compteurs.experience.value);
const toXpStress = fromXpSress + Number(stressRollData.xp); const toXpStress = fromXpSress + Number(stressRollData.xp);
const updates = { await this.update({
"system.compteurs.stress.value": toStress, "system.compteurs.stress.value": toStress,
"system.compteurs.experience.value": toXpStress, "system.compteurs.experience.value": toXpStress,
"system.compteurs.dissolution.value": dissolution - perteDissolution, "system.compteurs.dissolution.value": dissolution - perteDissolution,
"system.compteurs.exaltation.value": 0 "system.compteurs.exaltation.value": 0
} })
await this.update(updates);
await ExperienceLog.add(this, XP_TOPIC.STRESS, fromStress, toStress, 'Transformation') await ExperienceLog.add(this, XP_TOPIC.STRESS, fromStress, toStress, 'Transformation')
await ExperienceLog.add(this, XP_TOPIC.TRANSFORM, fromXpSress, toXpStress, 'Transformation') await ExperienceLog.add(this, XP_TOPIC.TRANSFORM, fromXpSress, toXpStress, 'Transformation')
} }
@@ -1595,34 +1571,7 @@ export class RdDActor extends RdDBaseActorSang {
/* -------------------------------------------- */ /* -------------------------------------------- */
async checkCompetenceXP(compName, newXP, display = true) { async checkCompetenceXP(compName, newXP, display = true) {
let compData = this.getCompetence(compName); return this.getCompetence(compName)?.checkCompetenceXP( newXP, display)
if (compData && newXP && newXP == compData.system.xp) { // Si édition, mais sans changement XP
return;
}
newXP = (newXP) ? newXP : compData.system.xp;
if (compData && newXP > 0) {
let xpNeeded = RdDItemCompetence.getCompetenceNextXp(compData.system.niveau + 1);
if (newXP >= xpNeeded) {
let newCompData = foundry.utils.duplicate(compData);
newCompData.system.niveau += 1;
newCompData.system.xp = newXP;
let checkXp = {
alias: this.getAlias(),
competence: newCompData.name,
niveau: newCompData.system.niveau,
xp: newCompData.system.xp,
archetype: newCompData.system.niveau_archetype,
archetypeWarning: newCompData.system.niveau > compData.system.niveau_archetype
}
if (display) {
ChatMessage.create({
whisper: ChatUtility.getOwners(this),
content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-actor-competence-xp.hbs`, checkXp)
});
}
return checkXp;
}
}
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
@@ -1792,30 +1741,30 @@ export class RdDActor extends RdDBaseActorSang {
/* -------------------------------------------- */ /* -------------------------------------------- */
async _rollUnSortResult(rollData) { async _rollUnSortResult(rollData) {
let rolled = rollData.rolled; let rolled = rollData.rolled
let selectedSort = rollData.selectedSort; let selectedSort = rollData.selectedSort
rollData.isSortReserve = rollData.mettreEnReserve && !selectedSort.system.isrituel; rollData.isSortReserve = rollData.mettreEnReserve && !selectedSort.system.isrituel
rollData.show = {} rollData.show = {}
rollData.depenseReve = Number(selectedSort.system.ptreve_reel); rollData.depenseReve = Number(selectedSort.system.ptreve_reel)
if (rollData.competence.name.includes('Thanatos')) { // Si Thanatos if (rollData.competence.name.includes('Thanatos')) { // Si Thanatos
await this.update({ "system.reve.reve.thanatosused": true }); await this.update({ "system.reve.reve.thanatosused": true })
} }
let reveActuel = parseInt(this.system.reve.reve.value) let reveActuel = parseInt(this.system.reve.reve.value)
if (rolled.isSuccess) { // Réussite du sort ! if (rolled.isSuccess) { // Réussite du sort !
if (rolled.isPart) { if (rolled.isPart) {
rollData.depenseReve = Math.max(Math.floor(rollData.depenseReve / 2), 1); rollData.depenseReve = Math.max(Math.floor(rollData.depenseReve / 2), 1)
} }
if (rollData.isSortReserve) { if (rollData.isSortReserve) {
rollData.depenseReve++; rollData.depenseReve++
} }
if (reveActuel > rollData.depenseReve) { if (reveActuel > rollData.depenseReve) {
// Incrémenter/gére le bonus de case // Incrémenter/gére le bonus de case
RdDItemSort.incrementBonusCase(this, selectedSort, rollData.tmr.coord); RdDItemSort.incrementBonusCase(this, selectedSort, rollData.tmr.coord)
if (rollData.isSortReserve) { if (rollData.isSortReserve) {
await this.sortMisEnReserve(selectedSort, rollData.competence, rollData.tmr.coord, Number(selectedSort.system.ptreve_reel)); await this.sortMisEnReserve(selectedSort, rollData.competence, rollData.tmr.coord, Number(selectedSort.system.ptreve_reel))
} }
else { else {
console.log('lancement de sort', rollData.selectedSort) console.log('lancement de sort', rollData.selectedSort)
@@ -1840,16 +1789,15 @@ export class RdDActor extends RdDBaseActorSang {
} }
} }
reveActuel = Math.max(reveActuel - rollData.depenseReve, 0); reveActuel = Math.max(reveActuel - rollData.depenseReve, 0)
await this.update({ "system.reve.reve.value": reveActuel }); await this.update({ "system.reve.reve.value": reveActuel })
await RdDRollResult.displayRollData(rollData, this, 'chat-resultat-sort.hbs')
await RdDRollResult.displayRollData(rollData, this, 'chat-resultat-sort.hbs');
if (reveActuel == 0) { // 0 points de reve if (reveActuel == 0) { // 0 points de reve
ChatMessage.create({ content: this.name + " est réduit à 0 Points de Rêve, et tombe endormi !" }); ChatMessage.create({ content: this.name + " est réduit à 0 Points de Rêve, et tombe endormi !" })
} }
if (!rollData.isSortReserve || !rolled.isSuccess) { if (!rollData.isSortReserve || !rolled.isSuccess) {
this.tmrApp?.close(); this.tmrApp?.close()
} }
} }
@@ -2210,12 +2158,11 @@ export class RdDActor extends RdDBaseActorSang {
let destinee = this.system.compteurs.destinee?.value ?? 0; let destinee = this.system.compteurs.destinee?.value ?? 0;
if (destinee > 0) { if (destinee > 0) {
ChatMessage.create({ content: `<span class="rdd-roll-part">${this.name} a fait appel à la Destinée !</span>` }); ChatMessage.create({ content: `<span class="rdd-roll-part">${this.name} a fait appel à la Destinée !</span>` });
destinee--; await this.update({ 'system.compteurs.destinee.value ': destinee - 1 })
await this.updateCompteurValue("destinee", destinee); onSuccess()
onSuccess();
} }
else { else {
onEchec(); onEchec()
} }
} }
@@ -2276,7 +2223,7 @@ export class RdDActor extends RdDBaseActorSang {
const from = Number(xpData.competence.system.xp); const from = Number(xpData.competence.system.xp);
const to = from + xpData.xpCompetence; const to = from + xpData.xpCompetence;
await this.updateEmbeddedDocuments('Item', [{ _id: xpData.competence._id, 'system.xp': to }]); await this.updateEmbeddedDocuments('Item', [{ _id: xpData.competence._id, 'system.xp': to }]);
xpData.checkComp = await this.checkCompetenceXP(xpData.competence.name, undefined, false); xpData.checkComp = await this.checkCompetenceXP(xpData.competence.name, undefined, false)
await ExperienceLog.add(this, XP_TOPIC.XP, from, to, xpData.competence.name); await ExperienceLog.add(this, XP_TOPIC.XP, from, to, xpData.competence.name);
return [xpData] return [xpData]
} }
@@ -2461,10 +2408,13 @@ export class RdDActor extends RdDBaseActorSang {
async quitterTMR(message, viewOnly, cumulFatigue) { async quitterTMR(message, viewOnly, cumulFatigue) {
if (this.tmrApp) { if (this.tmrApp) {
this.tmrApp = undefined this.tmrApp = undefined
const appliquerFatigue = ReglesOptionnelles.isUsing("appliquer-fatigue"); if (ReglesOptionnelles.isUsing("appliquer-fatigue")) {
await this.santeIncDec( await this.santeIncDec("fatigue", cumulFatigue)
appliquerFatigue ? "fatigue" : "endurance", }
(appliquerFatigue ? 1 : -1) * cumulFatigue) else {
await this.santeIncDec("endurance", - cumulFatigue)
}
if (!viewOnly) { if (!viewOnly) {
await this.supprimerSignesDraconiques(it => it.system.ephemere && it.system.duree == '1 round', { render: false }) await this.supprimerSignesDraconiques(it => it.system.ephemere && it.system.duree == '1 round', { render: false })
await this.setEffect(STATUSES.StatusDemiReve, false) await this.setEffect(STATUSES.StatusDemiReve, false)
@@ -2527,10 +2477,10 @@ export class RdDActor extends RdDBaseActorSang {
async equiperObjet(item) { async equiperObjet(item) {
if (item?.isEquipable()) { if (item?.isEquipable()) {
const isEquipe = !item.system.equipe; const isEquipe = !item.system.equipe;
await item.update({ "system.equipe": isEquipe }); await item.update({ "system.equipe": isEquipe })
this.computeEncTotal() this.computeEncTotal()
if (isEquipe) if (isEquipe)
this.verifierForceMin(item); this.verifierForceMin(item)
} }
} }
@@ -2673,10 +2623,10 @@ export class RdDActor extends RdDBaseActorSang {
async setPointsCoeur(subActorId, coeurs, options = { immediat: false }) { async setPointsCoeur(subActorId, coeurs, options = { immediat: false }) {
const newSuivants = foundry.utils.duplicate(this.system.subacteurs.suivants) const newSuivants = foundry.utils.duplicate(this.system.subacteurs.suivants)
const amoureux = newSuivants.find(it => it.id == subActorId); const amoureux = newSuivants.find(it => it.id == subActorId)
if (amoureux) { if (amoureux) {
amoureux[options.immediat ? 'coeur' : 'prochainCoeur'] = coeurs amoureux[options.immediat ? 'coeur' : 'prochainCoeur'] = coeurs
await this.update({ 'system.subacteurs.suivants': newSuivants }); await this.update({ 'system.subacteurs.suivants': newSuivants })
} }
} }
@@ -2730,9 +2680,9 @@ export class RdDActor extends RdDBaseActorSang {
let alreadyPresent = dataArray.find(attached => attached.id == subActor.id); let alreadyPresent = dataArray.find(attached => attached.id == subActor.id);
if (!alreadyPresent) { if (!alreadyPresent) {
let newArray = [...dataArray, subActor] let newArray = [...dataArray, subActor]
await this.update({ [dataPath]: newArray }); await this.update({ [dataPath]: newArray })
} else { } else {
ui.notifications.warn(dataName + " est déja attaché à " + this.name); ui.notifications.warn(dataName + " est déja attaché à " + this.name)
} }
} }
@@ -2754,18 +2704,19 @@ export class RdDActor extends RdDBaseActorSang {
async deleteSubActeur(actorId) { async deleteSubActeur(actorId) {
['vehicules', 'suivants', 'montures'].forEach(async type => { ['vehicules', 'suivants', 'montures'].forEach(async type => {
const subList = this.system.subacteurs[type]; const subList = this.system.subacteurs[type]
if (subList.find(it => it.id == actorId)) { if (subList.find(it => it.id == actorId)) {
let newList = subList.filter(it => it.id != actorId) let newList = subList.filter(it => it.id != actorId)
await this.update({ [`system.subacteurs.${type}`]: newList }, { renderSheet: false }); await this.update({ [`system.subacteurs.${type}`]: newList }, { render: false })
} }
}) })
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
async buildPotionGuerisonList(pointsGuerison) { async buildPotionGuerisonList(pointsGuerison) {
const pointsGuerisonInitial = pointsGuerison; const pointsGuerisonInitial = pointsGuerison
const blessures = this.filterItems(it => it.system.gravite > 0, 'blessure').sort(Misc.descending(it => it.system.gravite)) const blessures = this.filterItems(it => it.system.gravite > 0, 'blessure')
.sort(Misc.descending(it => it.system.gravite))
const ids = [] const ids = []
const guerisonData = { list: [], pointsConsommes: 0 } const guerisonData = { list: [], pointsConsommes: 0 }
for (let blessure of blessures) { for (let blessure of blessures) {
@@ -2776,14 +2727,14 @@ export class RdDActor extends RdDBaseActorSang {
} }
} }
if (ids.length > 0) { if (ids.length > 0) {
await this.supprimerBlessures(it => ids.includes(it.id), { render: blessures.length != ids.length }) await this.supprimerBlessures(it => ids.includes(it.id))
} }
if (blessures.length == ids.length) { if (blessures.length == ids.length) {
let pvManquants = this.system.sante.vie.max - this.system.sante.vie.value; let pvManquants = this.system.sante.vie.max - this.system.sante.vie.value;
let pvSoignees = Math.min(pvManquants, Math.floor(pointsGuerison / 2)); let pvSoignees = Math.min(pvManquants, Math.floor(pointsGuerison / 2));
pointsGuerison -= pvSoignees * 2; pointsGuerison -= pvSoignees * 2;
guerisonData.list.push(pvSoignees + " Points de Vie soignés"); guerisonData.list.push(pvSoignees + " Points de Vie soignés");
await this.santeIncDec('vie', +pvSoignees, { render: true }) await this.santeIncDec('vie', +pvSoignees)
} }
guerisonData.pointsConsommes = pointsGuerisonInitial - pointsGuerison; guerisonData.pointsConsommes = pointsGuerisonInitial - pointsGuerison;
return guerisonData; return guerisonData;
@@ -2913,12 +2864,6 @@ export class RdDActor extends RdDBaseActorSang {
await this.diminuerQuantiteObjet(potion.id, 1, { supprimerSiZero: potion.supprimer }); await this.diminuerQuantiteObjet(potion.id, 1, { supprimerSiZero: potion.supprimer });
} }
/* -------------------------------------------- */
async onPreUpdateItem(item, change, options, id) {
if (item.isCompetencePersonnage() && item.system.defaut_carac && item.system.xp) {
await this.checkCompetenceXP(item.name, item.system.xp);
}
}
/* -------------------------------------------- */ /* -------------------------------------------- */
async onCreateItem(item, options, id) { async onCreateItem(item, options, id) {
switch (item.type) { switch (item.type) {
+13 -13
View File
@@ -156,9 +156,9 @@ export class RdDBaseActorReve extends RdDBaseActor {
async remiseANeuf() { } async remiseANeuf() { }
async ajoutExperience(rollData, hideChatMessage = 'show') { } async ajoutExperience(rollData, hideChatMessage = 'show') { }
computeResumeBlessure() { } computeResumeBlessure() { return []}
countBlessures(filter = it => !it.isContusion()) { return 0 } countBlessures(filter = it => !it.isContusion()) { return 0 }
async santeIncDec(name, inc, options = {}) { } async santeIncDec(name, inc, isCritique) { }
async finDeRound(options = { terminer: false }) { async finDeRound(options = { terminer: false }) {
await this.finDeRoundSuppressionEffetsTermines(options) await this.finDeRoundSuppressionEffetsTermines(options)
@@ -255,15 +255,15 @@ export class RdDBaseActorReve extends RdDBaseActor {
if (competence) { if (competence) {
function getFieldPath(fieldName) { function getFieldPath(fieldName) {
switch (fieldName) { switch (fieldName) {
case "niveau": return 'system.niveau'; case "niveau": return 'system.niveau'
case "dommages": return 'system.dommages'; case "dommages": return 'system.dommages'
case "carac_value": return 'system.carac_value'; case "carac_value": return 'system.carac_value'
} }
return undefined return undefined
} }
const path = getFieldPath(fieldName); const path = getFieldPath(fieldName)
if (path) { if (path) {
await competence.update({ [path]: value }); await competence.update({ [path]: value })
} }
} }
} }
@@ -665,12 +665,12 @@ export class RdDBaseActorReve extends RdDBaseActor {
show: show ?? {} show: show ?? {}
}, { overwrite: false }); }, { overwrite: false });
await ChatUtility.createChatWithRollMode({ await ChatMessage.create(ChatUtility.adaptVisibility(
roll: encaissement.roll, {
content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-resultat-encaissement.hbs', encaissement) roll: encaissement.roll,
}, content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-resultat-encaissement.hbs', encaissement)
this },
) { actor: this }))
if (!encaissement.hasPlayerOwner && encaissement.endurance != 0) { if (!encaissement.hasPlayerOwner && encaissement.endurance != 0) {
encaissement = foundry.utils.duplicate(encaissement) encaissement = foundry.utils.duplicate(encaissement)
+51 -63
View File
@@ -17,6 +17,14 @@ import { CARACS } from "../rdd-carac.js";
*/ */
export class RdDBaseActorSang extends RdDBaseActorReve { export class RdDBaseActorSang extends RdDBaseActorReve {
async _preUpdate(changed, options, user) {
const updatedEndurance = changed?.system?.sante?.endurance
if (updatedEndurance && options.diff) {
await this.setEffect(STATUSES.StatusUnconscious, updatedEndurance.value == 0)
}
}
prepareActorData() { prepareActorData() {
this.system.sante.vie.max = Math.ceil((this.getTaille() + this.getConstitution()) / 2) this.system.sante.vie.max = Math.ceil((this.getTaille() + this.getConstitution()) / 2)
this.system.sante.vie.value = Math.min(this.system.sante.vie.value, this.system.sante.vie.max) this.system.sante.vie.value = Math.min(this.system.sante.vie.value, this.system.sante.vie.max)
@@ -71,36 +79,25 @@ export class RdDBaseActorSang extends RdDBaseActorReve {
return Math.min(0, Math.floor(this.getEncombrementMax() - this.encTotal)); return Math.min(0, Math.floor(this.getEncombrementMax() - this.encTotal));
} }
countBlessures(filter) { return this.itemTypes[ITEM_TYPES.blessure].filter(filter).length }
isDead() { return this.system.sante.vie.value < -this.getSConst() } isDead() { return this.system.sante.vie.value < -this.getSConst() }
nbBlessuresLegeres() { return this.itemTypes[ITEM_TYPES.blessure].filter(it => it.isLegere()).length }
nbBlessuresGraves() { return this.itemTypes[ITEM_TYPES.blessure].filter(it => it.isGrave()).length }
nbBlessuresCritiques() { return this.itemTypes[ITEM_TYPES.blessure].filter(it => it.isCritique()).length }
/* -------------------------------------------- */ /* -------------------------------------------- */
computeResumeBlessure() { computeResumeBlessure() {
const nbLegeres = this.nbBlessuresLegeres() function descBlessure(count, name) {
const nbGraves = this.nbBlessuresGraves() return count > 0 ? [`${count} ${name}${count > 1 ? "s" : ""}`] : []
const nbCritiques = this.nbBlessuresCritiques() }
if (nbLegeres + nbGraves + nbCritiques == 0) { const nbContusions = this.countBlessures(it => it.isContusion())
return "Aucune blessure"; const nbLegeres = this.countBlessures(it => it.isLegere())
} const nbGraves = this.countBlessures(it => it.isGrave())
let resume = "Blessures:"; const nbCritiques = this.countBlessures(it => it.isCritique())
if (nbLegeres > 0) { return [
resume += " " + nbLegeres + " légère" + (nbLegeres > 1 ? "s" : ""); ... (nbCritiques > 0 ? ['une CRITIQUE !'] : []),
} ...descBlessure(nbGraves, 'grave'),
if (nbGraves > 0) { ...descBlessure(nbLegeres, 'légère'),
if (nbLegeres > 0) ...descBlessure(nbContusions, 'contusion'),
resume += ","; ]
resume += " " + nbGraves + " grave" + (nbGraves > 1 ? "s" : "");
}
if (nbCritiques > 0) {
if (nbGraves > 0 || nbLegeres > 0)
resume += ",";
resume += " une CRITIQUE !";
}
return resume;
} }
blessuresASoigner() { return [] } blessuresASoigner() { return [] }
@@ -125,10 +122,10 @@ export class RdDBaseActorSang extends RdDBaseActorReve {
blessure.system.vie = blessure.system.vie blessure.system.vie = blessure.system.vie
const rollPerteEndurance = new Roll(blessure.system.endurance) const rollPerteEndurance = new Roll(blessure.system.endurance)
await rollPerteEndurance.evaluate() await rollPerteEndurance.evaluate()
blessure.system.endurance =rollPerteEndurance.total blessure.system.endurance = rollPerteEndurance.total
} }
const isCritique = blessure.system.gravite >= 6; const isCritique = blessure.system.gravite >= 6;
if (isCritique){ if (isCritique) {
blessure.system.endurance = this.getEnduranceActuelle() blessure.system.endurance = this.getEnduranceActuelle()
} }
// Will update the result table // Will update the result table
@@ -137,8 +134,8 @@ export class RdDBaseActorSang extends RdDBaseActorReve {
encaissement.mort = "à seconde blessure critique" encaissement.mort = "à seconde blessure critique"
} }
const perteVie = await this.santeIncDec("vie", -encaissement.vie, { render: false }) const perteVie = await this.santeIncDec("vie", -encaissement.vie)
const perteEndurance = await this.santeIncDec("endurance", -encaissement.endurance, { isCritique, render: false }) const perteEndurance = await this.santeIncDec("endurance", -encaissement.endurance, isCritique)
await this.createEmbeddedDocuments('Item', [blessure]) await this.createEmbeddedDocuments('Item', [blessure])
foundry.utils.mergeObject(encaissement, { foundry.utils.mergeObject(encaissement, {
@@ -152,7 +149,7 @@ export class RdDBaseActorSang extends RdDBaseActorReve {
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
async santeIncDec(name, inc, options = {}) { async santeIncDec(name, inc, isCritique = false) {
if (name == 'fatigue' && !ReglesOptionnelles.isUsing("appliquer-fatigue")) { if (name == 'fatigue' && !ReglesOptionnelles.isUsing("appliquer-fatigue")) {
return return
} }
@@ -164,16 +161,16 @@ export class RdDBaseActorSang extends RdDBaseActorReve {
const result = { sonne: false } const result = { sonne: false }
let perteEndurance = 0 let perteEndurance = 0
let minValue = name == "vie" ? -this.getSConst() - 1 : 0; let minValue = name == "vie" ? -this.getSConst() - 1 : 0;
result.newValue = Math.max(minValue, Math.min(compteur.value + inc, compteur.max)); result.newValue = Math.max(minValue, Math.min(compteur.value + inc, compteur.max));
let fatigue = 0; let fatigue = 0;
if (name == "endurance" && result.newValue == 0 && inc < 0 && !options.isCritique) { // perte endurance et endurance devient 0 (sauf critique) -> -1 vie
sante.vie.value--;
result.perteVie = true;
}
foundry.utils.mergeObject(options, { render: true }, { overwrite: false })
if (name == "endurance") { if (name == "endurance") {
if (result.newValue == 0 && inc < 0 && !isCritique) {
// perte endurance et endurance devient 0 (sauf critique) -> -1 vie
sante.vie.value--
result.perteVie = true
}
result.newValue = Math.max(0, result.newValue); result.newValue = Math.max(0, result.newValue);
if (inc > 0) { // le max d'endurance s'applique seulement à la récupération if (inc > 0) { // le max d'endurance s'applique seulement à la récupération
result.newValue = Math.min(result.newValue, this._computeEnduranceMax()) result.newValue = Math.min(result.newValue, this._computeEnduranceMax())
@@ -189,17 +186,17 @@ export class RdDBaseActorSang extends RdDBaseActorReve {
if (ReglesOptionnelles.isUsing("appliquer-fatigue") && sante.fatigue && fatigue > 0) { if (ReglesOptionnelles.isUsing("appliquer-fatigue") && sante.fatigue && fatigue > 0) {
sante.fatigue.value = Math.max(sante.fatigue.value + fatigue, this.getFatigueMin()); sante.fatigue.value = Math.max(sante.fatigue.value + fatigue, this.getFatigueMin());
} }
await this.update({ "system.sante": sante }, options) await this.update({ "system.sante": sante })
if (perteEndurance > 1) { if (perteEndurance > 1) {
// Peut-être sonné si 2 points d'endurance perdus d'un coup // Peut-être sonné si 2 points d'endurance perdus d'un coup
foundry.utils.mergeObject(result, await this.jetEndurance(result.newValue, options)); foundry.utils.mergeObject(result, await this.jetEndurance(result.newValue));
} else if (name == "endurance" && inc > 0) { } else if (name == "endurance" && inc > 0) {
await this.setSonne(false, options) await this.setSonne(false)
} }
if (this.isDead()) { if (this.isDead()) {
await this.setEffect(STATUSES.StatusComma, true, options) await this.setEffect(STATUSES.StatusComma, true)
} }
return result return result
} }
@@ -281,14 +278,6 @@ export class RdDBaseActorSang extends RdDBaseActorReve {
return Math.max(0, Math.min(maxEndVie, maxEndGraves, maxEndCritiques)); return Math.max(0, Math.min(maxEndVie, maxEndGraves, maxEndCritiques));
} }
async onUpdateActor(update, options, actorId) {
const updatedEndurance = update?.system?.sante?.endurance
if (updatedEndurance && options.diff) {
await this.setEffect(STATUSES.StatusUnconscious, updatedEndurance.value == 0)
}
await super.onUpdateActor(update, options, actorId)
}
async onCreateItem(item, options, id) { async onCreateItem(item, options, id) {
await this.changeItemEffects(item) await this.changeItemEffects(item)
await super.onCreateItem(item, options, id) await super.onCreateItem(item, options, id)
@@ -307,12 +296,12 @@ export class RdDBaseActorSang extends RdDBaseActorReve {
async changeItemEffects(item) { async changeItemEffects(item) {
switch (item.type) { switch (item.type) {
case ITEM_TYPES.blessure: case ITEM_TYPES.blessure:
await this.changeStateBleeding(); await this.changeStateBleeding()
break; break;
case ITEM_TYPES.maladie: case ITEM_TYPES.maladie:
case ITEM_TYPES.poison: case ITEM_TYPES.poison:
await this.changeStateMalade(); await this.changeStateMalade()
break; break
} }
} }
@@ -349,10 +338,10 @@ export class RdDBaseActorSang extends RdDBaseActorReve {
} }
} }
async supprimerBlessures(filterToDelete, options = { render: true}) { async supprimerBlessures(filterToDelete) {
const toDelete = this.filterItems(filterToDelete, ITEM_TYPES.blessure) const toDelete = this.filterItems(filterToDelete, ITEM_TYPES.blessure)
.map(it => it.id) .map(it => it.id)
await this.deleteEmbeddedDocuments('Item', toDelete, options) await this.deleteEmbeddedDocuments('Item', toDelete)
} }
countBlessures(filter = it => !it.isContusion()) { countBlessures(filter = it => !it.isContusion()) {
@@ -369,12 +358,11 @@ export class RdDBaseActorSang extends RdDBaseActorReve {
return return
} }
const jetDeVie = await RdDDice.roll("1d20"); const jetDeVie = await RdDDice.roll("1d20");
const sConst = this.getSConst(); const sConst = this.getSConst();
const vie = this.system.sante.vie.value; const vie = this.system.sante.vie.value;
const isCritique = this.nbBlessuresCritiques() > 0; const isCritique = this.countBlessures(it => it.isCritique()) > 0
const isGrave = this.nbBlessuresGraves(); const isGrave = this.countBlessures(it => it.isGrave())
const isEchecTotal = jetDeVie.total == 20; const isEchecTotal = jetDeVie.total == 20
const isSuccess = jetDeVie.total == 1 || jetDeVie.total <= vie; const isSuccess = jetDeVie.total == 1 || jetDeVie.total <= vie;
const perte = isSuccess ? 0 : 1 + (isEchecTotal ? vie + sConst : 0) const perte = isSuccess ? 0 : 1 + (isEchecTotal ? vie + sConst : 0)
const prochainJet = (jetDeVie.total == 1 && vie > 0 ? 20 : 1) * (isCritique ? 1 : isGrave > 0 ? sConst : 0) const prochainJet = (jetDeVie.total == 1 && vie > 0 ? 20 : 1) * (isCritique ? 1 : isGrave > 0 ? sConst : 0)
@@ -395,15 +383,15 @@ export class RdDBaseActorSang extends RdDBaseActorReve {
ChatMessage.create({ ChatMessage.create({
content: msgText, content: msgText,
whisper: ChatUtility.getOwners(this) whisper: ChatUtility.getOwners(this)
}); })
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
async jetEndurance(resteEndurance = undefined, options) { async jetEndurance(resteEndurance = undefined) {
const jetEndurance = (await RdDDice.roll("1d20")).total; const jetEndurance = (await RdDDice.roll("1d20")).total;
const sonne = jetEndurance == 20 || jetEndurance > (resteEndurance ?? this.system.sante.endurance.value) const sonne = jetEndurance == 20 || jetEndurance > (resteEndurance ?? this.system.sante.endurance.value)
if (sonne) { if (sonne) {
await this.setSonne(true, options) await this.setSonne(true)
} }
return { jetEndurance, sonne } return { jetEndurance, sonne }
} }
@@ -417,13 +405,13 @@ export class RdDBaseActorSang extends RdDBaseActorReve {
} }
} }
async setSonne(sonne = true, options = {}) { async setSonne(sonne = true) {
if (!game.combat && sonne) { if (!game.combat && sonne) {
// TODO: vérifier si comportement toujours valable // TODO: vérifier si comportement toujours valable
ui.notifications.info(`${this.getAlias()} est hors combat, il ne reste donc pas sonné`); ui.notifications.info(`${this.getAlias()} est hors combat, il ne reste donc pas sonné`);
return return
} }
await this.setEffect(STATUSES.StatusStunned, sonne, options) await this.setEffect(STATUSES.StatusStunned, sonne)
} }
isSonne() { isSonne() {
+54 -28
View File
@@ -49,11 +49,9 @@ export class RdDBaseActor extends Actor {
static init() { static init() {
Handlebars.registerHelper('actor-isFeminin', actor => actor.isFeminin()) Handlebars.registerHelper('actor-isFeminin', actor => actor.isFeminin())
Hooks.on("preUpdateItem", (item, change, options, id) => Misc.documentIfResponsible(item.parent)?.onPreUpdateItem(item, change, options, id))
Hooks.on("createItem", (item, options, id) => Misc.documentIfResponsible(item.parent)?.onCreateItem(item, options, id)) Hooks.on("createItem", (item, options, id) => Misc.documentIfResponsible(item.parent)?.onCreateItem(item, options, id))
Hooks.on("updateItem", (item, updates, options, id) => Misc.documentIfResponsible(item.parent)?.onUpdateItem(item, updates, options, id)) Hooks.on("updateItem", (item, updates, options, id) => Misc.documentIfResponsible(item.parent)?.onUpdateItem(item, updates, options, id))
Hooks.on("deleteItem", (item, options, id) => Misc.documentIfResponsible(item.parent)?.onDeleteItem(item, options, id)) Hooks.on("deleteItem", (item, options, id) => Misc.documentIfResponsible(item.parent)?.onDeleteItem(item, options, id))
Hooks.on("updateActor", (actor, change, options, actorId) => Misc.documentIfResponsible(actor)?.onUpdateActor(change, options, actorId))
} }
static onSocketMessage(sockmsg) { static onSocketMessage(sockmsg) {
@@ -97,16 +95,7 @@ export class RdDBaseActor extends Actor {
return actor ?? game.actors.get(actorId) return actor ?? game.actors.get(actorId)
} }
getAlias() { static extractActorMin(actor) { return { id: actor?.id, type: actor?.type, name: actor?.name, img: actor?.img } }
if (this.token?.name != null && this.token != this.prototypeToken) {
return this.token.name
}
return this.name
}
isPersonnageJoueur() { return false }
static extractActorMin = (actor) => { return { id: actor?.id, type: actor?.type, name: actor?.name, img: actor?.img }; };
/** /**
* Cette methode surcharge Actor.create() pour ajouter si besoin des Items par défaut: * Cette methode surcharge Actor.create() pour ajouter si besoin des Items par défaut:
@@ -151,6 +140,15 @@ export class RdDBaseActor extends Actor {
super(docData, context); super(docData, context);
} }
getAlias() {
if (this.token?.name != null && this.token != this.prototypeToken) {
return this.token.name
}
return this.name
}
isPersonnageJoueur() { return false }
getCarac() { getCarac() {
return foundry.utils.duplicate(this.system.carac) return foundry.utils.duplicate(this.system.carac)
} }
@@ -216,6 +214,41 @@ export class RdDBaseActor extends Actor {
} }
} }
async _preUpdate(changed, options, user) {
const updatedCarac = changed?.system?.carac
if (updatedCarac && (updatedCarac.force || updatedCarac.reve || updatedCarac.taille)) {
await this.setEffect(STATUSES.StatusSurEnc, this.isSurenc())
}
await this.delayedRenderSheet('_preUpdate', changed, options)
return super._preUpdate(changed, options, user)
}
_onUpdate(changed, options, userId) {
super._onUpdate(changed, options, userId)
if (userId == game.user.id){
this.delayedRenderSheet('_onUpdate', changed, options)
}
}
async delayedRenderSheet(caller, data, options) {
this.refreshDelayCounter = (this.refreshDelayCounter ?? 0)+1
if (this.refreshDelayCounter == 1) {
this.renderAfterDelay(this.refreshDelayCounter)
}
}
renderAfterDelay(currentCounter) {
setTimeout(async () => {
if (currentCounter == this.refreshDelayCounter) {
this.sheet?.render(true)
this.refreshDelayCounter = 0
}
else {
this.renderAfterDelay(this.refreshDelayCounter)
}
}, 30)
}
/* -------------------------------------------- */ /* -------------------------------------------- */
prepareData() { prepareData() {
super.prepareData() super.prepareData()
@@ -228,6 +261,7 @@ export class RdDBaseActor extends Actor {
prepareActorData() { } prepareActorData() { }
async computeEtatGeneral() { } async computeEtatGeneral() { }
/* -------------------------------------------- */ /* -------------------------------------------- */
findPlayer() { findPlayer() {
return game.users.players.find(player => player.active && player.character?.id == this.id); return game.users.players.find(player => player.active && player.character?.id == this.id);
@@ -321,16 +355,8 @@ export class RdDBaseActor extends Actor {
async updateCarac(caracName, to) { async updateCarac(caracName, to) {
} }
async onUpdateActor(change, options, actorId) {
const updatedCarac = change?.system?.carac
if (updatedCarac && (updatedCarac.force || updatedCarac.reve || updatedCarac.taille)) {
console.log(' onUpdateActor', change, options, actorId)
await this.setEffect(STATUSES.StatusSurEnc, this.isSurenc())
}
}
/* -------------------------------------------- */ /* -------------------------------------------- */
async onPreUpdateItem(item, change, options, id) { }
async onCreateItem(item, options, id) { async onCreateItem(item, options, id) {
} }
@@ -347,13 +373,13 @@ export class RdDBaseActor extends Actor {
} }
async _removeItemFromConteneur(item) { async _removeItemFromConteneur(item) {
const updates = this.findConteneur(item) const conteneur = this.findConteneur(item);
.map(conteneur => { if (conteneur) {
const nouveauContenu = conteneur.system.contenu.filter(id => id != item.id) const nouveauContenu = conteneur.system.contenu.filter(id => id != item.id)
return { _id: conteneur.id, 'system.contenu': nouveauContenu } const updates = { _id: conteneur.id, 'system.contenu': nouveauContenu }
}) if (updates.length > 0) {
if (updates.length > 0) { await this.updateEmbeddedDocuments('Item', updates)
await this.updateEmbeddedDocuments('Item', updates) }
} }
} }
+3 -3
View File
@@ -15,13 +15,13 @@ export class RdDCreature extends RdDBaseActorSang {
} }
async remiseANeuf() { async remiseANeuf() {
await this.removeEffects(e => true, { render: false }) await this.removeEffects(e => true)
await this.supprimerBlessures(it => true, { render: false }) await this.supprimerBlessures(it => true)
await this.update({ await this.update({
'system.sante.endurance.value': this.system.sante.endurance.max, 'system.sante.endurance.value': this.system.sante.endurance.max,
'system.sante.vie.value': this.system.sante.vie.max, 'system.sante.vie.value': this.system.sante.vie.max,
'system.sante.fatigue.value': 0 'system.sante.fatigue.value': 0
}, { render: true }); });
} }
async finDeRoundBlessures() { async finDeRoundBlessures() {
+1 -1
View File
@@ -76,6 +76,6 @@ export class RdDActorEntiteSheet extends RdDBaseActorReveSheet {
async resonanceDelete(actorId) { async resonanceDelete(actorId) {
console.log('Delete : ', actorId); console.log('Delete : ', actorId);
let newResonances = this.actor.system.sante.resonnance.actors.filter(id => id != actorId); let newResonances = this.actor.system.sante.resonnance.actors.filter(id => id != actorId);
await this.actor.update({ 'system.sante.resonnance.actors': newResonances }, { renderSheet: false }); await this.actor.update({ 'system.sante.resonnance.actors': newResonances }, { render: false });
} }
} }
+1 -3
View File
@@ -43,9 +43,7 @@ export class RdDEntite extends RdDBaseActorReve {
async remiseANeuf() { async remiseANeuf() {
if (!this.isEntiteNonIncarnee()) { if (!this.isEntiteNonIncarnee()) {
await this.update({ await this.update({ 'system.sante.endurance.value': this.system.sante.endurance.max })
'system.sante.endurance.value': this.system.sante.endurance.max
});
} }
await this.removeEffects(e => true) await this.removeEffects(e => true)
} }
@@ -46,9 +46,9 @@ export class RdDActorExportSheet extends RdDActorSheet {
formData.export = this.getMappingValues(formData.context, this.actor) formData.export = this.getMappingValues(formData.context, this.actor)
formData.competences = this.getCompetences(CATEGORIES_COMPETENCES_BASE) formData.competences = this.getCompetences(CATEGORIES_COMPETENCES_BASE)
formData.draconic = this.getCompetences(CATEGORIES_DRACONIC) formData.draconic = this.getCompetences(CATEGORIES_DRACONIC)
const legeres = this.actor.nbBlessuresLegeres() const legeres = this.actor.countBlessures(it => it.isLegere())
const graves = this.actor.nbBlessuresGraves() const graves = this.actor.countBlessures(it => it.isGrave())
const critiques = this.actor.nbBlessuresCritiques() const critiques = this.actor.countBlessures(it => it.isCritique())
formData.etat = { formData.etat = {
surenc: this.actor.computeMalusSurEncombrement(), surenc: this.actor.computeMalusSurEncombrement(),
fatigue: { fatigue: {
+12 -10
View File
@@ -92,27 +92,28 @@ export class ChatUtility {
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
static async createChatWithRollMode(messageData, actor = undefined, rollMode = game.settings.get("core", "rollMode")) { static adaptVisibility( messageData, options = { actor: undefined, rollMode: undefined }) {
switch (rollMode) { foundry.utils.mergeObject(options, { rollMode: game.settings.get("core", "rollMode") }, { overwrite: false });
switch (options.rollMode) {
case "blindroll": // GM only case "blindroll": // GM only
if (!game.user.isGM) { if (!game.user.isGM) {
ChatUtility.blindMessageToGM(messageData) ChatUtility.blindMessageToGM(messageData)
messageData.whisper = [game.user]; messageData.whisper = [game.user]
messageData.content = "Message envoyé en aveugle au Gardien" messageData.content = "Message envoyé en aveugle au Gardien";
} }
else { else {
messageData.whisper = ChatUtility.getGMs() messageData.whisper = ChatUtility.getGMs()
} }
break break;
case "gmroll": case "gmroll":
messageData.whisper = actor ? ChatUtility.getOwners(actor) : ChatUtility.getUserAndGMs() messageData.whisper = options.actor ? ChatUtility.getOwners(options.actor) : ChatUtility.getUserAndGMs()
break break;
case "selfroll": case "selfroll":
messageData.whisper = [game.user] messageData.whisper = [game.user]
break break
} }
messageData.alias = messageData.alias ?? actor?.name ?? game.user.name messageData.alias = messageData.alias ?? options.actor?.name ?? game.user.name
return await ChatMessage.create(messageData) return messageData
} }
static tellToUser(message) { static tellToUser(message) {
@@ -134,6 +135,7 @@ export class ChatUtility {
whisper: ChatUtility.getUserAndGMs() whisper: ChatUtility.getUserAndGMs()
}) })
} }
static getOwners(document) { static getOwners(document) {
return document ? game.users.filter(it => document.getUserLevel(it) == CONST.DOCUMENT_OWNERSHIP_LEVELS.OWNER) : [game.user] return document ? game.users.filter(it => document.getUserLevel(it) == CONST.DOCUMENT_OWNERSHIP_LEVELS.OWNER) : [game.user]
} }
@@ -216,7 +218,7 @@ export class ChatUtility {
static async onRenderChatMessage(chatMessage, html, data) { static async onRenderChatMessage(chatMessage, html, data) {
const rddTimestamp = chatMessage.getFlag(SYSTEM_RDD, 'rdd-timestamp') const rddTimestamp = chatMessage.getFlag(SYSTEM_RDD, 'rdd-timestamp')
const heureRdD = $(html).find('header.message-header .heure-rdd') const heureRdD = $(html).find('header.message-header .heure-rdd')
if (rddTimestamp && heureRdD.length==0) { if (rddTimestamp && heureRdD.length == 0) {
const messageTimestamp = $(html).find('header.message-header .message-timestamp'); const messageTimestamp = $(html).find('header.message-header .message-timestamp');
const timestamp = new RdDTimestamp(rddTimestamp); const timestamp = new RdDTimestamp(rddTimestamp);
const timestampData = timestamp.toCalendrier(); const timestampData = timestamp.toCalendrier();
+19
View File
@@ -0,0 +1,19 @@
export class RdDActiveEffect extends ActiveEffect {
async _preCreate(data, options, user) {
await this.parent?.delayedRenderSheet('_preCreateEffect', data, options)
return super._preCreate(data, options, user)
}
async _preUpdate(changed, options, user) {
await this.parent?.delayedRenderSheet('_preUpdateEffect', changed, options)
return super._preUpdate(changed, options, user)
}
async _preDelete(options, user) {
await this.parent?.delayedRenderSheet('_preDeleteEffect', { id: this.id }, options)
return super._preDelete(options, user)
}
}
+31 -1
View File
@@ -1,4 +1,4 @@
import { ChatUtility } from "./chat-utility.js";
import { Grammar } from "./grammar.js"; import { Grammar } from "./grammar.js";
import { RdDInitiative } from "./initiative.mjs"; import { RdDInitiative } from "./initiative.mjs";
import { RdDItem } from "./item.js"; import { RdDItem } from "./item.js";
@@ -71,6 +71,36 @@ export class RdDItemCompetence extends RdDItem {
} }
return undefined return undefined
} }
async _preUpdate(changed, options, user) {
await this.checkCompetenceXP(changed.system?.xp)
return super._preUpdate(changed, options, user)
}
async checkCompetenceXP(newXP, display = true) {
if (this.actor?.isPersonnage() && newXP && newXP != this.system.xp && newXP > 0) {
const newNiv = this.system.niveau + 1
let needed = RdDItemCompetence.getCompetenceNextXp(newNiv)
if (newXP >= needed) {
const xpData = {
alias: this.actor.getAlias(),
competence: this.name,
niveau: newNiv,
xp: newXP,
archetype: this.system.niveau_archetype,
archetypeWarning: newNiv > this.system.niveau_archetype
}
if (display) {
ChatMessage.create({
whisper: ChatUtility.getOwners(this.actor),
content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-actor-competence-xp.hbs`, xpData)
})
}
return xpData
}
}
}
/* -------------------------------------------- */ /* -------------------------------------------- */
static getLabelCategorie(category) { static getLabelCategorie(category) {
return CATEGORIES_COMPETENCES[category].label; return CATEGORIES_COMPETENCES[category].label;
+15 -1
View File
@@ -116,7 +116,6 @@ export class RdDItem extends Item {
return true; return true;
} }
static itemTypePluriel(type) { static itemTypePluriel(type) {
if (ITEM_TYPES[type]) { if (ITEM_TYPES[type]) {
return ITEM_TYPES_PLURIEL[type] ?? (type + 's') return ITEM_TYPES_PLURIEL[type] ?? (type + 's')
@@ -175,6 +174,21 @@ export class RdDItem extends Item {
super(docData, context); super(docData, context);
} }
async _preCreate(data, options, user) {
await this.parent?.delayedRenderSheet('_preCreateItem', data, options)
return super._preCreate(data, options, user)
}
async _preUpdate(changed, options, user) {
await this.parent?.delayedRenderSheet('_preUpdateItem', changed, options)
return super._preUpdate(changed, options, user)
}
async _preDelete(options, user) {
await this.parent?.delayedRenderSheet('_preDeleteItem', { id: this.id }, options)
return super._preDelete(options, user)
}
getUniteQuantite() { getUniteQuantite() {
switch (this.type) { switch (this.type) {
case ITEM_TYPES.monnaie: return "(Pièces)" case ITEM_TYPES.monnaie: return "(Pièces)"
+4 -6
View File
@@ -106,11 +106,9 @@ export class RdDItemBlessure extends RdDItem {
async updateTacheSoinBlessure(tache) { async updateTacheSoinBlessure(tache) {
if (tache) { if (tache) {
await tache.update({ await tache.update({
system: { 'system.itemId': this.id,
itemId: this.id, 'system.difficulte': Math.min(this.system.difficulte, tache.system.difficulte),
difficulte: Math.min(this.system.difficulte, tache.system.difficulte), 'system.points_de_tache_courant': Math.max(0, this.system.premierssoins.tache)
points_de_tache_courant: Math.max(0, this.system.premierssoins.tache)
}
}); });
} }
} }
@@ -162,7 +160,7 @@ export class RdDItemBlessure extends RdDItem {
message.content += ` -- une blessure ${label} reste stable`; message.content += ` -- une blessure ${label} reste stable`;
} }
} }
await this.update(update); await this.update(update)
} }
} }
+11
View File
@@ -28,6 +28,7 @@ const _MONTRER = {
} }
const _SPLIT = { const _SPLIT = {
code: 'item-split', label: 'Séparer le goupe', icon: 'fa-solid fa-unlink', code: 'item-split', label: 'Séparer le goupe', icon: 'fa-solid fa-unlink',
actorFilter: actor => actor.isOwner,
filter: it => Misc.toInt(it.system.quantite) > 1 && it.parent?.type != ACTOR_TYPES.commerce, filter: it => Misc.toInt(it.system.quantite) > 1 && it.parent?.type != ACTOR_TYPES.commerce,
action: (item, actor) => RdDSheetUtility.splitItem(item, actor) action: (item, actor) => RdDSheetUtility.splitItem(item, actor)
} }
@@ -45,6 +46,7 @@ const _DELETE = {
} }
const _EQUIPER = { const _EQUIPER = {
code: 'item-equip', label: 'Equiper', icon: it => it.system.equipe ? 'fa-solid fa-hand-rock' : 'fa-regular fa-hand-paper', code: 'item-equip', label: 'Equiper', icon: it => it.system.equipe ? 'fa-solid fa-hand-rock' : 'fa-regular fa-hand-paper',
actorFilter: actor => actor.isPersonnage(),
filter: it => !it.estContenu && it.isEquipable(), filter: it => !it.estContenu && it.isEquipable(),
action: (item, actor) => actor.equiperObjet(item) action: (item, actor) => actor.equiperObjet(item)
} }
@@ -52,26 +54,31 @@ const _EQUIPER = {
const _CUISINER = { const _CUISINER = {
code: 'item-cuisiner', label: 'Cuisiner', code: 'item-cuisiner', label: 'Cuisiner',
img: 'systems/foundryvtt-reve-de-dragon/assets/actions/cuisine.svg', img: 'systems/foundryvtt-reve-de-dragon/assets/actions/cuisine.svg',
actorFilter: actor => actor.isPersonnage(),
filter: it => it.getUtilisation() == 'cuisine' && it.system.sust > 0, filter: it => it.getUtilisation() == 'cuisine' && it.system.sust > 0,
action: (item, actor) => actor.preparerNourriture(item) action: (item, actor) => actor.preparerNourriture(item)
} }
const _MANGER_CRU = { const _MANGER_CRU = {
code: 'item-manger-cru', label: 'Manger cru', icon: 'fa-solid fa-drumstick-bite', code: 'item-manger-cru', label: 'Manger cru', icon: 'fa-solid fa-drumstick-bite',
actorFilter: actor => actor.isPersonnage(),
filter: it => it.getUtilisation() == 'cuisine' && it.system.sust > 0, filter: it => it.getUtilisation() == 'cuisine' && it.system.sust > 0,
action: (item, actor) => actor.mangerNourriture(item) action: (item, actor) => actor.mangerNourriture(item)
} }
const _MANGER = { const _MANGER = {
code: 'item-manger', label: 'Manger', icon: 'fa-solid fa-utensils', code: 'item-manger', label: 'Manger', icon: 'fa-solid fa-utensils',
actorFilter: actor => actor.isPersonnage(),
filter: it => !(it.system.boisson), filter: it => !(it.system.boisson),
action: (item, actor) => actor.mangerNourriture(item) action: (item, actor) => actor.mangerNourriture(item)
} }
const _BOIRE = { const _BOIRE = {
code: 'item-boire', label: 'Boire', icon: 'fa-solid fa-glass-water', code: 'item-boire', label: 'Boire', icon: 'fa-solid fa-glass-water',
actorFilter: actor => actor.isPersonnage(),
filter: it => it.system.boisson, filter: it => it.system.boisson,
action: (item, actor) => actor.mangerNourriture(item) action: (item, actor) => actor.mangerNourriture(item)
} }
const _DECOCTION = { const _DECOCTION = {
code: 'item-decoction', label: 'Décoction', icon: 'fa-solid fa-flask-vial', code: 'item-decoction', label: 'Décoction', icon: 'fa-solid fa-flask-vial',
actorFilter: actor => actor.isPersonnage(),
action: (item, actor) => actor.fabriquerDecoctionHerbe(item) action: (item, actor) => actor.fabriquerDecoctionHerbe(item)
} }
@@ -82,17 +89,20 @@ const _OUVRIR = {
} }
const _LIRE = { const _LIRE = {
code: 'item-lire', label: 'Lire', icon: 'fa-solid fa-book-open', code: 'item-lire', label: 'Lire', icon: 'fa-solid fa-book-open',
actorFilter: actor => actor.isPersonnage(),
action: (item, actor) => actor.actionLire(item) action: (item, actor) => actor.actionLire(item)
} }
const _REFOULER = { const _REFOULER = {
code: 'item-refouler', label: 'Refouler', icon: 'fa-solid fa-burst', code: 'item-refouler', label: 'Refouler', icon: 'fa-solid fa-burst',
actorFilter: actor => actor.isPersonnage(),
filter: it => it.system.refoulement > 0, filter: it => it.system.refoulement > 0,
action: (item, actor) => actor.actionRefoulement(item) action: (item, actor) => actor.actionRefoulement(item)
} }
const _SORT_RESERVE = { const _SORT_RESERVE = {
code: 'item-sortreserve-add', label: 'Ajouter en réserve', icon: 'fa-solid fa-sparkles', code: 'item-sortreserve-add', label: 'Ajouter en réserve', icon: 'fa-solid fa-sparkles',
actorFilter: actor => actor.isPersonnage(),
filter: it => game.user.isGM && !it.system.isrituel, filter: it => game.user.isGM && !it.system.isrituel,
action: (item, actor) => actor.addSortReserve(item) action: (item, actor) => actor.addSortReserve(item)
} }
@@ -118,6 +128,7 @@ export class ItemAction {
static applies(action, item, options) { static applies(action, item, options) {
return action && item return action && item
&& item.isActionAllowed(action.code) && item.isActionAllowed(action.code)
&& (!action.actorFilter || (item.actor && action.actorFilter(item.actor)))
&& (!action.filter || action.filter(item)) && (!action.filter || action.filter(item))
&& (action.allowLimited || options.editable) && (action.allowLimited || options.editable)
&& (!action.optionsFilter || action.optionsFilter(options)) && (!action.optionsFilter || action.optionsFilter(options))
+15 -15
View File
@@ -77,41 +77,41 @@ export class RdDInventaireItemSheet extends RdDItemSheetV1 {
} }
async onAddMilieu(event) { async onAddMilieu(event) {
const milieu = this.html.find('input.input-selection-milieu').val(); const milieu = this.html.find('input.input-selection-milieu').val()
if (!milieu) { if (!milieu) {
ui.notifications.warn(`Choisissez le milieu dans lequel se trouve le/la ${this.item.name}`); ui.notifications.warn(`Choisissez le milieu dans lequel se trouve le/la ${this.item.name}`)
return return
} }
const list = this.item.getEnvironnements(); const list = this.item.getEnvironnements()
const exists = list.find(it => it.milieu == milieu); const exists = list.find(it => it.milieu == milieu)
if (exists) { if (exists) {
ui.notifications.warn(`${this.item.name} a déjà une rareté ${exists.rarete} en ${milieu} (fréquence: ${exists.frequence})`); ui.notifications.warn(`${this.item.name} a déjà une rareté ${exists.rarete} en ${milieu} (fréquence: ${exists.frequence})`);
return return
} }
const rarete = RdDRaretes.rareteFrequente(); const rarete = RdDRaretes.rareteFrequente()
const added = { milieu, rarete: rarete.code, frequence: rarete.frequence }; const added = { milieu, rarete: rarete.code, frequence: rarete.frequence }
const newList = [added, ...list].sort(Misc.ascending(it => it.milieu)) const newList = [added, ...list].sort(Misc.ascending(it => it.milieu))
await this.item.update({ 'system.environnement': newList }) await this.item.update({ 'system.environnement': newList })
} }
async onDeleteMilieu(event) { async onDeleteMilieu(event) {
const milieu = this.$getEventMilieu(event); const milieu = this.$getEventMilieu(event)
if (milieu != undefined) { if (milieu != undefined) {
const newList = this.item.getEnvironnements().filter(it => it.milieu != milieu) const newList = this.item.getEnvironnements().filter(it => it.milieu != milieu)
.sort(Misc.ascending(it => it.milieu)); .sort(Misc.ascending(it => it.milieu))
await this.item.update({ 'system.environnement': newList }); await this.item.update({ 'system.environnement': newList })
} }
} }
async onChange(event, doMutation) { async onChange(event, doMutation) {
const list = this.item.system.environnement; const list = this.item.system.environnement
const milieu = this.$getEventMilieu(event); const milieu = this.$getEventMilieu(event)
const updated = list.find(it => it.milieu == milieu); const updated = list.find(it => it.milieu == milieu)
if (updated) { if (updated) {
doMutation(updated); doMutation(updated)
const newList = [...list.filter(it => it.milieu != milieu), updated] const newList = [...list.filter(it => it.milieu != milieu), updated]
.sort(Misc.ascending(it => it.milieu)); .sort(Misc.ascending(it => it.milieu))
await this.item.update({ 'system.environnement': newList }); await this.item.update({ 'system.environnement': newList })
} }
} }
+2 -2
View File
@@ -20,7 +20,7 @@ export class RdDFauneItemSheet extends RdDInventaireItemSheet {
'system.actor.pack': linkedActor.pack, 'system.actor.pack': linkedActor.pack,
'system.actor.id': linkedActor._id, 'system.actor.id': linkedActor._id,
'system.actor.name': linkedActor.name 'system.actor.name': linkedActor.name
}); })
} }
else { else {
ui.notifications.warn(`${linkedActor.name} ne provient pas d'un compendium. ui.notifications.warn(`${linkedActor.name} ne provient pas d'un compendium.
@@ -32,7 +32,7 @@ export class RdDFauneItemSheet extends RdDInventaireItemSheet {
'system.actor.pack': '', 'system.actor.pack': '',
'system.actor.id': '', 'system.actor.id': '',
'system.actor.name': '' 'system.actor.name': ''
}); })
} }
} }
+8 -8
View File
@@ -996,9 +996,9 @@ export class RdDCombat {
const arme = rollData.arme; const arme = rollData.arme;
const avecArme = !['', 'sans-armes', 'armes-naturelles'].includes(arme?.system.categorie_parade ?? ''); const avecArme = !['', 'sans-armes', 'armes-naturelles'].includes(arme?.system.categorie_parade ?? '');
const action = (rollData.attackerRoll ? (arme ? "la parade" : "l'esquive") : "l'attaque"); const action = (rollData.attackerRoll ? (arme ? "la parade" : "l'esquive") : "l'attaque");
ChatUtility.createChatWithRollMode( await ChatMessage.create(ChatUtility.adaptVisibility(
{ content: `<strong>Maladresse à ${action}!</strong> ` + await RdDRollTables.getMaladresse({ arme: avecArme }) }, { content: `<strong>Maladresse à ${action}!</strong> ` + await RdDRollTables.getMaladresse({ arme: avecArme }) },
this.defender) { actor: this.defender }))
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
@@ -1122,9 +1122,9 @@ export class RdDCombat {
async infoAttaquantDesarme(rollData) { async infoAttaquantDesarme(rollData) {
if (/*TODO: parade?*/!rollData.attackerRoll?.particuliere) { if (/*TODO: parade?*/!rollData.attackerRoll?.particuliere) {
// TODO: attaquant doit jouer résistance et peut être désarmé p132 // TODO: attaquant doit jouer résistance et peut être désarmé p132
ChatUtility.createChatWithRollMode( await ChatMessage.create(ChatUtility.adaptVisibility(
{ content: `(à gérer) L'attaquant doit jouer résistance et peut être désarmé (p132)` }, { content: `(à gérer) L'attaquant doit jouer résistance et peut être désarmé (p132)` },
this.defender) { actor: this.defender }))
} }
} }
@@ -1156,9 +1156,9 @@ export class RdDCombat {
console.log("RdDCombat._onParadeParticuliere >>>", defenderRoll); console.log("RdDCombat._onParadeParticuliere >>>", defenderRoll);
if (!defenderRoll.attackerRoll.isPart) { if (!defenderRoll.attackerRoll.isPart) {
// TODO: attaquant doit jouer résistance et peut être désarmé p132 // TODO: attaquant doit jouer résistance et peut être désarmé p132
ChatUtility.createChatWithRollMode( await ChatMessage.create(ChatUtility.adaptVisibility(
{ content: `(à gérer) L'attaquant doit jouer résistance et peut être désarmé (p132)` }, { content: `(à gérer) L'attaquant doit jouer résistance et peut être désarmé (p132)` },
this.defender) { actor: this.defender }))
} }
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
@@ -1243,9 +1243,9 @@ export class RdDCombat {
/* -------------------------------------------- */ /* -------------------------------------------- */
async _onEsquiveParticuliere(defenderRoll) { async _onEsquiveParticuliere(defenderRoll) {
console.log("RdDCombat._onEsquiveParticuliere >>>", defenderRoll); console.log("RdDCombat._onEsquiveParticuliere >>>", defenderRoll);
ChatUtility.createChatWithRollMode( await ChatMessage.create(ChatUtility.adaptVisibility(
{ content: "<strong>Vous pouvez esquiver une deuxième fois!</strong>" }, { content: "<strong>Vous pouvez esquiver une deuxième fois!</strong>" },
this.defender); { actor: this.defender }))
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
+4 -6
View File
@@ -224,12 +224,10 @@ export class RdDEmpoignade {
const isNouvelle = empoignade == undefined; const isNouvelle = empoignade == undefined;
empoignade = empoignade ?? (await RdDEmpoignade.createEmpoignade(attacker, defender)) empoignade = empoignade ?? (await RdDEmpoignade.createEmpoignade(attacker, defender))
if ((isNouvelle || empoignade.system.pointsemp == 0) && defender.hasArmeeMeleeEquipee()) { if ((isNouvelle || empoignade.system.pointsemp == 0) && defender.hasArmeeMeleeEquipee()) {
ChatUtility.createChatWithRollMode( await ChatMessage.create(ChatUtility.adaptVisibility(
{ { content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-empoignade-valider.hbs`, { attacker: attacker, defender: defender }) },
content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-empoignade-valider.hbs`, { attacker: attacker, defender: defender }) { actor: attacker }
}, ))
attacker
)
} else { } else {
await this.onAttaqueEmpoignadeValidee(attacker, defender) await this.onAttaqueEmpoignadeValidee(attacker, defender)
} }
+2
View File
@@ -94,6 +94,7 @@ import ChatRollResult from "./roll/chat-roll-result.mjs"
import ExportPdf from "./actor/export-pdf/export-pdf.mjs" import ExportPdf from "./actor/export-pdf/export-pdf.mjs"
import { DialogFlushByDate } from "./chat/dialog-flush-by-date.mjs" import { DialogFlushByDate } from "./chat/dialog-flush-by-date.mjs"
import { Remote } from "./remote.mjs" import { Remote } from "./remote.mjs"
import { RdDActiveEffect } from "./effect/base-active-effect.js"
/** /**
* RdD system * RdD system
@@ -199,6 +200,7 @@ export class SystemReveDeDragon {
// Define custom Entity classes // Define custom Entity classes
console.log(`Initializing Reve de Dragon Documents`) console.log(`Initializing Reve de Dragon Documents`)
CONFIG.Actor.documentClass = RdDBaseActor CONFIG.Actor.documentClass = RdDBaseActor
CONFIG.ActiveEffect.documentClass = RdDActiveEffect
CONFIG.Item.documentClass = RdDItem CONFIG.Item.documentClass = RdDItem
CONFIG.Item.dataModels = { CONFIG.Item.dataModels = {
monnaie: models.RdDModelMonnaie, monnaie: models.RdDModelMonnaie,
+3 -5
View File
@@ -4,12 +4,10 @@ import { renderTemplate } from "./constants.js";
export class RdDRollResult { export class RdDRollResult {
static async displayRollData(rollData, actor = undefined, template = 'chat-resultat-general.hbs') { static async displayRollData(rollData, actor = undefined, template = 'chat-resultat-general.hbs') {
const chatMessage = await ChatUtility.createChatWithRollMode( return await ChatMessage.create(ChatUtility.adaptVisibility(
{ content: await RdDRollResult.buildRollDataHtml(rollData, template) }, { content: await RdDRollResult.buildRollDataHtml(rollData, template) },
actor, { actor: actor, rollMode: rollData.current?.rollmode?.key }
rollData.current?.rollmode?.key ))
)
return chatMessage
} }
static async buildRollDataHtml(rollData, template = 'chat-resultat-general.hbs') { static async buildRollDataHtml(rollData, template = 'chat-resultat-general.hbs') {
+22 -20
View File
@@ -34,9 +34,9 @@ export class RdDRollTables {
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
static async getCompetence(toChat = false) { static async getCompetence(toChat = false, rollMode = "gmroll") {
if (toChat == 'liste') { if (toChat == 'liste') {
return await RdDRollTables.listOrRoll('competences', 'Item', ['competence'], toChat, it => 1); return await RdDRollTables.listOrRoll('competences', 'Item', ['competence'], toChat, rollMode, it => 1);
} }
else { else {
return await RdDRollTables.drawItemFromRollTable("Détermination aléatoire de compétence", toChat); return await RdDRollTables.drawItemFromRollTable("Détermination aléatoire de compétence", toChat);
@@ -44,56 +44,58 @@ export class RdDRollTables {
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
static async getSouffle(toChat = false) { static async getSouffle(toChat = false, rollMode = "gmroll") {
return await RdDRollTables.listOrRoll('souffles-de-dragon', 'Item', ['souffle'], toChat); return await RdDRollTables.listOrRoll('souffles-de-dragon', 'Item', ['souffle'], toChat, rollMode);
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
static async getQueue(toChat = false) { static async getQueue(toChat = false, rollMode = "gmroll") {
return await RdDRollTables.listOrRoll('queues-de-dragon', 'Item', ['queue'], toChat); return await RdDRollTables.listOrRoll('queues-de-dragon', 'Item', ['queue'], toChat, rollMode);
} }
static async getDesirLancinant(toChat = false) { static async getDesirLancinant(toChat = false, rollMode = "gmroll") {
return await RdDRollTables.listOrRoll('queues-de-dragon', 'Item', ['queue'], toChat, return await RdDRollTables.listOrRoll('queues-de-dragon', 'Item', ['queue'], toChat, rollMode,
it => it.system.frequence, it => it.system.frequence,
it => it.system.categorie == 'lancinant'); it => it.system.categorie == 'lancinant');
} }
static async getIdeeFixe(toChat = false) { static async getIdeeFixe(toChat = false, rollMode = "gmroll") {
return await RdDRollTables.listOrRoll('queues-de-dragon', 'Item', ['queue'], toChat, return await RdDRollTables.listOrRoll('queues-de-dragon', 'Item', ['queue'], toChat, rollMode,
it => it.system.frequence, it => it.system.frequence,
it => it.system.categorie == 'ideefixe'); it => it.system.categorie == 'ideefixe');
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
static async getTeteHR(toChat = false) { static async getTeteHR(toChat = false, rollMode = "gmroll") {
return await RdDRollTables.listOrRoll('tetes-de-dragon-pour-haut-revants', 'Item', ['tete'], toChat); return await RdDRollTables.listOrRoll('tetes-de-dragon-pour-haut-revants', 'Item', ['tete'], toChat, rollMode);
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
static async getTete(toChat = false) { static async getTete(toChat = false, rollMode = "gmroll") {
return await RdDRollTables.listOrRoll('tetes-de-dragon-pour-tous-personnages', 'Item', ['tete'], toChat); return await RdDRollTables.listOrRoll('tetes-de-dragon-pour-tous-personnages', 'Item', ['tete'], toChat, rollMode);
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
static async getOmbre(toChat = false) { static async getOmbre(toChat = false, rollMode = "gmroll") {
return await RdDRollTables.listOrRoll('ombres-de-thanatos', 'Item', ['ombre'], toChat); return await RdDRollTables.listOrRoll('ombres-de-thanatos', 'Item', ['ombre'], toChat, rollMode);
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
static async getTarot(toChat = true) { static async getTarot(toChat = true, rollMode = "gmroll") {
return await RdDRollTables.listOrRoll('tarot-draconique', 'Item', ['tarot'], toChat); return await RdDRollTables.listOrRoll('tarot-draconique', 'Item', ['tarot'], toChat, rollMode);
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
static async listOrRoll(compendium, type, subTypes, toChat, itemFrequence = it => it.system.frequence, filter = it => true) { static async listOrRoll(compendium, type, subTypes, toChat, rollMode,
itemFrequence = it => it.system.frequence,
filter = it => true) {
const table = new CompendiumTable(compendium, type, subTypes); const table = new CompendiumTable(compendium, type, subTypes);
if (toChat == 'liste') { if (toChat == 'liste') {
return await table.toChatMessage(itemFrequence, filter); return await table.toChatMessage(itemFrequence, filter);
} }
const row = await table.getRandom(itemFrequence, filter); const row = await table.getRandom(itemFrequence, filter);
if (row) { if (row) {
await CompendiumTableHelpers.tableRowToChatMessage(row, type); await CompendiumTableHelpers.tableRowToChatMessage(row, type, { rollMode: rollMode });
return row.document; return row.document;
} }
return undefined; return undefined;
+4 -4
View File
@@ -43,13 +43,13 @@ export default class ChatRollResult {
async display(roll, impacts) { async display(roll, impacts) {
this.prepareDisplay(roll) this.prepareDisplay(roll)
const chatMessage = await ChatUtility.createChatWithRollMode( const chatMessage = await ChatMessage.create(ChatUtility.adaptVisibility(
{ {
content: await this.buildRollHtml(roll) content: await this.buildRollHtml(roll)
}, },
roll.active.actor, roll.active.actor,
roll.current?.rollmode?.key roll.current?.rollmode?.key
) ))
await this.saveChatMessageRoll(chatMessage, roll, impacts) await this.saveChatMessageRoll(chatMessage, roll, impacts)
return chatMessage return chatMessage
@@ -105,8 +105,8 @@ export default class ChatRollResult {
if (attaque && if (attaque &&
(roll.rolled.isEchec || !roll.current.defense.isEsquive) && (roll.rolled.isEchec || !roll.current.defense.isEsquive) &&
(attaque.particuliere == 'force' || 'charge' == attaque.tactique?.key)) { (attaque.particuliere == 'force' || 'charge' == attaque.tactique?.key)) {
const taille = defender.system.carac.taille.value const taille = defender.getTaille()
const impact = attacker.system.carac.force.value + roll.attackerRoll?.dmg.dmgArme const impact = attacker.getForce() + roll.attackerRoll?.dmg.dmgArme
return { return {
raison: 'charge' == attaque.tactique?.key ? 'charge' : 'particulière en force', raison: 'charge' == attaque.tactique?.key ? 'charge' : 'particulière en force',
taille: taille, taille: taille,
+1
View File
@@ -25,6 +25,7 @@ const listeReglesOptionnelles = [
{ group: 'Affichage', name: 'afficher-colonnes-reussite', descr: "Afficher le nombre de colonnes de réussite ou d'échec", default: false }, { group: 'Affichage', name: 'afficher-colonnes-reussite', descr: "Afficher le nombre de colonnes de réussite ou d'échec", default: false },
{ group: 'Affichage', name: 'afficher-prix-joueurs', descr: "Afficher le prix de l'équipement des joueurs", uniquementJoueur: true}, { group: 'Affichage', name: 'afficher-prix-joueurs', descr: "Afficher le prix de l'équipement des joueurs", uniquementJoueur: true},
{ group: 'Affichage', name: 'afficher-table-source', descr: "Afficher la table d'origine des tirages aléatoires", default: false },
{ group: 'Confirmations', name: 'confirmer-combat-sans-cible', descr: "Confirmer avant une attaque sans cible", scope: "client"}, { group: 'Confirmations', name: 'confirmer-combat-sans-cible', descr: "Confirmer avant une attaque sans cible", scope: "client"},
{ group: 'Confirmations', name: 'confirmation-tmr', descr: "Confirmer pour monter dans les TMR", scope: "client"}, { group: 'Confirmations', name: 'confirmation-tmr', descr: "Confirmer pour monter dans les TMR", scope: "client"},
+24 -18
View File
@@ -4,6 +4,7 @@ import { Grammar } from "../grammar.js";
import { RdDItem } from "../item.js"; import { RdDItem } from "../item.js";
import { Misc } from "../misc.js"; import { Misc } from "../misc.js";
import { RdDDice } from "../rdd-dice.js"; import { RdDDice } from "../rdd-dice.js";
import { ReglesOptionnelles } from "./regles-optionnelles.js";
const COMPENDIUM_SETTING_PREFIX = 'compendium-'; const COMPENDIUM_SETTING_PREFIX = 'compendium-';
@@ -289,24 +290,28 @@ export class CompendiumTableHelpers {
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
static async tableRowToChatMessage(row, type, options = { showSource: true }) { static async tableRowToChatMessage(row, type, options = {}) {
if (options.showSource == undefined){
options.showSource = ReglesOptionnelles.isUsing('afficher-table-source')
}
if (!row) { if (!row) {
return; return
} }
const flavorContent = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-compendium-table-roll.hbs', { const flavorContent = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-compendium-table-roll.hbs', {
roll: row.roll, roll: row.roll,
document: row.document, document: row.document,
typeName: Misc.typeName(type, row.document?.type ?? 'objet'), typeName: Misc.typeName(type, row.document?.type ?? 'objet'),
isGM: game.user.isGM, isGM: game.user.isGM,
options options: { showSource: options.showSource }
}); })
const messageData = { await ChatMessage.create(ChatUtility.adaptVisibility(
user: game.user.id, {
rolls: [row.roll], user: game.user.id,
sound: CONFIG.sounds.dice, rolls: [row.roll],
content: flavorContent sound: CONFIG.sounds.dice,
}; content: flavorContent
await ChatUtility.createChatWithRollMode(messageData) },
{ rollMode: options.rollMode }))
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
@@ -316,13 +321,14 @@ export class CompendiumTableHelpers {
typeName: typeName ?? Misc.typeName(type, subTypes[0]), typeName: typeName ?? Misc.typeName(type, subTypes[0]),
table, table,
isGM: game.user.isGM, isGM: game.user.isGM,
}); })
const messageData = { await ChatMessage.create(ChatUtility.adaptVisibility(
user: game.user.id, {
whisper: [game.user], user: game.user.id,
content: flavorContent whisper: [game.user],
}; content: flavorContent
await ChatUtility.createChatWithRollMode(messageData) }
))
} }
} }
+1 -1
View File
@@ -38,7 +38,7 @@ export class TMRRencontres {
const frequence = it => it.system.frequence[tmrType]; const frequence = it => it.system.frequence[tmrType];
const row = await this.table.getRandom(frequence, filtreMauvaise, forcedRoll); const row = await this.table.getRandom(frequence, filtreMauvaise, forcedRoll);
if (row) { if (row) {
await CompendiumTableHelpers.tableRowToChatMessage(row, 'Item', { showSource: false }); await CompendiumTableHelpers.tableRowToChatMessage(row, 'Item', { showSource: false, rollMode: "gmroll" });
} }
return row?.document; return row?.document;
+1 -1
View File
@@ -129,7 +129,7 @@ export class EffetsRencontre {
} }
static regain_seuil = async (dialog, context) => { static regain_seuil = async (dialog, context) => {
await context.actor.regainPointDeSeuil() await context.actor.recuperationSeuilReve()
} }
static async $reinsertion(dialog, actor, filter) { static async $reinsertion(dialog, actor, filter) {
@@ -8,7 +8,7 @@ items:
type: competencecreature type: competencecreature
sort: 100000 sort: 100000
flags: {} flags: {}
img: systems/foundryvtt-reve-de-dragon/icons/competence_course.webp img: systems/foundryvtt-reve-de-dragon/icons/creatures/glou_t.webp
effects: [] effects: []
folder: null folder: null
system: system:
@@ -422,7 +422,7 @@ prototypeToken:
negative: false negative: false
priority: 0 priority: 0
texture: texture:
src: icons/svg/mystery-man.svg src: systems/foundryvtt-reve-de-dragon/icons/creatures/glou_t.webp
tint: '#ffffff' tint: '#ffffff'
scaleX: 1 scaleX: 1
scaleY: 1 scaleY: 1
@@ -299,7 +299,7 @@ prototypeToken:
negative: false negative: false
priority: 0 priority: 0
texture: texture:
src: systems/foundryvtt-reve-de-dragon/icons/creatures/sirene.svg src: systems/foundryvtt-reve-de-dragon/icons/creatures/sirene_t.webp
tint: '#ffffff' tint: '#ffffff'
scaleX: 1 scaleX: 1
scaleY: 1 scaleY: 1
@@ -348,7 +348,7 @@ prototypeToken:
negative: false negative: false
priority: 0 priority: 0
texture: texture:
src: systems/foundryvtt-reve-de-dragon/icons/creatures/tigre-vert.svg src: systems/foundryvtt-reve-de-dragon/icons/creatures/tigre-vert_t.webp
tint: '#ffffff' tint: '#ffffff'
scaleX: 1 scaleX: 1
scaleY: 1 scaleY: 1
@@ -215,7 +215,7 @@ prototypeToken:
negative: false negative: false
priority: 0 priority: 0
texture: texture:
src: systems/foundryvtt-reve-de-dragon/icons/creatures/chrasme_t.webp src: systems/foundryvtt-reve-de-dragon/icons/creatures/chrasme_t-old.webp
tint: '#d53434' tint: '#d53434'
scaleX: 0.8 scaleX: 0.8
scaleY: 0.8 scaleY: 0.8
@@ -298,7 +298,7 @@ prototypeToken:
negative: false negative: false
priority: 0 priority: 0
texture: texture:
src: systems/foundryvtt-reve-de-dragon/icons/creatures/zyglute.svg src: systems/foundryvtt-reve-de-dragon/icons/creatures/zyglute_t.webp
tint: '#ffffff' tint: '#ffffff'
scaleX: 1 scaleX: 1
scaleY: 1 scaleY: 1
+1 -1
View File
@@ -7,7 +7,7 @@
"changelog": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/raw/branch/v11/changelog.md", "changelog": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/raw/branch/v11/changelog.md",
"compatibility": { "compatibility": {
"minimum": "13", "minimum": "13",
"verified": "13" "verified": "14"
}, },
"description": "Rêve de Dragon RPG for FoundryVTT", "description": "Rêve de Dragon RPG for FoundryVTT",
"authors": [ "authors": [
+4 -2
View File
@@ -19,9 +19,11 @@
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/header-compteurs-creature.hbs"}} {{>"systems/foundryvtt-reve-de-dragon/templates/actor/header-compteurs-creature.hbs"}}
<div class="flex-group-left header-etats"> <div class="flex-group-left header-etats">
<div class="flexcol"> <div class="flexcol">
<span>{{>"systems/foundryvtt-reve-de-dragon/templates/actor/header-effects.hbs"}}</span>
<span>{{system.compteurs.etat.label}}: {{system.compteurs.etat.value}}</span> <span>{{system.compteurs.etat.label}}: {{system.compteurs.etat.value}}</span>
<span>{{calc.resumeBlessures}}</span> {{#each calc.blessures as |blessure|}}
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/header-effects.hbs"}} <span>{{blessure}}</span>
{{/each}}
</div> </div>
</div> </div>
</div> </div>
+4 -4
View File
@@ -1,9 +1,9 @@
<div class="flex-group-left header-etats"> <div class="flex-group-left header-etats">
<div class="flexcol"> <div class="flexcol">
<div>{{>"systems/foundryvtt-reve-de-dragon/templates/actor/header-effects.hbs"}} Enc: {{calc.surenc}}</div>
<div>{{system.compteurs.etat.label}}: {{system.compteurs.etat.value}}</div> <div>{{system.compteurs.etat.label}}: {{system.compteurs.etat.value}}</div>
<div>Sur-encombrement: {{calc.surenc}}</div> {{#each calc.blessures as |blessure|}}
<div>{{calc.resumeBlessures}}</div> <div>{{blessure}}</div>
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/header-effects.hbs"}} {{/each}}
</div> </div>
</div> </div>
+1 -1
View File
@@ -29,7 +29,7 @@
</li> </li>
{{#if system.reve.reve.thanatosused}} {{#if system.reve.reve.thanatosused}}
<li class="item flexrow" > <li class="item flexrow" >
<span class="generic-label">La prochaine queue est une Ombre</span> <span class="generic-label">La prochaine queue est une Ombre de thanatos</span>
<span> <span>
<img class="sheet-competence-img" src="systems/foundryvtt-reve-de-dragon/icons/competence_thanatos.webp"/> <img class="sheet-competence-img" src="systems/foundryvtt-reve-de-dragon/icons/competence_thanatos.webp"/>
</span> </span>