Compare commits

..

45 Commits

Author SHA1 Message Date
8775df5285 Merge pull request 'Corrections v12' (#700) from VincentVk/foundryvtt-reve-de-dragon:v11 into v11
Reviewed-on: #700
2024-06-01 09:11:18 +02:00
a103239288 Passe de vérification mergeObject
Quand mergeObject est utilisé pour retourner une valeur, faire très
attention à ne pas passer un Item/Actor, ou une de ses sous parties
en premier paramètre sans préciser l'option { inplace: false }

Sinon, le premier paramètre subit une mutation!
2024-06-01 01:53:14 +02:00
0b1c5d0a3d Fix again achatVente
- remplacement des données/JSON dans le html par des Flags sur
  le ChatMessage
- extraction de la gestion des infos de ventes pour rassembler la
  génération du ChatMessage
- on ne perd plus la quantité ou le vendeur
- attention au mergeObject: il modifie le premier parametre, ce
  qui modifiait parfois l'acteur (!!!) et toujours la quantité de
  l'objet du vendeur lors de la création de l'objet de l'acheteur!
2024-06-01 01:50:48 +02:00
e19577eab2 Fix for v12 2024-05-31 21:48:19 +02:00
c3b502ff6c Fix V12 Fenêtre de recherche 2024-05-31 21:42:09 +02:00
db2ca2453e Foundry v11/v12 support 2024-05-27 08:53:57 +02:00
915283a674 Merge pull request '11.2.21 - Le questionnement d'Akarlikarlikar' (#699) from VincentVk/foundryvtt-reve-de-dragon:v11 into v11
Reviewed-on: #699
2024-05-27 07:17:09 +02:00
621bb4ebc3 Version 11.2.21 2024-05-27 00:57:12 +02:00
26e805cf46 Ajout de la date/heure aux messages 2024-05-27 00:55:18 +02:00
657566fb11 Les effets s'appliquent aux créatures 2024-05-26 22:43:07 +02:00
26e8853a94 Passage v12 2024-05-26 22:16:42 +02:00
4f69d3cf78 Expérience sur rêve et chance actuels
L'expérience en caractéristique sur les jets de
2024-05-26 22:15:10 +02:00
dfe4b47452 Message de confirmation rencontre TMR
Quand un haut-rêvant monte dans les TMR avec une rencontre en attente,
un message est affiché pour demander confirmation
2024-05-26 22:13:47 +02:00
80719d8c15 Merge pull request '## 11.2.20 - Le soulagement d'Akarlikarlikar' (#698) from VincentVk/foundryvtt-reve-de-dragon:v11 into v11
Reviewed-on: #698
2024-05-13 17:24:51 +02:00
5c59f76c17 Version 11.2.20 2024-05-13 01:58:06 +02:00
65525cfd79 Correction récupération seuil
La récupération de seuil sur Rêve de Dragon était empéchée
par la gestion d'expérience quand aucune expérience n'était
gagnée.

Le même problème pouvait arriver pour d'autres raisons.
2024-05-13 01:58:06 +02:00
042f5d0f69 Cleanup Promise.all pour multi async 2024-05-13 01:50:22 +02:00
19dd3b540c Astrologie: garder toutes les lectures d'un acteur 2024-05-13 01:50:21 +02:00
611b57c149 Adaptation des encaissement alternatifs
Les encaissement alternatifs fonctionnent avec la validation
d'encaissement par le MJ.

- l'ajout de la difficulté d'attaque au dégâts est indiqué dans
les bonus de dégâts
- pour les minimums sur les dés d'encaissement, si le MJ remplace
le jet, les minimums sont alors ignorés.
2024-05-13 01:50:21 +02:00
fedf8f3b29 Fix: accorder entités x2 si validation GR
Les entités pouvaient être accordées 2 fois en cas de validation
par le GR
2024-05-13 01:50:12 +02:00
d1ec67e485 Correction Tooltips foundry
Suite à changement des Tooltips RdD, adaptation des tooltips
standard foundry
2024-05-12 19:37:58 +02:00
7f7148e658 Preparation du passage en v12 2024-05-02 14:08:02 +02:00
bc35c8d80e Preparation du passage en v12 2024-05-01 09:13:21 +02:00
ad9e75c66d Merge pull request '11.2.19 - Les hémorroïdes d'Akarlikarlikar' (#697) from VincentVk/foundryvtt-reve-de-dragon:v11 into v11
Reviewed-on: #697
2024-05-01 08:59:34 +02:00
e946299810 Version 11.2.19 2024-05-01 01:12:28 +02:00
fad894704d Fix: encaisser dommages par MJ
Lorsque l'option d'encaisser les dommages était contrôlée
par le MJ, les données envoyées par les joueurs ne correspondaient
pas aux paramètres de la méthode à exécuter par le MJ.

De plus, l'envoi de l'attacker (Actor) était reçu comme un Object,
donc inutilisable en tant qu'Actor.
2024-05-01 01:08:50 +02:00
3365852210 Merge pull request '11.2.18' (#696) from VincentVk/foundryvtt-reve-de-dragon:v11 into v11
Reviewed-on: #696
2024-03-21 15:51:07 +01:00
d71bf27311 Version 11.2.18 - Le bourrichon d'Akarlikarlikar 2024-03-20 21:57:02 +01:00
e6da18bebd Ajout du bouton Montrer
Ajout du bouton Montrer dans les différentes listes
2024-03-20 21:55:18 +01:00
972ae74e2c Merge pull request '11.2.17 - Le cache-oeil d'Akarlikarlikar' (#695) from VincentVk/foundryvtt-reve-de-dragon:v11 into v11
Reviewed-on: #695
2024-03-10 08:57:28 +01:00
7969e74c8d Version 11.2.17 2024-03-10 00:53:45 +01:00
84ea3a6ea9 Fix: TMR qui ne s'affichent pas
Après un certain temps (changements de scènes?), les TMR ne
s'affichaient plus correctement.

Tentative de forcer le chargement des textures manquantes lors
de l'ouverture de la fenêtre de TMR.
2024-03-10 00:47:50 +01:00
7ada5577aa Ajout de l'information Ombre de Thanatos
Si Thanatos a été utilisé, la prochaine queue est une ombre
Un indicateur apparait dans l'onglet Haut-Rêve.
2024-03-10 00:24:02 +01:00
b0e28ef937 Fix: labels for / id
- Ajout de "for" sur labels
- suppression d'id inutiles
- corrections de for="xp" incorrects
- simplification css alchimie-title/blessure-title
2024-03-10 00:13:36 +01:00
6414f76d67 Fix: ignorer personnages joueurs non liés
Pour les fenêtres de stress/repos/voyage/astrologie, ignorer
les personnages non liés (par exemple, un guerrier sorde)
2024-03-09 23:12:13 +01:00
dde3011f1d Fix: Checkbox cacher les points de tâche 2024-03-09 19:50:00 +01:00
6dbf322efe Fix: traduction tooltip Ediot/Delete 2024-03-09 19:49:31 +01:00
d34fde2ba4 Fix: titre des feuilles d'objets
Suite à la correction de l'ordre et du nom dans la fenêtre de création,
les titres étaient incorrects (TYPES.Item.Tache par exemple)
2024-03-09 19:48:53 +01:00
bc169d931b Fix: log erreur TMR en mode visu
En mode visualisation, les informations du personnage ne sont
pas affichées
2024-03-09 19:38:53 +01:00
3b269b2baa Simplifications 2024-03-09 19:13:13 +01:00
dffaa29fd1 Fix termes dans les fenetres de creation 2024-02-29 21:22:42 +01:00
c49e2a850b Fix termes dans les fenetres de creation 2024-02-29 20:59:06 +01:00
a5a9cc334e Fix termes dans les fenetres de creation 2024-02-29 20:45:25 +01:00
43e49a0eb8 New common CounterClass 2024-02-08 12:46:49 +01:00
5ab551da9e Rework usage log 2024-02-05 18:08:35 +01:00
130 changed files with 1059 additions and 914 deletions

View File

@ -1,4 +1,42 @@
# 11.2
## 11.2.22 - Le futur d'Akarlikarlikar
- correction de la vente par le tchat: seul le premier acheteur pouvait acheter
### Support V12
- adaptation fenêtre de recherche
## 11.2.21 - Le questionnement d'Akarlikarlikar
- Une confirmation spécifique est demandée pour monter dans les terres médianes en cas de rencontre en attente
- L'expérience en caractéristique sur les jets de chance et rêve actuels est mise dans la caractéristique correspondante
- Les effets s'appliquent correctement sur les créatures
- La date et l'heure (draconiques) sont affichées dans les messages du tchat
## 11.2.20 - Le soulagement d'Akarlikarlikar
- L'option "ajout de la difficulté d'attaque à l'encaissement" est affichée comme un modificateur d'encaissement
- Les options d'encaissement alternatives fonctionnent avec la validation de l'encaissement par le gardien
- La fenêtre d'astrologie du gardien affiche toutes les heures lues par un personnage
- Si aucune expérience n'est gagnée, les autres effets à appliquer (comme la récupération de seuil après avoir vaincu un rêve de Dragon) s'appliquent normalement
- Les tooltips de Foundry sont lisibles
- On n'accorde plus les entités de cauchemar deux fois quand le gardien valide les encaissements
- Les messages de récupération de rêve en cas de Rêve de Dragon sont clarifiés
## 11.2.19 - Les hémorroïdes d'Akarlikarlikar
- La validation des jets d'encaissement par le Gardien fonctionne de nouveau
## 11.2.18 - Le bourrichon d'Akarlikarlikar
- Les différentes listes de la feuille de personnage ont maintenant le bouton pour envoyer dans le tchat
## 11.2.17 - Le cache-oeil d'Akarlikarlikar
- Le titre des fenêtre d'objet affiche de nouveau le type traduit
- Les tooltips des boutons edit/delete sont maintenant en Français
- La case à cocher "Cacher les points de tâches" fonctionne de nouveau
- Les personnages non-liés ne sont plus dans les liste de personnages joueurs pour le repos, le stress, la fatigue
- L'utilisation de Thanatos est visible dans l'onglet Haut-Rêve pour indiquer que la prochaine queue est une ombre
- La fenêtre des TMRs ne devrait plus afficher une zone noire au lieu de la carte.
## 11.2.16 - Le Tri d'Akarlikarlikar
- Tri alphabétique des items dans la fenêtre de création
- Mise à jour comptage de monde
## 11.2.15 - La Table d'Akarlikarlikar
- Tirage automatique de la foce d'une rencontre (via la commande /tmrr)

4
icons/heures/.directory Normal file
View File

@ -0,0 +1,4 @@
[Dolphin]
Timestamp=2024,5,29,20,57,41.954
Version=4
VisibleRoles=Details_text,Details_size,Details_modificationtime,Details_creationtime,CustomizedDetails

View File

@ -1,55 +1,56 @@
{
"TYPES": {
"Actor": {
"Personnage": "Personnage",
"Creature": "Créature",
"Entite": "Entité de cauchemar",
"Commerce": "Commerce",
"Vehicule": "Véhicule"
"personnage": "Personnage",
"creature": "Créature",
"entite": "Entité de cauchemar",
"commerce": "Commerce",
"vehicule": "Véhicule"
},
"Item": {
"Arme": "Arme",
"Armure": "Armure",
"Blessure": "Blessure",
"Casetmr": "TMR spéciale",
"Chant": "Chant",
"Competence": "Compétence",
"Competencecreature": "Compétence de créature",
"Conteneur": "Conteneur",
"Danse": "Danse",
"Extraitpoetique": "Extrait poetique",
"Faune": "Faune",
"Gemme": "Gemme",
"Herbe": "Herbe",
"Ingredient": "Ingrédient",
"Jeu": "Jeu",
"Livre": "Livre",
"Maladie": "Maladie",
"Meditation": "Méditation",
"Monnaie": "Monnaie",
"Munition": "Munition",
"Musique": "Musique",
"Nombreastral": "Nombre astral",
"Nourritureboisson": "Nourriture & boisson",
"Objet": "Objet",
"Oeuvre": "Oeuvre",
"Ombre": "Ombre de Thanatos",
"Plante": "Plante",
"Poison": "Poison",
"Possession": "Possession",
"Potion": "Potion",
"Queue": "Queue de Dragon",
"Recettealchimique": "Recette alchimique",
"Recettecuisine": "Recette de cuisine",
"Rencontre": "Rencontre TMR",
"Service": "Service",
"Signedraconique": "Signe draconique",
"Sort": "Sort",
"Sortreserve": "Sort en réserve",
"Souffle": "Souffle de Dragon",
"Tache": "Tâche",
"Tarot": "Carte de tarot",
"Tete": "Tête de Dragon"
"arme": "Arme",
"armure": "Armure",
"blessure": "Blessure",
"casetmr": "Case TMR spéciale",
"chant": "Chant",
"competence": "Compétence",
"competencecreature": "Compétence de créature",
"conteneur": "Conteneur",
"danse": "Danse",
"empoignade": "Empoignade",
"extraitpoetique": "Extrait poetique",
"faune": "Faune",
"gemme": "Gemme",
"herbe": "Herbe",
"ingredient": "Ingrédient",
"jeu": "Jeu",
"livre": "Livre",
"maladie": "Maladie",
"meditation": "Méditation",
"monnaie": "Monnaie",
"munition": "Munition",
"musique": "Musique",
"nombreastral": "Nombre astral",
"nourritureboisson": "Nourriture & boisson",
"objet": "Objet",
"oeuvre": "Oeuvre",
"ombre": "Ombre de Thanatos",
"plante": "Plante",
"poison": "Poison",
"possession": "Possession",
"potion": "Potion",
"queue": "Queue de Dragon",
"recettealchimique": "Recette alchimique",
"recettecuisine": "Recette de cuisine",
"rencontre": "Rencontre TMR",
"service": "Service",
"signedraconique": "Signe draconique",
"sort": "Sort",
"sortreserve": "Sort en réserve",
"souffle": "Souffle de Dragon",
"tache": "Tâche",
"tarot": "Carte de tarot",
"tete": "Tête de Dragon"
}
},
"EFFECT": {

View File

@ -0,0 +1,70 @@
import { SYSTEM_RDD } from "../constants.js";
import { RdDUtility } from "../rdd-utility.js";
const DETAIL_VENTE = 'detailVente';
const NB_LOTS = 'nbLotss';
export class ChatVente {
static getDetailVente(chatMessageId) {
const chatMessage = game.messages.get(chatMessageId)
if (!chatMessage) {
return undefined;
}
const nbLots = chatMessage.getFlag(SYSTEM_RDD, NB_LOTS)
const detail = foundry.utils.duplicate(chatMessage.getFlag(SYSTEM_RDD, DETAIL_VENTE))
if (!detail.item) {
ui.notifications.warn("Impossible d'acheter: informations sur l'objet manquantes")
return undefined;
}
const vendeur = detail.vendeurId ? game.actors.get(detail.vendeurId) : undefined;
return foundry.utils.mergeObject(detail,
{
alias: vendeur?.name ?? game.user.name,
vendeur,
nbLots: nbLots,
chatMessageIdVente: chatMessageId
})
}
static getDetailAchatVente(chatMessageId) {
const acheteur = RdDUtility.getSelectedActor()
const detail = ChatVente.getDetailVente(chatMessageId)
if (!acheteur && !detail.vendeur) {
ui.notifications.info("Pas d'acheteur ni de vendeur, aucun changement");
return undefined;
}
return foundry.utils.mergeObject(detail, { acheteur })
}
static async setDetailAchatVente(chatMessage, vente) {
await chatMessage?.setFlag(SYSTEM_RDD, NB_LOTS, vente.nbLots)
await chatMessage?.setFlag(SYSTEM_RDD, DETAIL_VENTE, {
item: vente.item,
properties: vente.item.getProprietes(),
vendeurId: vente.vendeurId,
tailleLot: vente.tailleLot,
quantiteIllimite: vente.quantiteIllimite,
prixLot: vente.prixLot
})
}
static async diminuerQuantite(chatMessageId, quantite) {
const chatMessage = game.messages.get(chatMessageId)
const vente = ChatVente.getDetailVente(chatMessageId)
vente.nbLots = Math.max(0, vente.nbLots - quantite)
await chatMessage?.setFlag(SYSTEM_RDD, NB_LOTS, vente.nbLots)
const html = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-vente-item.html', vente);
chatMessage.update({ content: html });
chatMessage.render(true);
}
static async displayAchatVente(venteData) {
const html = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-vente-item.html', venteData);
const chatMessage = await ChatMessage.create(RdDUtility.chatDataSetup(html))
await ChatVente.setDetailAchatVente(chatMessage, venteData)
}
}

View File

@ -1,35 +1,13 @@
import { Misc } from "./misc.js";
import { RdDUtility } from "./rdd-utility.js";
import { Misc } from "../misc.js";
import { RdDUtility } from "../rdd-utility.js";
import { ChatVente } from "./chat-vente.js";
export class DialogItemAchat extends Dialog {
static preparerAchat(chatButton) {
const vendeurId = chatButton.attributes['data-vendeurId']?.value;
const vendeur = vendeurId ? game.actors.get(vendeurId) : undefined;
const acheteur = RdDUtility.getSelectedActor();
const json = chatButton.attributes['data-jsondata']?.value;
if (!acheteur && !vendeur) {
ui.notifications.info("Pas d'acheteur ni de vendeur, aucun changement");
return undefined;
}
if (!json) {
ui.notifications.warn("Impossible d'acheter: informations sur l'objet manquantes")
return undefined;
}
return {
item: JSON.parse(json),
vendeur,
acheteur,
nbLots: parseInt(chatButton.attributes['data-quantiteNbLots']?.value),
tailleLot: parseInt(chatButton.attributes['data-tailleLot']?.value ?? 1),
prixLot: Number(chatButton.attributes['data-prixLot']?.value ?? 0),
quantiteIllimite: chatButton.attributes['data-quantiteIllimite']?.value == 'true',
chatMessageIdVente: RdDUtility.findChatMessageId(chatButton),
};
return ChatVente.getDetailAchatVente(RdDUtility.findChatMessageId(chatButton))
}
static async onAcheter({ item, vendeur, acheteur, tailleLot, prixLot, nbLots, quantiteIllimite, chatMessageIdVente }) {
const venteData = {
item,
@ -38,17 +16,21 @@ export class DialogItemAchat extends Dialog {
acheteur,
tailleLot,
quantiteIllimite,
quantiteNbLots: nbLots,
nbLots,
choix: { seForcer: false, supprimerSiZero: true },
prixLot,
isVente: prixLot > 0,
isConsommable: item.type == 'nourritureboisson' && acheteur?.isPersonnage(),
chatMessageIdVente
};
}
if (venteData.vendeur?.id == venteData.acheteur?.id) {
ui.notifications.info("Inutile de se vendre à soi-même")
return
}
DialogItemAchat.changeNombreLots(venteData, 1);
const html = await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/dialog-item-achat.html`, venteData);
new DialogItemAchat(html, venteData).render(true);
DialogItemAchat.changeNombreLots(venteData, 1)
const html = await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/dialog-item-achat.html`, venteData)
new DialogItemAchat(html, venteData).render(true)
}
static changeNombreLots(venteData, nombreLots) {
@ -116,18 +98,18 @@ export class DialogItemAchat extends Dialog {
this.venteData.choix.seForcer = event.currentTarget.checked;
}
setNombreLots(nombreLots) {
setNombreLots(nbLots) {
if (!this.venteData.quantiteIllimite) {
if (!this.venteData.quantiteIllimite && nombreLots > this.venteData.quantiteNbLots) {
ui.notifications.warn(`Seulement ${this.venteData.quantiteNbLots} lots disponibles, vous ne pouvez pas en prendre ${nombreLots}`)
if (!this.venteData.quantiteIllimite && nbLots > this.venteData.nbLots) {
ui.notifications.warn(`Seulement ${this.venteData.nbLots} lots disponibles, vous ne pouvez pas en prendre ${nbLots}`)
}
nombreLots = Math.min(nombreLots, this.venteData.quantiteNbLots);
nbLots = Math.min(nbLots, this.venteData.nbLots);
}
DialogItemAchat.changeNombreLots(this.venteData, nombreLots);
DialogItemAchat.changeNombreLots(this.venteData, nbLots);
this.html.find(".nombreLots").val(nombreLots);
this.html.find(".nombreLots").val(nbLots);
this.html.find(".prixTotal").text(this.venteData.prixTotal);
this.html.find("span.total-sust").text(this.venteData.totalSust);
this.html.find("span.total-desaltere").text(this.venteData.totalDesaltere);

View File

@ -1,29 +1,30 @@
import { HtmlUtility } from "./html-utility.js";
import { HtmlUtility } from "../html-utility.js";
import { RdDUtility } from "../rdd-utility.js";
import { ChatVente } from "./chat-vente.js";
export class DialogItemVente extends Dialog {
static async display({ item, callback, quantiteMax = undefined }) {
static async display({ item, quantiteMax = undefined }) {
const quantite = quantiteMax ?? item.getQuantite() ?? 1;
const isOwned = item.parent;
const venteData = {
item: item,
alias: item.actor?.name ?? game.user.name,
vendeurId: item.actor?.id,
vendeurId: item.actor.id,
prixOrigine: item.calculerPrixCommercant(),
prixUnitaire: item.calculerPrixCommercant(),
prixLot: item.calculerPrixCommercant(),
tailleLot: 1,
quantiteNbLots: quantite,
quantiteMaxLots: quantite,
nbLots: quantite,
maxLots: quantite,
quantiteMax: quantite,
quantiteIllimite: item.isItemCommerce() ? quantiteMax == undefined : !isOwned,
isOwned: isOwned,
};
quantiteIllimite: item.isItemCommerce() ? quantiteMax == undefined : !item.parent,
isOwned: item.parent,
}
const html = await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/dialog-item-vente.html`, venteData);
return new DialogItemVente(venteData, html, callback).render(true);
return new DialogItemVente(venteData, html).render(true);
}
constructor(venteData, html, callback) {
constructor(venteData, html) {
let options = { classes: ["dialogvente"], width: 400, height: 'fit-content', 'z-index': 99999 };
let conf = {
@ -34,7 +35,6 @@ export class DialogItemVente extends Dialog {
};
super(conf, options);
this.callback = callback;
this.venteData = venteData;
}
@ -43,7 +43,7 @@ export class DialogItemVente extends Dialog {
this.html = html;
this.html.find(".tailleLot").change(event => this.setTailleLot(Number(event.currentTarget.value)));
this.html.find(".quantiteNbLots").change(event => this.setNbLots(Number(event.currentTarget.value)));
this.html.find(".nbLots").change(event => this.setNbLots(Number(event.currentTarget.value)));
this.html.find(".quantiteIllimite").change(event => this.setQuantiteIllimite(event.currentTarget.checked));
this.html.find(".prixLot").change(event => this.setPrixLot(Number(event.currentTarget.value)));
@ -52,16 +52,24 @@ export class DialogItemVente extends Dialog {
async onProposer(it) {
this.updateVente(this.getChoixVente());
this.callback(this.venteData);
this.venteData["properties"] = this.venteData.item.getProprietes();
if (this.venteData.isOwned) {
if (this.venteData.nbLots * this.venteData.tailleLot > this.venteData.quantiteMax) {
ui.notifications.warn(`Vous avez ${this.venteData.quantiteMax} ${this.venteData.item.name}, ce n'est pas suffisant pour vendre ${this.venteData.nbLots} de ${this.venteData.tailleLot}`)
return;
}
}
await ChatVente.displayAchatVente(this.venteData)
}
updateVente(update) {
mergeObject(this.venteData, update);
foundry.utils.mergeObject(this.venteData, update);
}
getChoixVente() {
return {
quantiteNbLots: Number(this.html.find(".quantiteNbLots").val()),
nbLots: Number(this.html.find(".nbLots").val()),
tailleLot: Number(this.html.find(".tailleLot").val()),
quantiteIllimite: this.html.find(".quantiteIllimite").is(':checked'),
prixLot: Number(this.html.find(".prixLot").val())
@ -77,26 +85,26 @@ export class DialogItemVente extends Dialog {
const maxLots = Math.floor(this.venteData.quantiteMax / tailleLot);
this.updateVente({
tailleLot,
quantiteNbLots: Math.min(maxLots, this.venteData.quantiteNbLots),
quantiteMaxLots: maxLots,
nbLots: Math.min(maxLots, this.venteData.nbLots),
maxLots: maxLots,
prixLot: (tailleLot * this.venteData.prixOrigine).toFixed(2)
});
this.html.find(".prixLot").val(this.venteData.prixLot);
this.html.find(".quantiteNbLots").val(this.venteData.quantiteNbLots);
this.html.find(".quantiteNbLots").attr("max", this.venteData.quantiteMaxLots)
this.html.find(".nbLots").val(this.venteData.nbLots);
this.html.find(".nbLots").attr("max", this.venteData.maxLots)
}
setNbLots(nbLots) {
this.updateVente({
quantiteNbLots: this.venteData.isOwned ? Math.max(0, Math.min(nbLots, this.venteData.quantiteMaxLots)) : nbLots
nbLots: this.venteData.isOwned ? Math.max(0, Math.min(nbLots, this.venteData.maxLots)) : nbLots
})
this.html.find(".quantiteNbLots").val(this.venteData.quantiteNbLots);
this.html.find(".nbLots").val(this.venteData.nbLots);
}
setQuantiteIllimite(checked) {
this.updateVente({ quantiteIllimite: checked })
this.html.find(".label-quantiteIllimite").text(this.venteData.quantiteIllimite ? "Illimités" : "disponibles");
HtmlUtility.showControlWhen(this.html.find(".quantiteNbLots"), !this.venteData.quantiteIllimite)
HtmlUtility.showControlWhen(this.html.find(".nbLots"), !this.venteData.quantiteIllimite)
}
}

View File

@ -16,7 +16,6 @@ import { RdDItem } from "./item.js";
import { RdDItemBlessure } from "./item/blessure.js";
import { RdDEmpoignade } from "./rdd-empoignade.js";
import { RdDBaseActorSangSheet } from "./actor/base-actor-sang-sheet.js";
import { ChatUtility } from "./chat-utility.js";
import { RdDCoeur } from "./coeur/rdd-coeur.js";
/* -------------------------------------------- */
@ -28,28 +27,26 @@ export class RdDActorSheet extends RdDBaseActorSangSheet {
/** @override */
static get defaultOptions() {
return mergeObject(RdDBaseActorReveSheet.defaultOptions, {
return foundry.utils.mergeObject(RdDBaseActorReveSheet.defaultOptions, {
template: "systems/foundryvtt-reve-de-dragon/templates/actor-sheet.html",
width: 550,
showCompNiveauBase: false,
vueArchetype: false,
});
}, { inplace: false });
}
/* -------------------------------------------- */
async getData() {
let formData = await super.getData();
mergeObject(formData,
{
editable: this.isEditable,
cssClass: this.isEditable ? "editable" : "locked",
effects: this.actor.effects.map(e => foundry.utils.deepClone(e)),
limited: this.actor.limited,
owner: this.actor.isOwner,
biographie: await TextEditor.enrichHTML(this.actor.system.biographie, { async: true }),
notes: await TextEditor.enrichHTML(this.actor.system.notes, { async: true }),
});
mergeObject(formData.calc, {
foundry.utils.mergeObject(formData, {
editable: this.isEditable,
cssClass: this.isEditable ? "editable" : "locked",
limited: this.actor.limited,
owner: this.actor.isOwner,
biographie: await TextEditor.enrichHTML(this.actor.system.biographie, { async: true }),
notes: await TextEditor.enrichHTML(this.actor.system.notes, { async: true }),
});
foundry.utils.mergeObject(formData.calc, {
surenc: this.actor.computeMalusSurEncombrement(),
surprise: RdDBonus.find(this.actor.getSurprise(false)).descr,
resumeBlessures: this.actor.computeResumeBlessure(this.actor.system.blessures),
@ -80,7 +77,7 @@ export class RdDActorSheet extends RdDBaseActorSangSheet {
// toujours avoir une liste d'armes (pour mettre esquive et corps à corps)
const actor = this.actor;
formData.combat = duplicate(formData.armes);
formData.combat = foundry.utils.duplicate(formData.armes);
RdDItemArme.computeNiveauArmes(formData.combat, formData.competences);
formData.combat.push(RdDItemArme.mainsNues(actor));
formData.combat.push(RdDItemArme.empoignade(actor));
@ -213,7 +210,7 @@ export class RdDActorSheet extends RdDBaseActorSangSheet {
const key = Number(li.data("key") ?? -1);
await this.actor.deleteExperienceLog(0, key + 1);
});
// Boutons spéciaux MJs
// Boutons spéciaux MJs
this.html.find('.forcer-tmr-aleatoire').click(async event => this.actor.reinsertionAleatoire("Action MJ"))
this.html.find('.afficher-tmr').click(async event => this.actor.changeTMRVisible())
}
@ -221,7 +218,7 @@ export class RdDActorSheet extends RdDBaseActorSangSheet {
// Points de reve actuel
this.html.find('.ptreve-actuel a').click(async event => this.actor.rollCarac('reve-actuel', true))
this.html.find('.empoignade-label a').click(async event => RdDEmpoignade.onAttaqueEmpoignadeFromItem(RdDSheetUtility.getItem(event, this.actor)))
this.html.find('.arme-label a').click(async event => this.actor.rollArme(duplicate(this._getEventArmeCombat(event))))
this.html.find('.arme-label a').click(async event => this.actor.rollArme(foundry.utils.duplicate(this._getEventArmeCombat(event))))
// Initiative pour l'arme
this.html.find('.arme-initiative a').click(async event => {
@ -388,7 +385,7 @@ export class RdDActorSheet extends RdDBaseActorSangSheet {
async _onSplitItem(item, split) {
if (split >= 1 && split < item.system.quantite) {
await item.diminuerQuantite(split);
const splitItem = duplicate(item);
const splitItem = foundry.utils.duplicate(item);
splitItem.system.quantite = split;
await this.actor.createEmbeddedDocuments('Item', [splitItem])
}

View File

@ -95,30 +95,32 @@ export class RdDActor extends RdDBaseActorSang {
return ![TYPES.competencecreature, TYPES.tarot, TYPES.service].includes(item.type)
}
isPersonnageJoueur() {
return this.hasPlayerOwner && this.prototypeToken.actorLink
}
isPersonnage() { return true }
isHautRevant() { return this.system.attributs.hautrevant.value != "" }
/* -------------------------------------------- */
getAgilite() { return Number(this.system.carac.agilite?.value ?? 0) }
getChance() { return Number(this.system.carac.chance?.value ?? 0) }
getAgilite() { return this.system.carac.agilite?.value ?? 0 }
getChance() { return this.system.carac.chance?.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) }
getReveActuel() { return this.system.reve?.reve?.value ?? this.carac.reve.value ?? 0 }
getChanceActuel() { return this.system.compteurs.chance?.value ?? 10 }
getMoralTotal() { return this.system.compteurs.moral?.value ?? 0 }
/* -------------------------------------------- */
getEtatGeneral(options = { ethylisme: false }) {
const etatGeneral = Misc.toInt(this.system.compteurs.etat?.value)
if (options.ethylisme) {
// Pour les jets d'Ethylisme, on retire le malus d'éthylisme (p.162)
return etatGeneral - this.malusEthylisme()
}
return etatGeneral
const etatGeneral = this.system.compteurs.etat?.value ?? 0
// Pour les jets d'Ethylisme, on retire le malus d'éthylisme (p.162)
const annuleMalusEthylisme = options.ethylisme ? this.malusEthylisme() : 0
return etatGeneral - annuleMalusEthylisme
}
/* -------------------------------------------- */
getActivePoisons() {
return duplicate(this.items.filter(item => item.type == 'poison' && item.system.active))
return foundry.utils.duplicate(this.items.filter(item => item.type == 'poison' && item.system.active))
}
/* -------------------------------------------- */
@ -141,7 +143,7 @@ export class RdDActor extends RdDBaseActorSang {
/* -------------------------------------------- */
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)) }
getBestDraconic() { return foundry.utils.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()]
@ -345,7 +347,7 @@ export class RdDActor extends RdDBaseActorSang {
const timestamp = game.system.rdd.calendrier.getTimestamp()
const blessures = this.filterItems(it => it.system.gravite > 0, TYPES.blessure).sort(Misc.ascending(it => it.system.gravite))
await Promise.all(blessures.map(b => b.recuperationBlessure({
await Promise.all(blessures.map(async b => b.recuperationBlessure({
actor: this,
timestamp,
message,
@ -427,7 +429,7 @@ export class RdDActor extends RdDBaseActorSang {
let jetsReve = [];
let dormi = await this.dormirDesHeures(jetsReve, message, heures, options);
if (jetsReve.length > 0) {
message.content += `Vous récupérez ${jetsReve.map(it => it < 0 ? '(dragon)' : it).reduce(Misc.joining("+"))} Points de rêve. `;
message.content += `Vous récupérez ${jetsReve.map(it => it < 0 ? '0 (réveil)' : it).reduce(Misc.joining("+"))} Points de rêve. `;
}
if (dormi.etat == 'eveil') {
await this.reveilReveDeDragon(message, dormi.heures);
@ -448,7 +450,6 @@ export class RdDActor extends RdDBaseActorSang {
}
async reveilReveDeDragon(message, heures) {
message.content += 'Vous êtes réveillé par un Rêve de Dragon.';
const restant = Math.max(this.system.sommeil?.heures - heures, 0)
if (restant > 0) {
await this.update({ 'system.sommeil': { heures: restant } });
@ -689,7 +690,7 @@ export class RdDActor extends RdDBaseActorSang {
}
let carac = this.findCaracByName(caracName);
if (carac) {
carac = duplicate(carac);
carac = foundry.utils.duplicate(carac);
const fromXp = Number(carac.xp);
const fromValue = Number(carac.value);
let toXp = fromXp;
@ -825,7 +826,7 @@ export class RdDActor extends RdDBaseActorSang {
async deleteExperienceLog(from, count) {
if (from >= 0 && count > 0) {
let expLog = duplicate(this.system.experiencelog);
let expLog = foundry.utils.duplicate(this.system.experiencelog);
expLog.splice(from, count);
await this.update({ [`system.experiencelog`]: expLog });
}
@ -901,7 +902,7 @@ export class RdDActor extends RdDBaseActorSang {
async ajouterRefoulement(value = 1, refouler) {
let refoulement = this.system.reve.refoulement.value + value;
const roll = new Roll("1d20");
await roll.evaluate({ async: true });
await roll.evaluate();
await roll.toMessage({ flavor: `${this.name} refoule ${refouler} pour ${value} points de refoulement (total: ${refoulement})` });
if (roll.total <= refoulement) {
refoulement = 0;
@ -990,25 +991,33 @@ export class RdDActor extends RdDBaseActorSang {
/* -------------------------------------------- */
buildTMRInnaccessible() {
const tmrInnaccessibles = this.filterItems(it => Draconique.isCaseTMR(it) &&
EffetsDraconiques.isInnaccessible(it));
return tmrInnaccessibles.map(it => it.system.coord);
return this.items[TYPES.casetmr]
.filter(it => EffetsDraconiques.isInnaccessible(it))
.map(it => it.system.coord)
}
/* -------------------------------------------- */
getTMRRencontres() {
return this.itemTypes['rencontre'];
getRencontresTMR() {
return this.itemTypes[TYPES.rencontre];
}
/* -------------------------------------------- */
async deleteTMRRencontreAtPosition() {
const demiReve = this.getDemiReve()
let rencontreIds = this.items.filter(it => it.type == 'rencontre' && it.system.coord == demiReve).map(it => it.id);
async deleteRencontreTMRAtPosition() {
const rencontreIds = this.itemTypes[TYPES.rencontre].filter(this.filterRencontreTMRDemiReve()).map(it => it.id)
if (rencontreIds.length > 0) {
await this.deleteEmbeddedDocuments('Item', rencontreIds);
await this.deleteEmbeddedDocuments('Item', rencontreIds)
}
}
getRencontreTMREnAttente() {
return this.itemTypes[TYPES.rencontre].find(this.filterRencontreTMRDemiReve())
}
filterRencontreTMRDemiReve() {
const position = this.getDemiReve()
return it => it.system.coord == position
}
/* -------------------------------------------- */
async addTMRRencontre(currentRencontre) {
const toCreate = currentRencontre.toObject();
@ -1140,6 +1149,7 @@ export class RdDActor extends RdDBaseActorSang {
finalLevel: 0,
diffConditions: 0,
ajustementsForce: CONFIG.RDD.difficultesLibres,
config: game.system.rdd.config
}
let html = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/dialog-roll-ethylisme.html', rollData);
new RdDRollDialogEthylisme(html, rollData, this, r => this.saouler(r.forceAlcool)).render(true);
@ -1310,7 +1320,7 @@ export class RdDActor extends RdDBaseActorSang {
/* -------------------------------------------- */
async saouler(forceAlcool, alcool = undefined) {
let ethylisme = duplicate(this.system.compteurs.ethylisme);
let ethylisme = foundry.utils.duplicate(this.system.compteurs.ethylisme);
const etat = this.getEtatGeneral({ ethylisme: true });
const nbDoses = Number(this.system.compteurs.ethylisme.nb_doses || 0);
@ -1331,7 +1341,7 @@ export class RdDActor extends RdDBaseActorSang {
}
await RdDResolutionTable.rollData(ethylismeData.jetVie);
this._appliquerExperienceRollData(ethylismeData.jetVie);
this._gererExperience(ethylismeData.jetVie);
RollDataAjustements.calcul(ethylismeData.jetVie, this);
if (ethylismeData.jetVie.rolled.isSuccess) {
ethylisme.nb_doses++;
@ -1363,7 +1373,7 @@ export class RdDActor extends RdDBaseActorSang {
finalLevel: Number(ethylisme.value) + Number(this.system.compteurs.moral.value)
}
await RdDResolutionTable.rollData(ethylismeData.jetVolonte);
this._appliquerExperienceRollData(ethylismeData.jetVolonte);
this._gererExperience(ethylismeData.jetVolonte);
RollDataAjustements.calcul(ethylismeData.jetVolonte, this);
}
}
@ -1487,7 +1497,7 @@ export class RdDActor extends RdDBaseActorSang {
const niveauSuivant = Number(carac.value) + 1;
let xpNeeded = RdDCarac.getCaracNextXp(niveauSuivant);
if (carac.xp >= xpNeeded) {
carac = duplicate(carac);
carac = foundry.utils.duplicate(carac);
carac.value = niveauSuivant;
let checkXp = {
@ -1517,7 +1527,7 @@ export class RdDActor extends RdDBaseActorSang {
if (compData && newXP > 0) {
let xpNeeded = RdDItemCompetence.getCompetenceNextXp(compData.system.niveau + 1);
if (newXP >= xpNeeded) {
let newCompData = duplicate(compData);
let newCompData = foundry.utils.duplicate(compData);
newCompData.system.niveau += 1;
newCompData.system.xp = newXP;
let checkXp = {
@ -1547,7 +1557,7 @@ export class RdDActor extends RdDBaseActorSang {
const content = await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-actor-gain-xp.html`, {
actor: this,
xpData
});
})
if (hideChatMessage) {
ChatUtility.blindMessageToGM({ content: content });
}
@ -1623,14 +1633,14 @@ export class RdDActor extends RdDBaseActorSang {
return;
}
// Duplication car les pts de reve sont modifiés dans le sort
let sorts = duplicate(this.$filterSortList(this.itemTypes['sort'], coord));
let sorts = foundry.utils.duplicate(this.$filterSortList(this.itemTypes['sort'], coord));
if (sorts.length == 0) {
ui.notifications.info(`Aucun sort disponible en ${TMRUtility.getTMR(coord).label} !`);
return;
}
const draconicList = this.computeDraconicAndSortIndex(sorts);
const reve = duplicate(this.system.carac.reve);
const reve = foundry.utils.duplicate(this.system.carac.reve);
const dialog = await this.openRollDialog({
name: 'lancer-un-sort',
@ -1729,7 +1739,7 @@ export class RdDActor extends RdDBaseActorSang {
else {
rollData.depenseReve = 0;
rollData.show.reveInsuffisant = true;
mergeObject(rollData.rolled, RdDResolutionTable.getResultat("echec"), { overwrite: true });
foundry.utils.mergeObject(rollData.rolled, RdDResolutionTable.getResultat("echec"), { overwrite: true });
}
} else {
if (rolled.isETotal) { // Echec total !
@ -1777,13 +1787,13 @@ export class RdDActor extends RdDBaseActorSang {
};
RollDataAjustements.calcul(rollData, this);
await RdDResolutionTable.rollData(rollData);
this._appliquerExperienceRollData(rollData);
this._gererExperience(rollData);
await RdDResolutionTable.displayRollData(rollData, this)
return rollData.rolled;
}
/* -------------------------------------------- */
_appliquerExperienceRollData(rollData) {
_gererExperience(rollData) {
const callback = this.createCallbackExperience();
if (callback.condition(rollData)) {
callback.action(rollData);
@ -1871,7 +1881,7 @@ export class RdDActor extends RdDBaseActorSang {
diffConditions: 0,
use: { libre: false, conditions: true },
carac: {
[tacheData.system.carac]: duplicate(this.system.carac[tacheData.system.carac])
[tacheData.system.carac]: foundry.utils.duplicate(this.system.carac[tacheData.system.carac])
}
},
callbackAction: r => this._tacheResult(r, options)
@ -1882,7 +1892,7 @@ export class RdDActor extends RdDBaseActorSang {
async _tacheResult(rollData, options) {
// Mise à jour de la tache
rollData.appliquerFatigue = ReglesOptionnelles.isUsing("appliquer-fatigue");
rollData.tache = duplicate(rollData.tache);
rollData.tache = foundry.utils.duplicate(rollData.tache);
rollData.tache.system.points_de_tache_courant += rollData.rolled.ptTache;
if (rollData.rolled.isETotal) {
rollData.tache.system.difficulte--;
@ -1906,21 +1916,21 @@ export class RdDActor extends RdDBaseActorSang {
/* -------------------------------------------- */
async _rollArt(artData, selected, oeuvre, callbackAction = r => this._resultArt(r)) {
oeuvre.system.niveau = oeuvre.system.niveau ?? 0;
mergeObject(artData,
foundry.utils.mergeObject(artData,
{
oeuvre: oeuvre,
art: oeuvre.type,
competence: duplicate(this.getCompetence(artData.compName ?? oeuvre.system.competence ?? artData.art)),
competence: foundry.utils.duplicate(this.getCompetence(artData.compName ?? oeuvre.system.competence ?? artData.art)),
diffLibre: - oeuvre.system.niveau,
diffConditions: 0,
use: { libre: false, conditions: true, surenc: false },
selectedCarac: duplicate(this.system.carac[selected])
selectedCarac: foundry.utils.duplicate(this.system.carac[selected])
},
{ overwrite: false });
artData.competence.system.defaut_carac = selected;
if (!artData.forceCarac) {
artData.forceCarac = {};
artData.forceCarac[selected] = duplicate(this.system.carac[selected]);
artData.forceCarac[selected] = foundry.utils.duplicate(this.system.carac[selected]);
}
await this.openRollDialog({
@ -1944,19 +1954,19 @@ export class RdDActor extends RdDBaseActorSang {
/* -------------------------------------------- */
async rollChant(id) {
const artData = { art: 'chant', verbe: 'Chanter' };
const oeuvre = duplicate(this.getChant(id));
const oeuvre = foundry.utils.duplicate(this.getChant(id));
await this._rollArt(artData, "ouie", oeuvre);
}
/* -------------------------------------------- */
async rollDanse(id) {
const artData = { art: 'danse', verbe: 'Danser', forceCarac: {} };
const oeuvre = duplicate(this.findItemLike(id, artData.art));
const oeuvre = foundry.utils.duplicate(this.findItemLike(id, artData.art));
if (oeuvre.system.agilite) {
artData.forceCarac['agilite'] = duplicate(this.system.carac.agilite);
artData.forceCarac['agilite'] = foundry.utils.duplicate(this.system.carac.agilite);
}
if (oeuvre.system.apparence) {
artData.forceCarac['apparence'] = duplicate(this.system.carac.apparence);
artData.forceCarac['apparence'] = foundry.utils.duplicate(this.system.carac.apparence);
}
const selectedCarac = this._getCaracDanse(oeuvre);
await this._rollArt(artData, selectedCarac, oeuvre);
@ -2059,7 +2069,7 @@ export class RdDActor extends RdDBaseActorSang {
const artData = {
art: 'jeu', verbe: 'Jeu',
use: { libre: true, conditions: true, },
competence: duplicate(this.getCompetence('jeu')),
competence: foundry.utils.duplicate(this.getCompetence('jeu')),
forceCarac: {}
};
listCarac.forEach(c => artData.forceCarac[c] = this.system.carac[c]);
@ -2070,14 +2080,14 @@ export class RdDActor extends RdDBaseActorSang {
async rollOeuvre(id) {
const artData = { art: 'oeuvre', verbe: 'Interpréter' }
const oeuvre = duplicate(this.findItemLike(id, artData.art))
const oeuvre = foundry.utils.duplicate(this.findItemLike(id, artData.art))
await this._rollArt(artData, oeuvre.system.default_carac, oeuvre)
}
/* -------------------------------------------- */
async rollMeditation(id) {
const meditation = duplicate(this.getMeditation(id));
const competence = duplicate(this.getCompetence(meditation.system.competence));
const meditation = foundry.utils.duplicate(this.getMeditation(id));
const competence = foundry.utils.duplicate(this.getCompetence(meditation.system.competence));
competence.system.defaut_carac = "intellect"; // Meditation = toujours avec intellect
let meditationData = {
competence: competence,
@ -2143,7 +2153,7 @@ export class RdDActor extends RdDBaseActorSang {
}
let draconicList = this.getDraconicList()
.map(draconic => {
let draconicLecture = duplicate(draconic);
let draconicLecture = foundry.utils.duplicate(draconic);
draconicLecture.system.defaut_carac = "intellect";
return draconicLecture;
});
@ -2267,7 +2277,7 @@ export class RdDActor extends RdDBaseActorSang {
async _appliquerExperience(rolled, caracName, competence, jetResistance) {
// Pas d'XP
if (!rolled.isPart || rolled.finalLevel >= 0) {
return undefined;
return []
}
if (this.checkDesirLancinant()) {
// Cas de désir lancinant, pas d'expérience sur particulière
@ -2275,7 +2285,7 @@ export class RdDActor extends RdDBaseActorSang {
content: `Vous souffrez au moins d'un Désir Lancinant, vous ne pouvez pas gagner d'expérience sur une Particulière tant que le désir n'est pas assouvi`,
whisper: ChatMessage.getWhisperRecipients(this.name)
});
return undefined;
return []
}
let xp = Math.abs(rolled.finalLevel);
@ -2312,7 +2322,7 @@ export class RdDActor extends RdDBaseActorSang {
/* -------------------------------------------- */
async _xpCarac(xpData) {
if (xpData.xpCarac > 0) {
const carac = duplicate(this.system.carac)
const carac = foundry.utils.duplicate(this.system.carac)
const code = RdDBaseActor._findCaracNode(carac, xpData.caracName)
const selectedCarac = carac[code]
if (this.isCaracMax(code)) {
@ -2336,7 +2346,7 @@ export class RdDActor extends RdDBaseActorSang {
async _xpCaracDerivee(xpData) {
const caracs = RdDActor._getComposantsCaracDerivee(xpData.caracName)
.map(c => mergeObject(this.system.carac[c], { isMax: this.isCaracMax(c) }))
.map(c => foundry.utils.mergeObject(this.system.carac[c], { isMax: this.isCaracMax(c) }, { inplace: false }))
switch (caracs.filter(it => !it.isMax).length) {
case 0:
xpData.caracRepartitionManuelle = true;
@ -2352,6 +2362,8 @@ export class RdDActor extends RdDBaseActorSang {
static _getComposantsCaracDerivee(caracName) {
switch (Grammar.toLowerCaseNoAccent(caracName)) {
case 'reve-actuel': case 'reve actuel': return ['reve']
case 'chance-actuelle': case 'chance actuelle': return ['chance']
case 'vie': return ['constitution']
case 'tir': return ['vue', 'dexterite']
case 'lancer': return ['force', 'dexterite', 'vue']
@ -2363,26 +2375,25 @@ export class RdDActor extends RdDBaseActorSang {
/* -------------------------------------------- */
async resetNombresAstraux() {
async deleteNombresAstraux() {
const deletions = this.itemTypes['nombreastral'].map(it => it._id);
await this.deleteEmbeddedDocuments("Item", deletions);
}
/* -------------------------------------------- */
async ajouteNombreAstral(callData) {
const indexDate = Number.parseInt(callData.date);
async ajouteNombreAstral(date, nbAstral, isValid) {
const indexDate = Number.parseInt(date);
// Ajout du nombre astral
const item = {
name: "Nombre Astral", type: "nombreastral", system:
{
value: callData.nbAstral,
istrue: callData.isvalid,
value: nbAstral,
istrue: isValid,
jourindex: indexDate,
jourlabel: RdDTimestamp.formatIndexDate(indexDate)
}
};
await this.createEmbeddedDocuments("Item", [item]);
game.system.rdd.calendrier.notifyChangeNombresAstraux();
}
async supprimerAnciensNombresAstraux() {
@ -2423,22 +2434,29 @@ export class RdDActor extends RdDBaseActorSang {
/* -------------------------------------------- */
async displayTMR(mode = "normal") {
if (this.tmrApp) {
ui.notifications.warn("Vous êtes déja dans les TMR....");
this.tmrApp.forceTMRDisplay();
ui.notifications.warn("Vous êtes déja dans les TMR....")
this.tmrApp.forceTMRDisplay()
return
}
if (mode != 'visu' && this.getEffect(STATUSES.StatusDemiReve)) {
ui.notifications.warn("Le joueur ou le MJ est déja dans les Terres Médianes avec ce personnage ! Visualisation uniquement");
ui.notifications.warn("Les personnage est déjà dans les Terres Médianes, elles s'affichent en visualisation")
mode = "visu"; // bascule le mode en visu automatiquement
}
RdDConfirm.confirmer({
bypass: mode == 'visu',
settingConfirmer: "confirmation-tmr",
content: `<p>Voulez vous monter dans les TMR en mode ${mode}?</p>`,
title: 'Confirmer la montée dans les TMR',
buttonLabel: 'Monter dans les TMR',
onAction: async () => await this._doDisplayTMR(mode)
});
if (mode == 'visu') {
await this._doDisplayTMR(mode)
}
else {
const rencontre = this.getRencontreTMREnAttente();
const settingConfirmer = rencontre ? "confirmation-tmr-rencontre" : "confirmation-tmr";
const messageRencontre = rencontre ? `<p>Vous devrez combattre ${rencontre.system.genre == 'f' ? 'la' : 'le'} ${rencontre.name} de ${rencontre.system.force} points de Rêve</p>` : '';
RdDConfirm.confirmer({
settingConfirmer: settingConfirmer,
content: `<p>Voulez vous monter dans les TMR en mode ${mode}?</p>` + messageRencontre,
title: 'Confirmer la montée dans les TMR',
buttonLabel: 'Monter dans les TMR',
onAction: async () => await this._doDisplayTMR(mode)
})
}
}
async _doDisplayTMR(mode) {
@ -2616,7 +2634,7 @@ export class RdDActor extends RdDBaseActorSang {
/* -------------------------------------------- */
async incDecItemUse(itemId, inc = 1) {
let itemUse = duplicate(this.getFlag(SYSTEM_RDD, 'itemUse') ?? {});
let itemUse = foundry.utils.duplicate(this.getFlag(SYSTEM_RDD, 'itemUse') ?? {});
itemUse[itemId] = (itemUse[itemId] ?? 0) + inc;
await this.setFlag(SYSTEM_RDD, 'itemUse', itemUse);
console.log("ITEM USE INC", inc, itemUse);
@ -2684,7 +2702,7 @@ export class RdDActor extends RdDBaseActorSang {
/* -------------------------------------------- */
static $transformSubActeurSuivant = (suivant, link) => {
return mergeObject(RdDBaseActor.extractActorMin(suivant), {
return foundry.utils.mergeObject(RdDBaseActor.extractActorMin(suivant), {
ephemere: !suivant.prototypeToken.actorLink,
coeur: link.coeur ?? 0,
prochainCoeur: link.prochainCoeur ?? link.coeur ?? 0
@ -2710,7 +2728,7 @@ export class RdDActor extends RdDBaseActorSang {
}
async setPointsCoeur(subActorId, coeurs, options = { immediat: false }) {
const newSuivants = duplicate(this.system.subacteurs.suivants)
const newSuivants = foundry.utils.duplicate(this.system.subacteurs.suivants)
const amoureux = newSuivants.find(it => it.id == subActorId);
if (amoureux) {
amoureux[options.immediat ? 'coeur' : 'prochainCoeur'] = coeurs
@ -2720,7 +2738,7 @@ export class RdDActor extends RdDBaseActorSang {
/* -------------------------------------------- */
static $transformSubActeurVehicule = (vehicle, link) => {
return mergeObject(RdDBaseActor.extractActorMin(vehicle), {
return foundry.utils.mergeObject(RdDBaseActor.extractActorMin(vehicle), {
system: { categorie: vehicle.system.categorie, etat: vehicle.system.etat }
})
};
@ -2967,9 +2985,6 @@ export class RdDActor extends RdDBaseActorSang {
}
}
/* -------------------------------------------- */
isEffectAllowed(effectId) { return true }
/* -------------------------------------------- */
async onPreUpdateItem(item, change, options, id) {
if (item.isCompetencePersonnage() && item.system.defaut_carac && item.system.xp) {
@ -3064,7 +3079,7 @@ export class RdDActor extends RdDBaseActorSang {
incarnation.name = 'Réincarnation de ' + incarnation.name
incarnation.system = {
carac: duplicate(this.system.carac),
carac: foundry.utils.duplicate(this.system.carac),
heure: RdDTimestamp.defHeure(await RdDDice.rollTotal("1dh", { rollMode: "selfroll", showDice: SHOW_DICE })).key,
age: 18,
biographie: '',

View File

@ -11,7 +11,7 @@ export class RdDBaseActorReveSheet extends RdDBaseActorSheet {
/** @override */
static get defaultOptions() {
return mergeObject(RdDBaseActorSheet.defaultOptions, {
return foundry.utils.mergeObject(RdDBaseActorSheet.defaultOptions, {
width: 550
});
}

View File

@ -180,7 +180,7 @@ export class RdDBaseActorReve extends RdDBaseActor {
}
/* -------------------------------------------- */
isEffectAllowed(effectId) { return true }
isEffectAllowed(effectId) { return false }
getEffects(filter = e => true) {
return this.getEmbeddedCollection("ActiveEffect").filter(filter);
@ -286,12 +286,12 @@ export class RdDBaseActorReve extends RdDBaseActor {
getCarac() {
// TODO: le niveau d'une entité de cauchemar devrait être exclu...
const carac = mergeObject(duplicate(this.system.carac),
return foundry.utils.mergeObject(this.system.carac,
{
'reve-actuel': this.getCaracReveActuel(),
'chance-actuelle': this.getCaracChanceActuelle()
});
return carac;
},
{ inplace: false })
}
/* -------------------------------------------- */
@ -425,21 +425,9 @@ export class RdDBaseActorReve extends RdDBaseActor {
if (attacker && !await attacker.accorder(this, 'avant-encaissement')) {
return;
}
const attackerId = attacker?.id;
if (ReglesOptionnelles.isUsing('validation-encaissement-gr') && !game.user.isGM) {
RdDBaseActor.remoteActorCall({
tokenId: this.token?.id,
actorId: this.id,
method: 'encaisserDommages',
args: [rollData, show, attackerId]
});
return;
}
const armure = await this.computeArmure(rollData);
if (ReglesOptionnelles.isUsing('validation-encaissement-gr')) {
DialogValidationEncaissement.validerEncaissement(this, rollData, armure,
jet => this.$onEncaissement(jet, show, attacker));
if (ReglesOptionnelles.isUsing('validation-encaissement-gr')){
await this.encaisserDommagesValidationGR(rollData, armure, attacker?.id, show);
}
else {
const jet = await RdDUtility.jetEncaissement(rollData, armure, { showDice: SHOW_DICE });
@ -447,6 +435,21 @@ export class RdDBaseActorReve extends RdDBaseActor {
}
}
async encaisserDommagesValidationGR(rollData, armure, attackerId, show) {
if (!game.user.isGM) {
RdDBaseActor.remoteActorCall({
tokenId: this.token?.id,
actorId: this.id,
method: 'encaisserDommagesValidationGR',
args: [rollData, armure, attackerId, show]
});
} else {
const attacker = game.actors.get(attackerId);
DialogValidationEncaissement.validerEncaissement(this, rollData, armure,
jet => this.$onEncaissement(jet, show, attacker));
}
}
async $onEncaissement(jet, show, attacker) {
await this.onAppliquerJetEncaissement(jet, attacker);
await this.$afficherEncaissement(jet, show);
@ -455,7 +458,7 @@ export class RdDBaseActorReve extends RdDBaseActor {
async onAppliquerJetEncaissement(encaissement, attacker) { }
async $afficherEncaissement(encaissement, show) {
mergeObject(encaissement, {
foundry.utils.mergeObject(encaissement, {
alias: this.name,
hasPlayerOwner: this.hasPlayerOwner,
show: show ?? {}
@ -467,7 +470,7 @@ export class RdDBaseActorReve extends RdDBaseActor {
});
if (!encaissement.hasPlayerOwner && encaissement.endurance != 0) {
encaissement = duplicate(encaissement);
encaissement = foundry.utils.duplicate(encaissement);
encaissement.isGM = true;
ChatMessage.create({
whisper: ChatMessage.getWhisperRecipients("GM"),

View File

@ -89,12 +89,12 @@ export class RdDBaseActorSang extends RdDBaseActorReve {
/* -------------------------------------------- */
async onAppliquerJetEncaissement(encaissement, attacker) {
const santeOrig = duplicate(this.system.sante);
const santeOrig = foundry.utils.duplicate(this.system.sante);
const blessure = await this.ajouterBlessure(encaissement, attacker); // Will update the result table
const perteVie = await this.santeIncDec("vie", -encaissement.vie);
const perteEndurance = await this.santeIncDec("endurance", -encaissement.endurance, blessure?.isCritique());
mergeObject(encaissement, {
foundry.utils.mergeObject(encaissement, {
resteEndurance: perteEndurance.newValue,
sonne: perteEndurance.sonne,
jetEndurance: perteEndurance.jetEndurance,
@ -108,7 +108,7 @@ export class RdDBaseActorSang extends RdDBaseActorReve {
if (name == 'fatigue' && !ReglesOptionnelles.isUsing("appliquer-fatigue")) {
return;
}
const sante = duplicate(this.system.sante)
const sante = foundry.utils.duplicate(this.system.sante)
let compteur = sante[name];
if (!compteur) {
return;
@ -135,7 +135,7 @@ export class RdDBaseActorSang extends RdDBaseActorReve {
result.perte = perte;
if (perte > 1) {
// Peut-être sonné si 2 points d'endurance perdus d'un coup
mergeObject(result, await this.jetEndurance(result.newValue));
foundry.utils.mergeObject(result, await this.jetEndurance(result.newValue));
} else if (inc > 0) {
await this.setSonne(false);
}
@ -269,6 +269,8 @@ export class RdDBaseActorSang extends RdDBaseActorReve {
return this.getEffect(STATUSES.StatusStunned);
}
isEffectAllowed(effectId) { return true }
/* -------------------------------------------- */
async computeEtatGeneral() { this.system.compteurs.etat.value = this.malusVie() + this.malusFatigue() + this.malusEthylisme() }
getEtatGeneral(options = { ethylisme: false }) { return this.system.compteurs.etat.value }

View File

@ -15,12 +15,12 @@ export class RdDBaseActorSheet extends ActorSheet {
/** @override */
static get defaultOptions() {
return mergeObject(ActorSheet.defaultOptions, {
return foundry.utils.mergeObject(ActorSheet.defaultOptions, {
classes: ["rdd", "sheet", "actor"],
tabs: [{ navSelector: ".sheet-tabs", contentSelector: ".sheet-body", initial: "carac" }],
dragDrop: [{ dragSelector: ".item-list .item", dropSelector: undefined }],
vueDetaillee: false
});
}, { inplace: false })
}
/* -------------------------------------------- */
@ -37,7 +37,9 @@ export class RdDBaseActorSheet extends ActorSheet {
system: this.actor.system,
description: await TextEditor.enrichHTML(this.actor.system.description, { async: true }),
notesmj: await TextEditor.enrichHTML(this.actor.system.notesmj, { async: true }),
options: RdDSheetUtility.mergeDocumentRights(this.options, this.actor, this.isEditable)
options: RdDSheetUtility.mergeDocumentRights(this.options, this.actor, this.isEditable),
effects: this.actor.effects,
config: game.system.rdd.config
}
RdDBaseActorSheet.filterItemsPerTypeForSheet(formData, this.actor.itemTypes);
@ -312,7 +314,7 @@ export class RdDBaseActorSheet extends ActorSheet {
async _onSplitItem(item, split) {
if (split >= 1 && split < item.system.quantite) {
await item.diminuerQuantite(split);
const splitItem = duplicate(item);
const splitItem = foundry.utils.duplicate(item);
splitItem.system.quantite = split;
await this.actor.createEmbeddedDocuments('Item', [splitItem])
}

View File

@ -1,3 +1,4 @@
import { ChatVente } from "../achat-vente/chat-vente.js";
import { ChatUtility } from "../chat-utility.js";
import { SYSTEM_SOCKET_ID } from "../constants.js";
import { Grammar } from "../grammar.js";
@ -8,7 +9,6 @@ import { RdDAudio } from "../rdd-audio.js";
import { RdDConfirm } from "../rdd-confirm.js";
import { RdDUtility } from "../rdd-utility.js";
import { SystemCompendiums } from "../settings/system-compendiums.js";
import { APP_ASTROLOGIE_REFRESH } from "../sommeil/app-astrologie.js";
export class RdDBaseActor extends Actor {
@ -16,7 +16,7 @@ export class RdDBaseActor extends Actor {
return Object.entries(carac)
.filter(it => Grammar.equalsInsensitive(it[1].label, name))
.map(it => it[0])
.find(it => it);
.find(it => it)
}
static $findCaracByName(carac, name) {
const caracList = Object.entries(carac);
@ -42,13 +42,6 @@ export class RdDBaseActor extends Actor {
switch (sockmsg.msg) {
case "msg_remote_actor_call":
return RdDBaseActor.onRemoteActorCall(sockmsg.data, sockmsg.userId);
case "msg_reset_nombre_astral":
game.user.character.resetNombresAstraux();
game.system.rdd.calendrier.notifyChangeNombresAstraux();
return;
case "msg_refresh_nombre_astral":
Hooks.callAll(APP_ASTROLOGIE_REFRESH);
return;
}
}
@ -85,6 +78,8 @@ export class RdDBaseActor extends Actor {
return game.actors.get(actorId)
}
isPersonnageJoueur() { return false }
static extractActorMin = (actor) => { return { id: actor?.id, type: actor?.type, name: actor?.name, img: actor?.img }; };
static getParentActor(document) {
@ -121,7 +116,7 @@ export class RdDBaseActor extends Actor {
constructor(docData, context = {}) {
if (!context.rdd?.ready) {
mergeObject(context, { rdd: { ready: true } });
foundry.utils.mergeObject(context, { rdd: { ready: true } });
const ActorConstructor = game.system.rdd.actorClasses[docData.type];
if (ActorConstructor) {
if (!docData.img) {
@ -366,16 +361,13 @@ export class RdDBaseActor extends Actor {
ChatUtility.notifyUser(achat.userId, 'warn', `Vous n'avez pas assez d'argent pour payer ${Math.ceil(cout / 100)} sols !`);
return;
}
await this.decrementerVente(vendeur, itemVendu, quantite, cout);
if (acheteur) {
await acheteur.depenserSols(cout);
const createdItemId = await acheteur.creerQuantiteItem(itemVendu, quantite);
await acheteur.consommerNourritureAchetee(achat, achat.vente, createdItemId);
}
await vendeur?.vendre(itemVendu, quantite, cout);
await acheteur?.acheter(itemVendu, quantite, cout, achat)
if (cout > 0) {
RdDAudio.PlayContextAudio("argent");
}
const chatAchatItem = duplicate(achat.vente);
const chatAchatItem = foundry.utils.duplicate(achat.vente);
chatAchatItem.quantiteTotal = quantite;
ChatMessage.create({
user: achat.userId,
@ -385,24 +377,26 @@ export class RdDBaseActor extends Actor {
});
if (!achat.vente.quantiteIllimite) {
if (achat.vente.quantiteNbLots <= achat.choix.nombreLots) {
if (achat.vente.nbLots <= achat.choix.nombreLots) {
ChatUtility.removeChatMessageId(achat.chatMessageIdVente);
}
else if (achat.chatMessageIdVente) {
achat.vente.properties = itemVendu.getProprietes();
achat.vente.quantiteNbLots -= achat.choix.nombreLots;
achat.vente.jsondata = JSON.stringify(achat.vente.item);
const messageVente = game.messages.get(achat.chatMessageIdVente);
messageVente.update({ content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-vente-item.html', achat.vente) });
messageVente.render(true);
await ChatVente.diminuerQuantite(achat.chatMessageIdVente, achat.choix.nombreLots)
}
}
}
async decrementerVente(vendeur, itemVendu, quantite, cout) {
if (vendeur) {
await vendeur.ajouterSols(cout);
await vendeur.decrementerQuantiteItem(itemVendu, quantite);
async vendre(item, quantite, cout) {
await this.ajouterSols(cout);
await this.decrementerQuantiteItem(item, quantite);
}
async acheter(item, quantite, cout, achat) {
await this.depenserSols(cout)
const createdItemId = await this.creerQuantiteItem(item, quantite)
if (achat.choix.consommer && item.type == 'nourritureboisson' && createdItemId != undefined) {
achat.choix.doses = achat.choix.nombreLots;
await this.consommerNourritureboisson(createdItemId, achat.choix, achat.vente.actingUserId);
}
}
@ -415,31 +409,28 @@ export class RdDBaseActor extends Actor {
return disponible == undefined || disponible >= quantiteDemande;
}
async consommerNourritureAchetee(achat, vente, createdItemId) {
if (achat.choix.consommer && vente.item.type == 'nourritureboisson' && createdItemId != undefined) {
achat.choix.doses = achat.choix.nombreLots;
await this.consommerNourritureboisson(createdItemId, achat.choix, vente.actingUserId);
}
}
async consommerNourritureboisson(itemId, choix, userId) { }
async decrementerQuantiteItem(item, quantite, options = { supprimerSiZero: true }) {
if (item.isService()) {
return;
}
const itemId = item.id;
let resteQuantite = (item.system.quantite ?? 1) - quantite;
if (resteQuantite <= 0) {
if (options.supprimerSiZero) {
await this.deleteEmbeddedDocuments("Item", [item.id]);
}
else {
await this.updateEmbeddedDocuments("Item", [{ _id: item.id, 'system.quantite': 0 }]);
await this.updateEmbeddedDocuments("Item", [{ _id: itemId, 'system.quantite': 0 }]);
}
if (resteQuantite < 0) {
ui.notifications.warn(`La quantité de ${item.name} était insuffisante, l'objet a donc été supprimé`)
}
}
else if (resteQuantite > 0) {
const realItem = this.getItem(item.id)
realItem.update({ 'system.quantite': resteQuantite });
await this.updateEmbeddedDocuments("Item", [{ _id: item.id, 'system.quantite': resteQuantite }]);
}
}
@ -451,7 +442,7 @@ export class RdDBaseActor extends Actor {
type: item.type,
img: item.img,
name: item.name,
system: mergeObject(item.system, { quantite: isItemEmpilable ? quantite : undefined })
system: foundry.utils.mergeObject(item.system, { quantite: isItemEmpilable ? quantite : undefined }, { inplace: false })
};
const newItems = isItemEmpilable ? [baseItem] : Array.from({ length: quantite }, (_, i) => baseItem);
const items = await this.createEmbeddedDocuments("Item", newItems);
@ -647,7 +638,7 @@ export class RdDBaseActor extends Actor {
sourceActor.buildSubConteneurObjetList(itemId, itemsList); // Get itemId list
const itemsDataToCreate = itemsList.map(it => sourceActor.getItem(it.id))
.map(it => duplicate(it))
.map(it => foundry.utils.duplicate(it))
.map(it => { it.system.contenu = []; return it; });
let newItems = await this.createEmbeddedDocuments('Item', itemsDataToCreate);

View File

@ -1,4 +1,4 @@
import { DialogItemAchat } from "../dialog-item-achat.js";
import { DialogItemAchat } from "../achat-vente/dialog-item-achat.js";
import { RdDItem } from "../item.js";
import { RdDUtility } from "../rdd-utility.js";
import { RdDBaseActorSheet } from "./base-actor-sheet.js";
@ -11,11 +11,11 @@ export class RdDCommerceSheet extends RdDBaseActorSheet {
/** @override */
static get defaultOptions() {
return mergeObject(super.defaultOptions, {
return foundry.utils.mergeObject(super.defaultOptions, {
template: "systems/foundryvtt-reve-de-dragon/templates/actor/commerce-actor-sheet.html",
width: 600, height: 720,
tabs: []
});
}, { inplace: false })
}
get title() {
if (this.actor.token && this.actor.token != this.actor.prototypeToken) {
@ -27,7 +27,7 @@ export class RdDCommerceSheet extends RdDBaseActorSheet {
async getData() {
const formData = await super.getData();
if (this.actor.token && this.actor.token != this.actor.prototypeToken) {
mergeObject(formData,
foundry.utils.mergeObject(formData,
{
title: this.actor.token.name,
token: {

View File

@ -25,8 +25,7 @@ export class RdDCommerce extends RdDBaseActor {
}
await super.depenserSols(cout)
}
async consommerNourritureAchetee(achat, vente, createdItemId) {
async consommerNourritureboisson(itemId, choix, userId) {
// ne pas consommer pour un commerce
}

View File

@ -9,10 +9,10 @@ export class RdDCreatureSheet extends RdDBaseActorSangSheet {
/** @override */
static get defaultOptions() {
return mergeObject(RdDBaseActorSangSheet.defaultOptions, {
return foundry.utils.mergeObject(RdDBaseActorSangSheet.defaultOptions, {
template: "systems/foundryvtt-reve-de-dragon/templates/actor-creature-sheet.html",
width: 640, height: 720
});
}, { inplace: false })
}
/* -------------------------------------------- */

View File

@ -33,10 +33,6 @@ export class RdDCreature extends RdDBaseActorSang {
}
}
isEffectAllowed(effectId) {
return [STATUSES.StatusComma].includes(effectId);
}
isEntiteAccordee(attacker) {
if (this.isEntite([ENTITE_INCARNE])) {
let resonnance = this.system.sante.resonnance
@ -48,7 +44,7 @@ export class RdDCreature extends RdDBaseActorSang {
/* -------------------------------------------- */
async setEntiteReveAccordee(attacker) {
if (this.isEntite([ENTITE_INCARNE])) {
let resonnance = duplicate(this.system.sante.resonnance);
let resonnance = foundry.utils.duplicate(this.system.sante.resonnance);
if (resonnance.actors.find(it => it == attacker.id)) {
// déjà accordé
return;

View File

@ -6,10 +6,10 @@ export class RdDActorEntiteSheet extends RdDBaseActorReveSheet {
/** @override */
static get defaultOptions() {
return mergeObject(RdDBaseActorReveSheet.defaultOptions, {
return foundry.utils.mergeObject(RdDBaseActorReveSheet.defaultOptions, {
template: "systems/foundryvtt-reve-de-dragon/templates/actor-entite-sheet.html",
width: 640, height: 720,
});
}, { inplace: false })
}
async getData() {

View File

@ -76,7 +76,7 @@ export class RdDEntite extends RdDBaseActorReve {
async onAppliquerJetEncaissement(encaissement, attacker) {
const perteEndurance = await this.santeIncDec("endurance", -encaissement.endurance);
mergeObject(encaissement, {
foundry.utils.mergeObject(encaissement, {
resteEndurance: perteEndurance.newValue,
endurance: perteEndurance.perte
});
@ -93,7 +93,7 @@ export class RdDEntite extends RdDBaseActorReve {
/* -------------------------------------------- */
async setEntiteReveAccordee(attacker) {
if (this.isEntite([ENTITE_INCARNE])) {
let resonnance = duplicate(this.system.sante.resonnance);
let resonnance = foundry.utils.duplicate(this.system.sante.resonnance);
if (resonnance.actors.find(it => it == attacker.id)) {
// déjà accordé
return;

View File

@ -12,7 +12,7 @@ export const XP_TOPIC = {
export class ExperienceLog {
static async add(actor, topic, from, to, raison, manuel = false) {
if (!actor.hasPlayerOwner || !actor.isPersonnage()) {
if (!actor.isPersonnageJoueur()) {
return
}
if (from == to) {

View File

@ -6,16 +6,16 @@ export class RdDActorVehiculeSheet extends RdDBaseActorSheet {
/** @override */
static get defaultOptions() {
return mergeObject(RdDBaseActorSheet.defaultOptions, {
return foundry.utils.mergeObject(RdDBaseActorSheet.defaultOptions, {
template: "systems/foundryvtt-reve-de-dragon/templates/actor-vehicule-sheet.html",
width: 640, height: 720,
});
}, { inplace: false })
}
/* -------------------------------------------- */
async getData() {
let formData = await super.getData();
mergeObject(formData,
foundry.utils.mergeObject(formData,
{
editable: this.isEditable,
cssClass: this.isEditable ? "editable" : "locked",

View File

@ -1,5 +1,6 @@
import { Misc } from "./misc.js";
import { SYSTEM_RDD, SYSTEM_SOCKET_ID } from "./constants.js";
import { RdDTimestamp } from "./time/rdd-timestamp.js";
/**
@ -131,7 +132,7 @@ export class ChatUtility {
/* -------------------------------------------- */
static blindMessageToGM(chatOptions) {
let chatGM = duplicate(chatOptions);
let chatGM = foundry.utils.duplicate(chatOptions);
chatGM.whisper = ChatUtility.getUsers(user => user.isGM);
chatGM.content = "Message aveugle de " + game.user.name + "<br>" + chatOptions.content;
console.log("blindMessageToGM", chatGM);
@ -163,4 +164,17 @@ export class ChatUtility {
return game.messages.get(chatMessageId);
}
static async onRenderChatMessage(chatMessage, html, data) {
const rddTimestamp = chatMessage.getFlag(SYSTEM_RDD, 'rdd-timestamp')
if (rddTimestamp) {
const timestamp = new RdDTimestamp(rddTimestamp);
const timestampData = timestamp.toCalendrier();
const dateHeure = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/common/date-heure.hbs', timestampData);
html.find('header.message-header .message-sender').after(dateHeure)
}
}
static async onCreateChatMessage(chatMessage, options, id) {
await chatMessage.setFlag(SYSTEM_RDD, 'rdd-timestamp', game.system.rdd.calendrier.getTimestamp());
}
}

View File

@ -69,7 +69,7 @@ export class RdDCoeur {
}
static async applyCoeurChateauDormant(actor, message) {
const newSuivants = duplicate(actor.system.subacteurs.suivants)
const newSuivants = foundry.utils.duplicate(actor.system.subacteurs.suivants)
let count = 0
newSuivants.forEach(async link => {
const suivant = game.actors.get(link.id)
@ -117,8 +117,8 @@ export class RdDCoeur {
}
ChatUtility.removeChatMessageId(infoCoeur.chatMessageId)
infoCoeur.target.jetTendre = (await (new Roll('1d6').evaluate({ async: true }))).total
infoCoeur.source.jetTendre = (await (new Roll('1d6').evaluate({ async: true }))).total
infoCoeur.target.jetTendre = (await (new Roll('1d6').evaluate())).total
infoCoeur.source.jetTendre = (await (new Roll('1d6').evaluate())).total
const diff = Math.abs(infoCoeur.source.jetTendre - infoCoeur.target.jetTendre)
for (let amoureux of [infoCoeur.source, infoCoeur.target]) {
const actorAmoureux = game.actors.get(amoureux.actor.id);

View File

@ -8,3 +8,46 @@ export const SHOW_DICE = 'show';
export const ENTITE_INCARNE = 'incarne';
export const ENTITE_NONINCARNE = 'nonincarne';
export const ENTITE_BLURETTE = 'blurette';
export const RDD_CONFIG = {
niveauEthylisme : [
{value: "1", label: "Aucun"},
{value: "0", label: "Eméché (0)"},
{value: "-1", label: "Gris (-1)"},
{value: "-2", label: "Pinté (-2)"},
{value: "-3", label: "Pas Frais (-3)"},
{value: "-4", label: "Ivre (-4)"},
{value: "-5", label: "Bu (-5)"},
{value: "-6", label: "Complètement fait (-6)"},
{value: "-7", label: "Ivre mort (-7)"}
],
categorieEntite: {
"cauchemar": "Cauchemar",
"reve": "Rêve"
},
typeEntite: {
"incarne": "Incarnée",
"nonincarne": "Non Incarnée",
"blurette": "Blurette"
},
heuresRdD : [
{value : "vaisseau", label: "Vaisseau", img: "modules/foundryvtt-reve-de-dragon/icons/heures/hd01.webp"},
{value : "sirene", label: "Sirène", img: "modules/foundryvtt-reve-de-dragon/icons/heures/hd02.webp"},
{value : "faucon", label: "Faucon", img: "modules/foundryvtt-reve-de-dragon/icons/heures/hd03.webp"},
{value : "couronne", label: "Couronne", img: "modules/foundryvtt-reve-de-dragon/icons/heures/hd04.webp"},
{value : "dragon", label: "Dragon", img: "modules/foundryvtt-reve-de-dragon/icons/heures/hd05.webp"},
{value : "epees", label: "Epées", img: "modules/foundryvtt-reve-de-dragon/icons/heures/hd06.webp"},
{value : "lyre", label: "Lyre", img: "modules/foundryvtt-reve-de-dragon/icons/heures/hd07.webp"},
{value : "serpent", label: "Serpent", img: "modules/foundryvtt-reve-de-dragon/icons/heures/hd08.webp"},
{value : "poissonacrobate", label: "Poisson Acrobate", img: "modules/foundryvtt-reve-de-dragon/icons/heures/hd09.webp"},
{value : "araignee", label: "Araignée", img: "modules/foundryvtt-reve-de-dragon/icons/heures/hd10.webp"},
{value : "roseau", label: "Roseau", img: "modules/foundryvtt-reve-de-dragon/icons/heures/hd11.webp"},
{value : "chateaudormant", label: "Chateau Dormant", img: "modules/foundryvtt-reve-de-dragon/icons/heures/hd12.webp"}
],
raretes: [
{value: "Commune", label: "Commune"},
{value: "Frequente", label: "Fréquente"},
{value: "Rare", label: "Rare"},
{value: "Rarissime", label: "Rarissime"}
]
}

View File

@ -2,8 +2,8 @@
export class DialogChoixXpCarac extends Dialog {
static async choix(actor, xpData, caracs) {
caracs = caracs.map(it => mergeObject({ ajout: 0 }, it))
xpData = mergeObject({ reste: xpData.xpCarac }, xpData)
caracs = caracs.map(it => foundry.utils.mergeObject({ ajout: 0 }, it))
xpData = foundry.utils.mergeObject({ reste: xpData.xpCarac }, xpData)
const dialogData = {
title: `Choisissez la répartition d'expérience`,
content: await renderTemplate("systems/foundryvtt-reve-de-dragon/templates/dialog-choix-xp-carac.hbs", {
@ -24,7 +24,7 @@ export class DialogChoixXpCarac extends Dialog {
}
constructor(dialogData, dialogOptions, actor, xpData, caracs) {
dialogData = mergeObject(dialogData, {
dialogData = foundry.utils.mergeObject(dialogData, {
default: 'appliquer',
buttons: {
'appliquer': { icon:'<i class="fa-solid fa-check"></i>', label: "Ajouter la répartition", callback: it => this.appliquerSelection() }

View File

@ -21,7 +21,7 @@ export class DialogFabriquerPotion extends Dialog {
/* -------------------------------------------- */
static prepareData(actor, item) {
let potionData = duplicate(item)
let potionData = foundry.utils.duplicate(item)
potionData.nbBrinsSelect = RdDUtility.buildListOptions(
DialogFabriquerPotion.nombreBrinsMinimum(item),
DialogFabriquerPotion.nombreBrinsOptimal(item));

View File

@ -47,7 +47,7 @@ export class DialogConsommer extends Dialog {
/* -------------------------------------------- */
static prepareData(actor, item) {
let consommerData = {
item: duplicate(item),
item: foundry.utils.duplicate(item),
cuisine: actor.getCompetence('cuisine'),
choix: {
doses: 1,

View File

@ -139,7 +139,7 @@ export class RdDItemArme extends Item {
const uneOuDeuxMains = armeData.system.unemain && armeData.system.deuxmains;
const containsSlash = !Number.isInteger(armeData.system.dommages) && armeData.system.dommages.includes("/");
if (containsSlash) { // Sanity check
armeData = duplicate(armeData);
armeData = foundry.utils.duplicate(armeData);
const tableauDegats = armeData.system.dommages.split("/");
if (aUneMain)

View File

@ -199,7 +199,7 @@ export class RdDItemCompetence extends Item {
if (idOrName == undefined || idOrName == "") {
return RdDItemCompetence.sansCompetence();
}
options = mergeObject(options, { preFilter: it => it.isCompetence(), description: 'compétence' }, { overwrite: false });
options = foundry.utils.mergeObject(options, { preFilter: it => it.isCompetence(), description: 'compétence' }, { overwrite: false, inplace: false });
return RdDItemCompetence.findFirstItem(list, idOrName, options);
}
@ -257,7 +257,7 @@ export class RdDItemCompetence extends Item {
/* -------------------------------------------- */
static computeResumeArchetype(competences) {
const computed = duplicate(limitesArchetypes);
const computed = foundry.utils.duplicate(limitesArchetypes);
computed.forEach(it => { it.nombre = 0; it.reste = it.nombreMax; });
competences.map(it => Math.max(0, it.system.niveau_archetype))

View File

@ -33,8 +33,7 @@ export class RdDItemCompetenceCreature extends Item {
if (categorieAttaque != undefined) {
// si c'est un Item compétence: cloner pour ne pas modifier la compétence
let arme = item.clone();
mergeObject(arme,
{
return foundry.utils.mergeObject(arme, {
action: item.isCompetencePossession() ? 'possession' : 'attaque',
system: {
competence: arme.name,
@ -48,8 +47,7 @@ export class RdDItemCompetenceCreature extends Item {
force: 0,
rapide: true,
}
});
return arme;
}, { inplace: false });
}
return undefined;
}

View File

@ -57,7 +57,7 @@ export class Monnaie {
}
static creerDeniers(fortune) {
const deniers = duplicate(MONNAIE_ETAIN);
const deniers = foundry.utils.duplicate(MONNAIE_ETAIN);
deniers.system.quantite = fortune;
return deniers;
}

View File

@ -39,12 +39,12 @@ export class RdDItemSheet extends ItemSheet {
/** @override */
static get defaultOptions() {
return mergeObject(super.defaultOptions, {
return foundry.utils.mergeObject(super.defaultOptions, {
classes: [SYSTEM_RDD, "sheet", "item"],
template: RdDItemSheet.defaultTemplate(RdDItemSheet.ITEM_TYPE),
width: 550,
height: 550
});
}, { inplace: false });
}
/* -------------------------------------------- */
@ -108,8 +108,8 @@ export class RdDItemSheet extends ItemSheet {
const competences = await SystemCompendiums.getCompetences('personnage');
formData.categories = this.item.getCategories()
if (this.item.type == 'tache' || this.item.type == 'livre' || this.item.type == 'meditation' || this.item.type == 'oeuvre') {
formData.caracList = duplicate(game.system.model.Actor.personnage.carac)
formData.caracList["reve-actuel"] = duplicate(game.system.model.Actor.personnage.reve.reve)
formData.caracList = foundry.utils.duplicate(game.system.model.Actor.personnage.carac)
formData.caracList["reve-actuel"] = foundry.utils.duplicate(game.system.model.Actor.personnage.reve.reve)
formData.competences = competences;
}
if (this.item.type == 'arme') {
@ -228,7 +228,7 @@ export class RdDItemSheet extends ItemSheet {
});
}
const updateItemTimestamp = (path, timestamp) => this.item.update({ [path]: duplicate(timestamp) })
const updateItemTimestamp = (path, timestamp) => this.item.update({ [path]: foundry.utils.duplicate(timestamp) })
RdDTimestamp.handleTimestampEditor(this.html, 'system.temporel.debut', updateItemTimestamp);
RdDTimestamp.handleTimestampEditor(this.html, 'system.temporel.fin', updateItemTimestamp);

View File

@ -1,4 +1,4 @@
import { DialogItemVente } from "./dialog-item-vente.js";
import { DialogItemVente } from "./achat-vente/dialog-item-vente.js";
import { Grammar } from "./grammar.js";
import { Misc } from "./misc.js";
import { RdDHerbes } from "./rdd-herbes.js";
@ -177,7 +177,7 @@ export class RdDItem extends Item {
constructor(docData, context = {}) {
if (!context.rdd?.ready) {
mergeObject(context, { rdd: { ready: true } });
foundry.utils.mergeObject(context, { rdd: { ready: true } });
const ItemConstructor = game.system.rdd.itemClasses[docData.type];
if (ItemConstructor) {
if (!docData.img) {
@ -233,7 +233,7 @@ export class RdDItem extends Item {
}
isCompetenceArme() {
return this.isCompetence() && [ 'melee','tir', 'lancer'].includes(this.system.categorie)
return this.isCompetence() && ['melee', 'tir', 'lancer'].includes(this.system.categorie)
}
isCompetencePossession() { return TYPES.competencecreature == this.type && this.system.categorie == "possession" }
@ -317,8 +317,8 @@ export class RdDItem extends Item {
const timestampFin = await this.calculerFinPeriodeTemporel(timestampDebut);
await actor.updateEmbeddedDocuments('Item', [{
_id: this.id,
'system.temporel.debut': duplicate(timestampDebut),
'system.temporel.fin': duplicate(timestampFin),
'system.temporel.debut': foundry.utils.duplicate(timestampDebut),
'system.temporel.fin': foundry.utils.duplicate(timestampFin),
}])
}
}
@ -538,7 +538,7 @@ export class RdDItem extends Item {
_id: this.id,
'system.quantite': this.system.quantite * sust,
'system.encombrement': Misc.keepDecimals(this.system.encombrement / sust, 2),
'system.cout': Misc.keepDecimals(this.system.cout / sust, 2),
'system.cout': Math.max(0, Misc.keepDecimals(this.system.cout / sust, 2)),
'system.sust': 1
}])
}
@ -621,23 +621,7 @@ export class RdDItem extends Item {
ui.notifications.warn(`Votre ${this.name} n'est pas vide, pas possible de le proposer`);
return;
}
await DialogItemVente.display({
item: this,
quantiteMax,
callback: async (vente) => {
vente["properties"] = this.getProprietes();
if (vente.isOwned) {
if (vente.quantiteNbLots * vente.tailleLot > vente.quantiteMax) {
ui.notifications.warn(`Vous avez ${vente.quantiteMax} ${vente.item.name}, ce n'est pas suffisant pour vendre ${vente.quantiteNbLots} de ${vente.tailleLot}`)
return;
}
}
vente.jsondata = JSON.stringify(vente.item);
let html = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-vente-item.html', vente);
ChatMessage.create(RdDUtility.chatDataSetup(html));
}
});
await DialogItemVente.display({ item: this, quantiteMax })
}
/* -------------------------------------------- */

View File

@ -39,7 +39,7 @@ export class RdDItemBlessure extends RdDItem {
ui.notifications.warn(`Pas de tâche de soins pour une blessure ${gravite}`)
return undefined;
}
return mergeObject(duplicate(BASE_TACHE_SOIN_BLESSURE), tache)
return foundry.utils.mergeObject(BASE_TACHE_SOIN_BLESSURE, tache, { inplace: false })
}
static async applyFullBlessure(actor, gravite) {
@ -48,7 +48,7 @@ export class RdDItemBlessure extends RdDItem {
let lostEndurance = 0
let lostVie = 0
if (definition.endurance) {
lostEndurance = new Roll(definition.endurance).roll({async: false}).total;
lostEndurance = await new Roll(definition.endurance).roll().total;
actor.santeIncDec("endurance", -Number(lostEndurance));
}
if (definition.vie) {
@ -106,12 +106,12 @@ export class RdDItemBlessure extends RdDItem {
}
async setSoinsBlessure(systemUpdate = {}) {
systemUpdate = mergeObject(systemUpdate, this.system, { overwrite: false }),
systemUpdate.soinscomplets.done = systemUpdate.premierssoins.done && systemUpdate.soinscomplets.done
systemUpdate = foundry.utils.mergeObject(systemUpdate, this.system, { overwrite: false })
systemUpdate.soinscomplets.done = systemUpdate.premierssoins.done && systemUpdate.soinscomplets.done
await this.update({
img: this.getImgSoins(systemUpdate.gravite, systemUpdate.soinscomplets.done),
system: systemUpdate
});
})
}
async recuperationBlessure({ actor, timestamp, message, isMaladeEmpoisonne, blessures }) {
@ -134,14 +134,14 @@ export class RdDItemBlessure extends RdDItem {
if (rolled.isETotal) {
message.content += ` -- une blessure ${label} s'infecte (temps de guérison augmenté de ${gravite} jours, perte de vie)`;
await actor.santeIncDec("vie", -1);
mergeObject(update, {
foundry.utils.mergeObject(update, {
system: { fin: { indexDate: timestamp.addJours(gravite).indexDate } }
});
}
else {
if (!isMaladeEmpoisonne && rolled.isSuccess && this.peutRetrograder(graviteMoindre, moindres)) {
message.content += ` -- une blessure ${label} cicatrise`;
mergeObject(update, {
foundry.utils.mergeObject(update, {
system: {
gravite: graviteMoindre,
temporel: { fin: { indexDate: timestamp.addJours(graviteMoindre).indexDate } }

View File

@ -38,7 +38,7 @@ export class RdDItemMaladie extends RdDItem {
await mal.actor.updateEmbeddedDocuments('Item', [{
_id: mal.id,
'system.temporel.fin': duplicate(timestampFin),
'system.temporel.fin': foundry.utils.duplicate(timestampFin),
}])
}
}

View File

@ -8,9 +8,9 @@ const TYPE_ITEMS_NATURELS = ["faune", "herbe", "plante", "ingredient"];
export class RdDItemInventaireSheet extends RdDItemSheet {
static get defaultOptions() {
return mergeObject(RdDItemSheet.defaultOptions, {
return foundry.utils.mergeObject(RdDItemSheet.defaultOptions, {
tabs: [{ navSelector: ".sheet-tabs", contentSelector: ".sheet-body", initial: "informations" }]
});
}, { inplace: false })
}
setPosition(options = {}) {
@ -23,9 +23,10 @@ export class RdDItemInventaireSheet extends RdDItemSheet {
async getData() {
const formData = await super.getData();
return mergeObject(formData, {
foundry.utils.mergeObject(formData, {
milieux: await game.system.rdd.environnement.autresMilieux(this.item)
});
})
return formData
}
activateListeners(html) {

View File

@ -6,9 +6,9 @@ export class RdDRencontreItemSheet extends RdDItemSheet {
static get ITEM_TYPE() { return "rencontre" };
static get defaultOptions() {
return mergeObject(super.defaultOptions, {
return foundry.utils.mergeObject(super.defaultOptions, {
tabs: [{ navSelector: ".sheet-tabs", contentSelector: ".sheet-body", initial: "carac" }]
});
}, { inplace: false })
}
/* -------------------------------------------- */
@ -24,7 +24,7 @@ export class RdDRencontreItemSheet extends RdDItemSheet {
/* -------------------------------------------- */
async getData() {
const formData = await super.getData();
mergeObject(formData, {
foundry.utils.mergeObject(formData, {
effets: {
succes: {
liste: RdDRencontre.getEffetsSucces(),
@ -35,7 +35,7 @@ export class RdDRencontreItemSheet extends RdDItemSheet {
select: RdDRencontre.mapEffets(this.item.system.echec.effets)
}
}
});
})
return formData;
}

View File

@ -5,6 +5,7 @@ import { Monnaie } from "./item-monnaie.js";
import { RdDItem, TYPES } from "./item.js";
import { RdDTimestamp } from "./time/rdd-timestamp.js";
import { RdDRaretes } from "./item/raretes.js";
import { RdDCalendrier } from "./time/rdd-calendrier.js";
class Migration {
get code() { return "sample"; }
@ -70,17 +71,17 @@ class _10_0_16_MigrationSortsReserve extends Migration {
get version() { return "10.0.16"; }
async migrate() {
await game.actors
.filter((actor) => actor.type == "personnage")
.filter((actor) => actor.system.reve?.reserve?.list?.length ?? 0 > 0)
.forEach(async (actor) => {
const sortsReserve = actor.system.reve.reserve.list.map(this.conversionSortReserve);
console.log(`${LOG_HEAD} Migration des sorts en réserve de ${actor.name}`, sortsReserve);
await actor.createEmbeddedDocuments("Item", sortsReserve, {
renderSheet: false,
});
await actor.update({ 'system.reve.reserve': undefined })
});
const actors = game.actors.filter((actor) => actor.type == "personnage" && (actor.system.reve?.reserve?.list?.length ?? 0 > 0))
Promise.all(actors.map(async it => await this.convertirSortsReserveActeur(it)))
}
async convertirSortsReserveActeur(actor) {
const sortsReserve = actor.system.reve.reserve.list.map(this.conversionSortReserve);
console.log(`${LOG_HEAD} Migration des sorts en réserve de ${actor.name}`, sortsReserve);
await actor.createEmbeddedDocuments("Item", sortsReserve, {
renderSheet: false,
});
await actor.update({ 'system.reve.reserve': undefined });
}
conversionSortReserve(it) {
@ -189,7 +190,7 @@ class _10_2_5_ArmesTirLancer extends Migration {
get version() { return "10.2.5"; }
migrateArmeTirLancer(it) {
let updates = mergeObject({ _id: it.id }, this.getMapping(it).updates);
let updates = foundry.utils.mergeObject({ _id: it.id }, this.getMapping(it).updates);
console.log(it.name, updates);
return updates;
}
@ -364,7 +365,7 @@ class _10_4_6_ServicesEnCommerces extends Migration {
const item = await RdDItem.getCorrespondingItem(serviceRefItem);
const itemToCreate = {
name: item.name, img: item.img, type: item.type,
system: mergeObject({ cout: serviceRefItem.system.cout, quantite: serviceRefItem.system.quantite }, item.system, { overwrite: false })
system: foundry.utils.mergeObject({ cout: serviceRefItem.system.cout, quantite: serviceRefItem.system.quantite }, item.system, { overwrite: false })
};
return itemToCreate;
}
@ -507,13 +508,28 @@ class _10_7_19_PossessionsEntiteVictime extends Migration {
}
migratePossession(it) {
return { _id: it.id,
return {
_id: it.id,
'system.entite.actorid': it.system.possesseurid,
'system.victime.actorid': it.system.possedeid
}
}
}
class _11_2_20_MigrationAstrologie extends Migration {
get code() { return "migration-astrologie" }
get version() { return "11.2.20" }
async migrate() {
const nombresAstraux = game.system.rdd.calendrier.getNombresAstraux()
nombresAstraux.forEach(na => {
na.lectures = na.valeursFausses
na.valeursFausses = undefined
})
await game.system.rdd.calendrier.setNombresAstraux(nombresAstraux)
}
}
export class Migrations {
static getMigrations() {
return [
@ -532,6 +548,7 @@ export class Migrations {
new _10_7_0_MigrationBlessures(),
new _10_7_19_CategorieCompetenceCreature(),
new _10_7_19_PossessionsEntiteVictime(),
new _11_2_20_MigrationAstrologie(),
];
}
@ -546,7 +563,10 @@ export class Migrations {
}
migrate() {
const currentVersion = game.settings.get(SYSTEM_RDD, "systemMigrationVersion");
let currentVersion = game.settings.get(SYSTEM_RDD, "systemMigrationVersion")
if (currentVersion.startsWith("v")) {
currentVersion = currentVersion.substring(1)
}
if (isNewerVersion(game.system.version, currentVersion)) {
// if (true) { /* comment previous and uncomment here to test before upgrade */
const migrations = Migrations.getMigrations().filter(m => isNewerVersion(m.version, currentVersion));
@ -554,7 +574,7 @@ export class Migrations {
migrations.sort((a, b) => this.compareVersions(a, b));
migrations.forEach(async (m) => {
ui.notifications.info(
`Executing migration ${m.code}: version ${currentVersion} is lower than ${m.version}`
`${LOG_HEAD} Executing migration ${m.code}: version ${currentVersion} is lower than ${m.version}`
);
await m.migrate();
});
@ -562,9 +582,7 @@ export class Migrations {
`Migrations done, version will change to ${game.system.version}`
);
} else {
console.log(
LOG_HEAD +
`No migration needeed, version will change to ${game.system.version}`
console.log(`${LOG_HEAD} No migration needeed, version will change to ${game.system.version}`
);
}
@ -574,7 +592,7 @@ export class Migrations {
game.system.version
);
} else {
console.log(LOG_HEAD + `No system version changed`);
console.log(`${LOG_HEAD} No system version changed`);
}
}

View File

@ -46,7 +46,7 @@ export class Misc {
}
static typeName(type, subType) {
return subType ? game.i18n.localize(`TYPES.${type}.${Misc.upperFirst(subType)}`)
return subType ? game.i18n.localize(`TYPES.${type}.${subType}`)
: '';
}
@ -200,7 +200,7 @@ export class Misc {
/* -------------------------------------------- */
static findFirstLike(value, elements, options = {}) {
options = mergeObject({
options = foundry.utils.mergeObject({
mapper: it => it.name,
preFilter: it => true,
description: 'valeur',
@ -225,7 +225,7 @@ export class Misc {
}
static findAllLike(value, elements, options = {}) {
options = mergeObject({
options = foundry.utils.mergeObject({
mapper: it => it.name,
preFilter: it => true,
description: 'valeur',

View File

@ -119,7 +119,7 @@ export class RdDCombatManager extends Combat {
//console.log("Combatat", c);
const roll = combatant.getInitiativeRoll(rollFormula);
if (!roll.total) {
roll.evaluate({ async: false });
await roll.evaluate();
}
const total = Math.max(roll.total, 0.00);
console.log("Compute init for", rollFormula, roll, total, combatant);
@ -128,21 +128,17 @@ export class RdDCombatManager extends Combat {
// Send a chat message
let rollMode = messageOptions.rollMode || game.settings.get("core", "rollMode");
let messageData = mergeObject(
{
speaker: {
scene: canvas.scene._id,
actor: combatant.actor?._id,
token: combatant.token._id,
alias: combatant.token.name,
sound: CONFIG.sounds.dice,
},
flavor: `${combatant.token.name} a fait son jet d'Initiative (${messageOptions.initInfo})
<br>
`,
let messageData = foundry.utils.mergeObject({
speaker: {
scene: canvas.scene._id,
actor: combatant.actor?._id,
token: combatant.token._id,
alias: combatant.token.name,
sound: CONFIG.sounds.dice,
},
messageOptions
);
flavor: `${combatant.token.name} a fait son jet d'Initiative (${messageOptions.initInfo})<br>`,
},
messageOptions);
roll.toMessage(messageData, { rollMode, create: true });
RdDCombatManager.processPremierRoundInit();
@ -218,7 +214,7 @@ export class RdDCombatManager extends Combat {
static $prepareAttaqueArme(infoAttaque) {
const comp = infoAttaque.competences.find(c => c.name == infoAttaque.competence);
const attaque = duplicate(infoAttaque.arme);
const attaque = foundry.utils.duplicate(infoAttaque.arme);
attaque.action = 'attaque';
attaque.system.competence = infoAttaque.competence;
attaque.system.dommagesReels = infoAttaque.dommagesReel;
@ -885,12 +881,12 @@ export class RdDCombat {
this.removeChatMessageActionsPasseArme(attackerRoll.passeArme);
if (essaisPrecedents) {
mergeObject(attackerRoll.essais, essaisPrecedents, { overwrite: true });
foundry.utils.mergeObject(attackerRoll.essais, essaisPrecedents, { overwrite: true });
}
// # utilisation esquive
const corpsACorps = this.defender.getCompetenceCorpsACorps({ onMessage: it => console.info(it, this.defender) });
const esquives = duplicate(this.defender.getCompetencesEsquive())
const esquives = foundry.utils.duplicate(this.defender.getCompetencesEsquive())
esquives.forEach(e => e.system.nbUsage = e?._id ? this.defender.getItemUse(e._id) : 0);
const paramChatDefense = {
@ -1282,7 +1278,7 @@ export class RdDCombat {
attackerRoll.defenderTokenId = defenderTokenId;
await this.computeRecul(defenderRoll);
this.defender.encaisserDommages(attackerRoll, this.attacker, defenderRoll?.show);
await this.defender.encaisserDommages(attackerRoll, this.attacker, defenderRoll?.show);
}
else { // envoi à un GM: les joueurs n'ont pas le droit de modifier les personnages qu'ils ne possèdent pas
game.socket.emit(SYSTEM_SOCKET_ID, {

View File

@ -463,14 +463,13 @@ export class RdDCommands {
let motif = params.slice(1, params.length - 2);
let name = params[params.length - 1];
const personnages = game.actors.filter(actor => actor.isPersonnageJoueur());
if (name == undefined) {
for (let actor of game.actors) {
// TODO: ne plus stresser les entités de cauchemar!
for (let actor of personnages) {
await actor.distribuerStress('stress', stress, motif);
}
} else {
//console.log(stressValue, nomJoueur);
let actor = Misc.findActor(name, game.actors.filter(it => it.hasPlayerOwner)) ?? Misc.findPlayer(name)?.character
let actor = Misc.findActor(name, personnages) ?? Misc.findPlayer(name)?.character
if (actor) {
await actor.distribuerStress('stress', stress, motif);
}

View File

@ -4,29 +4,23 @@ import { ReglesOptionnelles } from "./settings/regles-optionnelles.js";
export class RdDConfirm {
/* -------------------------------------------- */
static confirmer(options, autresActions) {
options.bypass = options.bypass || !(options.settingConfirmer == undefined || ReglesOptionnelles.isUsing(options.settingConfirmer));
if (options.bypass) {
options.onAction();
let buttons = {
"action": RdDConfirm._createButtonAction(options),
"cancel": RdDConfirm._createButtonCancel()
};
if (options.settingConfirmer) {
buttons = foundry.utils.mergeObject(RdDConfirm._createButtonActionSave(options), buttons);
}
else {
let buttons = {
"action": RdDConfirm._createButtonAction(options),
"cancel": RdDConfirm._createButtonCancel()
};
if (options.settingConfirmer) {
buttons = mergeObject(RdDConfirm._createButtonActionSave(options), buttons);
}
if (autresActions) {
buttons = mergeObject(autresActions, buttons);
}
const dialogDetails = {
title: options.title,
content: options.content,
default: "cancel",
buttons: buttons
};
new Dialog(dialogDetails, { width: 150 * Object.keys(buttons).length }).render(true);
if (autresActions) {
buttons = foundry.utils.mergeObject(autresActions, buttons, { inplace: false });
}
const dialogDetails = {
title: options.title,
content: options.content,
default: "cancel",
buttons: buttons
};
new Dialog(dialogDetails, { width: 150 * Object.keys(buttons).length }).render(true);
}
static _createButtonCancel() {

View File

@ -138,7 +138,7 @@ export class RdDDice {
static async roll(formula, options = { showDice: SHOW_DICE, rollMode: undefined }) {
const roll = new Roll(RdDDice._formulaOrFake(formula, options));
await roll.evaluate({ async: true });
await roll.evaluate();
await this.showDiceSoNice(roll, options);
return roll;
}
@ -216,7 +216,7 @@ export class RdDDice {
static async fakeD10(faces) {
let roll = new Roll(`1d${faces}`);
await roll.evaluate({ async: true });
await roll.evaluate();
return roll.total;
}

View File

@ -98,7 +98,7 @@ export class RdDEmpoignade {
/* -------------------------------------------- */
static getEmpoignadeById(actor, id) {
let emp = actor.itemTypes[TYPES.empoignade].find(it => it.system.empoignadeid == id)
return emp && duplicate(emp) || undefined;
return emp && foundry.utils.duplicate(emp) || undefined;
}
/* -------------------------------------------- */
@ -108,7 +108,7 @@ export class RdDEmpoignade {
(it.system.empoigneurid == defender.id && it.system.empoigneid == attacker.id)
)
if (emp) {
return duplicate(emp);
return foundry.utils.duplicate(emp);
}
return undefined;
}
@ -267,7 +267,7 @@ export class RdDEmpoignade {
return
}
empoignade = duplicate(empoignade)
empoignade = foundry.utils.duplicate(empoignade)
let defenderRoll = {
mode, attacker, defender, empoignade, attackerRoll,
diffLibre: attackerRoll.diffLibre,

View File

@ -1,4 +1,4 @@
import { SYSTEM_RDD, SYSTEM_SOCKET_ID } from "./constants.js";
import { SYSTEM_RDD, SYSTEM_SOCKET_ID, RDD_CONFIG } from "./constants.js";
import { Migrations } from './migrations.js';
import { RdDUtility } from "./rdd-utility.js";
@ -108,6 +108,7 @@ export class SystemReveDeDragon {
/* -------------------------------------------- */
async onInit() {
game.system.rdd = this;
game.system.rdd.config = RDD_CONFIG;
this.AppAstrologie = AppAstrologie;
@ -266,16 +267,16 @@ export class SystemReveDeDragon {
/* -------------------------------------------- */
/* Foundry VTT Initialization */
/* -------------------------------------------- */
// CSS patch for v9
if (game.version) {
let sidebar = document.getElementById("sidebar");
sidebar.style.width = "min-content";
}
game.system.rdd.calendrier = new RdDCalendrier();
if (Misc.isUniqueConnectedGM()) {
new Migrations().migrate();
this.messageDeBienvenue();
this.registerUsageCount(SYSTEM_RDD);
import("https://www.uberwald.me/fvtt_appcount/count-class-ready.js").then(moduleCounter=>{
console.log("ClassCounter loaded", moduleCounter)
moduleCounter.ClassCounter.registerUsageCount()
}).catch(err=>
console.log("No stats available, giving up.")
)
}
StatusEffects.onReady();
@ -306,30 +307,6 @@ export class SystemReveDeDragon {
` });
}
}
/* -------------------------------------------- */
// Register world usage statistics
async registerUsageCount(registerKey) {
if (game.user.isGM) {
game.settings.register("world", "world-key", {
name: "Unique world key",
scope: "world",
config: false,
default: "NONE",
type: String
});
let worldKey = game.settings.get("world", "world-key")
if (worldKey == undefined || worldKey == "") {
worldKey = randomID(32)
game.settings.set("world", "world-key", worldKey)
}
let regURL = `https://www.uberwald.me/fvtt_appcount/count.php?name="${registerKey}"&worldKey="${worldKey}"&version="${game.release.generation}.${game.release.build}"&system="${game.system.id}"&systemversion="${game.system.version}"`
$.ajax(regURL)
/* -------------------------------------------- */
}
}
}
SystemReveDeDragon.start();

View File

@ -56,7 +56,7 @@ const temperatures = [
export class RdDMeteo {
static async getForce() {
const roll = new Roll(`1dr`);
await roll.evaluate({ async: true });
await roll.evaluate();
return roll.total;
}
@ -67,14 +67,14 @@ export class RdDMeteo {
static async getTemperature() {
const degre = await RdDMeteo.getForce();
const rollChaudFroid = new Roll('1d2');
await rollChaudFroid.evaluate({ async: true });
await rollChaudFroid.evaluate();
const chaudFroid = rollChaudFroid.total == 1;
return chaudFroid.total ? degre : -degre;
}
static async getDirection(direction) {
const roll = new Roll(`1d16`);
await roll.evaluate({ async: true });
await roll.evaluate();
switch (roll.total % 16) {
case 0: return 'Nord';
case 1: return 'Nord Nord Est';

View File

@ -24,7 +24,7 @@ export class RdDPossession {
if (!poss) {
poss = defender.items.find(poss => poss.type == TYPES.possession && poss.system.victime.actorid == defender.id);
}
return poss && duplicate(poss) || undefined;
return poss && foundry.utils.duplicate(poss) || undefined;
}
/* -------------------------------------------- */
@ -52,7 +52,7 @@ export class RdDPossession {
/* -------------------------------------------- */
static async onConjurerPossession(attacker, possession) {
possession = duplicate(possession);
possession = foundry.utils.duplicate(possession);
RdDPossession.$updateEtatPossession(possession)
const defender = game.actors.get(possession.system.entite.actorid);
@ -80,7 +80,7 @@ export class RdDPossession {
ui.notifications.warn("Une erreur s'est produite : Aucune possession trouvée !!")
return
}
possession = duplicate(possession)
possession = foundry.utils.duplicate(possession)
// Update for draconic roll
let rollData = {
mode: "defense",

View File

@ -114,7 +114,7 @@ export class RdDResolutionTable {
/* -------------------------------------------- */
static async roll(caracValue, finalLevel, rollData = {}) {
let chances = duplicate(this.computeChances(caracValue, finalLevel));
let chances = foundry.utils.duplicate(this.computeChances(caracValue, finalLevel));
this._updateChancesWithBonus(chances, rollData.bonus, finalLevel);
this._updateChancesFactor(chances, rollData.diviseurSignificative);
chances.showDice = rollData.showDice;
@ -158,7 +158,7 @@ export class RdDResolutionTable {
static _updateChancesFactor(chances, diviseur) {
if (chances.level > -11 && diviseur && diviseur > 1) {
let newScore = Math.floor(chances.score / diviseur);
mergeObject(chances, this._computeCell(undefined, newScore), { overwrite: true });
foundry.utils.mergeObject(chances, this._computeCell(undefined, newScore), { overwrite: true });
}
}
@ -166,27 +166,27 @@ export class RdDResolutionTable {
static _updateChancesWithBonus(chances, bonus, finalLevel) {
if (bonus && finalLevel > -11) {
let newScore = Number(chances.score) + bonus;
mergeObject(chances, this._computeCell(undefined, newScore), { overwrite: true });
foundry.utils.mergeObject(chances, this._computeCell(undefined, newScore), { overwrite: true });
}
}
/* -------------------------------------------- */
static significativeRequise(chances) {
chances.roll = Math.floor(chances.score / 2);
mergeObject(chances, reussites.find(x => x.code == 'sign'), { overwrite: true });
foundry.utils.mergeObject(chances, reussites.find(x => x.code == 'sign'), { overwrite: true });
}
/* -------------------------------------------- */
static succesRequis(chances) {
chances.roll = chances.score;
mergeObject(chances, reussites.find(x => x.code == 'norm'), { overwrite: true });
foundry.utils.mergeObject(chances, reussites.find(x => x.code == 'norm'), { overwrite: true });
}
/* -------------------------------------------- */
static async rollChances(chances, diviseur, forceDiceResult = -1) {
chances.forceDiceResult = forceDiceResult <= 0 || forceDiceResult > 100 ? undefined : { total: forceDiceResult };
chances.roll = await RdDDice.rollTotal("1d100", chances);
mergeObject(chances, this.computeReussite(chances, chances.roll, diviseur), { overwrite: true });
foundry.utils.mergeObject(chances, this.computeReussite(chances, chances.roll, diviseur), { overwrite: true });
return chances;
}

View File

@ -38,7 +38,7 @@ export class RdDRollResolutionTable extends Dialog {
diffLibre: 0,
use: { conditions:true, libre:true }
}
mergeObject(rollData, defRollData, { overwrite: false });
foundry.utils.mergeObject(rollData, defRollData, { overwrite: false });
for (let i = 1; i < 21; i++) {
const key = `${i}`;
rollData.carac[key] = { type: "number", value: i, label: key }

View File

@ -65,7 +65,7 @@ export class RdDRoll extends Dialog {
defaultRollData.carac["reve-actuel"] = actor.system.reve.reve
}
mergeObject(rollData, defaultRollData, { recursive: true, overwrite: false });
foundry.utils.mergeObject(rollData, defaultRollData, { recursive: true, overwrite: false });
if (rollData.forceCarac) {
rollData.carac = rollData.forceCarac;
}

View File

@ -16,7 +16,7 @@ export class RdDSheetUtility {
isObserver: userRightLevel >= CONST.DOCUMENT_OWNERSHIP_LEVELS.OBSERVER,
isOwner: userRightLevel >= CONST.DOCUMENT_OWNERSHIP_LEVELS.OWNER
}
mergeObject(options, newOptions);
foundry.utils.mergeObject(options, newOptions);
return options;
}
@ -76,7 +76,7 @@ export class RdDSheetUtility {
static async _onSplitItem(item, split, actor) {
if (split >= 1 && split < item.system.quantite) {
await item.diminuerQuantite(split);
const splitItem = duplicate(item);
const splitItem = foundry.utils.duplicate(item);
// todo: ajouter dans le même conteneur?
splitItem.system.quantite = split;
await actor.createEmbeddedDocuments('Item', [splitItem])

View File

@ -44,16 +44,15 @@ export class RdDTMRDialog extends Dialog {
type: Number,
range: TMR_DISPLAY_SIZE.range
})
await PixiTMR.init()
}
static async create(actor, tmrData) {
await PixiTMR.init()
let html = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/dialog-tmr.html', tmrData);
if (tmrData.mode != 'visu' && !game.user.isGM) {
ChatMessage.create({ content: actor.name + " est monté dans les TMR en mode : " + tmrData.mode, whisper: ChatMessage.getWhisperRecipients("GM") });
}
return new RdDTMRDialog(html, actor, tmrData);
return new RdDTMRDialog(html, actor, tmrData)
}
/* -------------------------------------------- */
@ -71,7 +70,7 @@ export class RdDTMRDialog extends Dialog {
'z-index': 40
}
super(dialogConf, dialogOptions);
this.tmrdata = duplicate(tmrData);
this.tmrdata = foundry.utils.duplicate(tmrData);
this.actor = actor;
this.actor.tmrApp = this; // reference this app in the actor structure
this.viewOnly = tmrData.mode == "visu"
@ -213,7 +212,7 @@ export class RdDTMRDialog extends Dialog {
/* -------------------------------------------- */
loadRencontres() {
this.rencontresExistantes = this.actor.getTMRRencontres();
this.rencontresExistantes = this.actor.getRencontresTMR();
}
/* -------------------------------------------- */
@ -298,11 +297,10 @@ export class RdDTMRDialog extends Dialog {
/* -------------------------------------------- */
async updateValuesDisplay() {
if (!this.rendered) {
if (this.viewOnly || !this.rendered) {
return;
}
const coord = this._getCoordActor();
HtmlUtility.showControlWhen(this.html.find(".lire-signe-draconique"), this.actor.isResonanceSigneDraconique(coord));
let ptsreve = document.getElementById("tmr-pointsreve-value");
@ -384,7 +382,7 @@ export class RdDTMRDialog extends Dialog {
async refouler() {
console.log("-> refouler", this.currentRencontre);
await this.actor.ajouterRefoulement(this.currentRencontre.system.refoulement, `${this.currentRencontre.system.genre == 'f' ? 'une' : 'un'} ${this.currentRencontre.name}`);
await this.actor.deleteTMRRencontreAtPosition(); // Remove the stored rencontre if necessary
await this.actor.deleteRencontreTMRAtPosition()
this.updateTokens();
this.updateValuesDisplay();
this.nettoyerRencontre();
@ -394,7 +392,7 @@ export class RdDTMRDialog extends Dialog {
async ignorerRencontre() {
console.log("-> ignorer", this.currentRencontre);
this._tellToGM(this.actor.name + " a ignoré: " + this.currentRencontre.name);
await this.actor.deleteTMRRencontreAtPosition(); // Remove the stored rencontre if necessary
await this.actor.deleteRencontreTMRAtPosition()
this.updateTokens();
this.updateValuesDisplay();
this.nettoyerRencontre();
@ -409,7 +407,7 @@ export class RdDTMRDialog extends Dialog {
/* -------------------------------------------- */
$marquerCasesTMR(listCoordTMR) {
this.currentRencontre.locList = duplicate(listCoordTMR); // And track of allowed location
this.currentRencontre.locList = foundry.utils.duplicate(listCoordTMR); // And track of allowed location
this.currentRencontre.graphics = listCoordTMR.map(coordTMR => this.pixiTMR.addMarkTMR(coordTMR))
}
@ -448,7 +446,7 @@ export class RdDTMRDialog extends Dialog {
async maitriserRencontre() {
console.log("-> maitriser", this.currentRencontre);
await this.actor.deleteTMRRencontreAtPosition();
await this.actor.deleteRencontreTMRAtPosition()
this.updateTokens();
let rencontreData = {
@ -538,7 +536,7 @@ export class RdDTMRDialog extends Dialog {
/* -------------------------------------------- */
_rollPresentCite(rencData) {
let rolled = RdDResolutionTable.computeChances(rencData.reve, 0);
mergeObject(rolled, { caracValue: rencData.reve, finalLevel: 0, roll: rolled.score });
foundry.utils.mergeObject(rolled, { caracValue: rencData.reve, finalLevel: 0, roll: rolled.score });
RdDResolutionTable.succesRequis(rolled);
return rolled;
}
@ -681,7 +679,7 @@ export class RdDTMRDialog extends Dialog {
if (this.isCaseHumide(tmr)) {
let rollData = {
actor: this.actor,
competence: duplicate(this.actor.getBestDraconic()),
competence: foundry.utils.duplicate(this.actor.getBestDraconic()),
tmr: tmr,
canClose: false,
diffLibre: -7,
@ -806,7 +804,7 @@ export class RdDTMRDialog extends Dialog {
async _conquerir(tmr, options) {
let rollData = {
actor: this.actor,
competence: duplicate(this.actor.getBestDraconic()),
competence: foundry.utils.duplicate(this.actor.getBestDraconic()),
tmr: tmr,
canClose: options.canClose ?? false,
diffLibre: options.difficulte ?? -7,

View File

@ -4,7 +4,7 @@ import { RdDCombat } from "./rdd-combat.js";
import { Misc } from "./misc.js";
import { Grammar } from "./grammar.js";
import { TMRUtility } from "./tmr-utility.js";
import { DialogItemAchat } from "./dialog-item-achat.js";
import { DialogItemAchat } from "./achat-vente/dialog-item-achat.js";
import { ReglesOptionnelles } from "./settings/regles-optionnelles.js";
import { RdDDice } from "./rdd-dice.js";
import { RdDItem } from "./item.js";
@ -18,6 +18,7 @@ import { RdDRaretes } from "./item/raretes.js";
import { RdDEmpoignade } from "./rdd-empoignade.js";
import { ExperienceLog } from "./actor/experience-log.js";
import { RdDCoeur } from "./coeur/rdd-coeur.js";
import { APP_ASTROLOGIE_REFRESH } from "./sommeil/app-astrologie.js";
/* -------------------------------------------- */
// This table starts at 0 -> niveau -10
@ -31,7 +32,7 @@ function _buildAllSegmentsFatigue(max) {
const cycle = [5, 2, 4, 1, 3, 0];
const fatigue = [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]];
for (let i = 0; i <= max; i++) {
const ligneFatigue = duplicate(fatigue[i]);
const ligneFatigue = foundry.utils.duplicate(fatigue[i]);
const caseIncrementee = cycle[i % 6];
ligneFatigue[caseIncrementee]++;
ligneFatigue[caseIncrementee + 6]++;
@ -45,7 +46,7 @@ function _buildAllSegmentsFatigue(max) {
function _cumulSegmentsFatigue(matrix) {
let cumulMatrix = [];
for (let line of matrix) {
let cumul = duplicate(line);
let cumul = foundry.utils.duplicate(line);
for (let i = 1; i < 12; i++) {
cumul[i] += cumul[i - 1];
@ -98,8 +99,9 @@ export class RdDUtility {
static afficheContenu = {}
/* -------------------------------------------- */
static async init() {
Hooks.on("renderChatMessage", async (app, html, msg) => RdDUtility.onRenderChatMessage(app, html, msg));
Hooks.on('renderChatLog', (log, html, chatLog) => RdDUtility.chatListeners(html));
Hooks.on("renderChatMessage", async (app, html, msg) => await ChatUtility.onRenderChatMessage(app, html, msg))
Hooks.on("createChatMessage", async (chatMessage, options, id) => await ChatUtility.onCreateChatMessage(chatMessage, options, id))
Hooks.on('renderChatLog', (log, html, chatLog) => RdDUtility.chatListeners(html))
}
/* -------------------------------------------- */
@ -205,6 +207,7 @@ export class RdDUtility {
'systems/foundryvtt-reve-de-dragon/templates/voyage/fatigue-actor.hbs',
'systems/foundryvtt-reve-de-dragon/templates/voyage/option-vitesse-fatigue.hbs',
'systems/foundryvtt-reve-de-dragon/templates/common/timestamp.hbs',
'systems/foundryvtt-reve-de-dragon/templates/common/date-heure.hbs',
'systems/foundryvtt-reve-de-dragon/templates/common/periodicite.hbs',
'systems/foundryvtt-reve-de-dragon/templates/common/enum-duree.hbs',
'systems/foundryvtt-reve-de-dragon/templates/common/compendium-link.hbs',
@ -297,6 +300,14 @@ export class RdDUtility {
Handlebars.registerHelper('plusMoins', diff => (diff > 0 ? '+' : '') + Math.round(diff))
Handlebars.registerHelper('experienceLog-topic', topic => ExperienceLog.labelTopic(topic));
// Handle v12 removal of this helper
Handlebars.registerHelper('select', function (selected, options) {
const escapedValue = RegExp.escape(Handlebars.escapeExpression(selected));
const rgx = new RegExp(' value=[\"\']' + escapedValue + '[\"\']');
const html = options.fn(this);
return html.replace(rgx, "$& selected");
});
return loadTemplates(templatePaths);
}
@ -549,49 +560,54 @@ export class RdDUtility {
/* -------------------------------------------- */
static async jetEncaissement(rollData, armure, options = { showDice: HIDE_DICE }) {
let formula = "2d10";
const diff = Math.abs(rollData.diffLibre);
let formula = RdDUtility.formuleEncaissement(diff, options)
const roll = await RdDDice.roll(formula, options);
// Chaque dé fait au minmum la difficulté libre
if (ReglesOptionnelles.isUsing('degat-minimum-malus-libre')) {
if (rollData.diffLibre < 0) {
let valeurMin = Math.abs(rollData.diffLibre);
formula += "min" + valeurMin;
}
}
// Chaque dé fait au minmum la difficulté libre
if (ReglesOptionnelles.isUsing('degat-ajout-malus-libre')) {
if (rollData.diffLibre < 0) {
let valeurMin = Math.abs(rollData.diffLibre);
formula += "+" + valeurMin;
}
}
let roll = await RdDDice.roll(formula, options);
// 1 dé fait au minmum la difficulté libre
if (ReglesOptionnelles.isUsing('degat-minimum-malus-libre-simple')) {
if (rollData.diffLibre < 0) {
let valeurMin = Math.abs(rollData.diffLibre);
if (roll.terms[0].results[0].result < valeurMin) {
roll.terms[0].results[0].result = valeurMin;
} else if (roll.terms[0].results[1].result < valeurMin) {
roll.terms[0].results[1].result = valeurMin;
}
roll._total = roll.terms[0].results[0].result + roll.terms[0].results[1].result;
}
}
RdDUtility.remplaceDeMinParDifficulte(roll, diff, options);
return await RdDUtility.prepareEncaissement(rollData, roll, armure);
}
static remplaceDeMinParDifficulte(roll, diff, options) {
if (!ReglesOptionnelles.isUsing('degat-minimum-malus-libre-simple')) {
return
}
// 1 dé fait au minmum la difficulté libre
const total = options.forceDiceResult?.total;
if (total) {
const reste = Math.max(total - diff, 1)
roll.terms[0].number = reste + diff
}
else {
if (roll.terms[0].results[0].result < diff) {
roll.terms[0].results[0].result = diff;
} else if (roll.terms[0].results[1].result < diff) {
roll.terms[0].results[1].result = diff;
}
roll._total = roll.terms[0].results[0].result + roll.terms[0].results[1].result;
}
}
static formuleEncaissement(diff, options) {
// Chaque dé fait au minimum la difficulté libre
if (ReglesOptionnelles.isUsing('degat-minimum-malus-libre')) {
return `2d10min${diff}`
}
return '2d10'
}
/* -------------------------------------------- */
static async prepareEncaissement(rollData, roll, armure) {
const jetTotal = roll.total + rollData.dmg.total - armure;
let encaissement = RdDUtility._selectEncaissement(jetTotal, rollData.dmg.mortalite);
let over20 = Math.max(jetTotal - 20, 0);
// La difficulté d'ataque s'ajoute aux dégâts
const bonusDegatsDiffLibre = ReglesOptionnelles.isUsing('degat-ajout-malus-libre') ? Math.abs(rollData.diffLibre ?? 0) : 0
const jetTotal = roll.total + rollData.dmg.total - armure + bonusDegatsDiffLibre
const encaissement = RdDUtility._selectEncaissement(jetTotal, rollData.dmg.mortalite);
const over20 = Math.max(jetTotal - 20, 0);
encaissement.dmg = rollData.dmg;
encaissement.dmg.loc = rollData.dmg.loc ?? await RdDUtility.getLocalisation(this.type);
encaissement.dmg.loc.label = encaissement.dmg.loc.label ?? 'Corps;';
encaissement.dmg.bonusDegatsDiffLibre = bonusDegatsDiffLibre
encaissement.roll = roll;
encaissement.armure = armure;
encaissement.penetration = rollData.arme?.system.penetration ?? 0;
@ -607,34 +623,28 @@ export class RdDUtility {
for (let encaissement of table) {
if ((encaissement.minimum === undefined || encaissement.minimum <= degats)
&& (encaissement.maximum === undefined || degats <= encaissement.maximum)) {
return duplicate(encaissement);
return foundry.utils.duplicate(encaissement);
}
}
return duplicate(table[0]);
return foundry.utils.duplicate(table[0]);
}
/* -------------------------------------------- */
static async _evaluatePerte(formula, over20) {
let perte = new Roll(formula, { over20: over20 });
await perte.evaluate({ async: true });
await perte.evaluate();
return perte.total;
}
/* -------------------------------------------- */
static async responseNombreAstral(callData) {
let actor = game.actors.get(callData.id);
actor.ajouteNombreAstral(callData);
}
/* -------------------------------------------- */
static onSocketMessage(sockmsg) {
switch (sockmsg.msg) {
case "msg_gm_chat_message":
return ChatUtility.handleGMChatMessage(sockmsg.data);
case "msg_app_astrologie_refresh":
return Hooks.callAll(APP_ASTROLOGIE_REFRESH);
case "msg_request_nombre_astral":
return game.system.rdd.calendrier.requestNombreAstral(sockmsg.data);
case "msg_response_nombre_astral":
return RdDUtility.responseNombreAstral(sockmsg.data);
case "msg_tmr_move":
let actor = game.actors.get(sockmsg.data.actorId);
if (actor.isOwner || game.user.isGM) {
@ -890,10 +900,4 @@ export class RdDUtility {
}
}
/*-------------------------------------------- */
static async onRenderChatMessage(app, html, msg) {
// TODO
//console.log(app, html, msg);
}
}

View File

@ -166,7 +166,7 @@ export class RollDataAjustements {
/* -------------------------------------------- */
static calcul(rollData, actor) {
// s'assurer de la correction des infos rollData
mergeObject(rollData, { ajustements: {}, use: {} }, { overwrite: false })
foundry.utils.mergeObject(rollData, { ajustements: {}, use: {} }, { overwrite: false })
for (var key in referenceAjustements) {
const reference = referenceAjustements[key];

View File

@ -26,6 +26,7 @@ const listeReglesOptionnelles = [
{ group: 'Confirmations', name: 'confirmer-combat-sans-cible', descr: "Confirmer avant une attaque sans cible", scope: "client"},
{ group: 'Confirmations', name: 'confirmation-tmr', descr: "Confirmer pour monter dans les TMR", scope: "client"},
{ group: 'Confirmations', name: 'confirmation-tmr-rencontre', descr: "Confirmer pour monter dans les TMR avec rencontre en attente", scope: "client"},
{ group: 'Confirmations', name: 'confirmation-refouler', descr: "Confirmer avant de refouler", scope: "client"},
{ group: 'Confirmations', name: 'confirmation-vider', descr: "Confirmer pour vider l'équipement", scope: "client"},
{ group: 'Confirmations', name: 'confirmation-supprimer-lien-acteur', descr: "Confirmer pour détacher un animal/suivant/véhicule", scope: "client"},
@ -70,8 +71,7 @@ export class ReglesOptionnelles extends FormApplication {
}
static get defaultOptions() {
const options = super.defaultOptions;
mergeObject(options, {
return foundry.utils.mergeObject(super.defaultOptions, {
id: "regles-optionnelles",
template: "systems/foundryvtt-reve-de-dragon/templates/settings/regles-optionnelles.html",
height: 650,
@ -79,14 +79,13 @@ export class ReglesOptionnelles extends FormApplication {
minimizable: false,
closeOnSubmit: true,
title: "Règles optionnelles"
});
return options;
}, { inplace: false })
}
getData() {
let formData = super.getData();
const regles = listeReglesOptionnelles.filter(it => game.user.isGM || it.scope == "client").map(it => {
it = duplicate(it);
it = foundry.utils.duplicate(it);
it.id = ReglesOptionnelles._getIdRegle(it.name);
it.active = ReglesOptionnelles.isSet(it.name);
return it;

View File

@ -18,8 +18,8 @@ const rddStatusEffects = [
{ rdd: true, id: STATUSES.StatusStunned, label: 'EFFECT.StatusStunned', icon: 'icons/svg/stoned.svg', "duration.rounds": 1 },
{ rdd: true, id: STATUSES.StatusBleeding, label: 'EFFECT.StatusBleeding', icon: 'icons/svg/blood.svg' },
{ rdd: true, id: STATUSES.StatusProne, label: 'EFFECT.StatusProne', icon: 'icons/svg/falling.svg' },
{ rdd: true, id: STATUSES.StatusGrappling, tint: '#33cc33', label: 'EFFECT.StatusGrappling', icon: 'systems/foundryvtt-reve-de-dragon/icons/empoignade.svg' },
{ rdd: true, id: STATUSES.StatusGrappled, tint: '#ff9900', label: 'EFFECT.StatusGrappled', icon: 'systems/foundryvtt-reve-de-dragon/icons/empoignade.svg' },
{ rdd: true, id: STATUSES.StatusGrappling, tint: '#33cc33', label: 'EFFECT.StatusGrappling', icon: 'systems/foundryvtt-reve-de-dragon/icons/empoignade.webp' },
{ rdd: true, id: STATUSES.StatusGrappled, tint: '#ff9900', label: 'EFFECT.StatusGrappled', icon: 'systems/foundryvtt-reve-de-dragon/icons/empoignade.webp' },
{ rdd: true, id: STATUSES.StatusRestrained, label: 'EFFECT.StatusRestrained', icon: 'icons/svg/net.svg' },
{ rdd: true, id: STATUSES.StatusUnconscious, label: 'EFFECT.StatusUnconscious', icon: 'icons/svg/unconscious.svg' },
{ rdd: true, id: STATUSES.StatusBlind, label: 'EFFECT.StatusBlind', icon: 'icons/svg/blind.svg' },
@ -65,7 +65,7 @@ export class StatusEffects extends FormApplication {
static valeurSurprise(effect, isCombat) {
if (statusSurpriseTotale.intersects(effect.statuses)) {
return 2;
return 2
}
if (statusDemiSurprise.intersects(effect.statuses)) {
return 1
@ -94,7 +94,7 @@ export class StatusEffects extends FormApplication {
static prepareActiveEffect(effectId) {
let status = rddStatusEffects.find(it => it.id == effectId)
if (status) {
status = duplicate(status)
status = foundry.utils.duplicate(status)
status.statuses = [effectId]
}
return status;
@ -110,7 +110,7 @@ export class StatusEffects extends FormApplication {
static get defaultOptions() {
const options = super.defaultOptions;
mergeObject(options, {
foundry.utils.mergeObject(options, {
id: "status-effects",
template: "systems/foundryvtt-reve-de-dragon/templates/settings/status-effects.html",
height: 800,
@ -125,7 +125,7 @@ export class StatusEffects extends FormApplication {
getData() {
const used = StatusEffects._getUseStatusEffects();
let formData = super.getData();
formData.effects = duplicate(CONFIG.RDD.allEffects);
formData.effects = foundry.utils.duplicate(CONFIG.RDD.allEffects);
formData.effects.forEach(it => it.active = used.includes(it.id))
return formData;
}

View File

@ -27,7 +27,7 @@ export class SystemCompendiums extends FormApplication {
static init() {
Object.keys(CONFIGURABLE_COMPENDIUMS).forEach(compendium => {
const definition = CONFIGURABLE_COMPENDIUMS[compendium];
mergeObject(definition, {
foundry.utils.mergeObject(definition, {
compendium: compendium,
default: SystemCompendiums._getDefaultCompendium(compendium),
setting: SystemCompendiums._getSettingCompendium(compendium)
@ -138,7 +138,7 @@ export class SystemCompendiums extends FormApplication {
static get defaultOptions() {
const options = super.defaultOptions;
mergeObject(options, {
foundry.utils.mergeObject(options, {
id: "system-compendiums",
template: "systems/foundryvtt-reve-de-dragon/templates/settings/system-compendiums.html",
height: 'fit-content',
@ -152,7 +152,7 @@ export class SystemCompendiums extends FormApplication {
getData() {
const systemCompendiums = Object.values(CONFIGURABLE_COMPENDIUMS)
.map(it => mergeObject(it, { value: SystemCompendiums.getCompendium(it.compendium) }));
.map(it => foundry.utils.mergeObject(it, { value: SystemCompendiums.getCompendium(it.compendium) }, { inplace: false }))
const availableCompendiums = game.packs.map(pack => {
return {
name: pack.collection,
@ -160,10 +160,10 @@ export class SystemCompendiums extends FormApplication {
type: pack.metadata.type
}
});
return mergeObject(super.getData(), {
return foundry.utils.mergeObject(super.getData(), {
systemCompendiums: systemCompendiums,
availableCompendiums: availableCompendiums
});
}, { inplace: false })
}
activateListeners(html) {

View File

@ -17,7 +17,7 @@ export class AppAstrologie extends Application {
static get defaultOptions() {
return mergeObject(super.defaultOptions, {
return foundry.utils.mergeObject(super.defaultOptions, {
template: "systems/foundryvtt-reve-de-dragon/templates/sommeil/app-astrologie.hbs",
title: "Astrologie",
width: 'fit-content',
@ -25,19 +25,18 @@ export class AppAstrologie extends Application {
classes: ['calendar-astrologie'],
popOut: true,
resizable: false
});
}, { inplace: false })
}
constructor(actor, options = {}) {
super(options);
this.actor = actor;
this.hookReference = Hooks.on(APP_ASTROLOGIE_REFRESH, () => this.refreshAstrologie());
}
getData(options) {
this.appData = super.getData(options)
const calendrier = game.system.rdd.calendrier;
mergeObject(this.appData, {
foundry.utils.mergeObject(this.appData, {
isGM: game.user.isGM,
isActor: this.actor != undefined,
calendrier: calendrier.getTimestamp().toCalendrier(),
@ -50,7 +49,7 @@ export class AppAstrologie extends Application {
signeNaissance: RdDTimestamp.definition(0)
}
})
return this.appData;
return this.appData
}
getActorAstrologie() {
@ -85,9 +84,10 @@ export class AppAstrologie extends Application {
const nbAstral = calendrier.getNombreAstral()
const heures = RdDTimestamp.heures();
return {
ajustementsActors: game.actors.filter(it => it.isPersonnage() && it.hasPlayerOwner)
ajustementsActors: game.actors.filter(actor => actor.isPersonnageJoueur())
.map(actor => this.getAjustementActor(actor, nbAstral, heures)),
nombresAstraux: calendrier.getNombresAstraux().map(na => this.getDetailNombreAstral(na))
nombresAstraux: game.system.rdd.calendrier.getNombresAstraux()
.map(na => this.getDetailNombreAstral(na))
}
}
return {}
@ -104,15 +104,18 @@ export class AppAstrologie extends Application {
}
getDetailNombreAstral(nombreAstral) {
const detail = duplicate(nombreAstral);
const detail = foundry.utils.duplicate(nombreAstral);
const timestamp = new RdDTimestamp({ indexDate: nombreAstral.index });
detail.date = { mois: timestamp.mois, jour: timestamp.jour + 1 };
detail.valeursFausses.forEach(fausse => fausse.actorName = game.actors.get(fausse.actorId).name ?? "Inconnu");
detail.lectures.forEach(lecture => lecture.actorName = game.actors.get(lecture.actorId).name ?? "Inconnu");
return detail;
}
/* -------------------------------------------- */
activateListeners(html) {
if (!this.hookReference){
this.hookReference = Hooks.on(APP_ASTROLOGIE_REFRESH, () => this.refreshAstrologie());
}
super.activateListeners(html);
this.html = html;
this.html.find('select[name="signe-astral"]').change(event => {
@ -145,8 +148,7 @@ export class AppAstrologie extends Application {
/* -------------------------------------------- */
async onRebuild() {
game.system.rdd.calendrier.resetNombresAstraux();
await game.system.rdd.calendrier.resetNombresAstraux();
await game.system.rdd.calendrier.rebuildNombresAstraux();
}
@ -195,6 +197,8 @@ export class AppAstrologie extends Application {
}
refreshAstrologie() {
this.count = (this.count ?? 0)+1
console.log(`Refreshing ${this.count}`);
this.render(true)
}

View File

@ -3,10 +3,8 @@ export class DialogChateauDormant extends Dialog {
static async create() {
const date = game.system.rdd.calendrier.dateCourante();
const actors = game.actors.filter(actor => actor.hasPlayerOwner && actor.isPersonnage());
const dialogData = {
actors: actors,
actors: game.actors.filter(actor => actor.isPersonnageJoueur()),
date: date,
motifStress: `Nuit du ${date}`,
finChateauDormant: game.system.rdd.calendrier.getTimestampFinChateauDormant()

View File

@ -6,7 +6,7 @@ export class DialogStress extends Dialog {
motif: "Motif",
stress: 10,
immediat: false,
actors: game.actors.filter(actor => actor.hasPlayerOwner && actor.isPersonnage())
actors: game.actors.filter(actor => actor.isPersonnageJoueur())
.map(actor => ({
id: actor.id,
name: actor.name,

View File

@ -61,7 +61,7 @@ export class RdDCalendrierEditor extends Dialog {
/* -------------------------------------------- */
updateData(calendrierData) {
this.calendrierData = duplicate(calendrierData);
this.calendrierData = foundry.utils.duplicate(calendrierData);
}
}

View File

@ -35,7 +35,7 @@ export class RdDCalendrier extends Application {
}
static get defaultOptions() {
return mergeObject(super.defaultOptions, {
return foundry.utils.mergeObject(super.defaultOptions, {
title: "Calendrier",
template: TEMPLATE_CALENDRIER,
classes: ["calendar"],
@ -43,7 +43,7 @@ export class RdDCalendrier extends Application {
resizable: false,
width: 'fit-content',
height: 'fit-content',
});
}, { inplace: false })
}
constructor() {
@ -51,7 +51,6 @@ export class RdDCalendrier extends Application {
this.timestamp = RdDTimestamp.getWorldTime();
if (Misc.isUniqueConnectedGM()) { // Uniquement si GM
RdDTimestamp.setWorldTime(this.timestamp);
this.nombresAstraux = this.getNombresAstraux();
this.rebuildNombresAstraux(); // Ensure always up-to-date
}
Hooks.on('updateSetting', async (setting, update, options, id) => this.onUpdateSetting(setting, update, options, id));
@ -108,7 +107,10 @@ export class RdDCalendrier extends Application {
this.timestamp = RdDTimestamp.getWorldTime();
this.positionAiguilles()
this.render(false);
Hooks.callAll(APP_ASTROLOGIE_REFRESH);
Hooks.callAll(APP_ASTROLOGIE_REFRESH)
}
if (setting.key == SYSTEM_RDD + '.' + "liste-nombre-astral") {
Hooks.callAll(APP_ASTROLOGIE_REFRESH)
}
}
@ -120,7 +122,7 @@ export class RdDCalendrier extends Application {
/* -------------------------------------------- */
fillCalendrierData(formData = {}) {
mergeObject(formData, this.timestamp.toCalendrier());
foundry.utils.mergeObject(formData, this.timestamp.toCalendrier());
formData.isGM = game.user.isGM;
formData.heures = RdDTimestamp.definitions()
formData.horlogeAnalogique = this.horlogeAnalogique;
@ -167,7 +169,11 @@ export class RdDCalendrier extends Application {
/* -------------------------------------------- */
getNombresAstraux() {
return game.settings.get(SYSTEM_RDD, "liste-nombre-astral") ?? [];
return game.settings.get(SYSTEM_RDD, "liste-nombre-astral") ?? []
}
async setNombresAstraux(nombresAstraux) {
await game.settings.set(SYSTEM_RDD, "liste-nombre-astral", nombresAstraux)
}
/* -------------------------------------------- */
@ -225,20 +231,15 @@ export class RdDCalendrier extends Application {
const nombreAstral = await RdDDice.rollTotal("1dh", { showDice: HIDE_DICE, rollMode: "selfroll" });
return {
nombreAstral: nombreAstral,
valeursFausses: [],
lectures: [],
index: indexDate
}
}
/* -------------------------------------------- */
resetNombresAstraux() {
this.nombresAstraux = [];
game.settings.set(SYSTEM_RDD, "liste-nombre-astral", []);
game.socket.emit(SYSTEM_SOCKET_ID, {
msg: "msg_reset_nombre_astral",
data: {}
});
async resetNombresAstraux() {
await Promise.all(game.actors.filter(it => it.type == "personnage").map(async it => await it.deleteNombresAstraux()))
await this.setNombresAstraux([])
}
/**
@ -251,39 +252,30 @@ export class RdDCalendrier extends Application {
if (indexDate == undefined) {
indexDate = this.timestamp.indexDate;
}
this.nombresAstraux = this.getNombresAstraux();
let astralData = this.nombresAstraux.find((nombreAstral, i) => nombreAstral.index == indexDate);
const nombresAstraux = this.getNombresAstraux()
let astralData = nombresAstraux.find(it => it.index == indexDate);
return astralData?.nombreAstral ?? 0;
}
/* -------------------------------------------- */
async rebuildNombresAstraux() {
if (Misc.isUniqueConnectedGM()) {
let newList = [];
const nombresAstraux = this.getNombresAstraux()
let newNombresAstraux = [];
for (let i = 0; i < MAX_NOMBRE_ASTRAL; i++) {
let dayIndex = this.timestamp.indexDate + i;
let na = this.nombresAstraux.find(n => n.index == dayIndex);
let na = nombresAstraux.find(it => it.index == dayIndex);
if (na) {
newList[i] = na;
newNombresAstraux[i] = na;
} else {
newList[i] = await this.ajouterNombreAstral(dayIndex);
newNombresAstraux[i] = await this.ajouterNombreAstral(dayIndex);
}
}
this.nombresAstraux = newList;
game.settings.set(SYSTEM_RDD, "liste-nombre-astral", newList);
game.actors.filter(it => it.isPersonnage()).forEach(actor => actor.supprimerAnciensNombresAstraux());
this.notifyChangeNombresAstraux();
await this.setNombresAstraux(newNombresAstraux);
}
}
notifyChangeNombresAstraux() {
Hooks.callAll(APP_ASTROLOGIE_REFRESH);
game.socket.emit(SYSTEM_SOCKET_ID, {
msg: "msg_refresh_nombre_astral",
data: {}
});
}
/* -------------------------------------------- */
async setNewTimestamp(newTimestamp) {
const oldTimestamp = this.timestamp;
@ -373,25 +365,22 @@ export class RdDCalendrier extends Application {
request.nbAstral = await RdDDice.rollTotal("1dhr" + request.nbAstral, {
rollMode: "selfroll", showDice: HIDE_DICE
});
// Mise à jour des nombres astraux du joueur
this.addNbAstralIncorect(request.id, request.date, request.nbAstral);
}
if (Misc.getActiveUser(request.userId)?.isGM) {
RdDUtility.responseNombreAstral(request);
} else {
game.socket.emit(SYSTEM_SOCKET_ID, {
msg: "msg_response_nombre_astral",
data: request
});
}
// Mise à jour des nombres astraux du joueur
await this.addNbAstralJoueur(actor, request.date, request.nbAstral, request.isValid)
Hooks.callAll(APP_ASTROLOGIE_REFRESH)
game.socket.emit(SYSTEM_SOCKET_ID, { msg: "msg_app_astrologie_refresh", data: {} })
}
}
addNbAstralIncorect(actorId, date, nbAstral) {
const astralData = this.nombresAstraux.find((nombreAstral, i) => nombreAstral.index == date);
astralData.valeursFausses.push({ actorId: actorId, nombreAstral: nbAstral });
game.settings.set(SYSTEM_RDD, "liste-nombre-astral", this.nombresAstraux);
async addNbAstralJoueur(actor, date, nbAstral, isValid) {
const nombresAstraux = this.getNombresAstraux()
const astralData = nombresAstraux.find(it => it.index == date)
if (astralData) {
astralData.lectures.push({ actorId: actor.id, nombreAstral: nbAstral });
await this.setNombresAstraux(nombresAstraux);
await actor.ajouteNombreAstral(date, nbAstral, isValid);
}
}
/* -------------------------------------------- */

View File

@ -202,7 +202,7 @@ export class RdDTimestamp {
}
static setWorldTime(timestamp) {
game.settings.set(SYSTEM_RDD, WORLD_TIMESTAMP_SETTING, duplicate(timestamp));
game.settings.set(SYSTEM_RDD, WORLD_TIMESTAMP_SETTING, foundry.utils.duplicate(timestamp));
}
/** construit un RdDTimestamp à partir de l'année/mois/jour/heure?/minute? */
@ -231,6 +231,7 @@ export class RdDTimestamp {
get annee() { return Math.floor(this.indexDate / RDD_JOURS_PAR_AN) }
get mois() { return Math.floor(Misc.modulo(this.indexDate, RDD_JOURS_PAR_AN) / RDD_JOURS_PAR_MOIS) }
get nomMois() { return Math.floor(Misc.modulo(this.indexDate, RDD_JOURS_PAR_AN) / RDD_JOURS_PAR_MOIS) }
get jour() { return Misc.modulo(Misc.modulo(this.indexDate, RDD_JOURS_PAR_AN), RDD_JOURS_PAR_MOIS) }
get heure() { return Math.floor(this.indexMinute / RDD_MINUTES_PAR_HEURES) }
get minute() { return Misc.modulo(this.indexMinute, RDD_MINUTES_PAR_HEURES) }

View File

@ -117,7 +117,7 @@ function $loadFilters(parameters) {
export class FenetreRechercheTirage extends Application {
static get defaultOptions() {
return mergeObject(super.defaultOptions, {
return foundry.utils.mergeObject(super.defaultOptions, {
template: "systems/foundryvtt-reve-de-dragon/templates/tirage/fenetre-recherche-tirage.hbs",
title: `Recherches et tirages`,
width: 600,
@ -125,7 +125,7 @@ export class FenetreRechercheTirage extends Application {
popOut: true,
dragDrop: [{ dragSelector: "a.content-link" }],
resizable: true
});
}, { inplace: false })
}
static async create() {
@ -133,7 +133,7 @@ export class FenetreRechercheTirage extends Application {
const parameters = {
milieux: milieux,
filterMilieux: $filterMilieux(milieux),
filterGroups: duplicate(FILTER_GROUPS).filter(it => it.group),
filterGroups: foundry.utils.duplicate(FILTER_GROUPS).filter(it => it.group),
}
const options = {}
$loadFilters(parameters);
@ -147,7 +147,7 @@ export class FenetreRechercheTirage extends Application {
}
async getData() {
return mergeObject(await super.getData(), this.parameters)
return foundry.utils.mergeObject(await super.getData(), this.parameters)
}
_canDragStart() { return true; }
@ -294,7 +294,7 @@ class FenetreRechercheConfiguration extends Dialog {
static async create() {
const configuration = {
compendiums: game.packs.filter(it => it.metadata.type == 'Item').map(it => it.metadata)
.map(it => mergeObject({ selected: game.system.rdd.environnement.compendiums.includes(it.id) }, it))
.map(it => foundry.utils.mergeObject({ selected: game.system.rdd.environnement.compendiums.includes(it.id) }, it))
}
const html = await renderTemplate("systems/foundryvtt-reve-de-dragon/templates/tirage/fenetre-recherche-configuration.hbs", configuration);
new FenetreRechercheConfiguration(html).render(true);

View File

@ -107,7 +107,7 @@ export class EffetsRencontre {
}
static rdd_part_tete = async (dialog, context) => {
mergeObject(context, {
foundry.utils.mergeObject(context, {
tete: context.rolled.isPart,
poesie: await Poetique.getExtrait()
})
@ -118,7 +118,7 @@ export class EffetsRencontre {
}
static rdd_echec_queue = async (dialog, context) => {
mergeObject(context, {
foundry.utils.mergeObject(context, {
queues: [await context.actor.ajouterQueue()],
poesie: await Poetique.getExtrait()
})

View File

@ -1,4 +1,3 @@
import { SYSTEM_RDD } from "../constants.js";
import { Misc } from "../misc.js";
import { TMRConstants, tmrTokenZIndex } from "../tmr-constants.js";
import { TMRUtility } from "../tmr-utility.js";
@ -14,12 +13,12 @@ export class PixiTMR {
static register(name, img) {
PixiTMR.textures[name] = img;
}
static async init() {
await Promise.all(
Object.values(PixiTMR.textures)
.filter(img => img != undefined)
.map(async img => PIXI.Sprite.from(await PIXI.Assets.load(img)))
)
.filter(img => img != undefined && !PIXI.utils.TextureCache[img])
.map(async img => PIXI.Sprite.from(await PIXI.Assets.load(img))))
}
constructor(tmrDialog, displaySize) {
@ -106,8 +105,9 @@ export class PixiTMR {
sprite(code, options = {}) {
let img = PixiTMR.getImgFromCode(code)
const texture = PIXI.utils.TextureCache[img]
let texture = PIXI.utils.TextureCache[img]
if (!texture) {
// TODO: charger la texture
console.error("Texture manquante", code, PIXI.utils.TextureCache)
return;
}

View File

@ -16,7 +16,7 @@ export class Rencontre extends Draconique {
return pixiTMR.sprite(this.code(), {
zIndex: tmrTokenZIndex.rencontre,
decallage: pixiTMR.sizes.decallage(0, 0),
taille: () => pixiTMR.sizes.twoThird,
taille: () => pixiTMR.sizes.full,
})
}
}

View File

@ -33,11 +33,10 @@ export class DialogFatigueVoyage extends Dialog {
return
}
if (!DialogFatigueVoyage.dialog) {
const playerActors = game.actors.filter(actor => actor.hasPlayerOwner && actor.isPersonnage())
.map(actor => DialogFatigueVoyage.prepareActor(actor))
const parameters = {
tableauFatigueMarche: TABLEAU_FATIGUE_MARCHE,
playerActors: playerActors,
playerActors: game.actors.filter(actor => actor.isPersonnageJoueur())
.map(actor => DialogFatigueVoyage.prepareActor(actor)),
nombreHeures: 1,
}
DialogFatigueVoyage.setModeDeplacement(parameters, undefined, undefined)
@ -143,18 +142,19 @@ export class DialogFatigueVoyage extends Dialog {
it => this.$extractActor(this.html.find(it))
)
actors.filter(it => it.selected)
.forEach(async it => {
.forEach(async it => {
const perteFatigue = fatigueBase + it.ajustement
ChatMessage.create({
whisper: ChatUtility.getWhisperRecipientsAndGMs(it.actor.name),
content: await renderTemplate(
'systems/foundryvtt-reve-de-dragon/templates/voyage/chat-fatigue_voyage.hbs', mergeObject(it,
'systems/foundryvtt-reve-de-dragon/templates/voyage/chat-fatigue_voyage.hbs',
foundry.utils.mergeObject(it,
{
parameters: this.parameters,
fatigueBase: fatigueBase,
perteFatigue: perteFatigue,
isVoyage: fatigueBase == this.parameters.nombreHeures * this.parameters.fatigueHoraire
})
}, { inplace: false })
),
})
await it.actor.santeIncDec("fatigue", perteFatigue)

View File

@ -92,6 +92,8 @@
--background-custom-button-hover: linear-gradient(to bottom, rgb(128, 0, 0) 5%, rgb(62, 1, 1) 100%);
--background-control-selected: linear-gradient(to bottom, hsla(0, 100%, 25%, 0.5) 5%, hsla(0, 100%, 12%, 0.5) 100%);
--background-tooltip: hsla(60, 12%, 85%, 0.95);
--color-tooltip:hsla(282, 47%, 33%, 0.9);
--color-tooltip-faint:hsla(282, 47%, 66%, 0.5);
--background-error:hsla(16, 100%, 50%, 0.8);
--color-profile-border: hsla(0, 0%, 80%, 0.05);
}
@ -433,6 +435,7 @@ table {border: 1px solid #7a7971;}
}
.flex-shrink {
flex: 'flex-shrink' ;
flex-shrink: 2;
}
:is(.flex-grow, .flex-grow-3) {
flex-grow: 3;
@ -440,6 +443,12 @@ table {border: 1px solid #7a7971;}
.flex-grow-2 {
flex-grow: 2;
}
.flex-grow-1 {
flex-grow: 1;
}
.flex-grow-0-5 {
flex-grow: 0.5;
}
.voyage-liste-survies {
max-width: 12rem;
}
@ -1315,10 +1324,7 @@ div.competence-column div.categorie-competence{
margin-right: 0.2rem;
margin-left: 0.2rem;
}
.blessures-title {
font-weight: bold;
}
.alchimie-title {
.item-label {
font-weight: bold;
}
.pointsreve-value {
@ -1521,6 +1527,11 @@ div.control-icon.token-hud-icon {
font-size: 1rem;
}
.chat-message header.message-header .heure-rdd {
font-size: 0.7rem;
flex-grow: 3;
}
.chat-message.whisper {
background: rgba(220,220,210,0.75);
border: 2px solid #545469;
@ -1939,7 +1950,7 @@ div.calendar-timestamp-edit select.calendar-signe-heure {
padding: 3px;
}
aside#tooltip{
aside#tooltip {
background: var(--background-tooltip);
color: var(--color-text-dark-primary);
font-size: 1rem;
@ -1947,6 +1958,15 @@ aside#tooltip{
padding: 0.4rem;
}
aside#tooltip span.reference {
color: var(--color-tooltip);
border: 1px solid var(--color-tooltip-faint);
}
aside#tooltip .toolclip p.faint {
color: var(--color-tooltip-faint);
}
.tooltip :is(.ttt-xp,.ttt-levelup) {
width: 250px;
background: var(--background-tooltip) !important;

View File

@ -1,8 +1,8 @@
{
"id": "foundryvtt-reve-de-dragon",
"title": "Rêve de Dragon",
"version": "11.2.15",
"download": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/archive/foundryvtt-reve-de-dragon-11.2.15.zip",
"version": "11.2.21",
"download": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/archive/foundryvtt-reve-de-dragon-11.2.21.zip",
"manifest": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/raw/v11/system.json",
"changelog": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/raw/branch/v11/changelog.md",
"compatibility": {
@ -528,8 +528,10 @@
}
],
"socket": true,
"gridDistance": 1,
"gridUnits": "m",
"grid": {
"distance": 1,
"units": "m"
},
"primaryTokenAttribute": "sante.vie",
"secondaryTokenAttribute": "sante.endurance",
"media": [

View File

@ -525,15 +525,11 @@
},
"Item": {
"types": [
"competence", "competencecreature",
"recettealchimique", "musique", "chant", "danse", "jeu", "recettecuisine", "oeuvre",
"objet", "arme", "armure", "conteneur", "herbe", "plante", "ingredient", "faune", "livre", "potion", "munition",
"monnaie", "nourritureboisson", "gemme",
"service",
"meditation", "rencontre", "queue", "ombre", "souffle", "tete", "casetmr", "signedraconique", "sort", "sortreserve",
"nombreastral", "tache", "blessure", "maladie", "poison", "possession",
"tarot", "extraitpoetique", "empoignade"
],
"arme", "armure", "blessure", "casetmr", "chant", "competence", "competencecreature", "conteneur", "danse",
"empoignade", "extraitpoetique", "faune", "gemme", "herbe", "ingredient", "jeu", "livre", "maladie", "meditation",
"monnaie", "munition", "musique", "nombreastral", "nourritureboisson", "objet", "oeuvre", "ombre", "plante", "possession",
"poison", "potion", "queue", "recettealchimique", "recettecuisine", "rencontre",
"service" ,"signedraconique", "sort", "sortreserve", "souffle", "tarot", "tache", "tete" ],
"templates": {
"description": {
"description": "",

View File

@ -3,10 +3,12 @@
<ul class="item-list alterne-list">
{{#each (trier 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 flex-shrink">
<a class="item-edit" data-tooltip="Edit Item"><i class="fas fa-edit"></i></a>
<a class="item-delete" data-tooltip="Delete Item"><i class="fas fa-trash"></i></a>
</div>
<div class="item-controls">
<a class="item-edit" data-tooltip="Modifier"><i class="fas fa-edit"></i></a>
<a class="item-delete" data-tooltip="Supprimer"><i class="fas fa-trash"></i></a>
&nbsp;
<a class="item-montrer" data-tooltip="Montrer"><i class="fas fa-comment"></i></a>
</div>
</li>
{{/each}}
</ul>

View File

@ -36,6 +36,7 @@
<span class="item-controls">
<a class="item-edit" data-tooltip="Editer"><i class="fas fa-edit"></i></a>
<a class="item-delete" data-tooltip="Supprimer"><i class="fas fa-trash"></i></a>
&nbsp;
<a class="item-montrer" data-tooltip="Montrer"><i class="fas fa-comment"></i></a>
</span>
</li>

View File

@ -55,9 +55,7 @@
<li class="caracteristique flexrow list-item" data-tooltip="Niveau d'éthylisme">
<label class="derivee-label" for="system.compteurs.ethylisme.value">{{system.compteurs.ethylisme.label}}</label>
<select class="derivee-value" name="system.compteurs.ethylisme.value" data-dtype="Number">
{{#select system.compteurs.ethylisme.value}}
{{>"systems/foundryvtt-reve-de-dragon/templates/enum-niveau-ethylisme.html"}}
{{/select}}
{{selectOptions @root.config.niveauEthylisme selected=system.compteurs.ethylisme.value valueAttr="value" nameAttr="value" labelAttr="label"}}
</select>
</li>

View File

@ -2,20 +2,13 @@
<li class="caracteristique flexrow list-item">
<span class="carac-label" name="catEntite">Catégorie : </span>
<select name="system.definition.categorieentite" value="{{system.definition.categorieentite}}" data-dtype="String" {{#unless @root.options.vueDetaillee}}disabled{{/unless}}>
{{#select system.definition.categorieentite}}
<option value="cauchemar">Cauchemar</option>
<option value="reve">Rêve</option>
{{/select}}
{{selectOptions @root.config.categorieEntite selected=system.definition.categorieentite}}
</select>
</li>
<li class="caracteristique flexrow list-item">
<span class="carac-label" name="typeEntite">Type d'entité : </span>
<select name="system.definition.typeentite" value="{{system.definition.typeentite}}" data-dtype="String" {{#unless @root.options.vueDetaillee}}disabled{{/unless}}>
{{#select system.definition.typeentite}}
<option value="incarne">Incarnée</option>
<option value="nonincarne">Non Incarnée</option>
<option value="blurette">Blurette</option>
{{/select}}
{{selectOptions @root.config.typeEntite selected=system.definition.typeentite}}
</select>
</li>
{{#each system.attributs as |attr key|}}

View File

@ -12,9 +12,11 @@
<img class="sheet-competence-img" src="{{tache.img}}"/>
<span class="competence-title tache-label"><a>{{tache.name}}
({{tache.system.points_de_tache_courant}}/{{tache.system.points_de_tache}})</a></span>
<div class="item-controls flex-shrink">
<a class="item-edit" data-tooltip="Edit Item"><i class="fas fa-edit"></i></a>
<a class="item-delete" data-tooltip="Delete Item"><i class="fas fa-trash"></i></a>
<div class="item-controls">
<a class="item-edit" data-tooltip="Modifier"><i class="fas fa-edit"></i></a>
<a class="item-delete" data-tooltip="Supprimer"><i class="fas fa-trash"></i></a>
&nbsp;
<a class="item-montrer" data-tooltip="Montrer"><i class="fas fa-comment"></i></a>
</div>
</li>
{{/if}}

View File

@ -64,8 +64,8 @@
</span>
<span class="competence-value">{{emp.system.pointsemp}}</span>
<div class="item-controls">
<a class="item-edit" data-tooltip="Edit Item"><i class="fas fa-edit"></i></a>
<a class="item-delete" data-tooltip="Delete Item"><i class="fas fa-trash"></i></a>
<a class="item-edit" data-tooltip="Modifier"><i class="fas fa-edit"></i></a>
<a class="item-delete" data-tooltip="Supprimer"><i class="fas fa-trash"></i></a>
</div>
</li>
{{/each}}

View File

@ -23,8 +23,8 @@
/>
{{#if @root.options.vueDetaillee}}
<div class="item-controls">
<a class="item-edit" data-tooltip="Edit Item"><i class="fas fa-edit"></i></a>
<a class="item-delete" data-tooltip="Delete Item"><i class="fas fa-trash"></i></a>
<a class="item-edit" data-tooltip="Modifier"><i class="fas fa-edit"></i></a>
<a class="item-delete" data-tooltip="Supprimer"><i class="fas fa-trash"></i></a>
</div>
{{/if}}
</li>

View File

@ -6,8 +6,8 @@
<img class="sheet-competence-img" src="{{possession.img}}" data-tooltip="{{possession.name}}"/>
<span class="competence-label">{{possession.name}}</span>
<div class="item-controls">
<a class="item-edit" data-tooltip="Edit Item"><i class="fas fa-edit"></i></a>
<a class="item-delete" data-tooltip="Delete Item"><i class="fas fa-trash"></i></a>
<a class="item-edit" data-tooltip="Modifier"><i class="fas fa-edit"></i></a>
<a class="item-delete" data-tooltip="Supprimer"><i class="fas fa-trash"></i></a>
</div>
</li>
{{/each}}

View File

@ -48,7 +48,9 @@
{{#if @root.options.isGM}}
<a class="item-delete" data-tooltip="Supprimer"><i class="fas fa-trash"></i></a>
{{/if}}
</div>
&nbsp;
<a class="item-montrer" data-tooltip="Montrer"><i class="fas fa-comment"></i></a>
</div>
{{/if}}
</li>
{{/unless}}

View File

@ -8,7 +8,8 @@
<a>{{queue.name}}</a>
</span>
<div class="item-controls">
<a class="item-delete" data-tooltip="Delete Item"><i class="fas fa-trash"></i></a>
<a class="item-delete" data-tooltip="Supprimer"><i class="fas fa-trash"></i></a>
<a class="item-montrer" data-tooltip="Montrer"><i class="fas fa-comment"></i></a>
{{#if queue.system.refoulement}}
<a class="item-action">Refouler</a>
{{/if}}

View File

@ -5,8 +5,9 @@
<li class="item flexrow" data-attribute={{key}} data-item-id="{{souffle._id}}" data-tooltip="Souffle: {{souffle.name}}">
<img class="sheet-competence-img" src="{{souffle.img}}"/>
<span class="item-edit flex-grow"><a>{{souffle.name}}</a></span>
<div class="item-controls flex-shrink">
<a class="item-delete" data-tooltip="Delete Item"><i class="fas fa-trash"></i></a>
<div class="item-controls">
<a class="item-delete" data-tooltip="Supprimer"><i class="fas fa-trash"></i></a>
<a class="item-montrer" data-tooltip="Montrer"><i class="fas fa-comment"></i></a>
</div>
</li>
{{/each}}

View File

@ -5,8 +5,9 @@
<li class="item flexrow" data-attribute={{key}} data-item-id="{{tete._id}}" data-tooltip="Tête: {{tete.name}}">
<img class="sheet-competence-img" src="{{tete.img}}"/>
<span class="item-edit flex-grow"><a>{{tete.name}}</a></span>
<div class="item-controls flex-shrink">
<a class="item-delete" data-tooltip="Delete Item"><i class="fas fa-trash"></i></a>
<div class="item-controls">
<a class="item-delete" data-tooltip="Supprimer"><i class="fas fa-trash"></i></a>
<a class="item-montrer" data-tooltip="Montrer"><i class="fas fa-comment"></i></a>
</div>
</li>
{{/each}}

View File

@ -6,8 +6,10 @@
<img class="sheet-competence-img" src="{{casetmr.img}}"/>
<span class="item-edit"><a>{{casetmr.name}}</a></span>
<span>{{casetmr.system.coord}} - {{caseTmr-label casetmr.system.coord}}</span>
<div class="item-controls flex-shrink">
<div class="item-controls">
<a class="item-delete" data-tooltip="Supprimer"><i class="fas fa-trash"></i></a>
&nbsp;
<a class="item-montrer" data-tooltip="Montrer"><i class="fas fa-comment"></i></a>
</div>
</li>
{{/each}}

View File

@ -5,9 +5,11 @@
<li class="item flexrow" data-item-id="{{meditation._id}}" data-attribute="{{key}}" data-tooltip="Méditation: {{meditation.name}}">
<img class="sheet-competence-img" src="{{meditation.img}}"/>
<span class="meditation-label flex-grow"><a data-item-id="{{meditation._id}}">{{meditation.name}} - {{meditation.system.competence}}</a></span>
<div class="item-controls flex-shrink">
<div class="item-controls">
<a class="item-edit" data-tooltip="Editer"><i class="fas fa-edit"></i></a>
<a class="item-delete" data-tooltip="Supprimer"><i class="fas fa-trash"></i></a>
&nbsp;
<a class="item-montrer" data-tooltip="Montrer"><i class="fas fa-comment"></i></a>
</div>
</li>
{{/each}}

View File

@ -10,7 +10,7 @@
{{#if rencontre.system.date}}
<span class="flex-shrink">{{upperFirst rencontre.system.heure}}, le {{rencontre.system.date}}</span>
{{/if}}
<div class="item-controls flex-shrink">
<div class="item-controls">
<a class="item-delete" data-tooltip="Supprimer"><i class="fas fa-trash"></i></a>
</div>
</li>

View File

@ -6,7 +6,7 @@
<img class="sheet-competence-img" src="{{signe.img}}"/>
<span class="item-edit flex-grow"><a>{{signe.name}}</a></span>
<span class="flex-shrink">{{signe.system.difficulte}}</span>
<div class="item-controls flex-shrink">
<div class="item-controls">
<a class="item-delete" data-tooltip="Supprimer"><i class="fas fa-trash"></i></a>
</div>
</li>

View File

@ -7,7 +7,7 @@
<img class="sheet-competence-img" src="{{sort.img}}"/>
<span class="item-edit"><a>{{#if sort.system.echectotal}}Echec total: {{/if}}{{sort.name}} r{{sort.system.ptreve}}</a></span>
<span>{{sort.system.coord}} - {{caseTmr-label sort.system.coord}}</span>
<div class="item-controls flex-shrink">
<div class="item-controls">
<a class="item-delete flex-shrink" data-tooltip="Supprimer"><i class="fas fa-trash"></i></a>
</div>
</li>

View File

@ -4,15 +4,16 @@
{{#each (trier sorts) as |sort key|}}
<li class="item list-item flexrow" data-item-id="{{sort._id}}" data-attribute="{{key}}" data-tooltip="{{#if sort.system.isrituel}}Rituel{{else}}Sort{{/if}}: {{sort.name}}">
<img class="sheet-competence-img" src="{{sort.img}}"/>
<span class="item-edit flex-grow-2">
<span class="item-edit flex-grow-3">
<a data-item-id="{{sort._id}}">{{sort.name}}
- {{#if sort.system.caseTMRspeciale}}{{sort.system.caseTMRspeciale}}{{else}}{{upperFirst sort.system.caseTMR}}{{/if}}
</a>
</span>
<span>{{#if sort.system.isrituel}}Rituel{{/if}}</span>
<span>{{sort.system.draconic}} / {{sort.system.difficulte}}</span>
<span class="flex-grow-0-5">{{#if sort.system.isrituel}}Rituel{{/if}}</span>
<span class="flex-grow-2">{{sort.system.draconic}}/{{sort.system.difficulte}}</span>
<div class="item-controls flex-shrink">
<a class="item-delete" data-tooltip="Supprimer"><i class="fas fa-trash"></i></a>
<a class="item-montrer" data-tooltip="Montrer"><i class="fas fa-comment"></i></a>
</div>
</li>
{{/each}}

View File

@ -4,9 +4,11 @@
{{#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.system.base}})</a></span>
<div class="item-controls flex-shrink">
<a class="item-edit" data-tooltip="Edit Item"><i class="fas fa-edit"></i></a>
<a class="item-delete" data-tooltip="Delete Item"><i class="fas fa-trash"></i></a>
<div class="item-controls">
<a class="item-edit" data-tooltip="Modifier"><i class="fas fa-edit"></i></a>
<a class="item-delete" data-tooltip="Supprimer"><i class="fas fa-trash"></i></a>
&nbsp;
<a class="item-montrer" data-tooltip="Montrer"><i class="fas fa-comment"></i></a>
</div>
</li>
{{/each}}

View File

@ -22,7 +22,7 @@
{{/if}}
</span>
{{/if}}
<div class="item-controls flex-shrink">
<div class="item-controls">
<a class="subacteur-delete" data-tooltip="Supprimer"><i class="fas fa-trash"></i></a>
</div>
</li>

View File

@ -1,5 +1,5 @@
{{#if maladiesPoisons.length}}
<h3 class="blessures-title">Maladies & Poisons:</h3>
<h3 class="item-label">Maladies & Poisons:</h3>
<ul class="item-list alterne-list">
<li class="competence-header flexrow">
<span class="competence-title flex-grow competence-label">Nom</span>

View File

@ -12,13 +12,21 @@
<li class="item flexrow" >
<span class="competence-label">Refoulement : </span>
<span>
{{#if options.isGM}}
{{#if options.isGM}}
<input class="competence-value" type="text" name="system.reve.refoulement.value" value="{{system.reve.refoulement.value}}" data-dtype="Number"/>
{{else}}
{{else}}
{{system.reve.refoulement.value}}
{{/if}}
{{/if}}
</span>
</li>
{{#if system.reve.reve.thanatosused}}
<li class="item flexrow" >
<span class="competence-label">La prochaine queue est une Ombre</span>
<span>
<img class="sheet-competence-img" src="systems/foundryvtt-reve-de-dragon/icons/competence_thanatos.webp"/>
</span>
</li>
{{/if}}
</ul>
<hr>
{{> "systems/foundryvtt-reve-de-dragon/templates/actor/dragon-queues.html"}}

View File

@ -5,8 +5,10 @@
<a>{{oeuvre.name}} (niveau {{oeuvre.system.niveau}})</a>
</span>
<div class="item-controls">
<a class="item-edit" data-tooltip="Edit Item"><i class="fas fa-edit"></i></a>
<a class="item-delete" data-tooltip="Delete Item"><i class="fas fa-trash"></i></a>
<a class="item-edit" data-tooltip="Modifier"><i class="fas fa-edit"></i></a>
<a class="item-delete" data-tooltip="Supprimer"><i class="fas fa-trash"></i></a>
&nbsp;
<a class="item-montrer" data-tooltip="Montrer"><i class="fas fa-comment"></i></a>
</div>
</li>

View File

@ -1,6 +1,6 @@
{{#if possessions.length}}
{{!-- Possession --}}
<h3 class="blessures-title">Possession:</h3>
<h3 class="item-label">Possession:</h3>
<ul class="item-list alterne-list">
<li class="competence-header flexrow">
<span class="competence-title flex-grow competence-label">Nom</span>
@ -15,6 +15,8 @@
<div class="item-controls">
<a class="item-edit" data-tooltip="Modifier"><i class="fas fa-edit"></i></a>
<a class="item-delete" data-tooltip="Supprimer"><i class="fas fa-trash"></i></a>
&nbsp;
<a class="item-montrer" data-tooltip="Montrer"><i class="fas fa-comment"></i></a>
</div>
</li>
{{/each}}

View File

@ -8,9 +8,11 @@
({{tache.system.points_de_tache_courant}}{{#if
(or @root.options.isGM (not tache.system.cacher_points_de_tache))
}}/{{tache.system.points_de_tache}}{{/if}})</a></span>
<div class="item-controls flex-shrink">
<a class="item-edit" data-tooltip="Edit Item"><i class="fas fa-edit"></i></a>
<a class="item-delete" data-tooltip="Delete Item"><i class="fas fa-trash"></i></a>
<div class="item-controls">
<a class="item-edit" data-tooltip="Modifier"><i class="fas fa-edit"></i></a>
<a class="item-delete" data-tooltip="Supprimer"><i class="fas fa-trash"></i></a>
&nbsp;
<a class="item-montrer" data-tooltip="Montrer"><i class="fas fa-comment"></i></a>
</div>
</li>
{{/unless}}

View File

@ -1,3 +1,4 @@
{{log 'chat-vente-item' this}}
<div class="post-item" data-transfer="{{transfer}}">
<h3>{{#if alias}}{{alias}} propose: {{else}}Acheter {{/if}}{{item.name}}</h3>
{{#if item.img}}
@ -12,7 +13,7 @@
<hr>
<p>
{{#unless quantiteIllimite}}
<span>Lots disponibles: <span class="quantiteNbLots">{{quantiteNbLots}}</span></span><br>
<span>Lots disponibles: {{nbLots}}</span><br>
{{/unless}}
{{#if (gt tailleLot 1)}}
<span>Lots de: <span class="tailleLot">{{tailleLot}}</span></span><br>
@ -22,15 +23,9 @@
<span class="prixLot">{{numberFormat prixLot decimals=2 sign=false}}</span> Sols</strong></span><br>
{{/if}}
</p>
{{#if (or (gt quantiteNbLots 0) quantiteIllimite)}}
{{#if (or (gt nbLots 0) quantiteIllimite)}}
<span class="chat-card-button-area">
<a class="button-acheter chat-card-button"
data-jsondata='{{jsondata}}'
{{#if vendeurId}}data-vendeurId='{{vendeurId}}'{{/if}}
data-tailleLot="{{tailleLot}}"
data-quantiteNbLots="{{quantiteNbLots}}"
data-quantiteIllimite="{{#if quantiteIllimite}}true{{else}}false{{/if}}"
data-prixLot="{{prixLot}}">
<a class="button-acheter chat-card-button">
{{#if (eq prixLot 0)}}Prendre{{else}}Acheter{{/if}}</a>
</span>
{{/if}}

View File

@ -1,22 +1,20 @@
<span draggable="true">
{{#if pack}}
{{!-- draggable="true" --}}
<a class="content-link"
data-uuid="Compendium.{{pack}}.{{id}}"
<span draggable="true">
<a class="{{#if pack}}content-link{{else}}rdd-world-content-link{{/if}}"
data-id="{{id}}"
data-link=""
{{#if doctype}}
data-doctype="{{doctype}}"
data-type="{{doctype}}"
{{/if}}
{{#if pack}}
data-pack="{{pack}}"
{{#if doctype}}data-doctype="{{doctype}}"{{/if}}
data-id="{{id}}"
>
{{else}}
<a class="rdd-world-content-link"
{{#if doctype}}data-doctype="{{doctype}}"{{/if}}
data-id="{{id}}"
>
{{/if}}
{{#if img}}
<img class="in-text-img" src="{{img}}" data-tooltip="{{name}}" />
{{else}}
<i class="fas fa-suitcase"></i>
{{/if}}
{{name}}</a>
data-uuid="Compendium.{{pack}}.{{id}}"
{{/if}} >
{{#if img}}
<img class="in-text-img" src="{{img}}" data-tooltip="{{name}}" />
{{else}}
<i class="fas fa-suitcase"></i>
{{/if}}
{{name}}
</a>
</span>

View File

@ -0,0 +1,3 @@
<span class="message-metadata heure-rdd">
{{this.jourDuMois}} {{this.mois.label}} - {{timestamp-imgSigne this.heure}}
</span>

View File

@ -2,8 +2,6 @@
<div class="flexrow">
<input type="number" name="{{path}}.nombre" value="{{nombre}}" data-dtype="Number"/>
<select name="{{path}}.unite" data-dtype="String" >
{{#select unite}}
{{>"systems/foundryvtt-reve-de-dragon/templates/enum-periode.html"}}
{{/select}}
{{selectOptions (timestamp-formulesPeriode) selected=unite labelAttr="label" nameAttr="code" valueAttr="code"}}
</select>
</div>

Some files were not shown because too many files have changed in this diff Show More