Compare commits

..

11 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: public/foundryvtt-reve-de-dragon#567
2022-10-21 22:18:05 +02:00
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
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
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
32af9bf1b4 Ajout de confirmation pour refoulement 2022-10-21 02:41:32 +02:00
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: public/foundryvtt-reve-de-dragon#566
2022-10-19 07:41:55 +02:00
296bff2c5d v10.0.29
Fix de l'empilement
2022-10-17 21:21:45 +02:00
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: public/foundryvtt-reve-de-dragon#565
2022-10-14 22:52:08 +02:00
7 changed files with 76 additions and 63 deletions

View File

@ -393,7 +393,7 @@ export class RdDActor extends Actor {
potionImg: potion.img
}
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)
});
}
@ -801,7 +801,7 @@ export class RdDActor extends Actor {
rollData.poesie = await Poetique.getExtrait();
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)
});
}
@ -946,7 +946,7 @@ export class RdDActor extends Actor {
message += "<br>" + troncName;
}
ChatMessage.create({
whisper: ChatMessage.getWhisperRecipients(game.user.name),
whisper: ChatMessage.getWhisperRecipients(this.name),
content: message
});
}
@ -1187,8 +1187,8 @@ export class RdDActor extends Actor {
const src = this.getObjet(srcId);
const dest = this.getObjet(destId);
const cible = this.getContenantOrParent(dest);
const messageEquipementDifferent = item.messageEquipementDifferent(dest);
if (dest && !messageEquipementDifferent) {
const [empilable, message] = item.isEquipementEmpilable(dest);
if (empilable) {
await this.regrouperEquipementsSimilaires(item, dest);
result = false;
}
@ -1196,9 +1196,11 @@ export class RdDActor extends Actor {
else if (!cible || this.conteneurPeutContenir(cible, item)) {
await this.enleverDeConteneur(item, src, params.onEnleverConteneur);
await this.ajouterDansConteneur(item, cible, params.onAjouterDansConteneur);
}
else {
ui.notifications.info(messageEquipementDifferent);
if (message && !dest.isConteneur()) {
ui.notifications.info(cible
? `${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) {
const refoulement = item?.system.refoulement ?? 0;
if (refoulement>0){
await this.ajouterRefoulement(refoulement);
await item.delete();
if (refoulement>0) {
RdDConfirm.confirmer({
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]);
if (options.chat) {
ChatMessage.create({
whisper: ChatUtility.getWhisperRecipientsAndGMs(game.user.name),
whisper: ChatUtility.getWhisperRecipientsAndGMs(this.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]);
if (options.chat) {
ChatMessage.create({
whisper: ChatUtility.getWhisperRecipientsAndGMs(game.user.name),
whisper: ChatUtility.getWhisperRecipientsAndGMs(this.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));
ChatMessage.create({
content: `${raison} : ré-insertion aléatoire.`,
whisper: ChatUtility.getWhisperRecipientsAndGMs(game.user.name)
whisper: ChatUtility.getWhisperRecipientsAndGMs(this.name)
});
await this.forcerPositionTMRInconnue(tmr);
return tmr;
@ -1677,7 +1691,7 @@ export class RdDActor extends Actor {
const result = await this._jetEndurance(this.system.sante.endurance.value)
const message = {
content: "Jet d'Endurance : " + result.roll.total + " / " + endurance + "<br>",
whisper: ChatMessage.getWhisperRecipients(game.user.name)
whisper: ChatMessage.getWhisperRecipients(this.name)
};
if (result.sonne) {
message.content += `${this.name} a échoué son Jet d'Endurance et devient Sonné`;
@ -1727,7 +1741,7 @@ export class RdDActor extends Actor {
}
const message = {
content: msgText,
whisper: ChatMessage.getWhisperRecipients(game.user.name)
whisper: ChatMessage.getWhisperRecipients(this.name)
};
ChatMessage.create(message);
}
@ -1836,7 +1850,7 @@ export class RdDActor extends Actor {
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");
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}).`
});
return jetMoral.ajustement;
@ -2131,7 +2145,7 @@ export class RdDActor extends Actor {
};
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)
});
@ -2382,7 +2396,7 @@ export class RdDActor extends Actor {
}
ChatMessage.create({
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;
@ -2394,7 +2408,7 @@ export class RdDActor extends Actor {
if (countInertieDraconique > 0) {
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.`,
whisper: ChatMessage.getWhisperRecipients(game.user.name)
whisper: ChatMessage.getWhisperRecipients(this.name)
});
}
return countInertieDraconique + 1;
@ -2406,7 +2420,7 @@ export class RdDActor extends Actor {
await this.reveActuelIncDec(-1);
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).",
whisper: ChatMessage.getWhisperRecipients(game.user.name)
whisper: ChatMessage.getWhisperRecipients(this.name)
});
}
}
@ -3013,7 +3027,7 @@ export class RdDActor extends Actor {
// Cas de désir lancinant, pas d'expérience sur particulière
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`,
whisper: ChatMessage.getWhisperRecipients(game.user.name)
whisper: ChatMessage.getWhisperRecipients(this.name)
});
return undefined;
}
@ -3143,7 +3157,7 @@ export class RdDActor extends Actor {
if (countMonteeLaborieuse > 0) {
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.`,
whisper: ChatMessage.getWhisperRecipients(game.user.name)
whisper: ChatMessage.getWhisperRecipients(this.name)
});
}
return countMonteeLaborieuse;
@ -3183,7 +3197,7 @@ export class RdDActor extends Actor {
if (this.getReveActuel() < minReveValue) {
ChatMessage.create({
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;
}
@ -3701,7 +3715,7 @@ export class RdDActor extends Actor {
system: mergeObject(vente.item.system, { quantite: isItemEmpilable ? achat.quantiteTotal : undefined }),
}
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') {
achat.choix.doses = achat.choix.nombreLots;
await acheteur.consommerNourritureboisson(items[0], achat.choix);
@ -3929,7 +3943,7 @@ export class RdDActor extends Actor {
this.bonusRecuperationPotion = potionData.system.herbeBonus;
}
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)
});
}
@ -3962,7 +3976,7 @@ export class RdDActor extends Actor {
this.bonusRepos = potionData.system.herbeBonus;
}
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)
});
}
@ -4000,7 +4014,7 @@ export class RdDActor extends Actor {
this.diminuerQuantiteObjet(herbeData._id, herbeData.nbBrins);
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)
});
}
@ -4025,7 +4039,7 @@ export class RdDActor extends Actor {
}
}
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)
});
}
@ -4160,7 +4174,7 @@ export class RdDActor extends Actor {
/* -------------------------------------------- */
notifyGestionTeteSouffleQueue(item, manualMessage = true) {
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 : ''}`
});
}

View File

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

View File

@ -63,26 +63,21 @@ export class RdDItemSort extends Item {
/** Met à jour les données de formulaire
* si static des bonus de cases sont présents
* */
static buildBonusCaseStringFromFormData( formData ) {
if ( formData.bonusValue ) {
static buildBonusCaseStringFromFormData( bonuses, cases ) {
if ( bonuses ) {
let list = [];
let caseCheck = {};
for(let i=0; i<formData.bonusValue.length; i++) {
let coord = formData.caseValue[i] || 'A1';
coord = coord.toUpperCase();
if ( TMRUtility.verifyTMRCoord( coord ) ) { // Sanity check
let bonus = formData.bonusValue[i] || 0;
if ( bonus > 0 && caseCheck[coord] == undefined ) {
caseCheck[coord] = bonus;
list.push( coord+":"+bonus );
}
for (let i=0; i<bonuses.length; i++) {
let coord = cases[i]?.toUpperCase() || 'A1';
let bonus = bonuses[i] || 0;
if ( TMRUtility.verifyTMRCoord( coord ) && bonus > 0 && caseCheck[coord] == undefined ) {
caseCheck[coord] = bonus;
list.push( coord+":"+bonus );
}
}
formData.bonusValue = undefined;
formData.caseValue = undefined;
formData.system.bonuscase = list.toString(); // Reset
return list.toString();
}
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é
messageEquipementDifferent(other) {
if (!other || !this.isEquipement()) return undefined;
isEquipementEmpilable(other) {
if (!other || !this.isEquipement()) {
return [false, undefined];
}
let message = 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) {
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) {
message = `Impossible de regrouper ${this.name} avec ${other.name}`;
return [false, `Impossible de regrouper ${this.name} avec ${other.name}`];
}
else {
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) {
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) {
message += `<br>${key}: ${value} vs ${other.system[key]}`;
}
return [false, message];
}
}
return message;
return [true, undefined];
}
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);
try {
RdDUtility.onSocketMessage(sockmsg);

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: '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-vider', descr: "Confirmer pour vider l'équipement", scope: "client"},
{ group: 'Confirmations', name: 'confirmation-tmr', descr: "Confirmer pour monter dans les TMR", 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-equipement', descr: "Confirmer la suppression des équipements", scope: "client"},
{ group: 'Confirmations', name: 'confirmation-supprimer-oeuvre', descr: "Confirmer la suppression des oeuvres", scope: "client"},

View File

@ -1,12 +1,13 @@
{
"id": "foundryvtt-reve-de-dragon",
"title": "Rêve de Dragon",
"version": "10.0.28",
"download": "https://www.uberwald.me/gitea/VincentVk/foundryvtt-reve-de-dragon/archive/foundryvtt-reve-de-dragon-10.0.28.zip",
"manifest": "https://www.uberwald.me/gitea/VincentVk/foundryvtt-reve-de-dragon/raw/v10/system.json",
"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.288"
"verified": "10",
"maximum": "10"
},
"description": "Rêve de Dragon RPG for FoundryVTT",
"authors": [