Merge branch 'v1.4-adapt-acteur' into 'v1.4'

Adaptation Feuilles Acteurs

See merge request LeRatierBretonnien/foundryvtt-reve-de-dragon!176
This commit is contained in:
Leratier Bretonnien 2021-03-25 06:30:26 +00:00
commit fd6c3ac7c6
25 changed files with 360 additions and 246 deletions

View File

@ -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);

View File

@ -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;

View File

@ -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: "<table class='table-fatigue'>" + RdDUtility.makeHTMLfatigueMatrix(formData.data.sante.fatigue.value, formData.data.sante.endurance.max).html() + "</table>"
}
@ -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);
}
/* -------------------------------------------- */

View File

@ -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);

View File

@ -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: `<span class="rdd-roll-part">${this.name} a fait appel à la Destinée !</span>` });
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}<br>${b}`);
ui.notifications.info(`Plusieurs caractéristiques possibles:<br>${names}<br>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 += `<br>Et l'objet <strong>${dataObj.payload.name}</strong> 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();
}
/* -------------------------------------------- */

View File

@ -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);
}
}

View File

@ -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}<br>${b}`);
ui.notifications.info(`Plusieurs compétences possibles:<br>${names}<br>La première sera choisie: ${competence.name}`);
}
}
return competence;
}
/* -------------------------------------------- */

View File

@ -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;
}
}

View File

@ -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));

View File

@ -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) {

View File

@ -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:
<br><strong>/rdd</strong> ouvre la table de résolution
<br><strong>/rdd 10 3</strong> effectue un jet 10 à +3
<br><strong>/rdd 10 +2</strong> effectue un jet 10 à +2
<br><strong>/rdd 15 -2</strong> effectue un jet 15 à -2
<br><strong>/rdd 15 0 s</strong> effectue un jet 15 à 0, avec significative requise`
<br><strong>/rdd 15 0 s</strong> effectue un jet 15 à 0, avec significative requise
<br><strong>/rdd Vue Vigilance -2</strong> effectue un jet de Vue/Vigilance à -2 pour les tokens sélectionnés
<br><strong>/rdd vol déser +2</strong> 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")
}
}
}

View File

@ -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);

View File

@ -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);

View File

@ -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({

View File

@ -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('<div id="message-bienvenue-rdd">');
ChatMessage.create({
user: game.user._id,
user: game.user.id,
content: `<div id="message-bienvenue-rdd"><span class="rdd-roll-part">Bienvenue dans le Rêve des Dragons !</span>
<br>Vous trouverez quelques informations pour démarrer dans ce document : @Compendium[foundryvtt-reve-de-dragon.rappel-des-regles.7uGrUHGdPu0EmIu2]{Documentation MJ/Joueurs}
<br>La commande <code>/aide</code> dans le chat permet de voir les commandes spécifiques à Rêve de Dragon.</div>
@ -202,7 +202,7 @@ Hooks.once("ready", function () {
ui.notifications.info("Attention ! Vous n'êtes connecté à aucun personnage !");
ChatMessage.create({
content: "<b>ATTENTION</b> Le joueur " + game.user.name + " n'est connecté à aucun personnage !",
user: game.user._id
user: game.user.id
});
//whisper: [ ChatMessage.getWhisperRecipients("GM") ] } );
}

View File

@ -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;
}

View File

@ -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")) });
}
/* -------------------------------------------- */

View File

@ -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
};

View File

