diff --git a/module/actor-creature-sheet.js b/module/actor-creature-sheet.js index d8187818..47f5d3b7 100644 --- a/module/actor-creature-sheet.js +++ b/module/actor-creature-sheet.js @@ -40,11 +40,4 @@ export class RdDActorCreatureSheet extends RdDActorSheet { this.actor.updateCreatureCompetence(compName, "dommages", parseInt(event.target.value)); }); } - - /* -------------------------------------------- */ - /** @override */ - _updateObject(event, formData) { - // Update the Actor - return this.object.update(formData); - } } diff --git a/module/actor-sheet.js b/module/actor-sheet.js index 0108d369..b735fda4 100644 --- a/module/actor-sheet.js +++ b/module/actor-sheet.js @@ -12,13 +12,15 @@ import { RdDSheetUtility } from "./rdd-sheet-utility.js"; import { STATUSES } from "./settings/status-effects.js"; import { Monnaie } from "./item-monnaie.js"; import { MAINS_DIRECTRICES } from "./actor.js"; +import { RdDBaseActorSheet } from "./actor/base-actor-sheet.js"; +import { RdDItem } from "./item.js"; /* -------------------------------------------- */ /** * Extend the basic ActorSheet with some very simple modifications * @extends {ActorSheet} */ -export class RdDActorSheet extends ActorSheet { +export class RdDActorSheet extends RdDBaseActorSheet { /** @override */ static get defaultOptions() { @@ -36,42 +38,28 @@ export class RdDActorSheet extends ActorSheet { /* -------------------------------------------- */ async getData() { + let formData = await super.getData(); + mergeObject(formData, + { + editable: this.isEditable, + cssClass: this.isEditable ? "editable" : "locked", + effects: this.actor.effects.map(e => foundry.utils.deepClone(e)), + limited: this.actor.limited, + owner: this.actor.isOwner, + description: await TextEditor.enrichHTML(this.object.system.description, { async: true }), + biographie: await TextEditor.enrichHTML(this.object.system.biographie, { async: true }), + notes: await TextEditor.enrichHTML(this.object.system.notes, { async: true }), + notesmj: await TextEditor.enrichHTML(this.object.system.notesmj, { async: true }), + }); + mergeObject(formData.calc, { + surenc: this.actor.computeMalusSurEncombrement(), + surprise: RdDBonus.find(this.actor.getSurprise(false)).descr, + resumeBlessures: this.actor.computeResumeBlessure(this.actor.system.blessures), + caracTotal: RdDCarac.computeTotal(this.actor.system.carac, this.actor.system.beaute), + surEncombrementMessage: this.actor.getMessageSurEncombrement(), + }) + this.timerRecherche = undefined; - this.actor.computeEtatGeneral(); - - let formData = { - title: this.title, - id: this.actor.id, - type: this.actor.type, - img: this.actor.img, - name: this.actor.name, - editable: this.isEditable, - cssClass: this.isEditable ? "editable" : "locked", - system: foundry.utils.deepClone(this.actor.system), - effects: this.actor.effects.map(e => foundry.utils.deepClone(e)), - limited: this.actor.limited, - options: this.options, - owner: this.actor.isOwner, - description: await TextEditor.enrichHTML(this.object.system.description, { async: true }), - biographie: await TextEditor.enrichHTML(this.object.system.biographie, { async: true }), - notes: await TextEditor.enrichHTML(this.object.system.notes, { async: true }), - notesmj: await TextEditor.enrichHTML(this.object.system.notesmj, { async: true }), - calc: { - fortune: Monnaie.getFortuneSolsDeniers(this.actor), - encTotal: await this.actor.computeEncombrementTotalEtMalusArmure(), - surenc: this.actor.computeMalusSurEncombrement(), - prixTotalEquipement: this.actor.computePrixTotalEquipement(), - surprise: RdDBonus.find(this.actor.getSurprise(false)).descr, - resumeBlessures: this.actor.computeResumeBlessure(this.actor.system.blessures), - caracTotal: RdDCarac.computeTotal(this.actor.system.carac, this.actor.system.beaute), - surEncombrementMessage: this.actor.getMessageSurEncombrement(), - }, - } - formData.options.isGM = game.user.isGM; - - RdDUtility.filterItemsPerTypeForSheet(formData, this.actor.itemTypes); - this.objetVersConteneur = RdDUtility.buildArbreDeConteneurs(formData.conteneurs, formData.objets); - formData.conteneurs = RdDUtility.conteneursRacine(formData.conteneurs); if (formData.type == 'personnage') { formData.options.mainsDirectrices = MAINS_DIRECTRICES; @@ -125,22 +113,14 @@ export class RdDActorSheet extends ActorSheet { /* -------------------------------------------- */ /** @override */ activateListeners(html) { super.activateListeners(html); - this.html = html; HtmlUtility._showControlWhen(this.html.find(".appliquerFatigue"), ReglesOptionelles.isUsing("appliquer-fatigue")); // Everything below here is only needed if the sheet is editable if (!this.options.editable) return; - this.html.find('.item-split').click(async event => { - const item = RdDSheetUtility.getItem(event, this.actor); - RdDSheetUtility.splitItem(item, this.actor); - }); - this.html.find('.item-edit').click(async event => RdDSheetUtility.getItem(event, this.actor)?.sheet.render(true)) - this.html.find('.item-delete').click(async event => RdDUtility.confirmActorItemDelete(this, RdDSheetUtility.getItem(event, this.actor))); - this.html.find('.item-vendre').click(async event => RdDSheetUtility.getItem(event, this.actor)?.proposerVente()); - this.html.find('.item-montrer').click(async event => RdDSheetUtility.getItem(event, this.actor)?.postItem()); this.html.find('.item-action').click(async event => RdDSheetUtility.getItem(event, this.actor)?.actionPrincipale(this.actor)); + this.html.find('.subacteur-delete').click(async event => { const li = RdDSheetUtility.getEventElement(event); const actorId = li.data("actor-id"); @@ -174,14 +154,8 @@ export class RdDActorSheet extends ActorSheet { this.html.find('.creer-tache').click(async event => { this.createEmptyTache(); }); - this.html.find('.creer-un-objet').click(async event => { - RdDUtility.selectObjetType(this); - }); this.html.find('.creer-une-oeuvre').click(async event => { - RdDUtility.selectTypeOeuvre(this); - }); - this.html.find('.nettoyer-conteneurs').click(async event => { - this.actor.nettoyerConteneurs(); + this.selectTypeOeuvreToCreate(); }); // Blessure control @@ -325,10 +299,6 @@ export class RdDActorSheet extends ActorSheet { await this.actor.removeEffects(); } }); - this.html.find('.conteneur-name a').click(async event => { - RdDUtility.toggleAfficheContenu(RdDSheetUtility.getItemId(event)); - this.render(true); - }); this.html.find('.carac-xp-augmenter').click(async event => { let caracName = event.currentTarget.name.replace("augmenter.", ""); this.actor.updateCaracXPAuto(caracName); @@ -418,19 +388,12 @@ export class RdDActorSheet extends ActorSheet { this.actor.setPointsDeSeuil(event.currentTarget.value); }); - this.html.find('#attribut-protection-edit').change(async event => { - this.actor.updateAttributeValue(event.currentTarget.attributes.name.value, parseInt(event.target.value)); - }); - // On stress change this.html.find('.compteur-edit').change(async event => { let fieldName = event.currentTarget.attributes.name.value; this.actor.updateCompteurValue(fieldName, parseInt(event.target.value)); }); - this.html.find('#ethylisme').change(async event => { - this.actor.setEthylisme(parseInt(event.target.value)); - }); this.html.find('.stress-test').click(async event => { this.actor.transformerStress(); }); @@ -454,13 +417,6 @@ export class RdDActorSheet extends ActorSheet { this.actor.jetEndurance(); }); - this.html.find('.monnaie-plus').click(async event => { - this.actor.monnaieIncDec(RdDSheetUtility.getItemId(event), 1); - }); - this.html.find('.monnaie-moins').click(async event => { - this.actor.monnaieIncDec(RdDSheetUtility.getItemId(event), -1); - }); - this.html.find('.vie-plus').click(async event => { this.actor.santeIncDec("vie", 1); }); @@ -499,25 +455,30 @@ export class RdDActorSheet extends ActorSheet { } /* -------------------------------------------- */ - async _onDropItem(event, dragData) { - const destItemId = this.html.find(event.target)?.closest('.item').attr('data-item-id') - const dropParams = RdDSheetUtility.prepareItemDropParameters(destItemId, this.actor, dragData, this.objetVersConteneur) - if (dropParams) { - const callSuper = await this.actor.processDropItem(dropParams) - if (callSuper) { - await super._onDropItem(event, dragData) - } + async selectTypeOeuvreToCreate() { + let typeObjets = RdDItem.getTypesOeuvres(); + let content = `Selectionnez le type d'oeuvre'; + let dialog = new Dialog({ + title: "Créer une oeuvre", + content: content, + buttons: { + create: { + icon: '', + label: "Créer l'oeuvre", + callback: () => this.actor.createItem($(".item-type").val()) + } + } + }); + dialog.render(true); } /* -------------------------------------------- */ async createEmptyTache() { - await this.createItem('Nouvelle tache', 'tache'); + await this.actor.createItem('tache', 'Nouvelle tache'); } _optionRecherche(target) { diff --git a/module/actor.js b/module/actor.js index e3a955ee..f532d894 100644 --- a/module/actor.js +++ b/module/actor.js @@ -34,9 +34,9 @@ import { ENTITE_BLURETTE, ENTITE_INCARNE, ENTITE_NONINCARNE, HIDE_DICE, SHOW_DIC import { RdDConfirm } from "./rdd-confirm.js"; import { DialogValidationEncaissement } from "./dialog-validation-encaissement.js"; import { RdDRencontre } from "./item-rencontre.js"; -import { SystemCompendiums } from "./settings/system-compendiums.js"; import { Targets } from "./targets.js"; import { DialogRepos } from "./dialog-repos.js"; +import { RdDBaseActor } from "./actor/base-actor.js"; const POSSESSION_SANS_DRACONIC = { img: 'systems/foundryvtt-reve-de-dragon/icons/entites/possession.webp', @@ -56,88 +56,7 @@ export const MAINS_DIRECTRICES = ['Droitier', 'Gaucher', 'Ambidextre'] * Extend the base Actor entity by defining a custom roll data structure which is ideal for the Simple system. * @extends {Actor} */ -export class RdDActor extends Actor { - /* -------------------------------------------- */ - static init() { - Hooks.on("preUpdateItem", (item, change, options, id) => RdDActor.getParentActor(item)?.onPreUpdateItem(item, change, options, id)); - // TODO: replace with pre-hooks? - Hooks.on("createItem", (item, options, id) => RdDActor.getParentActor(item)?.onCreateItem(item, options, id)); - Hooks.on("deleteItem", (item, options, id) => RdDActor.getParentActor(item)?.onDeleteItem(item, options, id)); - Hooks.on("updateActor", (actor, change, options, actorId) => actor.onUpdateActor(change, options, actorId)); - } - - static onSocketMessage(sockmsg) { - switch (sockmsg.msg) { - case "msg_remote_actor_call": - return RdDActor.onRemoteActorCall(sockmsg.data, sockmsg.userId); - case "msg_reset_nombre_astral": - console.log("RESET ASTRAL", game.user.character); - game.user.character.resetNombreAstral(); - return; - } - } - - static remoteActorCall(callData, userId = undefined) { - userId = userId ?? Misc.firstConnectedGMId(); - if (userId == game.user.id) { - RdDActor.onRemoteActorCall(callData, userId); - return false; - } - else { - game.socket.emit(SYSTEM_SOCKET_ID, { msg: "msg_remote_actor_call", data: callData, userId: userId }); - return true; - } - } - - static onRemoteActorCall(callData, userId) { - if (userId == game.user.id) { - const actor = game.actors.get(callData?.actorId); - 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(`RdDActor.onRemoteActorCall: pour l'Actor ${callData.actorId}, appel de RdDActor.${callData.method}(`, ...args, ')'); - actor[callData.method](...args); - } - } - } - - /* -------------------------------------------- */ - static getParentActor(document) { - return document?.parent instanceof Actor ? document.parent : undefined - } - - /* -------------------------------------------- */ - /** - * Override the create() function to provide additional RdD functionality. - * - * This overrided create() function adds initial items - * Namely: Basic skills, money, - * - * @param {Object} actorData Barebones actor template data which this function adds onto. - * @param {Object} options Additional options which customize the creation workflow. - * - */ - static async create(actorData, options) { - // Case of compendium global import - if (actorData instanceof Array) { - return super.create(actorData, options); - } - - const isPersonnage = actorData.type == "personnage"; - // If the created actor has items (only applicable to duplicated actors) bypass the new actor creation logic - if (actorData.items) { - return await super.create(actorData, options); - } - - if (isPersonnage) { - const competences = await SystemCompendiums.getCompetences(actorData.type); - actorData.items = competences.map(i => i.toObject()) - .concat(Monnaie.monnaiesStandard()); - } - else { - actorData.items = []; - } - return super.create(actorData, options); - } +export class RdDActor extends RdDBaseActor { /* -------------------------------------------- */ prepareData() { @@ -145,6 +64,8 @@ export class RdDActor extends Actor { // Dynamic computing fields this.encTotal = 0; + // TODO: separate derived/base data preparation + // TODO: split by actor class // Make separate methods for each Actor type (character, npc, etc.) to keep // things organized. @@ -178,9 +99,9 @@ export class RdDActor extends Actor { /* -------------------------------------------- */ async cleanupConteneurs() { - let updates = this.listItemsData('conteneur') - .filter(c => c.system.contenu.filter(id => this.getObjet(id) == undefined).length > 0) - .map(c => { return { _id: c._id, 'system.contenu': c.system.contenu.filter(id => this.getObjet(id) != undefined) } }); + let updates = this.listItems('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) } }); if (updates.length > 0) { await this.updateEmbeddedDocuments("Item", updates) } @@ -206,23 +127,6 @@ export class RdDActor extends Actor { return false; } - /* -------------------------------------------- */ - isCreatureEntite() { - return this.type == 'creature' || this.type == 'entite'; - } - isCreature() { - return this.type == 'creature'; - } - isEntite() { - return this.type == 'entite'; - } - /* -------------------------------------------- */ - isPersonnage() { - return this.type == 'personnage'; - } - isVehicule() { - return this.type == 'vehicule'; - } /* -------------------------------------------- */ isHautRevant() { return this.isPersonnage() && this.system.attributs.hautrevant.value != "" @@ -330,50 +234,33 @@ export class RdDActor extends Actor { } /* -------------------------------------------- */ - getObjet(id) { - return this.getEmbeddedDocument('Item', id); - } - - listItemsData(type) { - return this.itemTypes[type]; - } - - filterItems(filter) { - return this.items.filter(filter); - } - - getItemOfType(idOrName, type) { - return this.items.find(it => it.id == idOrName && it.type == type) - ?? Misc.findFirstLike(idOrName, this.items, { filter: it => it.type == type, description: type }); - } - getMonnaie(id) { - return this.getItemOfType(id, 'monnaie'); + return this.findItemLike(id, 'monnaie'); } getTache(id) { - return this.getItemOfType(id, 'tache'); + return this.findItemLike(id, 'tache'); } getMeditation(id) { - return this.getItemOfType(id, 'meditation'); + return this.findItemLike(id, 'meditation'); } getChant(id) { - return this.getItemOfType(id, 'chant'); + return this.findItemLike(id, 'chant'); } getDanse(id) { - return this.getItemOfType(id, 'danse'); + return this.findItemLike(id, 'danse'); } getMusique(id) { - return this.getItemOfType(id, 'musique'); + return this.findItemLike(id, 'musique'); } getOeuvre(id, type = 'oeuvre') { - return this.getItemOfType(id, type); + return this.findItemLike(id, type); } getJeu(id) { - return this.getItemOfType(id, 'jeu'); + return this.findItemLike(id, 'jeu'); } getRecetteCuisine(id) { - return this.getItemOfType(id, 'recettecuisine'); + return this.findItemLike(id, 'recettecuisine'); } /* -------------------------------------------- */ getDraconicList() { @@ -476,6 +363,7 @@ export class RdDActor extends Actor { ); dialog.render(true); } + async repos() { await DialogRepos.create(this); } @@ -1109,7 +997,7 @@ export class RdDActor extends Actor { _isConteneurContenu(item, conteneur) { if (item?.isConteneur()) { // Si c'est un conteneur, il faut vérifier qu'on ne le déplace pas vers un sous-conteneur lui appartenant for (let id of item.system.contenu) { - let subObjet = this.getObjet(id); + let subObjet = this.getItem(id); if (subObjet?.id == conteneur.id) { return true; // Loop detected ! } @@ -1130,17 +1018,17 @@ export class RdDActor extends Actor { if (objet.type != 'conteneur') { return Number(tplData.encombrement) * Number(tplData.quantite); } - const encContenus = tplData.contenu.map(idContenu => this.getRecursiveEnc(this.getObjet(idContenu))); + const encContenus = tplData.contenu.map(idContenu => this.getRecursiveEnc(this.getItem(idContenu))); return encContenus.reduce(Misc.sum(), 0) + Number(tplData.encombrement) /* TODO? Number(tplData.quantite) -- on pourrait avoir plusieurs conteneurs...*/ } /* -------------------------------------------- */ buildSubConteneurObjetList(conteneurId, deleteList) { - let conteneur = this.getObjet(conteneurId); + let conteneur = this.getItem(conteneurId); if (conteneur?.type == 'conteneur') { // Si c'est un conteneur for (let subId of conteneur.system.contenu) { - let subObj = this.getObjet(subId); + let subObj = this.getItem(subId); if (subObj) { if (subObj.type == 'conteneur') { this.buildSubConteneurObjetList(subId, deleteList); @@ -1228,12 +1116,12 @@ export class RdDActor extends Actor { return false; } let result = true; - const item = this.getObjet(itemId); + const item = this.getItem(itemId); if (item?.isInventaire() && sourceActorId == targetActorId) { // rangement if (srcId != destId && itemId != destId) { // déplacement de l'objet - const src = this.getObjet(srcId); - const dest = this.getObjet(destId); + const src = this.getItem(srcId); + const dest = this.getItem(destId); const cible = this.getContenantOrParent(dest); const [empilable, message] = item.isInventaireEmpilable(dest); if (empilable) { @@ -1303,7 +1191,7 @@ export class RdDActor extends Actor { itemsList.push({ id: itemId, conteneurId: undefined }); // Init list sourceActor.buildSubConteneurObjetList(itemId, itemsList); // Get itemId list - const itemsDataToCreate = itemsList.map(it => sourceActor.getObjet(it.id)) + const itemsDataToCreate = itemsList.map(it => sourceActor.getItem(it.id)) .map(it => duplicate(it)) .map(it => { it.system.contenu = []; return it; }); let newItems = await this.createEmbeddedDocuments('Item', itemsDataToCreate); @@ -1314,7 +1202,7 @@ export class RdDActor extends Actor { // gestion conteneur/contenu if (item.conteneurId) { // l'Objet était dans un conteneur let newConteneurId = itemMap[item.conteneurId]; // Get conteneur - let newConteneur = this.getObjet(newConteneurId); + let newConteneur = this.getItem(newConteneurId); let newItemId = itemMap[item.id]; // Get newItem @@ -1377,7 +1265,7 @@ export class RdDActor extends Actor { hasItemNamed(type, name) { name = Grammar.toLowerCaseNoAccent(name); - return this.listItemsData(type).find(it => Grammar.toLowerCaseNoAccent(it.name) == name); + return this.listItems(type).find(it => Grammar.toLowerCaseNoAccent(it.name) == name); } /* -------------------------------------------- */ @@ -1444,6 +1332,10 @@ export class RdDActor extends Actor { } } + recompute(){ + this.computeEtatGeneral(); + } + /* -------------------------------------------- */ computeEtatGeneral() { // Pas d'état général pour les entités forçage à 0 @@ -2027,7 +1919,7 @@ export class RdDActor extends Actor { /* -------------------------------------------- */ async consommerNourritureboisson(itemId, choix = { doses: 1, seForcer: false, supprimerSiZero: false }, userId = undefined) { if (userId != undefined && userId != game.user.id) { - RdDActor.remoteActorCall({ + RdDBaseActor.remoteActorCall({ actorId: this.id, method: 'consommerNourritureboisson', args: [itemId, choix, userId] @@ -2035,7 +1927,7 @@ export class RdDActor extends Actor { userId) return; } - const item = this.getObjet(itemId) + const item = this.getItem(itemId) if (!item.isComestible()) { return; } @@ -2792,7 +2684,7 @@ export class RdDActor extends Actor { /* -------------------------------------------- */ async rollDanse(id) { const artData = { art: 'danse', verbe: 'Danser', forceCarac: {} }; - const oeuvre = duplicate(this.getItemOfType(id, artData.art)); + const oeuvre = duplicate(this.findItemLike(id, artData.art)); if (oeuvre.system.agilite) { artData.forceCarac['agilite'] = duplicate(this.system.carac.agilite); } @@ -2814,7 +2706,7 @@ export class RdDActor extends Actor { /* -------------------------------------------- */ async rollMusique(id) { const artData = { art: 'musique', verbe: 'Jouer' }; - const oeuvre = this.getItemOfType(id, artData.art); + const oeuvre = this.findItemLike(id, artData.art); await this._rollArt(artData, "ouie", oeuvre); } @@ -2911,7 +2803,7 @@ export class RdDActor extends Actor { async rollOeuvre(id) { const artData = { art: 'oeuvre', verbe: 'Interpréter' } - const oeuvre = duplicate(this.getItemOfType(id, artData.art)) + const oeuvre = duplicate(this.findItemLike(id, artData.art)) await this._rollArt(artData, oeuvre.system.default_carac, oeuvre) } @@ -2963,7 +2855,7 @@ export class RdDActor extends Actor { /* -------------------------------------------- */ _getSignesDraconiques(coord) { const type = TMRUtility.getTMRType(coord); - return this.listItemsData("signedraconique").filter(it => it.system.typesTMR.includes(type)); + return this.listItems("signedraconique").filter(it => it.system.typesTMR.includes(type)); } /* -------------------------------------------- */ @@ -3174,39 +3066,37 @@ export class RdDActor extends Actor { /* -------------------------------------------- */ async resetNombreAstral() { - let toDelete = this.listItemsData('nombreastral'); + let toDelete = this.listItems('nombreastral'); const deletions = toDelete.map(it => it._id); await this.deleteEmbeddedDocuments("Item", deletions); } /* -------------------------------------------- */ async ajouteNombreAstral(callData) { - // Gestion expérience (si existante) - callData.competence = this.getCompetence("astrologie") - callData.selectedCarac = this.system.carac["vue"]; - this.appliquerAjoutExperience(callData, 'hide'); - // Ajout du nombre astral const item = { name: "Nombre Astral", type: "nombreastral", system: { value: callData.nbAstral, istrue: callData.isvalid, jourindex: Number(callData.date), jourlabel: game.system.rdd.calendrier.getDateFromIndex(Number(callData.date)) } }; await this.createEmbeddedDocuments("Item", [item]); - - // Suppression des anciens nombres astraux - let toDelete = this.listItemsData('nombreastral').filter(it => it.system.jourindex < game.system.rdd.calendrier.getCurrentDayIndex()); - const deletions = toDelete.map(it => it._id); - await this.deleteEmbeddedDocuments("Item", deletions); - // Affichage Dialog this.astrologieNombresAstraux(); } + async supprimerAnciensNombresAstraux() { + const toDelete = this.listItems('nombreastral') + .filter(it => it.system.jourindex < game.system.rdd.calendrier.getCurrentDayIndex()) + .map(it => it._id); + await this.deleteEmbeddedDocuments("Item", toDelete); + } + /* -------------------------------------------- */ async astrologieNombresAstraux() { + // Suppression des anciens nombres astraux + await this.supprimerAnciensNombresAstraux(); + // Afficher l'interface spéciale - const astrologieDialog = await RdDAstrologieJoueur.create(this, {}); - astrologieDialog.render(true); + await RdDAstrologieJoueur.create(this); } /* -------------------------------------------- */ @@ -3256,7 +3146,7 @@ export class RdDActor extends Actor { /* -------------------------------------------- */ getSortList() { - return this.listItemsData("sort"); + return this.listItems("sort"); } /* -------------------------------------------- */ @@ -3319,7 +3209,7 @@ export class RdDActor extends Actor { fatigue: RdDUtility.calculFatigueHtml(fatigue, endurance), draconic: this.getDraconicList(), sort: this.getSortList(), - signes: this.listItemsData("signedraconique"), + signes: this.listItems("signedraconique"), caracReve: this.system.carac.reve.value, pointsReve: this.getReveActuel(), isRapide: isRapide, @@ -3470,7 +3360,7 @@ export class RdDActor extends Actor { async validerEncaissement(rollData, show) { if (ReglesOptionelles.isUsing('validation-encaissement-gr') && !game.user.isGM) { - RdDActor.remoteActorCall({ + RdDBaseActor.remoteActorCall({ actorId: this.id, method: 'validerEncaissement', args: [rollData, show] @@ -3691,7 +3581,7 @@ export class RdDActor extends Actor { if (depense == 0) { return; } - let fortune = Monnaie.getFortune(this); + let fortune = super.getFortune(); console.log("payer", game.user.character, depense, fortune); let msg = ""; if (fortune >= depense) { @@ -3710,7 +3600,7 @@ export class RdDActor extends Actor { } async depenserSols(sols) { - let reste = Monnaie.getFortune(this) - Number(sols); + let reste = super.getFortune() - Number(sols); if (reste >= 0) { await Monnaie.optimiserFortune(this, reste); } @@ -3727,7 +3617,7 @@ export class RdDActor extends Actor { return; } if (fromActorId && !game.user.isGM) { - RdDActor.remoteActorCall({ + RdDBaseActor.remoteActorCall({ userId: Misc.connectedGMOrUser(), actorId: this.id, method: 'ajouterSols', args: [sols, fromActorId] @@ -3735,7 +3625,7 @@ export class RdDActor extends Actor { } else { const fromActor = game.actors.get(fromActorId) - await Monnaie.optimiserFortune(this, sols + Monnaie.getFortune(this)); + await Monnaie.optimiserFortune(this, sols + this.getFortune()); RdDAudio.PlayContextAudio("argent"); // Petit son ChatMessage.create({ @@ -3761,7 +3651,7 @@ export class RdDActor extends Actor { return; } if (!Misc.isUniqueConnectedGM()) { - RdDActor.remoteActorCall({ + RdDBaseActor.remoteActorCall({ actorId: achat.vendeurId ?? achat.acheteurId, method: 'achatVente', args: [achat] @@ -3771,21 +3661,21 @@ export class RdDActor extends Actor { const cout = Number(achat.prixTotal ?? 0); const vendeur = achat.vendeurId ? game.actors.get(achat.vendeurId) : undefined; - const service = achat.serviceId ? (vendeur?.getObjet(achat.serviceId) ?? game.items.get(achat.serviceId)) : undefined; + const service = achat.serviceId ? (vendeur?.getItem(achat.serviceId) ?? game.items.get(achat.serviceId)) : undefined; const acheteur = achat.acheteurId ? game.actors.get(achat.acheteurId) : undefined; const vente = achat.vente; const quantite = (achat.choix.nombreLots ?? 1) * (vente.tailleLot); - const itemVendu = vendeur?.getObjet(vente.item._id) ?? (await RdDItem.getCorrespondingItem(vente.item)); - if (!this.verifierQuantite(service, vendeur, itemVendu, quantite)) { + const itemVendu = vendeur?.getItem(vente.item._id) ?? (await RdDItem.getCorrespondingItem(vente.item)); + if (!this.verifierQuantite(service, vente.serviceSubItem, vendeur, itemVendu, quantite)) { ChatUtility.notifyUser(achat.userId, 'warn', `Le vendeur n'a pas assez de ${itemVendu.name} !`); return } - if (Monnaie.getFortune(acheteur) < Number(cout)) { + if ((acheteur?.getFortune() ?? 0) < Number(cout)) { ChatUtility.notifyUser(achat.userId, 'warn', `Vous n'avez pas assez d'argent pour payer ${Math.ceil(cout / 100)} sols !`); return; } - await this.decrementerVente(service, vendeur, itemVendu, quantite, cout); + await this.decrementerVente(service, vendeur, itemVendu, quantite, cout); if (acheteur) { await acheteur.depenserSols(cout); let createdItemId = await acheteur.creerQuantiteItem(vente.item, quantite); @@ -3828,8 +3718,8 @@ export class RdDActor extends Actor { } } - verifierQuantite(service, vendeur, item, quantiteTotal) { - const disponible = service ? service.getQuantiteDisponible(item, quantiteTotal) : (vendeur ? (item?.getQuantite() ?? 0) : quantiteTotal); + verifierQuantite(service, serviceSubItem, vendeur, item, quantiteTotal) { + const disponible = service ? service.getQuantiteDisponible(serviceSubItem, quantiteTotal) : (vendeur ? (item?.getQuantite() ?? 0) : quantiteTotal); return disponible >= quantiteTotal; } @@ -3871,7 +3761,7 @@ export class RdDActor extends Actor { /* -------------------------------------------- */ async effectuerTacheAlchimie(recetteId, tacheAlchimie, texteTache) { - let recetteData = this.getItemOfType(recetteId, 'recettealchimique'); + let recetteData = this.findItemLike(recetteId, 'recettealchimique'); if (recetteData) { if (tacheAlchimie != "couleur" && tacheAlchimie != "consistance") { ui.notifications.warn(`L'étape alchimique ${tacheAlchimie} - ${texteTache} est inconnue`); @@ -4141,7 +4031,7 @@ export class RdDActor extends Actor { /* -------------------------------------------- */ async diminuerQuantiteObjet(id, nb, options = { supprimerSiZero: false }) { - const item = this.getObjet(id); + const item = this.getItem(id); if (item) { await item.diminuerQuantite(nb, options); } diff --git a/module/actor/base-actor-sheet.js b/module/actor/base-actor-sheet.js new file mode 100644 index 00000000..98cd8650 --- /dev/null +++ b/module/actor/base-actor-sheet.js @@ -0,0 +1,256 @@ +import { RdDUtility } from "../rdd-utility.js"; +import { Misc } from "../misc.js"; +import { DialogSplitItem } from "../dialog-split-item.js"; +import { RdDSheetUtility } from "../rdd-sheet-utility.js"; +import { Monnaie } from "../item-monnaie.js"; +import { RdDItem } from "../item.js"; + +/* -------------------------------------------- */ +/** + * Extend the basic ActorSheet with some very simple modifications + * @extends {ActorSheet} + */ +export class RdDBaseActorSheet extends ActorSheet { + + /** @override */ + static get defaultOptions() { + RdDUtility.initAfficheContenu(); + return mergeObject(super.defaultOptions, { + classes: ["rdd", "sheet", "actor"], + template: "systems/foundryvtt-reve-de-dragon/templates/actor-sheet.html", + width: 550, + tabs: [{ navSelector: ".sheet-tabs", contentSelector: ".sheet-body", initial: "carac" }], + dragDrop: [{ dragSelector: ".item-list .item", dropSelector: undefined }], + showCompNiveauBase: false, + vueDetaillee: false + }); + } + + /* -------------------------------------------- */ + async getData() { + Monnaie.validerMonnaies(this.actor.itemTypes['monnaie']); + + this.actor.recompute(); + const userRightLevel = this.actor.getUserLevel(game.user) + const options = duplicate(this.options); + mergeObject(options, { + isGM: game.user.isGM, + editable: this.isEditable, + cssClass: this.isEditable ? "editable" : "locked", + isLimited: userRightLevel >= CONST.DOCUMENT_OWNERSHIP_LEVELS.LIMITED, + isObserver: userRightLevel >= CONST.DOCUMENT_OWNERSHIP_LEVELS.OBSERVER, + isOwner: userRightLevel >= CONST.DOCUMENT_OWNERSHIP_LEVELS.OWNER, + }); + + let formData = { + title: this.title, + id: this.actor.id, + type: this.actor.type, + img: this.actor.img, + name: this.actor.name, + system: foundry.utils.deepClone(this.actor.system), + options: options, + } + this.filterItemsPerTypeForSheet(formData, this.actor.itemTypes); + formData.calc = { + fortune: this.toSolsDeniers(this.actor.getFortune()), + prixTotalEquipement: this.actor.computePrixTotalEquipement(), + encTotal: await this.actor.computeEncombrementTotalEtMalusArmure(), + } + + this.objetVersConteneur = RdDUtility.buildArbreDeConteneurs(formData.conteneurs, formData.objets); + formData.conteneurs = RdDUtility.conteneursRacine(formData.conteneurs); + + + return formData; + } + + toSolsDeniers(fortune) { + return { + sols: Math.floor(fortune), + deniers: Math.round(100 * (fortune - Math.floor(fortune))) + }; + } + + /* -------------------------------------------- */ + filterItemsPerTypeForSheet(formData, itemTypes) { + formData.services = Misc.arrayOrEmpty(itemTypes['service']); + formData.recettescuisine = Misc.arrayOrEmpty(itemTypes['recettecuisine']); + formData.recettesAlchimiques = Misc.arrayOrEmpty(itemTypes['recettealchimique']); + formData.maladies = Misc.arrayOrEmpty(itemTypes['maladie']); + formData.poisons = Misc.arrayOrEmpty(itemTypes['poison']); + formData.possessions = Misc.arrayOrEmpty(itemTypes['possession']); + formData.maladiesPoisons = formData.maladies.concat(formData.poisons); + formData.competences = (itemTypes['competence'] ?? []).concat(itemTypes['competencecreature'] ?? []); + formData.sortsReserve = Misc.arrayOrEmpty(itemTypes['sortreserve']); + + formData.sorts = Misc.arrayOrEmpty(itemTypes['sort']); + formData.rencontres = Misc.arrayOrEmpty(itemTypes['rencontre']); + formData.casestmr = Misc.arrayOrEmpty(itemTypes['casetmr']); + formData.signesdraconiques = Misc.arrayOrEmpty(itemTypes['signedraconique']); + formData.queues = Misc.arrayOrEmpty(itemTypes['queue']); + formData.souffles = Misc.arrayOrEmpty(itemTypes['souffle']); + formData.ombres = Misc.arrayOrEmpty(itemTypes['ombre']); + formData.tetes = Misc.arrayOrEmpty(itemTypes['tete']); + formData.taches = Misc.arrayOrEmpty(itemTypes['tache']); + formData.meditations = Misc.arrayOrEmpty(itemTypes['meditation']); + formData.chants = Misc.arrayOrEmpty(itemTypes['chant']); + formData.danses = Misc.arrayOrEmpty(itemTypes['danse']); + formData.musiques = Misc.arrayOrEmpty(itemTypes['musique']); + formData.oeuvres = Misc.arrayOrEmpty(itemTypes['oeuvre']); + formData.jeux = Misc.arrayOrEmpty(itemTypes['jeu']); + + + formData.conteneurs = Misc.arrayOrEmpty(itemTypes['conteneur']); + + formData.materiel = Misc.arrayOrEmpty(itemTypes['objet']); + formData.armes = Misc.arrayOrEmpty(itemTypes['arme']); + formData.armures = Misc.arrayOrEmpty(itemTypes['armure']); + formData.munitions = Misc.arrayOrEmpty(itemTypes['munition']); + formData.livres = Misc.arrayOrEmpty(itemTypes['livre']); + formData.potions = Misc.arrayOrEmpty(itemTypes['potion']); + formData.ingredients = Misc.arrayOrEmpty(itemTypes['ingredient']); + formData.faunes = Misc.arrayOrEmpty(itemTypes['faune']); + formData.herbes = Misc.arrayOrEmpty(itemTypes['herbe']); + formData.nourritureboissons = Misc.arrayOrEmpty(itemTypes['nourritureboisson']); + formData.gemmes = Misc.arrayOrEmpty(itemTypes['gemme']); + + formData.monnaie = Misc.arrayOrEmpty(itemTypes['monnaie']).sort(Monnaie.triValeurEntiere()); + + formData.objets = formData.conteneurs + .concat(formData.materiel) + .concat(formData.armes) + .concat(formData.armures) + .concat(formData.munitions) + .concat(formData.livres) + .concat(formData.potions) + .concat(formData.ingredients) + .concat(formData.herbes) + .concat(formData.faunes) + .concat(formData.monnaie) + .concat(formData.nourritureboissons) + .concat(formData.gemmes); + } + + /* -------------------------------------------- */ /** @override */ + activateListeners(html) { + super.activateListeners(html); + this.html = html; + + this.html.find('.conteneur-name a').click(async event => { + RdDUtility.toggleAfficheContenu(RdDSheetUtility.getItemId(event)); + this.render(true); + }); + this.html.find('.item-edit').click(async event => RdDSheetUtility.getItem(event, this.actor)?.sheet.render(true)) + this.html.find('.item-montrer').click(async event => RdDSheetUtility.getItem(event, this.actor)?.postItemToChat()); + this.html.find('.actor-montrer').click(async event => this.actor.postActorToChat()); + + // Everything below here is only needed if the sheet is editable + if (!this.options.editable) return; + + this.html.find('.item-split').click(async event => { + const item = RdDSheetUtility.getItem(event, this.actor); + RdDSheetUtility.splitItem(item, this.actor); + }); + this.html.find('.item-delete').click(async event => RdDUtility.confirmActorItemDelete(this, RdDSheetUtility.getItem(event, this.actor))); + this.html.find('.item-vendre').click(async event => RdDSheetUtility.getItem(event, this.actor)?.proposerVente()); + + this.html.find('.creer-un-objet').click(async event => { + this.selectObjetTypeToCreate(); + }); + this.html.find('.nettoyer-conteneurs').click(async event => { + this.actor.nettoyerConteneurs(); + }); + this.html.find('.monnaie-plus').click(async event => { + this.actor.monnaieIncDec(RdDSheetUtility.getItemId(event), 1); + }); + this.html.find('.monnaie-moins').click(async event => { + this.actor.monnaieIncDec(RdDSheetUtility.getItemId(event), -1); + }); + + } + + + /* -------------------------------------------- */ + _getHeaderButtons() { + let buttons = super._getHeaderButtons(); + buttons.unshift({ + class: "montrer", + icon: "fas fa-comment", + onclick: ev => this.actor.postActorToChat() + }); + return buttons + } + + /* -------------------------------------------- */ + async _onDropItem(event, dragData) { + const destItemId = this.html.find(event.target)?.closest('.item').attr('data-item-id') + const dropParams = RdDSheetUtility.prepareItemDropParameters(destItemId, this.actor, dragData, this.objetVersConteneur) + if (dropParams) { + const callSuper = await this.actor.processDropItem(dropParams) + if (callSuper) { + await super._onDropItem(event, dragData) + } + } + } + + + /* -------------------------------------------- */ + async selectObjetTypeToCreate() { + let typeObjets = RdDItem.getItemTypesInventaire(); + let content = `Selectionnez le type d'équipement'; + let d = new Dialog({ + title: "Créer un équipement", + content: content, + buttons: { + create: { + icon: '', + label: "Créer l'objet", + callback: () => this.actor.createItem($(".item-type").val()) + } + } + }); + d.render(true); + } + + /** @override */ + setPosition(options = {}) { + const position = super.setPosition(options); + const sheetHeader = this.element.find(".sheet-header"); + const sheetTabs = this.element.find(".sheet-tabs"); + const sheetBody = this.element.find(".sheet-body"); + let bodyHeight = position.height - sheetHeader[0].clientHeight; + if (sheetTabs.length > 0) { + bodyHeight -= sheetTabs[0].clientHeight; + } + sheetBody.css("height", bodyHeight); + return position; + } + + + /* -------------------------------------------- */ + /** @override */ + _updateObject(event, formData) { + // Update the Actor + return this.actor.update(formData); + } + + async splitItem(item) { + const dialog = await DialogSplitItem.create(item, (item, split) => this._onSplitItem(item, split)); + dialog.render(true); + } + + async _onSplitItem(item, split) { + if (split >= 1 && split < item.system.quantite) { + await item.diminuerQuantite(split); + const splitItem = duplicate(item); + splitItem.system.quantite = split; + await this.actor.createEmbeddedDocuments('Item', [splitItem]) + } + } + +} diff --git a/module/actor/base-actor.js b/module/actor/base-actor.js new file mode 100644 index 00000000..b95a7ff5 --- /dev/null +++ b/module/actor/base-actor.js @@ -0,0 +1,167 @@ +import { SYSTEM_SOCKET_ID } from "../constants.js"; +import { Monnaie } from "../item-monnaie.js"; +import { Misc } from "../misc.js"; +import { RdDUtility } from "../rdd-utility.js"; +import { SystemCompendiums } from "../settings/system-compendiums.js"; + +export class RdDBaseActor extends Actor { + + static getDefaultImg(itemType) { + return game.system.rdd.actorClasses[itemType]?.defaultIcon ?? defaultItemImg[itemType]; + } + + /* -------------------------------------------- */ + static init() { + Hooks.on("preUpdateItem", (item, change, options, id) => RdDBaseActor.getParentActor(item)?.onPreUpdateItem(item, change, options, id)); + Hooks.on("createItem", (item, options, id) => RdDBaseActor.getParentActor(item)?.onCreateItem(item, options, id)); + Hooks.on("deleteItem", (item, options, id) => RdDBaseActor.getParentActor(item)?.onDeleteItem(item, options, id)); + Hooks.on("updateActor", (actor, change, options, actorId) => actor.onUpdateActor(change, options, actorId)); + } + + + static onSocketMessage(sockmsg) { + switch (sockmsg.msg) { + case "msg_remote_actor_call": + return RdDBaseActor.onRemoteActorCall(sockmsg.data, sockmsg.userId); + case "msg_reset_nombre_astral": + console.log("RESET ASTRAL", game.user.character); + game.user.character.resetNombreAstral(); + return; + } + } + + static remoteActorCall(callData, userId = undefined) { + userId = userId ?? Misc.firstConnectedGMId(); + if (userId == game.user.id) { + RdDBaseActor.onRemoteActorCall(callData, userId); + return false; + } + else { + game.socket.emit(SYSTEM_SOCKET_ID, { msg: "msg_remote_actor_call", data: callData, userId: userId }); + return true; + } + } + + static onRemoteActorCall(callData, userId) { + if (userId == game.user.id) { + const actor = game.actors.get(callData?.actorId); + 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); + } + } + } + + static getParentActor(document) { + return document?.parent instanceof Actor ? document.parent : undefined + } + + /** + * Cet methode surcharge Actor.create() pour ajouter si besoin des Items par défaut: + * compétences et monnaies. + * + * @param {Object} actorData template d'acteur auquel ajouter des informations. + * @param {Object} options optionspour customiser la création + */ + static async create(actorData, options) { + // import depuis un compendium + if (actorData instanceof Array) { + return super.create(actorData, options); + } + // Création d'un acteur avec des items (uniquement en cas de duplication): pas besoin d'ajouter d'items + if (actorData.items) { + return await super.create(actorData, options); + } + + if (actorData.type == "personnage") { + const competences = await SystemCompendiums.getCompetences(actorData.type); + actorData.items = competences.map(i => i.toObject()) + .concat(Monnaie.monnaiesStandard()); + } + else { + actorData.items = []; + } + return super.create(actorData, options); + } + + constructor(docData, context = {}) { + if (!context.rdd?.ready) { + mergeObject(context, { rdd: { ready: true } }); + const ActorConstructor = game.system.rdd.actorClasses[docData.type]; + if (ActorConstructor) { + if (!docData.img) { + docData.img = ActorConstructor.defaultIcon; + } + return new ActorConstructor(docData, context); + } + } + super(docData, context); + } + + isCreatureEntite() { return this.type == 'creature' || this.type == 'entite'; } + isCreature() { return this.type == 'creature'; } + isEntite() { return this.type == 'entite'; } + isPersonnage() { return this.type == 'personnage'; } + isVehicule() { return this.type == 'vehicule'; } + + getItem(id, type = undefined) { + const item = this.items.get(id); + if (type == undefined || (item?.type == type)) { + return item; + } + return undefined; + } + + listItems(type = undefined) { return (type ? this.itemTypes[type] : this.items); } + filterItems(filter, type = undefined) { return this.listItems(type)?.filter(filter) ?? []; } + findItemLike(idOrName, type) { + return this.getItem(idOrName, type) + ?? Misc.findFirstLike(idOrName, this.listItems(type), { description: Misc.typeName('Item', type) }); + } + + + recompute() { } + + /* -------------------------------------------- */ + async onPreUpdateItem(item, change, options, id) { } + + async onCreateItem(item, options, id) { } + + async onDeleteItem(item, options, id) { } + + async onUpdateActor(update, options, actorId) { } + + + getFortune() { + return Monnaie.getFortune(this.itemTypes['monnaie']); + } + + async createItem(type, name = undefined) { + if (!name) { + name = 'Nouveau ' + Misc.typeName('Item', type); + } + await this.createEmbeddedDocuments('Item', [{ name: name, type: type }], { renderSheet: true }); + } + + canReceive(item) { + return false; + } + + /* -------------------------------------------- */ + async postActorToChat(modeOverride) { + let chatData = { + doctype: 'Actor', + id: this.id, + type: this.type, + img: this.img, + pack: this.pack, + name: this.name, + system: { description: this.system.description } + } + renderTemplate('systems/foundryvtt-reve-de-dragon/templates/post-actor.html', chatData) + .then(html => ChatMessage.create(RdDUtility.chatDataSetup(html, modeOverride))); + } + + +} \ No newline at end of file diff --git a/module/dialog-item-achat.js b/module/dialog-item-achat.js index 5509b178..12648644 100644 --- a/module/dialog-item-achat.js +++ b/module/dialog-item-achat.js @@ -30,13 +30,14 @@ export class DialogItemAchat extends Dialog { } - static async onAcheter({ item, vendeur, acheteur, service, tailleLot, prixLot, nbLots, quantiteIllimite, chatMessageIdVente }) { + static async onAcheter({ item, vendeur, acheteur, service, serviceSubItem, tailleLot, prixLot, nbLots, quantiteIllimite, chatMessageIdVente }) { const venteData = { item, actingUserId: game.user.id, vendeurId: vendeur?.id, vendeur, acheteur, + serviceSubItem: serviceSubItem, service, tailleLot, quantiteIllimite, diff --git a/module/item-monnaie.js b/module/item-monnaie.js index d766c0af..11946207 100644 --- a/module/item-monnaie.js +++ b/module/item-monnaie.js @@ -62,29 +62,17 @@ export class Monnaie { return deniers; } - static getFortune(actor) { - if (actor) { - Monnaie.validerMonnaies(actor); - return actor.itemTypes['monnaie'] - .map(m => Number(m.system.cout) * Number(m.system.quantite)) - .reduce(Misc.sum(), 0); - } - return 0; - } - - static getFortuneSolsDeniers(actor) { - const fortune = Monnaie.getFortune(actor); - return { - sols: Math.floor(fortune), - deniers: Math.round(100 * (fortune - Math.floor(fortune))) - }; + static getFortune(monnaies) { + return (monnaies??[]) + .map(m => Number(m.system.cout) * Number(m.system.quantite)) + .reduce(Misc.sum(), 0); } static async optimiserFortune(actor, fortune) { let resteEnDeniers = Math.round(fortune * 100); let monnaies = actor.itemTypes['monnaie']; let updates = []; - Monnaie.validerMonnaies(actor); + Monnaie.validerMonnaies(monnaies, actor); let parValeur = Misc.classifyFirst(monnaies, it => VALEUR_DENIERS(it.system.cout)); for (let valeurDeniers of [1000, 100, 10, 1]) { @@ -107,9 +95,9 @@ export class Monnaie { } } - static validerMonnaies(actor) { - actor.itemTypes['monnaie'].filter(it => VALEUR_DENIERS(it.system.cout) == 0) - .map(it => `La monnaie ${it.name} de l'acteur ${actor.name} a une valeur de 0!`) + static validerMonnaies(monnaies, actor = undefined) { + monnaies.filter(it => VALEUR_DENIERS(it.system.cout) == 0) + .map(it => `La monnaie ${it.name} de l'acteur ${actor?.name ?? 'sélectionné'} a une valeur de 0!`) .forEach(message => { ui.notifications.warn(message); console.warn(message); diff --git a/module/item-service.js b/module/item-service.js index 17fc6ab5..bc00ded4 100644 --- a/module/item-service.js +++ b/module/item-service.js @@ -23,7 +23,7 @@ export class RdDItemService extends RdDItem { getProprietes() { return []; } getServiceItem(itemRef) { - if (this.isService()) { + if (itemRef && this.isService()) { return this.system.items.find(it => it.id == itemRef.id && it.pack == itemRef.pack); } return undefined; @@ -64,6 +64,7 @@ export class RdDItemService extends RdDItem { await DialogItemAchat.onAcheter({ item: await RdDItem.getCorrespondingItem(subItem), acheteur, + serviceSubItem: subItem, service: this, quantiteIllimite: this.system.illimite, nbLots, diff --git a/module/item-sheet.js b/module/item-sheet.js index 27c1ebb8..11b742cb 100644 --- a/module/item-sheet.js +++ b/module/item-sheet.js @@ -66,7 +66,7 @@ export class RdDItemSheet extends ItemSheet { buttons.unshift({ class: "montrer", icon: "fas fa-comment", - onclick: ev => this.item.postItem() + onclick: ev => this.item.postItemToChat() }); return buttons } @@ -211,7 +211,7 @@ export class RdDItemSheet extends ItemSheet { this.html.find('.item-edit').click(async event => RdDSheetUtility.getItem(event, this.actor)?.sheet.render(true)); this.html.find('.item-delete').click(async event => RdDUtility.confirmActorItemDelete(this, RdDSheetUtility.getItem(event, this.actor))); this.html.find('.item-vendre').click(async event => RdDSheetUtility.getItem(event, this.actor)?.proposerVente()); - this.html.find('.item-montrer').click(async event => RdDSheetUtility.getItem(event, this.actor)?.postItem()); + this.html.find('.item-montrer').click(async event => RdDSheetUtility.getItem(event, this.actor)?.postItemToChat()); this.html.find('.item-action').click(async event => RdDSheetUtility.getItem(event, this.actor)?.actionPrincipale(this.actor, async () => this.render(true))); } diff --git a/module/item.js b/module/item.js index 6a2b5fed..95fadacf 100644 --- a/module/item.js +++ b/module/item.js @@ -428,7 +428,7 @@ export class RdDItem extends Item { } await DialogItemVente.display({ item: this, - service, + service: service, quantiteMax, callback: async (vente) => { vente["properties"] = this.getProprietes(); @@ -455,20 +455,19 @@ export class RdDItem extends Item { } /* -------------------------------------------- */ - async postItem(modeOverride) { + async postItemToChat(modeOverride) { console.log(this); - let chatData = duplicate(this); - chatData["properties"] = this.getProprietes(); - if (this.actor) { - chatData.actor = { id: this.actor.id }; + let chatData = { + doctype: 'Item', + id: this.id, + type: this.type, + img: this.img, + pack: this.pack, + name: this.name, + actor : this.actor ? { id: this.actor.id } : undefined, + system: { description: this.system.description }, + properties: this.getProprietes(), } - // JSON object for easy creation - chatData.jsondata = JSON.stringify( - { - compendium: "postedItem", - payload: chatData, - }); - renderTemplate(this.getChatItemTemplate(), chatData).then(html => { let chatOptions = RdDUtility.chatDataSetup(html, modeOverride); ChatMessage.create(chatOptions) diff --git a/module/misc.js b/module/misc.js index 2aa30278..185a3933 100644 --- a/module/misc.js +++ b/module/misc.js @@ -46,6 +46,9 @@ export class Misc { : ''; } + static arrayOrEmpty(items) { + return items?.length ? items : []; + } /** * Converts the value to an integer, or to 0 if undefined/null/not representing integer * @param {*} value value to convert to an integer using parseInt @@ -135,11 +138,11 @@ export class Misc { } static isRollModeHiddenToPlayer() { - switch (game.settings.get("core", "rollMode")) { - case CONST.DICE_ROLL_MODES.BLIND: - case CONST.DICE_ROLL_MODES.SELF: return true; - } - return false + switch (game.settings.get("core", "rollMode")) { + case CONST.DICE_ROLL_MODES.BLIND: + case CONST.DICE_ROLL_MODES.SELF: return true; + } + return false } static getActiveUser(id) { @@ -150,11 +153,11 @@ export class Misc { return game.users.filter(u => u.isGM && u.active).sort(Misc.ascending(u => u.id)).find(u => u.isGM && u.active); } - static isOwnerPlayer(actor, user=undefined) { + static isOwnerPlayer(actor, user = undefined) { return actor.testUserPermission(user ?? game.user, CONST.DOCUMENT_PERMISSION_LEVELS.OWNER) } - static isOwnerPlayerOrUniqueConnectedGM(actor, user =undefined){ + static isOwnerPlayerOrUniqueConnectedGM(actor, user = undefined) { return Misc.isOwnerPlayer(actor, user) ?? Misc.isUniqueConnectedGM(); } diff --git a/module/rdd-astrologie-joueur.js b/module/rdd-astrologie-joueur.js index 5ec5660d..abab8a66 100644 --- a/module/rdd-astrologie-joueur.js +++ b/module/rdd-astrologie-joueur.js @@ -10,7 +10,7 @@ import { SYSTEM_SOCKET_ID } from "./constants.js"; export class RdDAstrologieJoueur extends Dialog { /* -------------------------------------------- */ - static async create(actor, dialogConfig) { + static async create(actor) { let dialogData = { nombres: this.organizeNombres(actor), @@ -20,15 +20,14 @@ export class RdDAstrologieJoueur extends Dialog { astrologie: RdDItemCompetence.findCompetence(actor.items, 'Astrologie') } const html = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/dialog-astrologie-joueur.html', dialogData); - let options = { classes: ["rdd-roll-dialog"], width: 600, height: 500, 'z-index': 99999 }; - if (dialogConfig.options) { - mergeObject(options, dialogConfig.options, { overwrite: true }); - } - return new RdDAstrologieJoueur(html, actor, dialogData); + + const options = { classes: ["rdd-roll-dialog"], width: 600, height: 'fit-content', 'z-index': 99999 }; + const dialog = new RdDAstrologieJoueur(html, actor, dialogData, options); + dialog.render(true); } /* -------------------------------------------- */ - constructor(html, actor, dialogData) { + constructor(html, actor, dialogData, dialogOptions) { const dialogConf = { title: "Nombres Astraux", content: html, @@ -37,7 +36,6 @@ export class RdDAstrologieJoueur extends Dialog { saveButton: { label: "Fermer", callback: html => this.quitDialog() } }, }; - const dialogOptions = { classes: ["rdd-roll-dialog"], width: 600, height: 300, 'z-index': 99999 }; super(dialogConf, dialogOptions); this.actor = actor; @@ -49,9 +47,7 @@ export class RdDAstrologieJoueur extends Dialog { super.activateListeners(html); this.html = html; - this.html.find(function () { - this.html.find("[name='diffConditions']").val(0); - }); + this.html.find("[name='diffConditions']").val(0); this.html.find('[name="jet-astrologie"]').click((event) => { this.requestJetAstrologie(); @@ -60,7 +56,7 @@ export class RdDAstrologieJoueur extends Dialog { /* -------------------------------------------- */ static organizeNombres(actor) { - let itemNombres = actor.listItemsData('nombreastral'); + let itemNombres = actor.listItems('nombreastral'); let itemFiltered = {}; for (let item of itemNombres) { if (itemFiltered[item.system.jourindex]) { diff --git a/module/rdd-calendrier.js b/module/rdd-calendrier.js index 554a11e2..a4996963 100644 --- a/module/rdd-calendrier.js +++ b/module/rdd-calendrier.js @@ -14,7 +14,7 @@ import { DialogChronologie } from "./dialog-chronologie.js"; const dossierIconesHeures = 'systems/foundryvtt-reve-de-dragon/icons/heures/' const heuresList = ["vaisseau", "sirene", "faucon", "couronne", "dragon", "epees", "lyre", "serpent", "poissonacrobate", "araignee", "roseau", "chateaudormant"]; const heuresDef = { - "vaisseau": {key: "vaisseau", label: "Vaisseau", lettreFont: 'v', saison: "printemps", heure: 0, icon: 'hd01.svg' }, + "vaisseau": { key: "vaisseau", label: "Vaisseau", lettreFont: 'v', saison: "printemps", heure: 0, icon: 'hd01.svg' }, "sirene": { key: "sirene", label: "Sirène", lettreFont: 'i', saison: "printemps", heure: 1, icon: 'hd02.svg' }, "faucon": { key: "faucon", label: "Faucon", lettreFont: 'f', saison: "printemps", heure: 2, icon: 'hd03.svg' }, "couronne": { key: "couronne", label: "Couronne", lettreFont: '', saison: "ete", heure: 3, icon: 'hd04.svg' }, @@ -64,7 +64,7 @@ export class RdDCalendrier extends Application { const heure = (typeof value == 'string' || typeof value == 'number') && Number.isInteger(Number(value)) ? Number(value) : (typeof value == 'string') ? RdDCalendrier.getChiffreFromSigne(value) - : undefined + : undefined if (heure != undefined && ['key', 'label', 'lettreFont', 'saison', 'heure', 'icon'].includes(key)) { return RdDCalendrier.getDefSigne(heure)[key] @@ -340,21 +340,21 @@ export class RdDCalendrier extends Application { } /* -------------------------------------------- */ - checkMaladie( periode) { + checkMaladie(periode) { for (let actor of game.actors) { if (actor.type == 'personnage') { - let maladies = actor.items.filter( item => (item.type == 'maladie' || (item.type == 'poison' && item.system.active) ) && item.system.periodicite.toLowerCase().includes(periode) ); + let maladies = actor.items.filter(item => (item.type == 'maladie' || (item.type == 'poison' && item.system.active)) && item.system.periodicite.toLowerCase().includes(periode)); for (let maladie of maladies) { - if ( maladie.system.identifie) { + if (maladie.system.identifie) { ChatMessage.create({ content: `${actor.name} souffre de ${maladie.name} (${maladie.type}): vérifiez que les effets ne se sont pas aggravés !` }); } else { ChatMessage.create({ content: `${actor.name} souffre d'un mal inconnu (${maladie.type}): vérifiez que les effets ne se sont pas aggravés !` }); } - let itemMaladie = actor.getObjet(maladie.id) - itemMaladie.postItem( 'gmroll'); + let itemMaladie = actor.getItem(maladie.id) + itemMaladie.postItem('gmroll'); } } - } + } } /* -------------------------------------------- */ @@ -366,7 +366,7 @@ export class RdDCalendrier extends Application { this.calendrier.minutesRelative -= RDD_MINUTES_PAR_HEURES; this.calendrier.heureRdD += 1; this.checkMaladie("heure"); - } + } if (this.calendrier.heureRdD >= RDD_HEURES_PAR_JOUR) { this.calendrier.heureRdD -= RDD_HEURES_PAR_JOUR; await this.incrementerJour(); @@ -434,6 +434,7 @@ export class RdDCalendrier extends Application { /* -------------------------------------------- */ async requestNombreAstral(request) { + const actor = game.actors.get(request.id); if (Misc.isUniqueConnectedGM()) { // Only once console.log(request); let jourDiff = this.getLectureAstrologieDifficulte(request.date); @@ -445,18 +446,26 @@ export class RdDCalendrier extends Application { rollMode: "blindroll" }; await RdDResolutionTable.rollData(rollData); - let nbAstral = this.getNombreAstral(request.date); request.rolled = rollData.rolled; - request.isValid = true; - if (!request.rolled.isSuccess) { - request.isValid = false; - nbAstral = await RdDDice.rollTotal("1dhr" + nbAstral, { rollMode: "selfroll" }); - // Mise à jour des nombres astraux du joueur - let astralData = this.listeNombreAstral.find((nombreAstral, i) => nombreAstral.index == request.date); - astralData.valeursFausses.push({ actorId: request.id, nombreAstral: nbAstral }); - game.settings.set(SYSTEM_RDD, "liste-nombre-astral", this.listeNombreAstral); + request.isValid = request.rolled.isSuccess; + request.nbAstral = this.getNombreAstral(request.date); + + if (request.rolled.isSuccess) { + if (request.rolled.isPart){ + // Gestion expérience (si existante) + request.competence = actor.getCompetence("astrologie") + request.selectedCarac = actor.system.carac["vue"]; + actor.appliquerAjoutExperience(request, 'hide'); + } } - request.nbAstral = nbAstral; + else { + request.nbAstral = await RdDDice.rollTotal("1dhr" + request.nbAstral, { + rollMode: "selfroll", showDice: HIDE_DICE + }); + // Mise à jour des nombres astraux du joueur + this.addNbAstralIncorect(request.id, request.date, request.nbAstral); + } + if (Misc.getActiveUser(request.userId)?.isGM) { RdDUtility.responseNombreAstral(request); } else { @@ -468,6 +477,12 @@ export class RdDCalendrier extends Application { } } + addNbAstralIncorect(actorId, date, nbAstral) { + let astralData = this.listeNombreAstral.find((nombreAstral, i) => nombreAstral.index == date); + astralData.valeursFausses.push({ actorId: actorId, nombreAstral: nbAstral }); + game.settings.set(SYSTEM_RDD, "liste-nombre-astral", this.listeNombreAstral); + } + /* -------------------------------------------- */ findHeure(heure) { heure = Grammar.toLowerCaseNoAccentNoSpace(heure); @@ -483,7 +498,7 @@ export class RdDCalendrier extends Application { return undefined; } /* -------------------------------------------- */ - getHeureNumber( hNum) { + getHeureNumber(hNum) { let heure = Object.values(heuresDef).find(it => (it.heure) == hNum); return heure } @@ -495,12 +510,16 @@ export class RdDCalendrier extends Application { if (defHeure) { let hn = defHeure.heure; let chiffreAstral = this.getCurrentNombreAstral() ?? 0; - heuresChancesMalchances[0] = { value : "+4", heures: [this.getHeureNumber((hn + chiffreAstral) % RDD_HEURES_PAR_JOUR).label]}; - heuresChancesMalchances[1] = { value : "+2", heures: [this.getHeureNumber((hn + chiffreAstral+4) % RDD_HEURES_PAR_JOUR).label, - this.getHeureNumber((hn + chiffreAstral + 8) % RDD_HEURES_PAR_JOUR).label ] }; - heuresChancesMalchances[2] = { value : "-4", heures: [this.getHeureNumber((hn + chiffreAstral+6) % RDD_HEURES_PAR_JOUR).label]}; - heuresChancesMalchances[3] = { value : "-2", heures: [this.getHeureNumber((hn + chiffreAstral+3) % RDD_HEURES_PAR_JOUR).label, - this.getHeureNumber((hn + chiffreAstral + 9) % RDD_HEURES_PAR_JOUR).label ]}; + heuresChancesMalchances[0] = { value: "+4", heures: [this.getHeureNumber((hn + chiffreAstral) % RDD_HEURES_PAR_JOUR).label] }; + heuresChancesMalchances[1] = { + value: "+2", heures: [this.getHeureNumber((hn + chiffreAstral + 4) % RDD_HEURES_PAR_JOUR).label, + this.getHeureNumber((hn + chiffreAstral + 8) % RDD_HEURES_PAR_JOUR).label] + }; + heuresChancesMalchances[2] = { value: "-4", heures: [this.getHeureNumber((hn + chiffreAstral + 6) % RDD_HEURES_PAR_JOUR).label] }; + heuresChancesMalchances[3] = { + value: "-2", heures: [this.getHeureNumber((hn + chiffreAstral + 3) % RDD_HEURES_PAR_JOUR).label, + this.getHeureNumber((hn + chiffreAstral + 9) % RDD_HEURES_PAR_JOUR).label] + }; } return heuresChancesMalchances; } @@ -634,9 +653,9 @@ export class RdDCalendrier extends Application { let heuresParActeur = {}; for (let actor of game.actors) { let heureNaissance = actor.getHeureNaissance(); - if ( heureNaissance) { + if (heureNaissance) { heuresParActeur[actor.name] = this.getHeuresChanceMalchance(heureNaissance); - } + } } //console.log("ASTRO", astrologieArray); calendrierData.astrologieData = astrologieArray; diff --git a/module/rdd-combat.js b/module/rdd-combat.js index b9186d1d..45202088 100644 --- a/module/rdd-combat.js +++ b/module/rdd-combat.js @@ -247,7 +247,7 @@ export class RdDCombatManager extends Combat { } if (actor.isCreatureEntite()) { actions = actions.concat(RdDCombatManager.listActionsCreature(actor.itemTypes['competencecreature'])); - } else { + } else if (actor.isPersonnage()) { // Recupération des items 'arme' const armes = actor.itemTypes['arme'].filter(it => RdDItemArme.isArmeUtilisable(it)) //.concat(RdDItemArme.empoignade()) diff --git a/module/rdd-main.js b/module/rdd-main.js index e3d456d9..b1799ce7 100644 --- a/module/rdd-main.js +++ b/module/rdd-main.js @@ -36,6 +36,7 @@ import { RdDFauneItemSheet } from "./item-faune-sheet.js"; import { RdDConteneurItemSheet } from "./item-conteneur-sheet.js"; import { RdDServiceItemSheet } from "./item-service-sheet.js"; import { RdDItemService } from "./item-service.js"; +import { RdDBaseActor } from "./actor/base-actor.js"; /** * RdD system @@ -57,6 +58,10 @@ export class SystemReveDeDragon { service: RdDItemService } this.actorClasses = { + creature: RdDActor, + entite: RdDActor, + personnage: RdDActor, + vehicule: RdDActor, } } @@ -161,7 +166,7 @@ export class SystemReveDeDragon { RdDUtility.onSocketMessage(sockmsg); RdDCombat.onSocketMessage(sockmsg); ChatUtility.onSocketMessage(sockmsg); - RdDActor.onSocketMessage(sockmsg); + RdDBaseActor.onSocketMessage(sockmsg); } catch (e) { console.error('game.socket.on(SYSTEM_SOCKET_ID) Exception: ', sockmsg, ' => ', e) } @@ -218,7 +223,7 @@ export class SystemReveDeDragon { RdDCombat.init(); RdDCombatManager.init(); RdDTokenHud.init(); - RdDActor.init(); + RdDBaseActor.init(); RddCompendiumOrganiser.init(); EffetsDraconiques.init() TMRUtility.init(); diff --git a/module/rdd-utility.js b/module/rdd-utility.js index 33908d61..98d210fe 100644 --- a/module/rdd-utility.js +++ b/module/rdd-utility.js @@ -315,63 +315,13 @@ export class RdDUtility { } static getItem(itemId, actorId = undefined) { - return actorId ? game.actors.get(actorId)?.getObjet(itemId) : game.items.get(itemId); + return actorId ? game.actors.get(actorId)?.getItem(itemId) : game.items.get(itemId); } static linkCompendium(pack, id, name) { return `@Compendium[${pack}.${id}]{${name}}`; } - /* -------------------------------------------- */ - static async creerObjet(actorSheet) { - let itemType = $(".item-type").val(); - await actorSheet.createItem('Nouveau ' + itemType, itemType); - } - - /* -------------------------------------------- */ - static async selectObjetType(actorSheet) { - let typeObjets = RdDItem.getItemTypesInventaire(); - let options = `Selectionnez le type d'équipement'; - let d = new Dialog({ - title: "Créer un équipement", - content: options, - buttons: { - one: { - icon: '', - label: "Créer l'objet", - callback: () => this.creerObjet(actorSheet) - } - } - }); - d.render(true); - } - - /* -------------------------------------------- */ - static async selectTypeOeuvre(actorSheet) { - let typeObjets = RdDItem.getTypesOeuvres(); - let options = `Selectionnez le type d'oeuvre'; - let d = new Dialog({ - title: "Créer un équipement", - content: options, - buttons: { - one: { - icon: '', - label: "Créer l'objet", - callback: () => this.creerObjet(actorSheet) - } - } - }); - d.render(true); - } - /* -------------------------------------------- */ static buildListOptions(min, max) { let options = "" @@ -833,8 +783,16 @@ export class RdDUtility { } }); html.on("click", '.rdd-world-content-link', async event => { - const itemId = html.find(event.currentTarget)?.data("id"); - game.items.get(itemId)?.sheet.render(true) + const htmlElement = html.find(event.currentTarget); + const id = htmlElement?.data("id"); + const doctype= htmlElement?.data("doctype"); + switch (doctype ?? 'Item') { + case 'Actor': + return game.actors.get(id)?.sheet.render(true); + case 'Item': + default: + return game.items.get(id)?.sheet.render(true); + } }); } diff --git a/packs/sorts-narcos.db b/packs/sorts-narcos.db index 0b3cc48b..23ad348d 100644 --- a/packs/sorts-narcos.db +++ b/packs/sorts-narcos.db @@ -7,9 +7,9 @@ {"_id":"FpwaK1qJxKGs9HgS","name":"Permanence *","type":"sort","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.sorts-narcos.FpwaK1qJxKGs9HgS"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_narcos.webp","effects":[],"system":{"description":"
C'est par ce rituel que le haut-rêvant stabilise les points de rêve d'une potion ou d'un objet, afin d'en prévenir l'évaporation quotidienne. Facultatif pour les potions, le rituel de Permanence est obligatoire pour tous les autres objets magiques. Son accomplissement diminue de 1 point le seuil de rêve du haut-rêvant.
","descriptionmj":"","draconic":"Voie de Narcos","duree":"Instantanée","JR":"","cible":"","difficulte":"-5","portée":"","caseTMR":"sanctuaire","caseTMRspeciale":"","ptreve":"5","xp":0,"bonuscase":"","isrituel":true,"coutseuil":1,"portee":""},"ownership":{"default":0,"6ibmdmaeRSMTjU4c":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.0.32","coreVersion":"10.288","createdTime":1667259638599,"modifiedTime":1667260043444,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}} {"_id":"KW2VZhuEGJGglGcW","name":"Restauration *","type":"sort","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.sorts-narcos.KW2VZhuEGJGglGcW"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_narcos.webp","effects":[],"system":{"description":"Restauration est un rituel secondaire nullement obligatoire. Son seul usage est de redonner des points de rêve actifs à une amulette de protection. Il est en effet impossible d'utiliser le simple Enchantement une fois le rituel de Permanence accompli. Restauration fonctionne de façon semblable à un Enchantement, sauf que son accomplissement coûte chaque fois un point de seuil. On peut restaurer les points de rêve d'une amulette en plusieurs fois en intercalant un rituel de Purifcation entre chaque rituel de Restauration (qui coûte chaque fois un point de seuil). Il est possible de redonner plus de points de rêve actifs à l'objet qu'il n'en avait au départ, jusqu'à concurrence du maximum possible. Le nombre maximum de points de rêve actifs qu'un objet puisse posséder est égal à 7 fois l'enchantabilité de sa gemme.
","descriptionmj":"","draconic":"Voie de Narcos","duree":"Instantanée","JR":"Aucun","cible":"","difficulte":"-6","portée":"","caseTMR":"cite","caseTMRspeciale":"","ptreve":"1+","xp":0,"bonuscase":"","isrituel":true,"coutseuil":1,"portee":""},"ownership":{"default":0,"6ibmdmaeRSMTjU4c":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.0.32","coreVersion":"10.288","createdTime":1667259638599,"modifiedTime":1667260043444,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}} {"name":"Annulation de magie","type":"sort","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.sorts-narcos.BibuJdKmaQJm3kFw"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_vigilance.webp","effects":[],"system":{"description":"Ce rituel permet d’annuler un effet magique, que celui-ci ait été accompli par soi-même ou par un autre haut-rêvant. On peut annuler l’effet d’un sort, de zone ou individuel, d’un rituel d’enchantement, d’une invocation, etc.
\nLe haut-rêvant doit se trouver dans la case spécifique des TMR d’où la magie a été accomplie. Le jet de RÊVE qu’il doit réussir a alors la même difficulté que celui ayant permis la magie, avec une dépense de points de rêve pareillement identique.
\nPour annuler une invocation, le rituel d’Annulation doit être ciblé sur la créature invoquée. Quand la magie est le résultat conjoint de plusieurs rituels, ce qui est notamment le cas des objets magiques, chacun doit être annulé tour à tour, en commençant toujours par le dernier à avoir été accompli chronologiquement. D’une manière générale, ce sont les mêmes opérations qui doivent être répétées à l’envers. Quand un rituel coûte des points de seuil, son annulation en coûte également (le même nombre). Annulation de Magie sert également à exorciser les entités de cauchemar non incarnées. La difficulté d’un exorcisme est toujours R-7, et le coût en points de rêve égal au RÊVE de l’entité. Le ciblage doit être fait sur la créature possédée.
\nAvant d’accomplir une Annulation de Magie, les paramètres de la magie à annuler (case des TMR, R-, r) peuvent être découverts au moyen du rituel Lecture d’Aura.
\nPour la synthèse d’Annulation de Magie, considérer que ce rituel est de difficulté R-7. Il peut être utilisé indifféremment par Oniros, Hypnos ou Narcos (mais jamais Thanatos), quelle que soit la voie ayant servi à accomplir la magie à annuler.
","descriptionmj":"","draconic":"Voie de Narcos","duree":"Instantanée","JR":"Aucun","cible":"Effet magique","difficulte":"variable","portée":"","caseTMR":"special","caseTMRspeciale":"variable","ptreve":"variable","xp":0,"bonuscase":"","isrituel":true,"coutseuil":0,"portee":""},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.0.32","coreVersion":"10.288","createdTime":1667259638598,"modifiedTime":1667260043440,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"},"_id":"MM7Qe6gDaeuIggIR","folder":null,"sort":0,"ownership":{"default":0,"Hp9ImM4o9YRTSdfu":3}} -{"name":"Détection d'aura","type":"sort","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.sorts-narcos.xOicgRMCUxJNmVzF"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_vigilance.webp","effects":[],"system":{"description":"Les rituels de Détection d’Aura peuvent indifféremment être accomplis par n’importe laquelle des quatre voies.
\nToutes les créatures vivantes animées (humains, humanoïdes, animaux) ont une caractéristique RÊVE. Les objets enchantés possèdent des points de rêve, de même que les produits de magie naturelle, comme certaines pierres de chance. Les entités de cauchemar, incarnées ou non, en ont également. Quelle qu’elle soit, la présence de rêve émet une aura, laquelle est détectable par Détection d’Aura. Parallèlement, toute cible d’un sort ou d’un rituel, émet une aura propre, quand bien même ladite cible ne possède pas de points de rêve (centre de zone, objet ou plante soumis à une illusion d’Hypnos). Cette aura est également détectable par Détection d’Aura.
\nL’aura de présence de rêve se traduit par un halo bleuté constant ; l’aura résultant d’un effet magique par un halo parcouru de pulsations. Quand les deux auras sont présentes conjointement, le halo est pulsatif et d’un bleu plus foncé. On peut toujours effectuer Détection d’Aura sans aucun risque, il y a toujours une réponse. Soit une aura est perçue, constante ou pulsative, et l’on peut tenter une Lecture d’Aura pour en savoir plus ; soit aucune aura n’est perçue et il s’agit de matière inerte, sans rêve, non soumise à un sort.
","descriptionmj":"","draconic":"Voie de Narcos","duree":"Instantanée","JR":"Aucun","cible":"","difficulte":"-3","portée":"","caseTMR":"sanctuaire","caseTMRspeciale":"","ptreve":"1","xp":0,"bonuscase":"","isrituel":false,"coutseuil":0,"portee":""},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.0.32","coreVersion":"10.288","createdTime":1667259638601,"modifiedTime":1667260043441,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"},"_id":"NVGQJp4lPcMxnpaT","folder":null,"sort":0,"ownership":{"default":0,"Hp9ImM4o9YRTSdfu":3}} +{"name":"Détection d'aura","type":"sort","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.sorts-narcos.xOicgRMCUxJNmVzF"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_vigilance.webp","effects":[],"system":{"description":"Les rituels de Détection d’Aura peuvent indifféremment être accomplis par n’importe laquelle des quatre voies.
\nToutes les créatures vivantes animées (humains, humanoïdes, animaux) ont une caractéristique RÊVE. Les objets enchantés possèdent des points de rêve, de même que les produits de magie naturelle, comme certaines pierres de chance. Les entités de cauchemar, incarnées ou non, en ont également. Quelle qu’elle soit, la présence de rêve émet une aura, laquelle est détectable par Détection d’Aura. Parallèlement, toute cible d’un sort ou d’un rituel, émet une aura propre, quand bien même ladite cible ne possède pas de points de rêve (centre de zone, objet ou plante soumis à une illusion d’Hypnos). Cette aura est également détectable par Détection d’Aura.
\nL’aura de présence de rêve se traduit par un halo bleuté constant ; l’aura résultant d’un effet magique par un halo parcouru de pulsations. Quand les deux auras sont présentes conjointement, le halo est pulsatif et d’un bleu plus foncé. On peut toujours effectuer Détection d’Aura sans aucun risque, il y a toujours une réponse. Soit une aura est perçue, constante ou pulsative, et l’on peut tenter une Lecture d’Aura pour en savoir plus ; soit aucune aura n’est perçue et il s’agit de matière inerte, sans rêve, non soumise à un sort.
","descriptionmj":"","draconic":"Voie de Narcos","duree":"Instantanée","JR":"Aucun","cible":"","difficulte":"-3","portée":"","caseTMR":"sanctuaire","caseTMRspeciale":"","ptreve":"1","xp":0,"bonuscase":"","isrituel":true,"coutseuil":0,"portee":""},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.4.3","coreVersion":"10.291","createdTime":1667259638601,"modifiedTime":1672364107129,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"},"_id":"NVGQJp4lPcMxnpaT","folder":null,"sort":0,"ownership":{"default":0,"Hp9ImM4o9YRTSdfu":3}} {"_id":"P9jMT8pl4pgKEoEW","name":"Écailles de Protection contre le feu *","type":"sort","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.sorts-narcos.P9jMT8pl4pgKEoEW"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_narcos.webp","effects":[],"system":{"description":"Chaque écaille de protection diminue de 1 point le jet d'encaissement de tout dommage dû au feu, jouant le rôle d'une \"armure ignifugée\". Soit un personnage possédant une telle amulette dotée de 5 écailles, et se retrouvant dans une zone d'Air en Feu. Au lieu de jouer un jet d'encaissement à +10, il ne la joue qu'à +5. La protection de l'amulette est en plus de la protection physique qu'il peut avoir, laquelle ne peut être - rappelons-le - que d'un maximum de 2 points.
\nUne amulette peut avoir n'importe quelle forme, mais ne fonctionne que si elle est en contact avec la peau nue de son possesseur. Si c'est le cas, elle fonctionne spontanément en face du danger pour lequel elle est conçue, même si le possesseur n'a aucune idée de son pouvoir. Pour fonctionner, l'amulette a besoin de points de rêve actifs. Ces points doivent être des points de rêve conférés par le rituel d'Enchantement en plus des points inertes. Autrement dit, voulant fabriquer une amulette, le haut-rêvant ne s'arrête pas d'enchanter quand il atteint un nombre de points de rêve égal à l'inertie totale de l'objet, mais continue à en rajouter. Le nombre maximum de points actifs qu'une amulette puisse posséder est égal à 7 fois l'enchantabilité de sa gemme ; et, comme pour les écailles d'efficacité, le nombre d'écailles de protection qu'elle puisse posséder est égal à l'enchantabilité de celle-ci avec un maximum de 7. Des amulettes plus puissantes ne pourraient être obtenues que par de spécifiques Grandes Écailles de Narcos.
\nSoit une gemme de taille 6 et de pureté 5, ayant donc une inertie de 2 et une enchantabilité de 4. Elle peut posséder jusqu'à 4 écailles de protection (=enchantabilité) et un maximum de 28 points de rêve actifs (7 x 4 = 28).
\nChaque fois qu'une amulette de protection fonctionne, elle dépense un de ses points de rêve actifs quel que soit le nombre d'écailles. Le possesseur, lui, n'en dépense qu'un par heure, quel que soit le nombre de fonctionnements de l'amulette au cours de cette heure. Quand une amulette n'a plus de points actifs, elle cesse de fonctionner. On ne peut lui en redonner que par le rituel de Restauration. Les écailles de protection peuvent être posées progressivement, comme celles d'efficacité, même si l'amulette fonctionne entre temps. Mêmes règles d'application. Une gemme donnée ne peut recevoir que des écailles de protection d'un même type, mais grâce à Individualité, plusieurs gemmes d'une même amulette peuvent offrir des protections différentes. La pose de chaque écaille de protection coûte un point de seuil.
\n","descriptionmj":"","draconic":"Voie de Narcos","duree":"Instantanée","JR":"Aucun","cible":"","difficulte":"-6","portée":"","caseTMR":"desert","caseTMRspeciale":"","ptreve":"4","xp":0,"bonuscase":"","isrituel":true,"coutseuil":1,"portee":""},"ownership":{"default":0,"6ibmdmaeRSMTjU4c":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.0.32","coreVersion":"10.288","createdTime":1667259638599,"modifiedTime":1667260043441,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}} -{"name":"Lecture d'aura","type":"sort","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.sorts-narcos.Y4r9kTN2brWC2N0n"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_vigilance.webp","effects":[],"system":{"description":"
Les rituels de Lecture d’Aura peuvent indifféremment être accomplis par n’importe laquelle des quatre voies.
\nCe rituel permet d’approfondir les informations fournies par Détection d’Aura. Pratiquer Lecture d’Aura quand il n’y a pas d’aura revient à demander une magie impossible et crée immédiatement une déchirure du rêve.
\nLecture d’Aura est effectuée en plusieurs étapes, toutes étant de difficulté R-3 et coûtant 3 points de rêve. La première a toujours lieu dans un sanctuaire et ne fait que révéler dans quel(s) autre(s) genre(s) de case(s) le haut-rêvant doit se rendre pour continuer sa lecture. Là, il apprend quel genre de magie a été produit ou à quel type de rêve il a affaire, de même que les cases spécifiques concernées. Enfin dans les cases spécifiques, le haut-rêvant peut apprendre la force du rêve ou de la magie en cours, c’est-à-dire pratiquement la difficulté et le nombre de points de rêve impliqués, information indispensable dans l’optique d’une annulation de magie.
\nLecture d’Aura révèle également la couleur de l’aura (fixe ou pulsative) comme Détection d’Aura. Pour les créatures vivantes, on peut donc sauter l’étape de Détection d’Aura et commencer directement par la lecture, puisqu’on est sûr de trouver une aura. Dans les autres cas, il est plus prudent de commencer par la détection si, en l’absence finale d’une aura, on ne veut pas créer de magie impossible. Effectuée sur une créature non soumise à un effet magique ni sous l’emprise d’une entité, Lecture d’Aura indique toujours le Fleuve. Là, dans n’importe quelle case du Fleuve, le haut-rêvant se contente d’apprendre qu’il a affaire à une créature vivante et douée de rêve.
","descriptionmj":"","draconic":"Voie de Narcos","duree":"Instantanée","JR":"Aucun","cible":"","difficulte":"-3","portée":"","caseTMR":"special","caseTMRspeciale":"Sanctuaire / variable","ptreve":"3","xp":0,"bonuscase":"","isrituel":false,"coutseuil":0,"portee":""},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.0.32","coreVersion":"10.288","createdTime":1667259638600,"modifiedTime":1667260043443,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"},"_id":"QvAyeJIIEssOhJoV","folder":null,"sort":0,"ownership":{"default":0,"Hp9ImM4o9YRTSdfu":3}} +{"name":"Lecture d'aura","type":"sort","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.sorts-narcos.Y4r9kTN2brWC2N0n"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_vigilance.webp","effects":[],"system":{"description":"Les rituels de Lecture d’Aura peuvent indifféremment être accomplis par n’importe laquelle des quatre voies.
\nCe rituel permet d’approfondir les informations fournies par Détection d’Aura. Pratiquer Lecture d’Aura quand il n’y a pas d’aura revient à demander une magie impossible et crée immédiatement une déchirure du rêve.
\nLecture d’Aura est effectuée en plusieurs étapes, toutes étant de difficulté R-3 et coûtant 3 points de rêve. La première a toujours lieu dans un sanctuaire et ne fait que révéler dans quel(s) autre(s) genre(s) de case(s) le haut-rêvant doit se rendre pour continuer sa lecture. Là, il apprend quel genre de magie a été produit ou à quel type de rêve il a affaire, de même que les cases spécifiques concernées. Enfin dans les cases spécifiques, le haut-rêvant peut apprendre la force du rêve ou de la magie en cours, c’est-à-dire pratiquement la difficulté et le nombre de points de rêve impliqués, information indispensable dans l’optique d’une annulation de magie.
\nLecture d’Aura révèle également la couleur de l’aura (fixe ou pulsative) comme Détection d’Aura. Pour les créatures vivantes, on peut donc sauter l’étape de Détection d’Aura et commencer directement par la lecture, puisqu’on est sûr de trouver une aura. Dans les autres cas, il est plus prudent de commencer par la détection si, en l’absence finale d’une aura, on ne veut pas créer de magie impossible. Effectuée sur une créature non soumise à un effet magique ni sous l’emprise d’une entité, Lecture d’Aura indique toujours le Fleuve. Là, dans n’importe quelle case du Fleuve, le haut-rêvant se contente d’apprendre qu’il a affaire à une créature vivante et douée de rêve.
","descriptionmj":"","draconic":"Voie de Narcos","duree":"Instantanée","JR":"Aucun","cible":"","difficulte":"-3","portée":"","caseTMR":"special","caseTMRspeciale":"Sanctuaire / variable","ptreve":"3","xp":0,"bonuscase":"","isrituel":true,"coutseuil":0,"portee":""},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.4.3","coreVersion":"10.291","createdTime":1667259638600,"modifiedTime":1672364101034,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"},"_id":"QvAyeJIIEssOhJoV","folder":null,"sort":0,"ownership":{"default":0,"Hp9ImM4o9YRTSdfu":3}} {"_id":"SUrdOuvvelLtiZMy","name":"Écailles de Protection contre les projectiles *","type":"sort","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.sorts-narcos.SUrdOuvvelLtiZMy"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_narcos.webp","effects":[],"system":{"description":"Chaque écaille de protection diminue de 1 point le jet d'encaissement de tout dommage dû à un projectile, flèche, carreau, pierre de fronde, dague, javelot, fouet. La protection de l'amulette est en plus de l'armure véritable du personnage. Soit un personnage vêtu de cuir épais (prot. 3), possédant une amulette de 3 écailles, et recevant une flèche (+dom +2). Face à une flèche, le cuir épais ne vaut plus que 1, mais on y rajoute les 3 écailles de l'amulette, pour un jet d'encaissement final de -2 au lieu de +1.
\nUne amulette peut avoir n'importe quelle forme, mais ne fonctionne que si elle est en contact avec la peau nue de son possesseur. Si c'est le cas, elle fonctionne spontanément en face du danger pour lequel elle est conçue, même si le possesseur n'a aucune idée de son pouvoir. Pour fonctionner, l'amulette a besoin de points de rêve actifs. Ces points doivent être des points de rêve conférés par le rituel d'Enchantement en plus des points inertes. Autrement dit, voulant fabriquer une amulette, le haut-rêvant ne s'arrête pas d'enchanter quand il atteint un nombre de points de rêve égal à l'inertie totale de l'objet, mais continue à en rajouter. Le nombre maximum de points actifs qu'une amulette puisse posséder est égal à 7 fois l'enchantabilité de sa gemme ; et, comme pour les écailles d'efficacité, le nombre d'écailles de protection qu'elle puisse posséder est égal à l'enchantabilité de celle-ci avec un maximum de 7. Des amulettes plus puissantes ne pourraient être obtenues que par de spécifiques Grandes Écailles de Narcos.
\nSoit une gemme de taille 6 et de pureté 5, ayant donc une inertie de 2 et une enchantabilité de 4. Elle peut posséder jusqu'à 4 écailles de protection (=enchantabilité) et un maximum de 28 points de rêve actifs (7 x 4 = 28).
\nChaque fois qu'une amulette de protection fonctionne, elle dépense un de ses points de rêve actifs quel que soit le nombre d'écailles. Le possesseur, lui, n'en dépense qu'un par heure, quel que soit le nombre de fonctionnements de l'amulette au cours de cette heure. Quand une amulette n'a plus de points actifs, elle cesse de fonctionner. On ne peut lui en redonner que par le rituel de Restauration. Les écailles de protection peuvent être posées progressivement, comme celles d'efficacité, même si l'amulette fonctionne entre temps. Mêmes règles d'application. Une gemme donnée ne peut recevoir que des écailles de protection d'un même type, mais grâce à Individualité, plusieurs gemmes d'une même amulette peuvent offrir des protections différentes. La pose de chaque écaille de protection coûte un point de seuil.
\n","descriptionmj":"","draconic":"Voie de Narcos","duree":"Instantanée","JR":"Aucun","cible":"","difficulte":"-8","portée":"","caseTMR":"gouffre","caseTMRspeciale":"","ptreve":"6","xp":0,"bonuscase":"","isrituel":true,"coutseuil":1,"portee":""},"ownership":{"default":0,"6ibmdmaeRSMTjU4c":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.0.32","coreVersion":"10.288","createdTime":1667259638599,"modifiedTime":1667260043442,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}} {"_id":"TSDY6o00ri2ktlVM","name":"Puits de rêve *","type":"sort","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.sorts-narcos.TSDY6o00ri2ktlVM"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_narcos.webp","effects":[],"system":{"description":"
Le Puits de rêve permet de stocker des points de rêve et de les y puiser à volonté, c'est en quelque sorte une tirelire de points de rêve. Le Puits de rêve peut avoir la forme de n'importe quel objet et même se contenter d'être une gemme seule. Pour y stocker des points de rêve, l'utilisateur doit le tenir dans sa main nue et se concentrer pendant un round. Il perd autant de points de rêve que souhaité, points qui sont instantanément transvasés dans le Puits de rêve. Aucune montée en TMR ni jets de dés ne sont nécessaires. Pareillement, pour puiser des points de rêve dans le Puits, il suffit de le tenir dans sa main nue au moment de lancer un sort. Au lieu de dépenser ses propres points, l'utilisateur les puise dans le Puits de rêve. Les points puisés ne peuvent avoir qu'un seul usage : alimenter un sort, lancé naturellement ou via une écaille d'activité, ou alimenter un rituel. Rien d'autre. Il ne peuvent pas servir à payer un coût de maîtrise ni un coût d'objet efficace, ni un coût d'amulette de protection. La dépense de points de rêve doit provenir intégralement de l'une ou l'autre source, utilisateur ou Puits de rêve, on ne peut pas partager. On ne peut pas non plus les récupérer pour les \"remettre dans sa tête\".
\nLa gemme destinée à recevoir un Puits de rêve n'a pas besoin de points actifs ; si elle en a lors de l'accomplissement de Permanence, ils sont purement et simplement ignorés (annulés). La gemme peut recevoir autant de Grandes Écailles de Puits de rêve que son enchantibilité jusqu'à un maximum de 7. Chaque Grande Écaille permet de stocker jusqu'à 7 points de rêve. Soit une gemme d'enchantabilité 6 possédant 6 Grandes Écailles de Puits de rêve, on peut y stocker jusqu'à 42 points de rêve. Un Puits de rêve n'a jamais besoin d'être entièrement plein et peut pareillement rester vide sans en souffrir. Face à une grosse dépense, on peut le vider entièrement d'un seul coup.
\nUn Puits de rêve peut être posé (avec Individualité) sur une seconde gemme d'un objet possédant une écaille d'activité. Lors de l'utilisation de l'objet, les points de rêve de coût de sort pourront être dépensés par le Puits de rêve ou par l'utilisateur au choix de ce dernier. Un Puits de rêve changeant de main doit être maîtrisé selon la règle normale. La maîtrise a lieu soit au moment où l'on stocke, soit où l'on puise, le premier des deux, et coûte 1 point de rêve par Grande Écaille. Note : les points dépensés pour la maîtrise ne vont pas dans le Puis de rêve, sils ont perdus.
","descriptionmj":"","draconic":"Voie de Narcos","duree":"Instantanée","JR":"Aucun","cible":"","difficulte":"-8","portée":"","caseTMR":"lac","caseTMRspeciale":"","ptreve":"8","xp":0,"bonuscase":"","isrituel":true,"coutseuil":1,"portee":""},"ownership":{"default":0,"6ibmdmaeRSMTjU4c":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.0.32","coreVersion":"10.288","createdTime":1667259638599,"modifiedTime":1667260043444,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}} {"_id":"TjhnUMh6UL04k0k8","name":"Purification","type":"sort","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.sorts-narcos.TjhnUMh6UL04k0k8"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_narcos.webp","effects":[],"system":{"description":"Purification est un rituel secondaire, mais néanmoins obligatoire. A moins de disposer d'une énorme quantité de points de rêve, il est vain d'espérer enchanter l'objet en une seule fois. Purifcation doit toujours s'intercaler entre deux rituels identiques : entre deux Enchantements, mais également entre deux écailles, d'activité ou de protection. Sauter cette étape aboutit à un cas de magie impossible.
","descriptionmj":"","draconic":"Voie de Narcos","duree":"Instantanée","JR":"Aucun","cible":"","difficulte":"-4","portée":"","caseTMR":"necropole","caseTMRspeciale":"","ptreve":"4","xp":0,"bonuscase":"","isrituel":true,"coutseuil":0,"portee":""},"ownership":{"default":0,"6ibmdmaeRSMTjU4c":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.0.32","coreVersion":"10.288","createdTime":1667259638599,"modifiedTime":1667260043444,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}} diff --git a/packs/sorts-oniros.db b/packs/sorts-oniros.db index e4251ca3..6c59ddfc 100644 --- a/packs/sorts-oniros.db +++ b/packs/sorts-oniros.db @@ -48,7 +48,7 @@ {"_id":"cHOcwNOGQtiU4g0P","name":"Élargissement de zone","type":"sort","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.sorts-oniros.cHOcwNOGQtiU4g0P"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_oniros.webp","effects":[],"system":{"description":"Les rituels d’Oniros obéissent à toutes les règles des rituels : leurs chances de réussite sont ajustées astrologiquement selon l’heure de naissance du haut-rêvant, et ils ne peuvent être mis en réserve. Chaque étoile * dont peut être suivi le titre d’un rituel indique le coût d’un point de seuil de rêve. Le seuil est diminué aussitôt le rituel accompli. Chaque Rêve de Dragon vaincu permet d’en regagner 1 point.
\nCe rituel permet de doubler le diamètre des zones de Transmutation Élémentale et de quadrupler celui des autres sorts de zone. Le diamètre des zones de transmutation peut ainsi faire jusqu’à 6 mètres et celui des autres jusqu’à 12 mètres.
\nLe rituel doit être préalablement accompli dans la case d’où sera ensuite lancé le sort de zone. Il n’y a aucun temps limite entre le moment où le rituel est accompli et celui où sera lancé le sort de zone. Tout se passe comme si l’effet était en réserve.
\nPareillement, le demi-rêve ne redescend pas obligatoirement après l’accomplissement du rituel, cette option est au choix du haut-rêvant, qui peut lancer son sort de zone sans avoir à remonter en TMR.
\nLa seule restriction est que le prochain sort à être lancé depuis la case en question devra obligatoirement être un sort de zone. Contrevenir à cette règle crée instantanément une déchirure du rêve centrée sur le haut-rêvant. Bulle Volante, Barque de Rêve, Lanterne et Pont Immatériel ne sont pas affectés par ce rituel.
","descriptionmj":"","draconic":"Voie d'Oniros","duree":"Spéciale","JR":"Aucun","cible":"","difficulte":"-4","portée":"","caseTMR":"special","caseTMRspeciale":"variable","ptreve":"4","xp":0,"bonuscase":"","isrituel":true,"coutseuil":0},"ownership":{"default":0,"jOzRscDxoXZWpGS6":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.0.32","coreVersion":"10.288","createdTime":1667259472746,"modifiedTime":1667260037973,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}} {"_id":"cxPrEAv1kBXewoyh","name":"Métal en terre","type":"sort","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.sorts-oniros.cxPrEAv1kBXewoyh"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_oniros.webp","effects":[],"system":{"description":"Le principe de la Transmutation Élémentale est de transformer un élément en un autre, par exemple le métal en bois, l’air en feu. Il n’existe de transmutation que pour les six premiers éléments. La matière dont sont composées les créatures, mortes ou vivantes, n’est jamais transmuée, y compris l’air contenu dans les poumons. Il existe 26 transmutations élémentales ; chacune est un sort à part entière, obéissant en tout point aux règles des sorts de zone.
\nLa transmutation a lieu dans la zone paramétrée et ciblée par le haut-rêvant. Tout ce qui appartient à l’élément impliqué est transmué instantanément sans discrimination. On ne peut pas faire de choix. Tant que dure la zone, tout nouvel objet appartenant à l’élément impliqué qui pénètre dans la zone, est immédiatement transmué à son tour. La zone peut fort bien être lancée sur un lieu où l’élément impliqué n’existe pas, par exemple Terre en Eau à 5 m du sol. Rien ne se produira au premier abord, mais toute pierre lancée dans la zone sera instantanément liquéfiée pour retomber sous forme de pluie.
\nTout objet transmué, situé ou entrant dans la zone, adopte aussitôt la forme que lui permet le nouvel élément. On peut obtenir de gracieuses torsades avec du feu transmué en bois ou en métal. La transmutation est définitive, même si l’objet sort de la zone. À la fin de la zone (HN), l’effet cesse d’opérer, mais la matière transmuée le demeure définitivement sans recouvrer non plus son élément d’origine.
\nQuand une créature vivante se retrouve dans une zone de Transmutation Élémentale, bien que la matière dont elle est composée ne soit pas affectée en elle-même, elle subit l’effet naturel et normal du nouvel élément qui l’entoure, sans jet de résistance. Une créature prise dans une zone d’Air en Feu se retrouve dans un brasier qui la brûle, une créature nageant prise dans une zone d’Eau en Bois se retrouve enkystée dans un bloc de bois, etc.
\nL’élément Eau correspondant à tous les liquides d’origine non animale, réellement aqueux ou non, c’est tout le liquide qui est transmué et non pas uniquement ses molécules de H2O, y compris tout ce qui peut y être dissout (sels, cristaux). L’eau d’un végétal (sève, jus d’un fruit) appartient à l’élément Bois, qui est celui du végétal, tant qu’il est contenu dans ce dernier. L’humus appartient intégralement à l’élément Terre, même s’il est composé en grande partie de matière végétale (Bois) non encore décomposée.
\nX élément en Air : Pratiquement, l’ancien élément disparaît dans un courant d’air. L’air d’arrivée est toujours frais et pur.
\nX élément en Terre : L’élément d’arrivée est une roche friable et fragile comme de la craie.
\nX élément en Eau : L’eau nouvellement créée se comporte naturellement, attirée par la pesanteur : elle pleut, coule, cherche à s’infiltrer. Elle a la pureté de l’eau distillée.
\nX élément en Feu : L’ancien élément devenu Feu n’est plus que flammes. Toutefois, pour que ces nouvelles flammes continuent à brûler, il leur faut un combustible, faute de quoi elles s’éteignent. Quand c’est l’Air qui est transmué en Feu, celui-ci demeure même sans combustible, car l’Air entourant la zone la comble immédiatement, devenant Feu à son tour. Le résultat est une sphère en permanente ignition. Il en va de même pour l’eau au centre d’une rivière par exemple.
\nX élément en Bois : Le bois d’arrivée est un bois de qualité médiocre, du genre sapin, mais sec, sans aucune sève ni résine, combustible ou façonnable.
\nX élément en Métal : Il ne s’agit toujours que des deux métaux les plus inertes : fer ou plomb (tirer à pile ou face). Le fer de transmutation n’est ni de l’acier ni du fer forgé, c’est du fer natif, mou et sans dureté. Un forgeron peut néanmoins le travailler.
\nÀ mi-chemin entre les créatures et la matière inerte, les objets magiques ont droit à un jet de résistance pour ne pas être impliqués dans une transmutation. C’est un JR spécial, r0, où la protection magique du matériau est prise en guise de points de rêve (voir Résistance).
","descriptionmj":"","draconic":"Voie d'Oniros","duree":"HN","JR":"Aucun","cible":"","difficulte":"-6","portée":"","caseTMR":"plaines","caseTMRspeciale":"","ptreve":"4","xp":0,"bonuscase":"","isrituel":false,"coutseuil":0},"ownership":{"default":0,"jOzRscDxoXZWpGS6":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.0.32","coreVersion":"10.288","createdTime":1667259472746,"modifiedTime":1667260037974,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}} {"_id":"d7ke82YZPECyZXUY","name":"Feu en métal","type":"sort","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.sorts-oniros.d7ke82YZPECyZXUY"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_oniros.webp","effects":[],"system":{"description":"Le principe de la Transmutation Élémentale est de transformer un élément en un autre, par exemple le métal en bois, l’air en feu. Il n’existe de transmutation que pour les six premiers éléments. La matière dont sont composées les créatures, mortes ou vivantes, n’est jamais transmuée, y compris l’air contenu dans les poumons. Il existe 26 transmutations élémentales ; chacune est un sort à part entière, obéissant en tout point aux règles des sorts de zone.
\nLa transmutation a lieu dans la zone paramétrée et ciblée par le haut-rêvant. Tout ce qui appartient à l’élément impliqué est transmué instantanément sans discrimination. On ne peut pas faire de choix. Tant que dure la zone, tout nouvel objet appartenant à l’élément impliqué qui pénètre dans la zone, est immédiatement transmué à son tour. La zone peut fort bien être lancée sur un lieu où l’élément impliqué n’existe pas, par exemple Terre en Eau à 5 m du sol. Rien ne se produira au premier abord, mais toute pierre lancée dans la zone sera instantanément liquéfiée pour retomber sous forme de pluie.
\nTout objet transmué, situé ou entrant dans la zone, adopte aussitôt la forme que lui permet le nouvel élément. On peut obtenir de gracieuses torsades avec du feu transmué en bois ou en métal. La transmutation est définitive, même si l’objet sort de la zone. À la fin de la zone (HN), l’effet cesse d’opérer, mais la matière transmuée le demeure définitivement sans recouvrer non plus son élément d’origine.
\nQuand une créature vivante se retrouve dans une zone de Transmutation Élémentale, bien que la matière dont elle est composée ne soit pas affectée en elle-même, elle subit l’effet naturel et normal du nouvel élément qui l’entoure, sans jet de résistance. Une créature prise dans une zone d’Air en Feu se retrouve dans un brasier qui la brûle, une créature nageant prise dans une zone d’Eau en Bois se retrouve enkystée dans un bloc de bois, etc.
\nL’élément Eau correspondant à tous les liquides d’origine non animale, réellement aqueux ou non, c’est tout le liquide qui est transmué et non pas uniquement ses molécules de H2O, y compris tout ce qui peut y être dissout (sels, cristaux). L’eau d’un végétal (sève, jus d’un fruit) appartient à l’élément Bois, qui est celui du végétal, tant qu’il est contenu dans ce dernier. L’humus appartient intégralement à l’élément Terre, même s’il est composé en grande partie de matière végétale (Bois) non encore décomposée.
\nX élément en Air : Pratiquement, l’ancien élément disparaît dans un courant d’air. L’air d’arrivée est toujours frais et pur.
\nX élément en Terre : L’élément d’arrivée est une roche friable et fragile comme de la craie.
\nX élément en Eau : L’eau nouvellement créée se comporte naturellement, attirée par la pesanteur : elle pleut, coule, cherche à s’infiltrer. Elle a la pureté de l’eau distillée.
\nX élément en Feu : L’ancien élément devenu Feu n’est plus que flammes. Toutefois, pour que ces nouvelles flammes continuent à brûler, il leur faut un combustible, faute de quoi elles s’éteignent. Quand c’est l’Air qui est transmué en Feu, celui-ci demeure même sans combustible, car l’Air entourant la zone la comble immédiatement, devenant Feu à son tour. Le résultat est une sphère en permanente ignition. Il en va de même pour l’eau au centre d’une rivière par exemple.
\nX élément en Bois : Le bois d’arrivée est un bois de qualité médiocre, du genre sapin, mais sec, sans aucune sève ni résine, combustible ou façonnable.
\nX élément en Métal : Il ne s’agit toujours que des deux métaux les plus inertes : fer ou plomb (tirer à pile ou face). Le fer de transmutation n’est ni de l’acier ni du fer forgé, c’est du fer natif, mou et sans dureté. Un forgeron peut néanmoins le travailler.
\nÀ mi-chemin entre les créatures et la matière inerte, les objets magiques ont droit à un jet de résistance pour ne pas être impliqués dans une transmutation. C’est un JR spécial, r0, où la protection magique du matériau est prise en guise de points de rêve (voir Résistance).
","descriptionmj":"","draconic":"Voie d'Oniros","duree":"HN","JR":"Aucun","cible":"","difficulte":"-6","portée":"","caseTMR":"sanctuaire","caseTMRspeciale":"","ptreve":"4","xp":0,"bonuscase":"","isrituel":false,"coutseuil":0},"ownership":{"default":0,"jOzRscDxoXZWpGS6":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.0.32","coreVersion":"10.288","createdTime":1667259472746,"modifiedTime":1667260037973,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}} -{"name":"Lecture d'aura","type":"sort","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.sorts-oniros.Y4r9kTN2brWC2N0n"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_vigilance.webp","effects":[],"system":{"description":"Les rituels de Lecture d’Aura peuvent indifféremment être accomplis par n’importe laquelle des quatre voies.
\nCe rituel permet d’approfondir les informations fournies par Détection d’Aura. Pratiquer Lecture d’Aura quand il n’y a pas d’aura revient à demander une magie impossible et crée immédiatement une déchirure du rêve.
\nLecture d’Aura est effectuée en plusieurs étapes, toutes étant de difficulté R-3 et coûtant 3 points de rêve. La première a toujours lieu dans un sanctuaire et ne fait que révéler dans quel(s) autre(s) genre(s) de case(s) le haut-rêvant doit se rendre pour continuer sa lecture. Là, il apprend quel genre de magie a été produit ou à quel type de rêve il a affaire, de même que les cases spécifiques concernées. Enfin dans les cases spécifiques, le haut-rêvant peut apprendre la force du rêve ou de la magie en cours, c’est-à-dire pratiquement la difficulté et le nombre de points de rêve impliqués, information indispensable dans l’optique d’une annulation de magie.
\nLecture d’Aura révèle également la couleur de l’aura (fixe ou pulsative) comme Détection d’Aura. Pour les créatures vivantes, on peut donc sauter l’étape de Détection d’Aura et commencer directement par la lecture, puisqu’on est sûr de trouver une aura. Dans les autres cas, il est plus prudent de commencer par la détection si, en l’absence finale d’une aura, on ne veut pas créer de magie impossible. Effectuée sur une créature non soumise à un effet magique ni sous l’emprise d’une entité, Lecture d’Aura indique toujours le Fleuve. Là, dans n’importe quelle case du Fleuve, le haut-rêvant se contente d’apprendre qu’il a affaire à une créature vivante et douée de rêve.
","descriptionmj":"","draconic":"Voie d'Hypnos","duree":"Instantanée","JR":"Aucun","cible":"","difficulte":"-3","portée":"","caseTMR":"special","caseTMRspeciale":"Sanctuaire / variable","ptreve":"3","xp":0,"bonuscase":"","isrituel":false,"coutseuil":0,"portee":""},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.0.32","coreVersion":"10.288","createdTime":1667259472745,"modifiedTime":1667260037973,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"},"_id":"dNVah61DxVbM5bmL","folder":null,"sort":0,"ownership":{"default":0,"Hp9ImM4o9YRTSdfu":3}} +{"name":"Lecture d'aura","type":"sort","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.sorts-oniros.Y4r9kTN2brWC2N0n"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_vigilance.webp","effects":[],"system":{"description":"Les rituels de Lecture d’Aura peuvent indifféremment être accomplis par n’importe laquelle des quatre voies.
\nCe rituel permet d’approfondir les informations fournies par Détection d’Aura. Pratiquer Lecture d’Aura quand il n’y a pas d’aura revient à demander une magie impossible et crée immédiatement une déchirure du rêve.
\nLecture d’Aura est effectuée en plusieurs étapes, toutes étant de difficulté R-3 et coûtant 3 points de rêve. La première a toujours lieu dans un sanctuaire et ne fait que révéler dans quel(s) autre(s) genre(s) de case(s) le haut-rêvant doit se rendre pour continuer sa lecture. Là, il apprend quel genre de magie a été produit ou à quel type de rêve il a affaire, de même que les cases spécifiques concernées. Enfin dans les cases spécifiques, le haut-rêvant peut apprendre la force du rêve ou de la magie en cours, c’est-à-dire pratiquement la difficulté et le nombre de points de rêve impliqués, information indispensable dans l’optique d’une annulation de magie.
\nLecture d’Aura révèle également la couleur de l’aura (fixe ou pulsative) comme Détection d’Aura. Pour les créatures vivantes, on peut donc sauter l’étape de Détection d’Aura et commencer directement par la lecture, puisqu’on est sûr de trouver une aura. Dans les autres cas, il est plus prudent de commencer par la détection si, en l’absence finale d’une aura, on ne veut pas créer de magie impossible. Effectuée sur une créature non soumise à un effet magique ni sous l’emprise d’une entité, Lecture d’Aura indique toujours le Fleuve. Là, dans n’importe quelle case du Fleuve, le haut-rêvant se contente d’apprendre qu’il a affaire à une créature vivante et douée de rêve.
","descriptionmj":"","draconic":"Voie d'Hypnos","duree":"Instantanée","JR":"Aucun","cible":"","difficulte":"-3","portée":"","caseTMR":"special","caseTMRspeciale":"Sanctuaire / variable","ptreve":"3","xp":0,"bonuscase":"","isrituel":true,"coutseuil":0,"portee":""},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.4.3","coreVersion":"10.291","createdTime":1667259472745,"modifiedTime":1672364164096,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"},"_id":"dNVah61DxVbM5bmL","folder":null,"sort":0,"ownership":{"default":0,"Hp9ImM4o9YRTSdfu":3}} {"_id":"es0HZ4zpzO9idrRH","name":"Feu en terre","type":"sort","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.sorts-oniros.es0HZ4zpzO9idrRH"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_oniros.webp","effects":[],"system":{"description":"Le principe de la Transmutation Élémentale est de transformer un élément en un autre, par exemple le métal en bois, l’air en feu. Il n’existe de transmutation que pour les six premiers éléments. La matière dont sont composées les créatures, mortes ou vivantes, n’est jamais transmuée, y compris l’air contenu dans les poumons. Il existe 26 transmutations élémentales ; chacune est un sort à part entière, obéissant en tout point aux règles des sorts de zone.
\nLa transmutation a lieu dans la zone paramétrée et ciblée par le haut-rêvant. Tout ce qui appartient à l’élément impliqué est transmué instantanément sans discrimination. On ne peut pas faire de choix. Tant que dure la zone, tout nouvel objet appartenant à l’élément impliqué qui pénètre dans la zone, est immédiatement transmué à son tour. La zone peut fort bien être lancée sur un lieu où l’élément impliqué n’existe pas, par exemple Terre en Eau à 5 m du sol. Rien ne se produira au premier abord, mais toute pierre lancée dans la zone sera instantanément liquéfiée pour retomber sous forme de pluie.
\nTout objet transmué, situé ou entrant dans la zone, adopte aussitôt la forme que lui permet le nouvel élément. On peut obtenir de gracieuses torsades avec du feu transmué en bois ou en métal. La transmutation est définitive, même si l’objet sort de la zone. À la fin de la zone (HN), l’effet cesse d’opérer, mais la matière transmuée le demeure définitivement sans recouvrer non plus son élément d’origine.
\nQuand une créature vivante se retrouve dans une zone de Transmutation Élémentale, bien que la matière dont elle est composée ne soit pas affectée en elle-même, elle subit l’effet naturel et normal du nouvel élément qui l’entoure, sans jet de résistance. Une créature prise dans une zone d’Air en Feu se retrouve dans un brasier qui la brûle, une créature nageant prise dans une zone d’Eau en Bois se retrouve enkystée dans un bloc de bois, etc.
\nL’élément Eau correspondant à tous les liquides d’origine non animale, réellement aqueux ou non, c’est tout le liquide qui est transmué et non pas uniquement ses molécules de H2O, y compris tout ce qui peut y être dissout (sels, cristaux). L’eau d’un végétal (sève, jus d’un fruit) appartient à l’élément Bois, qui est celui du végétal, tant qu’il est contenu dans ce dernier. L’humus appartient intégralement à l’élément Terre, même s’il est composé en grande partie de matière végétale (Bois) non encore décomposée.
\nX élément en Air : Pratiquement, l’ancien élément disparaît dans un courant d’air. L’air d’arrivée est toujours frais et pur.
\nX élément en Terre : L’élément d’arrivée est une roche friable et fragile comme de la craie.
\nX élément en Eau : L’eau nouvellement créée se comporte naturellement, attirée par la pesanteur : elle pleut, coule, cherche à s’infiltrer. Elle a la pureté de l’eau distillée.
\nX élément en Feu : L’ancien élément devenu Feu n’est plus que flammes. Toutefois, pour que ces nouvelles flammes continuent à brûler, il leur faut un combustible, faute de quoi elles s’éteignent. Quand c’est l’Air qui est transmué en Feu, celui-ci demeure même sans combustible, car l’Air entourant la zone la comble immédiatement, devenant Feu à son tour. Le résultat est une sphère en permanente ignition. Il en va de même pour l’eau au centre d’une rivière par exemple.
\nX élément en Bois : Le bois d’arrivée est un bois de qualité médiocre, du genre sapin, mais sec, sans aucune sève ni résine, combustible ou façonnable.
\nX élément en Métal : Il ne s’agit toujours que des deux métaux les plus inertes : fer ou plomb (tirer à pile ou face). Le fer de transmutation n’est ni de l’acier ni du fer forgé, c’est du fer natif, mou et sans dureté. Un forgeron peut néanmoins le travailler.
\nÀ mi-chemin entre les créatures et la matière inerte, les objets magiques ont droit à un jet de résistance pour ne pas être impliqués dans une transmutation. C’est un JR spécial, r0, où la protection magique du matériau est prise en guise de points de rêve (voir Résistance).
","descriptionmj":"","draconic":"Voie d'Oniros","duree":"HN","JR":"Aucun","cible":"","difficulte":"-6","portée":"","caseTMR":"desert","caseTMRspeciale":"","ptreve":"4","xp":0,"bonuscase":"","isrituel":false,"coutseuil":0},"ownership":{"default":0,"jOzRscDxoXZWpGS6":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.0.32","coreVersion":"10.288","createdTime":1667259472746,"modifiedTime":1667260037973,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}} {"_id":"gT2Rgz1e61Iu7gbb","name":"Feu en bois","type":"sort","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.sorts-oniros.gT2Rgz1e61Iu7gbb"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_oniros.webp","effects":[],"system":{"description":"Le principe de la Transmutation Élémentale est de transformer un élément en un autre, par exemple le métal en bois, l’air en feu. Il n’existe de transmutation que pour les six premiers éléments. La matière dont sont composées les créatures, mortes ou vivantes, n’est jamais transmuée, y compris l’air contenu dans les poumons. Il existe 26 transmutations élémentales ; chacune est un sort à part entière, obéissant en tout point aux règles des sorts de zone.
\nLa transmutation a lieu dans la zone paramétrée et ciblée par le haut-rêvant. Tout ce qui appartient à l’élément impliqué est transmué instantanément sans discrimination. On ne peut pas faire de choix. Tant que dure la zone, tout nouvel objet appartenant à l’élément impliqué qui pénètre dans la zone, est immédiatement transmué à son tour. La zone peut fort bien être lancée sur un lieu où l’élément impliqué n’existe pas, par exemple Terre en Eau à 5 m du sol. Rien ne se produira au premier abord, mais toute pierre lancée dans la zone sera instantanément liquéfiée pour retomber sous forme de pluie.
\nTout objet transmué, situé ou entrant dans la zone, adopte aussitôt la forme que lui permet le nouvel élément. On peut obtenir de gracieuses torsades avec du feu transmué en bois ou en métal. La transmutation est définitive, même si l’objet sort de la zone. À la fin de la zone (HN), l’effet cesse d’opérer, mais la matière transmuée le demeure définitivement sans recouvrer non plus son élément d’origine.
\nQuand une créature vivante se retrouve dans une zone de Transmutation Élémentale, bien que la matière dont elle est composée ne soit pas affectée en elle-même, elle subit l’effet naturel et normal du nouvel élément qui l’entoure, sans jet de résistance. Une créature prise dans une zone d’Air en Feu se retrouve dans un brasier qui la brûle, une créature nageant prise dans une zone d’Eau en Bois se retrouve enkystée dans un bloc de bois, etc.
\nL’élément Eau correspondant à tous les liquides d’origine non animale, réellement aqueux ou non, c’est tout le liquide qui est transmué et non pas uniquement ses molécules de H2O, y compris tout ce qui peut y être dissout (sels, cristaux). L’eau d’un végétal (sève, jus d’un fruit) appartient à l’élément Bois, qui est celui du végétal, tant qu’il est contenu dans ce dernier. L’humus appartient intégralement à l’élément Terre, même s’il est composé en grande partie de matière végétale (Bois) non encore décomposée.
\nX élément en Air : Pratiquement, l’ancien élément disparaît dans un courant d’air. L’air d’arrivée est toujours frais et pur.
\nX élément en Terre : L’élément d’arrivée est une roche friable et fragile comme de la craie.
\nX élément en Eau : L’eau nouvellement créée se comporte naturellement, attirée par la pesanteur : elle pleut, coule, cherche à s’infiltrer. Elle a la pureté de l’eau distillée.
\nX élément en Feu : L’ancien élément devenu Feu n’est plus que flammes. Toutefois, pour que ces nouvelles flammes continuent à brûler, il leur faut un combustible, faute de quoi elles s’éteignent. Quand c’est l’Air qui est transmué en Feu, celui-ci demeure même sans combustible, car l’Air entourant la zone la comble immédiatement, devenant Feu à son tour. Le résultat est une sphère en permanente ignition. Il en va de même pour l’eau au centre d’une rivière par exemple.
\nX élément en Bois : Le bois d’arrivée est un bois de qualité médiocre, du genre sapin, mais sec, sans aucune sève ni résine, combustible ou façonnable.
\nX élément en Métal : Il ne s’agit toujours que des deux métaux les plus inertes : fer ou plomb (tirer à pile ou face). Le fer de transmutation n’est ni de l’acier ni du fer forgé, c’est du fer natif, mou et sans dureté. Un forgeron peut néanmoins le travailler.
\nÀ mi-chemin entre les créatures et la matière inerte, les objets magiques ont droit à un jet de résistance pour ne pas être impliqués dans une transmutation. C’est un JR spécial, r0, où la protection magique du matériau est prise en guise de points de rêve (voir Résistance).
","descriptionmj":"","draconic":"Voie d'Oniros","duree":"HN","JR":"Aucun","cible":"","difficulte":"-6","portée":"","caseTMR":"collines","caseTMRspeciale":"","ptreve":"4","xp":0,"bonuscase":"","isrituel":false,"coutseuil":0},"ownership":{"default":0,"jOzRscDxoXZWpGS6":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.0.32","coreVersion":"10.288","createdTime":1667259472746,"modifiedTime":1667260037973,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}} {"_id":"hNMkPyDqh6tGCqZI","name":"Froid","type":"sort","img":"systems/foundryvtt-reve-de-dragon/icons/competence_oniros.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.sorts-oniros.hNMkPyDqh6tGCqZI"}},"system":{"description":"Ce sort fonctionne exactement de façon inverse à zone de Chaleur. Chaque point de rêve dépensé fait baisser la température dans la zone de 5 degrés. Une fois modifiée, la température dans la zone reste fixe, quelles que soient les modifications de la température extérieure. L’effet de Froid peut être un bon substitut de réfrigérateur.
","descriptionmj":"","draconic":"Voie d'Oniros","duree":"HN","JR":"Aucun","cible":"","difficulte":"-4","portée":"","caseTMR":"desolation","caseTMRspeciale":"","ptreve":"1+","xp":0,"bonuscase":"","isrituel":false,"coutseuil":0,"portee":""},"ownership":{"default":0,"jOzRscDxoXZWpGS6":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.0.32","coreVersion":"10.288","createdTime":1667259472746,"modifiedTime":1667260037973,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}} @@ -60,7 +60,7 @@ {"_id":"mW2TaRuKKuppDN2R","name":"Bois en eau","type":"sort","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.sorts-oniros.mW2TaRuKKuppDN2R"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_oniros.webp","effects":[],"system":{"description":"Le principe de la Transmutation Élémentale est de transformer un élément en un autre, par exemple le métal en bois, l’air en feu. Il n’existe de transmutation que pour les six premiers éléments. La matière dont sont composées les créatures, mortes ou vivantes, n’est jamais transmuée, y compris l’air contenu dans les poumons. Il existe 26 transmutations élémentales ; chacune est un sort à part entière, obéissant en tout point aux règles des sorts de zone.
\nLa transmutation a lieu dans la zone paramétrée et ciblée par le haut-rêvant. Tout ce qui appartient à l’élément impliqué est transmué instantanément sans discrimination. On ne peut pas faire de choix. Tant que dure la zone, tout nouvel objet appartenant à l’élément impliqué qui pénètre dans la zone, est immédiatement transmué à son tour. La zone peut fort bien être lancée sur un lieu où l’élément impliqué n’existe pas, par exemple Terre en Eau à 5 m du sol. Rien ne se produira au premier abord, mais toute pierre lancée dans la zone sera instantanément liquéfiée pour retomber sous forme de pluie.
\nTout objet transmué, situé ou entrant dans la zone, adopte aussitôt la forme que lui permet le nouvel élément. On peut obtenir de gracieuses torsades avec du feu transmué en bois ou en métal. La transmutation est définitive, même si l’objet sort de la zone. À la fin de la zone (HN), l’effet cesse d’opérer, mais la matière transmuée le demeure définitivement sans recouvrer non plus son élément d’origine.
\nQuand une créature vivante se retrouve dans une zone de Transmutation Élémentale, bien que la matière dont elle est composée ne soit pas affectée en elle-même, elle subit l’effet naturel et normal du nouvel élément qui l’entoure, sans jet de résistance. Une créature prise dans une zone d’Air en Feu se retrouve dans un brasier qui la brûle, une créature nageant prise dans une zone d’Eau en Bois se retrouve enkystée dans un bloc de bois, etc.
\nL’élément Eau correspondant à tous les liquides d’origine non animale, réellement aqueux ou non, c’est tout le liquide qui est transmué et non pas uniquement ses molécules de H2O, y compris tout ce qui peut y être dissout (sels, cristaux). L’eau d’un végétal (sève, jus d’un fruit) appartient à l’élément Bois, qui est celui du végétal, tant qu’il est contenu dans ce dernier. L’humus appartient intégralement à l’élément Terre, même s’il est composé en grande partie de matière végétale (Bois) non encore décomposée.
\nX élément en Air : Pratiquement, l’ancien élément disparaît dans un courant d’air. L’air d’arrivée est toujours frais et pur.
\nX élément en Terre : L’élément d’arrivée est une roche friable et fragile comme de la craie.
\nX élément en Eau : L’eau nouvellement créée se comporte naturellement, attirée par la pesanteur : elle pleut, coule, cherche à s’infiltrer. Elle a la pureté de l’eau distillée.
\nX élément en Feu : L’ancien élément devenu Feu n’est plus que flammes. Toutefois, pour que ces nouvelles flammes continuent à brûler, il leur faut un combustible, faute de quoi elles s’éteignent. Quand c’est l’Air qui est transmué en Feu, celui-ci demeure même sans combustible, car l’Air entourant la zone la comble immédiatement, devenant Feu à son tour. Le résultat est une sphère en permanente ignition. Il en va de même pour l’eau au centre d’une rivière par exemple.
\nX élément en Bois : Le bois d’arrivée est un bois de qualité médiocre, du genre sapin, mais sec, sans aucune sève ni résine, combustible ou façonnable.
\nX élément en Métal : Il ne s’agit toujours que des deux métaux les plus inertes : fer ou plomb (tirer à pile ou face). Le fer de transmutation n’est ni de l’acier ni du fer forgé, c’est du fer natif, mou et sans dureté. Un forgeron peut néanmoins le travailler.
\nÀ mi-chemin entre les créatures et la matière inerte, les objets magiques ont droit à un jet de résistance pour ne pas être impliqués dans une transmutation. C’est un JR spécial, r0, où la protection magique du matériau est prise en guise de points de rêve (voir Résistance).
","descriptionmj":"","draconic":"Voie d'Oniros","duree":"HN","JR":"Aucun","cible":"","difficulte":"-6","portée":"","caseTMR":"sanctuaire","caseTMRspeciale":"","ptreve":"4","xp":0,"bonuscase":"","isrituel":false,"coutseuil":0},"ownership":{"default":0,"jOzRscDxoXZWpGS6":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.0.32","coreVersion":"10.288","createdTime":1667259472747,"modifiedTime":1667260037971,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}} {"_id":"mxFnT5gQgD4bcVPk","name":"Chaleur","type":"sort","img":"systems/foundryvtt-reve-de-dragon/icons/competence_oniros.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.sorts-oniros.mxFnT5gQgD4bcVPk"}},"system":{"description":"Augmente la température dans la zone visée, à raison de 5 degrés par point de rêve dépensé. L’augmentation n’a lieu que dans la zone et n’est pas sensible à l’extérieur de celle-ci. Une fois modifiée, la température dans la zone reste fixe, quelles que soient les modifications de la température extérieure.
","descriptionmj":"","draconic":"Voie d'Oniros","duree":"HN","JR":"Aucun","cible":"","difficulte":"-4","portée":"","caseTMR":"cite","caseTMRspeciale":"","ptreve":"1+","xp":0,"bonuscase":"","isrituel":false,"coutseuil":0,"portee":""},"ownership":{"default":0,"jOzRscDxoXZWpGS6":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.0.32","coreVersion":"10.288","createdTime":1667259472748,"modifiedTime":1667260037972,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}} {"_id":"oeY8a8yHKuAcI28o","name":"Silence","type":"sort","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.sorts-oniros.oeY8a8yHKuAcI28o"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_oniros.webp","effects":[],"system":{"description":"Cette zone est l’inverse Quiétude. Aucun bruit produit dans la zone de Silence, quelle que soit son intensité, ne peut être entendu à l’extérieur, quoique pouvant toujours être entendu à l’intérieur. Permet de dissimuler directement le vacarme que l’on s’apprête à commettre.
","descriptionmj":"","draconic":"Voie d'Oniros","duree":"HN","JR":"Aucun","cible":"","difficulte":"-2","portée":"","caseTMR":"desert","caseTMRspeciale":"","ptreve":"4","xp":0,"bonuscase":"","isrituel":false,"coutseuil":0},"ownership":{"default":0,"jOzRscDxoXZWpGS6":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.0.32","coreVersion":"10.288","createdTime":1667259472748,"modifiedTime":1667260037974,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}} -{"name":"Détection d'aura","type":"sort","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.sorts-hypnos.xOicgRMCUxJNmVzF"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_vigilance.webp","effects":[],"system":{"description":"Les rituels de Détection d’Aura peuvent indifféremment être accomplis par n’importe laquelle des quatre voies.
\nToutes les créatures vivantes animées (humains, humanoïdes, animaux) ont une caractéristique RÊVE. Les objets enchantés possèdent des points de rêve, de même que les produits de magie naturelle, comme certaines pierres de chance. Les entités de cauchemar, incarnées ou non, en ont également. Quelle qu’elle soit, la présence de rêve émet une aura, laquelle est détectable par Détection d’Aura. Parallèlement, toute cible d’un sort ou d’un rituel, émet une aura propre, quand bien même ladite cible ne possède pas de points de rêve (centre de zone, objet ou plante soumis à une illusion d’Hypnos). Cette aura est également détectable par Détection d’Aura.
\nL’aura de présence de rêve se traduit par un halo bleuté constant ; l’aura résultant d’un effet magique par un halo parcouru de pulsations. Quand les deux auras sont présentes conjointement, le halo est pulsatif et d’un bleu plus foncé. On peut toujours effectuer Détection d’Aura sans aucun risque, il y a toujours une réponse. Soit une aura est perçue, constante ou pulsative, et l’on peut tenter une Lecture d’Aura pour en savoir plus ; soit aucune aura n’est perçue et il s’agit de matière inerte, sans rêve, non soumise à un sort.
","descriptionmj":"","draconic":"Voie d'Oniros","duree":"Instantanée","JR":"Aucun","cible":"","difficulte":"-3","portée":"","caseTMR":"sanctuaire","caseTMRspeciale":"","ptreve":"1","xp":0,"bonuscase":"","isrituel":false,"coutseuil":0,"portee":""},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.0.32","coreVersion":"10.288","createdTime":1667259426564,"modifiedTime":1667260037972,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"},"_id":"pNVpReHU6nKJhYKV","folder":null,"sort":0,"ownership":{"default":0,"Hp9ImM4o9YRTSdfu":3}} +{"name":"Détection d'aura","type":"sort","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.sorts-hypnos.xOicgRMCUxJNmVzF"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_vigilance.webp","effects":[],"system":{"description":"Les rituels de Détection d’Aura peuvent indifféremment être accomplis par n’importe laquelle des quatre voies.
\nToutes les créatures vivantes animées (humains, humanoïdes, animaux) ont une caractéristique RÊVE. Les objets enchantés possèdent des points de rêve, de même que les produits de magie naturelle, comme certaines pierres de chance. Les entités de cauchemar, incarnées ou non, en ont également. Quelle qu’elle soit, la présence de rêve émet une aura, laquelle est détectable par Détection d’Aura. Parallèlement, toute cible d’un sort ou d’un rituel, émet une aura propre, quand bien même ladite cible ne possède pas de points de rêve (centre de zone, objet ou plante soumis à une illusion d’Hypnos). Cette aura est également détectable par Détection d’Aura.
\nL’aura de présence de rêve se traduit par un halo bleuté constant ; l’aura résultant d’un effet magique par un halo parcouru de pulsations. Quand les deux auras sont présentes conjointement, le halo est pulsatif et d’un bleu plus foncé. On peut toujours effectuer Détection d’Aura sans aucun risque, il y a toujours une réponse. Soit une aura est perçue, constante ou pulsative, et l’on peut tenter une Lecture d’Aura pour en savoir plus ; soit aucune aura n’est perçue et il s’agit de matière inerte, sans rêve, non soumise à un sort.
","descriptionmj":"","draconic":"Voie d'Oniros","duree":"Instantanée","JR":"Aucun","cible":"","difficulte":"-3","portée":"","caseTMR":"sanctuaire","caseTMRspeciale":"","ptreve":"1","xp":0,"bonuscase":"","isrituel":true,"coutseuil":0,"portee":""},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.4.3","coreVersion":"10.291","createdTime":1667259426564,"modifiedTime":1672364159360,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"},"_id":"pNVpReHU6nKJhYKV","folder":null,"sort":0,"ownership":{"default":0,"Hp9ImM4o9YRTSdfu":3}} {"_id":"qmTXFX7NkB5IIRnE","name":"Pont immatériel","type":"sort","img":"systems/foundryvtt-reve-de-dragon/icons/competence_oniros.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.sorts-oniros.qmTXFX7NkB5IIRnE"}},"system":{"description":"Quoique zone fixe, Pont Immatériel est un des rares exemples de zone non sphérique. C’est un pont en dos d’âne, champ de force immatériel sans épaisseur, ayant la fragile transparence bleutée d’une bulle de savon. On ne peut rien faire d’autre que l’emprunter, à pied, à dos d’animal ou en voiture. On ne peut rien y fixer. Si on le heurte par en dessous ou sur la tranche, il éclate comme une bulle. Dessus, par contre, il peut supporter les plus lourdes charges. Le Pont Immatériel peut être de longueur et de hauteur variables. Pour 2 points de rêve, il peut faire jusqu’à 3 m de long, avec une hauteur maximale de 1 m au centre. Chaque point supplémentaire dépensé permet d’accroître de 1 m sa longueur ou sa hauteur, sachant que sa hauteur ne peut jamais dépasser la moitié de sa longueur. L’entrée et la sortie du pont peuvent ne pas être au même niveau. Le haut-rêvant doit être capable de voir le centre du pont (ciblage) ainsi que les points de départ et d’arrivée. Sa largeur, par contre, n’est pas modifiée par les points dépensés. Au choix du haut-rêvant, elle peut aller de 10 cm à un maximum de 3 m.
","descriptionmj":"","draconic":"Voie d'Oniros","duree":"HN","JR":"Aucun","cible":"","difficulte":"6","portée":"","caseTMR":"pont","caseTMRspeciale":"","ptreve":"2+","xp":0,"bonuscase":"","isrituel":false,"coutseuil":0,"portee":""},"ownership":{"default":0,"jOzRscDxoXZWpGS6":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.0.32","coreVersion":"10.288","createdTime":1667259472748,"modifiedTime":1667260037974,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}} {"_id":"rWRDmyBrNFRDH0sP","name":"Barque de rêve","type":"sort","img":"systems/foundryvtt-reve-de-dragon/icons/competence_oniros.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.sorts-oniros.rWRDmyBrNFRDH0sP"}},"system":{"description":"La Barque de Rêve est une embarcation immatérielle, champ de force à peine visible de transparence bleutée, affectant la forme d’une barque effilée. Elle doit être ciblée à la surface de l’eau et est capable de voguer. Pour un coût de base de 5 points de rêve, elle peut embarquer jusqu’à cinq passagers de TAILLE 15 maximum. Sa capacité peut cependant être accrue lors du paramétrage en dépensant 1 point de rêve supplémentaire pour chaque passager et/ou point de TAILLE excédentaire. Toute surcharge annule instantanément la barque.
\nLa Barque de Rêve se dirige au gré de la personne située à sa proue et se concentrant pour cela, à l’exclusion de toute autre activité. Sa vitesse maximale par défaut est de 4 km/heure draconique (3,5 m par round). Chaque point de rêve spécialement dépensé l’accroît de 2 km/hdr, pour un maximum de 14 km/hdr (12 m par round).
\nLa Barque de Rêve est insubmersible : l’eau qui y pénètre en ressort automatiquement. En revanche, un choc violent peut la faire éclater et disparaître comme une bulle de savon. Elle possède une résistance de 20. Chaque fois qu’elle subit une agression, jouer un jet de Résistance ajusté négativement au +dom du choc.
\nJet réussi : elle tient bon et conserve sa résistance intacte.
\nJet échoué : elle éclate et disparaît.
\nLes réussites spéciales n’interviennent pas.
\nUne surcharge produit le même effet, la faisant immédiatement éclater. Même chose si elle est ciblée ailleurs que sur l’eau. Enfin, n’étant qu’un champ de force, il est impossible de rien y attacher, arrimer, agripper, etc. De même, le matériel doit être intégralement porté par les passagers\": on ne peut rien poser d’inanimé dans la barque, le champ de force l’éjecte aussitôt.
","descriptionmj":"","draconic":"Voie d'Oniros","duree":"Spéciale","JR":"Aucun","cible":"","difficulte":"-8","portée":"","caseTMR":"lac","caseTMRspeciale":"","ptreve":"5+","xp":0,"bonuscase":"","isrituel":false,"coutseuil":0,"portee":""},"ownership":{"default":0,"jOzRscDxoXZWpGS6":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.0.32","coreVersion":"10.288","createdTime":1667259472748,"modifiedTime":1667260037971,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}} {"_id":"rWa1oRVlveNalVfH","name":"Terre en métal","type":"sort","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.sorts-oniros.rWa1oRVlveNalVfH"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_oniros.webp","effects":[],"system":{"description":"Le principe de la Transmutation Élémentale est de transformer un élément en un autre, par exemple le métal en bois, l’air en feu. Il n’existe de transmutation que pour les six premiers éléments. La matière dont sont composées les créatures, mortes ou vivantes, n’est jamais transmuée, y compris l’air contenu dans les poumons. Il existe 26 transmutations élémentales ; chacune est un sort à part entière, obéissant en tout point aux règles des sorts de zone.
\nLa transmutation a lieu dans la zone paramétrée et ciblée par le haut-rêvant. Tout ce qui appartient à l’élément impliqué est transmué instantanément sans discrimination. On ne peut pas faire de choix. Tant que dure la zone, tout nouvel objet appartenant à l’élément impliqué qui pénètre dans la zone, est immédiatement transmué à son tour. La zone peut fort bien être lancée sur un lieu où l’élément impliqué n’existe pas, par exemple Terre en Eau à 5 m du sol. Rien ne se produira au premier abord, mais toute pierre lancée dans la zone sera instantanément liquéfiée pour retomber sous forme de pluie.
\nTout objet transmué, situé ou entrant dans la zone, adopte aussitôt la forme que lui permet le nouvel élément. On peut obtenir de gracieuses torsades avec du feu transmué en bois ou en métal. La transmutation est définitive, même si l’objet sort de la zone. À la fin de la zone (HN), l’effet cesse d’opérer, mais la matière transmuée le demeure définitivement sans recouvrer non plus son élément d’origine.
\nQuand une créature vivante se retrouve dans une zone de Transmutation Élémentale, bien que la matière dont elle est composée ne soit pas affectée en elle-même, elle subit l’effet naturel et normal du nouvel élément qui l’entoure, sans jet de résistance. Une créature prise dans une zone d’Air en Feu se retrouve dans un brasier qui la brûle, une créature nageant prise dans une zone d’Eau en Bois se retrouve enkystée dans un bloc de bois, etc.
\nL’élément Eau correspondant à tous les liquides d’origine non animale, réellement aqueux ou non, c’est tout le liquide qui est transmué et non pas uniquement ses molécules de H2O, y compris tout ce qui peut y être dissout (sels, cristaux). L’eau d’un végétal (sève, jus d’un fruit) appartient à l’élément Bois, qui est celui du végétal, tant qu’il est contenu dans ce dernier. L’humus appartient intégralement à l’élément Terre, même s’il est composé en grande partie de matière végétale (Bois) non encore décomposée.
\nX élément en Air : Pratiquement, l’ancien élément disparaît dans un courant d’air. L’air d’arrivée est toujours frais et pur.
\nX élément en Terre : L’élément d’arrivée est une roche friable et fragile comme de la craie.
\nX élément en Eau : L’eau nouvellement créée se comporte naturellement, attirée par la pesanteur : elle pleut, coule, cherche à s’infiltrer. Elle a la pureté de l’eau distillée.
\nX élément en Feu : L’ancien élément devenu Feu n’est plus que flammes. Toutefois, pour que ces nouvelles flammes continuent à brûler, il leur faut un combustible, faute de quoi elles s’éteignent. Quand c’est l’Air qui est transmué en Feu, celui-ci demeure même sans combustible, car l’Air entourant la zone la comble immédiatement, devenant Feu à son tour. Le résultat est une sphère en permanente ignition. Il en va de même pour l’eau au centre d’une rivière par exemple.
\nX élément en Bois : Le bois d’arrivée est un bois de qualité médiocre, du genre sapin, mais sec, sans aucune sève ni résine, combustible ou façonnable.
\nX élément en Métal : Il ne s’agit toujours que des deux métaux les plus inertes : fer ou plomb (tirer à pile ou face). Le fer de transmutation n’est ni de l’acier ni du fer forgé, c’est du fer natif, mou et sans dureté. Un forgeron peut néanmoins le travailler.
\nÀ mi-chemin entre les créatures et la matière inerte, les objets magiques ont droit à un jet de résistance pour ne pas être impliqués dans une transmutation. C’est un JR spécial, r0, où la protection magique du matériau est prise en guise de points de rêve (voir Résistance).
","descriptionmj":"","draconic":"Voie d'Oniros","duree":"HN","JR":"Aucun","cible":"","difficulte":"-6","portée":"","caseTMR":"gouffre","caseTMRspeciale":"","ptreve":"4","xp":0,"bonuscase":"","isrituel":false,"coutseuil":0},"ownership":{"default":0,"jOzRscDxoXZWpGS6":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.0.32","coreVersion":"10.288","createdTime":1667259472748,"modifiedTime":1667260037974,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}} diff --git a/packs/sorts-thanatos.db b/packs/sorts-thanatos.db index 95091685..4148253f 100644 --- a/packs/sorts-thanatos.db +++ b/packs/sorts-thanatos.db @@ -2,10 +2,10 @@ {"_id":"3SUbeB9OBaxbRwwy","name":"Dague de meurtre","type":"sort","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.sorts-thanatos.3SUbeB9OBaxbRwwy"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_thanatos.webp","effects":[],"system":{"description":"Ayant élaboré une dague magique au moyen des rituels normaux de la voie de Narcos, le haut-rêvant peut y poser la Grande Griffe de Thanatos Dague de meurtre. Lors du lancer, le haut-rêvant doit paramétrer le nom d'une victime précise ou d'un type de victime, par exemple : Uhn Telh (nom d'un personnage unique), le roi de Parissy (n'importe quel personnage occupant successivement cette fonction), une fille blonde (toute personne correspondant à cette description). La dague peut être normale hormis la Grande Griffe, ou avoir reçu en outre des écailles d'efficacité de Narcos. Ceci fait, le haut-rêvant de Thanatos n'a plus qu'à s'arranger pour que la dague se trouve un nouveau propriétaire.
\nLe seul fait de toucher à la dague, même à travers un gant ou une étoffe, déclenche le pouvoir de la Dague de meutre. La maîtrise de la Grande Griffe opère, coûtant 1 point de rêve au personnage (coût d'une écaille), qui doit aussi jouer un JR standard r-8. JR réussi, le personnage n'est pas affecté et peut utiliser la dague à son gré ; JR échoué, le personnage est atteint de l'équivalent d'un envoûtement de Tâche, et doit accomplir le meutre paramétré dans les plus brefs délais. Parallèlement, le personnage fait tout pour protéger la dague dont il se croit le possesseur (alors que c'est l'inverse). Dès que le meutre est accompli, le meurtrier joue un second JR r-8. Réussi, il laisse tomber la dague et s'en détourne horrifié ; échoué, il la retourne contre son propre sein et se suicide. Cela dit, et dans le cas où la victime paramétrée n'est pas une personne unique, la dague est prête à se trouver une nouvelle main pour continuer son oeuvre de mort.
","descriptionmj":"","draconic":"Voie de Thanatos","duree":"Permanente","JR":"r-8","cible":"","difficulte":"-13","portée":"","caseTMR":"desolation","caseTMRspeciale":"Désolation de Sel G9","ptreve":"13","xp":0,"bonuscase":"","isrituel":true,"coutseuil":2,"portee":""},"folder":null,"sort":0,"ownership":{"default":0},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.0.32","coreVersion":"10.288","createdTime":1667259843440,"modifiedTime":1667260048926,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}} {"_id":"5U7KXTsxph9wmbXH","name":"Invocation des entités de cauchemar non incarnées","type":"sort","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.sorts-thanatos.5U7KXTsxph9wmbXH"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_thanatos.webp","effects":[],"system":{"description":"INVOCATION D'UN DÉSESPOIR (Désolation) R-7 r7
\nINVOCATION D'UNE HAINE (Marais) R-7 r7
\nINVOCATION D'UNE PEUR (Gouffre) R-7 r7
\nAyant ciblé l'effet de son rituel sur un objet entièrement noir, le haut-rêvant de Thanatos invoque une entité de cauchemar non incarnée (ECNI) à se présenter devant lui. L'entité n'est pas créée magiquement, le rituel ne fait qu'appeler l'entité l aplus proche, qui se met aussitôt en route pour se présenter devant le haut-rêvant. Si, par rapport au scénario, on sait où se trouve l'entité la plus proche, il suffit de calculer le temps mis pour venir, sachant qu'elle parcourt 6 m par round. Dans le cas contraire, on la suppose arriver au bout de 1d7 heures. Sur son chemin vers le haut-rêvant, elle n'attaque personne, même si on lui barre le chemin, elle se contente de passer. Puis, dès qu'elle se retrouve en présence de son invocateur, elle l'attaque, cherchant à le posséder. Si ce dernier la combat par Thanatos et sort vainqueur, il peut alors la contrôler. A moins qu'on ne sache spécifiquement le nombre de points de rêve de l'entité la plus proche, les entités invoquées peuvent avoir de 4 à 24 points de rêve (4d6).
\n","descriptionmj":"","draconic":"Voie de Thanatos","duree":"Spéciale","JR":"Aucun","cible":"Un objet noir","difficulte":"","portée":"","caseTMR":"special","caseTMRspeciale":"","ptreve":"","xp":0,"bonuscase":"","isrituel":true,"coutseuil":0,"portee":""},"ownership":{"default":0,"6ibmdmaeRSMTjU4c":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.0.32","coreVersion":"10.288","createdTime":1667259843440,"modifiedTime":1667260048927,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}} {"_id":"8hCVBWM48GNb8e6P","name":"Faire parler un crâne","type":"sort","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.sorts-thanatos.8hCVBWM48GNb8e6P"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_thanatos.webp","effects":[],"system":{"description":"
Ce rituel permet de faire parler un crâne d'humanoïde. Le haut-rêvant de Thanatos doit le toucher et lui poser des questions, le crâne ne répondant qu'aux questions posées. Il peut parler de tout ce dont il a été témoin, aussi bien durant sa vie que depuis qu'il est mort, c'est-à-dire de ce dont, en tant qu'objet abandonné quelque part, il a pu être témoin. La durée de communication est de 1 round par point de rêve dépensé.
","descriptionmj":"","draconic":"Voie de Thanatos","duree":"Selon r dépensé","JR":"Aucun","cible":"Un crâne","difficulte":"-6","portée":"","caseTMR":"desert","caseTMRspeciale":"","ptreve":"1+","xp":0,"bonuscase":"","isrituel":true,"coutseuil":0,"portee":""},"ownership":{"default":0,"6ibmdmaeRSMTjU4c":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.0.32","coreVersion":"10.288","createdTime":1667259843440,"modifiedTime":1667260048926,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}} -{"name":"Lecture d'aura","type":"sort","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.sorts-narcos.Y4r9kTN2brWC2N0n"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_vigilance.webp","effects":[],"system":{"description":"Les rituels de Lecture d’Aura peuvent indifféremment être accomplis par n’importe laquelle des quatre voies.
\nCe rituel permet d’approfondir les informations fournies par Détection d’Aura. Pratiquer Lecture d’Aura quand il n’y a pas d’aura revient à demander une magie impossible et crée immédiatement une déchirure du rêve.
\nLecture d’Aura est effectuée en plusieurs étapes, toutes étant de difficulté R-3 et coûtant 3 points de rêve. La première a toujours lieu dans un sanctuaire et ne fait que révéler dans quel(s) autre(s) genre(s) de case(s) le haut-rêvant doit se rendre pour continuer sa lecture. Là, il apprend quel genre de magie a été produit ou à quel type de rêve il a affaire, de même que les cases spécifiques concernées. Enfin dans les cases spécifiques, le haut-rêvant peut apprendre la force du rêve ou de la magie en cours, c’est-à-dire pratiquement la difficulté et le nombre de points de rêve impliqués, information indispensable dans l’optique d’une annulation de magie.
\nLecture d’Aura révèle également la couleur de l’aura (fixe ou pulsative) comme Détection d’Aura. Pour les créatures vivantes, on peut donc sauter l’étape de Détection d’Aura et commencer directement par la lecture, puisqu’on est sûr de trouver une aura. Dans les autres cas, il est plus prudent de commencer par la détection si, en l’absence finale d’une aura, on ne veut pas créer de magie impossible. Effectuée sur une créature non soumise à un effet magique ni sous l’emprise d’une entité, Lecture d’Aura indique toujours le Fleuve. Là, dans n’importe quelle case du Fleuve, le haut-rêvant se contente d’apprendre qu’il a affaire à une créature vivante et douée de rêve.
","descriptionmj":"","draconic":"Voie de Thanatos","duree":"Instantanée","JR":"Aucun","cible":"","difficulte":"-3","portée":"","caseTMR":"special","caseTMRspeciale":"Sanctuaire / variable","ptreve":"3","xp":0,"bonuscase":"","isrituel":false,"coutseuil":0,"portee":""},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.0.32","coreVersion":"10.288","createdTime":1667259638600,"modifiedTime":1667260048927,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"},"_id":"AYmxbu3HzeNU9l2A","folder":null,"sort":0,"ownership":{"default":0,"Hp9ImM4o9YRTSdfu":3}} +{"name":"Lecture d'aura","type":"sort","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.sorts-narcos.Y4r9kTN2brWC2N0n"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_vigilance.webp","effects":[],"system":{"description":"Les rituels de Lecture d’Aura peuvent indifféremment être accomplis par n’importe laquelle des quatre voies.
\nCe rituel permet d’approfondir les informations fournies par Détection d’Aura. Pratiquer Lecture d’Aura quand il n’y a pas d’aura revient à demander une magie impossible et crée immédiatement une déchirure du rêve.
\nLecture d’Aura est effectuée en plusieurs étapes, toutes étant de difficulté R-3 et coûtant 3 points de rêve. La première a toujours lieu dans un sanctuaire et ne fait que révéler dans quel(s) autre(s) genre(s) de case(s) le haut-rêvant doit se rendre pour continuer sa lecture. Là, il apprend quel genre de magie a été produit ou à quel type de rêve il a affaire, de même que les cases spécifiques concernées. Enfin dans les cases spécifiques, le haut-rêvant peut apprendre la force du rêve ou de la magie en cours, c’est-à-dire pratiquement la difficulté et le nombre de points de rêve impliqués, information indispensable dans l’optique d’une annulation de magie.
\nLecture d’Aura révèle également la couleur de l’aura (fixe ou pulsative) comme Détection d’Aura. Pour les créatures vivantes, on peut donc sauter l’étape de Détection d’Aura et commencer directement par la lecture, puisqu’on est sûr de trouver une aura. Dans les autres cas, il est plus prudent de commencer par la détection si, en l’absence finale d’une aura, on ne veut pas créer de magie impossible. Effectuée sur une créature non soumise à un effet magique ni sous l’emprise d’une entité, Lecture d’Aura indique toujours le Fleuve. Là, dans n’importe quelle case du Fleuve, le haut-rêvant se contente d’apprendre qu’il a affaire à une créature vivante et douée de rêve.
","descriptionmj":"","draconic":"Voie de Thanatos","duree":"Instantanée","JR":"Aucun","cible":"","difficulte":"-3","portée":"","caseTMR":"special","caseTMRspeciale":"Sanctuaire / variable","ptreve":"3","xp":0,"bonuscase":"","isrituel":true,"coutseuil":0,"portee":""},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.4.3","coreVersion":"10.291","createdTime":1667259638600,"modifiedTime":1672364213966,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"},"_id":"AYmxbu3HzeNU9l2A","folder":null,"sort":0,"ownership":{"default":0,"Hp9ImM4o9YRTSdfu":3}} {"_id":"B7gtpMz81LZIv450","name":"Maladie","type":"sort","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.sorts-thanatos.B7gtpMz81LZIv450"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_thanatos.webp","effects":[],"system":{"description":"Quand la victime est entièrement possédée de corps, le haut-rêvant de Thanatos peut commencer l'envoûtement de Maladie. Chaque ensemble de 5 points de rêve dépensés (5r), fait perdre 1 point de vie à la victime. Dès qu'elle dépasse son seuil négatif, elle meurt. La maladie semble être une maladie de langueur, une inexplicable faiblesse. Aucune médecine, aucune herbe ne parvient à la soigner, pas même une potion enchantée. Annuler la possession brise en même temps l'envoûtement de Maladie, et la victime recouvre instantanément tous ses points de vie.
","descriptionmj":"","draconic":"Voie de Thanatos","duree":"Illimitée","JR":"Aucun","cible":"Relique","difficulte":"-11","portée":"","caseTMR":"desolation","caseTMRspeciale":"","ptreve":"5+","xp":0,"bonuscase":"","isrituel":false,"coutseuil":0,"portee":""},"ownership":{"default":0,"6ibmdmaeRSMTjU4c":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.0.32","coreVersion":"10.288","createdTime":1667259843440,"modifiedTime":1667260048927,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}} {"_id":"ChIxJ7jOvpJgctMz","name":"Interdiction","type":"sort","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.sorts-thanatos.ChIxJ7jOvpJgctMz"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_thanatos.webp","effects":[],"system":{"description":"Quand la victime est entièrement possédée d'esprit, le haut-rêvant de Thanatos peut lancer sur elle un interdit, et la victime ne pourra en aucun cas contrevenir à cette interdiction. Cette dernière doit pouvoir être obéie par la VOLONTÉ normale de la victime : l'interdiction de vivre ou de respirer est impossible. L'interdiction doit être formulée très exactement ; en cas de doute sur son interprétation, c'est au gardien des rêves de statuer. L'interdiction ne peut comporter qu'un seul verbe, à l'impératif, et par définition à la forme négative : ne fais pas. Il ne peut comporter qu'un seul complément d'objet direct ou indirect, et ce dernier ne prut avoir qu'un seul qualificatif ou autre complément. Exemples : n'ouvre pas les yeux, ne prend pas tes armes, ne parle à personne, ne touche pas à la pierre noire, ne préviens pas les gardes du palais, etc. La contrainte de l'interdiction dure jusqu'à la fin de l'heure de naissnace de la vitime. Le haut-rêvant peut renouveler l'interdiction de jour en jour ou en apporter une nouvelle, mais ne peut pas en faire coexister deux simultanément. Annuler la possession brise en même temps l'envoûtement d'Interdiction, et la victime recouvre instantanément toute sa liberté.
","descriptionmj":"","draconic":"Voie de Thanatos","duree":"HN de la victime","JR":"Aucun","cible":"Relique","difficulte":"-7","portée":"","caseTMR":"desert","caseTMRspeciale":"","ptreve":"7","xp":0,"bonuscase":"","isrituel":false,"coutseuil":0,"portee":""},"ownership":{"default":0,"6ibmdmaeRSMTjU4c":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.0.32","coreVersion":"10.288","createdTime":1667259843440,"modifiedTime":1667260048927,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}} -{"name":"Détection d'aura","type":"sort","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.sorts-narcos.xOicgRMCUxJNmVzF"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_vigilance.webp","effects":[],"system":{"description":"Les rituels de Détection d’Aura peuvent indifféremment être accomplis par n’importe laquelle des quatre voies.
\nToutes les créatures vivantes animées (humains, humanoïdes, animaux) ont une caractéristique RÊVE. Les objets enchantés possèdent des points de rêve, de même que les produits de magie naturelle, comme certaines pierres de chance. Les entités de cauchemar, incarnées ou non, en ont également. Quelle qu’elle soit, la présence de rêve émet une aura, laquelle est détectable par Détection d’Aura. Parallèlement, toute cible d’un sort ou d’un rituel, émet une aura propre, quand bien même ladite cible ne possède pas de points de rêve (centre de zone, objet ou plante soumis à une illusion d’Hypnos). Cette aura est également détectable par Détection d’Aura.
\nL’aura de présence de rêve se traduit par un halo bleuté constant ; l’aura résultant d’un effet magique par un halo parcouru de pulsations. Quand les deux auras sont présentes conjointement, le halo est pulsatif et d’un bleu plus foncé. On peut toujours effectuer Détection d’Aura sans aucun risque, il y a toujours une réponse. Soit une aura est perçue, constante ou pulsative, et l’on peut tenter une Lecture d’Aura pour en savoir plus ; soit aucune aura n’est perçue et il s’agit de matière inerte, sans rêve, non soumise à un sort.
","descriptionmj":"","draconic":"Voie de Thanatos","duree":"Instantanée","JR":"Aucun","cible":"","difficulte":"-3","portée":"","caseTMR":"sanctuaire","caseTMRspeciale":"","ptreve":"1","xp":0,"bonuscase":"","isrituel":false,"coutseuil":0,"portee":""},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.0.32","coreVersion":"10.288","createdTime":1667259638601,"modifiedTime":1667260048926,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"},"_id":"GHsNBFq6uFOzAwK5","folder":null,"sort":0,"ownership":{"default":0,"Hp9ImM4o9YRTSdfu":3}} +{"name":"Détection d'aura","type":"sort","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.sorts-narcos.xOicgRMCUxJNmVzF"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_vigilance.webp","effects":[],"system":{"description":"Les rituels de Détection d’Aura peuvent indifféremment être accomplis par n’importe laquelle des quatre voies.
\nToutes les créatures vivantes animées (humains, humanoïdes, animaux) ont une caractéristique RÊVE. Les objets enchantés possèdent des points de rêve, de même que les produits de magie naturelle, comme certaines pierres de chance. Les entités de cauchemar, incarnées ou non, en ont également. Quelle qu’elle soit, la présence de rêve émet une aura, laquelle est détectable par Détection d’Aura. Parallèlement, toute cible d’un sort ou d’un rituel, émet une aura propre, quand bien même ladite cible ne possède pas de points de rêve (centre de zone, objet ou plante soumis à une illusion d’Hypnos). Cette aura est également détectable par Détection d’Aura.
\nL’aura de présence de rêve se traduit par un halo bleuté constant ; l’aura résultant d’un effet magique par un halo parcouru de pulsations. Quand les deux auras sont présentes conjointement, le halo est pulsatif et d’un bleu plus foncé. On peut toujours effectuer Détection d’Aura sans aucun risque, il y a toujours une réponse. Soit une aura est perçue, constante ou pulsative, et l’on peut tenter une Lecture d’Aura pour en savoir plus ; soit aucune aura n’est perçue et il s’agit de matière inerte, sans rêve, non soumise à un sort.
","descriptionmj":"","draconic":"Voie de Thanatos","duree":"Instantanée","JR":"Aucun","cible":"","difficulte":"-3","portée":"","caseTMR":"sanctuaire","caseTMRspeciale":"","ptreve":"1","xp":0,"bonuscase":"","isrituel":true,"coutseuil":0,"portee":""},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.4.3","coreVersion":"10.291","createdTime":1667259638601,"modifiedTime":1672364217190,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"},"_id":"GHsNBFq6uFOzAwK5","folder":null,"sort":0,"ownership":{"default":0,"Hp9ImM4o9YRTSdfu":3}} {"_id":"H4K9R6zq7nyC9Qkf","name":"Cauchemar","type":"sort","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.sorts-thanatos.H4K9R6zq7nyC9Qkf"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_thanatos.webp","effects":[],"system":{"description":"Quand la victime est entièrement possédée d'esprit, le haut-rêvant de Thanataos peut peupler de cauchemars ses rêves accomplis dans les Basses Terres du Rêve. Les cauchemars durent depuis le moment où est lancé le sort d'envoûtement jusqu'à l'heure du Châteu Dormant. Le sommeil de la victime en est à tel point empoisonné qu'elle ne récupère qu'une case de fatigue par heure au lieu d'un segment. Si la règle du Moral est utilisée, la victime en perd automatiquement 2 points au réveil au lieu de jouer normalement le jet de Moral journalier. Si elle est déjà à -3, elle prend 2 points de dissolution. Annuler la possession brise en même temps l'envoûtement de Cauchemar, et la victime recouvre instantanément son sommeil normal.
","descriptionmj":"","draconic":"Voie de Thanatos","duree":"Fin de la nuit en cours","JR":"Aucun","cible":"Relique","difficulte":"-5","portée":"","caseTMR":"monts","caseTMRspeciale":"","ptreve":"5","xp":0,"bonuscase":"","isrituel":false,"coutseuil":0,"portee":""},"ownership":{"default":0,"6ibmdmaeRSMTjU4c":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.0.32","coreVersion":"10.288","createdTime":1667259843441,"modifiedTime":1667260048926,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}} {"_id":"IfVWI1LIk2PcT89J","name":"Autométamorphose en bête","type":"sort","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.sorts-thanatos.IfVWI1LIk2PcT89J"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_thanatos.webp","effects":[],"system":{"description":"Par l'usage de ce sort, le haut-rêvant de Thanatos se transforme lui-même en l'animal de son choix. La métamorphose est instantanée, et correspond dans son résultat à une métamorphose de corps uniquement, et non d'esprit. Le haut-rêvant peut choisir n'importe quelle forme animale d'une TAILLE maximale égale à la sienne, et minimale de 1 (souris). Seul son corps est affecté, pas ses vêtements ni son équipement. Il peut continuer à monter en TMR et lancer des sorts sous cette forme.
\nSes caractéristiques physiques deviennent celles de l'animal choisi, c'est à dire TAILLE, CONSTITUTION, FORCE, PERCEPTION. Les seules qu'il conserve sont INTELLECT, VOLONTÉ, RÊVE. Son Endurance et ses points de vie sont calculés d'après les caractéristiques de l'animal et selon les règles de cacul de ces dernières (Endurance = Vie + CONSTITUTION). Les notions d'Apparence et de Chance disparaissent. Dextérite et Agilité (ou leur équivalent) sont directement inclues dans les compétences de l'animal. Le haut-rêvant n'acquiert que les caractéristiques physiques de l'animal, pas ses caractéristiques spéciales ou magiques. Ainsi un haut-rêvant de Thanatos métamorphosé en sirène, ne pourra pas obtenir les illusions dont ces créatures sont capables, ni d'avoir un chant irrésistible. Transformé en oiseau-oracle, il pourra toujours parler, mais son discours ne reflétera pas automatiquement la vérité. Pour déterminer les caractéristiques physiques des animaux, se fonder sur les modèles présentés dans le Livre III.
\nLa caractéristique VOLONTÉ reste la sienne. Mais toutes les heures d'autométamorphose et chaque fois que survient un incident pouvant faire réagir l'instinct de l'animal (proie ou prédateur, partenaire de l'autre sexe, etc), tirer un jet de VOLONTÉ à zéro.
\nToute réussite. Le haut-rêvant garde ou reprend le contrôle de l'animal et à la prochaine occasion, le jet de VOLONTÉ sera à nouveau à zéro.
\nEchec et Ech.P. L'instinct de l'animal l'emporte et la VOLONTÉ du haut-rêvant s'obscurcit. En termes de jeu, l'animal passe sous le contrôle du gardien des rêves pour la durée du round. Au round suivant, rejouer VOLONTÉ à -1, et ainsi de suite de round en round, avec des ajustements cumulatifs de -1 jusqu'à la réussite ou l'échec total.
\nEch.T. La VOLONTÉ du haut-rêvant est définitivement annihilée. A partir de cet instant, l'animal passe entièrement sous le contrôle du gardien des rêves jusqu'à la fin de la durée de l'autométamorphose. Redevenu humain, le haut-rêvant de Thanatos n'a aucun souvenir de ce qu'il a vécu sous forme animale. Qui plus est, son esprit est toujours celui de l'animal, exactement comme s'il était envoûté de métamorphose d'esprit. Il doit alors jouer un jet de VOLONTÉ toutes les heures. Le premier jet à une difficulté de zéro, mais chaque nouvel échec s'incrémente d'un maus de -1. Dès qu'une réussite survient, le haut-rêvant recouvre son mental. Dès qu'un échec total survient, son esprit est définitivement animal, comme s'il avait été envoûté et métamorphosé d'esprit. Seule une Annulation de Magie accomplie par un tiers pourra le délivrer.
\nLes points de vie perdus et les blessures sont conservés dans les deux sens, c'est-à-dire au passage de l'humain à l'animal et inversement. Lors du passage à l'état animal, soustraire les points d'endurance dus aux blessures existantes sur l'humain en retirant les jets comme si ces blessures venaient tout juste d'être reçues. Les blessures elles-mêmes figureront sur l'animal. Lors du retour à l'humain, l'endurance est celles qu'il restait à l'animal (jusqu'à concurrence de l'endurance de l'humain), de même que ses éventuelles blessures.
","descriptionmj":"","draconic":"Voie de Thanatos","duree":"HN","JR":"Aucun","cible":"Soi-même","difficulte":"-7","portée":"","caseTMR":"foret","caseTMRspeciale":"","ptreve":"7","xp":0,"bonuscase":"","isrituel":false,"coutseuil":0,"portee":""},"ownership":{"default":0,"6ibmdmaeRSMTjU4c":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.0.32","coreVersion":"10.288","createdTime":1667259843441,"modifiedTime":1667260048926,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}} {"_id":"Ix0zKfupAloZoUCK","name":"Faire parler un mort","type":"sort","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.sorts-thanatos.Ix0zKfupAloZoUCK"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_thanatos.webp","effects":[],"system":{"description":"Ce rituel permet de faire parler un cadavre dont il reste au moins la tête, peu importe son degré de décomposition. Le haut-rêvant de Thanatos doit le toucher et lui poser des questions, le mort ne répondant qu'aux questions posées. Les seuls souvenirs qu'il peut communiquer sont ceux de la dernière heure de sa vie. La durée de la communication est de 1 round par point de rêve dépensé.
","descriptionmj":"","draconic":"Voie de Thanatos","duree":"Selon r dépensé","JR":"Aucun","cible":"Un cadavre","difficulte":"-4","portée":"","caseTMR":"pont","caseTMRspeciale":"","ptreve":"1+","xp":0,"bonuscase":"","isrituel":true,"coutseuil":0,"portee":""},"ownership":{"default":0,"6ibmdmaeRSMTjU4c":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.0.32","coreVersion":"10.288","createdTime":1667259843441,"modifiedTime":1667260048926,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}} diff --git a/templates/actor-sheet.html b/templates/actor-sheet.html index 20782f13..3a824616 100644 --- a/templates/actor-sheet.html +++ b/templates/actor-sheet.html @@ -21,88 +21,90 @@ {{!-- Sheet Tab Navigation --}} + {{#if options.isObserver}} + Carac. + Compétences + Combat + Savoirs&Taches + Haut-Rêve + {{/if}} + Équipement + Description + - {{!-- Sheet Body --}} -