diff --git a/module/actor-sheet.js b/module/actor-sheet.js
index 7f60980a..a81838c6 100644
--- a/module/actor-sheet.js
+++ b/module/actor-sheet.js
@@ -126,25 +126,20 @@ export class RdDActorSheet extends RdDBaseActorSangSheet {
this.actor.conjurerPossession(poss)
})
- this.html.find('.subacteur-label a').click(async event => {
- let actorId = RdDSheetUtility.getEventItemData(event, 'actor-id');
- let actor = game.actors.get(actorId);
- if (actor) {
- actor.sheet.render(true);
- }
- });
+ this.html.find('.subacteur-coeur-toggle a').click(async event => {
+ const actorId = RdDSheetUtility.getEventItemData(event, 'actor-id')
+ const clickCoeurNombre = $(event.currentTarget).data("coeur-nombre")
+ this.toggleSubActeurCoeur(actorId, clickCoeurNombre)
+ })
+ this.html.find('.subacteur-open').click(async event => {
+ const subActorId = RdDSheetUtility.getEventItemData(event, 'subactor-id');
+ this.openSubActeur(subActorId);
+ })
this.html.find('.subacteur-delete').click(async event => {
const li = RdDSheetUtility.getEventElement(event);
- const actorId = li.data("actor-id");
- if (actorId) {
- const subActor = game.actors.get(actorId);
- RdDUtility.confirmerSuppressionSubacteur(this, subActor, li, () => {
- console.log('Delete : ', subActor.id);
- this.actor.removeSubacteur(subActor.id);
- RdDUtility.slideOnDelete(this, li);
- });
- }
- });
+ const subActorId = li.data("subactor-id");
+ this.deleteSubActeur(subActorId, li);
+ })
this.html.find('.experiencelog-delete').click(async event => {
const li = this.html.find(event.currentTarget)?.parents(".experiencelog");
const key = Number(li.data("key") ?? -1);
@@ -286,9 +281,8 @@ export class RdDActorSheet extends RdDBaseActorSangSheet {
}
getBlessure(event) {
- const itemId = this.html.find(event.currentTarget).parents(".item-blessure").data('item-id');
- const blessure = this.actor.getItem(itemId, 'blessure');
- return blessure;
+ const blessureId = this.html.find(event.currentTarget).parents(".item-blessure").data('item-id');
+ return this.actor.getItem(blessureId, 'blessure');
}
isCompetenceAffichable(competence) {
@@ -302,6 +296,36 @@ export class RdDActorSheet extends RdDBaseActorSangSheet {
super._onDropActor(event, dragData);
}
+ openSubActeur(actorId) {
+ let actor = game.actors.get(actorId);
+ if (actor) {
+ actor.sheet.render(true);
+ }
+ }
+
+ deleteSubActeur(actorId, li) {
+ if (actorId) {
+ const subActor = game.actors.get(actorId);
+ RdDUtility.confirmSubActeurDelete(this, subActor, li, () => {
+ console.log('Delete : ', subActor.id);
+ this.actor.removeSubActeur(subActor.id);
+ RdDUtility.slideOnDelete(this, li);
+ });
+ }
+ }
+
+ toggleSubActeurCoeur(actorId, toggleCoeur) {
+ console.log(this.actor, 'toggleSubActeurCoeur', actorId, toggleCoeur)
+ const coeur = this.actor.getPointsCoeur(actorId)
+ if (toggleCoeur <= coeur) {
+ this.actor.jetDeMoral('malheureuse');
+ this.actor.setPointsCoeur(actorId, Math.max(0, coeur - 1))
+ }
+ else {
+ this.actor.setPointsCoeur(actorId, Math.min(4, toggleCoeur))
+ }
+ }
+
/* -------------------------------------------- */
async selectTypeOeuvreToCreate() {
let types = RdDItem.getTypesOeuvres();
diff --git a/module/actor.js b/module/actor.js
index 2cfd990a..911e0855 100644
--- a/module/actor.js
+++ b/module/actor.js
@@ -83,29 +83,27 @@ export class RdDActor extends RdDBaseActorSang {
this.system.compteurs.chance.max = this.system.carac.chance.value;
}
+ $computeIsHautRevant() {
+ this.system.attributs.hautrevant.value = this.itemTypes['tete'].find(it => Grammar.equalsInsensitive(it.name, 'don de haut-reve'))
+ ? "Haut rêvant"
+ : "";
+ }
+
+ /* -------------------------------------------- */
canReceive(item) {
return ![TYPES.competencecreature, TYPES.tarot, TYPES.service].includes(item.type)
}
- /* -------------------------------------------- */
isPersonnage() { return true }
isHautRevant() { return this.system.attributs.hautrevant.value != "" }
- getReveActuel() {
- return Misc.toInt(this.system.reve?.reve?.value ?? this.carac.reve.value);
- }
-
- getChanceActuel() {
- return Misc.toInt(this.system.compteurs.chance?.value ?? 10);
- }
-
+ /* -------------------------------------------- */
getAgilite() { return Number(this.system.carac.agilite?.value ?? 0) }
getChance() { return Number(this.system.carac.chance?.value ?? 0) }
- /* -------------------------------------------- */
- getMoralTotal() {
- return Number(this.system.compteurs.moral?.value ?? 0);
- }
+ getReveActuel() { return Misc.toInt(this.system.reve?.reve?.value ?? this.carac.reve.value) }
+ getChanceActuel() { return Misc.toInt(this.system.compteurs.chance?.value ?? 10) }
+ getMoralTotal() { return Number(this.system.compteurs.moral?.value ?? 0) }
/* -------------------------------------------- */
getEtatGeneral(options = { ethylisme: false }) {
@@ -130,41 +128,19 @@ export class RdDActor extends RdDBaseActorSang {
}
/* -------------------------------------------- */
- getTache(id) {
- return this.findItemLike(id, 'tache');
- }
- getMeditation(id) {
- return this.findItemLike(id, 'meditation');
- }
- getChant(id) {
- return this.findItemLike(id, 'chant');
- }
- getDanse(id) {
- return this.findItemLike(id, 'danse');
- }
- getMusique(id) {
- return this.findItemLike(id, 'musique');
- }
- getOeuvre(id, type = 'oeuvre') {
- return this.findItemLike(id, type);
- }
- getJeu(id) {
- return this.findItemLike(id, 'jeu');
- }
- getRecetteCuisine(id) {
- return this.findItemLike(id, 'recettecuisine');
- }
- /* -------------------------------------------- */
- getDraconicList() {
- return this.itemTypes[TYPES.competence].filter(it => it.system.categorie == 'draconic')
- }
- /* -------------------------------------------- */
- getBestDraconic() {
- const list = this.getDraconicList()
- .sort(Misc.descending(it => it.system.niveau))
- return duplicate(list[0])
- }
+ getTache(id) { return this.findItemLike(id, 'tache') }
+ getMeditation(id) { return this.findItemLike(id, 'meditation') }
+ getChant(id) { return this.findItemLike(id, 'chant') }
+ getDanse(id) { return this.findItemLike(id, 'danse') }
+ getMusique(id) { return this.findItemLike(id, 'musique') }
+ getOeuvre(id, type = 'oeuvre') { return this.findItemLike(id, type) }
+ getJeu(id) { return this.findItemLike(id, 'jeu') }
+ getRecetteCuisine(id) { return this.findItemLike(id, 'recettecuisine') }
+ /* -------------------------------------------- */
+ getDemiReve() { return this.system.reve.tmrpos.coord }
+ getDraconicList() { return this.itemTypes[TYPES.competence].filter(it => it.system.categorie == 'draconic') }
+ getBestDraconic() { return duplicate(this.getDraconicList().sort(Misc.descending(it => it.system.niveau)).find(it => true)) }
getDraconicOuPossession() {
return [...this.getDraconicList().filter(it => it.system.niveau >= 0),
super.getDraconicOuPossession()]
@@ -172,36 +148,33 @@ export class RdDActor extends RdDBaseActorSang {
.find(it => true)
}
- getDemiReve() {
- return this.system.reve.tmrpos.coord;
+ /* -------------------------------------------- */
+ async $perteRevePotionsEnchantees() {
+ let potions = this.itemTypes[TYPES.potion]
+ .filter(it => it.system.categorie.toLowerCase().includes('enchant') && !potion.system.prpermanent)
+
+ const potionUpdates = Promise.all(potions.map(async potion => {
+ console.log(potion)
+ let nouveauReve = (potion.system.pr > 0) ? potion.system.pr - 1 : 0;
+ const message = await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-potionenchantee-chateaudormant.html`, {
+ pr: nouveauReve,
+ alias: this.name,
+ potionName: potion.name,
+ potionImg: potion.img
+ })
+ ChatMessage.create({
+ whisper: ChatUtility.getWhisperRecipientsAndGMs(this.name),
+ content: message
+ });
+ return { _id: potion._id, 'system.pr': nouveauReve };
+ }))
+ await this.updateEmbeddedDocuments('Item', potionUpdates);
}
- /* -------------------------------------------- */
- async verifierPotionsEnchantees() {
- let potionsEnchantees = this.filterItems(it => it.type == 'potion' && it.system.categorie.toLowerCase().includes('enchant'));
- for (let potion of potionsEnchantees) {
- if (!potion.system.prpermanent) {
- console.log(potion);
- let newPr = (potion.system.pr > 0) ? potion.system.pr - 1 : 0;
- let update = { _id: potion._id, 'system.pr': newPr };
- const updated = await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
-
- let messageData = {
- pr: newPr,
- alias: this.name,
- potionName: potion.name,
- potionImg: potion.img
- }
- ChatMessage.create({
- whisper: ChatUtility.getWhisperRecipientsAndGMs(this.name),
- content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-potionenchantee-chateaudormant.html`, messageData)
- });
- }
- }
- }
-
- /* -------------------------------------------- */
- hasArmeeMeleeEquipee() { // Return true si l'acteur possède au moins 1 arme de mêlée équipée
+ /** --------------------------------------------
+ * @returns true si l'acteur possède au moins 1 arme de mêlée équipée
+ */
+ hasArmeeMeleeEquipee() {
return this.itemTypes['arme'].find(it => it.system.equipe && it.system.competence != "")
}
@@ -229,12 +202,12 @@ export class RdDActor extends RdDBaseActorSang {
}
/* -------------------------------------------- */
- async grisReve(nGrisReve) {
+ async grisReve(nbJours) {
let message = {
whisper: ChatUtility.getWhisperRecipientsAndGMs(this.name),
- content: `${nGrisReve} jours de gris rêve sont passés. `
+ content: `${nbJours} jours de gris rêve sont passés. `
};
- for (let i = 0; i < nGrisReve; i++) {
+ for (let i = 0; i < nbJours; i++) {
await this.dormir(4, { grisReve: true });
await this._recuperationSante(message);
@@ -252,7 +225,7 @@ export class RdDActor extends RdDBaseActorSang {
}
async _recuperationSante(message) {
- const maladiesPoisons = this._maladiePoisons(message);
+ const maladiesPoisons = this.getMaladiePoisons();
const isMaladeEmpoisonne = maladiesPoisons.length > 0;
this._messageRecuperationMaladiePoisons(maladiesPoisons, message);
@@ -260,9 +233,8 @@ export class RdDActor extends RdDBaseActorSang {
await this._recupererVie(message, isMaladeEmpoisonne);
}
- _maladiePoisons(message) {
- const actifs = this.items.filter(item => item.type == 'maladie' || (item.type == 'poison' && item.system.active));
- return actifs;
+ getMaladiePoisons() {
+ return this.items.filter(item => item.type == 'maladie' || (item.type == 'poison' && item.system.active));
}
_messageRecuperationMaladiePoisons(maladiesPoisons, message) {
@@ -275,12 +247,9 @@ export class RdDActor extends RdDBaseActorSang {
case 1: message.content += ` d'un mal inconnu`; break;
default: message.content += ` de ${nonIdentifies.length} maux inconnus`; break;
}
+ if (identifies.length > 0 && nonIdentifies.length > 0) { message.content += ' et' }
if (identifies.length > 0) {
- if (nonIdentifies > 0) {
- message.content += ' et';
- } else {
- message.content += ' de ' + identifies.map(it => it.name).reduce(Misc.joining(', '));
- }
+ message.content += ' de ' + identifies.map(it => it.name).reduce(Misc.joining(', '));
}
}
}
@@ -300,7 +269,7 @@ export class RdDActor extends RdDBaseActorSang {
await this.retourSeuilDeReve(message);
await this.setBonusPotionSoin(0);
await this.retourSust(message);
- await this.verifierPotionsEnchantees();
+ await this.$perteRevePotionsEnchantees();
if (message.content != "") {
message.content = `A la fin Chateau Dormant, ${message.content}
Un nouveau jour se lève`;
ChatMessage.create(message);
@@ -794,10 +763,8 @@ export class RdDActor extends RdDBaseActorSang {
const toNiveau = compValue ?? RdDItemCompetence.getNiveauBase(competence.system.categorie, competence.getCategories());
this.notifyCompetencesTronc(competence, toNiveau);
const fromNiveau = competence.system.niveau;
- await this.updateEmbeddedDocuments('Item', [{ _id: competence.id, 'system.niveau': toNiveau }]);
+ await competence.update({ 'system.niveau': toNiveau });
await ExperienceLog.add(this, XP_TOPIC.NIVEAU, fromNiveau, toNiveau, competence.name, true);
- } else {
- console.log("Competence not found", idOrName);
}
}
@@ -821,13 +788,11 @@ export class RdDActor extends RdDBaseActorSang {
if (isNaN(toXp) || typeof (toXp) != 'number') toXp = 0;
const fromXp = competence.system.xp;
this.checkCompetenceXP(idOrName, toXp);
- await this.updateEmbeddedDocuments('Item', [{ _id: competence.id, 'system.xp': toXp }]);
+ await competence.update({ 'system.xp': toXp });
await ExperienceLog.add(this, XP_TOPIC.XP, fromXp, toXp, competence.name, true);
if (toXp > fromXp) {
RdDUtility.checkThanatosXP(idOrName);
}
- } else {
- console.log("Competence not found", idOrName);
}
}
@@ -837,23 +802,19 @@ export class RdDActor extends RdDBaseActorSang {
if (competence) {
if (isNaN(toXpSort) || typeof (toXpSort) != 'number') toXpSort = 0;
const fromXpSort = competence.system.xp_sort;
- await this.updateEmbeddedDocuments('Item', [{ _id: competence.id, 'system.xp_sort': toXpSort }]);
+ await competence.update({ 'system.xp_sort': toXpSort });
await ExperienceLog.add(this, XP_TOPIC.XPSORT, fromXpSort, toXpSort, competence.name, true);
if (toXpSort > fromXpSort) {
RdDUtility.checkThanatosXP(idOrName);
}
- } else {
- console.log("Competence not found", idOrName);
}
}
/* -------------------------------------------- */
async updateCompetenceArchetype(idOrName, compValue) {
- let competence = this.getCompetence(idOrName);
+ let competence = this.getCompetence(idOrName)
if (competence) {
- await this.updateEmbeddedDocuments('Item', [{ _id: competence.id, 'system.niveau_archetype': Math.max(compValue ?? 0, 0) }]);
- } else {
- console.log("Competence not found", idOrName);
+ await competence.update({ 'system.niveau_archetype': Math.max(compValue ?? 0, 0) });
}
}
@@ -909,12 +870,6 @@ export class RdDActor extends RdDBaseActorSang {
}
/* -------------------------------------------- */
- $computeIsHautRevant() {
- this.system.attributs.hautrevant.value = this.itemTypes['tete'].find(it => Grammar.equalsInsensitive(it.name, 'don de haut-reve'))
- ? "Haut rêvant"
- : "";
- }
-
malusEthylisme() {
return Math.min(0, (this.system.compteurs.ethylisme?.value ?? 0));
}
@@ -1299,7 +1254,7 @@ export class RdDActor extends RdDBaseActorSang {
if (exotisme < 0 || qualite < 0) {
const competence = qualite > 0 ? 'cuisine' : undefined
const difficulte = Math.min(exotisme, qualite)
- const rolled = await this.doRollCaracCompetence('volonte', competence, difficulte, { title: `tente de surmonter l'exotisme de ${item.name}` })
+ const rolled = await this.doRollCaracCompetence('volonte', competence, difficulte, { title: `tente de surmonter l'exotisme de ${item.name}` })
return rolled.isSuccess
}
return true;
@@ -2561,7 +2516,7 @@ export class RdDActor extends RdDBaseActorSang {
let item = this.getEmbeddedDocument('Item', itemID);
if (item?.isEquipable()) {
const isEquipe = !item.system.equipe;
- await this.updateEmbeddedDocuments('Item', [{ _id: item.id, "system.equipe": isEquipe }]);
+ await item.update({ "system.equipe": isEquipe });
this.computeEncTotal();
if (isEquipe)
this.verifierForceMin(item);
@@ -2677,85 +2632,106 @@ export class RdDActor extends RdDBaseActorSang {
}
/* -------------------------------------------- */
- listeVehicules() {
- const listeVehichules = this.system.subacteurs?.vehicules ?? [];
- return this._buildActorLinksList(listeVehichules, vehicle => RdDActor._vehicleData(vehicle));
+ static $transformSubActeurSuivant = (suivant, link) => {
+ return mergeObject(RdDBaseActor.extractActorMin(suivant), {
+ coeur: link.coeur ?? 0
+ })
+ };
+
+ listeSuivants(filter = suivant => true) {
+ return RdDActor.$buildSubActorLinks(
+ this.system.subacteurs.suivants.filter(filter), RdDActor.$transformSubActeurSuivant
+ )
}
- /* -------------------------------------------- */
- listeSuivants() {
- return this._buildActorLinksList(this.system.subacteurs?.suivants ?? []);
- }
-
- /* -------------------------------------------- */
- listeMontures() {
- return this._buildActorLinksList(this.system.subacteurs?.montures ?? []);
- }
-
- /* -------------------------------------------- */
- _buildActorLinksList(links, actorTransformation = it => RdDActor._buildActorData(it)) {
- return links.map(link => game.actors.get(link.id))
- .filter(it => it != undefined)
- .map(actorTransformation);
- }
-
- /* -------------------------------------------- */
- static _vehicleData(vehicle) {
- return {
- id: vehicle.id,
- name: vehicle.name,
- img: vehicle.img,
- system: {
- categorie: vehicle.system.categorie,
- etat: vehicle.system.etat
- }
- };
- }
-
- /* -------------------------------------------- */
- static _buildActorData(it) {
- return { id: it.id, name: it.name, img: it.img };
- }
-
- /* -------------------------------------------- */
- async pushSubacteur(actor, dataArray, dataPath, dataName) {
- let alreadyPresent = dataArray.find(attached => attached.id == actor._id);
- if (!alreadyPresent) {
- let newArray = duplicate(dataArray);
- newArray.push({ id: actor._id });
- await this.update({ [dataPath]: newArray });
- } else {
- ui.notifications.warn(dataName + " est déja attaché à ce Personnage.");
+ getSuivant(actorId) {
+ const suivant = this.system.subacteurs.suivants.find(it => it.id == actorId);
+ if (suivant) {
+ return RdDActor.$transformSubActeurSuivant(game.actors.get(actorId), suivant);
}
+ return undefined
+ }
+
+ /* -------------------------------------------- */
+ static $transformSubActeurVehicule = (vehicle, link) => {
+ return mergeObject(RdDBaseActor.extractActorMin(vehicle), {
+ system: { categorie: vehicle.system.categorie, etat: vehicle.system.etat }
+ })
+ };
+
+ listeVehicules() {
+ return RdDActor.$buildSubActorLinks(this.system.subacteurs.vehicules, RdDActor.$transformSubActeurVehicule)
+ }
+
+ /* -------------------------------------------- */
+ static $transformSubActeurCreature = (actor, link) => RdDBaseActor.extractActorMin(actor.id)
+
+ listeMontures() {
+ return RdDActor.$buildSubActorLinks(this.system.subacteurs.montures, RdDActor.$transformSubActeurCreature);
+ }
+
+ /* -------------------------------------------- */
+ static $buildSubActorLinks(subActors, actorTransformation = (actor, link) => undefined) {
+ if (!subActors) {
+ return []
+ }
+ return subActors.map(link => {
+ const actor = game.actors.get(link.id)
+ return actor ? actorTransformation(actor, link) : undefined
+ })
+ .filter(it => it != undefined)
+ .sort(Misc.ascending(it => it.name))
}
/* -------------------------------------------- */
addSubActeur(subActor) {
- if (subActor?.id == this.id) {
- ui.notifications.warn("Vous ne pouvez pas attacher un acteur à lui même")
+ if (!this.isAddSubActeurAllowed(subActor)) {
+ return
}
- else if (!subActor?.isOwner) {
- ui.notifications.warn("Vous n'avez pas les droits sur l'acteur que vous attachez.")
- }
- else {
- if (subActor.type == 'vehicule') {
- this.pushSubacteur(subActor, this.system.subacteurs.vehicules, 'system.subacteurs.vehicules', 'Ce Véhicule');
- } else if (subActor.type == 'creature') {
- this.pushSubacteur(subActor, this.system.subacteurs.montures, 'system.subacteurs.montures', 'Cette Monture');
- } else if (subActor.type == 'personnage') {
- this.pushSubacteur(subActor, this.system.subacteurs.suivants, 'system.subacteurs.suivants', 'Ce Suivant');
- }
+ const subActorOnlyId = { id: subActor._id };
+ if (subActor.type == 'vehicule') {
+ this.pushSubActeur(subActorOnlyId, this.system.subacteurs.vehicules, `system.subacteurs.vehicules`, `Le véhicule ${subActor.name}`)
+ } else if (subActor.type == 'creature') {
+ this.pushSubActeur(subActorOnlyId, this.system.subacteurs.montures, 'system.subacteurs.montures', `L'animal ${subActor.name}`)
+ } else if (subActor.type == 'personnage') {
+ this.pushSubActeur(subActorOnlyId, this.system.subacteurs.suivants, 'system.subacteurs.suivants', `Le compagnon ${subActor.name}`)
}
}
- /* -------------------------------------------- */
- async removeSubacteur(actorId) {
- let newVehicules = this.system.subacteurs.vehicules.filter(function (obj, index, arr) { return obj.id != actorId });
- let newSuivants = this.system.subacteurs.suivants.filter(function (obj, index, arr) { return obj.id != actorId });
- let newMontures = this.system.subacteurs.montures.filter(function (obj, index, arr) { return obj.id != actorId });
- await this.update({ 'system.subacteurs.vehicules': newVehicules }, { renderSheet: false });
- await this.update({ 'system.subacteurs.suivants': newSuivants }, { renderSheet: false });
- await this.update({ 'system.subacteurs.montures': newMontures }, { renderSheet: false });
+ async pushSubActeur(subActor, dataArray, dataPath, dataName) {
+ let alreadyPresent = dataArray.find(attached => attached.id == subActor.id);
+ if (!alreadyPresent) {
+ let newArray = [...dataArray, subActor]
+ await this.update({ [dataPath]: newArray });
+ } else {
+ ui.notifications.warn(dataName + " est déja attaché à " + this.name);
+ }
+ }
+
+ isAddSubActeurAllowed(subActor) {
+ if (subActor?.id == undefined) {
+ ui.notifications.warn("Aucun acteur à ajouter")
+ return false
+ }
+ if (subActor?.id == this.id) {
+ ui.notifications.warn("Vous ne pouvez pas attacher un acteur à lui même")
+ return false
+ }
+ else if (!subActor?.isOwner) {
+ ui.notifications.warn("Vous n'avez pas les droits sur l'acteur que vous attachez.")
+ return false
+ }
+ return true
+ }
+
+ async deleteSubActeur(actorId) {
+ ['vehicules', 'suivants', 'montures'].forEach(async type => {
+ const subList = this.system.subacteurs[type];
+ if (subList.find(it => it.id == actorId)) {
+ let newList = subList.filter(it => it.id != actorId)
+ await this.update({ [`system.subacteurs.${type}`]: newList }, { renderSheet: false });
+ }
+ })
}
/* -------------------------------------------- */
diff --git a/module/actor/base-actor-reve.js b/module/actor/base-actor-reve.js
index d6f5988f..6a361f74 100644
--- a/module/actor/base-actor-reve.js
+++ b/module/actor/base-actor-reve.js
@@ -174,7 +174,7 @@ export class RdDBaseActorReve extends RdDBaseActor {
}
const path = getFieldPath(fieldName);
if (path) {
- await this.updateEmbeddedDocuments('Item', [{ _id: competence.id, [path]: value }]); // updates one EmbeddedEntity
+ await competence.update({ [path]: value });
}
}
}
@@ -287,10 +287,10 @@ export class RdDBaseActorReve extends RdDBaseActor {
getCarac() {
// TODO: le niveau d'une entité de cauchemar devrait être exclu...
const carac = mergeObject(duplicate(this.system.carac),
- {
- 'reve-actuel': this.getCaracReveActuel(),
- 'chance-actuelle': this.getCaracChanceActuelle()
- });
+ {
+ 'reve-actuel': this.getCaracReveActuel(),
+ 'chance-actuelle': this.getCaracChanceActuelle()
+ });
return carac;
}
diff --git a/module/actor/base-actor-sheet.js b/module/actor/base-actor-sheet.js
index 447c2a31..20f2a5c2 100644
--- a/module/actor/base-actor-sheet.js
+++ b/module/actor/base-actor-sheet.js
@@ -15,7 +15,6 @@ export class RdDBaseActorSheet extends ActorSheet {
/** @override */
static get defaultOptions() {
- RdDUtility.initAfficheContenu();
return mergeObject(ActorSheet.defaultOptions, {
classes: ["rdd", "sheet", "actor"],
tabs: [{ navSelector: ".sheet-tabs", contentSelector: ".sheet-body", initial: "carac" }],
diff --git a/module/actor/base-actor.js b/module/actor/base-actor.js
index 0a3e0c03..ed43802e 100644
--- a/module/actor/base-actor.js
+++ b/module/actor/base-actor.js
@@ -29,21 +29,10 @@ export class RdDBaseActor extends Actor {
return entry && entry.length > 0 ? carac[entry[0]] : undefined;
}
- getCaracByName(name) {
- switch (Grammar.toLowerCaseNoAccent(name)) {
- case 'reve-actuel': case 'reve actuel':
- return this.getCaracReveActuel();
- case 'chance-actuelle': case 'chance-actuelle':
- return this.getCaracChanceActuelle();
- }
- return RdDBaseActor._findCaracByName(this.system.carac, name);
- }
-
static getDefaultImg(itemType) {
return game.system.rdd.actorClasses[itemType]?.defaultIcon ?? defaultItemImg[itemType];
}
- /* -------------------------------------------- */
static init() {
Hooks.on("preUpdateItem", (item, change, options, id) => RdDBaseActor.getParentActor(item)?.onPreUpdateItem(item, change, options, id));
Hooks.on("createItem", (item, options, id) => RdDBaseActor.getParentActor(item)?.onCreateItem(item, options, id));
@@ -98,17 +87,19 @@ export class RdDBaseActor extends Actor {
return game.actors.get(actorId)
}
+ static extractActorMin = (actor) => { return { id: actor?.id, type: actor?.type, name: actor?.name, img: actor?.img }; };
+
static getParentActor(document) {
return document?.parent instanceof Actor ? document.parent : undefined
}
/**
- * Cet methode surcharge Actor.create() pour ajouter si besoin des Items par défaut:
+ * Cette methode surcharge Actor.create() pour ajouter si besoin des Items par défaut:
* compétences et monnaies.
- *
- * @param {Object} actorData template d'acteur auquel ajouter des informations.
- * @param {Object} options optionspour customiser la création
- */
+ *
+ * @param {Object} actorData template d'acteur auquel ajouter des informations.
+ * @param {Object} options optionspour customiser la création
+ */
static async create(actorData, options) {
// import depuis un compendium
if (actorData instanceof Array) {
@@ -144,6 +135,17 @@ export class RdDBaseActor extends Actor {
super(docData, context);
}
+ getCaracByName(name) {
+ switch (Grammar.toLowerCaseNoAccent(name)) {
+ case 'reve-actuel': case 'reve actuel':
+ return this.getCaracReveActuel();
+ case 'chance-actuelle': case 'chance-actuelle':
+ return this.getCaracChanceActuelle();
+ }
+ return RdDBaseActor._findCaracByName(this.system.carac, name);
+ }
+
+ /* -------------------------------------------- */
/* -------------------------------------------- */
async _preCreate(data, options, user) {
await super._preCreate(data, options, user);
@@ -184,7 +186,7 @@ export class RdDBaseActor extends Actor {
}
return undefined;
}
-
+ listeSuivants(filter = suivant => true) { return [] }
listItems(type = undefined) { return (type ? this.itemTypes[type] : this.items); }
filterItems(filter, type = undefined) { return (type ? this.itemTypes[type] : this.items)?.filter(filter) ?? []; }
findItemLike(idOrName, type) {
@@ -242,7 +244,7 @@ export class RdDBaseActor extends Actor {
let item = this.getItem(id);
if (item && item.isInventaire()) {
const quantite = Math.max(0, item.system.quantite + value);
- await this.updateEmbeddedDocuments('Item', [{ _id: item.id, 'system.quantite': quantite }]);
+ await item.update({ 'system.quantite': quantite });
}
}
@@ -549,8 +551,7 @@ export class RdDBaseActor extends Actor {
}
/* -------------------------------------------- */
- /** Ajoute un item dans un conteneur, sur la base
- * de leurs ID */
+ /** Ajoute un item dans un conteneur, sur la base de leurs ID */
async ajouterDansConteneur(item, conteneur, onAjouterDansConteneur) {
if (!conteneur) {
// TODO: afficher
@@ -558,10 +559,8 @@ export class RdDBaseActor extends Actor {
}
else if (conteneur.isConteneur()) {
item.estContenu = true;
- await this.updateEmbeddedDocuments('Item', [{
- _id: conteneur.id,
- 'system.contenu': [...conteneur.system.contenu, item.id]
- }]);
+ const nouveauContenu = [...conteneur.system.contenu, item.id];
+ await conteneur.update({ 'system.contenu': nouveauContenu });
onAjouterDansConteneur(item.id, conteneur.id);
}
}
@@ -621,10 +620,8 @@ export class RdDBaseActor extends Actor {
async enleverDeConteneur(item, conteneur, onEnleverDeConteneur) {
if (conteneur?.isConteneur()) {
item.estContenu = false;
- await this.updateEmbeddedDocuments('Item', [{
- _id: conteneur.id,
- 'system.contenu': conteneur.system.contenu.filter(id => id != item.id)
- }]);
+ const contenu = conteneur.system.contenu.filter(id => id != item.id);
+ await conteneur.update({ 'system.contenu': contenu });
onEnleverDeConteneur();
}
}
@@ -645,20 +642,17 @@ export class RdDBaseActor extends Actor {
for (let item of itemsList) { // Second boucle pour traiter la remise en conteneurs
// gestion conteneur/contenu
if (item.conteneurId) { // l'Objet était dans un conteneur
- let newConteneurId = itemMap[item.conteneurId]; // Get conteneur
- let newConteneur = this.getItem(newConteneurId);
-
- let newItemId = itemMap[item.id]; // Get newItem
+ const newConteneurId = itemMap[item.conteneurId];
+ const newConteneur = this.getItem(newConteneurId);
+ const newItemId = itemMap[item.id]; // Get newItem
console.log('New conteneur filling!', newConteneur, newItemId, item);
- let contenu = duplicate(newConteneur.system.contenu);
- contenu.push(newItemId);
- await this.updateEmbeddedDocuments('Item', [{ _id: newConteneurId, 'system.contenu': contenu }]);
+ const nouveauContenu = [...newConteneur.system.contenu, newItemId]
+ await newConteneur.update({ 'system.contenu': nouveauContenu })
}
}
- for (let item of itemsList) {
- await sourceActor.deleteEmbeddedDocuments('Item', [item.id]);
- }
+ const deletedItemIds = itemsList.map(it => it.id)
+ await sourceActor.deleteEmbeddedDocuments('Item', deletedItemIds);
}
_buildMapOldNewId(itemsList, newItems) {
@@ -693,7 +687,7 @@ export class RdDBaseActor extends Actor {
async rollAppelChance() { this.actionImpossible("appel à la chance") }
async jetDeMoral() { this.actionImpossible("jet de moral") }
- async actionPrincipale(item, onActionItem = async () => { }) {
+ async actionPrincipale(item, onActionItem = async () => { }) {
switch (item.type) {
case TYPES.conteneur: return await item.sheet.render(true);
}
diff --git a/module/actor/creature.js b/module/actor/creature.js
index 254c7c0f..08eb6672 100644
--- a/module/actor/creature.js
+++ b/module/actor/creature.js
@@ -18,12 +18,11 @@ export class RdDCreature extends RdDBaseActorSang {
async remiseANeuf() {
await this.removeEffects(e => true);
await this.supprimerBlessures(it => true);
- const updates = {
+ await this.update({
'system.sante.endurance.value': this.system.sante.endurance.max,
'system.sante.vie.value': this.system.sante.vie.max,
'system.sante.fatigue.value': 0
- };
- await this.update(updates);
+ });
}
async finDeRoundBlessures() {
@@ -54,13 +53,11 @@ export class RdDCreature extends RdDBaseActorSang {
// déjà accordé
return;
}
- resonnance.actors.push(attacker.id);
- await this.update({ "system.sante.resonnance": resonnance });
+ await this.update({ "system.sante.resonnance": [...resonnance, attacker.id] });
}
else {
super.setEntiteReveAccordee(attacker)
}
}
-
}
diff --git a/module/actor/entite-sheet.js b/module/actor/entite-sheet.js
index 5feaa7db..482adc70 100644
--- a/module/actor/entite-sheet.js
+++ b/module/actor/entite-sheet.js
@@ -45,18 +45,17 @@ export class RdDActorEntiteSheet extends RdDBaseActorReveSheet {
const actorId = li.data("actor-id");
if (actorId) {
const actorResonance = game.actors.get(actorId);
- RdDUtility.confirmerSuppressionSubacteur(this, actorResonance, li, () => {
+ RdDUtility.confirmSubActeurDelete(this, actorResonance, li, () => {
console.log('Delete : ', actorId);
- this.removeSubacteur(actorId);
+ this.deleteSubActeur(actorId);
RdDUtility.slideOnDelete(this, li);
});
}
});
}
- async removeSubacteur(actorId) {
+ async deleteSubActeur(actorId) {
let newResonances = this.actor.system.sante.resonnance.actors.filter(id => id != actorId);
await this.actor.update({ 'system.sante.resonnance.actors': newResonances }, { renderSheet: false });
}
-
}
diff --git a/module/actor/vehicule-sheet.js b/module/actor/vehicule-sheet.js
index da24b32d..62a89ea1 100644
--- a/module/actor/vehicule-sheet.js
+++ b/module/actor/vehicule-sheet.js
@@ -6,8 +6,6 @@ export class RdDActorVehiculeSheet extends RdDBaseActorSheet {
/** @override */
static get defaultOptions() {
- RdDUtility.initAfficheContenu();
-
return mergeObject(RdDBaseActorSheet.defaultOptions, {
template: "systems/foundryvtt-reve-de-dragon/templates/actor-vehicule-sheet.html",
width: 640, height: 720,
diff --git a/module/dialog-select-target.js b/module/dialog-select-target.js
deleted file mode 100644
index dd6140ff..00000000
--- a/module/dialog-select-target.js
+++ /dev/null
@@ -1,37 +0,0 @@
-
-export class DialogSelectTarget extends Dialog {
- constructor(html, onSelectTarget, targets) {
- const options = {
- classes: ["rdd-dialog-select-target"],
- width: 'fit-content',
- height: 'fit-content',
- 'max-height': 600,
- 'z-index': 99999
- };
- const conf = {
- title: "Choisir une cible",
- content: html,
- buttons: {}
- };
- super(conf, options);
- this.onSelectTarget = onSelectTarget;
- this.targets = targets;
- }
-
- activateListeners(html) {
- super.activateListeners(html);
- this.html = html;
- this.html.find("li.select-target").click((event) => {
- this.targetSelected(this.html.find(event.currentTarget)?.data("token-id"));
- });
- }
-
-
- targetSelected(tokenId) {
- const target = this.targets.find(it => it.id == tokenId);
- this.close();
- if (target) {
- this.onSelectTarget(target);
- }
- }
-}
\ No newline at end of file
diff --git a/module/dialog-select.js b/module/dialog-select.js
new file mode 100644
index 00000000..cb7ccbc2
--- /dev/null
+++ b/module/dialog-select.js
@@ -0,0 +1,45 @@
+
+export class DialogSelect extends Dialog {
+ static extractIdNameImg(it) { return { id: it.id, name: it.name, img: it.img } }
+
+ static async select(selectData, onSelectChoice) {
+ const html = await renderTemplate("systems/foundryvtt-reve-de-dragon/templates/dialog-select.html", selectData)
+
+ const dialogData = {
+ title: selectData.title ?? selectData.label,
+ content: html,
+ buttons: {}
+ }
+
+ const dialogOptions = {
+ classes: ["rdd-dialog-select"],
+ width: 'fit-content',
+ height: 'fit-content',
+ 'max-height': 600,
+ 'z-index': 99999
+ }
+ new DialogSelect(dialogData, dialogOptions, selectData, onSelectChoice).render(true)
+ }
+
+ constructor(dialogData, dialogOptions, selectionData, onSelectChoice) {
+ super(dialogData, dialogOptions)
+ this.selectionData = selectionData
+ this.onSelectChoice = onSelectChoice
+ }
+
+ activateListeners(html) {
+ super.activateListeners(html)
+ this.html = html
+ this.html.find("li.select-choice").click(event =>
+ this.choiceSelected(this.html.find(event.currentTarget)?.data("id"))
+ )
+ }
+
+ choiceSelected(selectedId) {
+ const selected = this.selectionData.find(it => it.id == selectedId)
+ this.close()
+ if (selected) {
+ this.onSelectChoice(selected)
+ }
+ }
+}
\ No newline at end of file
diff --git a/module/misc.js b/module/misc.js
index e7ce38fe..354fef4d 100644
--- a/module/misc.js
+++ b/module/misc.js
@@ -205,6 +205,7 @@ export class Misc {
const subset = this.findAllLike(value, elements, options);
if (subset.length == 0) {
+ console.log(`Aucune ${options.description} pour ${value}`);
return undefined
}
if (subset.length == 1) {
diff --git a/module/rdd-bonus.js b/module/rdd-bonus.js
index 74a03a49..2df1b670 100644
--- a/module/rdd-bonus.js
+++ b/module/rdd-bonus.js
@@ -36,20 +36,18 @@ export class RdDBonus {
/* -------------------------------------------- */
static dmg(rollData, dmgActor, isEntiteIncarnee = false) {
- let dmg = { total: 0 };
- if (rollData.arme && rollData.arme.name.toLowerCase() == "esquive") {
- // Specific case management
- ui.notifications.warn("Calcul de bonus dégats sur esquive !");
- } else {
- dmg.dmgArme = RdDBonus._dmgArme(rollData);
- dmg.penetration = RdDBonus._peneration(rollData);
- dmg.dmgTactique = RdDBonus.dmgBonus(rollData.tactique);
- dmg.dmgParticuliere = RdDBonus._dmgParticuliere(rollData);
- dmg.dmgSurprise = RdDBonus.dmgBonus(rollData.ajustements?.attaqueDefenseurSurpris.used);
- dmg.dmgActor = rollData.selectedCarac ? RdDBonus._dmgPerso(dmgActor, rollData.selectedCarac.label, dmg.dmgArme) : 0;
- dmg.total = dmg.dmgSurprise + dmg.dmgTactique + dmg.dmgArme + dmg.dmgActor + dmg.dmgParticuliere;
- dmg.mortalite = RdDBonus._calculMortalite(rollData, isEntiteIncarnee)
+ const dmgArme = RdDBonus._dmgArme(rollData)
+ let dmg = {
+ total: 0,
+ dmgArme: dmgArme,
+ penetration: RdDBonus._peneration(rollData),
+ dmgTactique: RdDBonus.dmgBonus(rollData.tactique),
+ dmgParticuliere: RdDBonus._dmgParticuliere(rollData),
+ dmgSurprise: RdDBonus.dmgBonus(rollData.ajustements?.attaqueDefenseurSurpris.used),
+ mortalite: RdDBonus._calculMortalite(rollData, isEntiteIncarnee),
+ dmgActor: RdDBonus._dmgPerso(dmgActor, rollData.selectedCarac?.label, dmgArme)
}
+ dmg.total = dmg.dmgSurprise + dmg.dmgTactique + dmg.dmgArme + dmg.dmgActor + dmg.dmgParticuliere;
return dmg;
}
@@ -93,6 +91,9 @@ export class RdDBonus {
/* -------------------------------------------- */
static _dmgPerso(dmgActor, categorie, dmgArme) {
+ if (categorie == undefined) {
+ return 0
+ }
switch (categorie) {
case "Tir": return 0;
case "Lancer": return Math.max(0, Math.min(dmgArme, dmgActor));
diff --git a/module/rdd-utility.js b/module/rdd-utility.js
index d2a71c6b..ce41a0c7 100644
--- a/module/rdd-utility.js
+++ b/module/rdd-utility.js
@@ -99,7 +99,8 @@ const definitionsEncaissement = {
/* -------------------------------------------- */
export class RdDUtility {
-
+ // persistent handling of conteneur show/hide
+ static afficheContenu = {}
/* -------------------------------------------- */
static async init() {
Hooks.on("renderChatMessage", async (app, html, msg) => RdDUtility.onRenderChatMessage(app, html, msg));
@@ -165,9 +166,9 @@ export class RdDUtility {
'systems/foundryvtt-reve-de-dragon/templates/actor/inventaire.html',
'systems/foundryvtt-reve-de-dragon/templates/actor/inventaire-item.html',
"systems/foundryvtt-reve-de-dragon/templates/actor/inventaire-monnaie.html",
- 'systems/foundryvtt-reve-de-dragon/templates/actor/liens-animaux.html',
- 'systems/foundryvtt-reve-de-dragon/templates/actor/liens-suivants.html',
- 'systems/foundryvtt-reve-de-dragon/templates/actor/liens-vehicules.html',
+ 'systems/foundryvtt-reve-de-dragon/templates/actor/liens-animaux.hbs',
+ 'systems/foundryvtt-reve-de-dragon/templates/actor/liens-suivants.hbs',
+ 'systems/foundryvtt-reve-de-dragon/templates/actor/liens-vehicules.hbs',
'systems/foundryvtt-reve-de-dragon/templates/actor/commerce-inventaire.html',
'systems/foundryvtt-reve-de-dragon/templates/actor/commerce-inventaire-item.html',
//Items
@@ -323,24 +324,16 @@ export class RdDUtility {
}
/* -------------------------------------------- */
- static getNomEthylisme(niveauEthylisme) {
- let index = -niveauEthylisme;
- return index < 0 ? 'Aucun' : nomEthylisme[index];
- }
+ static getNomEthylisme(niveauEthylisme) { return niveauEthylisme > 0 ? 'Aucun' : nomEthylisme[-niveauEthylisme] }
- /* -------------------------------------------- */
- static initAfficheContenu() { // persistent handling of conteneur show/hide
- if (!this.afficheContenu)
- this.afficheContenu = {};
- }
/* -------------------------------------------- */
static toggleAfficheContenu(conteneurId) {
- this.afficheContenu[conteneurId] = !this.afficheContenu[conteneurId];
+ RdDUtility.afficheContenu[conteneurId] = !RdDUtility.afficheContenu[conteneurId];
}
/* -------------------------------------------- */
static getAfficheContenu(conteneurId) {
if (conteneurId)
- return this.afficheContenu[conteneurId];
+ return RdDUtility.afficheContenu[conteneurId];
return undefined;
}
@@ -651,8 +644,8 @@ export class RdDUtility {
/* -------------------------------------------- */
static async chatListeners(html) {
- RdDCombat.registerChatCallbacks(html);
- RdDEmpoignade.registerChatCallbacks(html);
+ RdDCombat.registerChatCallbacks(html)
+ RdDEmpoignade.registerChatCallbacks(html)
// Gestion spécifique message passeurs
html.on("click", '.tmr-passeur-coord a', event => {
@@ -811,7 +804,7 @@ export class RdDUtility {
}
/* -------------------------------------------- */
- static confirmerSuppressionSubacteur(sheet, subActor, htmlToDelete, onSuppression = ()=>{}) {
+ static confirmSubActeurDelete(sheet, subActor, htmlToDelete, onSuppression = ()=>{}) {
RdDConfirm.confirmer({
settingConfirmer: "confirmation-supprimer-lien-acteur",
content: `
Etes vous certain de vouloir supprimer le lien vers ${subActor.name} ?
`, diff --git a/module/settings/system-compendiums.js b/module/settings/system-compendiums.js index b28ecb47..9e977a73 100644 --- a/module/settings/system-compendiums.js +++ b/module/settings/system-compendiums.js @@ -301,11 +301,12 @@ export class CompendiumTableHelpers { table, isGM: game.user.isGM, }); - ChatMessage.create({ + const messageData = { user: game.user.id, whisper: game.user.id, content: flavorContent - }, { rollMode: "gmroll" }); + }; + ChatMessage.create(messageData, { rollMode: "gmroll" }); } } \ No newline at end of file diff --git a/module/targets.js b/module/targets.js index 7217bea1..09d83e5d 100644 --- a/module/targets.js +++ b/module/targets.js @@ -1,5 +1,5 @@ import { ENTITE_NONINCARNE } from "./constants.js"; -import { DialogSelectTarget } from "./dialog-select-target.js"; +import { DialogSelect } from "./dialog-select.js"; export class Targets { static listTargets() { @@ -11,10 +11,7 @@ export class Targets { } static extractTokenData(target) { - if (!target) { - return undefined - } - return { id: target.id, name: target.document.name, img: target.document.texture.src ?? target.actor.img ?? 'icons/svg/mystery-man.svg' }; + return { id: target?.id, name: target?.document.name, img: target?.document.texture.src ?? target?.actor.img ?? 'icons/svg/mystery-man.svg' }; } static isTargetEntite(target) { @@ -30,11 +27,12 @@ export class Targets { return; default: { - const tokens = targets.map(it => Targets.extractTokenData(it)) - const html = await renderTemplate("systems/foundryvtt-reve-de-dragon/templates/dialog-select-target.html", { - tokens: tokens - }); - new DialogSelectTarget(html, onSelectTarget, targets).render(true); + const selectData = { + title: "Choisir une cible", + label: "Choisir une seule des cibles", + list: targets.map(it => Targets.extractTokenData(it)) + }; + DialogSelect.select(selectData, onSelectTarget); } } } diff --git a/module/tmr/carte-tmr.js b/module/tmr/carte-tmr.js index b73822b2..94513e5f 100644 --- a/module/tmr/carte-tmr.js +++ b/module/tmr/carte-tmr.js @@ -4,10 +4,6 @@ import { PixiTMR } from "./pixi-tmr.js"; export class CarteTmr extends Draconique { - constructor() { - super(); - } - type() { return '' } match(item) { return false; } manualMessage() { return false } diff --git a/styles/simple.css b/styles/simple.css index 608e94c5..0ea124ce 100644 --- a/styles/simple.css +++ b/styles/simple.css @@ -135,7 +135,7 @@ section.window-content div.dialog-buttons { .strong-text { font-weight: bold; } -i:is(.fas, .far) { +i:is(.fas, .far, .fa-solid, .fa-regular, .fa-sharp ) { font-size: smaller; } @@ -199,6 +199,7 @@ i:is(.fas, .far) { object-fit: scale-down; object-position: 50% 0; margin: 0.1rem; + object-fit: contain; } .system-foundryvtt-reve-de-dragon .rdd-item-sheet-tarot img.profile-img { @@ -210,6 +211,7 @@ i:is(.fas, .far) { border: none; margin-right: 5px; object-position: 50% 0; + object-fit: contain; } .system-foundryvtt-reve-de-dragon img.equipement-inutilisable { vertical-align: bottom ; @@ -526,7 +528,7 @@ input:is(.blessure-premiers_soins, .blessure-soins_complets) { text-shadow: 1px 1px 4px rgba(60, 60, 60, 1); } -.rdd-dialog-select-target img.select-token-img { +.rdd-dialog-select img.select-img { -webkit-box-flex: 0; -ms-flex: 0 0 48px; flex: 0 0 48px; @@ -538,7 +540,7 @@ input:is(.blessure-premiers_soins, .blessure-soins_complets) { vertical-align: baseline; } -.rdd-dialog-select-target li.select-target { +.rdd-dialog-select li.select-choice { vertical-align: baseline; padding: 0.1rem; } @@ -1528,6 +1530,8 @@ table.table-nombres-astraux tr:hover { float: left; max-width: 64px; max-height: 64px; + height: 100%; + object-fit: contain; } #sidebar-tabs { diff --git a/templates/actor-sheet.html b/templates/actor-sheet.html index 265aa607..71c34d2d 100644 --- a/templates/actor-sheet.html +++ b/templates/actor-sheet.html @@ -140,12 +140,10 @@