@ -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}%)<br>Vous rencontrez un ${rencontre.name} de ${rencontre.force} Points de Rêve`
});
return false;

View File

@ -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) {

View File

@ -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;
}

View File

@ -2,10 +2,10 @@
{{!-- Sheet Header --}}
<header class="sheet-header">
<img class="profile-img" src="{{actor.img}}" data-edit="img" title="{{actor.name}}" />
<img class="profile-img" src="{{img}}" data-edit="img" title="{{name}}" />
<div class="header-fields">
<div class="flexrow">
<h1 class="charname"><input name="name" type="text" value="{{actor.name}}" placeholder="Name" /></h1>
<h1 class="charname"><input name="name" type="text" value="{{name}}" placeholder="Name" /></h1>
</div>
<div class="flexrow flex-group-center flex-actions-bar">
<div>
@ -19,8 +19,8 @@
</div>
<div class="flexrow">
{{#if calc.surprise}}{{calc.surprise}}! {{/if}}
{{#if actor.effects}}
{{#each actor.effects as |effect key|}}
{{#if effects}}
{{#each effects as |effect key|}}
<span id="effect-{{effect.flags.core.status.statusId}} ">
<img class="button-effect-img" src="{{effect.icon}}" alt="{{effect.label}}" width="24" height="24" />
</span>
@ -55,7 +55,7 @@
<ol class="carac-list alterne-list">
{{#each data.carac as |carac key|}}
<li class="competence flexrow list-item" data-attribute="{{key}}">
{{#if carac.isTaille}}
{{#if (eq key 'taille')}}
<span class="carac-label flexrow" name="data.carac.{{key}}.label">{{carac.label}}</span>
{{else}}
<span class="carac-label flexrow" name="data.carac.{{key}}.label"><a
@ -113,18 +113,15 @@
<div class="flexcol">
<div class="flex-group-left flexcol competence-column">
<ol class="item-list alterne-list">
{{#each data.competencecreature as |comp key|}}
{{#each competences as |comp key|}}
<li class="item flexrow list-item" data-item-id="{{comp._id}}">
<img class="sheet-competence-img" src="{{comp.img}}" />
<span class="competence-label"><a>{{comp.name}}</a></span>
<input class="competence-value creature-carac" type="text"
name="data.competencecreature[{{key}}].data.carac_value" compname="{{comp.name}}"
<input class="competence-value creature-carac" type="text" compname="{{comp.name}}"
value="{{comp.data.carac_value}}" data-dtype="number" />
<input class="competence-value creature-niveau" type="text"
compname="{{comp.name}}"
<input class="competence-value creature-niveau" type="text" compname="{{comp.name}}"
value="{{numberFormat comp.data.niveau decimals=0 sign=true}}" data-dtype="number" />
<input class="competence-value creature-dommages" type="text"
name="data.competencecreature[{{key}}]].data.dommages" compname="{{comp.name}}"
<input class="competence-value creature-dommages" type="text" compname="{{comp.name}}"
value="{{numberFormat comp.data.dommages decimals=0 sign=true}}" data-dtype="number" />
<div class="item-controls">
<a class="item-control item-edit" title="Edit Item"><i class="fas fa-edit"></i></a>

View File

@ -2,10 +2,10 @@
{{!-- Sheet Header --}}
<header class="sheet-header">
<img class="profile-img" src="{{actor.img}}" data-edit="img" title="{{actor.name}}" />
<img class="profile-img" src="{{img}}" data-edit="img" title="{{name}}" />
<div class="header-fields">
<div class="flexrow">
<h1 class="charname"><input name="name" type="text" value="{{actor.name}}" placeholder="Name" /></h1>
<h1 class="charname"><input name="name" type="text" value="{{name}}" placeholder="Name" /></h1>
</div>
<div class="flexrow flex-group-center flex-actions-bar">
<div>
@ -33,7 +33,7 @@
<ol class="carac-list alterne-list">
{{#each data.carac as |carac key|}}
<li class="competence flexrow list-item" data-attribute="{{key}}">
{{#if carac.isTaille}}
{{#if (eq key 'taille')}}
<span class="carac-label flexrow" name="data.carac.{{key}}.label">{{carac.label}}</span>
{{else}}
<span class="carac-label flexrow" name="data.carac.{{key}}.label"><a
@ -71,7 +71,7 @@
<div class="flexcol">
<div class="flex-group-left flexcol competence-column">
<ol class="item-list alterne-list">
{{#each data.competencecreature as |comp key|}}
{{#each competences as |comp key|}}
<li class="item flexrow list-item" data-item-id="{{comp._id}}">
<img class="sheet-competence-img" src="{{comp.img}}" />
<span class="competence-label"><a>{{comp.name}}</a></span>

View File

@ -4,8 +4,8 @@
<header class="sheet-header">
<div class="header-fields">
<div class="flexrow">
<img class="profile-img" src="{{actor.img}}" data-edit="img" title="{{actor.name}}" />
<h1 class="charname"><input name="name" type="text" value="{{actor.name}}" placeholder="Name"/></h1>
<img class="profile-img" src="{{img}}" data-edit="img" title="{{name}}" />
<h1 class="charname"><input name="name" type="text" value="{{name}}" placeholder="Name"/></h1>
</div>
<div class="flexrow">
<ul class="flex-group-center flex-compteurs">
@ -75,8 +75,8 @@
</div>
<div>
{{#if calc.surprise}}{{calc.surprise}}! {{/if}}
{{#if actor.effects}}
{{#each actor.effects as |effect key|}}
{{#if effects}}
{{#each effects as |effect key|}}
<span id="effect-{{effect.flags.core.status.statusId}} ">
<img class="button-effect-img" src="{{effect.icon}}" alt="{{effect.label}}" width="24" height="24" />
</span>
@ -121,29 +121,29 @@
{{else}}
<li class="competence flexrow list-item" data-attribute="{{key}}">
{{/if}}
{{#if carac.isTaille}}
<span class="carac-label flexrow" name="data.carac.{{key}}.label">{{carac.label}}</span>
<input class="carac-value flexrow" type="text" name="data.carac.{{key}}.value" value="{{carac.value}}" data-dtype="{{carac.type}}" {{#unless @root.options.editCaracComp}}disabled{{/unless}} />
{{#if (eq key 'taille')}}
<span class="carac-label flexrow" name="data.carac.{{key}}.label">{{carac.label}}</span>
<input class="carac-value flexrow" type="text" name="data.carac.{{key}}.value" value="{{carac.value}}" data-dtype="{{carac.type}}" {{#unless @root.options.editCaracComp}}disabled{{/unless}} />
<label class="carac-xp flexrow"/>
{{else}}
{{#if carac.derivee}}
<span class="carac-label flexrow" name="data.carac.{{key}}.label"> <a name={{key}}>{{carac.label}}</a></span>
<label class="competence-value flexrow">{{carac.value}}</label>
<label class="carac-xp flexrow"/>
{{else}}
{{#if carac.derivee}}
<span class="carac-label flexrow" name="data.carac.{{key}}.label"> <a name={{key}}>{{carac.label}}</a></span>
<label class="competence-value flexrow">{{carac.value}}</label>
<label class="carac-xp flexrow"/>
{{else}}
{{#if carac.isLevelUp}}
<span class="carac-label flexrow tooltip tooltip-nobottom" name="data.carac.{{key}}.label">
<span class="tooltiptext ttt-xp">
Vous pouvez dépenser {{carac.xpNext}} points d'Experience pour augmenter de 1 votre caractéristique {{carac.label}}
</span>
<a name={{key}}>{{carac.label}}</a></span>
{{else}}
<span class="carac-label flexrow tooltip tooltip-nobottom" name="data.carac.{{key}}.label"><a name={{key}}>{{carac.label}}</a></span>
{{/if}}
<input class="carac-value flexrow" type="text" name="data.carac.{{key}}.value" value="{{carac.value}}" data-dtype="{{carac.type}}" {{#unless @root.options.editCaracComp}}disabled{{/unless}} />
<input class="carac-xp flexrow" type="text" name="data.carac.{{key}}.xp" value="{{carac.xp}}" data-dtype="number" {{#unless @root.options.editCaracComp}}disabled{{/unless}} />
{{else}}
{{#if carac.isLevelUp}}
<span class="carac-label flexrow tooltip tooltip-nobottom" name="data.carac.{{key}}.label">
<span class="tooltiptext ttt-xp">
Vous pouvez dépenser {{carac.xpNext}} points d'Experience pour augmenter de 1 votre caractéristique {{carac.label}}
</span>
<a name={{key}}>{{carac.label}}</a></span>
{{else}}
<span class="carac-label flexrow tooltip tooltip-nobottom" name="data.carac.{{key}}.label"><a name={{key}}>{{carac.label}}</a></span>
{{/if}}
{{/if}}
<input class="carac-value flexrow" type="text" name="data.carac.{{key}}.value" value="{{carac.value}}" data-dtype="{{carac.type}}" {{#unless @root.options.editCaracComp}}disabled{{/unless}} />
<input class="carac-xp flexrow" type="text" name="data.carac.{{key}}.xp" value="{{carac.xp}}" data-dtype="number" {{#unless @root.options.editCaracComp}}disabled{{/unless}} />
{{/if}}
{{/if}}
</li>
{{/each}}
<li class="competence flexrow">
@ -234,7 +234,7 @@
<span class="competence-title">Compétences générales</span>
</header>
<ul class="item-list alterne-list">
{{#each data.competenceByCategory.generale as |comp key|}}
{{#each competenceByCategory.generale as |comp key|}}
{{> "systems/foundryvtt-reve-de-dragon/templates/actor-sheet-competence-partial.html" comp}}
{{/each}}
</ul>
@ -243,7 +243,7 @@
<span class="competence-title">Compétences Particulières</span>
</header>
<ul class="item-list alterne-list">
{{#each data.competenceByCategory.particuliere as |comp key|}}
{{#each competenceByCategory.particuliere as |comp key|}}
{{> "systems/foundryvtt-reve-de-dragon/templates/actor-sheet-competence-partial.html" comp}}
{{/each}}
</ul>
@ -252,7 +252,7 @@
<span class="competence-title">Compétences Spécialisées</span>
</header>
<ul class="item-list alterne-list">
{{#each data.competenceByCategory.specialisee as |comp key|}}
{{#each competenceByCategory.specialisee as |comp key|}}
{{> "systems/foundryvtt-reve-de-dragon/templates/actor-sheet-competence-partial.html" comp}}
{{/each}}
</ul>
@ -263,7 +263,7 @@
<span class="competence-title">Compétences de Mêlée</span>
</header>
<ul class="item-list alterne-list">
{{#each data.competenceByCategory.melee as |comp key|}}
{{#each competenceByCategory.melee as |comp key|}}
{{> "systems/foundryvtt-reve-de-dragon/templates/actor-sheet-competence-partial.html" comp}}
{{/each}}
</ul>
@ -272,7 +272,7 @@
<span class="competence-title">Compétences de Tir</span>
</header>
<ul class="item-list alterne-list">
{{#each data.competenceByCategory.tir as |comp key|}}
{{#each competenceByCategory.tir as |comp key|}}
{{> "systems/foundryvtt-reve-de-dragon/templates/actor-sheet-competence-partial.html" comp}}
{{/each}}
</ul>
@ -281,7 +281,7 @@
<span class="competence-title">Compétences de Lancer</span>
</header>
<ul class="item-list alterne-list">
{{#each data.competenceByCategory.lancer as |comp key|}}
{{#each competenceByCategory.lancer as |comp key|}}
{{> "systems/foundryvtt-reve-de-dragon/templates/actor-sheet-competence-partial.html" comp}}
{{/each}}
</ul>
@ -290,7 +290,7 @@
<span class="competence-title">Connaissances</span>
</header>
<ul class="item-list alterne-list">
{{#each data.competenceByCategory.connaissance as |comp key|}}
{{#each competenceByCategory.connaissance as |comp key|}}
{{> "systems/foundryvtt-reve-de-dragon/templates/actor-sheet-competence-partial.html" comp}}
{{/each}}
</ul>
@ -299,7 +299,7 @@
<span class="competence-title">Draconic</span>
</header>
<ul class="item-list alterne-list">
{{#each data.competenceByCategory.draconic as |comp key|}}
{{#each competenceByCategory.draconic as |comp key|}}
{{> "systems/foundryvtt-reve-de-dragon/templates/actor-sheet-competence-partial.html" comp}}
{{/each}}
</ul>
@ -338,7 +338,7 @@
<span class="competence-title competence-value">Niveau</span>
<span class="competence-title competence-value">+dom</span>
</li>
{{#each data.combat as |arme key|}}
{{#each combat as |arme key|}}
<li class="item flexrow list-item" data-item-id="{{arme._id}}">
<span class="arme-label"><a data-competence-name="{{arme.data.competence}}">{{arme.name}}</a></span>
<span class="arme-initiative"><a data-arme-name="{{arme.name}}" data-competence-name="{{arme.data.competence}}">{{arme.data.initiative}}</a></span>
@ -463,7 +463,7 @@
<div class="tab connaissances" data-group="primary" data-tab="connaissances">
<h3>Oeuvres diverses :</h3>
<ul class="item-list alterne-list">
{{#each data.chants as |chant id|}}
{{#each chants as |chant id|}}
<li class="item flexrow list-item" data-item-id="{{chant._id}}"><span>Chant</span><span class="competence-title chant-label"><a>{{chant.name}} (niveau {{chant.data.niveau}})</a></span>
<div class="item-controls">
<a class="item-control item-edit" title="Edit Item"><i class="fas fa-edit"></i></a>
@ -471,7 +471,7 @@
</div>
</li>
{{/each}}
{{#each data.musiques as |musique id|}}
{{#each musiques as |musique id|}}
<li class="item flexrow list-item" data-item-id="{{musique._id}}"><span>Musique</span><span class="competence-title musique-label"><a>{{musique.name}} (niveau {{musique.data.niveau}})</a></span>
<div class="item-controls">
<a class="item-control item-edit" title="Edit Item"><i class="fas fa-edit"></i></a>
@ -479,7 +479,7 @@
</div>
</li>
{{/each}}
{{#each data.danses as |danse id|}}
{{#each danses as |danse id|}}
<li class="item flexrow list-item" data-item-id="{{danse._id}}"><span>Danse</span><span class="competence-title danse-label"><a>{{danse.name}} (niveau {{danse.data.niveau}})</a></span>
<div class="item-controls">
<a class="item-control item-edit" title="Edit Item"><i class="fas fa-edit"></i></a>
@ -487,7 +487,7 @@
</div>
</li>
{{/each}}
{{#each data.oeuvres as |oeuvre id|}}
{{#each oeuvres as |oeuvre id|}}
<li class="item flexrow list-item" data-item-id="{{oeuvre._id}}"><span>{{upperFirst oeuvre.data.competence}}</span><span class="competence-title oeuvre-label"><a>{{oeuvre.name}} (niveau {{oeuvre.data.niveau}})</a></span>
<div class="item-controls">
<a class="item-control item-edit" title="Edit Item"><i class="fas fa-edit"></i></a>
@ -495,7 +495,7 @@
</div>
</li>
{{/each}}
{{#each data.recettescuisine as |recette id|}}
{{#each recettescuisine as |recette id|}}
<li class="item flexrow list-item" data-item-id="{{recette._id}}"><span>Recette de cuisine</span><span class="competence-title recettecuisine-label"><a>{{recette.name}} (niveau {{recette.data.niveau}})</a></span>
<div class="item-controls">
<a class="item-control item-edit" title="Edit Item"><i class="fas fa-edit"></i></a>
@ -506,7 +506,7 @@
</ul>
<h3>Jeux :</h3>
<ul class="item-list alterne-list">
{{#each data.jeux as |jeu id|}}
{{#each jeux as |jeu id|}}
<li class="item flexrow list-item" data-item-id="{{jeu._id}}"><span class="competence-title jeu-label"><a>{{jeu.name}} (base {{jeu.data.base}})</a></span>
<div class="item-controls">
<a class="item-control item-edit" title="Edit Item"><i class="fas fa-edit"></i></a>
@ -517,7 +517,7 @@
</ul>
<h3>Recettes Alchimiques</h3>
<ul class="item-list alterne-list">
{{#each data.recettesAlchimiques as |recette id|}}
{{#each recettesAlchimiques as |recette id|}}
<li class="item flexrow list-item" data-item-id="{{recette._id}}"><span class="competence-title recette-label item-edit"><a>{{recette.name}}</a></span>
<div class="item-controls">
<a class="item-control item-edit" title="Edit Item"><i class="fas fa-edit"></i></a>
@ -528,7 +528,7 @@
</ul>
<h3>Tâches</h3><a id='creer-tache'>Créer une nouvelle Tâche</a>
<ul class="item-list alterne-list">
{{#each data.taches as |tache id|}}
{{#each taches as |tache id|}}
<li class="item flexrow list-item" data-item-id="{{tache._id}}"><span class="competence-title tache-label"><a>{{tache.name}} ({{tache.data.points_de_tache_courant}}/{{tache.data.points_de_tache}})</a></span>
<div class="item-controls">
<a class="item-control item-edit" title="Edit Item"><i class="fas fa-edit"></i></a>
@ -584,7 +584,7 @@
<div>
<h3>Sorts:</h3>
<ul class="item-list">
{{#each data.sorts as |mysort key|}}
{{#each sorts as |mysort key|}}
<li class="item flexrow" data-item-id="{{mysort._id}}" data-attribute="{{key}}">
<span class="sort-label"> <a data-id="{{mysort._id}}">{{mysort.name}}</a></span>
<span>{{mysort.data.draconic}} / {{mysort.data.difficulte}}</span>
@ -610,7 +610,7 @@
<div>
<h3>Méditations:</h3>
<ul class="item-list">
{{#each data.meditations as |meditation key|}}
{{#each meditations as |meditation key|}}
<li class="item flexrow" data-item-id="{{meditation._id}}" data-attribute="{{key}}">
<span class="meditation-label"><a data-id="{{meditation._id}}">{{meditation.name}} - {{meditation.data.competence}}</a></span>
<div class="item-controls">
@ -654,7 +654,7 @@
<hr>
<h3>Queues:</h3>
<ul class="flex-group-left">
{{#each data.queues as |queue key|}}
{{#each queues as |queue key|}}
<li class="item flexrow" data-attribute={{key}} data-item-id="{{queue._id}}">
<span class="queuesouffle-label"> <a data-item-id="{{queue._id}}">{{queue.name}}</a></span>
<div class="item-controls">
@ -665,7 +665,7 @@
</ul>
<h3>Souffles:</h3>
<ul class="item-list">
{{#each data.souffles as |souffle key|}}
{{#each souffles as |souffle key|}}
<li class="item flexrow" data-attribute={{key}} data-item-id="{{souffle._id}}">
<span class="queuesouffle-label"> <a data-item-id="{{souffle._id}}">{{souffle.name}}</a></span>
<div class="item-controls">
@ -676,7 +676,7 @@
</ul>
<h3>Tetes:</h3>
<ul class="item-list">
{{#each data.tetes as |tete key|}}
{{#each tetes as |tete key|}}
<li class="item flexrow" data-attribute={{key}} data-item-id="{{tete._id}}">
<span class="queuesouffle-label"> <a data-item-id="{{tete._id}}">{{tete.name}}</a></span>
<div class="item-controls">
@ -687,7 +687,7 @@
</ul>
<h3>Ombres de Thanatos:</h3>
<ul class="item-list">
{{#each data.ombres as |ombre key|}}
{{#each ombres as |ombre key|}}
<li class="item flexrow" data-attribute={{key}} data-item-id="{{ombre._id}}">
<span class="queuesouffle-label"> <a data-item-id="{{ombre._id}}">{{ombre.name}}</a></span>
<div class="item-controls">
@ -703,7 +703,7 @@
<div class="tab items" data-group="primary" data-tab="items">
<span class="item-name"><h4>Argent et Monnaies</h4></span>
<ul class="item-list alterne-list">
{{#each data.monnaie as |piece id|}}
{{#each monnaie as |piece id|}}
<li class="item flexrow list-item" data-item-id="{{piece._id}}">
<img class="sheet-competence-img" src="{{piece.img}}" title="{{piece.name}}"/>
<span class="competence-title competence-label">{{piece.name}}</span>
@ -736,7 +736,7 @@
<span class="competence-title competence-label">Enc.</span>
<span class="competence-title competence-label">Equiper/Editer/Suppr.</span>
</li>
{{#each data.objets as |item id|}}
{{#each objets as |item id|}}
{{#unless item.estContenu}}
{{#if (ne item.type 'conteneur')}}
<li class="item flexrow list-item" data-item-id="{{item._id}}">
@ -753,7 +753,7 @@
{{/if}}
{{/unless}}
{{/each}}
{{#each data.conteneurs as |conteneur id|}}
{{#each conteneurs as |conteneur id|}}
{{buildConteneur this}}
{{/each}}
</ul>
@ -863,6 +863,7 @@
<article class="flexcol">
<h3>Biographie : </h3>
<div class="form-group editor">
{{log 'biographie' data.biographie}}
{{editor content=data.biographie target="data.biographie" button=true owner=owner editable=editable}}
</div>
<h3>Notes : </h3>

View File

@ -2,10 +2,10 @@
{{!-- Sheet Header --}}
<header class="sheet-header">
<img class="profile-img" src="{{actor.img}}" data-edit="img" title="{{actor.name}}" />
<img class="profile-img" src="{{img}}" data-edit="img" title="{{name}}" />
<div class="header-fields">
<div class="flexrow">
<h1 class="charname"><input name="name" type="text" value="{{actor.name}}" placeholder="Name" /></h1>
<h1 class="charname"><input name="name" type="text" value="{{name}}" placeholder="Name" /></h1>
</div>
</div>
</header>