diff --git a/changelog.md b/changelog.md index 250213e5..b584171c 100644 --- a/changelog.md +++ b/changelog.md @@ -1,4 +1,10 @@ # 12.0 +## 12.0.26 - Astrobazzarh le Haut-rêvant +- bouton pour le don de haut-rêve en un clic +- les compétences de draconic ne sont plus précédées de "Voie de" + - migration des compétences & compendiums +- Correction feuille simplifiée qui ne s'affichait pas en ccas de sort variable + ## 12.0.24 - Les ajustements d'Astrobazzarh - amélioration - meilleure gestion des noms des voies de draconic diff --git a/module/actor-sheet.js b/module/actor-sheet.js index b41baf20..19254bb0 100644 --- a/module/actor-sheet.js +++ b/module/actor-sheet.js @@ -214,6 +214,8 @@ export class RdDActorSheet extends RdDBaseActorSangSheet { }); // Boutons spéciaux MJs this.html.find('.forcer-tmr-aleatoire').click(async event => this.actor.reinsertionAleatoire("Action MJ")) + this.html.find('.don-de-haut-reve').click(async event => this.actor.addDonDeHautReve()) + this.html.find('.afficher-tmr').click(async event => this.actor.changeTMRVisible()) } diff --git a/module/actor.js b/module/actor.js index badb3492..a128e4b8 100644 --- a/module/actor.js +++ b/module/actor.js @@ -38,6 +38,8 @@ import { RdDCoeur } from "./coeur/rdd-coeur.js"; import { DialogChoixXpCarac } from "./dialog-choix-xp-carac.js"; import { RdDItemArme } from "./item-arme.js"; import { RdDCombatManager } from "./rdd-combat.js"; +import { RdDItemTete } from "./item/tete.js"; +import { SystemCompendiums } from "./settings/system-compendiums.js"; export const MAINS_DIRECTRICES = ['Droitier', 'Gaucher', 'Ambidextre'] @@ -53,41 +55,27 @@ export class RdDActor extends RdDBaseActorSang { * Prepare Character type specific data */ prepareActorData() { - this.$computeCaracDerivee() - this.$computeIsHautRevant() - } - - /* -------------------------------------------- */ - $computeCaracDerivee() { this.system.carac.force.value = Math.min(this.system.carac.force.value, parseInt(this.system.carac.taille.value) + 4); - 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((this.getForce() + 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.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; + super.prepareActorData() - 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.attributs.sconst.value = RdDCarac.calculSConst(this.getConstitution()) + this.system.attributs.sust.value = RdDCarac.getCaracDerivee(this.getTaille()).sust - this.system.sante.vie.value = Math.min(this.system.sante.vie.value, this.system.sante.vie.max) - this.system.sante.endurance.max = Math.max(parseInt(this.system.carac.taille.value) + parseInt(this.system.carac.constitution.value), parseInt(this.system.sante.vie.max) + parseInt(this.system.carac.volonte.value)); - this.system.sante.endurance.value = Math.min(this.system.sante.endurance.value, this.system.sante.endurance.max); - this.system.sante.fatigue.max = this.getFatigueMax(); + this.system.sante.fatigue.max = this.getFatigueMax() this.system.sante.fatigue.value = Math.min(this.system.sante.fatigue.value, this.system.sante.fatigue.max); //Compteurs - this.system.reve.reve.max = this.system.carac.reve.value; - this.system.compteurs.chance.max = this.system.carac.chance.value; - } + this.system.reve.reve.max = 3 * this.getReve() + this.system.compteurs.chance.max = this.getChance() - $computeIsHautRevant() { - this.system.attributs.hautrevant.value = this.itemTypes['tete'].find(it => Grammar.equalsInsensitive(it.name, 'don de haut-reve')) + this.system.attributs.hautrevant.value = this.itemTypes[ITEM_TYPES.tete].find(it => RdDItemTete.isDonDeHautReve(it)) ? "Haut rêvant" : ""; } @@ -112,6 +100,8 @@ export class RdDActor extends RdDBaseActorSang { getChanceActuel() { return this.system.compteurs.chance?.value ?? 10 } getMoralTotal() { return this.system.compteurs.moral?.value ?? 0 } + getEnduranceMax() { return Math.max(1, Math.max(this.getTaille() + this.getConstitution(), this.getVieMax() + this.getVolonte())) } + /* -------------------------------------------- */ getEtatGeneral(options = { ethylisme: false }) { const etatGeneral = this.system.compteurs.etat?.value ?? 0 @@ -989,6 +979,16 @@ export class RdDActor extends RdDBaseActorSang { }); } + /* -------------------------------------------- */ + async addDonDeHautReve() { + if (!game.user.isGM || this.isHautRevant()) { + return + } + const donHR = await RdDItemTete.teteDonDeHautReve() + if (donHR) { + this.createEmbeddedDocuments('Item', [donHR.toObject()]) + } + } /* -------------------------------------------- */ async reinsertionAleatoire(raison, accessible = tmr => true) { @@ -1083,9 +1083,7 @@ export class RdDActor extends RdDBaseActorSang { } /* -------------------------------------------- */ - getSConst() { - return RdDCarac.calculSConst(this.system.carac.constitution.value) - } + getSConst() { return RdDCarac.calculSConst(this.getConstitution()) } async ajoutXpConstitution(xp) { await this.update({ "system.carac.constitution.xp": Misc.toInt(this.system.carac.constitution.xp) + xp }); @@ -1237,16 +1235,14 @@ export class RdDActor extends RdDBaseActorSang { } /* -------------------------------------------- */ - async consommerNourritureboisson(itemId, choix = { doses: 1, seForcer: false, supprimerSiZero: false }, userId = undefined) { - if (userId != undefined && userId != game.user.id) { + async consommerNourritureboisson(itemId, choix = { doses: 1, seForcer: false, supprimerSiZero: false }) { + if (!this.isOwner) { RdDBaseActor.remoteActorCall({ tokenId: this.token?.id, actorId: this.id, - method: 'consommerNourritureboisson', - args: [itemId, choix, userId] - }, - userId) - return; + method: 'consommerNourritureboisson', args: [itemId, choix] + }) + return } const item = this.getItem(itemId) if (!item.getUtilisationCuisine()) { @@ -2521,7 +2517,11 @@ export class RdDActor extends RdDBaseActorSang { async onRollTachePremiersSoins(blessureId, rollData) { if (!this.isOwner) { - return RdDBaseActor.remoteActorCall({ tokenId: this.token?.id, actorId: this.id, method: 'onRollTachePremiersSoins', args: [blessureId, rollData] }); + return RdDBaseActor.remoteActorCall({ + tokenId: this.token?.id, + actorId: this.id, + method: 'onRollTachePremiersSoins', args: [blessureId, rollData] + }) } const blessure = this.getItem(blessureId, 'blessure') console.log('TODO update blessure', this, blessureId, rollData, rollData.tache); @@ -2551,7 +2551,11 @@ export class RdDActor extends RdDBaseActorSang { async onRollSoinsComplets(blessureId, rollData) { if (!this.isOwner) { - return RdDBaseActor.remoteActorCall({ tokenId: this.token?.id, actorId: this.id, method: 'onRollSoinsComplets', args: [blessureId, rollData] }); + return RdDBaseActor.remoteActorCall({ + tokenId: this.token?.id, + actorId: this.id, + method: 'onRollSoinsComplets', args: [blessureId, rollData] + }) } const blessure = this.getItem(blessureId, 'blessure') if (blessure && blessure.system.premierssoins.done && !blessure.system.soinscomplets.done) { diff --git a/module/actor/base-actor-reve.js b/module/actor/base-actor-reve.js index fbbf03ca..1d2f1495 100644 --- a/module/actor/base-actor-reve.js +++ b/module/actor/base-actor-reve.js @@ -19,6 +19,7 @@ import { RdDCombat, RdDCombatManager } from "../rdd-combat.js"; import { RdDConfirm } from "../rdd-confirm.js"; import { ENTITE_INCARNE, SHOW_DICE, SYSTEM_RDD } from "../constants.js"; import { RdDItemArme } from "../item-arme.js"; +import { RdDCarac } from "../rdd-carac.js"; const POSSESSION_SANS_DRACONIC = { img: 'systems/foundryvtt-reve-de-dragon/icons/entites/possession.webp', @@ -36,6 +37,13 @@ const POSSESSION_SANS_DRACONIC = { */ export class RdDBaseActorReve extends RdDBaseActor { + prepareActorData() { + super.prepareActorData() + this.system.attributs.plusdom.value = this.getBonusDegat() + this.system.sante.endurance.max = this.getEnduranceMax() + this.system.sante.endurance.value = Math.min(this.system.sante.endurance.value, this.system.sante.endurance.max) + } + getCaracChanceActuelle() { return { label: 'Chance actuelle', @@ -52,21 +60,26 @@ export class RdDBaseActorReve extends RdDBaseActor { }; } + + getTaille() { return Misc.toInt(this.system.carac.taille?.value) } + getConstitution() { return this.getReve() } + getForce() { return this.getReve() } + getAgilite() { return this.getForce() } + getReve() { return Misc.toInt(this.system.carac.reve?.value) } + getChance() { return this.getReve() } + getReveActuel() { return this.getReve() } getChanceActuel() { return this.getChance() } - getReve() { return Number(this.system.carac.reve?.value ?? 0) } - getForce() { return this.getReve() } - getTaille() { return Number(this.system.carac.taille?.value ?? 0) } - getAgilite() { return this.getForce() } - getChance() { return this.getReve() } + getEnduranceMax() { return Math.max(1, this.getTaille() + this.getConstitution()) } + getEncombrementMax() { return (this.getForce() + this.getTaille()) / 2 } + getBonusDegat() { return RdDCarac.getCaracDerivee(this.getEncombrementMax()).plusdom } + getMoralTotal() { return 0 } - getBonusDegat() { return Number(this.system.attributs?.plusdom?.value ?? 0) } getProtectionNaturelle() { return Number(this.system.attributs?.protection?.value ?? 0) } getSConst() { return 0 } /* -------------------------------------------- */ - getEncombrementMax() { return 0 } isSurenc() { return false } computeMalusSurEncombrement() { return 0 } @@ -84,7 +97,7 @@ export class RdDBaseActorReve extends RdDBaseActor { isActorCombat() { return true } getCaracInit(competence) { - if (!competence){ + if (!competence) { return 0 } if (competence.type == ITEM_TYPES.competencecreature) { @@ -445,8 +458,7 @@ export class RdDBaseActorReve extends RdDBaseActor { RdDBaseActor.remoteActorCall({ tokenId: this.token?.id, actorId: this.id, - method: 'encaisserDommagesValidationGR', - args: [rollData, armure, show, attackerToken, defenderToken] + method: 'encaisserDommagesValidationGR', args: [rollData, armure, show, attackerToken, defenderToken] }) } else { DialogValidationEncaissement.validerEncaissement(this, rollData, armure, diff --git a/module/actor/base-actor-sang.js b/module/actor/base-actor-sang.js index 45d84458..689273d9 100644 --- a/module/actor/base-actor-sang.js +++ b/module/actor/base-actor-sang.js @@ -6,6 +6,7 @@ import { RdDBaseActorReve } from "./base-actor-reve.js"; import { RdDDice } from "../rdd-dice.js"; import { RdDItemBlessure } from "../item/blessure.js"; import { ChatUtility } from "../chat-utility.js"; +import { Misc } from "../misc.js"; /** * Classe de base pour les acteurs qui peuvent subir des blessures @@ -14,25 +15,32 @@ import { ChatUtility } from "../chat-utility.js"; */ export class RdDBaseActorSang extends RdDBaseActorReve { + prepareActorData() { + this.system.sante.vie.max = Math.ceil((this.getTaille() + this.getConstitution()) / 2) + this.system.sante.vie.value = Math.min(this.system.sante.vie.value, this.system.sante.vie.max) + super.prepareActorData() + this.system.attributs.encombrement.value = this.getEncombrementMax() + } - getForce() { return Number(this.system.carac.force?.value ?? 0) } + getForce() { return Misc.toInt(this.system.carac.force?.value) } + getConstitution() { return Misc.toInt(this.system.carac.constitution?.value) } + getVolonte() { return Misc.toInt(this.system.carac.volonte?.value) } - getBonusDegat() { return Number(this.system.attributs?.plusdom?.value ?? 0) } - getProtectionNaturelle() { return Number(this.system.attributs?.protection?.value ?? 0) } - getSConst() { return 0 } + getVieMax() { return Misc.toInt(this.system.sante.vie?.max) } + getEnduranceMax() { return Math.max(1, this.getTaille() + this.getConstitution()) } + getFatigueMax() { return this.getEnduranceMax() * 2 } - getEnduranceMax() { return Math.max(1, Math.min(this.system.sante.endurance.max, MAX_ENDURANCE_FATIGUE)) } + getProtectionNaturelle() { return Misc.toInt(this.system.attributs?.protection?.value) } getFatigueActuelle() { if (ReglesOptionnelles.isUsing("appliquer-fatigue")) { - return Math.max(0, Math.min(this.getFatigueMax(), this.system.sante.fatigue?.value ?? 0)); + return Math.max(0, Math.min(this.getFatigueMax(), Misc.toInt(this.system.sante.fatigue?.value))) } return 0; } getFatigueRestante() { return this.getFatigueMax() - this.getFatigueActuelle() } getFatigueMin() { return this.system.sante.endurance.max - this.system.sante.endurance.value } - getFatigueMax() { return this.getEnduranceMax() * 2 } malusFatigue() { if (ReglesOptionnelles.isUsing("appliquer-fatigue")) { @@ -42,7 +50,6 @@ export class RdDBaseActorSang extends RdDBaseActorReve { } /* -------------------------------------------- */ - getEncombrementMax() { return Number(this.system.attributs?.encombrement?.value ?? 0) } isSurenc() { return this.computeMalusSurEncombrement() < 0 } computeMalusSurEncombrement() { diff --git a/module/actor/base-actor.js b/module/actor/base-actor.js index a1456895..0342c03c 100644 --- a/module/actor/base-actor.js +++ b/module/actor/base-actor.js @@ -18,6 +18,7 @@ export class RdDBaseActor extends Actor { .map(it => it[0]) .find(it => it) } + static $findCaracByName(carac, name) { const caracList = Object.entries(carac); let entry = Misc.findFirstLike(name, caracList, { mapper: it => it[0], description: 'caractéristique' }); @@ -26,6 +27,16 @@ export class RdDBaseActor extends Actor { } return entry && entry.length > 0 ? carac[entry[0]] : undefined; } + static getDefaultValue(actorType, path) { + if (path.includes('.')) { + path = path.split('.') + } + let obj = game.model.Actor[actorType] + for (let p of path) { + obj = obj ? obj[p] : undefined + } + return obj + } static getDefaultImg(itemType) { return game.system.rdd.actorClasses[itemType]?.defaultIcon ?? defaultItemImg[itemType]; @@ -45,29 +56,32 @@ export class RdDBaseActor extends Actor { } } - static remoteActorCall(callData, userId = undefined) { - userId = userId ?? Misc.firstConnectedGMId(); - if (userId == game.user.id) { - RdDBaseActor.onRemoteActorCall(callData, userId); - return false; + static remoteActorCall(callData) { + if (game.user.isGM) { + RdDBaseActor.onRemoteActorCall(callData, game.user.id) + return false } else { - game.socket.emit(SYSTEM_SOCKET_ID, { msg: "msg_remote_actor_call", data: callData, userId: userId }); - return true; + game.socket.emit(SYSTEM_SOCKET_ID, { + msg: "msg_remote_actor_call", + data: callData, + userId: Misc.firstConnectedGMId() + }) + return true } } static onRemoteActorCall(callData, userId) { + const actor = RdDBaseActor.getRealActor(callData?.actorId, callData?.tokenId); if (userId == game.user.id) { - const actor = RdDBaseActor.getRealActor(callData?.actorId, callData?.tokenId); - if (Misc.isOwnerPlayerOrUniqueConnectedGM(actor)) { // Seul le joueur choisi effectue l'appel: le joueur courant si propriétaire de l'actor, ou le MJ sinon - const args = callData.args; - console.info(`RdDBaseActor.onRemoteActorCall: pour l'Actor ${callData.actorId}, appel de RdDBaseActor.${callData.method}(`, ...args, ')'); - actor[callData.method](...args); - } + // Seul le joueur choisi effectue l'appel: le joueur courant si propriétaire de l'actor, ou le MJ sinon + const args = callData.args; + console.info(`RdDBaseActor.onRemoteActorCall: pour l'Actor ${callData.actorId}, appel de RdDBaseActor.${callData.method}(`, ...args, ')'); + actor[callData.method](...args); } } + static getRealActor(actorId, tokenId) { if (tokenId) { let token = canvas.tokens.get(tokenId) @@ -178,7 +192,8 @@ export class RdDBaseActor extends Actor { this.computeEncTotal() } - async prepareActorData() { } + prepareActorData() { } + async computeEtatGeneral() { } /* -------------------------------------------- */ findPlayer() { @@ -210,6 +225,9 @@ export class RdDBaseActor extends Actor { getMonnaie(id) { return this.findItemLike(id, 'monnaie'); } getEncombrementMax() { return 0 } + /* -------------------------------------------- */ + async updateCarac(caracName, to) { + } /* -------------------------------------------- */ async onPreUpdateItem(item, change, options, id) { } async onCreateItem(item, options, id) { } @@ -234,21 +252,20 @@ export class RdDBaseActor extends Actor { } async creerObjetParMJ(object) { - if (!Misc.isFirstConnectedGM()) { - RdDBaseActor.remoteActorCall({ - tokenId: this.token?.id, - actorId: this.id, - method: 'creerObjetParMJ', - args: [object] - }); - return; + if (this.isOwner) { + await this.createEmbeddedDocuments('Item', [object]) + return } - await this.createEmbeddedDocuments('Item', [object]) + RdDBaseActor.remoteActorCall({ + tokenId: this.token?.id, + actorId: this.id, + method: 'creerObjetParMJ', args: [object] + }) } /* -------------------------------------------- */ async cleanupConteneurs() { - if (Misc.isOwnerPlayerOrUniqueConnectedGM(this)) { + if (Misc.isOwnerPlayer(this)) { let updates = this.itemTypes['conteneur'] .filter(c => c.system.contenu.filter(id => this.getItem(id) == undefined).length > 0) .map(c => { return { _id: c._id, 'system.contenu': c.system.contenu.filter(id => this.getItem(id) != undefined) } }); @@ -319,7 +336,7 @@ export class RdDBaseActor extends Actor { ui.notifications.error(`Impossible d'ajouter un gain de ${sols} <0`); return; } - if (fromActorId && !game.user.isGM) { + if (fromActorId && !this.isOwner) { RdDBaseActor.remoteActorCall({ userId: Misc.connectedGMOrUser(), tokenId: this.token?.id, @@ -354,10 +371,9 @@ export class RdDBaseActor extends Actor { if (!Misc.isFirstConnectedGM()) { RdDBaseActor.remoteActorCall({ actorId: achat.vendeurId ?? achat.acheteurId, - method: 'achatVente', - args: [achat] + method: 'achatVente', args: [achat] }); - return; + return } const cout = Number(achat.prixTotal ?? 0); const vendeur = achat.vendeurId ? game.actors.get(achat.vendeurId) : undefined; diff --git a/module/actor/commerce.js b/module/actor/commerce.js index ed075a6b..0b7f9a99 100644 --- a/module/actor/commerce.js +++ b/module/actor/commerce.js @@ -25,9 +25,6 @@ export class RdDCommerce extends RdDBaseActor { } await super.depenserSols(cout) } - async consommerNourritureboisson(itemId, choix, userId) { - // ne pas consommer pour un commerce - } async decrementerQuantiteItem(item, quantite) { if (this.system.illimite) { diff --git a/module/actor/creature.js b/module/actor/creature.js index d0307e66..c2f51b27 100644 --- a/module/actor/creature.js +++ b/module/actor/creature.js @@ -1,6 +1,4 @@ -import { ENTITE_INCARNE } from "../constants.js"; import { ITEM_TYPES } from "../item.js"; -import { STATUSES } from "../settings/status-effects.js"; import { RdDBaseActorSang } from "./base-actor-sang.js"; export class RdDCreature extends RdDBaseActorSang { @@ -9,6 +7,7 @@ export class RdDCreature extends RdDBaseActorSang { return "systems/foundryvtt-reve-de-dragon/icons/creatures/bramart.svg"; } + getEnduranceMax() { return Math.max(1, this.getVieMax() + this.getConstitution()) } isCreature() { return true } canReceive(item) { diff --git a/module/actor/entite.js b/module/actor/entite.js index ff0ad06a..d72935c9 100644 --- a/module/actor/entite.js +++ b/module/actor/entite.js @@ -27,6 +27,7 @@ export class RdDEntite extends RdDBaseActorReve { getForce() { return this.getReve() } getAgilite() { return this.getReve() } getChance() { return this.getReve() } + getEnduranceMax() { return Math.max(1, this.getTaille() + this.getReve()) } getDraconicOuPossession() { return this.itemTypes[ITEM_TYPES.competencecreature] diff --git a/module/actor/export-scriptarium/mapping.js b/module/actor/export-scriptarium/mapping.js index e36db5ff..88912f49 100644 --- a/module/actor/export-scriptarium/mapping.js +++ b/module/actor/export-scriptarium/mapping.js @@ -76,7 +76,7 @@ const MAPPING_BASE = [ { column: "derobee", rollClass: 'roll-carac', colName: 'Dérobée', getter: (actor, context) => actor.system.carac.derobee.value }, { column: "vie", getter: (actor, context) => actor.system.sante.vie.max }, { column: "endurance", getter: (actor, context) => actor.system.sante.endurance.max }, - { column: "plusdom", colName: '+dom', getter: (actor, context) => actor.system.attributs.plusdom.value }, + { column: "plusdom", colName: '+dom', getter: (actor, context) => actor.getBonusDegat() }, { column: "protectionnaturelle", colName: 'Protection naturelle', getter: (actor, context) => actor.system.attributs.protection.value > 0 ? actor.system.attributs.protection.value : '' }, { column: "description", getter: (actor, context) => Mapping.getDescription(actor) }, { column: "armure", getter: (actor, context) => Mapping.getArmure(actor, context) }, @@ -169,10 +169,10 @@ export class Mapping { arme: arme } } - static dommagesArme(actor, arme, maniement){ + static dommagesArme(actor, arme, maniement) { const dmgArme = RdDItemArme.dommagesReels(arme, maniement) const dommages = Misc.toSignedString(dmgArme + RdDBonus.bonusDmg(actor, maniement, dmgArme)) - switch(arme.system.mortalite) { + switch (arme.system.mortalite) { case 'non-mortel': return `(${dommages})` case 'empoignade': return '-' } @@ -259,6 +259,9 @@ export class Mapping { const diff = 'R' + RdDItemSort.addSpaceToNonNumeric(sort.system.difficulte) return `${sort.name}${ptSeuil} (${caseTMR}) ${diff} ${coutReve}` } + static toVar(caseSpeciale) { + return Grammar.toLowerCaseNoAccent(caseSpeciale).startsWith('var') ? 'var' : caseSpeciale + } static bonusCase(sort) { const list = RdDItemSort.stringToBonuscases(sort.system.bonuscase).sort(Misc.descending(it => it.bonus)) diff --git a/module/apps/rdd-import-stats.js b/module/apps/rdd-import-stats.js index 894f594f..f40fe5e7 100644 --- a/module/apps/rdd-import-stats.js +++ b/module/apps/rdd-import-stats.js @@ -5,12 +5,12 @@ import { RdDBaseActorReve } from "../actor/base-actor-reve.js"; import { Grammar } from "../grammar.js"; import { Misc } from "../misc.js"; import { ENTITE_INCARNE, ENTITE_NONINCARNE } from "../constants.js"; +import { RdDItemTete } from "../item/tete.js"; const WHITESPACES = "\\s+" const NUMERIC = "[\\+\\-]?\\d+" const NUMERIC_VALUE = "(?" + NUMERIC + ")" -const XREGEXP_NAME = "(?[A-Za-zÀ-ÖØ-öø-ÿ\\s\\-]+)" const XREGEXP_COMP_CREATURE = WHITESPACES + "(?\\d+)" + WHITESPACES + NUMERIC_VALUE + "(" + WHITESPACES + "(?\\d+)?\\s+?(?[\\+\\-]?\\d+)?" + ")?" @@ -22,11 +22,12 @@ const compParser = { entite: XREGEXP_COMP_CREATURE } -const XREGEXP_SORT_VOIE = "[OHNT\\/]+" -const XREGEXP_SORT_CASE = "\\((?[A-Za-zÀ-ÖØ-öø-ÿ\\s\\-]+)\\)"; +const XREGEXP_SORT_VOIE = "(?[OHNT](\\/[OHNT])*)" +const XREGEXP_SORT_NAME = "(?[^\\(]+)" +const XREGEXP_SORT_CASE = "\\((?([A-Za-zÀ-ÖØ-öø-ÿ\\s\\-]+|[A-M]\\d{1,2})+)\\)"; const XREGEXP_SORT = "(" + XREGEXP_SORT_VOIE - + WHITESPACES + XREGEXP_NAME + + WHITESPACES + XREGEXP_SORT_NAME + WHITESPACES + XREGEXP_SORT_CASE + WHITESPACES + "R(?([\\-\\d]+|(\\w|\\s)+))" + WHITESPACES + "r(?(\\d+(\\+)?|\\s\\w+))" @@ -104,7 +105,7 @@ export class RdDStatBlockParser { return "vaisseau"; } - static async parseStatBlock(statString, type = "npc") { + static async parseStatBlock(statString) { //statString = statBlock03; if (!statString) { @@ -122,10 +123,10 @@ export class RdDStatBlockParser { statString = statString.trim(); // TODO: check for entite - let actorType = RdDStatBlockParser.parseActorType(statString); + let type = RdDStatBlockParser.parseActorType(statString); // Now start carac - let actorData = foundry.utils.deepClone(game.model.Actor[actorType]); + let actorData = foundry.utils.deepClone(game.model.Actor[type]); for (let key in actorData.carac) { let caracDef = actorData.carac[key]; // Parse the stat string for each caracteristic @@ -136,7 +137,7 @@ export class RdDStatBlockParser { } // If creature we need to setup additionnal fields - switch (actorType) { + switch (type) { case "creature": RdDStatBlockParser.parseCreature(statString, actorData) break @@ -147,14 +148,14 @@ export class RdDStatBlockParser { let items = []; // Get skills from compendium - const competences = await SystemCompendiums.getCompetences(actorType); + const competences = await SystemCompendiums.getCompetences(type); //console.log("Competences : ", competences); for (let comp of competences) { - let compMatch = XRegExp.exec(statString, XRegExp(comp.name + compParser[actorType], 'giu')); + let compMatch = XRegExp.exec(statString, XRegExp(comp.name + compParser[type], 'giu')); if (compMatch) { comp = comp.toObject() comp.system.niveau = Number(compMatch.value); - if (actorType == "creature" || actorType == "entite") { + if (type == "creature" || type == "entite") { comp.system.carac_value = Number(compMatch.carac); if (compMatch.dommages != undefined) { comp.system.dommages = Number(compMatch.dommages); @@ -163,7 +164,7 @@ export class RdDStatBlockParser { } items.push(comp) } - else if (actorType == "personnage") { + else if (type == "personnage") { comp = comp.toObject() items.push(comp) } @@ -213,103 +214,133 @@ export class RdDStatBlockParser { } } - // Attemp to detect spell - let hautRevant = false - let sorts = await SystemCompendiums.getWorldOrCompendiumItems("sort", "sorts-oniros") - sorts = sorts.concat(await SystemCompendiums.getWorldOrCompendiumItems("sort", "sorts-hypnos")) - sorts = sorts.concat(await SystemCompendiums.getWorldOrCompendiumItems("sort", "sorts-narcos")) - sorts = sorts.concat(await SystemCompendiums.getWorldOrCompendiumItems("sort", "sorts-thanatos")) - XRegExp.forEach(statString, XRegExp(XREGEXP_SORT, 'giu'), - function (matchSort, i) { - let sort = sorts.find(s => Grammar.equalsInsensitive(s.name, matchSort.name)) - if (sort) { - hautRevant = true - sort = sort.toObject(); - if (matchSort.bonus && matchSort.bonuscase) { - sort.system.bonuscase = `${matchSort.bonuscase}:${matchSort.bonus}` - } - items.push(sort); - } - }); - - if (hautRevant) { - let tetes = await SystemCompendiums.getWorldOrCompendiumItems("tete", "tetes-de-dragon-pour-tous-personnages") - let donHR = tetes.find(t => Grammar.equalsInsensitive(t.name, "Don de Haut-Rêve")) - if (donHR) { - items.push(donHR.toObject()); - } - } - if (actorType == "personnage") { - - let feminin = XRegExp.exec(statString, XRegExp("né(?e?) à", 'giu')); - actorData.sexe = (feminin?.value == 'e') ? 'féminin' : 'masculin' - - // Get hour name : heure du XXXXX - let heure = XRegExp.exec(statString, XRegExp("heure (du|de la|des|de l\')\\s*(?[A-Za-zÀ-ÖØ-öø-ÿ\\s]+),", 'giu')); - actorData.heure = this.getHeureKey(heure?.value || "Vaisseau"); - - // Get age - let age = XRegExp.exec(statString, XRegExp("(?\\d+) ans", 'giu')); - if (age?.value) { - actorData.age = Number(age.value); - } - // Get height - let taille = XRegExp.exec(statString, XRegExp("(?\\d+m\\d+)", 'giu')); - if (taille?.value) { - actorData.taille = taille.value; - } - // Get weight - let poids = XRegExp.exec(statString, XRegExp("(?\\d+) kg", 'giu')); - if (poids?.value) { - actorData.poids = poids.value; - } - // Get cheveux - let cheveux = XRegExp.exec(statString, XRegExp("kg,\\s+(?[A-Za-zÀ-ÖØ-öø-ÿ\\s\\-]+),\\s+yeux", 'giu')); - if (cheveux?.value) { - actorData.cheveux = cheveux.value; - } - // Get yeux - let yeux = XRegExp.exec(statString, XRegExp("yeux\\s+(?[A-Za-zÀ-ÖØ-öø-ÿ\\s\\-]+), Beau", 'giu')); - if (yeux?.value) { - actorData.yeux = yeux.value; - } - - // Get beauty - let beaute = XRegExp.exec(statString, XRegExp("beauté\\s+(?\\d+)", 'giu')); - if (beaute?.value) { - actorData.beaute = Number(beaute.value); - } + if (type == "personnage") { + await RdDStatBlockParser.parseHautReve(statString, actorData, items); + RdDStatBlockParser.parsePersonnage(statString, actorData); } - // Name is all string before ', né' - let name = RdDStatBlockParser.extractName(actorType, statString); - - let newActor = RdDBaseActorReve.create({ name: name || "Importé", type: actorType, system: actorData, items: items }); + let name = RdDStatBlockParser.extractName(type, statString); + let newActor = await RdDBaseActorReve.create({ name, type: type, system: actorData, items }); + await newActor.remiseANeuf() + await RdDStatBlockParser.setValActuelle(newActor, statString) // DUmp.... console.log(actorData); } - static parseCreature(statString, actorData) { - let plusDom = XRegExp.exec(statString, XRegExp("\\+dom\\s+(?[\\+\\-]?\\d+)", 'giu')); - if (plusDom?.values) { - actorData.attributs.plusdom.value = Number(plusDom.value); + static async setValActuelle(newActor, statString) { + const updates = { } + const endurance = XRegExp.exec(statString, XRegExp("endurance\\s+(?\\d+)\\s+(\\(actuelle\\s*:\\s+(?\\d+)\\))?", 'giu')); + if (endurance?.value) { + if (newActor.getEnduranceMax() != endurance.value) { + ui.notifications.warn(`Vérifier le calcul de l'endurance, calcul: ${newActor.getEnduranceMax()} / import: ${endurance.value}`) + } + } + if (endurance?.actuelle) { + updates['system.sante.endurance.value'] = Number(endurance?.actuelle) + } + + const vie = XRegExp.exec(statString, XRegExp("vie\\s+(?\\d+)\\s+(\\(actuelle\\s*:\\s+(?\\d+)\\))?", 'giu')); + if (vie?.value) { + if (newActor.getVieMax() != vie.value) { + ui.notifications.warn(`Vérifier le calcul de la vie, calcul: ${newActor.getVieMax()} / import: ${vie.value}`) + } + } + if (vie?.actuelle) { + updates['system.sante.vie.value'] = Number(vie?.actuelle) + } + await newActor.update(updates) + } + + static async parseHautReve(statString, actorData, items) { + let hautRevant = false; + // Attemp to detect spell + let sorts = await SystemCompendiums.getWorldOrCompendiumItems("sort", "sorts-oniros"); + sorts = sorts.concat(await SystemCompendiums.getWorldOrCompendiumItems("sort", "sorts-hypnos")); + sorts = sorts.concat(await SystemCompendiums.getWorldOrCompendiumItems("sort", "sorts-narcos")); + sorts = sorts.concat(await SystemCompendiums.getWorldOrCompendiumItems("sort", "sorts-thanatos")); + + XRegExp.forEach(statString, XRegExp(XREGEXP_SORT, 'gu' /* keep case sensitive to match the spell draconic skill */), + function (matchSort, i) { + const sortName = Grammar.toLowerCaseNoAccent(matchSort.name).trim().replace("’", "'"); + let sort = sorts.find(s => Grammar.toLowerCaseNoAccent(s.name) == sortName) + if (sort) { + hautRevant = true; + sort = sort.toObject(); + if (matchSort.bonus && matchSort.bonuscase) { + sort.system.bonuscase = `${matchSort.bonuscase}:${matchSort.bonus}`; + } + items.push(sort); + } + else { + ui.notifications.warn(`Impossible de trouver le sort ${matchSort.name} / ${sortName}`) + } + }); + + if (hautRevant) { + const donHR = await RdDItemTete.teteDonDeHautReve(); + if (donHR) { + items.push(donHR.toObject()); + } + + const demiReve = XRegExp.exec(statString, XRegExp("Demi-rêve\\s+(?[A-M]\\d{1,2})", 'giu')) + actorData.reve.tmrpos.coord = demiReve?.value ?? 'A1' + } + } + + static parsePersonnage(statString, actorData) { + actorData.reve.seuil.value = actorData.carac.reve.value + + const reveActuel = XRegExp.exec(statString, XRegExp("Rêve actuel\\s+(?\\d+)", 'giu')) + actorData.reve.reve.value = reveActuel?.value ? Number(reveActuel.value) : actorData.reve.seuil.value + + const feminin = XRegExp.exec(statString, XRegExp("né(?e?) à", 'giu')); + actorData.sexe = (feminin?.value == 'e') ? 'féminin' : 'masculin'; + + // Get hour name : heure du XXXXX + const heure = XRegExp.exec(statString, XRegExp("heure (du|de la|des|de l\')\\s*(?[A-Za-zÀ-ÖØ-öø-ÿ\\s]+),", 'giu')); + actorData.heure = this.getHeureKey(heure?.value || "Vaisseau"); + + // Get age + const age = XRegExp.exec(statString, XRegExp("(?\\d+) ans", 'giu')); + if (age?.value) { + actorData.age = Number(age.value); + } + // Get height + const taille = XRegExp.exec(statString, XRegExp("(?\\d+m\\d+)", 'giu')); + if (taille?.value) { + actorData.taille = taille.value; + } + // Get weight + const poids = XRegExp.exec(statString, XRegExp("(?\\d+) kg", 'giu')); + if (poids?.value) { + actorData.poids = poids.value; + } + // Get cheveux + const cheveux = XRegExp.exec(statString, XRegExp("kg,\\s+(?[A-Za-zÀ-ÖØ-öø-ÿ\\s\\-]+),\\s+yeux", 'giu')); + if (cheveux?.value) { + actorData.cheveux = cheveux.value; + } + // Get yeux + const yeux = XRegExp.exec(statString, XRegExp("yeux\\s+(?[A-Za-zÀ-ÖØ-öø-ÿ\\s\\-]+), Beau", 'giu')); + if (yeux?.value) { + actorData.yeux = yeux.value; + } + + // Get beauty + const beaute = XRegExp.exec(statString, XRegExp("beauté\\s+(?\\d+)", 'giu')); + if (beaute?.value) { + actorData.beaute = Number(beaute.value); + } + } + + static parseCreature(statString, actorData) { let protection = XRegExp.exec(statString, XRegExp("protection\\s+(?[\\-]?\\d+)", 'giu')); if (protection?.value) { actorData.attributs.protection.value = Number(protection.value); } - let endurance = XRegExp.exec(statString, XRegExp("endurance\\s+(?\\d+)", 'giu')); - if (endurance?.value) { - actorData.sante.endurance.value = Number(endurance.value); - actorData.sante.endurance.max = Number(endurance.value); - } - let vie = XRegExp.exec(statString, XRegExp("vie\\s+(?\\d+)", 'giu')); - if (vie.value) { - actorData.sante.vie.value = Number(vie.value); - actorData.sante.vie.max = Number(vie.value); - } let vitesse = XRegExp.exec(statString, XRegExp("vitesse\\s+(?[\\d\\/]+)", 'giu')); if (vitesse?.value) { actorData.attributs.vitesse.value = vitesse.value; @@ -317,11 +348,6 @@ export class RdDStatBlockParser { } static parseEntite(statString, actorData) { - let plusDom = XRegExp.exec(statString, XRegExp("\\+dom\\s+(?[\\+\\-]?\\d+)", 'giu')); - if (plusDom?.values) { - actorData.attributs.plusdom.value = Number(plusDom.value); - } - actorData.definition.categorieentite = 'cauchemar' actorData.definition.typeentite = ENTITE_NONINCARNE let endurance = XRegExp.exec(statString, XRegExp("endurance\\s+(?\\d+)", 'giu')); @@ -350,24 +376,21 @@ export class RdDStatBlockParser { static extractName(actorType, statString) { switch (actorType) { - case "personnage": return RdDStatBlockParser.extractNamePersonnage(statString); - case "creature": return RdDStatBlockParser.extractNameCreature(statString); + case "personnage": + // Name is all string before first comma ',' + const namePersonnage = XRegExp.exec(statString, XRegExp("(?[\\p{Letter}\\s\\d]+),", 'giu')); + if (namePersonnage?.value) { + return Misc.upperFirst(namePersonnage?.value); + } } - return RdDStatBlockParser.extractNameCreature(statString); - } - - static extractNamePersonnage(statString) { - let name = XRegExp.exec(statString, XRegExp("(?[\\p{Letter}\\s\\d]+),", 'giu')); - if (!name?.value) { - name = XRegExp.exec(statString, XRegExp("(?.+)\\s+taille", 'giu')); - } - return Misc.upperFirst(name?.value || "Importé"); - } - - static extractNameCreature(statString) { const name = XRegExp.exec(statString, XRegExp("(?.+)\\s+taille", 'giu')); return Misc.upperFirst(name?.value || "Importé"); } + + static warning(message) { + ui.notifications.warn(message); + } + } /************************************************************************************/ diff --git a/module/item/tete.js b/module/item/tete.js new file mode 100644 index 00000000..f16598cb --- /dev/null +++ b/module/item/tete.js @@ -0,0 +1,25 @@ +import { Grammar } from "../grammar.js" +import { ITEM_TYPES, RdDItem } from "../item.js" +import { SystemCompendiums } from "../settings/system-compendiums.js" + +const DON_HAUT_REVE = "Don de Haut-Rêve" + +export class RdDItemTete extends RdDItem { + + static get defaultIcon() { + return "systems/foundryvtt-reve-de-dragon/icons/tete_dragon.webp" + } + + static isDonDeHautReve(tete) { + return tete.type == ITEM_TYPES.tete && Grammar.equalsInsensitive(tete.name, DON_HAUT_REVE) + } + + static async teteDonDeHautReve() { + const tetes = await SystemCompendiums.getItems("tetes-de-dragon-pour-tous-personnages", ITEM_TYPES.tete) + const tete = tetes.find(it => RdDItemTete.isDonDeHautReve(it)) + if (!tete) { + ui.notifications.warn(`Impossible de trouver la tête "${DON_HAUT_REVE}", vérifiez le compendium de têtes pour tous personnages`) + } + return tete + } +} diff --git a/module/migrations.js b/module/migrations.js index 26c84756..4e2e3ef4 100644 --- a/module/migrations.js +++ b/module/migrations.js @@ -137,7 +137,7 @@ class _10_0_21_VehiculeStructureResistanceMax extends Migration { } class _10_0_33_MigrationNomsDraconic extends Migration { - get code() { return "competences-creature-parade"; } + get code() { return "competences-nom-draconic"; } get version() { return "10.0.33"; } migrationNomDraconic(ancien) { @@ -530,15 +530,25 @@ class _11_2_20_MigrationAstrologie extends Migration { } } -class _12_0_24_MigrationVoieSorts extends Migration { +class _12_0_26_MigrationVoieSorts extends Migration { get code() { return "migration-voies-sorts" } - get version() { return "12.0.24" } + get version() { return "12.0.26" } async migrate() { await this.applyItemsUpdates(items => items - .filter(it => ITEM_TYPES.sort == it.type) + .filter(it => [ITEM_TYPES.sort, ITEM_TYPES.sortreserve].includes(it.type)) .map(it => this.migrateSort(it)) ) + await this.applyItemsUpdates(items => items + .filter(it => ITEM_TYPES.competence == it.type && it.system.categorie == 'draconic') + .map(it => this.migrateDraconic(it)) + ) + } + migrateDraconic(it) { + return { + _id: it.id, + name: this.convertDraconic(it.name), + } } migrateSort(it) { return { @@ -575,6 +585,7 @@ export class Migrations { new _10_7_19_CategorieCompetenceCreature(), new _10_7_19_PossessionsEntiteVictime(), new _11_2_20_MigrationAstrologie(), + new _12_0_26_MigrationVoieSorts() ]; } diff --git a/module/misc.js b/module/misc.js index df4301ff..2829985a 100644 --- a/module/misc.js +++ b/module/misc.js @@ -58,9 +58,6 @@ export class Misc { * @param {*} value value to convert to an integer using parseInt */ static toInt(value) { - if (value == undefined) { - return 0; - } const parsed = parseInt(value); return isNaN(parsed) ? 0 : parsed; } @@ -203,11 +200,7 @@ export class Misc { if (!document.testUserPermission){ return false } - return game.users.filter(u => document.testUserPermission(u, CONST.DOCUMENT_OWNERSHIP_LEVELS.OWNER)) == game.user - } - - static isOwnerPlayerOrUniqueConnectedGM(actor) { - return Misc.isFirstOwnerPlayer(actor) ?? Misc.isFirstConnectedGM(); + return game.users.find(u => document.testUserPermission(u, CONST.DOCUMENT_OWNERSHIP_LEVELS.OWNER)) == game.user } /** diff --git a/module/rdd-carac.js b/module/rdd-carac.js index a2f42ce6..272f0869 100644 --- a/module/rdd-carac.js +++ b/module/rdd-carac.js @@ -64,7 +64,7 @@ export class RdDCarac { } static getCaracDerivee(value) { - return TABLE_CARACTERISTIQUES_DERIVEES[Math.min(Math.max(Number(value), 1), 32)]; + return TABLE_CARACTERISTIQUES_DERIVEES[Math.min(Math.max(Math.floor(Number(value)), 1), 32)]; } static computeTotal(carac, beaute = undefined) { diff --git a/module/rdd-combat.js b/module/rdd-combat.js index 9521828b..a888f653 100644 --- a/module/rdd-combat.js +++ b/module/rdd-combat.js @@ -436,7 +436,7 @@ export class RdDCombat { /* -------------------------------------------- */ static onMsgEncaisser(msg) { let defender = canvas.tokens.get(msg.defenderToken.id).actor; - if (Misc.isOwnerPlayerOrUniqueConnectedGM(defender)) { + if (Misc.isOwnerPlayer(defender)) { let attackerRoll = msg.attackerRoll; let attacker = msg.attackerId ? game.actors.get(msg.attackerId) : undefined; defender.encaisserDommages(attackerRoll, attacker, msg.attackerToken); @@ -1251,7 +1251,7 @@ export class RdDCombat { this._onEchecTotal(defenderRoll); } - if (Misc.isOwnerPlayerOrUniqueConnectedGM(this.defender)) { + if (Misc.isOwnerPlayer(this.defender)) { attackerRoll.attackerId = this.attackerId; attackerRoll.defenderTokenId = this.defenderToken.id; diff --git a/module/rdd-main.js b/module/rdd-main.js index 5b857b87..64f78328 100644 --- a/module/rdd-main.js +++ b/module/rdd-main.js @@ -70,6 +70,7 @@ import { AppPersonnageAleatoire } from "./actor/random/app-personnage-aleatoire. import { RdDActorExportSheet } from "./actor/export-scriptarium/actor-encart-sheet.js" import { RdDStatBlockParser } from "./apps/rdd-import-stats.js" import { RdDItemSort } from "./item-sort.js" +import { RdDItemTete } from "./item/tete.js" /** * RdD system @@ -97,6 +98,7 @@ export class SystemReveDeDragon { ombre: RdDItemOmbre, poison: RdDItemPoison, queue: RdDItemQueue, + tete: RdDItemTete, rencontre: RdDRencontre, service: RdDItemService, signedraconique: RdDItemSigneDraconique, diff --git a/module/rdd-utility.js b/module/rdd-utility.js index 59bc9809..6397ca2a 100644 --- a/module/rdd-utility.js +++ b/module/rdd-utility.js @@ -20,6 +20,7 @@ import { ExperienceLog } from "./actor/experience-log.js"; import { RdDCoeur } from "./coeur/rdd-coeur.js"; import { APP_ASTROLOGIE_REFRESH } from "./sommeil/app-astrologie.js"; import { RDD_CONFIG } from "./constants.js"; +import { RdDBaseActor } from "./actor/base-actor.js"; /* -------------------------------------------- */ // This table starts at 0 -> niveau -10 @@ -145,8 +146,8 @@ export class RdDUtility { 'systems/foundryvtt-reve-de-dragon/templates/actor/alchimie.html', 'systems/foundryvtt-reve-de-dragon/templates/actor/astrologie.html', 'systems/foundryvtt-reve-de-dragon/templates/actor/chirurgie.html', - 'systems/foundryvtt-reve-de-dragon/templates/actor/non-haut-revant.html', - 'systems/foundryvtt-reve-de-dragon/templates/actor/haut-revant.html', + 'systems/foundryvtt-reve-de-dragon/templates/actor/non-haut-revant.hbs', + 'systems/foundryvtt-reve-de-dragon/templates/actor/haut-revant.hbs', 'systems/foundryvtt-reve-de-dragon/templates/actor/dragon-queues.html', 'systems/foundryvtt-reve-de-dragon/templates/actor/dragon-queue.html', 'systems/foundryvtt-reve-de-dragon/templates/actor/dragon-souffles.html', @@ -288,6 +289,8 @@ export class RdDUtility { Handlebars.registerHelper('timestamp-formulesDuree', () => RdDTimestamp.formulesDuree()); Handlebars.registerHelper('timestamp-formulesPeriode', () => RdDTimestamp.formulesPeriode()); + Handlebars.registerHelper('actor-default', (actorType, ...path) => RdDBaseActor.getDefaultValue(actorType, path.slice(0, -1))); + Handlebars.registerHelper('array-includes', (array, value) => array.includes(value)); Handlebars.registerHelper('min', (...args) => Math.min(...args.slice(0, -1))); Handlebars.registerHelper('isLastIndex', (index, list) => index + 1 >= list.length); diff --git a/module/settings/system-compendiums.js b/module/settings/system-compendiums.js index 663b3c5a..fba598ff 100644 --- a/module/settings/system-compendiums.js +++ b/module/settings/system-compendiums.js @@ -1,5 +1,6 @@ import { ChatUtility } from "../chat-utility.js"; import { HIDE_DICE, SYSTEM_RDD } from "../constants.js"; +import { Grammar } from "../grammar.js"; import { RdDItem } from "../item.js"; import { Misc } from "../misc.js"; import { RdDDice } from "../rdd-dice.js"; @@ -84,15 +85,14 @@ export class SystemCompendiums extends FormApplication { static async getWorldOrCompendiumItems(itemType, compendium) { let items = game.items.filter(it => it.type == itemType) if (compendium) { - const ids = items.map(it => it.id); - const names = items.map(it => it.name.toLowerCase()); - const compendiumItems = await SystemCompendiums.getItems(compendium); - items = items.concat(compendiumItems - .filter(it => it.type == itemType) + const ids = items.map(it => it.id) + const names = items.map(it => Grammar.toLowerCaseNoAccent(it.name)) + const compendiumItems = await SystemCompendiums.getItems(compendium, itemType) + return items.concat(compendiumItems .filter(it => !ids.includes(it.id)) - .filter(it => !names.includes(it.name.toLowerCase()))); + .filter(it => !names.includes(Grammar.equalsInsensitive(it.name)))) } - return items; + return items } static async loadDocument(document) { diff --git a/packs_src/competences/competence_Voie_d_Hypnos_bt2cR4aE6lIOeg4F.yml b/packs_src/competences/competence_Hypnos_bt2cR4aE6lIOeg4F.yml similarity index 96% rename from packs_src/competences/competence_Voie_d_Hypnos_bt2cR4aE6lIOeg4F.yml rename to packs_src/competences/competence_Hypnos_bt2cR4aE6lIOeg4F.yml index 61144e04..b6a76376 100644 --- a/packs_src/competences/competence_Voie_d_Hypnos_bt2cR4aE6lIOeg4F.yml +++ b/packs_src/competences/competence_Hypnos_bt2cR4aE6lIOeg4F.yml @@ -1,4 +1,4 @@ -name: Voie d'Hypnos +name: Hypnos type: competence img: systems/foundryvtt-reve-de-dragon/icons/competence_hypnos.webp _id: bt2cR4aE6lIOeg4F diff --git a/packs_src/competences/competence_Voie_de_Narcos_u1Peok1EYkBcVsmN.yml b/packs_src/competences/competence_Narcos_u1Peok1EYkBcVsmN.yml similarity index 95% rename from packs_src/competences/competence_Voie_de_Narcos_u1Peok1EYkBcVsmN.yml rename to packs_src/competences/competence_Narcos_u1Peok1EYkBcVsmN.yml index 2e50bd38..bf21b1b1 100644 --- a/packs_src/competences/competence_Voie_de_Narcos_u1Peok1EYkBcVsmN.yml +++ b/packs_src/competences/competence_Narcos_u1Peok1EYkBcVsmN.yml @@ -1,4 +1,4 @@ -name: Voie de Narcos +name: Narcos type: competence img: systems/foundryvtt-reve-de-dragon/icons/competence_narcos.webp _id: u1Peok1EYkBcVsmN diff --git a/packs_src/competences/competence_Voie_d_Oniros_nnR2UHelUaF8dxYn.yml b/packs_src/competences/competence_Oniros_nnR2UHelUaF8dxYn.yml similarity index 96% rename from packs_src/competences/competence_Voie_d_Oniros_nnR2UHelUaF8dxYn.yml rename to packs_src/competences/competence_Oniros_nnR2UHelUaF8dxYn.yml index 0570fa06..7c472840 100644 --- a/packs_src/competences/competence_Voie_d_Oniros_nnR2UHelUaF8dxYn.yml +++ b/packs_src/competences/competence_Oniros_nnR2UHelUaF8dxYn.yml @@ -1,4 +1,4 @@ -name: Voie d'Oniros +name: Oniros type: competence img: systems/foundryvtt-reve-de-dragon/icons/competence_oniros.webp _id: nnR2UHelUaF8dxYn diff --git a/packs_src/competences/competence_Voie_de_Thanatos_dPlTQzvU3CEg5qKc.yml b/packs_src/competences/competence_Thanatos_dPlTQzvU3CEg5qKc.yml similarity index 95% rename from packs_src/competences/competence_Voie_de_Thanatos_dPlTQzvU3CEg5qKc.yml rename to packs_src/competences/competence_Thanatos_dPlTQzvU3CEg5qKc.yml index 9073849b..f7897b36 100644 --- a/packs_src/competences/competence_Voie_de_Thanatos_dPlTQzvU3CEg5qKc.yml +++ b/packs_src/competences/competence_Thanatos_dPlTQzvU3CEg5qKc.yml @@ -1,4 +1,4 @@ -name: Voie de Thanatos +name: Thanatos type: competence img: systems/foundryvtt-reve-de-dragon/icons/competence_thanatos.webp _id: dPlTQzvU3CEg5qKc diff --git a/system.json b/system.json index ae27d840..873d27ca 100644 --- a/system.json +++ b/system.json @@ -1,9 +1,9 @@ { "id": "foundryvtt-reve-de-dragon", "title": "Rêve de Dragon", - "version": "12.0.24", - "download": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/releases/download/12.0.24/rddsystem.zip", - "manifest": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/releases/download//12.0.24/system.json", + "version": "12.0.26", + "download": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/releases/download/12.0.26/rddsystem.zip", + "manifest": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/releases/download/12.0.26/system.json", "changelog": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/raw/branch/v11/changelog.md", "compatibility": { "minimum": "11", diff --git a/template.json b/template.json index 815e9a35..2fe4362d 100644 --- a/template.json +++ b/template.json @@ -112,7 +112,7 @@ "type": "string", "value": 0, "label": "Vitesse", - "derivee": true + "derivee": false }, "protection": { "type": "number", @@ -195,13 +195,13 @@ "type": "string", "value": 0, "label": "Vitesse", - "derivee": true + "derivee": false }, "encombrement": { "type": "number", "value": 0, "label": "Encombrement", - "derivee": false + "derivee": true }, "protection": { "type": "number", diff --git a/templates/actor-sheet.html b/templates/actor-sheet.html index 58bf0955..9e772304 100644 --- a/templates/actor-sheet.html +++ b/templates/actor-sheet.html @@ -129,11 +129,10 @@
{{#if system.attributs.hautrevant.value}}

Haut rêvant

- {{> "systems/foundryvtt-reve-de-dragon/templates/actor/haut-revant.html"}} + {{> "systems/foundryvtt-reve-de-dragon/templates/actor/haut-revant.hbs"}} {{else}}

Vous n'avez pas le don de haut-rêve

-

Attribuer la Tête de Dragon 'Don de Haut Rêve' pour rendre le personnage Haut-Rêvant.

- {{> "systems/foundryvtt-reve-de-dragon/templates/actor/non-haut-revant.html"}} + {{> "systems/foundryvtt-reve-de-dragon/templates/actor/non-haut-revant.hbs"}} {{/if}}

diff --git a/templates/actor/carac-creature.html b/templates/actor/carac-creature.html index 34905034..e16b56f3 100644 --- a/templates/actor/carac-creature.html +++ b/templates/actor/carac-creature.html @@ -1,8 +1,21 @@
    {{#each system.attributs as |attr key|}} -
  1. - {{attr.label}} - -
  2. + {{#if (and (eq key 'plusdom') (eq @root.system.definition.typeentite 'nonincarne'))}} + {{else}} +
  3. + {{attr.label}} + {{#if (actor-default @root.type 'attributs' key 'derivee')}} + + {{else}} + + {{/if}} +
  4. + {{/if}} {{/each}}
diff --git a/templates/actor/carac-entitee.html b/templates/actor/carac-entitee.html index 80e08729..b177c5ff 100644 --- a/templates/actor/carac-entitee.html +++ b/templates/actor/carac-entitee.html @@ -11,10 +11,6 @@ {{selectOptions (RDD_CONFIG 'typeEntite') selected=system.definition.typeentite}} - {{#each system.attributs as |attr key|}} -
  • - {{attr.label}} : - -
  • - {{/each}} - \ No newline at end of file + + +{{> "systems/foundryvtt-reve-de-dragon/templates/actor/carac-creature.html"}} diff --git a/templates/actor/carac-main.html b/templates/actor/carac-main.html index 3ed28231..2ed701db 100644 --- a/templates/actor/carac-main.html +++ b/templates/actor/carac-main.html @@ -1,36 +1,39 @@
      {{#each system.carac as |carac key|}} + {{#if (and (eq key 'taille') (eq @root.system.definition.typeentite 'nonincarne'))}} + {{else}}
    • {{#if (eq key 'taille')}} {{carac.label}}
    • + {{/if}} {{/each}}
    diff --git a/templates/actor/haut-revant.html b/templates/actor/haut-revant.hbs similarity index 99% rename from templates/actor/haut-revant.html rename to templates/actor/haut-revant.hbs index 604fca15..74d59386 100644 --- a/templates/actor/haut-revant.html +++ b/templates/actor/haut-revant.hbs @@ -26,7 +26,7 @@ {{/if}} -{{> "systems/foundryvtt-reve-de-dragon/templates/actor/non-haut-revant.html"}} +{{> "systems/foundryvtt-reve-de-dragon/templates/actor/non-haut-revant.hbs"}}
    {{> "systems/foundryvtt-reve-de-dragon/templates/actor/hr-signes-draconiques.html"}} {{> "systems/foundryvtt-reve-de-dragon/templates/actor/hr-rencontres.html"}} diff --git a/templates/actor/header-compteurs-creature.html b/templates/actor/header-compteurs-creature.html index 8674ea3a..c35d34d0 100644 --- a/templates/actor/header-compteurs-creature.html +++ b/templates/actor/header-compteurs-creature.html @@ -5,9 +5,7 @@ Vie - / {{#if @root.options.vueDetaillee}} - - {{else}}{{system.sante.vie.max}}{{/if}} + / {{system.sante.vie.max}} @@ -16,9 +14,7 @@ Endurance - / {{#if @root.options.vueDetaillee}} - - {{else}}{{system.sante.endurance.max}}{{/if}} + / {{system.sante.endurance.max}} diff --git a/templates/actor/header-compteurs-entitee.html b/templates/actor/header-compteurs-entitee.html index dbf92db4..7974334c 100644 --- a/templates/actor/header-compteurs-entitee.html +++ b/templates/actor/header-compteurs-entitee.html @@ -6,9 +6,7 @@ Endurance - / {{#if @root.options.vueDetaillee}} - - {{else}}{{system.sante.endurance.max}}{{/if}} + / {{system.sante.endurance.max}} diff --git a/templates/actor/non-haut-revant.hbs b/templates/actor/non-haut-revant.hbs new file mode 100644 index 00000000..c91ed10b --- /dev/null +++ b/templates/actor/non-haut-revant.hbs @@ -0,0 +1,41 @@ +{{#if (not system.attributs.hautrevant.value)}} +

    Attribuer la Tête de Dragon + {{#if options.isGM}} + Don de Haut Rêve + {{else}} + 'Don de Haut Rêve' + {{/if}} + pour rendre le personnage Haut-Rêvant.

    +{{/if}} +
  • + Seuil de Rêve : + + {{#if options.isGM}} + + {{else}} + {{system.reve.seuil.value}} + {{/if}} + +
  • +
  • + Refoulement : + + {{#if options.isGM}} + + {{else}} + {{system.reve.refoulement.value}} + {{/if}} + +
  • +{{#if system.reve.reve.thanatosused}} +
  • + La prochaine queue est une Ombre + + + +
  • +{{/if}} +
    +{{> "systems/foundryvtt-reve-de-dragon/templates/actor/dragon-queues.html"}} +{{> "systems/foundryvtt-reve-de-dragon/templates/actor/dragon-souffles.html"}} +{{> "systems/foundryvtt-reve-de-dragon/templates/actor/dragon-tetes.html"}} diff --git a/templates/actor/non-haut-revant.html b/templates/actor/non-haut-revant.html deleted file mode 100644 index 333cf48a..00000000 --- a/templates/actor/non-haut-revant.html +++ /dev/null @@ -1,34 +0,0 @@ -
      -
    • - Seuil de Rêve : - - {{#if options.isGM}} - - {{else}} - {{system.reve.seuil.value}} - {{/if}} - -
    • -
    • - Refoulement : - - {{#if options.isGM}} - - {{else}} - {{system.reve.refoulement.value}} - {{/if}} - -
    • - {{#if system.reve.reve.thanatosused}} -
    • - La prochaine queue est une Ombre - - - -
    • - {{/if}} -
    -
    -{{> "systems/foundryvtt-reve-de-dragon/templates/actor/dragon-queues.html"}} -{{> "systems/foundryvtt-reve-de-dragon/templates/actor/dragon-souffles.html"}} -{{> "systems/foundryvtt-reve-de-dragon/templates/actor/dragon-tetes.html"}}