diff --git a/module/actor-sheet.js b/module/actor-sheet.js index 19837d4e..e42c3ce8 100644 --- a/module/actor-sheet.js +++ b/module/actor-sheet.js @@ -33,7 +33,7 @@ export class RdDActorSheet extends ActorSheet { /* -------------------------------------------- */ getData() { let data = super.getData(); - if ( data.actor.type == 'creature' || data.actor.type == 'humanoide') return data; // Shortcut + if (data.actor.type == 'creature' || data.actor.type == 'humanoide') return data; // Shortcut data.data.editCaracComp = this.options.editCaracComp; data.data.showCompNiveauBase = this.options.showCompNiveauBase; @@ -50,13 +50,13 @@ export class RdDActorSheet extends ActorSheet { item => { let archetypeKey = (item.data.niveau_archetype < 0) ? 0 : item.data.niveau_archetype; if (data.data.comptageArchetype[archetypeKey] == undefined) { - data.data.comptageArchetype[archetypeKey] = { "niveau": archetypeKey, "nombreMax": 0, "nombre": 0}; + data.data.comptageArchetype[archetypeKey] = { "niveau": archetypeKey, "nombreMax": 0, "nombre": 0 }; } - data.data.comptageArchetype[archetypeKey].nombre = (data.data.comptageArchetype[archetypeKey]?.nombre??0) + 1; //Comptage archetype + data.data.comptageArchetype[archetypeKey].nombre = (data.data.comptageArchetype[archetypeKey]?.nombre ?? 0) + 1; //Comptage archetype item.data.xpNext = RdDItemCompetence.getCompetenceNextXp(item.data.niveau); item.data.isLevelUp = item.data.xp >= item.data.xpNext; // Flag de niveau à MAJ //this.actor.checkCompetenceXP(item.name); // Petite vérification experience - item.data.showCompetence = !data.data.showCompNiveauBase || (Number(item.data.niveau) != Number(RdDUtility.getLevelCategory(item.data.categorie))); + item.data.showCompetence = !data.data.showCompNiveauBase || (Number(item.data.niveau) != Number(RdDItemCompetence.getLevelCategory(item.data.categorie))); // Ignorer les compétences 'troncs' à ce stade data.data.competenceXPTotal += RdDItemCompetence.computeCompetenceXPCost(item); return item; @@ -68,7 +68,7 @@ export class RdDActorSheet extends ActorSheet { for (let caracName in data.data.carac) { let currentCarac = data.data.carac[caracName]; if (!currentCarac.derivee) { - sum += parseInt(currentCarac.value); + sum += parseInt(currentCarac.value); } currentCarac.xpNext = RdDUtility.getCaracNextXp(currentCarac.value); currentCarac.isLevelUp = (currentCarac.xp >= currentCarac.xpNext); @@ -98,7 +98,7 @@ export class RdDActorSheet extends ActorSheet { data.data.combat = duplicate(RdDUtility.checkNull(data.itemsByType['arme'])); data.data.combat = RdDCombatManager.finalizeArmeList(data.data.combat, data.itemsByType.competence, data.data.carac); - data.esquive = { name: "Esquive", niveau: data.competenceByCategory?.melee.find(it => it.name == 'Esquive')?.data.niveau ?? -6}; + data.esquive = { name: "Esquive", niveau: data.competenceByCategory?.melee.find(it => it.name == 'Esquive')?.data.niveau ?? -6 }; let corpsACorps = data.competenceByCategory?.melee.find(it => it.name == 'Corps à corps'); if (corpsACorps) { let cc_init = RdDCombatManager.calculInitiative(corpsACorps.data.niveau, data.data.carac['melee'].value); @@ -113,7 +113,7 @@ export class RdDActorSheet extends ActorSheet { // Mise à jour de l'encombrement total et du prix de l'équipement this.actor.computeEncombrementTotalEtMalusArmure(); this.actor.computePrixTotalEquipement(); - + // Common data data.data.competenceByCategory = data.competenceByCategory; data.data.encTotal = this.actor.encTotal; @@ -131,20 +131,20 @@ export class RdDActorSheet extends ActorSheet { RdDUtility.filterItemsPerTypeForSheet(data); data.data.sortReserve = data.data.reve.reserve.list; - data.data.rencontres = duplicate(data.data.reve.rencontre.list); + data.data.rencontres = duplicate(data.data.reve.rencontre.list); data.data.caseSpeciales = data.itemsByType['casetmr']; RdDUtility.buildArbreDeConteneur(this, data); data.data.surEncombrementMessage = (data.data.compteurs.surenc.value < 0) ? "Sur-Encombrement!" : ""; data.data.vehiculesList = this.actor.buildVehiculesList(); - data.data.monturesList = this.actor.buildMonturesList(); - data.data.suivantsList = this.actor.buildSuivantsList(); + data.data.monturesList = this.actor.buildMonturesList(); + data.data.suivantsList = this.actor.buildSuivantsList(); return data; } /* -------------------------------------------- */ async _onDrop(event) { let toSuper = await RdDUtility.processItemDropEvent(this, event); - if ( toSuper) { + if (toSuper) { super._onDrop(event); } } @@ -213,12 +213,12 @@ export class RdDActorSheet extends ActorSheet { html.find('.item-delete').click(ev => { const li = $(ev.currentTarget).parents(".item"); RdDUtility.confirmerSuppression(this, li); - }); + }); html.find('.subacteur-delete').click(ev => { const li = $(ev.currentTarget).parents(".item"); RdDUtility.confirmerSuppressionSubacteur(this, li); }); - + html.find('#encaisser-direct').click(ev => { this.actor.encaisser(); }); @@ -335,12 +335,12 @@ export class RdDActorSheet extends ActorSheet { html.find('.subacteur-label a').click((event) => { const li = $(event.currentTarget).parents(".item"); let actorId = li.data('actor-id'); - let actor = game.actors.get( actorId) ; - if ( actor ) { + let actor = game.actors.get(actorId); + if (actor) { actor.sheet.render(true); } }); - + // Points de reve actuel html.find('.ptreve-actuel a').click((event) => { this.actor.rollCarac('reve-actuel'); diff --git a/module/actor.js b/module/actor.js index 9859fc79..ce68b6a4 100644 --- a/module/actor.js +++ b/module/actor.js @@ -113,12 +113,12 @@ export class RdDActor extends Actor { } /* -------------------------------------------- */ - setRollWindowsOpened( flag ) { + setRollWindowsOpened(flag) { this.rollWindowsOpened = flag; } /* -------------------------------------------- */ - isRollWindowsOpened( ) { + isRollWindowsOpened() { return this.rollWindowsOpened; } @@ -315,11 +315,11 @@ export class RdDActor extends Actor { let reserve = duplicate(this.data.data.reve.reserve); let tmr = TMRUtility.getTMR(sortReserve.coord); let index = reserve.list.findIndex(tmr.type == 'fleuve' - ? sort => (TMRUtility.getTMR(sort.coord).type == 'fleuve' && sort.sort.name == sortReserve.sort.name) - : sort => (sort.coord == sortReserve.coord && sort.sort.name == sortReserve.sort.name) + ? sort => (TMRUtility.getTMR(sort.coord).type == 'fleuve' && sort.sort.name == sortReserve.sort.name) + : sort => (sort.coord == sortReserve.coord && sort.sort.name == sortReserve.sort.name) ); - if (index >=0 ) { - reserve.list.splice(index,1); + if (index >= 0) { + reserve.list.splice(index, 1); await this.update({ "data.reve.reserve": reserve }); } } @@ -356,7 +356,7 @@ export class RdDActor extends Actor { // On ne récupère un point de chance que si aucun appel à la chance dans la journée let utilisationChance = duplicate(this.getFlag('foundryvtt-reve-de-dragon', 'utilisationChance') ?? false); - if ( !utilisationChance ) { + if (!utilisationChance) { await this.chanceActuelleIncDec(1); } await this.unsetFlag('foundryvtt-reve-de-dragon', 'utilisationChance'); // Nouveau jour, suppression du flag @@ -489,7 +489,7 @@ export class RdDActor extends Actor { async dormir(heures = 1) { let message = { whisper: ChatUtility.getWhisperRecipientsAndGMs(this.name), - content: `${this.name}: Vous dormez ${heures == 1 ? 'une': heures} heure${heures == 1 ? '': 's'}.` + content: `${this.name}: Vous dormez ${heures == 1 ? 'une' : heures} heure${heures == 1 ? '' : 's'}.` }; await this.recupereEndurance(message); for (let i = 0; i < heures; i++) { @@ -710,7 +710,7 @@ export class RdDActor extends Actor { return; } let caracpath = "data.carac." + caracName + ".xp"; - await this.update({ [caracpath]: caracXP }); + await this.update({ [caracpath]: caracXP ?? 0 }); this.checkCaracXP(caracName); } @@ -736,7 +736,7 @@ export class RdDActor extends Actor { let comp = this.getCompetence(compName); if (comp) { let troncList = RdDItemCompetence.isTronc(compName); - let maxNiveau = compValue; + let nouveauNiveau = compValue ?? RdDItemCompetence.getLevelCategory(comp.data.categorie); if (troncList) { let message = "Vous avez modifié une compétence 'tronc'. Vérifiez que les compétences suivantes évoluent ensemble jusqu'au niveau 0 : "; for (let troncName of troncList) { @@ -747,7 +747,7 @@ export class RdDActor extends Actor { content: message }); } - const update = { _id: comp._id, 'data.niveau': maxNiveau }; + const update = { _id: comp._id, 'data.niveau': nouveauNiveau }; const updated = await this.updateEmbeddedEntity("OwnedItem", update); // Updates one EmbeddedEntity } else { console.log("Competence not found", compName); @@ -758,6 +758,7 @@ export class RdDActor extends Actor { async updateCompetenceXP(compName, compValue) { let comp = this.getCompetence(compName); if (comp) { + compValue = compValue ?? 0; this.checkCompetenceXP(compName, compValue); const update = { _id: comp._id, 'data.xp': compValue }; const updated = await this.updateEmbeddedEntity("OwnedItem", update); // Updates one EmbeddedEntity @@ -771,6 +772,7 @@ export class RdDActor extends Actor { async updateCompetenceXPSort(compName, compValue) { let comp = this.getCompetence(compName); if (comp) { + compValue = compValue ?? 0; const update = { _id: comp._id, 'data.xp_sort': compValue }; const updated = await this.updateEmbeddedEntity("OwnedItem", update); // Updates one EmbeddedEntity } else { @@ -782,6 +784,7 @@ export class RdDActor extends Actor { async updateCompetenceArchetype(compName, compValue) { let comp = this.getCompetence(compName); if (comp) { + compValue = compValue ?? 0; const update = { _id: comp._id, 'data.niveau_archetype': compValue }; const updated = await this.updateEmbeddedEntity("OwnedItem", update); // Updates one EmbeddedEntity } else { @@ -1121,7 +1124,7 @@ export class RdDActor extends Actor { queue = await RdDRollTables.getOmbre(); let myReve = duplicate(this.data.data.reve.reve); myReve.thanatosused = false; - await this.update({ "data.reve.reve": myReve } ); + await this.update({ "data.reve.reve": myReve }); } else { queue = await RdDRollTables.getQueue(); @@ -1143,7 +1146,7 @@ export class RdDActor extends Actor { whisper: ChatUtility.getWhisperRecipientsAndGMs(game.user.name) }); const innaccessible = this.buildTMRInnaccessible(); - let tmr = TMRUtility.getTMRAleatoire(tmr => !innaccessible.includes(tmr.coord) ); + let tmr = TMRUtility.getTMRAleatoire(tmr => !innaccessible.includes(tmr.coord)); this.updateCoordTMR(tmr.coord); return tmr; } @@ -1218,8 +1221,8 @@ export class RdDActor extends Actor { let list = duplicate(this.data.data.reve.rencontre.list); let newList = []; for (let i = 0; i < list.length; i++) { - if ( i != rencontreKey) - newList.push( list[i]); + if (i != rencontreKey) + newList.push(list[i]); } await this.update({ "data.reve.rencontre.list": newList }); } @@ -1270,13 +1273,13 @@ export class RdDActor extends Actor { getSonneRound() { return !this.isEntiteCauchemar() && (this.data.data.sante.sonne?.round ?? false); } - + /* -------------------------------------------- */ - async verifierSonneRound( round ) { - if ( this.getSonne() ) { - if ( round >= this.getSonneRound() + 1) { - await this.setSonne( false, -1 ); // Nettoyer l'état sonné - ChatMessage.create( { content: `${this.name} n'est plus sonné ce round !`} ); + async verifierSonneRound(round) { + if (this.getSonne()) { + if (round >= this.getSonneRound() + 1) { + await this.setSonne(false, -1); // Nettoyer l'état sonné + ChatMessage.create({ content: `${this.name} n'est plus sonné ce round !` }); } } } @@ -1322,10 +1325,10 @@ export class RdDActor extends Actor { if (roll.total == 1) { let xp = Misc.toInt(this.data.data.carac.constitution.xp) + 1; this.update({ "data.carac.constitution.xp": xp }); // +1 XP ! - ChatMessage.create( { content: `${this.name} a obenu 1 sur son Jet d'Endurance et a gagné 1 point d'Expérience en Constitution. Ce point d'XP a été ajouté automatiquement).`}); + ChatMessage.create({ content: `${this.name} a obenu 1 sur son Jet d'Endurance et a gagné 1 point d'Expérience en Constitution. Ce point d'XP a été ajouté automatiquement).` }); } if (result.sonne) { - + await this.setSonne(); sante.sonne.value = true; } @@ -1700,15 +1703,15 @@ export class RdDActor extends Actor { action: r => this._appliquerAjoutExperience(r, game.settings.get("core", "rollMode") != 'blindroll') }; } - + /* -------------------------------------------- */ createCallbackAppelAuMoral() { /* Si l'appel au moral est utilisé, on l'affiche dans le chat et on diminue éventuellement le moral */ return { condition: r => r.use.appelAuMoral && game.settings.get("core", "rollMode") != 'selfroll', - action: r => { this.displayAppelAuMoral ; this._appliquerAppelMoral(r, game.settings.get("core", "rollMode") != 'blindroll') } + action: r => this._appliquerAppelMoral(r) }; } - + /* -------------------------------------------- */ async checkCaracXP(caracName) { let carac = this.data.data.carac[caracName]; @@ -1778,14 +1781,15 @@ export class RdDActor extends Actor { if (xpResult && xpResult.xpCarac > 0 && rollData.selectedCarac) { this.checkCaracXP(rollData.selectedCarac.name); } - } - + } + /* -------------------------------------------- */ async _appliquerAppelMoral(rollData, display = true) { if (!this.isPersonnage()) return; - if (!rollData.rolled.isEchec) return; - this.moralIncDec(-1); /* L'appel au moral a échoué. Le personnage perd un point de moral */ - rollData.jetEchouerMoralDiminuer = true; + if (rollData.rolled.isEchec || (rollData.rolled.roll * rollData.ajustements.diviseurSignificative > rollData.score)) { + this.moralIncDec(-1); /* L'appel au moral a échoué. Le personnage perd un point de moral */ + rollData.perteMoralEchec = true; + } } /* -------------------------------------------- */ @@ -1956,7 +1960,7 @@ export class RdDActor extends Actor { if (rollData.isSortReserve) { rollData.depenseReve++; } - if ( rollData.competence.name.includes('Thanatos')) { // Si Thanatos + if (rollData.competence.name.includes('Thanatos')) { // Si Thanatos myReve.thanatosused = true; } if (myReve.value > rollData.depenseReve) { @@ -2010,6 +2014,7 @@ export class RdDActor extends Actor { label: 'Jet ' + Grammar.apostrophe('de', rollData.selectedCarac.label), callbacks: [ this.createCallbackExperience(), + this.createCallbackAppelAuMoral(), { action: r => this._onRollCaracResult(r) } ] } @@ -2046,7 +2051,7 @@ export class RdDActor extends Actor { label: 'Jet ' + Grammar.apostrophe('de', name), callbacks: [ this.createCallbackExperience(), - this.createCallbackAppelAuMoral(), + this.createCallbackAppelAuMoral(), { action: r => this._competenceResult(r) } ] }); @@ -2093,6 +2098,7 @@ export class RdDActor extends Actor { label: 'Jet de Tâche ' + tache.name, callbacks: [ this.createCallbackExperience(), + this.createCallbackAppelAuMoral(), { condition: r => r.rolled.isETotal, action: r => this._tacheETotal(r) }, { action: r => this._tacheResult(r) } ] @@ -2128,7 +2134,7 @@ export class RdDActor extends Actor { selectedCarac: duplicate(this.data.data.carac[selected]) }); artData.competence.data.defaut_carac = selected; - if ( !artData.forceCarac ) { + if (!artData.forceCarac) { artData.forceCarac = {}; artData.forceCarac[selected] = duplicate(this.data.data.carac[selected]); } @@ -2141,6 +2147,7 @@ export class RdDActor extends Actor { height: 600, callbacks: [ this.createCallbackExperience(), + this.createCallbackAppelAuMoral(), { action: r => callBackResult(r) } ] }); @@ -2168,17 +2175,17 @@ export class RdDActor extends Actor { const artData = { art: 'danse', verbe: 'Danser', forceCarac: {} }; const oeuvre = duplicate(this.getOeuvre(id, artData.art)); const selectedCarac = this._getCaracDanse(oeuvre); - if ( oeuvre.data.agilite) { - artData.forceCarac['agilite'] = duplicate(this.data.data.carac.agilite ); + if (oeuvre.data.agilite) { + artData.forceCarac['agilite'] = duplicate(this.data.data.carac.agilite); } - if ( oeuvre.data.apparence) { - artData.forceCarac['apparence'] = duplicate(this.data.data.carac.apparence ); + if (oeuvre.data.apparence) { + artData.forceCarac['apparence'] = duplicate(this.data.data.carac.apparence); } await this._rollArt(artData, selectedCarac, oeuvre); } /* -------------------------------------------- */ - _getCaracDanse(oeuvre) { + _getCaracDanse(oeuvre) { if (oeuvre.data.agilite) { return "agilite"; } else if (oeuvre.data.apparence) { return "apparence"; } const competence = this.getCompetence(oeuvre.data.competence); @@ -2289,7 +2296,7 @@ export class RdDActor extends Actor { async rollAppelChance(onSuccess = () => { }, onEchec = () => { }) { // Stocke si utilisation de la chance await this.unsetFlag('foundryvtt-reve-de-dragon', 'utilisationChance'); - await this.setFlag('foundryvtt-reve-de-dragon', 'utilisationChance', true ); + await this.setFlag('foundryvtt-reve-de-dragon', 'utilisationChance', true); let rollData = { selectedCarac: this.getCaracByName('chance-actuelle'), surprise: '' }; const dialog = await RdDRoll.create(this, rollData, @@ -2556,10 +2563,12 @@ export class RdDActor extends Actor { } /* -------------------------------------------- */ - verifierForceMin( item ) { - if ( item.type == 'arme' && item.data.force > this.data.data.carac.force.value ) { - ChatMessage.create( { content: `${this.name} s'est équipé(e) de l'arme ${item.name}, mais n'a pas une force suffisante pour l'utiliser normalement - (${item.data.force} nécessaire pour une Force de ${this.data.data.carac.force.value})` } ); + verifierForceMin(item) { + if (item.type == 'arme' && item.data.force > this.data.data.carac.force.value) { + ChatMessage.create({ + content: `${this.name} s'est équipé(e) de l'arme ${item.name}, mais n'a pas une force suffisante pour l'utiliser normalement + (${item.data.force} nécessaire pour une Force de ${this.data.data.carac.force.value})` + }); } } @@ -2571,8 +2580,8 @@ export class RdDActor extends Actor { await this.updateEmbeddedEntity("OwnedItem", update); this.computeEncombrementTotalEtMalusArmure(); // Mise à jour encombrement this.computePrixTotalEquipement(); // Mis à jour du prix total de l'équipement - if ( item.data.data.equipe ) - this.verifierForceMin( item.data ); + if (item.data.data.equipe) + this.verifierForceMin(item.data); } } @@ -2593,10 +2602,10 @@ export class RdDActor extends Actor { protection = Math.max(protection - penetration, 0); protection += this.getProtectionNaturelle(); // Gestion des cas particuliers sur la fenêtre d'encaissement - if ( attackerRoll.dmg.encaisserSpecial && attackerRoll.dmg.encaisserSpecial == "noarmure") { + if (attackerRoll.dmg.encaisserSpecial && attackerRoll.dmg.encaisserSpecial == "noarmure") { protection = 0; } - if ( attackerRoll.dmg.encaisserSpecial && attackerRoll.dmg.encaisserSpecial == "chute" && Number(protection) > 2) { + if (attackerRoll.dmg.encaisserSpecial && attackerRoll.dmg.encaisserSpecial == "chute" && Number(protection) > 2) { protection = 2; } console.log("Final protect", protection, attackerRoll); @@ -2693,7 +2702,7 @@ export class RdDActor extends Actor { let encaissement = RdDUtility.selectEncaissement(jetTotal, rollData.dmg.mortalite) let over20 = Math.max(jetTotal - 20, 0); encaissement.dmg = rollData.dmg; - encaissement.dmg.loc = rollData.dmg.loc ?? RdDUtility.getLocalisation( this.data.type ); + encaissement.dmg.loc = rollData.dmg.loc ?? RdDUtility.getLocalisation(this.data.type); encaissement.dmg.loc.label = encaissement.dmg.loc.label ?? 'Corps;' encaissement.roll = roll; encaissement.armure = armure; @@ -2782,26 +2791,26 @@ export class RdDActor extends Actor { } /* -------------------------------------------- */ - async resetItemUse( ) { + async resetItemUse() { await this.unsetFlag('foundryvtt-reve-de-dragon', 'itemUse'); - await this.setFlag('foundryvtt-reve-de-dragon', 'itemUse', {} ); + await this.setFlag('foundryvtt-reve-de-dragon', 'itemUse', {}); } /* -------------------------------------------- */ - async incDecItemUse( itemId, inc = 1 ) { + async incDecItemUse(itemId, inc = 1) { let itemUse = duplicate(this.getFlag('foundryvtt-reve-de-dragon', 'itemUse') ?? {}); itemUse[itemId] = (itemUse[itemId] ?? 0) + inc; - await this.setFlag( 'foundryvtt-reve-de-dragon', 'itemUse', itemUse); + await this.setFlag('foundryvtt-reve-de-dragon', 'itemUse', itemUse); console.log("ITEM USE INC", inc, itemUse); } /* -------------------------------------------- */ - getItemUse( itemId ) { + getItemUse(itemId) { let itemUse = this.getFlag('foundryvtt-reve-de-dragon', 'itemUse') ?? {}; console.log("ITEM USE GET", itemUse); return itemUse[itemId] ?? 0; } - + /* -------------------------------------------- */ /* -- entites -- */ /* retourne true si on peut continuer, false si on ne peut pas continuer */ @@ -2977,6 +2986,7 @@ export class RdDActor extends Actor { label: 'Tache Alchimique', callbacks: [ this.createCallbackExperience(), + this.createCallbackAppelAuMoral(), { action: r => this._alchimieResult(r, false) } ] } @@ -3210,10 +3220,11 @@ export class RdDActor extends Actor { } } - notifyGestionTeteSouffleQueue(item, manualMessage=true){ + notifyGestionTeteSouffleQueue(item, manualMessage = true) { ChatMessage.create({ whisper: ChatUtility.getWhisperRecipientsAndGMs(game.user.name), - content: `${this.name} a reçu un/une ${item.type}: ${item.name}, qui ${manualMessage ? "n'est pas" : "est" } géré automatiquement. ${manualMessage ?? ''}` + content: `${this.name} a reçu un/une ${item.type}: ${item.name}, qui ${manualMessage ? "n'est pas" : "est"} géré automatiquement. ${manualMessage ?? ''}` }); - }} + } +} diff --git a/module/item-competence.js b/module/item-competence.js index deca47f1..2820001a 100644 --- a/module/item-competence.js +++ b/module/item-competence.js @@ -5,6 +5,18 @@ const competenceTroncs = [["Esquive", "Dague", "Corps à corps"], const competence_xp_par_niveau = [5, 5, 5, 10, 10, 10, 10, 15, 15, 15, 15, 20, 20, 20, 20, 30, 30, 40, 40, 60, 60, 100, 100, 100, 100, 100, 100, 100, 100, 100]; const competence_niveau_max = competence_xp_par_niveau.length - 10; +/* -------------------------------------------- */ +const categorieCompetences = { + "generale": { level: "-4", label: "Générales" }, + "particuliere": { level: "-8", label: "Particulières" }, + "specialisee": { level: "-11", label: "Spécialisées" }, + "connaissance": { level: "-11", label: "Connaissances" }, + "draconic": { level: "-11", label: "Draconics" }, + "melee": { level: "-6", label: "Mêlée" }, + "tir": { level: "-8", label: "Tir" }, + "lancer": { level: "-8", label: "Lancer" } +} + function _buildCumulXP() { let cumulXP = { "-11": 0 }; let cumul = 0; @@ -20,6 +32,16 @@ const competence_xp_cumul = _buildCumulXP(); export class RdDItemCompetence extends Item { + static getCategorieCompetences() { + return categorieCompetences; + } + static getLevelCategory(category) { + return categorieCompetences[category].level; + } + static getLabelCategory(category) { + return categorieCompetences[category].label; + } + /* -------------------------------------------- */ static isCompetenceArme(competence) { switch (competence.data.categorie) { diff --git a/module/item-sheet.js b/module/item-sheet.js index f70e3483..2d1bfdf6 100644 --- a/module/item-sheet.js +++ b/module/item-sheet.js @@ -48,7 +48,7 @@ export class RdDItemSheet extends ItemSheet { /* -------------------------------------------- */ async getData() { let data = super.getData(); - data.categorieCompetences = RdDUtility.getCategorieCompetences(); + data.categorieCompetences = RdDItemCompetence.getCategorieCompetences(); if ( data.item.type == 'tache' || data.item.type == 'livre' || data.item.type == 'meditation' || data.item.type == 'oeuvre') { data.caracList = duplicate(game.system.model.Actor.personnage.carac); data.competences = await RdDUtility.loadCompendiumNames( 'foundryvtt-reve-de-dragon.competences' ); @@ -111,7 +111,7 @@ export class RdDItemSheet extends ItemSheet { async _onClickSelectCategorie(event) { event.preventDefault(); - let level = RdDUtility.getLevelCategory(event.currentTarget.value); + let level = RdDItemCompetence.getLevelCategory(event.currentTarget.value); this.object.data.data.base = level; $("#base").val( level ); } diff --git a/module/rdd-combat.js b/module/rdd-combat.js index b338adb1..db85f5c1 100644 --- a/module/rdd-combat.js +++ b/module/rdd-combat.js @@ -700,6 +700,7 @@ export class RdDCombat { label: 'Attaque: ' + (arme?.name ?? competence.name), callbacks: [ this.attacker.createCallbackExperience(), + this.attacker.createCallbackAppelAuMoral(), { action: r => this.removeChatMessageActionsPasseArme(r.passeArme) }, { condition: r => arme && !RdDCombat.isParticuliere(r), action: r => this.attacker.incDecItemUse(arme._id) }, { condition: r => (RdDCombat.isReussite(r) && !RdDCombat.isParticuliere(r)), action: r => this._onAttaqueNormale(r) }, @@ -936,6 +937,7 @@ export class RdDCombat { label: 'Parade: ' + (arme ? arme.name : rollData.competence.name), callbacks: [ this.defender.createCallbackExperience(), + this.defender.createCallbackAppelAuMoral(), { action: r => this.removeChatMessageActionsPasseArme(r.passeArme) }, { condition: r => !RdDCombat.isParticuliere(r), action: r => this.defender.incDecItemUse(armeParadeId) }, { condition: RdDCombat.isReussite, action: r => this._onParadeNormale(r) }, @@ -1039,6 +1041,7 @@ export class RdDCombat { label: 'Esquiver', callbacks: [ this.defender.createCallbackExperience(), + this.defender.createCallbackAppelAuMoral(), { condition: r => !RdDCombat.isParticuliere(r), action: r => this.defender.incDecItemUse(esquive._id) }, { action: r => this.removeChatMessageActionsPasseArme(r.passeArme) }, { condition: RdDCombat.isReussite, action: r => this._onEsquiveNormale(r) }, diff --git a/module/rdd-roll.js b/module/rdd-roll.js index 079fc277..fb25994d 100644 --- a/module/rdd-roll.js +++ b/module/rdd-roll.js @@ -54,7 +54,7 @@ export class RdDRoll extends Dialog { useMalusSurenc: false, appelAuMoralPossible : false, /* Est-ce que l'appel au moral est possible ? Variable utisé pour l'affichage ou non de la ligne concernant le moral */ appelAuMoralDemander :false, /* Est-ce que le joueur demande d'utiliser le moral ? Utile si le joueur change plusieurs fois de carac associée. */ - jetEchouerMoralDiminuer : false, /* Pour l'affichage dans le chat */ + perteMoralEchec : false, /* Pour l'affichage dans le chat */ use: { libre: true, conditions: true, surenc: false, encTotal: false, appelAuMoral : false /* Le jet se fait ou non en utilisant l'appel au moral */}, isMalusEncombrementTotal: RdDItemCompetence.isMalusEncombrementTotal(rollData.competence), useMalusEncTotal: false, diff --git a/module/rdd-utility.js b/module/rdd-utility.js index 482b829d..d9cfa1e0 100644 --- a/module/rdd-utility.js +++ b/module/rdd-utility.js @@ -1,27 +1,10 @@ /* Common useful functions shared between objects */ -import { RdDRollTables } from "./rdd-rolltables.js"; import { ChatUtility } from "./chat-utility.js"; -import { RdDCombat, RdDCombatManager } from "./rdd-combat.js"; -import { RdDRollResolutionTable } from "./rdd-roll-resolution-table.js"; -import { RdDItemCompetenceCreature } from "./item-competencecreature.js"; -import { RdDItemArme } from "./item-arme.js"; -import { RdDItemCompetence } from "./item-competence.js"; +import { RdDCombat } from "./rdd-combat.js"; import { Misc } from "./misc.js"; import { Grammar } from "./grammar.js"; -/* -------------------------------------------- */ -const categorieCompetences = { - "generale": { level: "-4", label: "Générales" }, - "particuliere": { level: "-8", label: "Particulières" }, - "specialisee": { level: "-11", label: "Spécialisées" }, - "connaissance": { level: "-11", label: "Connaissances" }, - "draconic": { level: "-11", label: "Draconics" }, - "melee": { level: "-6", label: "Mêlée" }, - "tir": { level: "-8", label: "Tir" }, - "lancer": { level: "-8", label: "Lancer" } -} - /* -------------------------------------------- */ const limitesArchetypes = [ { "niveau": 0, "nombreMax": 100, "nombre": 0 }, @@ -403,15 +386,6 @@ export class RdDUtility { } /* -------------------------------------------- */ - static getCategorieCompetences() { - return categorieCompetences; - } - static getLevelCategory(category) { - return categorieCompetences[category].level; - } - static getLabelCategory(category) { - return categorieCompetences[category].label; - } static getCaracArray() { return carac_array; } diff --git a/system.json b/system.json index 866aa97b..152c8cfe 100644 --- a/system.json +++ b/system.json @@ -2,7 +2,7 @@ "name": "foundryvtt-reve-de-dragon", "title": "Rêve de Dragon", "description": "Rêve de Dragon RPG for FoundryVTT", - "version": "1.3.32", + "version": "1.3.33", "manifestPlusVersion": "1.0.0", "minimumCoreVersion": "0.7.5", "compatibleCoreVersion": "0.7.9", diff --git a/templates/chat-info-appel-au-moral.html b/templates/chat-info-appel-au-moral.html index df0f2282..fceb6eff 100644 --- a/templates/chat-info-appel-au-moral.html +++ b/templates/chat-info-appel-au-moral.html @@ -1,4 +1,8 @@ -{{#if use.appelAuMoral}}
- {{alias}} fait appel {{#if (gt moral 0)}}au moral{{else}}à l'énergie du déspoir{{/if}} {{#if jetEchouerMoralDiminuer}}et échoue, diminuant son moral.{{else}} et réussit.{{/if}} - {{^jetEchouerMoralDiminuer}} Son moral reste inchangé à {{moral}}.{{/jetEchouerMoralDiminuer}} -
{{/if}} +{{#if use.appelAuMoral}} + + Vous avez fait appel {{#if (gt moral 0)}}au moral{{else}}à l'énergie du déspoir{{/if}} + {{#if perteMoralEchec}}et échoué, votre moral baisse à {{moral}}. + {{else}}et réussi, votre moral reste de {{moral}}. + {{/if}} + +{{/if}} diff --git a/templates/chat-resultat-alchimie.html b/templates/chat-resultat-alchimie.html index 38273c82..e76696fe 100644 --- a/templates/chat-resultat-alchimie.html +++ b/templates/chat-resultat-alchimie.html @@ -10,4 +10,5 @@ {{else}} {{alias}} a raté son opération alchimique ! Sa recette est un echec. {{/if}} + {{> "systems/foundryvtt-reve-de-dragon/templates/chat-info-appel-au-moral.html"}}
diff --git a/templates/chat-resultat-attaque.html b/templates/chat-resultat-attaque.html index 3f3ed617..5c29754e 100644 --- a/templates/chat-resultat-attaque.html +++ b/templates/chat-resultat-attaque.html @@ -17,25 +17,24 @@
{{/if}}
- {{#if rolled.isSuccess}} - {{show.cible}} doit se défendre à {{diffLibre}}, ou encaisser à - {{~#if (eq dmg.mortalite 'non-mortel')}} - ({{numberFormat dmg.total decimals=0 sign=true}}) (dommages non-mortel) - {{else if (eq dmg.mortalite 'mortel')}} - {{numberFormat dmg.total decimals=0 sign=true}} - {{else}} - {{numberFormat dmg.total decimals=0 sign=true}} (entités de cauchemar) - {{~/if}}. - {{#if show.isRecul}}Si votre adversaire n'esquive pas, il devra résister à l'impact ou reculer sous le choc!{{/if}} - -
+ {{#if rolled.isSuccess}} + {{show.cible}} doit se défendre à {{diffLibre}}, ou encaisser à + {{~#if (eq dmg.mortalite 'non-mortel')}} + ({{numberFormat dmg.total decimals=0 sign=true}}) (dommages non-mortel) + {{else if (eq dmg.mortalite 'mortel')}} + {{numberFormat dmg.total decimals=0 sign=true}} + {{else}} + {{numberFormat dmg.total decimals=0 sign=true}} (entités de cauchemar) + {{~/if}}. + {{#if show.isRecul}}Si votre adversaire n'esquive pas, il devra résister à l'impact ou reculer sous le choc!{{/if}} + {{#if (eq particuliere 'rapidite')}} -

Votre attaque rapide vous permet une deuxième attaque, ou défense supplémentaire!
{{/if}} - {{else}} - Votre attaque a échoué! - {{/if}} +{{else}} + Votre attaque a échoué! +{{/if}} +{{> "systems/foundryvtt-reve-de-dragon/templates/chat-info-appel-au-moral.html"}}
\ No newline at end of file diff --git a/templates/chat-resultat-chant.html b/templates/chat-resultat-chant.html index 6af6e9d6..4ebcacbc 100644 --- a/templates/chat-resultat-chant.html +++ b/templates/chat-resultat-chant.html @@ -10,5 +10,6 @@ {{else}} {{alias}} est peu inspiré(e) et son interprétation a une qualité de {{qualiteFinale}}. {{/if}} + {{> "systems/foundryvtt-reve-de-dragon/templates/chat-info-appel-au-moral.html"}} {{> "systems/foundryvtt-reve-de-dragon/templates/chat-poesie.html" oeuvre.data}} diff --git a/templates/chat-resultat-danse.html b/templates/chat-resultat-danse.html index 9d12528b..50a5cc2c 100644 --- a/templates/chat-resultat-danse.html +++ b/templates/chat-resultat-danse.html @@ -10,5 +10,6 @@ {{else}} {{alias}} est peu inspiré(e) et son interprétation a une qualité de {{qualiteFinale}}. {{/if}} + {{> "systems/foundryvtt-reve-de-dragon/templates/chat-info-appel-au-moral.html"}} {{> "systems/foundryvtt-reve-de-dragon/templates/chat-poesie.html" oeuvre.data}} diff --git a/templates/chat-resultat-encaissement.html b/templates/chat-resultat-encaissement.html index 86fa9811..8e1621f6 100644 --- a/templates/chat-resultat-encaissement.html +++ b/templates/chat-resultat-encaissement.html @@ -4,7 +4,8 @@ De plus, {{alias}} a perdu {{endurance}} points d'endurance {{#if (ne vie 0)}}et {{vie}} points de vie{{/if}} {{/if}} - + {{#if (gt endurance 1)}}Jet d'endurance : {{jetEndurance}} / {{resteEndurance}} {{/if}} + {{else}}

{{alias}} encaisse à @@ -36,8 +37,8 @@ {{/if}} {{#if (ne dmg.mortalite 'cauchemar')}} {{#if (gt endurance 1)}}et - {{#if sonne}}est sonnécharge jusqu'à la fin du prochain round{{else}}n'est pas sonné{{/if}} - ({{jetEndurance}} / {{resteEndurance}})! + {{#if sonne}}est sonnécharge jusqu'à la fin du prochain round{{else}}n'est pas sonné{{/if}}! + {{#if hasPlayerOwner}}Jet d'endurance : Jet d'endurance : {{jetEndurance}} / {{resteEndurance}}{{/if}} {{/if}} {{/if}} {{/if}} diff --git a/templates/chat-resultat-esquive.html b/templates/chat-resultat-esquive.html index e6aab0f0..9d350499 100644 --- a/templates/chat-resultat-esquive.html +++ b/templates/chat-resultat-esquive.html @@ -13,6 +13,7 @@ {{else}} Votre esquive a échoué! {{/if}} + {{> "systems/foundryvtt-reve-de-dragon/templates/chat-info-appel-au-moral.html"}} {{#if attackerRoll.tactique}} diff --git a/templates/chat-resultat-general.html b/templates/chat-resultat-general.html index 2bc62cb6..830c7e4f 100644 --- a/templates/chat-resultat-general.html +++ b/templates/chat-resultat-general.html @@ -12,6 +12,7 @@
{{#if rolled.ptTache}}{{rolled.ptTache}} points de tâche{{/if}}{{#if rolled.ptQualite}}{{#if rolled.ptTache}},{{/if}} ajustement Qualité {{numberFormat rolled.ptQualite decimals=0 sign=true}}{{/if}} + {{> "systems/foundryvtt-reve-de-dragon/templates/chat-info-appel-au-moral.html"}}
{{~#if show.explications}}
diff --git a/templates/chat-resultat-jeu.html b/templates/chat-resultat-jeu.html index 6b8c01f3..2dc5247e 100644 --- a/templates/chat-resultat-jeu.html +++ b/templates/chat-resultat-jeu.html @@ -10,5 +10,6 @@ {{else}} {{alias}} a perdu ... {{/if}} + {{> "systems/foundryvtt-reve-de-dragon/templates/chat-info-appel-au-moral.html"}}
{{> "systems/foundryvtt-reve-de-dragon/templates/chat-poesie.html" oeuvre.data}} diff --git a/templates/chat-resultat-musique.html b/templates/chat-resultat-musique.html index 0b0a6d0b..eaf9096d 100644 --- a/templates/chat-resultat-musique.html +++ b/templates/chat-resultat-musique.html @@ -10,5 +10,6 @@ {{else}} {{alias}} est peu inspiré(e) et son interprétation a une qualité de {{qualiteFinale}}. {{/if}} + {{> "systems/foundryvtt-reve-de-dragon/templates/chat-info-appel-au-moral.html"}} {{> "systems/foundryvtt-reve-de-dragon/templates/chat-poesie.html" oeuvre.data}} diff --git a/templates/chat-resultat-oeuvre.html b/templates/chat-resultat-oeuvre.html index d7e349e5..447f7897 100644 --- a/templates/chat-resultat-oeuvre.html +++ b/templates/chat-resultat-oeuvre.html @@ -11,5 +11,6 @@ {{else}} {{alias}} est peu inspiré(e) et son interprétation a une qualité de {{qualiteFinale}}. {{/if}} + {{> "systems/foundryvtt-reve-de-dragon/templates/chat-info-appel-au-moral.html"}} {{> "systems/foundryvtt-reve-de-dragon/templates/chat-poesie.html" oeuvre.data}} diff --git a/templates/chat-resultat-parade.html b/templates/chat-resultat-parade.html index e6638f0e..2bc336a5 100644 --- a/templates/chat-resultat-parade.html +++ b/templates/chat-resultat-parade.html @@ -12,6 +12,7 @@ La parade a échoué! {{/if}}
+ {{> "systems/foundryvtt-reve-de-dragon/templates/chat-info-appel-au-moral.html"}} {{#if (eq show.recul 'encaisse')}}
{{alias}} ne recule pas malgré la violence du coup.
diff --git a/templates/chat-resultat-recettecuisine.html b/templates/chat-resultat-recettecuisine.html index 5eb098fd..f775caf3 100644 --- a/templates/chat-resultat-recettecuisine.html +++ b/templates/chat-resultat-recettecuisine.html @@ -4,16 +4,18 @@

{{> "systems/foundryvtt-reve-de-dragon/templates/chat-infojet.html"}}
- -{{#if rolled.isSuccess}} + + {{#if rolled.isSuccess}} {{alias}} réussit sa recette, avec un plat de qualité {{qualiteFinale}} pour {{oeuvre.data.sust}} Points de Sustentation. -{{else}} + {{else}} {{alias}} fait un piètre cuisinier(e), et obtient {{#if (lt qualiteFinale 0)}}un plat à l'exotisme certain{{else}}un plat de qualité {{qualiteFinale}}{{/if}}. Selon la décision du MJ, le plat peut fournir {{oeuvre.data.sust}} Points de Sustentation -{{/if}} - -{{#if (lt exotismeFinal 0)}} -
Au vu de l'exotisme du plat, les convives devront réussir un jet de Volonté / Cuisine à {{exotismeFinal}}. -En cas d'échec, ils peuvent se forcer pour faire plaisir au Maître Queux, mais devront faire un jet de moral Malheureux. -{{/if}} + {{/if}} + + {{#if (lt exotismeFinal 0)}} +
Au vu de l'exotisme du plat, les convives devront réussir un jet de Volonté / Cuisine à {{exotismeFinal}}. + En cas d'échec, ils peuvent se forcer pour faire plaisir au Maître Queux, mais devront faire un jet de moral Malheureux. + {{/if}} +
+{{> "systems/foundryvtt-reve-de-dragon/templates/chat-info-appel-au-moral.html"}} {{> "systems/foundryvtt-reve-de-dragon/templates/chat-poesie.html" oeuvre.data}} diff --git a/templates/chat-resultat-tache.html b/templates/chat-resultat-tache.html index b9792039..a5049bed 100644 --- a/templates/chat-resultat-tache.html +++ b/templates/chat-resultat-tache.html @@ -10,4 +10,5 @@ votre avancement est de {{tache.data.points_de_tache_courant}} sur {{tache.data.points_de_tache}} point{{~#if (gt tache.data.points_de_tache_courant 1)}}s{{/if}} de tâche. {{#if tache.data.fatigue}}
Vous vous êtes fatigué de {{tache.data.fatigue}} case{{~#if (gt tache.data.fatigue 1)}}s{{/if}}.{{/if}} {{#if rolled.isETotal}}
Votre échec total augmente de 1 la difficulté de la tâche!{{/if~}} + {{> "systems/foundryvtt-reve-de-dragon/templates/chat-info-appel-au-moral.html"}}