diff --git a/module/actor-creature-sheet.js b/module/actor-creature-sheet.js
index e0429e53..beef2d47 100644
--- a/module/actor-creature-sheet.js
+++ b/module/actor-creature-sheet.js
@@ -35,9 +35,6 @@ export class RdDActorCreatureSheet extends RdDActorSheet {
encTotal: await this.actor.computeEncombrementTotalEtMalusArmure(),
}
formData.calc.surEncombrementMessage = (formData.data.compteurs.surenc.value < 0) ? "Sur-Encombrement!" : "";
- formData.options.isGM = game.user.isGM;
-
- formData.data.competencecreature = formData.itemsByType["competencecreature"];
RdDUtility.filterItemsPerTypeForSheet(formData);
RdDUtility.buildArbreDeConteneur(this, formData);
diff --git a/module/actor-entite-sheet.js b/module/actor-entite-sheet.js
index 1b7afc01..41f444c0 100644
--- a/module/actor-entite-sheet.js
+++ b/module/actor-entite-sheet.js
@@ -5,6 +5,7 @@
import { HtmlUtility } from "./html-utility.js";
import { Misc } from "./misc.js";
+import { RdDUtility } from "./rdd-utility.js";
/* -------------------------------------------- */
export class RdDActorEntiteSheet extends ActorSheet {
@@ -31,14 +32,27 @@ export class RdDActorEntiteSheet extends ActorSheet {
/* -------------------------------------------- */
async getData() {
- let formData = super.getData();
+ const objectData = Misc.data(this.object);
+ let formData = {
+ title: this.title,
+ id: objectData.id,
+ type: objectData.type,
+ img: objectData.img,
+ name: objectData.name,
+ // actor: this.object,
+ editable: this.isEditable,
+ cssClass: this.isEditable ? "editable" : "locked",
+ data: foundry.utils.deepClone(Misc.templateData(this.object)),
+ effects: this.object.effects.map(e => foundry.utils.deepClone(e.data)),
+ // items: items,
+ limited: this.object.limited,
+ options: this.options,
+ owner: this.document.isOwner,
+ itemsByType: Misc.classify(this.object.items.map(i => foundry.utils.deepClone(i.data))),
+ };
- formData.itemsByType = Misc.classify(formData.items);
-
formData.options.isGM = game.user.isGM;
-
- formData.data.carac.taille.isTaille = true; // To avoid button link;
- formData.data.competencecreature = formData.itemsByType["competencecreature"];
+ RdDUtility.filterItemsPerTypeForSheet(formData);
return formData;
diff --git a/module/actor-sheet.js b/module/actor-sheet.js
index c14aee91..b0b99090 100644
--- a/module/actor-sheet.js
+++ b/module/actor-sheet.js
@@ -33,7 +33,8 @@ export class RdDActorSheet extends ActorSheet {
/* -------------------------------------------- */
async getData() {
- let formData = super.getData();
+ // 0.8.0
+ const objectData = Misc.data(this.object);
// -------------- version 0.7.9
// let formData = {
// cssClass: this.entity.owner ? "editable" : "locked",
@@ -47,26 +48,50 @@ export class RdDActorSheet extends ActorSheet {
// // Entity data
// formData.actor = formData.entity;
// formData.data = formData.entity.data;
-
+
// // Owned items
// formData.items = formData.actor.items;
// formData.items.sort((a, b) => (a.sort || 0) - (b.sort || 0));
+
+ // -------------- version 0.8.0
+
+ // // Copy and sort Items
+ // items.sort((a, b) => (a.sort || 0) - (b.sort || 0));
+ // data.items = items;
+
+ // // Copy Active Effects
+ // data.effects = effects;
+
+ // // Return template data
+ let formData = {
+ title: this.title,
+ id: objectData.id,
+ type: objectData.type,
+ img: objectData.img,
+ name: objectData.name,
+ // actor: this.object,
+ editable: this.isEditable,
+ cssClass: this.isEditable ? "editable" : "locked",
+ data: foundry.utils.deepClone(Misc.templateData(this.object)),
+ effects: this.object.effects.map(e => foundry.utils.deepClone(e.data)),
+ // items: items,
+ limited: this.object.limited,
+ options: this.options,
+ owner: this.document.isOwner,
+ itemsByType: Misc.classify(this.object.items.map(i => foundry.utils.deepClone(i.data))),
+ };
- formData.itemsByType = Misc.classify(formData.items);
RdDUtility.filterItemsPerTypeForSheet(formData);
formData.options.isGM = game.user.isGM;
- // la taille est la taille: on ne peut pas l'utiliser pour un jet
- formData.data.carac.taille.isTaille = true;
+ if (formData.type == 'creature') return formData; // Shortcut
- if (this.actor.data.type == 'creature') return formData; // Shortcut
+ formData.competenceByCategory = Misc.classify(formData.competences, it => it.data.categorie);
- formData.competenceByCategory = Misc.classify(formData.data.competences, it => it.data.categorie);
-
formData.calc = {
- comptageArchetype: RdDItemCompetence.computeResumeArchetype(formData.data.competences),
- competenceXPTotal: RdDItemCompetence.computeTotalXP(formData.data.competences),
+ comptageArchetype: RdDItemCompetence.computeResumeArchetype(formData.competences),
+ competenceXPTotal: RdDItemCompetence.computeTotalXP(formData.competences),
caracTotal: RdDCarac.computeTotal(formData.data.carac, formData.data.beaute),
// Mise à jour de l'encombrement total et du prix de l'équipement
encTotal: await this.actor.computeEncombrementTotalEtMalusArmure(),
@@ -80,7 +105,7 @@ export class RdDActorSheet extends ActorSheet {
};
formData.calc.surEncombrementMessage = (formData.data.compteurs.surenc.value < 0) ? "Sur-Encombrement!" : "";
- formData.data.competences.forEach(item => {
+ formData.competences.forEach(item => {
item.visible = !this.options.showCompNiveauBase || !RdDItemCompetence.isNiveauBase(item);
RdDItemCompetence.levelUp(item);
});
@@ -91,25 +116,20 @@ export class RdDActorSheet extends ActorSheet {
// toujours avoir une liste d'armes (pour mettre esquive et corps à corps)
- formData.data.combat = duplicate(formData.itemsByType.arme ?? []);
- RdDItemArme.computeNiveauArmes(formData.data.combat, formData.data.competences);
- RdDItemArme.ajoutCorpsACorps(formData.data.combat, formData.data.competences, formData.data.carac );
- formData.esquive = RdDItemCompetence.getEsquive(formData.data.competences);
- formData.data.combat = RdDCombatManager.finalizeArmeList(formData.data.combat, formData.itemsByType.competence, formData.data.carac);
+ formData.combat = duplicate(formData.armes ?? []);
+ RdDItemArme.computeNiveauArmes(formData.combat, formData.competences);
+ RdDItemArme.ajoutCorpsACorps(formData.combat, formData.competences, formData.data.carac);
+ formData.esquive = RdDItemCompetence.getEsquive(formData.competences);
+ formData.combat = RdDCombatManager.finalizeArmeList(formData.combat, formData.competences, formData.data.carac);
-
- this.armesList = formData.data.combat;
-
- // Mise à jour de l'encombrement total et du prix de l'équipement
+ this.armesList = formData.combat;
// Common data
- formData.data.competenceByCategory = formData.competenceByCategory;
- formData.data.isGM = game.user.isGM;
formData.ajustementsConditions = CONFIG.RDD.ajustementsConditions;
formData.difficultesLibres = CONFIG.RDD.difficultesLibres;
// low is normal, this the base used to compute the grid.
- formData.data.fatigue = {
+ formData.fatigue = {
malus: RdDUtility.calculMalusFatigue(formData.data.sante.fatigue.value, formData.data.sante.endurance.max),
html: "
" + RdDUtility.makeHTMLfatigueMatrix(formData.data.sante.fatigue.value, formData.data.sante.endurance.max).html() + "
"
}
@@ -141,15 +161,20 @@ export class RdDActorSheet extends ActorSheet {
}
}
+ /* -------------------------------------------- */
+ async createItem(name, type) {
+ await this.actor.createEmbeddedDocuments('Item', [{ name: name, type: type }], { renderSheet: true });
+ }
+
/* -------------------------------------------- */
async createEmptyTache() {
- await this.actor.createOwnedItem({ name: 'Nouvelle tache', type: 'tache' }, { renderSheet: true });
+ await this.createItem('Nouvelle tache', 'tache');
}
/* -------------------------------------------- */
async creerObjet() {
let itemType = $("#creer-equipement").val();
- await this.actor.createOwnedItem({ name: 'Nouveau ' + itemType, type: itemType }, { renderSheet: true });
+ await this.createItem('Nouveau ' + itemType, itemType);
}
/* -------------------------------------------- */
diff --git a/module/actor-vehicule-sheet.js b/module/actor-vehicule-sheet.js
index e9cfc46e..10ef7aaf 100644
--- a/module/actor-vehicule-sheet.js
+++ b/module/actor-vehicule-sheet.js
@@ -34,9 +34,22 @@ export class RdDActorVehiculeSheet extends ActorSheet {
/* -------------------------------------------- */
async getData() {
- let formData = super.getData();
-
- formData.itemsByType = Misc.classify(formData.items);
+ const objectData = Misc.data(this.object);
+ let formData = {
+ title: this.title,
+ id: objectData.id,
+ type: objectData.type,
+ img: objectData.img,
+ name: objectData.name,
+ editable: this.isEditable,
+ cssClass: this.isEditable ? "editable" : "locked",
+ data: foundry.utils.deepClone(Misc.templateData(this.object)),
+ effects: this.object.effects.map(e => foundry.utils.deepClone(e.data)),
+ limited: this.object.limited,
+ options: this.options,
+ owner: this.document.isOwner,
+ itemsByType: Misc.classify(this.object.items.map(i => foundry.utils.deepClone(i.data))),
+ };
RdDUtility.filterItemsPerTypeForSheet(formData);
RdDUtility.buildArbreDeConteneur(this, formData);
diff --git a/module/actor.js b/module/actor.js
index 8097e01c..8165d919 100644
--- a/module/actor.js
+++ b/module/actor.js
@@ -72,7 +72,8 @@ export class RdDActor extends Actor {
return actor;
}
- data.items = await RdDUtility.loadCompendium(RdDItemCompetence.actorCompendium(data.type));
+ const competences = await RdDUtility.loadCompendium(RdDItemCompetence.actorCompendium(data.type));
+ data.items = competences.map(it => Misc.data(it));
if (isPersonnage) {
data.items = data.items.concat(Monnaie.monnaiesData());
}
@@ -143,7 +144,7 @@ export class RdDActor extends Actor {
if (!items) return; // Sanity check during import
let manquantes = Monnaie.monnaiesManquantes(items);
if (manquantes.length > 0) {
- await this.createOwnedItem(manquantes);
+ await this.createEmbeddedDocuments('Item', manquantes, { renderSheet: false });
}
}
@@ -171,8 +172,8 @@ export class RdDActor extends Actor {
}
/* -------------------------------------------- */
getReveActuel() {
- const actorData = Misc.data(this);
- return Misc.toInt(actorData.data.reve?.reve?.value ?? actorData.data.carac.reve.value);
+ const templateData = Misc.templateData(this);
+ return Misc.toInt(templateData.reve?.reve?.value ?? templateData.carac.reve.value);
}
/* -------------------------------------------- */
getChanceActuel() {
@@ -231,10 +232,6 @@ export class RdDActor extends Actor {
return Misc.toInt(Misc.templateData(this).compteurs.surenc?.value);
}
/* -------------------------------------------- */
- loadCompendiumNames() {
- return this.data.items.filter(item => item.type == 'competence');
- }
- /* -------------------------------------------- */
getCompetence(name) {
return RdDItemCompetence.findCompetence(this.data.items, name);
}
@@ -913,7 +910,7 @@ export class RdDActor extends Actor {
let itemMap = {};
for (let item of itemsList) {
let srcItem = sourceActor.data.items.find(subItem => subItem._id == item.id);
- let newItem = await this.createOwnedItem(duplicate(srcItem));
+ let newItem = await this.createEmbeddedDocuments('Item', [duplicate(srcItem)]);
console.log('New object', newItem, srcItem);
itemMap[srcItem._id] = newItem._id; // Pour garder le lien ancien / nouveau
}
@@ -943,7 +940,7 @@ export class RdDActor extends Actor {
maxEnc = Misc.templateData(this).capacite_encombrement;
else
maxEnc = Misc.templateData(this).attributs.encombrement.value;
- let diffEnc = Number(this.encTotal) - Number(maxEnc);
+ let diffEnc = Number(this.data.encTotal) - Number(maxEnc);
return Math.max(0, Math.ceil(diffEnc));
}
@@ -951,7 +948,7 @@ export class RdDActor extends Actor {
async computeEncombrementTotalEtMalusArmure() {
let encTotal = 0;
let newMalusArmure = 0;
- for (const itemData of this.data.items) {
+ for (const itemData of this.data.items.filter(it => Misc.templateData(it).encombrement != undefined)) {
if (itemData.type == 'armure' && itemData.data.equipe) { // Armure équipée, intégration du malus armure total
newMalusArmure += itemData.data.malus;
}
@@ -967,7 +964,7 @@ export class RdDActor extends Actor {
}
}
// Mise à jour valeur totale et états
- this.encTotal = encTotal;
+ this.data.encTotal = encTotal;
this.detectSurEncombrement();
// Mise à jour éventuelle du malus armure
@@ -1064,7 +1061,7 @@ export class RdDActor extends Actor {
/* -------------------------------------------- */
async ajouterSouffle(options = { chat: false }) {
let souffle = await RdDRollTables.getSouffle();
- await this.createOwnedItem(souffle);
+ await this.createEmbeddedDocuments('Item', [souffle]);
if (options.chat) {
ChatMessage.create({
whisper: ChatUtility.getWhisperRecipientsAndGMs(game.user.name),
@@ -1084,7 +1081,7 @@ export class RdDActor extends Actor {
else {
queue = await RdDRollTables.getQueue();
}
- await this.createOwnedItem(queue);
+ await this.createEmbeddedDocuments('Item', [queue]);
if (options.chat) {
ChatMessage.create({
whisper: ChatUtility.getWhisperRecipientsAndGMs(game.user.name),
@@ -1613,6 +1610,12 @@ export class RdDActor extends Actor {
return 0;
}
+ /* -------------------------------------------- */
+ appliquerExperience(rollData) {
+ const callback = this.createCallbackExperience();
+ if (callback.condition(rollData)) { callback.action(rollData); }
+ }
+
/* -------------------------------------------- */
createCallbackExperience() {
return {
@@ -1948,6 +1951,32 @@ export class RdDActor extends Actor {
RdDResolutionTable.displayRollData(rollData, this, 'chat-resultat-general.html');
}
+ async rollCaracCompetence(caracName, compName, diff) {
+ const carac = this.getCaracByName(caracName);
+ if (!carac) {
+ ui.notifications.warn(`${this.name} n'a pas de caractéristique correspondant à ${caracName}`)
+ return;
+ }
+ const competence = this.getCompetence(compName);
+ if (compName && !competence) {
+ ui.notifications.warn(`${this.name} n'a pas de compétence correspondant à ${compName}`)
+ return;
+ }
+ let rollData = {
+ alias: this.name,
+ caracValue: Number(carac.value),
+ selectedCarac: carac,
+ competence: competence,
+ finalLevel: (competence?.data.niveau ?? 0) + diff,
+ diffLibre: diff,
+ showDice: true,
+ show: { title: "Jets multiples" }
+ };
+ await RdDResolutionTable.rollData(rollData);
+ this.appliquerExperience(rollData);
+ RdDResolutionTable.displayRollData(rollData, this)
+ }
+
/* -------------------------------------------- */
async rollCompetence(name) {
let rollData = { competence: this.getCompetence(name) }
@@ -1994,7 +2023,7 @@ export class RdDActor extends Actor {
description: "Lecture du livre " + item.name + " - XP : " + itemData.data.xp + " - Compétences : " + itemData.data.competence
}
}
- await this.createOwnedItem(tache, { renderSheet: true });
+ await this.createEmbeddedDocuments('Item', [tache], { renderSheet: true });
}
/* -------------------------------------------- */
@@ -2262,7 +2291,7 @@ export class RdDActor extends Actor {
if (destinee > 0) {
ChatMessage.create({ content: `${this.name} a fait appel à la Destinée !` });
destinee--;
- await this.updateCompteurValue( "destinee", destinee);
+ await this.updateCompteurValue("destinee", destinee);
onSuccess();
}
else {
@@ -2380,19 +2409,29 @@ export class RdDActor extends Actor {
/* -------------------------------------------- */
static _findCaracByName(carac, name) {
- name = name.toLowerCase();
+ name = Grammar.toLowerCaseNoAccent(name);
switch (name) {
case 'reve-actuel': case 'rêve actuel':
return carac.reve;
case 'chance-actuelle': case 'chance actuelle':
return carac.chance;
}
- for (const [key, value] of Object.entries(carac)) {
- if (name == key || name == value.label.toLowerCase()) {
- return carac[key];
- }
+ const keys = Object.entries(carac)
+ .filter(it => it[0].includes(name) || Grammar.toLowerCaseNoAccent(it[1].label).includes(name))
+ .map(it => it[0]);
+ if (keys.length > 1) {
+ const names = keys.reduce((a, b) => `${a}
${b}`);
+ ui.notifications.info(`Plusieurs caractéristiques possibles:
${names}
La première sera choisie.`);
}
- return carac[name]; // Per default
+ if (keys.length > 0) {
+ return carac[keys[0]];
+ }
+ // for (const [key, value] of Object.entries(carac)) {
+ // if (key.includes(name) || Grammar.toLowerCaseNoAccent(value.label).includes('name')) {
+ // return carac[key];
+ // }
+ // }
+ return undefined; // Per default
}
/* -------------------------------------------- */
@@ -2848,7 +2887,7 @@ export class RdDActor extends Actor {
if (dataObj) {
dataObj.payload.data.cout = sumDenier / 100; // Mise à jour du prix en sols , avec le prix acheté
dataObj.payload.data.quantite = quantite;
- await this.createOwnedItem(dataObj.payload);
+ await this.createEmbeddedDocuments('Item',[dataObj.payload]);
msg += `
Et l'objet ${dataObj.payload.name} a été ajouté à votre inventaire.`;
}
} else {
@@ -3070,22 +3109,20 @@ export class RdDActor extends Actor {
/* -------------------------------------------- */
_deleteStatusEffectsByIds(effectIds, options) {
this.deleteEmbeddedEntity('ActiveEffect', effectIds, options);
- this.applyActiveEffects();
}
/* -------------------------------------------- */
- async addStatusEffectById(id, options = { renderSheet: true }) {
+ async addStatusEffectById(id, options = { renderSheet: false }) {
const statusEffect = CONFIG.statusEffects.find(it => it.id == id);
await this.addStatusEffect(statusEffect, options);
}
/* -------------------------------------------- */
- async addStatusEffect(statusEffect, options = { renderSheet: true }) {
+ async addStatusEffect(statusEffect, options = { renderSheet: false }) {
this.deleteStatusEffectById(statusEffect.id, options);
const effet = duplicate(statusEffect);
effet["flags.core.statusId"] = effet.id;
await this.createEmbeddedEntity('ActiveEffect', effet, options);
- this.applyActiveEffects();
}
/* -------------------------------------------- */
diff --git a/module/chat-utility.js b/module/chat-utility.js
index b4ac3414..7e95b705 100644
--- a/module/chat-utility.js
+++ b/module/chat-utility.js
@@ -13,7 +13,7 @@ export class ChatUtility {
/* -------------------------------------------- */
static onRemoveMessages(part, gmId) {
- if (game.user._id == gmId) {
+ if (game.user.id == gmId) {
const toDelete = game.messages.filter(it => it.data.content.includes(part));
toDelete.forEach(it => it.delete());
}
@@ -21,10 +21,10 @@ export class ChatUtility {
/* -------------------------------------------- */
static removeChatMessageContaining(part) {
- const gmId = game.user.isGM ? game.user._id : game.users.entities.find(u => u.isGM && u.active)?.id;
+ const gmId = game.user.isGM ? game.user.id : game.users.entities.find(u => u.isGM && u.active)?.id;
if (!gmId || game.user.isGM) {
- ChatUtility.onRemoveMessages(part, game.user._id);
+ ChatUtility.onRemoveMessages(part, game.user.id);
}
else {
game.socket.emit("system.foundryvtt-reve-de-dragon", {
@@ -47,7 +47,7 @@ export class ChatUtility {
if (!game.user.isGM) {
ChatUtility.blindMessageToGM(chatOptions);
- chatOptions.whisper = [game.user._id];
+ chatOptions.whisper = [game.user.id];
chatOptions.content = "Message envoyé en aveugle au Gardien";
}
else {
@@ -65,7 +65,7 @@ export class ChatUtility {
/* -------------------------------------------- */
static prepareChatMessage(rollMode, name) {
return {
- user: game.user._id,
+ user: game.user.id,
whisper: ChatUtility.getWhisperRecipients(rollMode, name)
}
}
@@ -75,7 +75,7 @@ export class ChatUtility {
switch (rollMode) {
case "blindroll": return ChatUtility.getUsers(user => user.isGM);
case "gmroll": return ChatUtility.getWhisperRecipientsAndGMs(name);
- case "selfroll": return [game.user._id];
+ case "selfroll": return [game.user.id];
}
return undefined;
}
@@ -104,7 +104,7 @@ export class ChatUtility {
static handleGMChatMessage(data) {
console.log("blindMessageToGM", data);
if (game.user.isGM) { // message privé pour GM only
- data.user = game.user._id;
+ data.user = game.user.id;
ChatMessage.create(data);
}
}
diff --git a/module/item-competence.js b/module/item-competence.js
index a399e6fd..dacf1b9f 100644
--- a/module/item-competence.js
+++ b/module/item-competence.js
@@ -1,3 +1,5 @@
+import { Grammar } from "./grammar.js";
+
const competenceTroncs = [["Esquive", "Dague", "Corps à corps"],
["Epée à 1 main", "Epée à 2 mains", "Hache à 1 main", "Hache à 2 mains", "Lance", "Masse à 1 main", "Masse à 2 mains"]];
@@ -183,8 +185,20 @@ export class RdDItemCompetence extends Item {
/* -------------------------------------------- */
static findCompetence(list, name) {
- name = name.toLowerCase();
- return list.find(it => it.name.toLowerCase() == name && (it.type == "competence" || it.type == "competencecreature"))
+ name = Grammar.toLowerCaseNoAccent(name);
+ const competences = list.filter(it => Grammar.toLowerCaseNoAccent(it.name).includes(name) && (it.type == "competence" || it.type == "competencecreature"));
+ if (competences.length == 0) {
+ return undefined;
+ }
+ let competence = competences.find(it => Grammar.toLowerCaseNoAccent(it.name) == name);
+ if (!competence) {
+ competence = competences[0];
+ if (competences.length>1) {
+ const names = competences.map(it => it.name).reduce((a, b) => `${a}
${b}`);
+ ui.notifications.info(`Plusieurs compétences possibles:
${names}
La première sera choisie: ${competence.name}`);
+ }
+ }
+ return competence;
}
/* -------------------------------------------- */
diff --git a/module/item-monnaie.js b/module/item-monnaie.js
index b0a76110..0b3224d2 100644
--- a/module/item-monnaie.js
+++ b/module/item-monnaie.js
@@ -1,22 +1,23 @@
+import { Misc } from "./misc.js";
const monnaiesData = [
{
- _id: randomID(16), name: "Etain (1 denier)", type: 'monnaie',
+ name: "Etain (1 denier)", type: 'monnaie',
img: "systems/foundryvtt-reve-de-dragon/icons/objets/piece_etain_poisson.webp",
data: { quantite: 0, valeur_deniers: 1, encombrement: 0.001, description: "" }
},
{
- _id: randomID(16), name: "Bronze (10 deniers)", type: 'monnaie',
+ name: "Bronze (10 deniers)", type: 'monnaie',
img: "systems/foundryvtt-reve-de-dragon/icons/objets/piece_bronze_epees.webp",
data: { quantite: 0, valeur_deniers: 10, encombrement: 0.002, description: "" }
},
{
- _id: randomID(16), name: "Argent (1 sol)", type: 'monnaie',
+ name: "Argent (1 sol)", type: 'monnaie',
img: "systems/foundryvtt-reve-de-dragon/icons/objets/piece_argent_sol.webp",
data: { quantite: 0, valeur_deniers: 100, encombrement: 0.003, description: "" }
},
{
- _id: randomID(16), name: "Or (10 sols)", type: 'monnaie',
+ name: "Or (10 sols)", type: 'monnaie',
img: "systems/foundryvtt-reve-de-dragon/icons/objets/piece_or_sol.webp",
data: { quantite: 0, valeur_deniers: 1000, encombrement: 0.004, description: "" }
}
@@ -33,8 +34,13 @@ export class Monnaie {
}
static monnaiesManquantes(items) {
- const valeurs = Monnaie.filtrerMonnaies(items)
- .map(it => it.data.valeur_deniers)
- return duplicate(monnaiesData.filter(monnaie => !valeurs.find(v => v != monnaie.data.valeur_deniers)));
+ const valeurs = Monnaie.filtrerMonnaies(items)
+ .map(it => Misc.templateData(it).valeur_deniers)
+ const manquantes = monnaiesData.filter(monnaie => !valeurs.find(v => v != Misc.templateData(monnaie).valeur_deniers));
+ return manquantes;
+ }
+
+ static deValeur(monnaie, v) {
+ return v != monnaie.data.valeur_deniers;
}
}
diff --git a/module/item-sheet.js b/module/item-sheet.js
index b51cb2ab..aec1cc75 100644
--- a/module/item-sheet.js
+++ b/module/item-sheet.js
@@ -52,7 +52,7 @@ export class RdDItemSheet extends ItemSheet {
formData.categorieCompetences = RdDItemCompetence.getCategorieCompetences();
if ( formData.item.type == 'tache' || formData.item.type == 'livre' || formData.item.type == 'meditation' || formData.item.type == 'oeuvre') {
formData.caracList = duplicate(game.system.model.Actor.personnage.carac);
- formData.competences = await RdDUtility.loadCompendiumNames( 'foundryvtt-reve-de-dragon.competences' );
+ formData.competences = await RdDUtility.loadCompendium( 'foundryvtt-reve-de-dragon.competences' );
}
if (formData.item.type == 'arme') {
formData.competences = await RdDUtility.loadCompendium( 'foundryvtt-reve-de-dragon.competences', it => RdDItemCompetence.isCompetenceArme(it));
diff --git a/module/misc.js b/module/misc.js
index fcc89b22..e443a63f 100644
--- a/module/misc.js
+++ b/module/misc.js
@@ -55,7 +55,7 @@ export class Misc {
}
return itemsBy;
}
-
+
static classifyInto(itemsBy, items, classifier = it => it.type, transform = it => it) {
for (const item of items) {
const classification = classifier(item);
@@ -66,6 +66,9 @@ export class Misc {
}
list.push(transform(item));
}
+ for (const [key, list] of Object.entries(itemsBy)) {
+ list.sort();
+ };
}
static rollOneOf(array) {
diff --git a/module/rdd-commands.js b/module/rdd-commands.js
index dddfdb2c..0163d31e 100644
--- a/module/rdd-commands.js
+++ b/module/rdd-commands.js
@@ -11,9 +11,9 @@ import { RdDRollResolutionTable } from "./rdd-roll-resolution-table.js";
import { RdDRollTables } from "./rdd-rolltables.js";
import { RdDUtility } from "./rdd-utility.js";
import { TMRRencontres } from "./tmr-rencontres.js";
-import { TMRType, TMRUtility } from "./tmr-utility.js";
+import { TMRUtility } from "./tmr-utility.js";
-const rddRollNumeric = /(\d+)\s*([\+\-]?\d+)?\s*(s)?/;
+const rddRollNumeric = /$(\d+)\s*([\+\-]?\d+)?\s*(s)?/;
/* -------------------------------------------- */
export class RdDCommands {
@@ -64,9 +64,11 @@ export class RdDCommands {
descr: `Effectue un jet de dés dans la table de résolution. Exemples:
/rdd ouvre la table de résolution
/rdd 10 3 effectue un jet 10 à +3
-
/rdd 10 +2 effectue un jet 10 à +2
/rdd 15 -2 effectue un jet 15 à -2
-
/rdd 15 0 s effectue un jet 15 à 0, avec significative requise`
+
/rdd 15 0 s effectue un jet 15 à 0, avec significative requise
+
/rdd Vue Vigilance -2 effectue un jet de Vue/Vigilance à -2 pour les tokens sélectionnés
+
/rdd vol déser +2 effectue un jet de Volonté/Survie en désert à +2 pour les tokens sélectionnés
+ `
});
rddCommands.registerCommand({ path: ["/ddr"], func: (content, msg, params) => rddCommands.rollDeDraconique(msg), descr: "Lance un Dé Draconique" });
@@ -173,7 +175,7 @@ export class RdDCommands {
/* -------------------------------------------- */
static _chatAnswer(msg, content) {
- msg.whisper = [game.user._id];
+ msg.whisper = [game.user.id];
msg.content = content;
ChatMessage.create(msg);
}
@@ -217,6 +219,27 @@ export class RdDCommands {
await this.rollRdDNumeric(msg, carac, diff, significative);
return;
}
+
+ let actors = canvas.tokens.controlled.map(it => it.actor).filter(it => it);
+ if (actors && actors.length > 0){
+ let length = params.length;
+ let diff = Number(params[length-1]);
+ if (Number.isInteger(Number(diff))){
+ length --;
+ }
+ else {
+ diff = 0;
+ }
+ const caracName = params[0];
+ const compName = length>1 ? params.slice(1, length).reduce((a, b) => `${a} ${b}`): undefined;
+ for (let actor of actors) {
+ await actor.rollCaracCompetence(caracName, compName, diff);
+ }
+ return;
+ }
+ else{
+ ui.notifications.warn("Sélectionnez au moins un personnage pour lancer les dés")
+ }
}
}
diff --git a/module/rdd-compendium-organiser.js b/module/rdd-compendium-organiser.js
index ad7e1ea2..1655b87d 100644
--- a/module/rdd-compendium-organiser.js
+++ b/module/rdd-compendium-organiser.js
@@ -36,14 +36,14 @@ export class RddCompendiumOrganiser {
Hooks.on('renderCompendium', async (pack, html, data) => RddCompendiumOrganiser.onRenderCompendium(pack, html, data))
}
- static async onRenderCompendium(pack, html, data) {
- console.log('onRenderCompendium', pack, html, data);
+ static async onRenderCompendium(compendium, html, data) {
+ console.log('onRenderCompendium', compendium, html, data);
+ let pack = compendium.collection
if (pack.metadata.system === 'foundryvtt-reve-de-dragon') {
const content = await pack.getContent();
html.find('.directory-item').each((i, element) => {
- let entity = content.find(it => it._id === element.dataset.entryId);
-
+ let entity = pack.get(element.dataset.documentId);
if (entity?.entity === 'Actor' || entity?.entity === 'Item') {
const typeName = typeDisplayName[entity.data.type] ?? Misc.upperFirst(entity.data.type);
RddCompendiumOrganiser.insertEntityType(element, typeName);
diff --git a/module/rdd-dice.js b/module/rdd-dice.js
index 81d41057..94df5543 100644
--- a/module/rdd-dice.js
+++ b/module/rdd-dice.js
@@ -26,7 +26,7 @@ export class RdDDice {
whisper = ChatUtility.getUsers(user => user.active);
break;
case "selfroll":
- whisper = [game.user._id];
+ whisper = [game.user.id];
break;
}
await game.dice3d.showForRoll(roll, game.user, true, whisper, blind);
diff --git a/module/rdd-hotbar-drop.js b/module/rdd-hotbar-drop.js
index 12b925bb..d0dd3440 100644
--- a/module/rdd-hotbar-drop.js
+++ b/module/rdd-hotbar-drop.js
@@ -9,12 +9,12 @@ export class RdDHotbar {
*/
static initDropbar( ) {
- Hooks.on("hotbarDrop", async (bar, data, slot) => {
+ Hooks.on("hotbarDrop", async (bar, documentData, slot) => {
// Create item macro if rollable item - weapon, spell, prayer, trait, or skill
- if (data.type == "Item") {
- if (data.data.type != "arme" && data.data.type != "competence" )
+ if (documentData.type == "Item") {
+ if (documentData.data.type != "arme" && documentData.data.type != "competence" )
return
- let item = data.data
+ let item = documentData.data
let command = `game.system.rdd.RdDHotbar.rollMacro("${item.name}", "${item.type}");`;
let macro = game.macros.entities.find(m => (m.name === item.name) && (m.command === command));
if (!macro) {
@@ -28,9 +28,9 @@ export class RdDHotbar {
game.user.assignHotbarMacro(macro, slot);
}
// Create a macro to open the actor sheet of the actor dropped on the hotbar
- else if (data.type == "Actor") {
- let actor = game.actors.get(data.id);
- let command = `game.actors.get("${data.id}").sheet.render(true)`
+ else if (documentData.type == "Actor") {
+ let actor = game.actors.get(documentData.id);
+ let command = `game.actors.get("${documentData.id}").sheet.render(true)`
let macro = game.macros.entities.find(m => (m.name === actor.name) && (m.command === command));
if (!macro) {
macro = await Macro.create({
@@ -43,9 +43,9 @@ export class RdDHotbar {
}
}
// Create a macro to open the journal sheet of the journal dropped on the hotbar
- else if (data.type == "JournalEntry") {
- let journal = game.journal.get(data.id);
- let command = `game.journal.get("${data.id}").sheet.render(true)`
+ else if (documentData.type == "JournalEntry") {
+ let journal = game.journal.get(documentData.id);
+ let command = `game.journal.get("${documentData.id}").sheet.render(true)`
let macro = game.macros.entities.find(m => (m.name === journal.name) && (m.command === command));
if (!macro) {
macro = await Macro.create({
diff --git a/module/rdd-main.js b/module/rdd-main.js
index 2b7d2e43..0f147060 100644
--- a/module/rdd-main.js
+++ b/module/rdd-main.js
@@ -133,7 +133,7 @@ Hooks.once("init", async function () {
/* -------------------------------------------- */
// Define custom Entity classes
- CONFIG.Actor.entityClass = RdDActor;
+ CONFIG.Actor.documentClass = RdDActor;
CONFIG.RDD = {
resolutionTable: RdDResolutionTable.resolutionTable,
carac_array: RdDUtility.getCaracArray(),
@@ -150,7 +150,7 @@ Hooks.once("init", async function () {
Actors.registerSheet("foundryvtt-reve-de-dragon", RdDActorEntiteSheet, { types: ["entite"], makeDefault: true });
Items.unregisterSheet("core", ItemSheet);
Items.registerSheet("foundryvtt-reve-de-dragon", RdDItemSheet, { makeDefault: true });
- CONFIG.Combat.entityClass = RdDCombatManager;
+ CONFIG.Combat.documentClass = RdDCombatManager;
// préparation des différents modules
RdDCommands.init();
@@ -171,7 +171,7 @@ function messageDeBienvenue() {
if (game.user.isGM) {
ChatUtility.removeChatMessageContaining('');
ChatMessage.create({
- user: game.user._id,
+ user: game.user.id,
content: `
Bienvenue dans le Rêve des Dragons !
Vous trouverez quelques informations pour démarrer dans ce document : @Compendium[foundryvtt-reve-de-dragon.rappel-des-regles.7uGrUHGdPu0EmIu2]{Documentation MJ/Joueurs}
La commande /aide
dans le chat permet de voir les commandes spécifiques à Rêve de Dragon.
@@ -202,7 +202,7 @@ Hooks.once("ready", function () {
ui.notifications.info("Attention ! Vous n'êtes connecté à aucun personnage !");
ChatMessage.create({
content: "
ATTENTION Le joueur " + game.user.name + " n'est connecté à aucun personnage !",
- user: game.user._id
+ user: game.user.id
});
//whisper: [ ChatMessage.getWhisperRecipients("GM") ] } );
}
diff --git a/module/rdd-rolltables.js b/module/rdd-rolltables.js
index 74d06152..15b05165 100644
--- a/module/rdd-rolltables.js
+++ b/module/rdd-rolltables.js
@@ -5,7 +5,7 @@ export class RdDRollTables {
const pack = game.packs.get("foundryvtt-reve-de-dragon.tables-diverses");
const index = await pack.getIndex();
const entry = index.find(e => e.name === tableName);
- const table = await pack.getEntity(entry._id);
+ const table = await pack.getDocument(entry._id);
const draw = await table.draw({ displayChat: toChat, rollMode: "gmroll"});
console.log("RdDRollTables", tableName, toChat, ":", draw);
return draw;
@@ -17,7 +17,7 @@ export class RdDRollTables {
const drawnItemRef = draw.results.length > 0 ? draw.results[0] : undefined;
if (drawnItemRef.collection) {
const pack = game.packs.get(drawnItemRef.collection);
- return await pack.getEntity(drawnItemRef.resultId);
+ return await pack.getDocument(drawnItemRef.resultId);
}
ui.notifications.warn("le tirage ne correspond pas à une entrée d'un Compendium")
return drawnItemRef.text;
@@ -29,7 +29,7 @@ export class RdDRollTables {
const drawnItemRef = draw.results.length > 0 ? draw.results[0] : undefined;
if (drawnItemRef.collection) {
ui.notifications.warn("le tirage correspond à une entrée d'un Compendium, on attendait un texte")
- return await pack.getEntity(drawnItemRef.resultId);
+ return await pack.getDocument(drawnItemRef.resultId);
}
return drawnItemRef.text;
}
diff --git a/module/rdd-tmr-dialog.js b/module/rdd-tmr-dialog.js
index 92329451..fcc92d6d 100644
--- a/module/rdd-tmr-dialog.js
+++ b/module/rdd-tmr-dialog.js
@@ -383,17 +383,17 @@ export class RdDTMRDialog extends Dialog {
/* -------------------------------------------- */
_tellToUser(message) {
- ChatMessage.create({ content: message, user: game.user._id, whisper: [game.user._id] });
+ ChatMessage.create({ content: message, user: game.user.id, whisper: [game.user.id] });
}
/* -------------------------------------------- */
_tellToGM(message) {
- ChatMessage.create({ content: message, user: game.user._id, whisper: ChatMessage.getWhisperRecipients("GM") });
+ ChatMessage.create({ content: message, user: game.user.id, whisper: ChatMessage.getWhisperRecipients("GM") });
}
/* -------------------------------------------- */
_tellToUserAndGM(message) {
- ChatMessage.create({ content: message, user: game.user._id, whisper: [game.user._id].concat(ChatMessage.getWhisperRecipients("GM")) });
+ ChatMessage.create({ content: message, user: game.user.id, whisper: [game.user.id].concat(ChatMessage.getWhisperRecipients("GM")) });
}
/* -------------------------------------------- */
diff --git a/module/rdd-utility.js b/module/rdd-utility.js
index 34573582..6992ec06 100644
--- a/module/rdd-utility.js
+++ b/module/rdd-utility.js
@@ -223,40 +223,40 @@ export class RdDUtility {
}
/* -------------------------------------------- */
- static filterItemsPerTypeForSheet(formData) {
- formData.data.materiel = this.checkNull(formData.itemsByType['objet']);
- formData.data.conteneurs = this.checkNull(formData.itemsByType['conteneur']);
- formData.data.armes = this.checkNull(formData.itemsByType['arme']);
- formData.data.armures = this.checkNull(formData.itemsByType['armure']);
- formData.data.livres = this.checkNull(formData.itemsByType['livre']);
- formData.data.potions = this.checkNull(formData.itemsByType['potion']);
- formData.data.ingredients = this.checkNull(formData.itemsByType['ingredient']);
- formData.data.munitions = this.checkNull(formData.itemsByType['munition']);
- formData.data.herbes = this.checkNull(formData.itemsByType['herbe']);
- formData.data.sorts = this.checkNull(formData.itemsByType['sort']);
- formData.data.queues = this.checkNull(formData.itemsByType['queue']);
- formData.data.souffles = this.checkNull(formData.itemsByType['souffle']);
- formData.data.ombres = this.checkNull(formData.itemsByType['ombre']);
- formData.data.tetes = this.checkNull(formData.itemsByType['tete']);
- formData.data.taches = this.checkNull(formData.itemsByType['tache']);
- formData.data.monnaie = this.checkNull(formData.itemsByType['monnaie']);
- formData.data.meditations = this.checkNull(formData.itemsByType['meditation']);
- formData.data.chants = this.checkNull(formData.itemsByType['chant']);
- formData.data.danses = this.checkNull(formData.itemsByType['danse']);
- formData.data.musiques = this.checkNull(formData.itemsByType['musique']);
- formData.data.oeuvres = this.checkNull(formData.itemsByType['oeuvre']);
- formData.data.jeux = this.checkNull(formData.itemsByType['jeu']);
- formData.data.recettescuisine = this.checkNull(formData.itemsByType['recettecuisine']);
- formData.data.recettesAlchimiques = this.checkNull(formData.itemsByType['recettealchimique']);
- formData.data.objets = formData.data.conteneurs.concat(formData.data.materiel)
- .concat(formData.data.armes)
- .concat(formData.data.armures)
- .concat(formData.data.munitions)
- .concat(formData.data.livres)
- .concat(formData.data.potions)
- .concat(formData.data.herbes)
- .concat(formData.data.ingredients);
- formData.data.competences = (formData.itemsByType.competence??[]).concat(formData.itemsByType.competencecreature??[]);
+ static filterItemsPerTypeForSheet(formData, itemsByType) {
+ formData.materiel = this.checkNull(formData.itemsByType['objet']);
+ formData.conteneurs = this.checkNull(formData.itemsByType['conteneur']);
+ formData.armes = this.checkNull(formData.itemsByType['arme']);
+ formData.armures = this.checkNull(formData.itemsByType['armure']);
+ formData.livres = this.checkNull(formData.itemsByType['livre']);
+ formData.potions = this.checkNull(formData.itemsByType['potion']);
+ formData.ingredients = this.checkNull(formData.itemsByType['ingredient']);
+ formData.munitions = this.checkNull(formData.itemsByType['munition']);
+ formData.herbes = this.checkNull(formData.itemsByType['herbe']);
+ formData.sorts = this.checkNull(formData.itemsByType['sort']);
+ formData.queues = this.checkNull(formData.itemsByType['queue']);
+ formData.souffles = this.checkNull(formData.itemsByType['souffle']);
+ formData.ombres = this.checkNull(formData.itemsByType['ombre']);
+ formData.tetes = this.checkNull(formData.itemsByType['tete']);
+ formData.taches = this.checkNull(formData.itemsByType['tache']);
+ formData.monnaie = this.checkNull(formData.itemsByType['monnaie']);
+ formData.meditations = this.checkNull(formData.itemsByType['meditation']);
+ formData.chants = this.checkNull(formData.itemsByType['chant']);
+ formData.danses = this.checkNull(formData.itemsByType['danse']);
+ formData.musiques = this.checkNull(formData.itemsByType['musique']);
+ formData.oeuvres = this.checkNull(formData.itemsByType['oeuvre']);
+ formData.jeux = this.checkNull(formData.itemsByType['jeu']);
+ formData.recettescuisine = this.checkNull(formData.itemsByType['recettecuisine']);
+ formData.recettesAlchimiques = this.checkNull(formData.itemsByType['recettealchimique']);
+ formData.objets = formData.conteneurs.concat(formData.materiel)
+ .concat(formData.armes)
+ .concat(formData.armures)
+ .concat(formData.munitions)
+ .concat(formData.livres)
+ .concat(formData.potions)
+ .concat(formData.herbes)
+ .concat(formData.ingredients);
+ formData.competences = (formData.itemsByType.competence??[]).concat(formData.itemsByType.competencecreature??[]);
}
/* -------------------------------------------- */
@@ -287,16 +287,16 @@ export class RdDUtility {
}
/* -------------------------------------------- */
- static buildArbreDeConteneur(actorSheet, data) {
+ static buildArbreDeConteneur(actorSheet, formData) {
actorSheet.objetVersConteneur = {}; // Table de hash locale pour recupération rapide du conteneur parent (si existant)
// Attribution des objets aux conteneurs
- for (let conteneur of data.data.conteneurs) {
+ for (let conteneur of formData.conteneurs) {
conteneur.subItems = [];
if (!conteneur.data.encTotal) conteneur.data.encTotal = 0;
//conteneur.data.encTotal = ; Deja calculé
if (conteneur.data.contenu) {
for (let id of conteneur.data.contenu) {
- let objet = data.data.objets.find(objet => (id == objet._id));
+ let objet = formData.objets.find(objet => (id == objet._id));
if (objet) {
if (!objet.data.encombrement) objet.data.encombrement = 0; // Auto-fix
objet.estContenu = true; // Permet de filtrer ce qifui est porté dans le template
@@ -308,8 +308,8 @@ export class RdDUtility {
}
}
// Construit la liste des conteneurs de niveau 1 (c'est à dire non contenu eux-même dans un conteneur)
- let newConteneurs = data.data.conteneurs.filter(function (conteneur, index, arr) { return !conteneur.estContenu });
- data.data.conteneurs = newConteneurs;
+ let newConteneurs = formData.conteneurs.filter(function (conteneur, index, arr) { return !conteneur.estContenu });
+ formData.conteneurs = newConteneurs;
//console.log(newConteneurs);
}
@@ -476,30 +476,15 @@ export class RdDUtility {
}
/* -------------------------------------------- */
- static async loadCompendiumNames(compendium) {
+ static async loadCompendiumData(compendium) {
const pack = game.packs.get(compendium);
- let competences;
- await pack.getIndex().then(index => competences = index);
- return competences;
+ return await pack?.getDocuments() ?? [];
}
/* -------------------------------------------- */
static async loadCompendium(compendium, filter = item => true) {
- if (!compendium){
- return [];
- }
- let compendiumItems = await RdDUtility.loadCompendiumNames(compendium);
- const pack = game.packs.get(compendium);
- let list = [];
- for (let compendiumItem of compendiumItems) {
- await pack.getEntity(compendiumItem._id).then(it => {
- const item = it.data;
- if (filter(item)) {
- list.push(item);
- }
- });
- };
- return list;
+ let compendiumData = await RdDUtility.loadCompendiumData(compendium);
+ return compendiumData.filter(filter);
}
/* -------------------------------------------- */
@@ -606,7 +591,7 @@ export class RdDUtility {
/* -------------------------------------------- */
static chatDataSetup(content, modeOverride, isRoll = false, forceWhisper) {
let chatData = {
- user: game.user._id,
+ user: game.user.id,
rollMode: modeOverride || game.settings.get("core", "rollMode"),
content: content
};
diff --git a/module/tmr-rencontres.js b/module/tmr-rencontres.js
index 6905b6cc..7737ee5f 100644
--- a/module/tmr-rencontres.js
+++ b/module/tmr-rencontres.js
@@ -329,8 +329,8 @@ export class TMRRencontres {
}
let rencontre = await TMRRencontres.getRencontreAleatoire(terrain, roll);
ChatMessage.create({
- user: game.user._id,
- whisper: [game.user._id],
+ user: game.user.id,
+ whisper: [game.user.id],
content: `Rencontre en ${terrain} (jet : ${roll}%)
Vous rencontrez un ${rencontre.name} de ${rencontre.force} Points de Rêve`
});
return false;
diff --git a/module/tmr/draconique.js b/module/tmr/draconique.js
index f6b88794..6061d7d9 100644
--- a/module/tmr/draconique.js
+++ b/module/tmr/draconique.js
@@ -122,10 +122,10 @@ export class Draconique {
}
async createCaseTmr(actor, label, tmr, sourceId = undefined) {
- await actor.createOwnedItem({
+ await actor.createEmbeddedDocuments('Item',[{
name: label, type: 'casetmr', img: this.img(), _id: randomID(16),
data: { coord: tmr.coord, specific: this.code(), sourceid: sourceId }
- });
+ }]);
}
async deleteCasesTmr(actor, draconique) {
diff --git a/module/tmr/urgence-draconique.js b/module/tmr/urgence-draconique.js
index 8af5c992..81543a29 100644
--- a/module/tmr/urgence-draconique.js
+++ b/module/tmr/urgence-draconique.js
@@ -1,6 +1,5 @@
import { ChatUtility } from "../chat-utility.js";
import { Grammar } from "../grammar.js";
-import { Misc } from "../misc.js";
import { RdDRollTables } from "../rdd-rolltables.js";
import { tmrColors, tmrConstants, tmrTokenZIndex, TMRUtility } from "../tmr-utility.js";
import { Draconique } from "./draconique.js";
@@ -23,7 +22,7 @@ export class UrgenceDraconique extends Draconique {
whisper: ChatUtility.getWhisperRecipientsAndGMs(game.user.name),
content: `En l'absence de sorts en réserve, l'urgence draconique de ${actor.name} se transforme en ${queue.name}`
});
- await actor.createOwnedItem(ideeFixe);
+ await actor.createEmbeddedDocuments('Item',[ideeFixe]);
await actor.deleteOwnedItem(queue._id);
return;
}
diff --git a/templates/actor-creature-sheet.html b/templates/actor-creature-sheet.html
index 599c23a8..6509b75c 100644
--- a/templates/actor-creature-sheet.html
+++ b/templates/actor-creature-sheet.html
@@ -2,10 +2,10 @@
{{!-- Sheet Header --}}