Compare commits

..

18 Commits

Author SHA1 Message Date
484f02277b Merge pull request 'Version 10.0.30' (#567) from VincentVk/foundryvtt-reve-de-dragon:v10 into v10
Reviewed-on: #567
2022-10-21 22:18:05 +02:00
Vincent Vandemeulebrouck
0ef9123cd5 Version 10.0.30
* Fix de bug de socket qui pouvait conduire à un plantage de Foundry,
  par exemple lors d'un achat par un joueur
* Fix de l'édition des sorts des personnages: la sauvegarde fonctionne
  de nouveau
* Ajout d'une demande de confirmation lors d'un refoulement: l'action
  refouler est très proche de la suppression, un mauvais clic est vite
  arrivé
2022-10-21 22:10:38 +02:00
Vincent Vandemeulebrouck
e6b71faa02 Passer un async à game.socket.on()
Corrige le problème causé par l'update d'un objet pendant le traitement
d'un message du socket, qui peut échouer quand le socket est occupé,
et cause donc un rejet du message du socket, qui est réessayé en boucle
infinier.

Ce qui devrait résoudre le problème d'achat/vente qui fait planter le
MJ et le serveur Foundry.
2022-10-21 22:05:35 +02:00
Vincent Vandemeulebrouck
9a1a464cb6 Whisper vers l'actor
Plutôt que le game.user.name, pour que les messages soient envoyés
au joueur même si c'est le MJ qui agit pour le user
2022-10-21 02:41:32 +02:00
Vincent Vandemeulebrouck
32af9bf1b4 Ajout de confirmation pour refoulement 2022-10-21 02:41:32 +02:00
Vincent Vandemeulebrouck
362fd964d0 Fix: édition de sorts d'Actor
L'édition était impossible parce que le formData ne contient pas
de noeud system, mais des propriétés 'system.portee', ...
2022-10-21 02:41:32 +02:00
e4f9b0f589 New 10.0.29 release 2022-10-19 07:43:10 +02:00
975e525fd5 Merge pull request 'v10.0.29: Fix empilement' (#566) from VincentVk/foundryvtt-reve-de-dragon:v10 into v10
Reviewed-on: #566
2022-10-19 07:41:55 +02:00
Vincent Vandemeulebrouck
296bff2c5d v10.0.29
Fix de l'empilement
2022-10-17 21:21:45 +02:00
Vincent Vandemeulebrouck
3e65bcb848 Fix: empilement de nouveau possible
Les objets empilables peuvent de nouveau être empilés.

Un message indique en cas de drop sur un objet non empilable qui
n'est pas un conteneur que l'objet est déplacé dans le conteneur parent
ou dans les objets portés.
2022-10-17 21:20:52 +02:00
8bb2afe83e Merge pull request 'Bugfixes' (#565) from VincentVk/foundryvtt-reve-de-dragon:v10 into v10
Reviewed-on: #565
2022-10-14 22:52:08 +02:00
Vincent Vandemeulebrouck
37e5b3c0aa Version 10.0.28 2022-10-14 21:47:34 +02:00
Vincent Vandemeulebrouck
e1aecb05c3 Fix: Organisation boutons/messages d'équipement
Le message de surencombrement rendait la présentation moche
2022-10-14 00:58:26 +02:00
Vincent Vandemeulebrouck
168127d8fe Fix: tirage dans une table ne fonctionnait plus
Régression bête, qui empêchait aussi d'afficher le résultat d'un échec
contre un rêve de dragon
2022-10-14 00:48:05 +02:00
Vincent Vandemeulebrouck
21ec043e98 Fix: alignement des queues avec le reste
Sans l'onglet Haut rêve, les queues n'étaient pas bien alignées.
2022-10-14 00:46:42 +02:00
Vincent Vandemeulebrouck
00b3b7f9b3 Fix: Affichage ajustement encaissement
Pour les encaissements hors combat, rappel de l'ajustement
d'encaissement choisi
2022-10-14 00:45:53 +02:00
Vincent Vandemeulebrouck
d1be242791 Minor: optimisation de monnaies
pas d'updates pour les monnaies non affectées
2022-10-14 00:43:37 +02:00
Vincent Vandemeulebrouck
fa75828bc1 Fix: régression lancer de sorts
A cause du duplicate, les voies n'étaient plus des RdDItem, du coup,
la méthode isCompetence de la recherche de compétences ne marche
pas...

Et le duplicate était inutile de toutes façons.
2022-10-14 00:42:35 +02:00
14 changed files with 109 additions and 87 deletions

View File

@@ -393,7 +393,7 @@ export class RdDActor extends Actor {
potionImg: potion.img potionImg: potion.img
} }
ChatMessage.create({ ChatMessage.create({
whisper: ChatUtility.getWhisperRecipientsAndGMs(game.user.name), whisper: ChatUtility.getWhisperRecipientsAndGMs(this.name),
content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-potionenchantee-chateaudormant.html`, messageData) content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-potionenchantee-chateaudormant.html`, messageData)
}); });
} }
@@ -801,7 +801,7 @@ export class RdDActor extends Actor {
rollData.poesie = await Poetique.getExtrait(); rollData.poesie = await Poetique.getExtrait();
ChatMessage.create({ ChatMessage.create({
whisper: ChatUtility.getWhisperRecipientsAndGMs(game.user.name), whisper: ChatUtility.getWhisperRecipientsAndGMs(this.name),
content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-resultat-reve-de-dragon.html`, rollData) content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-resultat-reve-de-dragon.html`, rollData)
}); });
} }
@@ -946,7 +946,7 @@ export class RdDActor extends Actor {
message += "<br>" + troncName; message += "<br>" + troncName;
} }
ChatMessage.create({ ChatMessage.create({
whisper: ChatMessage.getWhisperRecipients(game.user.name), whisper: ChatMessage.getWhisperRecipients(this.name),
content: message content: message
}); });
} }
@@ -1187,8 +1187,8 @@ export class RdDActor extends Actor {
const src = this.getObjet(srcId); const src = this.getObjet(srcId);
const dest = this.getObjet(destId); const dest = this.getObjet(destId);
const cible = this.getContenantOrParent(dest); const cible = this.getContenantOrParent(dest);
const messageEquipementDifferent = item.messageEquipementDifferent(dest); const [empilable, message] = item.isEquipementEmpilable(dest);
if (dest && !messageEquipementDifferent) { if (empilable) {
await this.regrouperEquipementsSimilaires(item, dest); await this.regrouperEquipementsSimilaires(item, dest);
result = false; result = false;
} }
@@ -1196,9 +1196,11 @@ export class RdDActor extends Actor {
else if (!cible || this.conteneurPeutContenir(cible, item)) { else if (!cible || this.conteneurPeutContenir(cible, item)) {
await this.enleverDeConteneur(item, src, params.onEnleverConteneur); await this.enleverDeConteneur(item, src, params.onEnleverConteneur);
await this.ajouterDansConteneur(item, cible, params.onAjouterDansConteneur); await this.ajouterDansConteneur(item, cible, params.onAjouterDansConteneur);
} if (message && !dest.isConteneur()) {
else { ui.notifications.info(cible
ui.notifications.info(messageEquipementDifferent); ? `${message}<br>${item.name} a été déplacé dans: ${cible.name}`
: `${message}<br>${item.name} a été sorti du conteneur`);
}
} }
} }
} }
@@ -1424,9 +1426,21 @@ export class RdDActor extends Actor {
/* -------------------------------------------- */ /* -------------------------------------------- */
async actionRefoulement(item) { async actionRefoulement(item) {
const refoulement = item?.system.refoulement ?? 0; const refoulement = item?.system.refoulement ?? 0;
if (refoulement>0){ if (refoulement>0) {
await this.ajouterRefoulement(refoulement); RdDConfirm.confirmer({
await item.delete(); settingConfirmer: "confirmation-refouler",
content: `<p>Prennez-vous le risque de refouler ${item.name} pour ${refoulement} points de refoulement ?</p>`,
title: 'Confirmer la refoulement',
buttonLabel: 'Refouler',
onAction: async () => {
ChatMessage.create({
whisper: ChatUtility.getWhisperRecipientsAndGMs(this.name),
content: `${this.name} a refoulé une queue ${item.nname} pour ${refoulement} points de refoulement`
});
await this.ajouterRefoulement(refoulement);
await item.delete();
}
})
} }
} }
@@ -1449,7 +1463,7 @@ export class RdDActor extends Actor {
await this.createEmbeddedDocuments('Item', [souffle]); await this.createEmbeddedDocuments('Item', [souffle]);
if (options.chat) { if (options.chat) {
ChatMessage.create({ ChatMessage.create({
whisper: ChatUtility.getWhisperRecipientsAndGMs(game.user.name), whisper: ChatUtility.getWhisperRecipientsAndGMs(this.name),
content: this.name + " subit un Souffle de Dragon : " + souffle.name content: this.name + " subit un Souffle de Dragon : " + souffle.name
}); });
} }
@@ -1469,7 +1483,7 @@ export class RdDActor extends Actor {
await this.createEmbeddedDocuments('Item', [queue]); await this.createEmbeddedDocuments('Item', [queue]);
if (options.chat) { if (options.chat) {
ChatMessage.create({ ChatMessage.create({
whisper: ChatUtility.getWhisperRecipientsAndGMs(game.user.name), whisper: ChatUtility.getWhisperRecipientsAndGMs(this.name),
content: this.name + " subit une Queue de Dragon : " + queue.name content: this.name + " subit une Queue de Dragon : " + queue.name
}); });
} }
@@ -1507,7 +1521,7 @@ export class RdDActor extends Actor {
let tmr = await TMRUtility.getTMRAleatoire(tmr => accessible(tmr) && !innaccessible.includes(tmr.coord)); let tmr = await TMRUtility.getTMRAleatoire(tmr => accessible(tmr) && !innaccessible.includes(tmr.coord));
ChatMessage.create({ ChatMessage.create({
content: `${raison} : ré-insertion aléatoire.`, content: `${raison} : ré-insertion aléatoire.`,
whisper: ChatUtility.getWhisperRecipientsAndGMs(game.user.name) whisper: ChatUtility.getWhisperRecipientsAndGMs(this.name)
}); });
await this.forcerPositionTMRInconnue(tmr); await this.forcerPositionTMRInconnue(tmr);
return tmr; return tmr;
@@ -1677,7 +1691,7 @@ export class RdDActor extends Actor {
const result = await this._jetEndurance(this.system.sante.endurance.value) const result = await this._jetEndurance(this.system.sante.endurance.value)
const message = { const message = {
content: "Jet d'Endurance : " + result.roll.total + " / " + endurance + "<br>", content: "Jet d'Endurance : " + result.roll.total + " / " + endurance + "<br>",
whisper: ChatMessage.getWhisperRecipients(game.user.name) whisper: ChatMessage.getWhisperRecipients(this.name)
}; };
if (result.sonne) { if (result.sonne) {
message.content += `${this.name} a échoué son Jet d'Endurance et devient Sonné`; message.content += `${this.name} a échoué son Jet d'Endurance et devient Sonné`;
@@ -1727,7 +1741,7 @@ export class RdDActor extends Actor {
} }
const message = { const message = {
content: msgText, content: msgText,
whisper: ChatMessage.getWhisperRecipients(game.user.name) whisper: ChatMessage.getWhisperRecipients(this.name)
}; };
ChatMessage.create(message); ChatMessage.create(message);
} }
@@ -1836,7 +1850,7 @@ export class RdDActor extends Actor {
const jetMoral = await this._jetDeMoral(situation); const jetMoral = await this._jetDeMoral(situation);
const finMessage = (jetMoral.succes ? messageReussi : messageManque) ?? (jetMoral.ajustement == 0 ? "Vous gardez votre moral" : jetMoral.ajustement > 0 ? "Vous gagnez du moral" : "Vous perdez du moral"); const finMessage = (jetMoral.succes ? messageReussi : messageManque) ?? (jetMoral.ajustement == 0 ? "Vous gardez votre moral" : jetMoral.ajustement > 0 ? "Vous gagnez du moral" : "Vous perdez du moral");
ChatMessage.create({ ChatMessage.create({
whisper: ChatUtility.getWhisperRecipientsAndGMs(game.user.name), whisper: ChatUtility.getWhisperRecipientsAndGMs(this.name),
content: `${finMessage} - jet ${jetMoral.succes ? "réussi" : "manqué"} en situation ${situation} (${jetMoral.jet}/${jetMoral.difficulte}).` content: `${finMessage} - jet ${jetMoral.succes ? "réussi" : "manqué"} en situation ${situation} (${jetMoral.jet}/${jetMoral.difficulte}).`
}); });
return jetMoral.ajustement; return jetMoral.ajustement;
@@ -2131,7 +2145,7 @@ export class RdDActor extends Actor {
}; };
ChatMessage.create({ ChatMessage.create({
whisper: ChatUtility.getWhisperRecipientsAndGMs(game.user.name), whisper: ChatUtility.getWhisperRecipientsAndGMs(this.name),
content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-resultat-transformer-stress.html`, stressRollData) content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-resultat-transformer-stress.html`, stressRollData)
}); });
@@ -2293,12 +2307,7 @@ export class RdDActor extends Actor {
/* -------------------------------------------- */ /* -------------------------------------------- */
computeDraconicAndSortIndex(sortList) { computeDraconicAndSortIndex(sortList) {
let draconicList = this.getDraconicList() let draconicList = this.getDraconicList();
.map(it => {
it = duplicate(it)
it.system.defaut_carac = "reve";
return it;
});
for (let sort of sortList) { for (let sort of sortList) {
let draconicsSort = this.getDraconicsSort(draconicList, sort).map(it => it.name); let draconicsSort = this.getDraconicsSort(draconicList, sort).map(it => it.name);
for (let index = 0; index < draconicList.length && sort.system.listIndex == undefined; index++) { for (let index = 0; index < draconicList.length && sort.system.listIndex == undefined; index++) {
@@ -2387,7 +2396,7 @@ export class RdDActor extends Actor {
} }
ChatMessage.create({ ChatMessage.create({
content: "Vous êtes sous le coup d'une Mauvaise Rencontre en Persective." + addMsg, content: "Vous êtes sous le coup d'une Mauvaise Rencontre en Persective." + addMsg,
whisper: ChatMessage.getWhisperRecipients(game.user.name) whisper: ChatMessage.getWhisperRecipients(this.name)
}); });
} }
return rencSpecial; return rencSpecial;
@@ -2399,7 +2408,7 @@ export class RdDActor extends Actor {
if (countInertieDraconique > 0) { if (countInertieDraconique > 0) {
ChatMessage.create({ ChatMessage.create({
content: `Vous êtes sous le coup d'Inertie Draconique : vous perdrez ${countInertieDraconique + 1} cases de Fatigue par déplacement au lieu d'une.`, content: `Vous êtes sous le coup d'Inertie Draconique : vous perdrez ${countInertieDraconique + 1} cases de Fatigue par déplacement au lieu d'une.`,
whisper: ChatMessage.getWhisperRecipients(game.user.name) whisper: ChatMessage.getWhisperRecipients(this.name)
}); });
} }
return countInertieDraconique + 1; return countInertieDraconique + 1;
@@ -2411,7 +2420,7 @@ export class RdDActor extends Actor {
await this.reveActuelIncDec(-1); await this.reveActuelIncDec(-1);
ChatMessage.create({ ChatMessage.create({
content: "Vous êtes sous le coup d'un Péage : l'entrée sur cette case vous a coûté 1 Point de Rêve (déduit automatiquement).", content: "Vous êtes sous le coup d'un Péage : l'entrée sur cette case vous a coûté 1 Point de Rêve (déduit automatiquement).",
whisper: ChatMessage.getWhisperRecipients(game.user.name) whisper: ChatMessage.getWhisperRecipients(this.name)
}); });
} }
} }
@@ -3018,7 +3027,7 @@ export class RdDActor extends Actor {
// Cas de désir lancinant, pas d'expérience sur particulière // Cas de désir lancinant, pas d'expérience sur particulière
ChatMessage.create({ ChatMessage.create({
content: `Vous souffrez au moins d'un Désir Lancinant, vous ne pouvez pas gagner d'expérience sur une Particulière tant que le désir n'est pas assouvi`, content: `Vous souffrez au moins d'un Désir Lancinant, vous ne pouvez pas gagner d'expérience sur une Particulière tant que le désir n'est pas assouvi`,
whisper: ChatMessage.getWhisperRecipients(game.user.name) whisper: ChatMessage.getWhisperRecipients(this.name)
}); });
return undefined; return undefined;
} }
@@ -3148,7 +3157,7 @@ export class RdDActor extends Actor {
if (countMonteeLaborieuse > 0) { if (countMonteeLaborieuse > 0) {
ChatMessage.create({ ChatMessage.create({
content: `Vous êtes sous le coup d'une Montée Laborieuse : vos montées en TMR coûtent ${countMonteeLaborieuse} Point de Rêve de plus.`, content: `Vous êtes sous le coup d'une Montée Laborieuse : vos montées en TMR coûtent ${countMonteeLaborieuse} Point de Rêve de plus.`,
whisper: ChatMessage.getWhisperRecipients(game.user.name) whisper: ChatMessage.getWhisperRecipients(this.name)
}); });
} }
return countMonteeLaborieuse; return countMonteeLaborieuse;
@@ -3188,7 +3197,7 @@ export class RdDActor extends Actor {
if (this.getReveActuel() < minReveValue) { if (this.getReveActuel() < minReveValue) {
ChatMessage.create({ ChatMessage.create({
content: `Vous n'avez les ${minReveValue} Points de Reve nécessaires pour monter dans les Terres Médianes`, content: `Vous n'avez les ${minReveValue} Points de Reve nécessaires pour monter dans les Terres Médianes`,
whisper: ChatMessage.getWhisperRecipients(game.user.name) whisper: ChatMessage.getWhisperRecipients(this.name)
}); });
return; return;
} }
@@ -3706,7 +3715,7 @@ export class RdDActor extends Actor {
system: mergeObject(vente.item.system, { quantite: isItemEmpilable ? achat.quantiteTotal : undefined }), system: mergeObject(vente.item.system, { quantite: isItemEmpilable ? achat.quantiteTotal : undefined }),
} }
let listeAchat = isItemEmpilable ? [achatData] : Array.from({ length: achat.quantiteTotal }, (_, i) => achatData) let listeAchat = isItemEmpilable ? [achatData] : Array.from({ length: achat.quantiteTotal }, (_, i) => achatData)
let items = await acheteur.createEmbeddedDocuments("Item", listeAchat) let items = await acheteur.createEmbeddedDocuments("Item", listeAchat);
if (achat.choix.consommer && vente.item.type == 'nourritureboisson') { if (achat.choix.consommer && vente.item.type == 'nourritureboisson') {
achat.choix.doses = achat.choix.nombreLots; achat.choix.doses = achat.choix.nombreLots;
await acheteur.consommerNourritureboisson(items[0], achat.choix); await acheteur.consommerNourritureboisson(items[0], achat.choix);
@@ -3934,7 +3943,7 @@ export class RdDActor extends Actor {
this.bonusRecuperationPotion = potionData.system.herbeBonus; this.bonusRecuperationPotion = potionData.system.herbeBonus;
} }
ChatMessage.create({ ChatMessage.create({
whisper: ChatUtility.getWhisperRecipientsAndGMs(game.user.name), whisper: ChatUtility.getWhisperRecipientsAndGMs(this.name),
content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-consommer-potion-soin.html`, potionData) content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-consommer-potion-soin.html`, potionData)
}); });
} }
@@ -3967,7 +3976,7 @@ export class RdDActor extends Actor {
this.bonusRepos = potionData.system.herbeBonus; this.bonusRepos = potionData.system.herbeBonus;
} }
ChatMessage.create({ ChatMessage.create({
whisper: ChatUtility.getWhisperRecipientsAndGMs(game.user.name), whisper: ChatUtility.getWhisperRecipientsAndGMs(this.name),
content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-consommer-potion-repos.html`, potionData) content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-consommer-potion-repos.html`, potionData)
}); });
} }
@@ -4005,7 +4014,7 @@ export class RdDActor extends Actor {
this.diminuerQuantiteObjet(herbeData._id, herbeData.nbBrins); this.diminuerQuantiteObjet(herbeData._id, herbeData.nbBrins);
ChatMessage.create({ ChatMessage.create({
whisper: ChatUtility.getWhisperRecipientsAndGMs(game.user.name), whisper: ChatUtility.getWhisperRecipientsAndGMs(this.name),
content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-fabriquer-potion-base.html`, messageData) content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-fabriquer-potion-base.html`, messageData)
}); });
} }
@@ -4030,7 +4039,7 @@ export class RdDActor extends Actor {
} }
} }
ChatMessage.create({ ChatMessage.create({
whisper: ChatUtility.getWhisperRecipientsAndGMs(game.user.name), whisper: ChatUtility.getWhisperRecipientsAndGMs(this.name),
content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-consommer-potion-generique.html`, potionData) content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-consommer-potion-generique.html`, potionData)
}); });
} }
@@ -4165,7 +4174,7 @@ export class RdDActor extends Actor {
/* -------------------------------------------- */ /* -------------------------------------------- */
notifyGestionTeteSouffleQueue(item, manualMessage = true) { notifyGestionTeteSouffleQueue(item, manualMessage = true) {
ChatMessage.create({ ChatMessage.create({
whisper: ChatUtility.getWhisperRecipientsAndGMs(game.user.name), whisper: ChatUtility.getWhisperRecipientsAndGMs(this.name),
content: `${this.name} a reçu un/une ${item.type}: ${item.name}, qui ${manualMessage ? "n'est pas" : "est"} géré(e) automatiquement. ${manualMessage ? manualMessage : ''}` content: `${this.name} a reçu un/une ${item.type}: ${item.name}, qui ${manualMessage ? "n'est pas" : "est"} géré(e) automatiquement. ${manualMessage ? manualMessage : ''}`
}); });
} }

View File

@@ -84,7 +84,10 @@ export class RdDItemCompetence extends Item {
/* -------------------------------------------- */ /* -------------------------------------------- */
static getVoieDraconic(competences, voie) { static getVoieDraconic(competences, voie) {
return RdDItemCompetence.findCompetence(competences.filter(it => RdDItemCompetence.isDraconic(it)), voie); return RdDItemCompetence.findFirstItem(competences, voie, {
preFilter: it => it.isCompetence() && RdDItemCompetence.isDraconic(it),
description: 'Draconic',
});
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
@@ -219,9 +222,8 @@ export class RdDItemCompetence extends Item {
if (idOrName == undefined) { if (idOrName == undefined) {
return undefined; return undefined;
} }
options = mergeObject(options, { preFilter: it => it.isCompetence(), description: 'compétence', }); options = mergeObject(options, { preFilter: it => it.isCompetence(), description: 'compétence' }, {overwrite: false});
return list.find(it => it.id == idOrName && it.isCompetence()) return RdDItemCompetence.findFirstItem(list, idOrName, options);
?? Misc.findFirstLike(idOrName, list, options);
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
@@ -229,6 +231,11 @@ export class RdDItemCompetence extends Item {
return Misc.findAllLike(name, list, { filter: it => it.isCompetence(), description: 'compétence' }); return Misc.findAllLike(name, list, { filter: it => it.isCompetence(), description: 'compétence' });
} }
static findFirstItem(list, idOrName, options) {
return list.find(it => it.id == idOrName && options.preFilter(it))
?? Misc.findFirstLike(idOrName, list, options);
}
/* -------------------------------------------- */ /* -------------------------------------------- */
static getCompetenceNextXp(niveau) { static getCompetenceNextXp(niveau) {
return RdDItemCompetence.getCompetenceXp(niveau + 1); return RdDItemCompetence.getCompetenceXp(niveau + 1);

View File

@@ -71,9 +71,12 @@ export class Monnaie {
let updates = []; let updates = [];
let parValeur = Misc.classifyFirst(monnaies, it => it.system.valeur_deniers); let parValeur = Misc.classifyFirst(monnaies, it => it.system.valeur_deniers);
for (let valeur of [1000, 100, 10, 1]) { for (let valeur of [1000, 100, 10, 1]) {
if (parValeur[valeur]) { const itemPiece = parValeur[valeur];
const piecesDeCetteValeur = Math.floor(reste / valeur); const piecesDeCetteValeur = Math.floor(reste / valeur);
updates.push({ _id: parValeur[valeur].id, 'system.quantite': piecesDeCetteValeur }); if (itemPiece) {
if (piecesDeCetteValeur != itemPiece.system.quantite) {
updates.push({ _id: parValeur[valeur].id, 'system.quantite': piecesDeCetteValeur });
}
reste -= piecesDeCetteValeur*valeur; reste -= piecesDeCetteValeur*valeur;
} }
} }

View File

@@ -250,9 +250,9 @@ export class RdDItemSheet extends ItemSheet {
/* -------------------------------------------- */ /* -------------------------------------------- */
/** @override */ /** @override */
_updateObject(event, formData) { // Deprecated en v0.8 à clarifier _updateObject(event, formData) {
// Données de bonus de cases ? // Données de bonus de cases ?
formData = RdDItemSort.buildBonusCaseStringFromFormData(formData); formData['system.bonuscase'] = RdDItemSort.buildBonusCaseStringFromFormData(formData.bonusValue, formData.caseValue);
return this.item.update(formData); return this.item.update(formData);
} }

View File

@@ -63,26 +63,21 @@ export class RdDItemSort extends Item {
/** Met à jour les données de formulaire /** Met à jour les données de formulaire
* si static des bonus de cases sont présents * si static des bonus de cases sont présents
* */ * */
static buildBonusCaseStringFromFormData( formData ) { static buildBonusCaseStringFromFormData( bonuses, cases ) {
if ( formData.bonusValue ) { if ( bonuses ) {
let list = []; let list = [];
let caseCheck = {}; let caseCheck = {};
for(let i=0; i<formData.bonusValue.length; i++) { for (let i=0; i<bonuses.length; i++) {
let coord = formData.caseValue[i] || 'A1'; let coord = cases[i]?.toUpperCase() || 'A1';
coord = coord.toUpperCase(); let bonus = bonuses[i] || 0;
if ( TMRUtility.verifyTMRCoord( coord ) ) { // Sanity check if ( TMRUtility.verifyTMRCoord( coord ) && bonus > 0 && caseCheck[coord] == undefined ) {
let bonus = formData.bonusValue[i] || 0; caseCheck[coord] = bonus;
if ( bonus > 0 && caseCheck[coord] == undefined ) { list.push( coord+":"+bonus );
caseCheck[coord] = bonus;
list.push( coord+":"+bonus );
}
} }
} }
formData.bonusValue = undefined; return list.toString();
formData.caseValue = undefined;
formData.system.bonuscase = list.toString(); // Reset
} }
return formData; return undefined;
} }
/* -------------------------------------------- */ /* -------------------------------------------- */

View File

@@ -242,30 +242,32 @@ export class RdDItem extends Item {
/* -------------------------------------------- */ /* -------------------------------------------- */
// détermine si deux équipements sont similaires: de même type, et avec les même champs hormis la quantité // détermine si deux équipements sont similaires: de même type, et avec les même champs hormis la quantité
messageEquipementDifferent(other) { isEquipementEmpilable(other) {
if (!other || !this.isEquipement()) return undefined; if (!other || !this.isEquipement()) {
return [false, undefined];
}
let message = undefined;
if (this.system.quantite == undefined) { if (this.system.quantite == undefined) {
message = `Impossible de regrouper des ${this.type}, ils ne sont pas empilables`; return [false, `Impossible de regrouper des ${this.type}, ils ne sont pas empilables`];
} }
else if (this.type != other.type) { else if (this.type != other.type) {
message = `Impossible de regrouper des ${this.type} avec des ${other.type}`; return [false, `Impossible de regrouper des ${this.type} avec des ${other.type}`];
} }
else if (this.name != other.name) { else if (this.name != other.name) {
message = `Impossible de regrouper ${this.name} avec ${other.name}`; return [false, `Impossible de regrouper ${this.name} avec ${other.name}`];
} }
else { else {
const differences = Object.entries(this.system) const differences = Object.entries(this.system)
.filter(([key, value]) => !['quantite', 'cout'].includes(key) && value != other.system[key]); .filter(([key, value]) => !['quantite', 'cout', 'encTotal'].includes(key) && value != other.system[key]);
if (differences.length > 0) { if (differences.length > 0) {
message = `Impossible de regrouper les ${this.type} ${this.name}: `; let message = `Impossible de regrouper les ${this.type} ${this.name}: `;
for (const [key, value] of differences) { for (const [key, value] of differences) {
message += `<br>${key}: ${value} vs ${other.system[key]}`; message += `<br>${key}: ${value} vs ${other.system[key]}`;
} }
return [false, message];
} }
} }
return message; return [true, undefined];
} }
async proposerVente() { async proposerVente() {

View File

@@ -148,7 +148,7 @@ Hooks.once("init", async function () {
}; };
/* -------------------------------------------- */ /* -------------------------------------------- */
game.socket.on(SYSTEM_SOCKET_ID, sockmsg => { game.socket.on(SYSTEM_SOCKET_ID, async (sockmsg) => {
console.log(">>>>> MSG RECV", sockmsg); console.log(">>>>> MSG RECV", sockmsg);
try { try {
RdDUtility.onSocketMessage(sockmsg); RdDUtility.onSocketMessage(sockmsg);

View File

@@ -51,6 +51,7 @@ export class RdDEncaisser extends Dialog {
this.actor.encaisserDommages({ this.actor.encaisserDommages({
dmg: { dmg: {
total: Number(this.modifier), total: Number(this.modifier),
ajustement: Number(this.modifier),
encaisserSpecial: this.encaisserSpecial, encaisserSpecial: this.encaisserSpecial,
loc: { result: 0, label: "" }, loc: { result: 0, label: "" },
mortalite: mortalite mortalite: mortalite

View File

@@ -2,14 +2,14 @@ export class RdDRollTables {
/* -------------------------------------------- */ /* -------------------------------------------- */
static async genericGetTableResult(tableName, toChat) { static async genericGetTableResult(tableName, toChat) {
let table = RdDRollTables.getWorldTable() ?? (await RdDRollTables.getSystemTable(tableName)); let table = RdDRollTables.getWorldTable(tableName) ?? (await RdDRollTables.getSystemTable(tableName));
const draw = await table.draw({ displayChat: toChat, rollMode: "gmroll"}); const draw = await table.draw({ displayChat: toChat, rollMode: "gmroll"});
//console.log("RdDRollTables", tableName, toChat, ":", draw); //console.log("RdDRollTables", tableName, toChat, ":", draw);
return draw.results.length > 0 ? draw.results[0] : undefined; return draw.results.length > 0 ? draw.results[0] : undefined;
} }
static getWorldTable() { static getWorldTable(tableName) {
return game.tables.find(table => table.name.toLowerCase() == tableName.toLowerCase()); return game.tables.find(table => table.name.toLowerCase() == tableName.toLowerCase());
} }

View File

@@ -18,8 +18,9 @@ const listeReglesOptionelles = [
{ group: 'Règles générales', name: 'appliquer-fatigue', descr: "Appliquer les règles de fatigue"}, { group: 'Règles générales', name: 'appliquer-fatigue', descr: "Appliquer les règles de fatigue"},
{ group: 'Règles générales', name: 'afficher-colonnes-reussite', descr: "Afficher le nombre de colonnes de réussite ou d'échec", default: false }, { group: 'Règles générales', name: 'afficher-colonnes-reussite', descr: "Afficher le nombre de colonnes de réussite ou d'échec", default: false },
{ 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"},
{ group: 'Confirmations', name: 'confirmation-vider', descr: "Confirmer pour vider l'équipement", scope: "client"}, { group: 'Confirmations', name: 'confirmation-refouler', descr: "Confirmer avant de refouler", scope: "client"},
{ group: 'Confirmations', name: 'confirmation-vider', descr: "Confirmer pour vider l'équipement", scope: "client"},
{ group: 'Confirmations', name: 'confirmation-supprimer-lien-acteur', descr: "Confirmer pour détacher un animal/suivant/véhicule", scope: "client"}, { group: 'Confirmations', name: 'confirmation-supprimer-lien-acteur', descr: "Confirmer pour détacher un animal/suivant/véhicule", scope: "client"},
{ group: 'Confirmations', name: 'confirmation-supprimer-equipement', descr: "Confirmer la suppression des équipements", scope: "client"}, { group: 'Confirmations', name: 'confirmation-supprimer-equipement', descr: "Confirmer la suppression des équipements", scope: "client"},
{ group: 'Confirmations', name: 'confirmation-supprimer-oeuvre', descr: "Confirmer la suppression des oeuvres", scope: "client"}, { group: 'Confirmations', name: 'confirmation-supprimer-oeuvre', descr: "Confirmer la suppression des oeuvres", scope: "client"},

View File

@@ -1,6 +1,14 @@
{ {
"id": "foundryvtt-reve-de-dragon", "id": "foundryvtt-reve-de-dragon",
"title": "Rêve de Dragon", "title": "Rêve de Dragon",
"version": "10.0.30",
"download": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/archive/foundryvtt-reve-de-dragon-10.0.30.zip",
"manifest": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/raw/v10/system.json",
"compatibility": {
"minimum": "10",
"verified": "10",
"maximum": "10"
},
"description": "Rêve de Dragon RPG for FoundryVTT", "description": "Rêve de Dragon RPG for FoundryVTT",
"authors": [ "authors": [
{ {
@@ -34,11 +42,6 @@
], ],
"url": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/", "url": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/",
"license": "LICENSE.txt", "license": "LICENSE.txt",
"version": "10.0.27",
"compatibility": {
"minimum": "10",
"verified": "10.287"
},
"esmodules": [ "esmodules": [
"module/rdd-main.js" "module/rdd-main.js"
], ],
@@ -332,8 +335,6 @@
} }
], ],
"socket": true, "socket": true,
"manifest": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/raw/v10/system.json",
"download": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/archive/foundryvtt-reve-de-dragon-10.0.27.zip",
"gridDistance": 1, "gridDistance": 1,
"gridUnits": "m", "gridUnits": "m",
"primaryTokenAttribute": "sante.vie", "primaryTokenAttribute": "sante.vie",

View File

@@ -4,7 +4,7 @@
{{#if (and queues.length ombres.length)}} et {{/if}} {{#if (and queues.length ombres.length)}} et {{/if}}
{{#if ombres.length}}Ombres de Thanatos{{/if}} {{#if ombres.length}}Ombres de Thanatos{{/if}}
</h3> </h3>
<ul class="flex-group-left"> <ul class="item-list">
{{#each queues as |queue key|}} {{#each queues as |queue key|}}
{{> "systems/foundryvtt-reve-de-dragon/templates/actor/dragon-queue.html" queue=queue key=key}} {{> "systems/foundryvtt-reve-de-dragon/templates/actor/dragon-queue.html" queue=queue key=key}}
{{/each}} {{/each}}

View File

@@ -2,15 +2,15 @@
<h4>Equipement</h4> <h4>Equipement</h4>
<span class="item-name"> <span class="item-name">
Encombrement: {{numberFormat calc.encTotal decimals=2}} (max: {{system.attributs.encombrement.value}}){{#if calc.surEncombrementMessage}}<b>{{calc.surEncombrementMessage}}</b>{{/if}}
{{#if (regle-optionnelle 'afficher-prix-joueurs')}}
&hyphen; Valeur: {{numberFormat calc.prixTotalEquipement decimals=2}} Sols
{{/if}}
&hyphen;
<a class="chat-card-button creer-un-objet">Nouvel objet</a> <a class="chat-card-button creer-un-objet">Nouvel objet</a>
{{#if options.isGM}} {{#if options.isGM}}
<a class="chat-card-button nettoyer-conteneurs">Tout vider</a> <a class="chat-card-button nettoyer-conteneurs">Tout vider</a>
{{/if}} {{/if}}
{{#if calc.surEncombrementMessage}}<b>{{calc.surEncombrementMessage}}</b> &hyphen;{{/if}}
Encombrement: {{numberFormat calc.encTotal decimals=2}} (max: {{system.attributs.encombrement.value}})
{{#if (regle-optionnelle 'afficher-prix-joueurs')}}
&hyphen; Valeur: {{numberFormat calc.prixTotalEquipement decimals=2}} Sols
{{/if}}
</span> </span>
<ul class="item-list alterne-list"> <ul class="item-list alterne-list">
<li class="competence-header flexrow"> <li class="competence-header flexrow">

View File

@@ -19,6 +19,9 @@
<div>Pénétration: -{{rollData.dmg.penetration}}</div> <div>Pénétration: -{{rollData.dmg.penetration}}</div>
{{/if}} {{/if}}
<hr> <hr>
{{#if encaissement.dmg.total}}
<div>+dom encaissement: {{numberFormat rollData.dmg.total decimals=0 sign=true}}</div>
{{/if}}
{{#if rollData.dmg.dmgArme}} {{#if rollData.dmg.dmgArme}}
<div>+dom arme: {{numberFormat rollData.dmg.dmgArme decimals=0 sign=true}}</div> <div>+dom arme: {{numberFormat rollData.dmg.dmgArme decimals=0 sign=true}}</div>
{{/if}} {{/if}}