Merge pull request '11.2.10 - Les expériences d'Akarlikarlikar' (#691) from VincentVk/foundryvtt-reve-de-dragon:v11 into v11

Reviewed-on: public/foundryvtt-reve-de-dragon#691
This commit is contained in:
uberwald 2023-12-11 09:34:21 +01:00
commit f0fc44e00f
17 changed files with 299 additions and 108 deletions

View File

@ -1,4 +1,10 @@
# 11.2 # 11.2
## 11.2.10 - Les expériences d'Akarlikarlikar
- En cas d'expérience des caractéristiques dérivées,
- si plusieurs caractéristiques pourraient recevoir l'expérience, une fenêtre demande au joueur
- si une seule caractéristique peut recevoir de l'expérience, c'est attribué automatiquement
- Si la force est au maximum pour la taille personnage, on ne peut plus gagner d'expérience
## 11.2.9 - La barbe d'Akarlikarlikar ## 11.2.9 - La barbe d'Akarlikarlikar
- Amélioration des textes de tooltips - Amélioration des textes de tooltips
- Les tooltips sont plus dans le thème de couleur du système Rêve de Dragon - Les tooltips sont plus dans le thème de couleur du système Rêve de Dragon

View File

@ -35,6 +35,7 @@ import { ExperienceLog, XP_TOPIC } from "./actor/experience-log.js";
import { TYPES } from "./item.js"; import { TYPES } from "./item.js";
import { RdDBaseActorSang } from "./actor/base-actor-sang.js"; import { RdDBaseActorSang } from "./actor/base-actor-sang.js";
import { RdDCoeur } from "./coeur/rdd-coeur.js"; import { RdDCoeur } from "./coeur/rdd-coeur.js";
import { DialogChoixXpCarac } from "./dialog-choix-xp-carac.js";
export const MAINS_DIRECTRICES = ['Droitier', 'Gaucher', 'Ambidextre'] export const MAINS_DIRECTRICES = ['Droitier', 'Gaucher', 'Ambidextre']
@ -56,21 +57,20 @@ export class RdDActor extends RdDBaseActorSang {
/* -------------------------------------------- */ /* -------------------------------------------- */
$computeCaracDerivee() { $computeCaracDerivee() {
this.system.carac.force.value = Math.min(this.system.carac.force.value, parseInt(this.system.carac.taille.value) + 4); this.system.carac.force.value = Math.min(this.system.carac.force.value, parseInt(this.system.carac.taille.value) + 4);
this.system.carac.derobee.value = Math.floor(parseInt(((21 - this.system.carac.taille.value)) + parseInt(this.system.carac.agilite.value)) / 2);
let bonusDomKey = Math.floor((parseInt(this.system.carac.force.value) + parseInt(this.system.carac.taille.value)) / 2);
let tailleData = RdDCarac.getCaracDerivee(bonusDomKey);
this.system.attributs.plusdom.value = tailleData.plusdom;
this.system.attributs.sconst.value = RdDCarac.calculSConst(this.system.carac.constitution.value);
this.system.attributs.sust.value = RdDCarac.getCaracDerivee(this.system.carac.taille.value).sust;
this.system.attributs.encombrement.value = (parseInt(this.system.carac.force.value) + parseInt(this.system.carac.taille.value)) / 2;
this.system.carac.melee.value = Math.floor((parseInt(this.system.carac.force.value) + parseInt(this.system.carac.agilite.value)) / 2); this.system.carac.melee.value = Math.floor((parseInt(this.system.carac.force.value) + parseInt(this.system.carac.agilite.value)) / 2);
this.system.carac.tir.value = Math.floor((parseInt(this.system.carac.vue.value) + parseInt(this.system.carac.dexterite.value)) / 2); this.system.carac.tir.value = Math.floor((parseInt(this.system.carac.vue.value) + parseInt(this.system.carac.dexterite.value)) / 2);
this.system.carac.lancer.value = Math.floor((parseInt(this.system.carac.tir.value) + parseInt(this.system.carac.force.value)) / 2); this.system.carac.lancer.value = Math.floor((parseInt(this.system.carac.tir.value) + parseInt(this.system.carac.force.value)) / 2);
this.system.carac.derobee.value = Math.floor(parseInt(((21 - this.system.carac.taille.value)) + parseInt(this.system.carac.agilite.value)) / 2);
let bonusDomKey = Math.floor((parseInt(this.system.carac.force.value) + parseInt(this.system.carac.taille.value)) / 2);
let tailleData = RdDCarac.getCaracDerivee(bonusDomKey);
this.system.attributs.plusdom.value = tailleData.plusdom;
this.system.attributs.encombrement.value = (parseInt(this.system.carac.force.value) + parseInt(this.system.carac.taille.value)) / 2;
this.system.attributs.sconst.value = RdDCarac.calculSConst(this.system.carac.constitution.value);
this.system.attributs.sust.value = RdDCarac.getCaracDerivee(this.system.carac.taille.value).sust;
this.system.sante.vie.max = Math.ceil((parseInt(this.system.carac.taille.value) + parseInt(this.system.carac.constitution.value)) / 2); this.system.sante.vie.max = Math.ceil((parseInt(this.system.carac.taille.value) + parseInt(this.system.carac.constitution.value)) / 2);
this.system.sante.vie.value = Math.min(this.system.sante.vie.value, this.system.sante.vie.max) this.system.sante.vie.value = Math.min(this.system.sante.vie.value, this.system.sante.vie.max)
@ -659,7 +659,7 @@ export class RdDActor extends RdDBaseActorSang {
this.setPointsDeChance(to); this.setPointsDeChance(to);
} }
} }
let selectedCarac = RdDBaseActor._findCaracByName(this.system.carac, caracName); let selectedCarac = this.findCaracByName(caracName);
const from = selectedCarac.value const from = selectedCarac.value
await this.update({ [`system.carac.${caracName}.value`]: to }); await this.update({ [`system.carac.${caracName}.value`]: to });
await ExperienceLog.add(this, XP_TOPIC.CARAC, from, to, caracName); await ExperienceLog.add(this, XP_TOPIC.CARAC, from, to, caracName);
@ -670,7 +670,7 @@ export class RdDActor extends RdDBaseActorSang {
if (caracName == 'Taille') { if (caracName == 'Taille') {
return; return;
} }
let selectedCarac = RdDBaseActor._findCaracByName(this.system.carac, caracName); let selectedCarac = this.findCaracByName(caracName);
if (!selectedCarac.derivee) { if (!selectedCarac.derivee) {
const from = Number(selectedCarac.xp); const from = Number(selectedCarac.xp);
await this.update({ [`system.carac.${caracName}.xp`]: to }); await this.update({ [`system.carac.${caracName}.xp`]: to });
@ -684,7 +684,7 @@ export class RdDActor extends RdDBaseActorSang {
if (caracName == 'Taille') { if (caracName == 'Taille') {
return; return;
} }
let carac = RdDBaseActor._findCaracByName(this.system.carac, caracName); let carac = this.findCaracByName(caracName);
if (carac) { if (carac) {
carac = duplicate(carac); carac = duplicate(carac);
const fromXp = Number(carac.xp); const fromXp = Number(carac.xp);
@ -1166,8 +1166,8 @@ export class RdDActor extends RdDBaseActorSang {
title: "Nourriture brute", title: "Nourriture brute",
content: `Que faire de votre ${item.name}`, content: `Que faire de votre ${item.name}`,
buttons: { buttons: {
'cuisiner': { icon: '<i class="fas fa-check"></i>', label: 'Cuisiner', callback: async () => await this.preparerNourriture(item) }, 'cuisiner': { icon: '<i class="fa-solid fa-utensils"></i>', label: 'Cuisiner', callback: async () => await this.preparerNourriture(item) },
'manger': { icon: '<i class="fas fa-check"></i>', label: 'Manger cru', callback: async () => await this.mangerNourriture(item, onActionItem) } 'manger': { icon: '<i class="fa-solid fa-drumstick-bite"></i>', label: 'Manger cru', callback: async () => await this.mangerNourriture(item, onActionItem) }
} }
}); });
return utilisation.render(true); return utilisation.render(true);
@ -1472,8 +1472,14 @@ export class RdDActor extends RdDBaseActorSang {
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
isCaracMax(code) {
if (code == 'force' && parseInt(this.system.carac.force.value) >= parseInt(this.system.carac.taille.value) + 4) {
return true;
}
return false
}
async checkCaracXP(caracName, display = true) { async checkCaracXP(caracName, display = true) {
let carac = RdDBaseActor._findCaracByName(this.system.carac, caracName); let carac = this.findCaracByName(caracName);
if (carac && carac.xp > 0) { if (carac && carac.xp > 0) {
const niveauSuivant = Number(carac.value) + 1; const niveauSuivant = Number(carac.value) + 1;
let xpNeeded = RdDCarac.getCaracNextXp(niveauSuivant); let xpNeeded = RdDCarac.getCaracNextXp(niveauSuivant);
@ -1534,8 +1540,11 @@ export class RdDActor extends RdDBaseActorSang {
async appliquerAjoutExperience(rollData, hideChatMessage = 'show') { async appliquerAjoutExperience(rollData, hideChatMessage = 'show') {
hideChatMessage = hideChatMessage == 'hide' || (Misc.isRollModeHiddenToPlayer() && !game.user.isGM) hideChatMessage = hideChatMessage == 'hide' || (Misc.isRollModeHiddenToPlayer() && !game.user.isGM)
let xpData = await this._appliquerExperience(rollData.rolled, rollData.selectedCarac.label, rollData.competence, rollData.jetResistance); let xpData = await this._appliquerExperience(rollData.rolled, rollData.selectedCarac.label, rollData.competence, rollData.jetResistance);
if (xpData) { if (xpData.length) {
const content = await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-actor-gain-xp.html`, xpData); const content = await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-actor-gain-xp.html`, {
actor: this,
xpData
});
if (hideChatMessage) { if (hideChatMessage) {
ChatUtility.blindMessageToGM({ content: content }); ChatUtility.blindMessageToGM({ content: content });
} }
@ -1698,7 +1707,7 @@ export class RdDActor extends RdDBaseActorSang {
if (rollData.competence.name.includes('Thanatos')) { // Si Thanatos if (rollData.competence.name.includes('Thanatos')) { // Si Thanatos
await this.update({ "system.reve.reve.thanatosused": true }); await this.update({ "system.reve.reve.thanatosused": true });
} }
let reveActuel = this.system.reve.reve.value; let reveActuel = parseInt(this.system.reve.reve.value)
if (rolled.isSuccess) { // Réussite du sort ! if (rolled.isSuccess) { // Réussite du sort !
if (rolled.isPart) { if (rolled.isPart) {
rollData.depenseReve = Math.max(Math.floor(rollData.depenseReve / 2), 1); rollData.depenseReve = Math.max(Math.floor(rollData.depenseReve / 2), 1);
@ -2265,9 +2274,7 @@ export class RdDActor extends RdDBaseActorSang {
}); });
return undefined; return undefined;
} }
if (caracName == 'Vie') caracName = 'constitution';
if (caracName == 'derobee') caracName = 'agilite';
if (caracName == 'reve-actuel') caracName = 'reve';
let xp = Math.abs(rolled.finalLevel); let xp = Math.abs(rolled.finalLevel);
// impair: arrondi inférieur en carac // impair: arrondi inférieur en carac
let xpCarac = competence ? Math.floor(xp / 2) : Math.max(Math.floor(xp / 2), 1); let xpCarac = competence ? Math.floor(xp / 2) : Math.max(Math.floor(xp / 2), 1);
@ -2280,11 +2287,10 @@ export class RdDActor extends RdDBaseActorSang {
// max 1 xp sur jets de résistance // max 1 xp sur jets de résistance
xpCarac = Math.min(1, xpCarac); xpCarac = Math.min(1, xpCarac);
} }
let xpData = { alias: this.name, caracName, xpCarac, competence, xpCompetence }; return [
...(await this._xpCompetence({ competence, xpCompetence })),
await this._xpCompetence(xpData); ...(await this._xpCarac({ caracName, xpCarac }))
await this._xpCarac(xpData); ];
return xpData;
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
@ -2292,31 +2298,67 @@ export class RdDActor extends RdDBaseActorSang {
if (xpData.competence) { if (xpData.competence) {
const from = Number(xpData.competence.system.xp); const from = Number(xpData.competence.system.xp);
const to = from + xpData.xpCompetence; const to = from + xpData.xpCompetence;
let update = { _id: xpData.competence._id, 'system.xp': to }; await this.updateEmbeddedDocuments('Item', [{ _id: xpData.competence._id, 'system.xp': to }]);
await this.updateEmbeddedDocuments('Item', [update]);
xpData.checkComp = await this.checkCompetenceXP(xpData.competence.name, undefined, false); xpData.checkComp = await this.checkCompetenceXP(xpData.competence.name, undefined, false);
await ExperienceLog.add(this, XP_TOPIC.XP, from, to, xpData.competence.name); await ExperienceLog.add(this, XP_TOPIC.XP, from, to, xpData.competence.name);
return [xpData]
} }
return []
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
async _xpCarac(xpData) { async _xpCarac(xpData) {
if (xpData.xpCarac > 0) { if (xpData.xpCarac > 0) {
let carac = duplicate(this.system.carac); const carac = duplicate(this.system.carac)
let selectedCarac = RdDBaseActor._findCaracByName(carac, xpData.caracName); const code = RdDBaseActor._findCaracNode(carac, xpData.caracName)
if (!selectedCarac.derivee) { const selectedCarac = carac[code]
const from = Number(selectedCarac.xp); if (this.isCaracMax(code)) {
const to = from + xpData.xpCarac; ui.notifications.info(`Pas d'expérience: la caractéristique '${selectedCarac.label}' est déjà au maximum pour ${this.name}`)
selectedCarac.xp = to; return []
await this.update({ "system.carac": carac }); }
xpData.checkCarac = await this.checkCaracXP(selectedCarac.label, false); if (selectedCarac && !selectedCarac.derivee) {
await ExperienceLog.add(this, XP_TOPIC.XPCARAC, from, to, xpData.caracName); const from = Number(selectedCarac.xp)
const to = from + xpData.xpCarac
selectedCarac.xp = to
await this.update({ "system.carac": carac })
xpData.checkCarac = await this.checkCaracXP(selectedCarac.label, false)
await ExperienceLog.add(this, XP_TOPIC.XPCARAC, from, to, xpData.caracName)
return [xpData]
} else { } else {
xpData.caracRepartitionManuelle = true; return await this._xpCaracDerivee(xpData)
} }
} }
return []
} }
async _xpCaracDerivee(xpData) {
const caracs = RdDActor._getComposantsCaracDerivee(xpData.caracName)
.map(c => mergeObject(this.system.carac[c], { isMax: this.isCaracMax(c) }))
switch (caracs.filter(it => !it.isMax).length) {
case 0:
xpData.caracRepartitionManuelle = true;
return [xpData]
case 1:
xpData.caracName = caracs.find(it => !it.isMax).label
return this._xpCarac(xpData)
default:
await DialogChoixXpCarac.choix(this, xpData, caracs)
return []
}
}
static _getComposantsCaracDerivee(caracName) {
switch (Grammar.toLowerCaseNoAccent(caracName)) {
case 'vie': return ['constitution']
case 'tir': return ['vue', 'dexterite']
case 'lancer': return ['force', 'dexterite', 'vue']
case 'melee': return ['force', 'agilite']
case 'derobee': return ['agilite']
}
return []
}
/* -------------------------------------------- */ /* -------------------------------------------- */
async resetNombresAstraux() { async resetNombresAstraux() {
const deletions = this.itemTypes['nombreastral'].map(it => it._id); const deletions = this.itemTypes['nombreastral'].map(it => it._id);
@ -2418,7 +2460,7 @@ export class RdDActor extends RdDBaseActorSang {
draconic: this.getDraconicList(), draconic: this.getDraconicList(),
sort: this.itemTypes['sort'], sort: this.itemTypes['sort'],
signes: this.itemTypes['signedraconique'], signes: this.itemTypes['signedraconique'],
caracReve: this.system.carac.reve.value, caracReve: parseInt(this.system.carac.reve.value),
pointsReve: this.getReveActuel(), pointsReve: this.getReveActuel(),
isRapide: isRapide, isRapide: isRapide,
isGM: game.user.isGM, isGM: game.user.isGM,
@ -2509,7 +2551,7 @@ export class RdDActor extends RdDBaseActorSang {
/* -------------------------------------------- */ /* -------------------------------------------- */
verifierForceMin(item) { verifierForceMin(item) {
if (item.type == 'arme' && item.system.force > this.system.carac.force.value) { if (item.type == 'arme' && item.system.force > parseInt(this.system.carac.force.value)) {
ChatMessage.create({ ChatMessage.create({
content: `<strong>${this.name} s'est équipé(e) de l'arme ${item.name}, mais n'a pas une force suffisante pour l'utiliser normalement </strong> content: `<strong>${this.name} s'est équipé(e) de l'arme ${item.name}, mais n'a pas une force suffisante pour l'utiliser normalement </strong>
(${item.system.force} nécessaire pour une Force de ${this.system.carac.force.value})` (${item.system.force} nécessaire pour une Force de ${this.system.carac.force.value})`

View File

@ -11,16 +11,14 @@ import { SystemCompendiums } from "../settings/system-compendiums.js";
import { APP_ASTROLOGIE_REFRESH } from "../sommeil/app-astrologie.js"; import { APP_ASTROLOGIE_REFRESH } from "../sommeil/app-astrologie.js";
export class RdDBaseActor extends Actor { export class RdDBaseActor extends Actor {
/* -------------------------------------------- */
static _findCaracByName(carac, name) {
name = Grammar.toLowerCaseNoAccent(name);
switch (name) {
case 'reve-actuel': case 'reve actuel':
return carac.reve;
case 'chance-actuelle': case 'chance actuelle':
return carac.chance;
}
static _findCaracNode(carac, name) {
return Object.entries(carac)
.filter(it => Grammar.equalsInsensitive(it[1].label, name))
.map(it => it[0])
.find(it => it);
}
static $findCaracByName(carac, name) {
const caracList = Object.entries(carac); const caracList = Object.entries(carac);
let entry = Misc.findFirstLike(name, caracList, { mapper: it => it[0], description: 'caractéristique' }); let entry = Misc.findFirstLike(name, caracList, { mapper: it => it[0], description: 'caractéristique' });
if (!entry || entry.length == 0) { if (!entry || entry.length == 0) {
@ -135,6 +133,21 @@ export class RdDBaseActor extends Actor {
super(docData, context); super(docData, context);
} }
findCaracByName(name) {
name = Grammar.toLowerCaseNoAccent(name)
switch (name) {
case 'reve-actuel': case 'reve actuel':
return this.system.carac.reve
case 'chance-actuelle': case 'chance actuelle':
return this.system.carac.chance
case 'vie':
return this.system.sante.vie
}
const carac = this.system.carac;
return RdDBaseActor.$findCaracByName(carac, name);
}
getCaracByName(name) { getCaracByName(name) {
switch (Grammar.toLowerCaseNoAccent(name)) { switch (Grammar.toLowerCaseNoAccent(name)) {
case 'reve-actuel': case 'reve actuel': case 'reve-actuel': case 'reve actuel':
@ -142,7 +155,7 @@ export class RdDBaseActor extends Actor {
case 'chance-actuelle': case 'chance-actuelle': case 'chance-actuelle': case 'chance-actuelle':
return this.getCaracChanceActuelle(); return this.getCaracChanceActuelle();
} }
return RdDBaseActor._findCaracByName(this.system.carac, name); return this.findCaracByName(name);
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
@ -187,7 +200,7 @@ export class RdDBaseActor extends Actor {
} }
listeSuivants(filter = suivant => true) { return [] } listeSuivants(filter = suivant => true) { return [] }
listeSuivants(filter = suivant =>true) { return [] } listeSuivants(filter = suivant => true) { return [] }
listItems(type = undefined) { return (type ? this.itemTypes[type] : this.items); } listItems(type = undefined) { return (type ? this.itemTypes[type] : this.items); }
filterItems(filter, type = undefined) { return (type ? this.itemTypes[type] : this.items)?.filter(filter) ?? []; } filterItems(filter, type = undefined) { return (type ? this.itemTypes[type] : this.items)?.filter(filter) ?? []; }
findItemLike(idOrName, type) { findItemLike(idOrName, type) {

View File

@ -0,0 +1,84 @@
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)
const dialogData = {
title: `Choisissez la répartition d'expérience`,
content: await renderTemplate("systems/foundryvtt-reve-de-dragon/templates/dialog-choix-xp-carac.hbs", {
actor,
caracDerivee: actor.findCaracByName(xpData.caracName),
xpData,
caracs
}),
}
const dialogOptions = {
classes: ["rdd-dialog-select"],
width: 400,
height: 'fit-content',
'z-index': 99999
}
new DialogChoixXpCarac(dialogData, dialogOptions, actor, xpData, caracs).render(true)
}
constructor(dialogData, dialogOptions, actor, xpData, caracs) {
dialogData = mergeObject(dialogData, {
default: 'appliquer',
buttons: {
'appliquer': { icon:'<i class="fa-solid fa-check"></i>', label: "Ajouter la répartition", callback: it => this.appliquerSelection() }
}
})
super(dialogData, dialogOptions)
this.actor = actor
this.xpData = xpData
this.caracs = caracs
}
activateListeners(html) {
//TODO
super.activateListeners(html)
this.html = html
this.html.find("li.xpCarac-option .xpCarac-moins").click(event =>
this.ajouterXp(event, -1)
)
this.html.find("li.xpCarac-option .xpCarac-plus").click(event =>
this.ajouterXp(event, 1)
)
}
async ajouterXp(event, delta) {
const liCarac = this.html.find(event.currentTarget)?.parents("li.xpCarac-option")
const label = liCarac?.data("carac-label")
const carac = this.caracs.find(c => c.label == label)
if (carac.ajout + delta < 0) {
ui.notifications.warn(`Impossible de diminuer les points à répartir en ${carac.label} en dessous de 0`)
return
}
if (this.xpData.reste - delta < 0) {
ui.notifications.warn(`Il ne reste plus de points à répartir en ${carac.label}`)
return
}
carac.ajout += delta
this.xpData.reste -= delta
liCarac.find("input.xpCarac-view-ajout").val(carac.ajout)
this.html.find("input.xpCarac-reste").val(this.xpData.reste)
}
async appliquerSelection() {
if (this.xpData.reste > 0) {
ui.notifications.warn(`Il vous reste ${this.xpData.reste} points à répartir`)
return
}
this.caracs.filter(c => c.ajout > 0).forEach(c => {
const xpData = { caracName: c.label, xpCarac: c.ajout }
this.actor._xpCarac(xpData)
})
await super.close()
}
async close() { }
_getHeaderButtons() { return [] }
}

View File

@ -328,8 +328,8 @@ export class RdDCombatManager extends Combat {
} }
} }
options = [ options = [
{ name: "Incrémenter initiative", condition: true, icon: '<i class="fas fa-plus"></i>', callback: target => { RdDCombatManager.incDecInit(target.data('combatant-id'), +0.01); } }, { name: "Incrémenter initiative", condition: true, icon: '<i class="fa-solid fa-plus"></i>', callback: target => { RdDCombatManager.incDecInit(target.data('combatant-id'), +0.01); } },
{ name: "Décrémenter initiative", condition: true, icon: '<i class="fas fa-minus"></i>', callback: target => { RdDCombatManager.incDecInit(target.data('combatant-id'), -0.01); } } { name: "Décrémenter initiative", condition: true, icon: '<i class="fa-solid fa-minus"></i>', callback: target => { RdDCombatManager.incDecInit(target.data('combatant-id'), -0.01); } }
].concat(options); ].concat(options);
} }
/* -------------------------------------------- */ /* -------------------------------------------- */

View File

@ -58,7 +58,7 @@ export class PixiTMR {
this.sizes = new TMRConstants({ size: displaySize }) this.sizes = new TMRConstants({ size: displaySize })
const appSize = PixiTMR.computeTMRSize(this.sizes) const appSize = PixiTMR.computeTMRSize(this.sizes)
this.pixiApp.renderer.resize(appSize.width, appSize.height) this.pixiApp.renderer.resize(appSize.width, appSize.height)
this.tooltipStyle.fontSize = Math.max(this.sizes.size / 4, 16) this.tooltipStyle.fontSize = Math.max(this.sizes.size / 3, 16)
} }
get view() { get view() {
@ -199,7 +199,7 @@ export class PixiTMR {
setTooltipPosition(event) { setTooltipPosition(event) {
const oddq = this.sizes.computeEventOddq(event); const oddq = this.sizes.computeEventOddq(event);
this.tooltip.x = oddq.x + (oddq.col > 7 ? -3 * this.sizes.full : this.sizes.quarter); this.tooltip.x = oddq.x + (oddq.col > 7 ? -2.5 * this.sizes.full : this.sizes.quarter);
this.tooltip.y = oddq.y + (oddq.row > 10 ? -this.sizes.size : 0); this.tooltip.y = oddq.y + (oddq.row > 10 ? -this.sizes.size : 0);
} }

View File

@ -1,8 +1,8 @@
{ {
"id": "foundryvtt-reve-de-dragon", "id": "foundryvtt-reve-de-dragon",
"title": "Rêve de Dragon", "title": "Rêve de Dragon",
"version": "11.2.9", "version": "11.2.10",
"download": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/archive/foundryvtt-reve-de-dragon-11.2.9.zip", "download": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/archive/foundryvtt-reve-de-dragon-11.2.10.zip",
"manifest": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/raw/v11/system.json", "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", "changelog": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/raw/branch/v11/changelog.md",
"compatibility": { "compatibility": {

View File

@ -12,19 +12,19 @@
<ul> <ul>
<li data-attribute="resistance" class="flexrow"> <li data-attribute="resistance" class="flexrow">
<span class="carac-label">Résistance</span> <span class="carac-label">Résistance</span>
<a class="resistance-moins"><i class="fas fa-minus-square"></i></a> <a class="resistance-moins"><i class="fa-solid fa-square-minus"></i></a>
<input type="text" name="system.etat.resistance.value" value="{{system.etat.resistance.value}}" data-dtype="Number" /> <input type="text" name="system.etat.resistance.value" value="{{system.etat.resistance.value}}" data-dtype="Number" />
/ /
<input type="text" name="system.etat.resistance.max" value="{{system.etat.resistance.max}}" data-dtype="Number" {{#unless @root.options.vueDetaillee}}disabled{{/unless}} /> <input type="text" name="system.etat.resistance.max" value="{{system.etat.resistance.max}}" data-dtype="Number" {{#unless @root.options.vueDetaillee}}disabled{{/unless}} />
<a class="resistance-plus"><i class="fas fa-plus-square"></i></a> <a class="resistance-plus"><i class="fa-solid fa-square-plus"></i></a>
</li> </li>
<li data-attribute="structure" class="flexrow"> <li data-attribute="structure" class="flexrow">
<span class="carac-label">Structure</span> <span class="carac-label">Structure</span>
<a class="structure-moins"><i class="fas fa-minus-square"></i></a> <a class="structure-moins"><i class="fa-solid fa-square-minus"></i></a>
<input type="text" name="system.etat.structure.value" value="{{system.etat.structure.value}}" data-dtype="Number" /> <input type="text" name="system.etat.structure.value" value="{{system.etat.structure.value}}" data-dtype="Number" />
/ /
<input type="text" name="system.etat.structure.max" value="{{system.etat.structure.max}}" data-dtype="Number" {{#unless @root.options.vueDetaillee}}disabled{{/unless}} /> <input type="text" name="system.etat.structure.max" value="{{system.etat.structure.max}}" data-dtype="Number" {{#unless @root.options.vueDetaillee}}disabled{{/unless}} />
<a class="structure-plus"><i class="fas fa-plus-square"></i></a> <a class="structure-plus"><i class="fa-solid fa-square-plus"></i></a>
</li> </li>
</ul> </ul>
</div> </div>

View File

@ -17,13 +17,13 @@
<span class="equipement-detail-buttons flexrow"> <span class="equipement-detail-buttons flexrow">
{{#unless (or (eq item.type 'service') (and (eq item.type 'conteneur') (not vide)))}} {{#unless (or (eq item.type 'service') (and (eq item.type 'conteneur') (not vide)))}}
{{#if options.isOwner}} {{#if options.isOwner}}
<a class="item-quantite-moins"><i class="fas fa-minus-square"></i></a> <a class="item-quantite-moins"><i class="fa-solid fa-square-minus"></i></a>
{{/if}} {{/if}}
<input {{#unless options.isOwner}}disabled{{/unless}} type="number" data-dtype="Number" <input {{#unless options.isOwner}}disabled{{/unless}} type="number" data-dtype="Number"
class="item-quantite number-x3" name="items[{{item._id}}].system.quantite" class="item-quantite number-x3" name="items[{{item._id}}].system.quantite"
value="{{item.system.quantite}}" /> value="{{item.system.quantite}}" />
{{#if options.isOwner}} {{#if options.isOwner}}
<a class="item-quantite-plus"><i class="fas fa-plus-square"></i></a> <a class="item-quantite-plus"><i class="fa-solid fa-square-plus"></i></a>
{{/if}} {{/if}}
{{/unless}} {{/unless}}
</span> </span>

View File

@ -3,23 +3,23 @@
<li data-attribute="vie"> <li data-attribute="vie">
<label class="compteur"> <label class="compteur">
<a class="jet-vie" name="system.sante.vie.label" data-tooltip="Faire un jet de vie">Vie</a> <a class="jet-vie" name="system.sante.vie.label" data-tooltip="Faire un jet de vie">Vie</a>
<a class="vie-moins"><i class="fas fa-minus-square"></i></a> <a class="vie-moins"><i class="fa-solid fa-square-minus"></i></a>
<input class="resource-content" type="text" name="system.sante.vie.value" value="{{system.sante.vie.value}}" data-dtype="Number" /> <input class="resource-content" type="text" name="system.sante.vie.value" value="{{system.sante.vie.value}}" data-dtype="Number" />
/ {{#if @root.options.vueDetaillee}} / {{#if @root.options.vueDetaillee}}
<input class="resource-content" type="text" name="system.sante.vie.max" value="{{system.sante.vie.max}}" data-dtype="Number"/> <input class="resource-content" type="text" name="system.sante.vie.max" value="{{system.sante.vie.max}}" data-dtype="Number"/>
{{else}}{{system.sante.vie.max}}{{/if}} {{else}}{{system.sante.vie.max}}{{/if}}
<a class="vie-plus"><i class="fas fa-plus-square"></i></a> <a class="vie-plus"><i class="fa-solid fa-square-plus"></i></a>
</label> </label>
</li> </li>
<li data-attribute="endurance"> <li data-attribute="endurance">
<label class="compteur"> <label class="compteur">
<a class="jet-endurance" name="system.sante.endurance.label" data-tooltip="Faire un jet d'endurance pour ne pas être sonné">Endurance</a> <a class="jet-endurance" name="system.sante.endurance.label" data-tooltip="Faire un jet d'endurance pour ne pas être sonné">Endurance</a>
<a class="endurance-moins"><i class="fas fa-minus-square"></i></a> <a class="endurance-moins"><i class="fa-solid fa-square-minus"></i></a>
<input class="resource-content" type="text" name="system.sante.endurance.value" value="{{system.sante.endurance.value}}" data-dtype="Number"/> <input class="resource-content" type="text" name="system.sante.endurance.value" value="{{system.sante.endurance.value}}" data-dtype="Number"/>
/ {{#if @root.options.vueDetaillee}} / {{#if @root.options.vueDetaillee}}
<input class="resource-content" type="text" name="system.sante.endurance.max" value="{{system.sante.endurance.max}}" data-dtype="Number"/> <input class="resource-content" type="text" name="system.sante.endurance.max" value="{{system.sante.endurance.max}}" data-dtype="Number"/>
{{else}}{{system.sante.endurance.max}}{{/if}} {{else}}{{system.sante.endurance.max}}{{/if}}
<a class="endurance-plus"><i class="fas fa-plus-square"></i></a> <a class="endurance-plus"><i class="fa-solid fa-square-plus"></i></a>
</label> </label>
</li> </li>
</ul> </ul>

View File

@ -4,12 +4,12 @@
<li data-attribute="endurance"> <li data-attribute="endurance">
<label class="compteur"> <label class="compteur">
Endurance Endurance
<a class="endurance-moins"><i class="fas fa-minus-square"></i></a> <a class="endurance-moins"><i class="fa-solid fa-square-minus"></i></a>
<input class="resource-content" type="text" name="system.sante.endurance.value" value="{{system.sante.endurance.value}}" data-dtype="Number" /> <input class="resource-content" type="text" name="system.sante.endurance.value" value="{{system.sante.endurance.value}}" data-dtype="Number" />
/ {{#if @root.options.vueDetaillee}} / {{#if @root.options.vueDetaillee}}
<input class="resource-content" type="text" name="system.sante.endurance.max" value="{{system.sante.endurance.max}}" data-dtype="Number"/> <input class="resource-content" type="text" name="system.sante.endurance.max" value="{{system.sante.endurance.max}}" data-dtype="Number"/>
{{else}}{{system.sante.endurance.max}}{{/if}} {{else}}{{system.sante.endurance.max}}{{/if}}
<a class="endurance-plus"><i class="fas fa-plus-square"></i></a> <a class="endurance-plus"><i class="fa-solid fa-square-plus"></i></a>
</label> </label>
</li> </li>
</ul> </ul>

View File

@ -3,38 +3,38 @@
<li> <li>
<label class="compteur"> <label class="compteur">
<a class="jet-vie" data-tooltip="Faire un jet de vie">Vie</a> <a class="jet-vie" data-tooltip="Faire un jet de vie">Vie</a>
<a class="vie-moins"><i class="fas fa-minus-square"></i></a> <a class="vie-moins"><i class="fa-solid fa-square-minus"></i></a>
<input class="resource-content" type="text" name="system.sante.vie.value" value="{{system.sante.vie.value}}" data-dtype="Number"/> <input class="resource-content" type="text" name="system.sante.vie.value" value="{{system.sante.vie.value}}" data-dtype="Number"/>
<span>/ {{system.sante.vie.max}}</span> <span>/ {{system.sante.vie.max}}</span>
<a class="vie-plus"><i class="fas fa-plus-square"></i></a> <a class="vie-plus"><i class="fa-solid fa-square-plus"></i></a>
</label> </label>
</li> </li>
<li> <li>
<label class="compteur"> <label class="compteur">
<a class="jet-endurance" data-tooltip="Faire un jet d'endurance pour ne pas être sonné">Endurance</a> <a class="jet-endurance" data-tooltip="Faire un jet d'endurance pour ne pas être sonné">Endurance</a>
<a class="endurance-moins"><i class="fas fa-minus-square"></i></a> <a class="endurance-moins"><i class="fa-solid fa-square-minus"></i></a>
<input class="resource-content" type="text" name="system.sante.endurance.value" value="{{system.sante.endurance.value}}" data-dtype="Number"/> <input class="resource-content" type="text" name="system.sante.endurance.value" value="{{system.sante.endurance.value}}" data-dtype="Number"/>
<span>/ {{system.sante.endurance.max}}</span> <span>/ {{system.sante.endurance.max}}</span>
<a class="endurance-plus"><i class="fas fa-plus-square"></i></a> <a class="endurance-plus"><i class="fa-solid fa-square-plus"></i></a>
</label> </label>
</li> </li>
<li> <li>
<label class="appliquerFatigue compteur tooltip"> <label class="appliquerFatigue compteur tooltip">
<span class="tooltiptext ttt-fatigue">{{{calc.fatigue.html}}}</span> <span class="tooltiptext ttt-fatigue">{{{calc.fatigue.html}}}</span>
Fatigue ({{calc.fatigue.malus}}) Fatigue ({{calc.fatigue.malus}})
<a class="fatigue-moins"><i class="fas fa-minus-square"></i></a> <a class="fatigue-moins"><i class="fa-solid fa-square-minus"></i></a>
<input class="resource-content" type="text" name="system.sante.fatigue.value" value="{{system.sante.fatigue.value}}" data-dtype="Number" /> <input class="resource-content" type="text" name="system.sante.fatigue.value" value="{{system.sante.fatigue.value}}" data-dtype="Number" />
<span>/ {{system.sante.fatigue.max}}</span> <span>/ {{system.sante.fatigue.max}}</span>
<a class="fatigue-plus"><i class="fas fa-plus-square"></i></a> <a class="fatigue-plus"><i class="fa-solid fa-square-plus"></i></a>
</label> </label>
</li> </li>
<li> <li>
<label class="compteur"> <label class="compteur">
<span class="ptreve-actuel" data-tooltip="Faire un jet de Rêve actuel (ou jet de résistance)"><a>Rêve</a></span> <span class="ptreve-actuel" data-tooltip="Faire un jet de Rêve actuel (ou jet de résistance)"><a>Rêve</a></span>
<a class="ptreve-actuel-moins"><i class="fas fa-minus-square"></i></a> <a class="ptreve-actuel-moins"><i class="fa-solid fa-square-minus"></i></a>
<input class="resource-content" class="pointsreve-value" type="text" name="system.reve.reve.value" value="{{system.reve.reve.value}}" data-dtype="Number" /> <input class="resource-content" class="pointsreve-value" type="text" name="system.reve.reve.value" value="{{system.reve.reve.value}}" data-dtype="Number" />
<span>/ {{system.reve.seuil.value}}</span> <span>/ {{system.reve.seuil.value}}</span>
<a class="ptreve-actuel-plus"><i class="fas fa-plus-square"></i></a> <a class="ptreve-actuel-plus"><i class="fa-solid fa-square-plus"></i></a>
</label> </label>
</li> </li>
</ul> </ul>

View File

@ -22,7 +22,7 @@
</span> </span>
<span class="equipement-detail"> <span class="equipement-detail">
{{#if (gt item.system.quantite 1)}} {{#if (gt item.system.quantite 1)}}
<a class="item-quantite-moins" data-tooltip="Diminuer la quantité de {{item.name}}"><i class="fas fa-minus-square"></i></a> <a class="item-quantite-moins" data-tooltip="Diminuer la quantité de {{item.name}}"><i class="fa-solid fa-square-minus"></i></a>
{{/if}} {{/if}}
{{item.system.quantite}} {{item.system.quantite}}
{{#if (gt item.system.quantite 1)}} {{#if (gt item.system.quantite 1)}}

View File

@ -10,7 +10,7 @@
</span> </span>
{{#if @root.options.isOwner}} {{#if @root.options.isOwner}}
<span class="equipement-button item-controls"> <span class="equipement-button item-controls">
<a class="item-quantite-moins"><i class="fas fa-minus-square"></i></a> <a class="item-quantite-moins"><i class="fa-solid fa-square-minus"></i></a>
</span> </span>
{{/if}} {{/if}}
<span class="equipement-detail"> <span class="equipement-detail">
@ -18,7 +18,7 @@
</span> </span>
{{#if @root.options.isOwner}} {{#if @root.options.isOwner}}
<span class="equipement-button item-controls"> <span class="equipement-button item-controls">
<a class="item-quantite-plus"><i class="fas fa-plus-square"></i></a> <a class="item-quantite-plus"><i class="fa-solid fa-square-plus"></i></a>
</span> </span>
{{/if}} {{/if}}
<span class="equipement-actions item-controls"> <span class="equipement-actions item-controls">

View File

@ -1,26 +1,29 @@
<h4>{{alias}} a gagné de l'expérience en {{caracName}}{{#if competence}} / {{competence.name}}{{/if}}!</h4> <img class="chat-icon" src="{{actor.img}}" data-tooltip="{{actor.name}}" />
{{#if (gt xpCarac 0)}} <h4>{{actor.name}} a gagné de l'expérience</h4>
<hr> {{#each xpData as |it|}}
{{xpCarac}} point{{#if (gt xpCarac 1)}}s{{/if}} {{#if (gt it.xpCarac 0)}}
{{#if caracRepartitionManuelle}}à répartir manuellement dans la caractéristique dérivée{{else}}en{{/if}} <hr>
{{caracName}}. {{it.xpCarac}} point{{#if (gt it.xpCarac 1)}}s{{/if}}
{{#if checkCarac}} {{#if it.caracRepartitionManuelle}}à répartir manuellement dans la caractéristique dérivée{{else}}en{{/if}}
L'expérience dans cette caractéristique est de {{checkCarac.xp}}, elle peut progresser! {{it.caracName}}.
<br>Vous devez ouvrir votre fiche de personnage et appliquer (ou pas) l'augmentation manuellement. {{#if it.checkCarac}}
L'expérience dans cette caractéristique est de {{it.checkCarac.xp}}, elle peut progresser!
<br>Vous devez ouvrir votre fiche de personnage et appliquer l'augmentation manuellement.
{{/if}}
{{/if}} {{/if}}
{{/if}} {{#if (gt it.xpCompetence 0)}}
<hr>
{{#if (gt xpCompetence 0)}} {{it.xpCompetence}} point{{#if (gt it.xpCompetence 1)}}s{{/if}} en {{it.competence.name}}.
<hr> {{#if it.checkComp}}
{{xpCompetence}} point{{#if (gt xpCompetence 1)}}s{{/if}} en {{competence.name}}. L'expérience dans cette compétence est de {{it.checkComp.xp}}, elle peut progresser jusqu'à {{it.checkComp.niveau}}!
{{#if checkComp}} Vous devez ouvrir votre fiche de personnage et appliquer l'augmentation manuellement.
L'expérience dans cette compétence est de {{checkComp.xp}}, elle peut progresser jusqu'à {{checkComp.niveau}}! {{#if (gt it.checkComp.niveau it.checkComp.archetype)}}
Vous devez ouvrir votre fiche de personnage et appliquer l'augmentation manuellement. <br>Le niveau d'archétype est de {{it.checkComp.archetype}}.
{{#if (gt checkComp.niveau checkComp.archetype)}}<br>Le niveau d'archétype est de {{checkComp.archetype}}. {{#if it.checkComp.archetypeWarning}}
{{#if checkComp.archetypeWarning}} <br><strong>ATTENTION !!</strong> Si vous appliquez cette augmentation, votre compétence dépassera l'archétype.
<br><strong>ATTENTION !!</strong> Si vous appliquez cette augmentation, votre compétence dépassera l'archétype. Veuillez contrôler que votre archétype est à jour, ou bien ne pas augmenter le niveau de cette compétence.
Veuillez contrôler que votre archétype est à jour, ou bien ne pas augmenter le niveau de cette compétence. {{/if}}
{{/if}} {{/if}}
{{/if}} {{/if}}
{{/if}} {{/if}}
{{/if}} {{/each}}

View File

@ -0,0 +1,43 @@
<form class="rdd-dialog-select">
<div>
<img class="chat-icon" src="{{actor.img}}" data-tooltip="{{actor.name}}" />
<label>Répartir l'expérience en {{caracDerivee.label}}</label>
</div>
<hr>
<span>
<label>Points à répartir:</label>
<input class="xpCarac-reste number-x2"
type="number" data-dtype="Number"
min="0" max="10" value="{{xpData.reste}}" disabled />
<label> sur {{xpData.xpCarac}}</label>
</span>
<ul class="flexcol item-list alterne-list">
<li class="competence-header flexrow">
<label class="flex-grow-2">Caractéristique</label>
<label>valeur</label>
<label>xp</label>
<span>ajout</span>
</li>
{{log 'choix-xp' @root}}
{{#each caracs as |carac key|}}
<li class="xpCarac-option item list-item flexrow" data-carac-label="{{carac.label}}">
<label class="flex-grow-2">{{carac.label}}</label>
<label>{{carac.value}}</label>
{{#if carac.isMax}}
<label>max</label>
<span class="flexrow">
</span>
{{else}}
<label>{{carac.xp}}</label>
<span class="flexrow">
<a class="xpCarac-moins"><i class="fa-solid fa-square-minus"></i></a>
<input class="xpCarac-view-ajout" value="{{carac.ajout}}" type="number" max="99" disabled/>
<a class="xpCarac-plus"><i class="fa-solid fa-square-plus"></i></a>
</span>
{{/if}}
</li>
{{/each}}
</ul>
</form>

View File

@ -40,8 +40,8 @@
</div> </div>
<div class="form-group"> <div class="form-group">
<label class="flex-shrink" for="information">Information <label class="flex-shrink" for="information">Information
<a class="chronologie-preset-show"><i class="fas fa-plus-square"></i></a> <a class="chronologie-preset-show"><i class="fa-solid fa-square-plus"></i></a>
<a class="chronologie-preset-hide"><i class="fas fa-minus-square"></i></a> <a class="chronologie-preset-hide"><i class="fa-solid fa-square-minus"></i></a>
</label> </label>
<textarea autocomplete="off" data-tooltip="Information" name="information" autofocus>{{information}}</textarea> <textarea autocomplete="off" data-tooltip="Information" name="information" autofocus>{{information}}</textarea>
</div> </div>