forked from public/foundryvtt-reve-de-dragon
Compare commits
47 Commits
foundryvtt
...
foundryvtt
Author | SHA1 | Date | |
---|---|---|---|
c2a3b5e246 | |||
09bf28eed1 | |||
33c20dd2b7 | |||
c933810b6b | |||
df92a65f5d | |||
dbcab12f24 | |||
454193490d | |||
c79298b60a | |||
26808d7b49 | |||
2062ff0777 | |||
6adeb790a0 | |||
2546b89b44 | |||
84f4a152a8 | |||
d6f8698189 | |||
4f80c719c2 | |||
7d8b5c9549 | |||
ec58317b35 | |||
7c70e944b1 | |||
f397c82c6d | |||
81e3ceb4dc | |||
7bec249e8d | |||
70b30b545b | |||
ed2eebf99d | |||
4ba2c384d7 | |||
7f27399f3c | |||
61389e117b | |||
46cc245abf | |||
a372531849 | |||
8a8323ac8d | |||
8e6d4fbb89 | |||
886307f24c | |||
f40dbd5d7b | |||
66da7d5eb4 | |||
b2d8c2439a | |||
ceb4095c31 | |||
2af37cf98f | |||
fd156960a7 | |||
80a904e533 | |||
c9dc847440 | |||
4e382d405e | |||
6a12dc97f6 | |||
e0b6957bc6 | |||
944120b524 | |||
bb6bf3387e | |||
467a4d53a4 | |||
d5635b27fe | |||
3a33f7c4fc |
BIN
icons/items/services.webp
Normal file
BIN
icons/items/services.webp
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.2 KiB |
@ -27,6 +27,7 @@
|
||||
"TypeArmure": "Armure",
|
||||
"TypeConteneur": "Conteneur",
|
||||
"TypeNourritureboisson": "Nourriture & boisson",
|
||||
"TypeService": "Services/Boutique",
|
||||
"TypeChant": "Chant",
|
||||
"TypeDanse": "Danse",
|
||||
"TypeMusique": "Musique",
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -8,18 +8,19 @@ import { RdDCombatManager } from "./rdd-combat.js";
|
||||
import { RdDCarac } from "./rdd-carac.js";
|
||||
import { DialogSplitItem } from "./dialog-split-item.js";
|
||||
import { ReglesOptionelles } from "./settings/regles-optionelles.js";
|
||||
import { DialogRepos } from "./dialog-repos.js";
|
||||
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() {
|
||||
@ -37,41 +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.getFortune(this.actor),
|
||||
encTotal: await this.actor.computeEncombrementTotalEtMalusArmure(),
|
||||
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.confirmerSuppressionItem(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
|
||||
@ -312,7 +286,7 @@ export class RdDActorSheet extends ActorSheet {
|
||||
});
|
||||
|
||||
this.html.find('.repos').click(async event => {
|
||||
await DialogRepos.create(this.actor);
|
||||
await this.actor.repos();
|
||||
});
|
||||
this.html.find('.delete-active-effect').click(async event => {
|
||||
if (game.user.isGM) {
|
||||
@ -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 = `<span class="competence-label">Selectionnez le type d'oeuvre</span><select class="item-type">`;
|
||||
for (let typeName of typeObjets) {
|
||||
content += `<option value="${typeName}">${Misc.typeName('Item', typeName)}</option>`
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async createItem(name, type) {
|
||||
await this.actor.createEmbeddedDocuments('Item', [{ name: name, type: type }], { renderSheet: true });
|
||||
content += '</select>';
|
||||
let dialog = new Dialog({
|
||||
title: "Créer une oeuvre",
|
||||
content: content,
|
||||
buttons: {
|
||||
create: {
|
||||
icon: '<i class="fas fa-check"></i>',
|
||||
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) {
|
||||
|
347
module/actor.js
347
module/actor.js
@ -34,8 +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',
|
||||
@ -55,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() {
|
||||
@ -144,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.
|
||||
@ -177,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)
|
||||
}
|
||||
@ -187,17 +109,17 @@ export class RdDActor extends Actor {
|
||||
|
||||
canReceive(item) {
|
||||
if (this.isCreature()) {
|
||||
return item.type == 'competencecreature' || RdDItem.isItemInventaire(item);
|
||||
return item.type == 'competencecreature' || item.isInventaire();
|
||||
}
|
||||
if (this.isEntite()) {
|
||||
return item.type == 'competencecreature';
|
||||
}
|
||||
if (this.isVehicule()) {
|
||||
return RdDItem.isItemInventaire(item);
|
||||
return item.isInventaire();
|
||||
}
|
||||
if (this.isPersonnage()) {
|
||||
switch (item.type) {
|
||||
case 'competencecreature': case 'tarot':
|
||||
case 'competencecreature': case 'tarot': case 'service':
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@ -205,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 != ""
|
||||
@ -329,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() {
|
||||
@ -446,6 +334,39 @@ export class RdDActor extends Actor {
|
||||
return '';
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async roll() {
|
||||
const carac = mergeObject(
|
||||
duplicate(this.system.carac),
|
||||
{
|
||||
'reve-actuel': this.getCaracReveActuel(),
|
||||
'chance-actuelle': this.getCaracChanceActuelle()
|
||||
});
|
||||
let rollData = {
|
||||
carac: carac,
|
||||
selectedCarac: carac.apparence,
|
||||
selectedCaracName: 'apparence',
|
||||
competences: this.itemTypes['competence']
|
||||
};
|
||||
|
||||
const dialog = await RdDRoll.create(this, rollData,
|
||||
{ html: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll.html' },
|
||||
{
|
||||
name: `jet-${this.id}`,
|
||||
label: `Jet de ${this.name}`,
|
||||
callbacks: [
|
||||
this.createCallbackExperience(),
|
||||
this.createCallbackAppelAuMoral(),
|
||||
{ action: r => this._onRollCaracResult(r) }
|
||||
]
|
||||
}
|
||||
);
|
||||
dialog.render(true);
|
||||
}
|
||||
|
||||
async repos() {
|
||||
await DialogRepos.create(this);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async grisReve(nGrisReve) {
|
||||
@ -1076,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 !
|
||||
}
|
||||
@ -1097,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);
|
||||
@ -1195,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) {
|
||||
@ -1270,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);
|
||||
@ -1281,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
|
||||
|
||||
@ -1344,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);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
@ -1352,9 +1273,6 @@ export class RdDActor extends Actor {
|
||||
if (!this.pack) {
|
||||
await this.computeMalusArmure();
|
||||
this.encTotal = this.items.map(it => it.getEncTotal()).reduce(Misc.sum(), 0);
|
||||
if (!this.isVehicule()) {
|
||||
this.system.compteurs.surenc.value = this.computeMalusSurEncombrement();
|
||||
}
|
||||
return this.encTotal;
|
||||
}
|
||||
return 0;
|
||||
@ -1376,6 +1294,7 @@ export class RdDActor extends Actor {
|
||||
/* -------------------------------------------- */
|
||||
computePrixTotalEquipement() {
|
||||
const valeur = this.items.filter(it => it.isInventaire())
|
||||
.filter(it => !it.isMonnaie())
|
||||
.map(it => it.valeurTotale())
|
||||
.reduce(Misc.sum(), 0);
|
||||
return valeur;
|
||||
@ -1413,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
|
||||
@ -1996,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]
|
||||
@ -2004,7 +1927,7 @@ export class RdDActor extends Actor {
|
||||
userId)
|
||||
return;
|
||||
}
|
||||
const item = this.getObjet(itemId)
|
||||
const item = this.getItem(itemId)
|
||||
if (!item.isComestible()) {
|
||||
return;
|
||||
}
|
||||
@ -2761,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);
|
||||
}
|
||||
@ -2783,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);
|
||||
}
|
||||
|
||||
@ -2880,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)
|
||||
}
|
||||
|
||||
@ -2932,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));
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
@ -3143,60 +3066,66 @@ 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);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
getCaracByName(name) {
|
||||
switch (Grammar.toLowerCaseNoAccent(name)) {
|
||||
case 'reve-actuel': case 'reve actuel':
|
||||
return {
|
||||
label: 'Rêve actuel',
|
||||
value: this.getReveActuel(),
|
||||
type: "number"
|
||||
};
|
||||
return this.getCaracReveActuel();
|
||||
case 'chance-actuelle': case 'chance-actuelle':
|
||||
return {
|
||||
label: 'Chance actuelle',
|
||||
value: this.getChanceActuel(),
|
||||
type: "number"
|
||||
};
|
||||
return this.getCaracChanceActuelle();
|
||||
}
|
||||
return RdDActor._findCaracByName(this.system.carac, name);
|
||||
}
|
||||
|
||||
getCaracChanceActuelle() {
|
||||
return {
|
||||
label: 'Chance actuelle',
|
||||
value: this.getChanceActuel(),
|
||||
type: "number"
|
||||
};
|
||||
}
|
||||
|
||||
getCaracReveActuel() {
|
||||
return {
|
||||
label: 'Rêve actuel',
|
||||
value: this.getReveActuel(),
|
||||
type: "number"
|
||||
};
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static _findCaracByName(carac, name) {
|
||||
name = Grammar.toLowerCaseNoAccent(name);
|
||||
@ -3217,7 +3146,7 @@ export class RdDActor extends Actor {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
getSortList() {
|
||||
return this.listItemsData("sort");
|
||||
return this.listItems("sort");
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
@ -3280,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,
|
||||
@ -3431,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]
|
||||
@ -3652,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) {
|
||||
@ -3671,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);
|
||||
}
|
||||
@ -3688,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]
|
||||
@ -3696,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({
|
||||
@ -3722,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]
|
||||
@ -3731,35 +3660,32 @@ export class RdDActor extends Actor {
|
||||
}
|
||||
|
||||
const cout = Number(achat.prixTotal ?? 0);
|
||||
const vente = achat.vente;
|
||||
const acheteur = achat.acheteurId ? game.actors.get(achat.acheteurId) : undefined;
|
||||
const vendeur = achat.vendeurId ? game.actors.get(achat.vendeurId) : undefined;
|
||||
let itemVendu = vendeur?.getObjet(vente.item._id);
|
||||
|
||||
if (vendeur && (itemVendu?.getQuantite() ?? 0) < achat.quantiteTotal) {
|
||||
ChatUtility.notifyUser(achat.userId, 'warn', `Le vendeur n'a plus assez de ${vente.item.name} !`);
|
||||
return;
|
||||
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?.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;
|
||||
}
|
||||
|
||||
achat.quantiteTotal = (achat.choix.nombreLots ?? 1) * (vente.tailleLot);
|
||||
if (vendeur) {
|
||||
await vendeur.ajouterSols(cout);
|
||||
await vendeur.decrementerQuantiteItem(itemVendu, achat.quantiteTotal,);
|
||||
}
|
||||
await this.decrementerVente(service, vendeur, itemVendu, quantite, cout);
|
||||
if (acheteur) {
|
||||
await acheteur.depenserSols(cout);
|
||||
let createdItemId = await acheteur.creerQuantiteItem(vente.item, achat.quantiteTotal);
|
||||
let createdItemId = await acheteur.creerQuantiteItem(vente.item, quantite);
|
||||
await acheteur.consommerNourritureAchetee(achat, vente, createdItemId);
|
||||
}
|
||||
if (cout > 0) {
|
||||
RdDAudio.PlayContextAudio("argent");
|
||||
}
|
||||
const chatAchatItem = duplicate(vente);
|
||||
chatAchatItem.quantiteTotal = achat.quantiteTotal;
|
||||
chatAchatItem.quantiteTotal = quantite;
|
||||
ChatMessage.create({
|
||||
user: achat.userId,
|
||||
speaker: { alias: (acheteur ?? vendeur).name },
|
||||
@ -3771,8 +3697,8 @@ export class RdDActor extends Actor {
|
||||
if (vente.quantiteNbLots <= achat.choix.nombreLots) {
|
||||
ChatUtility.removeChatMessageId(achat.chatMessageIdVente);
|
||||
}
|
||||
else {
|
||||
vente["properties"] = new RdDItem(vente.item).getProprietes();
|
||||
else if (!service) {
|
||||
vente["properties"] = itemVendu.getProprietes();
|
||||
vente.quantiteNbLots -= achat.choix.nombreLots;
|
||||
vente.jsondata = JSON.stringify(vente.item);
|
||||
const messageVente = game.messages.get(achat.chatMessageIdVente);
|
||||
@ -3782,6 +3708,21 @@ export class RdDActor extends Actor {
|
||||
}
|
||||
}
|
||||
|
||||
async decrementerVente(service, vendeur, itemVendu, quantite, cout) {
|
||||
if (service) {
|
||||
await service.venteRefItem(itemVendu, quantite, cout)
|
||||
}
|
||||
else if (vendeur) {
|
||||
await vendeur.ajouterSols(cout);
|
||||
await vendeur.decrementerQuantiteItem(itemVendu, quantite);
|
||||
}
|
||||
}
|
||||
|
||||
verifierQuantite(service, serviceSubItem, vendeur, item, quantiteTotal) {
|
||||
const disponible = service ? service.getQuantiteDisponible(serviceSubItem, quantiteTotal) : (vendeur ? (item?.getQuantite() ?? 0) : quantiteTotal);
|
||||
return disponible >= quantiteTotal;
|
||||
}
|
||||
|
||||
async consommerNourritureAchetee(achat, vente, createdItemId) {
|
||||
if (achat.choix.consommer && vente.item.type == 'nourritureboisson' && createdItemId != undefined) {
|
||||
achat.choix.doses = achat.choix.nombreLots;
|
||||
@ -3820,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`);
|
||||
@ -4090,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);
|
||||
}
|
||||
|
256
module/actor/base-actor-sheet.js
Normal file
256
module/actor/base-actor-sheet.js
Normal file
@ -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 = `<span class="competence-label">Selectionnez le type d'équipement</span><select class="item-type">`;
|
||||
for (let typeName of typeObjets) {
|
||||
content += `<option value="${typeName}">${Misc.typeName('Item', typeName)}</option>`
|
||||
}
|
||||
content += '</select>';
|
||||
let d = new Dialog({
|
||||
title: "Créer un équipement",
|
||||
content: content,
|
||||
buttons: {
|
||||
create: {
|
||||
icon: '<i class="fas fa-check"></i>',
|
||||
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])
|
||||
}
|
||||
}
|
||||
|
||||
}
|
167
module/actor/base-actor.js
Normal file
167
module/actor/base-actor.js
Normal file
@ -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)));
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -1,14 +1,13 @@
|
||||
|
||||
import { Monnaie } from "./item-monnaie.js";
|
||||
import { Misc } from "./misc.js";
|
||||
import { RdDUtility } from "./rdd-utility.js";
|
||||
|
||||
export class DialogItemAchat extends Dialog {
|
||||
|
||||
static venteData(button) {
|
||||
const vendeurId = button.attributes['data-vendeurId']?.value;
|
||||
static preparerAchat(chatButton) {
|
||||
const vendeurId = chatButton.attributes['data-vendeurId']?.value;
|
||||
const vendeur = vendeurId ? game.actors.get(vendeurId) : undefined;
|
||||
const acheteur = RdDUtility.getSelectedActor();
|
||||
const json = button.attributes['data-jsondata']?.value;
|
||||
const json = chatButton.attributes['data-jsondata']?.value;
|
||||
if (!acheteur && !vendeur) {
|
||||
ui.notifications.info("Pas d'acheteur ni de vendeur, aucun changement");
|
||||
return undefined;
|
||||
@ -18,46 +17,69 @@ export class DialogItemAchat extends Dialog {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const prixLot = Number(button.attributes['data-prixLot']?.value ?? 0);
|
||||
return {
|
||||
item: json ? JSON.parse(json) : undefined,
|
||||
actingUserId: game.user.id,
|
||||
vendeurId: vendeurId,
|
||||
vendeur: vendeur,
|
||||
acheteur: acheteur,
|
||||
tailleLot: parseInt(button.attributes['data-tailleLot']?.value ?? 1),
|
||||
quantiteIllimite: button.attributes['data-quantiteIllimite']?.value == 'true',
|
||||
quantiteNbLots: parseInt(button.attributes['data-quantiteNbLots']?.value),
|
||||
choix: {
|
||||
nombreLots: 1,
|
||||
seForcer: false,
|
||||
supprimerSiZero: true
|
||||
},
|
||||
prixLot: prixLot,
|
||||
prixTotal: prixLot,
|
||||
isVente: prixLot > 0,
|
||||
chatMessageIdVente: RdDUtility.findChatMessageId(button)
|
||||
item: (json ? JSON.parse(json) : undefined),
|
||||
vendeur,
|
||||
acheteur,
|
||||
nbLots: parseInt(chatButton.attributes['data-quantiteNbLots']?.value),
|
||||
tailleLot: parseInt(chatButton.attributes['data-tailleLot']?.value ?? 1),
|
||||
prixLot: Number(chatButton.attributes['data-prixLot']?.value ?? 0),
|
||||
quantiteIllimite: chatButton.attributes['data-quantiteIllimite']?.value == 'true',
|
||||
chatMessageIdVente: RdDUtility.findChatMessageId(chatButton),
|
||||
};
|
||||
}
|
||||
|
||||
static async onAcheter(venteData) {
|
||||
|
||||
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,
|
||||
quantiteNbLots: nbLots,
|
||||
choix: { seForcer: false, supprimerSiZero: true },
|
||||
prixLot,
|
||||
isVente: prixLot > 0,
|
||||
isConsommable: item.type == 'nourritureboisson' && acheteur?.isPersonnage(),
|
||||
chatMessageIdVente
|
||||
};
|
||||
|
||||
DialogItemAchat.changeNombreLots(venteData, 1);
|
||||
const html = await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/dialog-item-achat.html`, venteData);
|
||||
new DialogItemAchat(html, venteData).render(true);
|
||||
}
|
||||
|
||||
static changeNombreLots(venteData, nombreLots) {
|
||||
venteData.choix.nombreLots = nombreLots;
|
||||
venteData.prixTotal = (nombreLots * venteData.prixLot).toFixed(2);
|
||||
if (venteData.isConsommable) {
|
||||
const doses = nombreLots * venteData.tailleLot;
|
||||
venteData.totalSust = Misc.keepDecimals(doses * (venteData.item.system.sust ?? 0), 2);
|
||||
venteData.totalDesaltere = venteData.item.system.boisson
|
||||
? Misc.keepDecimals(doses * (venteData.item.system.desaltere ?? 0), 2)
|
||||
: 0;
|
||||
}
|
||||
}
|
||||
|
||||
constructor(html, venteData) {
|
||||
const isConsommable = venteData.item.type == 'nourritureboisson' && venteData.acheteur?.isPersonnage();
|
||||
let options = { classes: ["dialogachat"], width: 400, height: 'fit-content', 'z-index': 99999 };
|
||||
|
||||
const actionAchat = venteData.prixLot > 0 ? "Acheter" : "Prendre";
|
||||
const buttons = {};
|
||||
if (isConsommable) {
|
||||
if (venteData.isConsommable) {
|
||||
buttons["consommer"] = { label: venteData.item.system.boisson ? "Boire" : "Manger", callback: it => this.onAchatConsommer() }
|
||||
}
|
||||
buttons[actionAchat] = { label: actionAchat, callback: it => { this.onAchat(); } };
|
||||
buttons["decliner"] = { label: "Décliner", callback: it => { } };
|
||||
const acheteur = venteData.acheteur?.name ?? 'Un acheteur';
|
||||
const vendeur = (venteData.service ?? venteData.vendeur)?.name ?? 'Un vendeur';
|
||||
let conf = {
|
||||
title: venteData.acheteur ? venteData.acheteur.name + " - " + actionAchat : actionAchat,
|
||||
title: `${acheteur} - ${actionAchat} à ${vendeur}`,
|
||||
content: html,
|
||||
default: actionAchat,
|
||||
buttons: buttons
|
||||
@ -71,6 +93,7 @@ export class DialogItemAchat extends Dialog {
|
||||
await this.html.find(".nombreLots").change();
|
||||
(this.venteData.vendeur ?? this.venteData.acheteur).achatVente({
|
||||
userId: game.user.id,
|
||||
serviceId: this.venteData.service?.id,
|
||||
vendeurId: this.venteData.vendeur?.id,
|
||||
acheteurId: this.venteData.acheteur?.id,
|
||||
prixTotal: this.venteData.prixTotal,
|
||||
@ -98,13 +121,21 @@ export class DialogItemAchat extends Dialog {
|
||||
}
|
||||
|
||||
setNombreLots(nombreLots) {
|
||||
if (nombreLots > this.venteData.quantiteNbLots) {
|
||||
ui.notifications.warn(`Seulement ${this.venteData.quantiteNbLots} lots disponibles, vous ne pouvez pas en prendre ${nombreLots}`)
|
||||
|
||||
if (!this.venteData.quantiteIllimite) {
|
||||
if (!this.venteData.quantiteIllimite && nombreLots > this.venteData.quantiteNbLots) {
|
||||
ui.notifications.warn(`Seulement ${this.venteData.quantiteNbLots} lots disponibles, vous ne pouvez pas en prendre ${nombreLots}`)
|
||||
}
|
||||
nombreLots = Math.min(nombreLots, this.venteData.quantiteNbLots);
|
||||
}
|
||||
this.venteData.choix.nombreLots = Math.min(nombreLots, this.venteData.quantiteNbLots);
|
||||
this.venteData.prixTotal = (nombreLots * this.venteData.prixLot).toFixed(2);
|
||||
this.html.find(".nombreLots").val(this.venteData.choix.nombreLots);
|
||||
|
||||
DialogItemAchat.changeNombreLots(this.venteData, nombreLots);
|
||||
|
||||
this.html.find(".nombreLots").val(nombreLots);
|
||||
this.html.find(".prixTotal").text(this.venteData.prixTotal);
|
||||
this.html.find("span.total-sust").text(this.venteData.totalSust);
|
||||
this.html.find("span.total-desaltere").text(this.venteData.totalDesaltere);
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -2,21 +2,24 @@ import { HtmlUtility } from "./html-utility.js";
|
||||
|
||||
export class DialogItemVente extends Dialog {
|
||||
|
||||
static async display(item, callback) {
|
||||
const quantite = item.isConteneur() ? 1 : item.system.quantite;
|
||||
static async display({ item, callback, service = undefined, quantiteMax = undefined }) {
|
||||
const quantite = quantiteMax ?? item.getQuantite();
|
||||
const isOwned = item.isOwned;
|
||||
// const isOwned = item.isOwned || service?.actor;
|
||||
const venteData = {
|
||||
item: item,
|
||||
alias: item.actor?.name ?? game.user.name,
|
||||
vendeurId: item.actor?.id,
|
||||
alias: item.actor?.name ?? service?.name ?? game.user.name,
|
||||
serviceId: service?.id,
|
||||
vendeurId: item.actor?.id ?? service?.actor?.id,
|
||||
prixOrigine: item.system.cout,
|
||||
prixUnitaire: item.system.cout,
|
||||
prixLot: item.system.cout,
|
||||
tailleLot: 1,
|
||||
quantiteNbLots: quantite,
|
||||
quantiteMaxLots: quantite,
|
||||
quantiteMax: quantite ,
|
||||
quantiteIllimite: !item.isOwned,
|
||||
isOwned: item.isOwned,
|
||||
quantiteMax: quantite,
|
||||
quantiteIllimite: (service && service.system && service.system.illimite) ? service.system.illimite : !isOwned,
|
||||
isOwned: isOwned,
|
||||
};
|
||||
const html = await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/dialog-item-vente.html`, venteData);
|
||||
return new DialogItemVente(venteData, html, callback).render(true);
|
||||
@ -54,7 +57,7 @@ export class DialogItemVente extends Dialog {
|
||||
await this.html.find(".quantiteIllimite").change();
|
||||
await this.html.find(".prixLot").change();
|
||||
this.callback(this.venteData);
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
setPrixLot(prixLot) {
|
||||
@ -68,13 +71,11 @@ export class DialogItemVente extends Dialog {
|
||||
this.html.find(".prixLot").val(this.venteData.prixLot);
|
||||
}
|
||||
this.venteData.tailleLot = tailleLot;
|
||||
if (this.venteData.isOwned) {
|
||||
// recalculer le nombre de lots max
|
||||
this.venteData.quantiteMaxLots = Math.floor(this.venteData.quantiteMax / tailleLot);
|
||||
this.venteData.quantiteNbLots = Math.min(this.venteData.quantiteMaxLots, this.venteData.quantiteNbLots);
|
||||
this.html.find(".quantiteNbLots").val(this.venteData.quantiteNbLots);
|
||||
this.html.find(".quantiteNbLots").attr("max", this.venteData.quantiteMaxLots)
|
||||
}
|
||||
// recalculer le nombre de lots max
|
||||
this.venteData.quantiteMaxLots = Math.floor(this.venteData.quantiteMax / tailleLot);
|
||||
this.venteData.quantiteNbLots = Math.min(this.venteData.quantiteMaxLots, this.venteData.quantiteNbLots);
|
||||
this.html.find(".quantiteNbLots").val(this.venteData.quantiteNbLots);
|
||||
this.html.find(".quantiteNbLots").attr("max", this.venteData.quantiteMaxLots)
|
||||
}
|
||||
|
||||
setNbLots(nbLots) {
|
||||
|
@ -1,4 +1,3 @@
|
||||
import { Misc } from "./misc.js";
|
||||
|
||||
export class DialogRepos extends Dialog {
|
||||
|
||||
@ -33,6 +32,7 @@ export class DialogRepos extends Dialog {
|
||||
const selection = await this.html.find("[name='repos']:checked").val();
|
||||
const nbHeures = Number.parseInt(await this.html.find("[name='nb-heures']").val());
|
||||
const nbJours = Number.parseInt(await this.html.find("[name='nb-jours']").val());
|
||||
console.log("ACTOR", this.actor)
|
||||
switch (selection) {
|
||||
case "sieste": {
|
||||
await this.actor.dormir(nbHeures);
|
||||
|
@ -2,22 +2,22 @@ import { Misc } from "./misc.js";
|
||||
import { LOG_HEAD } from "./constants.js";
|
||||
|
||||
const MONNAIE_ETAIN = {
|
||||
name: "Etain (1 denier)", type: 'monnaie',
|
||||
name: "Denier (étain)", type: 'monnaie',
|
||||
img: "systems/foundryvtt-reve-de-dragon/icons/objets/piece_etain_poisson.webp",
|
||||
system: { quantite: 0, cout: 0.01, encombrement: 0.001, description: "" }
|
||||
};
|
||||
const MONNAIE_BRONZE = {
|
||||
name: "Bronze (10 deniers)", type: 'monnaie',
|
||||
name: "Sou (bronze)", type: 'monnaie',
|
||||
img: "systems/foundryvtt-reve-de-dragon/icons/objets/piece_bronze_epees.webp",
|
||||
system: { quantite: 0, cout: 0.10, encombrement: 0.002, description: "" }
|
||||
};
|
||||
const MONNAIE_ARGENT = {
|
||||
name: "Argent (1 sol)", type: 'monnaie',
|
||||
name: "Sol (argent)", type: 'monnaie',
|
||||
img: "systems/foundryvtt-reve-de-dragon/icons/objets/piece_argent_sol.webp",
|
||||
system: { quantite: 0, cout: 1, encombrement: 0.003, description: "" }
|
||||
};
|
||||
const MONNAIE_OR = {
|
||||
name: "Or (10 sols)", type: 'monnaie',
|
||||
name: "Dreagon (or)", type: 'monnaie',
|
||||
img: "systems/foundryvtt-reve-de-dragon/icons/objets/piece_or_sol.webp",
|
||||
system: { quantite: 0, cout: 10, encombrement: 0.004, description: "" }
|
||||
};
|
||||
@ -62,21 +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 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]) {
|
||||
@ -99,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);
|
||||
|
@ -23,15 +23,8 @@ export class RdDRencontreItemSheet extends RdDItemSheet {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async getData() {
|
||||
const formData = duplicate(this.item);
|
||||
const formData = await super.getData();
|
||||
mergeObject(formData, {
|
||||
title: formData.name,
|
||||
isGM: game.user.isGM,
|
||||
owner: this.actor?.isOwner,
|
||||
isOwned: this.actor ? true : false,
|
||||
actorId: this.actor?.id,
|
||||
editable: this.isEditable,
|
||||
cssClass: this.isEditable ? "editable" : "locked",
|
||||
effets: {
|
||||
succes: {
|
||||
liste: RdDRencontre.getEffetsSucces(),
|
||||
|
81
module/item-service-sheet.js
Normal file
81
module/item-service-sheet.js
Normal file
@ -0,0 +1,81 @@
|
||||
import { RdDItemSheet } from "./item-sheet.js";
|
||||
import { Misc } from "./misc.js";
|
||||
import { RdDUtility } from "./rdd-utility.js";
|
||||
import { SystemCompendiums } from "./settings/system-compendiums.js";
|
||||
import { DialogItemAchat } from "./dialog-item-achat.js";
|
||||
import { RdDItem } from "./item.js";
|
||||
import { RdDItemService } from "./item-service.js";
|
||||
|
||||
export class RdDServiceItemSheet extends RdDItemSheet {
|
||||
|
||||
static get ITEM_TYPE() { return "service" };
|
||||
|
||||
async getData() {
|
||||
const formData = await super.getData();
|
||||
formData.disabled = formData.isGM || formData.isOwned ? '' : 'disabled';
|
||||
return formData;
|
||||
}
|
||||
|
||||
activateListeners(html) {
|
||||
super.activateListeners(html);
|
||||
|
||||
this.html.find('a.rdd-world-content-link').click(async event => {
|
||||
const itemRef = this.getItemRef(event);
|
||||
game.items.get(itemRef.id)?.sheet.render(true)
|
||||
});
|
||||
|
||||
this.html.find('a.sub-item-acheter').click(async event => {
|
||||
const subItem = this.item.findRefItem(this.getItemRef(event));
|
||||
await this.item.acheter(RdDUtility.getSelectedActor(), subItem);
|
||||
});
|
||||
|
||||
if (!this.options.editable) return;
|
||||
|
||||
this.html.find('a.sub-item-vendre').click(async event => {
|
||||
const subItem = this.item.findRefItem(this.getItemRef(event));
|
||||
await this.item.vendre(subItem);
|
||||
});
|
||||
|
||||
this.html.find('a.sub-item-delete').click(async event => {
|
||||
await this.item.removeRefItem(this.getItemRef(event));
|
||||
});
|
||||
|
||||
this.html.find('a.sub-item-quantite-moins').click(async event => await this.item.increaseRefItemQuantite(this.getItemRef(event), -1))
|
||||
this.html.find('a.sub-item-quantite-plus').click(async event => await this.item.increaseRefItemQuantite(this.getItemRef(event), 1))
|
||||
this.html.find('input.sub-item-quantite').change(async event => {
|
||||
const newQuantite = Math.max(0, Number.parseInt(this.html.find(event.currentTarget).val()));
|
||||
await this.item.updateRefItem(this.getItemRef(event), it => it.system.quantite = newQuantite);
|
||||
})
|
||||
this.html.find('input.sub-item-cout').change(async event => {
|
||||
const newCout = Math.max(0, Number(this.html.find(event.currentTarget).val()));
|
||||
await this.item.updateRefItem(this.getItemRef(event), it => it.system.cout = newCout);
|
||||
})
|
||||
this.html.find('a.sub-item-info-add').click(__ =>
|
||||
ui.notifications.info(`Utiliser le glisser-déposer pour ajouter des objets depuis un compendium ou les objets du monde`)
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
async _onDropItem(event, dragData) {
|
||||
let linkedItem = fromUuidSync(dragData.uuid);
|
||||
const existing = this.item.system.items.find(it => it.pack == linkedItem.pack && it.id == linkedItem.id && it.type == linkedItem.type);
|
||||
if (existing) {
|
||||
ui.notifications.warn(`${this.item.name} contient déjà un ${existing.name}`);
|
||||
return;
|
||||
}
|
||||
if (linkedItem.pack) {
|
||||
linkedItem = await SystemCompendiums.loadDocument(linkedItem);
|
||||
}
|
||||
if (linkedItem.isInventaire()) {
|
||||
await this.item.addRefItem(RdDItemService.createSubItem(linkedItem));
|
||||
}
|
||||
else {
|
||||
ui.notifications.warn(`${this.item.name} ne peut pas proposer à la vente de ${Misc.typeName('Item', linkedItem.type)}: ${linkedItem.name}`);
|
||||
}
|
||||
}
|
||||
|
||||
getItemRef(event) {
|
||||
const itemRow = this.html.find(event.currentTarget)?.parents('.item.service-item');
|
||||
return { id: itemRow?.data("item-id"), pack: itemRow?.data("pack") ?? undefined }
|
||||
}
|
||||
}
|
141
module/item-service.js
Normal file
141
module/item-service.js
Normal file
@ -0,0 +1,141 @@
|
||||
import { DialogItemAchat } from "./dialog-item-achat.js";
|
||||
import { RdDItem } from "./item.js";
|
||||
import { Misc } from "./misc.js";
|
||||
|
||||
export class RdDItemService extends RdDItem {
|
||||
|
||||
static get defaultIcon() {
|
||||
return "systems/foundryvtt-reve-de-dragon/icons/items/services.webp";
|
||||
}
|
||||
|
||||
/** @override*/
|
||||
getUserLevel(user) {
|
||||
const level = super.getUserLevel(user);
|
||||
if (level == CONST.DOCUMENT_OWNERSHIP_LEVELS.NONE) {
|
||||
// si quelqu'un a accès au lien d'un service, il peut le voir
|
||||
return CONST.DOCUMENT_OWNERSHIP_LEVELS.LIMITED;
|
||||
}
|
||||
return level;
|
||||
}
|
||||
|
||||
isService() { return true; }
|
||||
getChatItemTemplate() { return 'systems/foundryvtt-reve-de-dragon/templates/post-item-service.html'; }
|
||||
getProprietes() { return []; }
|
||||
|
||||
getServiceItem(itemRef) {
|
||||
if (itemRef && this.isService()) {
|
||||
return this.system.items.find(it => it.id == itemRef.id && it.pack == itemRef.pack);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
getQuantiteDisponible(itemRef, max) {
|
||||
if (this.system.illimite) {
|
||||
return max;
|
||||
}
|
||||
const subItem = this.getServiceItem(itemRef);
|
||||
return subItem?.system.quantite ?? 0;
|
||||
}
|
||||
|
||||
async venteRefItem(ref, quantite, cout) {
|
||||
if (this.actor) {
|
||||
await this.actor.ajouterSols(cout);
|
||||
}
|
||||
await this.increaseRefItemQuantite(ref, -quantite);
|
||||
}
|
||||
|
||||
async vendre(subItem) {
|
||||
const item = await RdDItem.getCorrespondingItem(subItem);
|
||||
const quantiteMax = this.system.illimite ? undefined : subItem.system.quantite;
|
||||
await item.proposerVente({ service: this, quantiteMax });
|
||||
}
|
||||
|
||||
async acheter(acheteur, subItem) {
|
||||
if (!acheteur) {
|
||||
ui.notifications.warn(`Pas d'acheteur sélectionné`);
|
||||
return;
|
||||
}
|
||||
const nbLots = this.system.illimite ? 1 : subItem.system.quantite;
|
||||
if (nbLots <= 0) {
|
||||
ui.notifications.warn(`${this.name} n'a plus de ${subItem.name} en vente`);
|
||||
return;
|
||||
}
|
||||
|
||||
await DialogItemAchat.onAcheter({
|
||||
item: await RdDItem.getCorrespondingItem(subItem),
|
||||
acheteur,
|
||||
serviceSubItem: subItem,
|
||||
service: this,
|
||||
quantiteIllimite: this.system.illimite,
|
||||
nbLots,
|
||||
tailleLot: 1,
|
||||
prixLot: subItem.system.cout
|
||||
});
|
||||
}
|
||||
|
||||
static createSubItem(linkedItem) {
|
||||
return {
|
||||
id: linkedItem.id,
|
||||
pack: linkedItem.pack,
|
||||
name: linkedItem.name,
|
||||
img: linkedItem.img,
|
||||
system: {
|
||||
quantite: 1,
|
||||
cout: linkedItem.system.cout ?? 0
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
static matchRefItem({ id, pack }) {
|
||||
return it => it.id == id && (pack ? (it.pack == pack) : (!it.pack));
|
||||
}
|
||||
|
||||
findRefItem(ref) {
|
||||
return this.system.items.find(RdDItemService.matchRefItem(ref));
|
||||
}
|
||||
|
||||
async increaseRefItemQuantite(ref, quantite) {
|
||||
await this.updateRefItem(ref,
|
||||
it => it.system.quantite = Math.max(0, it.system.quantite + quantite)
|
||||
);
|
||||
}
|
||||
|
||||
async updateRefItem(ref, update = it => { }) {
|
||||
await this.updateRefItems(RdDItemService.matchRefItem(ref), update);
|
||||
}
|
||||
|
||||
async addRefItem(newItem) {
|
||||
if (!newItem.id) {
|
||||
ui.notifications.warn(`${newItem?.name ?? '??'} n'a pas d'identifiant`);
|
||||
return;
|
||||
}
|
||||
if (this.system.items.find(RdDItemService.matchRefItem(newItem))) {
|
||||
ui.notifications.warn(`${newItem?.name ?? newItem.id} est déjà présent ici`);
|
||||
return;
|
||||
}
|
||||
await this.setRefItems([...this.system.items, newItem]);
|
||||
}
|
||||
|
||||
async removeRefItem(ref) {
|
||||
await this.removeRefItems(RdDItemService.matchRefItem(ref));
|
||||
}
|
||||
|
||||
async removeRefItems(matcher = it => false) {
|
||||
await this.setRefItems(this.system.items.filter(it => !matcher(it)));
|
||||
}
|
||||
|
||||
async updateRefItems(matcher = it => false, update = it => { }) {
|
||||
const updatedList = this.system.items.map(it => {
|
||||
if (matcher(it)) {
|
||||
update(it);
|
||||
}
|
||||
return it;
|
||||
});
|
||||
await this.setRefItems(updatedList);
|
||||
}
|
||||
|
||||
async setRefItems(newItems) {
|
||||
await this.update({ 'system.items': newItems.sort(Misc.ascending(it => it.type + ':' + it.name)) });
|
||||
}
|
||||
|
||||
}
|
@ -60,13 +60,13 @@ export class RdDItemSheet extends ItemSheet {
|
||||
buttons.unshift({
|
||||
class: "vendre",
|
||||
icon: "fas fa-comments-dollar",
|
||||
onclick: ev => this.item.proposerVente()
|
||||
onclick: ev => this.item.proposerVente({service: this, quantiteMax: 1})
|
||||
});
|
||||
}
|
||||
buttons.unshift({
|
||||
class: "montrer",
|
||||
icon: "fas fa-comment",
|
||||
onclick: ev => this.item.postItem()
|
||||
onclick: ev => this.item.postItemToChat()
|
||||
});
|
||||
return buttons
|
||||
}
|
||||
@ -209,9 +209,9 @@ export class RdDItemSheet extends ItemSheet {
|
||||
|
||||
this.html.find('.item-split').click(async event => RdDSheetUtility.splitItem(RdDSheetUtility.getItem(event, this.actor), this.actor, async () => this.render(true)));
|
||||
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.confirmerSuppressionItem(this, RdDSheetUtility.getItem(event, 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('.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)));
|
||||
}
|
||||
|
||||
|
@ -23,18 +23,9 @@ export class RdDSigneDraconiqueItemSheet extends RdDItemSheet {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async getData() {
|
||||
const formData = duplicate(this.item);
|
||||
const formData = await super.getData();
|
||||
this.tmrs = TMRUtility.buildSelectionTypesTMR(this.item.system.typesTMR);
|
||||
mergeObject(formData, {
|
||||
tmrs: this.tmrs,
|
||||
title: formData.name,
|
||||
isGM: game.user.isGM,
|
||||
owner: this.actor?.isOwner,
|
||||
isOwned: this.actor ? true : false,
|
||||
actorId: this.actor?.id,
|
||||
editable: this.isEditable,
|
||||
cssClass: this.isEditable ? "editable" : "locked",
|
||||
});
|
||||
formData.tmrs = this.tmrs;
|
||||
return formData;
|
||||
}
|
||||
|
||||
|
154
module/item.js
154
module/item.js
@ -3,6 +3,7 @@ import { Grammar } from "./grammar.js";
|
||||
import { Misc } from "./misc.js";
|
||||
import { RdDHerbes } from "./rdd-herbes.js";
|
||||
import { RdDUtility } from "./rdd-utility.js";
|
||||
import { SystemCompendiums } from "./settings/system-compendiums.js";
|
||||
|
||||
const typesObjetsInventaire = [
|
||||
"arme",
|
||||
@ -57,6 +58,7 @@ export const defaultItemImg = {
|
||||
poison: "systems/foundryvtt-reve-de-dragon/icons/maladies_venins/venin.webp",
|
||||
oeuvre: "systems/foundryvtt-reve-de-dragon/icons/competence_comedie.webp",
|
||||
nourritureboisson: "systems/foundryvtt-reve-de-dragon/icons/objets/provision_crue.webp",
|
||||
service: "systems/foundryvtt-reve-de-dragon/icons/items/services.webp",
|
||||
signedraconique: "systems/foundryvtt-reve-de-dragon/icons/tmr/signe_draconique.webp",
|
||||
gemme: "systems/foundryvtt-reve-de-dragon/icons/gemmes/almaze.webp",
|
||||
possession: "systems/foundryvtt-reve-de-dragon/icons/entites/possession2.webp",
|
||||
@ -69,11 +71,7 @@ export const defaultItemImg = {
|
||||
export class RdDItem extends Item {
|
||||
|
||||
static getDefaultImg(itemType) {
|
||||
return defaultItemImg[itemType];
|
||||
}
|
||||
|
||||
static isItemInventaire(newLocal) {
|
||||
return typesObjetsInventaire.includes(newLocal.type);
|
||||
return game.system.rdd.itemClasses[itemType]?.defaultIcon ?? defaultItemImg[itemType];
|
||||
}
|
||||
|
||||
static isFieldInventaireModifiable(type, field) {
|
||||
@ -92,6 +90,42 @@ export class RdDItem extends Item {
|
||||
return true;
|
||||
}
|
||||
|
||||
static async getCorrespondingItem(itemRef) {
|
||||
if (itemRef.pack) {
|
||||
return await SystemCompendiums.loadDocument(itemRef)
|
||||
}
|
||||
return game.items.get(itemRef.id ?? itemRef._id);
|
||||
}
|
||||
|
||||
static getItemTypesInventaire() {
|
||||
return typesObjetsInventaire
|
||||
}
|
||||
|
||||
static getTypesOeuvres() {
|
||||
return typesObjetsOeuvres
|
||||
}
|
||||
|
||||
constructor(docData, context = {}) {
|
||||
if (!context.rdd?.ready) {
|
||||
mergeObject(context, { rdd: { ready: true } });
|
||||
const ItemConstructor = game.system.rdd.itemClasses[docData.type];
|
||||
if (ItemConstructor) {
|
||||
if (!docData.img) {
|
||||
docData.img = ItemConstructor.defaultIcon;
|
||||
}
|
||||
return new ItemConstructor(docData, context);
|
||||
}
|
||||
}
|
||||
if (!docData.img) {
|
||||
docData.img = RdDItem.getDefaultImg(docData.type);
|
||||
}
|
||||
super(docData, context);
|
||||
}
|
||||
|
||||
static get defaultIcon() {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
getUniteQuantite() {
|
||||
switch (this.type) {
|
||||
case "monnaie": return "(Pièces)"
|
||||
@ -107,32 +141,17 @@ export class RdDItem extends Item {
|
||||
return '';
|
||||
}
|
||||
|
||||
constructor(itemData, context) {
|
||||
if (!itemData.img) {
|
||||
itemData.img = RdDItem.getDefaultImg(itemData.type);
|
||||
}
|
||||
super(itemData, context);
|
||||
}
|
||||
|
||||
static getItemTypesInventaire() {
|
||||
return typesObjetsInventaire
|
||||
}
|
||||
|
||||
static getTypesOeuvres() {
|
||||
return typesObjetsOeuvres
|
||||
}
|
||||
|
||||
isCompetencePersonnage() {
|
||||
return this.type == 'competence'
|
||||
}
|
||||
isCompetenceCreature() {
|
||||
return this.type == 'competencecreature'
|
||||
}
|
||||
isCompetencePersonnage() { return this.type == 'competence' }
|
||||
isCompetenceCreature() { return this.type == 'competencecreature' }
|
||||
isConteneur() { return this.type == 'conteneur'; }
|
||||
isMonnaie() { return this.type == 'monnaie'; }
|
||||
isNourritureBoisson() { return this.type == 'nourritureboisson'; }
|
||||
isService() { return this.type == 'service'; }
|
||||
isCompetence() {
|
||||
return typesObjetsCompetence.includes(this.type)
|
||||
}
|
||||
isInventaire() {
|
||||
return RdDItem.isItemInventaire(this)
|
||||
return typesObjetsInventaire.includes(this.type);
|
||||
}
|
||||
isOeuvre() {
|
||||
return typesObjetsOeuvres.includes(this.type)
|
||||
@ -146,12 +165,7 @@ export class RdDItem extends Item {
|
||||
isConnaissance() {
|
||||
return typesObjetsConnaissance.includes(this.type)
|
||||
}
|
||||
isConteneur() {
|
||||
return this.type == 'conteneur';
|
||||
}
|
||||
isMonnaie() {
|
||||
return this.type == 'monnaie';
|
||||
}
|
||||
|
||||
|
||||
getItemGroup() {
|
||||
if (this.isInventaire()) return "equipement";
|
||||
@ -175,10 +189,6 @@ export class RdDItem extends Item {
|
||||
return !this.isConteneur() || (this.system.contenu?.length ?? 0) == 0;
|
||||
}
|
||||
|
||||
isNourritureBoisson() {
|
||||
return this.type == 'nourritureboisson';
|
||||
}
|
||||
|
||||
isComestible() {
|
||||
switch (this.type) {
|
||||
case 'nourritureboisson': return 'pret';
|
||||
@ -209,7 +219,7 @@ export class RdDItem extends Item {
|
||||
}
|
||||
|
||||
getQuantite() {
|
||||
return Math.round(this.isConteneur() ? 1 : (this.system.quantite ?? 0))
|
||||
return Math.round(this.system.quantite ?? 0)
|
||||
}
|
||||
|
||||
getEncTotal() {
|
||||
@ -284,7 +294,7 @@ export class RdDItem extends Item {
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async actionPrincipale(actor, onActionItem = async () => { }) {
|
||||
if (!this.getActionPrincipale()) {
|
||||
@ -410,54 +420,67 @@ export class RdDItem extends Item {
|
||||
return [true, undefined];
|
||||
}
|
||||
|
||||
async proposerVente() {
|
||||
async proposerVente({ service = undefined, quantiteMax = undefined }) {
|
||||
console.log(this);
|
||||
if (this.isConteneurNonVide()) {
|
||||
ui.notifications.warn(`Votre ${this.name} n'est pas vide, pas possible de le proposer`);
|
||||
return;
|
||||
}
|
||||
await DialogItemVente.display(this, async (vente) => {
|
||||
vente["properties"] = this.getProprietes();
|
||||
if (vente.isOwned) {
|
||||
if (vente.quantiteNbLots * vente.tailleLot > vente.quantiteMax) {
|
||||
ui.notifications.warn(`Vous avez ${vente.quantiteMax} ${vente.item.name}, ce n'est pas suffisant pour vendre ${vente.quantiteNbLots} de ${vente.tailleLot}`)
|
||||
return;
|
||||
await DialogItemVente.display({
|
||||
item: this,
|
||||
service: service,
|
||||
quantiteMax,
|
||||
callback: async (vente) => {
|
||||
vente["properties"] = this.getProprietes();
|
||||
if (vente.isOwned) {
|
||||
if (vente.quantiteNbLots * vente.tailleLot > vente.quantiteMax) {
|
||||
ui.notifications.warn(`Vous avez ${vente.quantiteMax} ${vente.item.name}, ce n'est pas suffisant pour vendre ${vente.quantiteNbLots} de ${vente.tailleLot}`)
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
vente.jsondata = JSON.stringify(vente.item);
|
||||
vente.jsondata = JSON.stringify(vente.item);
|
||||
|
||||
console.log(vente);
|
||||
let html = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-vente-item.html', vente);
|
||||
ChatMessage.create(RdDUtility.chatDataSetup(html));
|
||||
let html = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-vente-item.html', vente);
|
||||
ChatMessage.create(RdDUtility.chatDataSetup(html));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
getProprietes() {
|
||||
return this[`_${this.type}ChatData`]().filter(it => it != undefined);
|
||||
if (this[`_${this.type}ChatData`]) {
|
||||
return this[`_${this.type}ChatData`]().filter(it => it != undefined);
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
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('systems/foundryvtt-reve-de-dragon/templates/post-item.html', chatData).then(html => {
|
||||
renderTemplate(this.getChatItemTemplate(), chatData).then(html => {
|
||||
let chatOptions = RdDUtility.chatDataSetup(html, modeOverride);
|
||||
ChatMessage.create(chatOptions)
|
||||
});
|
||||
}
|
||||
|
||||
getChatItemTemplate() {
|
||||
switch (this.type) {
|
||||
case 'service': return 'systems/foundryvtt-reve-de-dragon/templates/post-item-service.html';
|
||||
}
|
||||
return 'systems/foundryvtt-reve-de-dragon/templates/post-item.html';
|
||||
}
|
||||
|
||||
static propertyIfDefined(name, val, condition = true) {
|
||||
return condition ? `<b>${name}</b>: ${val}` : undefined;
|
||||
}
|
||||
@ -706,5 +729,4 @@ export class RdDItem extends Item {
|
||||
...this._inventaireTemplateChatData()
|
||||
]
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -29,6 +29,39 @@ class Migration {
|
||||
|
||||
}
|
||||
|
||||
class _1_5_34_migrationPngWebp {
|
||||
get code() { return "migrationPngWebp"; }
|
||||
get version() { return "1.5.34"; }
|
||||
async migrate() {
|
||||
|
||||
const regexOldPngJpg = /(systems\/foundryvtt-reve-de-dragon\/icons\/.*)\.(png|jpg)/;
|
||||
const replaceWithWebp = '$1.webp';
|
||||
function convertImgToWebp(img) {
|
||||
return img.replace(regexOldPngJpg, replaceWithWebp);
|
||||
}
|
||||
function prepareDocumentsImgUpdate(documents) {
|
||||
return documents.filter(it => it.img && it.img.match(regexOldPngJpg))
|
||||
.map(it => {
|
||||
return { _id: it.id, img: convertImgToWebp(it.img) }
|
||||
});
|
||||
}
|
||||
|
||||
const itemsUpdates = prepareDocumentsImgUpdate(game.items);
|
||||
const actorsUpdates = prepareDocumentsImgUpdate(game.actors);
|
||||
//Migrate system png to webp
|
||||
await Item.updateDocuments(itemsUpdates);
|
||||
await Actor.updateDocuments(actorsUpdates);
|
||||
game.actors.forEach(actor => {
|
||||
if (actor.token?.img && actor.token.img.match(regexOldPngJpg)) {
|
||||
actor.update({ "token.img": convertImgToWebp(actor.token.img) });
|
||||
}
|
||||
const actorItemsToUpdate = prepareDocumentsImgUpdate(actor.items);
|
||||
actor.updateEmbeddedDocuments('Item', actorItemsToUpdate);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class _10_0_16_MigrationSortsReserve extends Migration {
|
||||
get code() { return "creation-item-sort-reserve"; }
|
||||
get version() { return "10.0.16"; }
|
||||
@ -236,7 +269,7 @@ class _10_3_0_Inventaire extends Migration {
|
||||
}
|
||||
_updatesMonnaies(items) {
|
||||
return items
|
||||
.filter(it => ['monnaie'].includes(it.type) && it.system.cout == undefined)
|
||||
.filter(it => ['monnaie'].includes(it.type) && it.system.valeur_deniers != undefined)
|
||||
.map(it => { return { _id: it.id, 'system.cout': it.system.valeur_deniers / 100, 'system.valeur_deniers': undefined } });
|
||||
}
|
||||
}
|
||||
@ -259,9 +292,44 @@ class _10_3_0_FrequenceEnvironnement extends Migration {
|
||||
}
|
||||
}
|
||||
|
||||
class _10_3_17_Monnaies extends Migration {
|
||||
constructor() {
|
||||
super();
|
||||
this.mapValeur = {
|
||||
"Etain (1 denier)": { name: 'Denier (étain)', system: { cout: 0.01 } },
|
||||
"Bronze (10 deniers)": { name: "Sou (bronze)", system: { cout: 0.1 } },
|
||||
"Argent (1 sol)": { name: "Sol (argent)", system: { cout: 1 } },
|
||||
"Or (10 sols)": { name: "Dragon (or)", system: { cout: 10 } }
|
||||
};
|
||||
}
|
||||
get code() { return "migration-monnaies"; }
|
||||
get version() { return "10.3.17"; }
|
||||
|
||||
async migrate() {
|
||||
await this.applyItemsUpdates(items => this._updatesMonnaies(items));
|
||||
}
|
||||
|
||||
_updatesMonnaies(items) {
|
||||
return items
|
||||
.filter(it => 'monnaie' == it.type)
|
||||
.filter(it => this.mapValeur[it.name] != undefined)
|
||||
.map(it => {
|
||||
const correction = this.mapValeur[it.name];
|
||||
return {
|
||||
_id: it.id,
|
||||
'name': correction.name,
|
||||
'system.cout': correction.system.cout,
|
||||
'system.valeur_deniers': undefined
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export class Migrations {
|
||||
static getMigrations() {
|
||||
return [
|
||||
new _1_5_34_migrationPngWebp(),
|
||||
new _10_0_16_MigrationSortsReserve(),
|
||||
new _10_0_17_MigrationCompetenceCreature(),
|
||||
new _10_0_21_VehiculeStructureResistanceMax(),
|
||||
@ -269,7 +337,8 @@ export class Migrations {
|
||||
new _10_2_5_ArmesTirLancer(),
|
||||
new _10_2_10_DesirLancinant_IdeeFixe(),
|
||||
new _10_3_0_Inventaire(),
|
||||
new _10_3_0_FrequenceEnvironnement()
|
||||
new _10_3_0_FrequenceEnvironnement(),
|
||||
new _10_3_17_Monnaies()
|
||||
];
|
||||
}
|
||||
|
||||
@ -284,9 +353,9 @@ export class Migrations {
|
||||
}
|
||||
|
||||
migrate() {
|
||||
const currentVersion = game.settings.get(SYSTEM_RDD,"systemMigrationVersion");
|
||||
//if (isNewerVersion(game.system.version, currentVersion)) {
|
||||
if (true) { /* comment previous and uncomment here to test before upgrade */
|
||||
const currentVersion = game.settings.get(SYSTEM_RDD, "systemMigrationVersion");
|
||||
if (isNewerVersion(game.system.version, currentVersion)) {
|
||||
//if (true) { /* comment previous and uncomment here to test before upgrade */
|
||||
const migrations = Migrations.getMigrations().filter(m => isNewerVersion(m.version, currentVersion));
|
||||
if (migrations.length > 0) {
|
||||
migrations.sort((a, b) =>
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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]) {
|
||||
|
@ -29,7 +29,7 @@ export class RdDCalendrierEditeur extends Dialog {
|
||||
this.html.find("input[name='nomMois']").val(this.calendrierData.moisKey);
|
||||
this.html.find("select[name='nomHeure']").val(this.calendrierData.heureKey);
|
||||
this.html.find("select[name='jourMois']").val(this.calendrierData.jourMois);
|
||||
this.html.find("select[name='minutesRelative']").val(calendrierData.minutesRelative);
|
||||
this.html.find("select[name='minutesRelative']").val(this.calendrierData.minutesRelative);
|
||||
this.html.find("select[name='annee']").val(this.calendrierData.annee);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -162,7 +162,6 @@ export class RdDCombatManager extends Combat {
|
||||
if (arme.system.unemain && arme.system.deuxmains && !dommages.includes("/")) {
|
||||
ui.notifications.info("Les dommages de l'arme à 1/2 mains " + arme.name + " ne sont pas corrects (ie sous la forme X/Y)");
|
||||
}
|
||||
console.log(">>>>", arme)
|
||||
if ((arme.system.unemain && arme.system.competence) ||
|
||||
(arme.system.competence.toLowerCase().includes("corps à corps"))) {
|
||||
actions.push(RdDCombatManager.$prepareAttaqueArme({
|
||||
@ -248,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())
|
||||
|
@ -331,7 +331,7 @@ export class RdDCommands {
|
||||
diff = 0;
|
||||
}
|
||||
const caracName = params[0];
|
||||
let competence = length > 1 ? actors[0].getCompetence(Misc.join(params.slice(1, length), ' ')) : undefined;
|
||||
let competence = length > 1 ? actors[0].getCompetence(Misc.join(params.slice(1, length), ' ')) : {name:undefined};
|
||||
if (competence) {
|
||||
for (let actor of actors) {
|
||||
await actor.rollCaracCompetence(caracName, competence.name, diff);
|
||||
|
@ -1,4 +1,3 @@
|
||||
import { Misc } from "./misc.js";
|
||||
|
||||
export class RdDHotbar {
|
||||
|
||||
|
@ -1,13 +1,3 @@
|
||||
/**
|
||||
* RdD system
|
||||
* Author: LeRatierBretonnien
|
||||
* Software License: GNU GPLv3
|
||||
*/
|
||||
|
||||
/* -------------------------------------------- */
|
||||
|
||||
/* -------------------------------------------- */
|
||||
// Import Modules
|
||||
import { SYSTEM_RDD, SYSTEM_SOCKET_ID } from "./constants.js";
|
||||
import { RdDActor } from "./actor.js";
|
||||
import { RdDItemSheet } from "./item-sheet.js";
|
||||
@ -44,302 +34,286 @@ import { Environnement } from "./environnement.js";
|
||||
import { RdDIngredientItemSheet } from "./item-ingredient-sheet.js";
|
||||
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";
|
||||
|
||||
/* -------------------------------------------- */
|
||||
/* Foundry VTT Initialization */
|
||||
/* -------------------------------------------- */
|
||||
/**
|
||||
* RdD system
|
||||
* Author: LeRatierBretonnien
|
||||
* Software License: GNU GPLv3
|
||||
*/
|
||||
export class SystemReveDeDragon {
|
||||
|
||||
|
||||
|
||||
/************************************************************************************/
|
||||
Hooks.once("init", async function () {
|
||||
console.log(`Initializing Reve de Dragon System`);
|
||||
|
||||
// preload handlebars templates
|
||||
RdDUtility.preloadHandlebarsTemplates();
|
||||
// Create useful storage space
|
||||
game.system.rdd = {
|
||||
TMRUtility,
|
||||
RdDUtility,
|
||||
RdDHotbar,
|
||||
RdDPossession,
|
||||
static start() {
|
||||
const system = new SystemReveDeDragon();
|
||||
Hooks.once('init', async () => await system.onInit());
|
||||
Hooks.once('diceSoNiceReady', (dice3d) => RdDDice.diceSoNiceReady(dice3d));
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
game.settings.register(SYSTEM_RDD, "accorder-entite-cauchemar", {
|
||||
name: "Accorder le rêve aux entités",
|
||||
hint: "A quel moment les personnages doivent accorder leur rêve aux entités de cauchemar",
|
||||
scope: "world",
|
||||
config: true,
|
||||
type: String,
|
||||
choices: { // If choices are defined, the resulting setting will be a select menu
|
||||
"avant-attaque": "Avant l'attaque",
|
||||
"avant-defense": "Avant la défense",
|
||||
"avant-encaissement": "Avant l'encaissement",
|
||||
},
|
||||
default: "avant-encaissement"
|
||||
});
|
||||
|
||||
/* -------------------------------------------- */
|
||||
game.settings.register(SYSTEM_RDD, "calendrier", {
|
||||
name: "calendrier",
|
||||
scope: "world",
|
||||
config: false,
|
||||
default: RdDCalendrier.createCalendrierInitial(),
|
||||
type: Object
|
||||
});
|
||||
|
||||
/* -------------------------------------------- */
|
||||
game.settings.register(SYSTEM_RDD, "migration-png-webp-1.5.34", {
|
||||
name: "calendrier",
|
||||
scope: "world",
|
||||
config: false,
|
||||
default: false,
|
||||
type: Boolean
|
||||
});
|
||||
|
||||
/* -------------------------------------------- */
|
||||
game.settings.register(SYSTEM_RDD, "liste-nombre-astral", {
|
||||
name: "liste-nombre-astral",
|
||||
scope: "world",
|
||||
config: false,
|
||||
default: [],
|
||||
type: Object
|
||||
});
|
||||
|
||||
/* -------------------------------------------- */
|
||||
game.settings.register(SYSTEM_RDD, "calendrier-pos", {
|
||||
name: "calendrierPos",
|
||||
scope: "client",
|
||||
config: false,
|
||||
default: RdDCalendrier.createCalendrierPos(),
|
||||
type: Object
|
||||
});
|
||||
|
||||
|
||||
/* -------------------------------------------- */
|
||||
game.settings.register(SYSTEM_RDD, "supprimer-dialogues-combat-chat", {
|
||||
name: "Supprimer les dialogues de combat",
|
||||
hint: "Si désactivée, tous les dialogues de combat sont conservés dans la conversation",
|
||||
scope: "world",
|
||||
config: true,
|
||||
default: true,
|
||||
type: Boolean
|
||||
});
|
||||
/* -------------------------------------------- */
|
||||
game.settings.register(SYSTEM_RDD, "activer-sons-audio", {
|
||||
name: "Activer les bruitages intégrés",
|
||||
hint: "Si activé, certaines actions en jeu déclenchent un son d'ambiance",
|
||||
scope: "world",
|
||||
config: true,
|
||||
default: true,
|
||||
type: Boolean
|
||||
});
|
||||
/* -------------------------------------------- */
|
||||
game.settings.register(SYSTEM_RDD, "appliquer-famine-soif", {
|
||||
name: "Notifier de la famine et la soif pour",
|
||||
hint: "Indique si les cas de famine et de soif seront indiqués durant Château Dormant",
|
||||
scope: "world",
|
||||
config: true,
|
||||
type: String,
|
||||
choices: {
|
||||
"aucun": "ni la famine, ni la soif",
|
||||
"famine": "seulement la famine",
|
||||
"famine-soif": "la famine et la soif",
|
||||
},
|
||||
default: "aucun"
|
||||
});
|
||||
|
||||
/* -------------------------------------------- */
|
||||
// Set an initiative formula for the system
|
||||
CONFIG.Combat.initiative = {
|
||||
formula: "1+(1d6/10)",
|
||||
decimals: 2
|
||||
};
|
||||
|
||||
/* -------------------------------------------- */
|
||||
game.socket.on(SYSTEM_SOCKET_ID, async (sockmsg) => {
|
||||
console.log(">>>>> MSG RECV", sockmsg);
|
||||
try {
|
||||
RdDUtility.onSocketMessage(sockmsg);
|
||||
RdDCombat.onSocketMessage(sockmsg);
|
||||
ChatUtility.onSocketMessage(sockmsg);
|
||||
RdDActor.onSocketMessage(sockmsg);
|
||||
} catch (e) {
|
||||
console.error('game.socket.on(SYSTEM_SOCKET_ID) Exception: ', sockmsg, ' => ', e)
|
||||
constructor() {
|
||||
this.RdDUtility = RdDUtility;
|
||||
this.RdDHotbar = RdDHotbar;
|
||||
this.itemClasses = {
|
||||
service: RdDItemService
|
||||
}
|
||||
this.actorClasses = {
|
||||
creature: RdDActor,
|
||||
entite: RdDActor,
|
||||
personnage: RdDActor,
|
||||
vehicule: RdDActor,
|
||||
}
|
||||
});
|
||||
|
||||
/* -------------------------------------------- */
|
||||
// Define custom Entity classes
|
||||
CONFIG.Actor.documentClass = RdDActor;
|
||||
CONFIG.Item.documentClass = RdDItem;
|
||||
CONFIG.RDD = {
|
||||
resolutionTable: RdDResolutionTable.resolutionTable,
|
||||
carac_array: RdDUtility.getCaracArray(),
|
||||
ajustementsConditions: RdDUtility.getAjustementsConditions(),
|
||||
difficultesLibres: RdDUtility.getDifficultesLibres()
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
// Register sheet application classes
|
||||
Actors.unregisterSheet("core", ActorSheet);
|
||||
Actors.registerSheet(SYSTEM_RDD, RdDActorSheet, { types: ["personnage"], makeDefault: true });
|
||||
Actors.registerSheet(SYSTEM_RDD, RdDActorCreatureSheet, { types: ["creature"], makeDefault: true });
|
||||
Actors.registerSheet(SYSTEM_RDD, RdDActorVehiculeSheet, { types: ["vehicule"], makeDefault: true });
|
||||
Actors.registerSheet(SYSTEM_RDD, RdDActorEntiteSheet, { types: ["entite"], makeDefault: true });
|
||||
Items.unregisterSheet("core", ItemSheet);
|
||||
/* Foundry VTT Initialization */
|
||||
/* -------------------------------------------- */
|
||||
async onInit() {
|
||||
game.system.rdd = this;
|
||||
|
||||
RdDItemSheet.register(RdDSigneDraconiqueItemSheet);
|
||||
RdDItemSheet.register(RdDRencontreItemSheet);
|
||||
RdDItemSheet.register(RdDConteneurItemSheet);
|
||||
RdDItemSheet.register(RdDHerbeItemSheet);
|
||||
RdDItemSheet.register(RdDFauneItemSheet);
|
||||
RdDItemSheet.register(RdDIngredientItemSheet);
|
||||
console.log(`Initializing Reve de Dragon System`);
|
||||
|
||||
Items.registerSheet(SYSTEM_RDD, RdDItemSheet, {
|
||||
types: [
|
||||
"competence", "competencecreature",
|
||||
"recettealchimique", "musique", "chant", "danse", "jeu", "recettecuisine", "oeuvre",
|
||||
"objet", "arme", "armure", "livre", "potion", "munition",
|
||||
"monnaie", "nourritureboisson", "gemme",
|
||||
"meditation", "queue", "ombre", "souffle", "tete", "casetmr", "sort", "sortreserve",
|
||||
"nombreastral", "tache", "maladie", "poison", "possession",
|
||||
"tarot", "extraitpoetique"
|
||||
], makeDefault: true
|
||||
});
|
||||
CONFIG.Combat.documentClass = RdDCombatManager;
|
||||
// preload handlebars templates
|
||||
RdDUtility.preloadHandlebarsTemplates();
|
||||
|
||||
// préparation des différents modules
|
||||
SystemCompendiums.init();
|
||||
DialogChronologie.init();
|
||||
ReglesOptionelles.init();
|
||||
RdDUtility.init();
|
||||
RdDDice.init();
|
||||
RdDCommands.init();
|
||||
RdDCombat.init();
|
||||
RdDCombatManager.init();
|
||||
RdDTokenHud.init();
|
||||
RdDActor.init();
|
||||
RddCompendiumOrganiser.init();
|
||||
EffetsDraconiques.init()
|
||||
TMRUtility.init();
|
||||
RdDHotbar.initDropbar();
|
||||
RdDPossession.init();
|
||||
TMRRencontres.init();
|
||||
Environnement.init();
|
||||
});
|
||||
/* -------------------------------------------- */
|
||||
game.settings.register(SYSTEM_RDD, "accorder-entite-cauchemar", {
|
||||
name: "Accorder le rêve aux entités",
|
||||
hint: "A quel moment les personnages doivent accorder leur rêve aux entités de cauchemar",
|
||||
scope: "world",
|
||||
config: true,
|
||||
type: String,
|
||||
choices: { // If choices are defined, the resulting setting will be a select menu
|
||||
"avant-attaque": "Avant l'attaque",
|
||||
"avant-defense": "Avant la défense",
|
||||
"avant-encaissement": "Avant l'encaissement",
|
||||
},
|
||||
default: "avant-encaissement"
|
||||
});
|
||||
|
||||
/* -------------------------------------------- */
|
||||
function messageDeBienvenue() {
|
||||
if (game.user.isGM) {
|
||||
ChatUtility.removeChatMessageContaining('<div id="message-bienvenue-rdd">');
|
||||
ChatMessage.create({
|
||||
user: game.user.id,
|
||||
content: `<div id="message-bienvenue-rdd"><span class="rdd-roll-part">Bienvenue dans le Rêve des Dragons !</span>
|
||||
/* -------------------------------------------- */
|
||||
game.settings.register(SYSTEM_RDD, "calendrier", {
|
||||
name: "calendrier",
|
||||
scope: "world",
|
||||
config: false,
|
||||
default: RdDCalendrier.createCalendrierInitial(),
|
||||
type: Object
|
||||
});
|
||||
|
||||
/* -------------------------------------------- */
|
||||
game.settings.register(SYSTEM_RDD, "liste-nombre-astral", {
|
||||
name: "liste-nombre-astral",
|
||||
scope: "world",
|
||||
config: false,
|
||||
default: [],
|
||||
type: Object
|
||||
});
|
||||
|
||||
/* -------------------------------------------- */
|
||||
game.settings.register(SYSTEM_RDD, "calendrier-pos", {
|
||||
name: "calendrierPos",
|
||||
scope: "client",
|
||||
config: false,
|
||||
default: RdDCalendrier.createCalendrierPos(),
|
||||
type: Object
|
||||
});
|
||||
|
||||
|
||||
/* -------------------------------------------- */
|
||||
game.settings.register(SYSTEM_RDD, "supprimer-dialogues-combat-chat", {
|
||||
name: "Supprimer les dialogues de combat",
|
||||
hint: "Si désactivée, tous les dialogues de combat sont conservés dans la conversation",
|
||||
scope: "world",
|
||||
config: true,
|
||||
default: true,
|
||||
type: Boolean
|
||||
});
|
||||
/* -------------------------------------------- */
|
||||
game.settings.register(SYSTEM_RDD, "activer-sons-audio", {
|
||||
name: "Activer les bruitages intégrés",
|
||||
hint: "Si activé, certaines actions en jeu déclenchent un son d'ambiance",
|
||||
scope: "world",
|
||||
config: true,
|
||||
default: true,
|
||||
type: Boolean
|
||||
});
|
||||
/* -------------------------------------------- */
|
||||
game.settings.register(SYSTEM_RDD, "appliquer-famine-soif", {
|
||||
name: "Notifier de la famine et la soif pour",
|
||||
hint: "Indique si les cas de famine et de soif seront indiqués durant Château Dormant",
|
||||
scope: "world",
|
||||
config: true,
|
||||
type: String,
|
||||
choices: {
|
||||
"aucun": "ni la famine, ni la soif",
|
||||
"famine": "seulement la famine",
|
||||
"famine-soif": "la famine et la soif",
|
||||
},
|
||||
default: "aucun"
|
||||
});
|
||||
|
||||
/* -------------------------------------------- */
|
||||
// Set an initiative formula for the system
|
||||
CONFIG.Combat.initiative = {
|
||||
formula: "1+(1d6/10)",
|
||||
decimals: 2
|
||||
};
|
||||
|
||||
/* -------------------------------------------- */
|
||||
game.socket.on(SYSTEM_SOCKET_ID, async (sockmsg) => {
|
||||
console.log(">>>>> MSG RECV", sockmsg);
|
||||
try {
|
||||
RdDUtility.onSocketMessage(sockmsg);
|
||||
RdDCombat.onSocketMessage(sockmsg);
|
||||
ChatUtility.onSocketMessage(sockmsg);
|
||||
RdDBaseActor.onSocketMessage(sockmsg);
|
||||
} catch (e) {
|
||||
console.error('game.socket.on(SYSTEM_SOCKET_ID) Exception: ', sockmsg, ' => ', e)
|
||||
}
|
||||
});
|
||||
|
||||
/* -------------------------------------------- */
|
||||
// Define custom Entity classes
|
||||
CONFIG.Actor.documentClass = RdDActor;
|
||||
CONFIG.Item.documentClass = RdDItem;
|
||||
CONFIG.RDD = {
|
||||
resolutionTable: RdDResolutionTable.resolutionTable,
|
||||
carac_array: RdDUtility.getCaracArray(),
|
||||
ajustementsConditions: RdDUtility.getAjustementsConditions(),
|
||||
difficultesLibres: RdDUtility.getDifficultesLibres()
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
// Register sheet application classes
|
||||
Actors.unregisterSheet("core", ActorSheet);
|
||||
Actors.registerSheet(SYSTEM_RDD, RdDActorSheet, { types: ["personnage"], makeDefault: true });
|
||||
Actors.registerSheet(SYSTEM_RDD, RdDActorCreatureSheet, { types: ["creature"], makeDefault: true });
|
||||
Actors.registerSheet(SYSTEM_RDD, RdDActorVehiculeSheet, { types: ["vehicule"], makeDefault: true });
|
||||
Actors.registerSheet(SYSTEM_RDD, RdDActorEntiteSheet, { types: ["entite"], makeDefault: true });
|
||||
Items.unregisterSheet("core", ItemSheet);
|
||||
|
||||
RdDItemSheet.register(RdDSigneDraconiqueItemSheet);
|
||||
RdDItemSheet.register(RdDRencontreItemSheet);
|
||||
RdDItemSheet.register(RdDConteneurItemSheet);
|
||||
RdDItemSheet.register(RdDHerbeItemSheet);
|
||||
RdDItemSheet.register(RdDFauneItemSheet);
|
||||
RdDItemSheet.register(RdDIngredientItemSheet);
|
||||
RdDItemSheet.register(RdDServiceItemSheet);
|
||||
|
||||
Items.registerSheet(SYSTEM_RDD, RdDItemSheet, {
|
||||
types: [
|
||||
"competence", "competencecreature",
|
||||
"recettealchimique", "musique", "chant", "danse", "jeu", "recettecuisine", "oeuvre",
|
||||
"objet", "arme", "armure", "livre", "potion", "munition",
|
||||
"monnaie", "nourritureboisson", "gemme",
|
||||
"meditation", "queue", "ombre", "souffle", "tete", "casetmr", "sort", "sortreserve",
|
||||
"nombreastral", "tache", "maladie", "poison", "possession",
|
||||
"tarot", "extraitpoetique"
|
||||
], makeDefault: true
|
||||
});
|
||||
CONFIG.Combat.documentClass = RdDCombatManager;
|
||||
|
||||
// préparation des différents modules
|
||||
SystemCompendiums.init();
|
||||
DialogChronologie.init();
|
||||
ReglesOptionelles.init();
|
||||
RdDUtility.init();
|
||||
RdDDice.init();
|
||||
RdDCommands.init();
|
||||
RdDCombat.init();
|
||||
RdDCombatManager.init();
|
||||
RdDTokenHud.init();
|
||||
RdDBaseActor.init();
|
||||
RddCompendiumOrganiser.init();
|
||||
EffetsDraconiques.init()
|
||||
TMRUtility.init();
|
||||
RdDHotbar.initDropbar();
|
||||
RdDPossession.init();
|
||||
TMRRencontres.init();
|
||||
Environnement.init();
|
||||
|
||||
Hooks.once('ready', () => this.onReady());
|
||||
}
|
||||
|
||||
async onReady() {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
/* Foundry VTT Initialization */
|
||||
/* -------------------------------------------- */
|
||||
// CSS patch for v9
|
||||
if (game.version) {
|
||||
let sidebar = document.getElementById("sidebar");
|
||||
sidebar.style.width = "min-content";
|
||||
}
|
||||
|
||||
if (Misc.isUniqueConnectedGM()) {
|
||||
new Migrations().migrate();
|
||||
}
|
||||
|
||||
StatusEffects.onReady();
|
||||
RdDHerbes.initializeHerbes();
|
||||
RdDDice.onReady();
|
||||
/* -------------------------------------------- */
|
||||
/* Affiche/Init le calendrier */
|
||||
let calendrier = new RdDCalendrier();
|
||||
let templatePath = "systems/foundryvtt-reve-de-dragon/templates/calendar-template.html";
|
||||
let templateData = {};
|
||||
renderTemplate(templatePath, templateData).then(html => {
|
||||
calendrier.render(true);
|
||||
});
|
||||
game.system.rdd.calendrier = calendrier; // Reference;
|
||||
|
||||
// Avertissement si joueur sans personnage
|
||||
if (!game.user.isGM && game.user.character == undefined) {
|
||||
ui.notifications.info("Attention ! Vous n'êtes connecté à aucun personnage !");
|
||||
ChatMessage.create({
|
||||
content: "<b>ATTENTION</b> Le joueur " + game.user.name + " n'est connecté à aucun personnage !",
|
||||
user: game.user.id
|
||||
});
|
||||
}
|
||||
if (Misc.isUniqueConnectedGM()) {
|
||||
this.messageDeBienvenue();
|
||||
this.registerUsageCount(SYSTEM_RDD);
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
messageDeBienvenue() {
|
||||
if (game.user.isGM) {
|
||||
ChatUtility.removeChatMessageContaining('<div id="message-bienvenue-rdd">');
|
||||
ChatMessage.create({
|
||||
user: game.user.id,
|
||||
content: `<div id="message-bienvenue-rdd"><span class="rdd-roll-part">Bienvenue dans le Rêve des Dragons !</span>
|
||||
<br>Vous trouverez quelques informations pour démarrer dans ce document : @Compendium[foundryvtt-reve-de-dragon.rappel-des-regles.7uGrUHGdPu0EmIu2]{Documentation MJ/Joueurs}
|
||||
<br>La commande <code>/aide</code> dans le chat permet de voir les commandes spécifiques à Rêve de Dragon.</div>
|
||||
` });
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
// Register world usage statistics
|
||||
function registerUsageCount(registerKey) {
|
||||
if (game.user.isGM) {
|
||||
game.settings.register("world", "world-key", {
|
||||
name: "Unique world key",
|
||||
scope: "world",
|
||||
config: false,
|
||||
default: "NONE",
|
||||
type: String
|
||||
});
|
||||
|
||||
let worldKey = game.settings.get("world", "world-key")
|
||||
if (worldKey == undefined || worldKey == "") {
|
||||
worldKey = randomID(32)
|
||||
game.settings.set("world", "world-key", worldKey)
|
||||
}
|
||||
let regURL = `https://www.uberwald.me/fvtt_appcount/count.php?name="${registerKey}"&worldKey="${worldKey}"&version="${game.release.generation}.${game.release.build}"&system="${game.system.id}"&systemversion="${game.system.version}"`
|
||||
$.ajax(regURL)
|
||||
/* -------------------------------------------- */
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
/* Foundry VTT Initialization */
|
||||
/* -------------------------------------------- */
|
||||
Hooks.once("ready", async function () {
|
||||
await migrationPngWebp_1_5_34()
|
||||
if (Misc.isUniqueConnectedGM()) {
|
||||
new Migrations().migrate();
|
||||
}
|
||||
|
||||
StatusEffects.onReady();
|
||||
RdDHerbes.initializeHerbes();
|
||||
RdDDice.onReady();
|
||||
/* -------------------------------------------- */
|
||||
/* Affiche/Init le calendrier */
|
||||
let calendrier = new RdDCalendrier();
|
||||
let templatePath = "systems/foundryvtt-reve-de-dragon/templates/calendar-template.html";
|
||||
let templateData = {};
|
||||
renderTemplate(templatePath, templateData).then(html => {
|
||||
calendrier.render(true);
|
||||
});
|
||||
game.system.rdd.calendrier = calendrier; // Reference;
|
||||
// Register world usage statistics
|
||||
async registerUsageCount(registerKey) {
|
||||
if (game.user.isGM) {
|
||||
game.settings.register("world", "world-key", {
|
||||
name: "Unique world key",
|
||||
scope: "world",
|
||||
config: false,
|
||||
default: "NONE",
|
||||
type: String
|
||||
});
|
||||
|
||||
// Avertissement si joueur sans personnage
|
||||
if (!game.user.isGM && game.user.character == undefined) {
|
||||
ui.notifications.info("Attention ! Vous n'êtes connecté à aucun personnage !");
|
||||
ChatMessage.create({
|
||||
content: "<b>ATTENTION</b> Le joueur " + game.user.name + " n'est connecté à aucun personnage !",
|
||||
user: game.user.id
|
||||
});
|
||||
}
|
||||
if (Misc.isUniqueConnectedGM()) {
|
||||
messageDeBienvenue();
|
||||
registerUsageCount(SYSTEM_RDD);
|
||||
}
|
||||
});
|
||||
|
||||
async function migrationPngWebp_1_5_34() {
|
||||
if (!game.settings.get(SYSTEM_RDD, "migration-png-webp-1.5.34")) {
|
||||
const regexOldPngJpg = /(systems\/foundryvtt-reve-de-dragon\/icons\/.*)\.(png|jpg)/;
|
||||
const replaceWithWebp = '$1.webp';
|
||||
function convertImgToWebp(img) {
|
||||
return img.replace(regexOldPngJpg, replaceWithWebp);
|
||||
}
|
||||
function prepareDocumentsImgUpdate(documents) {
|
||||
return documents.filter(it => it.img && it.img.match(regexOldPngJpg))
|
||||
.map(it => {
|
||||
return { _id: it.id, img: convertImgToWebp(it.img) }
|
||||
});
|
||||
}
|
||||
const itemsUpdates = prepareDocumentsImgUpdate(game.items);
|
||||
const actorsUpdates = prepareDocumentsImgUpdate(game.actors);
|
||||
//Migrate system png to webp
|
||||
await Item.updateDocuments(itemsUpdates);
|
||||
await Actor.updateDocuments(actorsUpdates);
|
||||
game.actors.forEach(actor => {
|
||||
if (actor.token?.img && actor.token.img.match(regexOldPngJpg)) {
|
||||
actor.update({ "token.img": convertImgToWebp(actor.token.img) });
|
||||
let worldKey = game.settings.get("world", "world-key")
|
||||
if (worldKey == undefined || worldKey == "") {
|
||||
worldKey = randomID(32)
|
||||
game.settings.set("world", "world-key", worldKey)
|
||||
}
|
||||
const actorItemsToUpdate = prepareDocumentsImgUpdate(actor.items);
|
||||
actor.updateEmbeddedDocuments('Item', actorItemsToUpdate);
|
||||
});
|
||||
game.settings.set(SYSTEM_RDD, "migration-png-webp-1.5.34", true)
|
||||
}
|
||||
|
||||
// CSS patch for v9
|
||||
if (game.version) {
|
||||
let sidebar = document.getElementById("sidebar");
|
||||
sidebar.style.width = "min-content";
|
||||
let regURL = `https://www.uberwald.me/fvtt_appcount/count.php?name="${registerKey}"&worldKey="${worldKey}"&version="${game.release.generation}.${game.release.build}"&system="${game.system.id}"&systemversion="${game.system.version}"`
|
||||
$.ajax(regURL)
|
||||
/* -------------------------------------------- */
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
/* Dice-so-nice ready */
|
||||
/* -------------------------------------------- */
|
||||
Hooks.once('diceSoNiceReady', (dice3d) => RdDDice.diceSoNiceReady(dice3d));
|
||||
SystemReveDeDragon.start();
|
||||
|
||||
|
@ -95,8 +95,9 @@ export class RdDRollTables {
|
||||
const row = await table.getRandom(itemFrequence, filter);
|
||||
if (row) {
|
||||
await CompendiumTableHelpers.tableRowToChatMessage(row, type);
|
||||
return row.document;
|
||||
}
|
||||
return row;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
|
@ -405,6 +405,8 @@ export class RdDTMRDialog extends Dialog {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async _tentativeMaitrise(rencData) {
|
||||
this.rencontreState = 'normal';
|
||||
|
||||
rencData.reve = this.actor.getReveActuel();
|
||||
rencData.etat = this.actor.getEtatGeneral();
|
||||
|
||||
@ -450,7 +452,6 @@ export class RdDTMRDialog extends Dialog {
|
||||
this._tentativeMaitrise(rencData);
|
||||
this._deleteTmrMessages(rencData.actor, rencData.nbRounds);
|
||||
}, 2000);
|
||||
this.rencontreState == 'normal';
|
||||
}
|
||||
|
||||
formatMessageRencontre(rencData, template) {
|
||||
@ -460,14 +461,14 @@ export class RdDTMRDialog extends Dialog {
|
||||
messageDuree = ` Au total, vous avez passé ${rencData.nbRounds} rounds à vous battre!`;
|
||||
}
|
||||
else {
|
||||
messageDuree = ` Vous avez passé ${rencData.nbRounds} rounds à lutter!`;
|
||||
messageDuree = ` Vous avez passé ${rencData.nbRounds} rounds à lutter!`;
|
||||
}
|
||||
}
|
||||
try {
|
||||
const compiled = Handlebars.compile(template);
|
||||
return compiled(rencData) + messageDuree ;
|
||||
return compiled(rencData) + messageDuree;
|
||||
} catch (error) {
|
||||
return template + messageDuree ;
|
||||
return template + messageDuree;
|
||||
}
|
||||
}
|
||||
|
||||
@ -520,7 +521,7 @@ export class RdDTMRDialog extends Dialog {
|
||||
}
|
||||
this.currentRencontre = await this._jetDeRencontre(tmr);
|
||||
if (this.currentRencontre) {
|
||||
if (this.rencontresExistantes.find(it => it.id == this.currentRencontre.id)){
|
||||
if (this.rencontresExistantes.find(it => it.id == this.currentRencontre.id)) {
|
||||
// rencontre en attente suite à dérobade
|
||||
await this.maitriserRencontre();
|
||||
}
|
||||
@ -550,7 +551,7 @@ export class RdDTMRDialog extends Dialog {
|
||||
this.currentRencontre = present.clone({
|
||||
'system.force': await RdDDice.rollTotal(present.system.formule),
|
||||
'system.coord': tmr.coord
|
||||
}, {save: false});
|
||||
}, { save: false });
|
||||
|
||||
await EffetsDraconiques.presentCites.ouvrirLePresent(this.actor, presentCite);
|
||||
this.removeToken(tmr, presentCite);
|
||||
|
@ -126,6 +126,7 @@ export class RdDUtility {
|
||||
'systems/foundryvtt-reve-de-dragon/templates/actor/header-compteurs-creature.html',
|
||||
'systems/foundryvtt-reve-de-dragon/templates/actor/header-compteurs-entitee.html',
|
||||
'systems/foundryvtt-reve-de-dragon/templates/actor/header-effects.html',
|
||||
'systems/foundryvtt-reve-de-dragon/templates/actor/header-hautreve.html',
|
||||
'systems/foundryvtt-reve-de-dragon/templates/actor/vue-detaillee.html',
|
||||
'systems/foundryvtt-reve-de-dragon/templates/actor/carac-main.html',
|
||||
'systems/foundryvtt-reve-de-dragon/templates/actor/carac-derivee.html',
|
||||
@ -202,6 +203,7 @@ export class RdDUtility {
|
||||
'systems/foundryvtt-reve-de-dragon/templates/item-signedraconique-sheet.html',
|
||||
'systems/foundryvtt-reve-de-dragon/templates/item-possession-sheet.html',
|
||||
'systems/foundryvtt-reve-de-dragon/templates/item-extraitpoetique-sheet.html',
|
||||
'systems/foundryvtt-reve-de-dragon/templates/item-service-sheet.html',
|
||||
// partial enums
|
||||
'systems/foundryvtt-reve-de-dragon/templates/enum-caracteristiques.html',
|
||||
'systems/foundryvtt-reve-de-dragon/templates/enum-base-competence.html',
|
||||
@ -313,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 = `<span class="competence-label">Selectionnez le type d'équipement</span><select class="item-type">`;
|
||||
for (let typeName of typeObjets) {
|
||||
options += `<option value="${typeName}">${typeName}</option>`
|
||||
}
|
||||
options += '</select>';
|
||||
let d = new Dialog({
|
||||
title: "Créer un équipement",
|
||||
content: options,
|
||||
buttons: {
|
||||
one: {
|
||||
icon: '<i class="fas fa-check"></i>',
|
||||
label: "Créer l'objet",
|
||||
callback: () => this.creerObjet(actorSheet)
|
||||
}
|
||||
}
|
||||
});
|
||||
d.render(true);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static async selectTypeOeuvre(actorSheet) {
|
||||
let typeObjets = RdDItem.getTypesOeuvres();
|
||||
let options = `<span class="competence-label">Selectionnez le type d'oeuvre</span><select class="item-type">`;
|
||||
for (let typeName of typeObjets) {
|
||||
options += `<option value="${typeName}">${typeName}</option>`
|
||||
}
|
||||
options += '</select>';
|
||||
let d = new Dialog({
|
||||
title: "Créer un équipement",
|
||||
content: options,
|
||||
buttons: {
|
||||
one: {
|
||||
icon: '<i class="fas fa-check"></i>',
|
||||
label: "Créer l'objet",
|
||||
callback: () => this.creerObjet(actorSheet)
|
||||
}
|
||||
}
|
||||
});
|
||||
d.render(true);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static buildListOptions(min, max) {
|
||||
let options = ""
|
||||
@ -430,6 +382,7 @@ export class RdDUtility {
|
||||
formData.oeuvres = this.arrayOrEmpty(itemTypes['oeuvre']);
|
||||
formData.jeux = this.arrayOrEmpty(itemTypes['jeu']);
|
||||
|
||||
formData.services = this.arrayOrEmpty(itemTypes['service']);
|
||||
formData.recettescuisine = this.arrayOrEmpty(itemTypes['recettecuisine']);
|
||||
formData.recettesAlchimiques = this.arrayOrEmpty(itemTypes['recettealchimique']);
|
||||
formData.maladies = this.arrayOrEmpty(itemTypes['maladie']);
|
||||
@ -813,7 +766,7 @@ export class RdDUtility {
|
||||
|
||||
// gestion bouton tchat Acheter
|
||||
html.on("click", '.button-acheter', event => {
|
||||
const venteData = DialogItemAchat.venteData(event.currentTarget);
|
||||
const venteData = DialogItemAchat.preparerAchat(event.currentTarget);
|
||||
if (venteData) {
|
||||
DialogItemAchat.onAcheter(venteData);
|
||||
}
|
||||
@ -829,6 +782,18 @@ export class RdDUtility {
|
||||
ChatUtility.removeChatMessageId(RdDUtility.findChatMessageId(event.currentTarget));
|
||||
}
|
||||
});
|
||||
html.on("click", '.rdd-world-content-link', async event => {
|
||||
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);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
static findChatMessageId(current) {
|
||||
@ -946,7 +911,7 @@ export class RdDUtility {
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static async confirmerSuppressionItem(sheet, item, htmlToDelete) {
|
||||
static async confirmActorItemDelete(sheet, item, htmlToDelete) {
|
||||
const itemId = item.id;
|
||||
const confirmationSuppression = {
|
||||
settingConfirmer: "confirmation-supprimer-" + item.getItemGroup(),
|
||||
|
@ -87,6 +87,11 @@ export class SystemCompendiums extends FormApplication {
|
||||
return items;
|
||||
}
|
||||
|
||||
static async loadDocument(document) {
|
||||
const pack = game.packs.get(document.pack);
|
||||
return await pack.getDocument(document.id ?? document._id);
|
||||
}
|
||||
|
||||
static async getItems(compendium, itemType = undefined) {
|
||||
const items = await SystemCompendiums.getPackContent(compendium, 'Item');
|
||||
return (itemType ? items.filter(it => it.type == itemType) : items);
|
||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
11
packs/macros.db
Normal file
11
packs/macros.db
Normal file
@ -0,0 +1,11 @@
|
||||
{"name":"Jet de moral","type":"script","author":"Hp9ImM4o9YRTSdfu","img":"icons/magic/control/mouth-smile-deception-purple.webp","scope":"global","command":"const selected = game.system.rdd.RdDUtility.getSelectedActor();\nif (!selected) {\n ui.notifications.info('Pas de personnage sélectionné');\n return;\n}\n\nconst dialogMoral = new Dialog({\n title: `Jet de moral`,\n content: `Jet de moral en situation`,\n buttons: {\n malheureuse: { label: `malheureuse`, icon: \"<i class='fa-regular fa-face-frown'></i>\", callback: () => selected.jetDeMoral('malheureuse') },\n neutre: { label: `neutre`, icon: \"<i class='fa-regular fa-face-meh'></i>\", callback: () => selected.jetDeMoral('neutre') },\n heureuse: { label: `heureuse`, icon: \"<i class='fa-regular fa-face-smile'></i>\", callback: () => selected.jetDeMoral('heureuse') }\n },\n});\n\ndialogMoral.render(true)","ownership":{"default":0,"Hp9ImM4o9YRTSdfu":3},"flags":{"core":{"sourceId":"Macro.aJ0QGnXAXT0WiXbk"}},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.15","coreVersion":"10.291","createdTime":1671235038906,"modifiedTime":1671236054480,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"},"folder":null,"sort":0,"_id":"2VvH2rmxV33jGjMU"}
|
||||
{"name":"Repos","type":"script","scope":"global","author":"Hp9ImM4o9YRTSdfu","img":"icons/svg/sleep.svg","command":"const selected = game.system.rdd.RdDUtility.getSelectedActor();\nif (selected) {\n selected.repos();\n}\nelse {\n ui.notifications.info('Pas de personnage sélectionné');\n}","ownership":{"default":0,"Hp9ImM4o9YRTSdfu":3},"flags":{"core":{"sourceId":"Macro.XHNbjnGKXaCiCadq"}},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.15","coreVersion":"10.291","createdTime":1671220038331,"modifiedTime":1671234271278,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"},"folder":null,"sort":0,"_id":"6LRZ8DOVfqotIEsi"}
|
||||
{"name":"Météo marine","type":"chat","author":"Hp9ImM4o9YRTSdfu","img":"icons/magic/air/wind-weather-sailing-ship.webp","scope":"global","command":"/meteo","flags":{"core":{"sourceId":"Macro.EPhCYk7PFMPlIFhS"}},"ownership":{"default":0,"Hp9ImM4o9YRTSdfu":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.15","coreVersion":"10.291","createdTime":1671237060687,"modifiedTime":1671237060687,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"},"folder":null,"sort":0,"_id":"9mYZfKoi4ZYHydxa"}
|
||||
{"name":"Chuchoter aux joueurs","type":"script","author":"Hp9ImM4o9YRTSdfu","img":"icons/svg/deaf.svg","scope":"global","command":"/** \n * Provides a dialog to whisper specific players. If you have tokens selected, it will automatically default to try and whisper those players.\n * @Author: Nelson#3570\n */\n\nlet applyChanges = false;\n\nlet users = game.users.filter(user => user.active);\nlet checkOptions = \"\"\nlet playerTokenIds = users.map(u => u.character?.id).filter(id => id !== undefined);\nlet selectedPlayerIds = canvas.tokens.controlled.map(token => {\n if (playerTokenIds.includes(token.actor.id)) return token.actor.id;\n});\n\n// Build checkbox list for all active players\nusers.forEach(user => {\n let checked = !!user.character && selectedPlayerIds.includes(user.character.id) && 'checked';\n checkOptions+=`\n <br>\n <input type=\"checkbox\" name=\"${user.id}\" id=\"${user.id}\" value=\"${user.name}\" ${checked}>\\n\n <label for=\"${user.id}\">${user.name}</label>\n `\n});\n\nnew Dialog({\n title:\"Whisper\",\n content:`Whisper To: ${checkOptions} <br>\n <label for=\"message\">Message:</label>\n <textarea id=\"message\" name=\"message\" rows=\"4\" cols=\"50\"></textarea><br>`,\n buttons:{\n whisper:{ \n label:\"Whisper\",\n callback: (html) => createMessage(html)\n }\n }\n}).render(true);\n\nfunction createMessage(html) {\n var targets = [];\n // build list of selected players ids for whispers target\n for ( let user of users ) {\n if (html.find('[name=\"'+user.id+'\"]')[0].checked){\n applyChanges=true;\n targets.push(user.id);\n }\n var messageText = html.find('[name=\"message\"]')[0].value\n }\nif(!applyChanges)return;\n ChatMessage.create({\n content: messageText,\n whisper: targets\n });\n}","flags":{"core":{"sourceId":"Compendium.foundry_community_macros.community-macros-misc.QTDeg4HOYCAmr4dK"}},"ownership":{"default":2,"Hp9ImM4o9YRTSdfu":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.15","coreVersion":"10.291","createdTime":1671237211578,"modifiedTime":1671237211578,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"},"folder":null,"sort":0,"_id":"ALAVJEEP3iJosOoi"}
|
||||
{"name":"Terres médianes du rêve","type":"script","scope":"global","author":"Hp9ImM4o9YRTSdfu","img":"systems/foundryvtt-reve-de-dragon/styles/img/ui/icon-tmr-normal.svg","command":"const selected = game.system.rdd.RdDUtility.getSelectedActor();\nif (!selected) {\n ui.notifications.info('Pas de personnage sélectionné');\n return;\n}\nif (!selected.isHautRevant()) {\n ui.notifications.info(`Le personnage ${selected.name} n'a pas le don de haut-rêve`);\n return;\n}\n\nconst dialogMoral = new Dialog({\n title: `Monter dans les TMR`,\n content: `Monter dans les TMR`,\n buttons: {\n normale: { label: `normale`, icon: `<img class=\"button-img\" src=\"systems/foundryvtt-reve-de-dragon/styles/img/ui/icon-tmr-normal.svg\" alt=\"Montée dans les Terres Médianes !\"/>`, callback: () => selected.displayTMR(\"normal\") },\n rapide: { label: `rapide`, icon: `<img class=\"button-img\" src=\"systems/foundryvtt-reve-de-dragon/styles/img/ui/icon-tmr-rapide.svg\" alt=\"Montée accélérée dans les Terres Médianes !\"/>`, callback: () => selected.displayTMR(\"rapide\") },\n },\n});\n\ndialogMoral.render(true)","ownership":{"default":0,"Hp9ImM4o9YRTSdfu":3},"flags":{"core":{"sourceId":"Macro.zCAQxg2duk0j3s5r"}},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.15","coreVersion":"10.291","createdTime":1669250715114,"modifiedTime":1671236057731,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"},"folder":null,"sort":0,"_id":"ERsBfwsodzH6UX4x"}
|
||||
{"name":"Signe draconique","type":"chat","author":"Hp9ImM4o9YRTSdfu","img":"systems/foundryvtt-reve-de-dragon/icons/tmr/signe_draconique.webp","scope":"global","command":"/signe +","flags":{"core":{"sourceId":"Macro.RmOLbONUNnINcqCO"}},"ownership":{"default":0,"klwAm8zAKxw8YBLf":3,"Hp9ImM4o9YRTSdfu":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.15","coreVersion":"10.291","createdTime":1671237375774,"modifiedTime":1671237375774,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"},"folder":null,"sort":0,"_id":"MJByzsEdneZ64P56"}
|
||||
{"name":"Appel à la chance","type":"script","scope":"global","author":"Hp9ImM4o9YRTSdfu","img":"icons/commodities/flowers/clover.webp","command":"const selected = game.system.rdd.RdDUtility.getSelectedActor();\nif (selected) {\n selected.rollAppelChance();\n}\nelse {\n ui.notifications.info('Pas de personnage sélectionné');\n}","ownership":{"default":0,"Hp9ImM4o9YRTSdfu":3},"flags":{"core":{"sourceId":"Macro.XHNbjnGKXaCiCadq"}},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.15","coreVersion":"10.291","createdTime":1671220038331,"modifiedTime":1671233849101,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"},"folder":null,"sort":0,"_id":"UzAWljmFq5sY702w"}
|
||||
{"name":"Encaissement","type":"script","scope":"global","author":"Hp9ImM4o9YRTSdfu","img":"icons/svg/bones.svg","command":"const selected = game.system.rdd.RdDUtility.getSelectedActor();\nif (selected) {\n selected.encaisser();\n}\nelse {\n ui.notifications.info('Pas de personnage sélectionné');\n}","ownership":{"default":0,"Hp9ImM4o9YRTSdfu":3},"flags":{"core":{"sourceId":"Macro.XHNbjnGKXaCiCadq"}},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.15","coreVersion":"10.291","createdTime":1671220038331,"modifiedTime":1671234017623,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"},"folder":null,"sort":0,"_id":"WD6T8AdRbX2Ylxqe"}
|
||||
{"name":"Jet quelconque","type":"script","scope":"global","author":"Hp9ImM4o9YRTSdfu","img":"icons/sundries/gaming/dice-runed-tan.webp","command":"const selected = game.system.rdd.RdDUtility.getSelectedActor();\nif (selected) {\n selected.roll();\n}\nelse {\n ui.notifications.info('Pas de personnage sélectionné');\n}","ownership":{"default":0,"Hp9ImM4o9YRTSdfu":3},"flags":{"core":{"sourceId":"Macro.XHNbjnGKXaCiCadq"}},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.15","coreVersion":"10.291","createdTime":1671220038331,"modifiedTime":1671233500655,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"},"folder":null,"sort":0,"_id":"bnJnbKDHpbqY8Pr9"}
|
||||
{"name":"Jet d'éthylisme","type":"script","scope":"global","author":"Hp9ImM4o9YRTSdfu","img":"icons/consumables/drinks/alcohol-beer-stein-wooden-metal-brown.webp","command":"const selected = game.system.rdd.RdDUtility.getSelectedActor();\nif (selected) {\n selected.jetEthylisme();\n}\nelse {\n ui.notifications.info('Pas de personnage sélectionné');\n}","ownership":{"default":0,"Hp9ImM4o9YRTSdfu":3},"flags":{"core":{"sourceId":"Macro.XHNbjnGKXaCiCadq"}},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.15","coreVersion":"10.291","createdTime":1671220038331,"modifiedTime":1671233646086,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"},"folder":null,"sort":0,"_id":"mvub1dRHNFmWjRr7"}
|
||||
{"name":"Tirer le tarot","type":"chat","scope":"global","author":"Hp9ImM4o9YRTSdfu","img":"systems/foundryvtt-reve-de-dragon/icons/tarots/dos-tarot.webp","command":"/tirer tarot","ownership":{"default":0,"Hp9ImM4o9YRTSdfu":3},"flags":{"core":{"sourceId":"Macro.HBZSKR9OHCQbLcTC"}},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.15","coreVersion":"10.291","createdTime":1669469547231,"modifiedTime":1671237401618,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"},"folder":null,"sort":0,"_id":"vTfJTFYYiRu8X5LM"}
|
@ -1,17 +1,17 @@
|
||||
{"name":"Passeur des Rêves","type":"rencontre","img":"systems/foundryvtt-reve-de-dragon/icons/tete_dragon.webp","system":{"genre":"m","formule":"2d4","refoulement":0,"presentCite":true,"mauvaiseRencontre":false,"ordreTri":2,"force":0,"coord":"","date":"","heure":"","succes":{"effets":["passeur"],"message":"Le Passeur des Rêves propose de vous transporter{{#if actor.system.reve.tmrpos.cache}}, mais vous ne savez pas où vous êtes{{else}} à {{rencontre.system.force}} cases de {{tmr.label}}{{/if}}.","poesie":"<p>Comme je descendais des Fleuves impassibles,<br>Je ne me sentis plus guidé par les haleurs :<br>Des Peaux-Rouges criards les avaient pris pour cibles,<br>Les ayant cloués nus aux poteaux de couleurs.</p>","reference":"Le bateau ivre, Arthur Rimbaud"},"echec":{"effets":[],"message":"Le prix que demande le Passeur des Rêves est trop élevé, vous êtes réduit à poursuivre votre chemin par vos propres moyens.","poesie":"<p>Loin des peuples vivants, errantes, condamnées,<br>A travers les déserts courez comme les loups ;<br>Faites votre destin, âmes désordonnées,<br>Et fuyez l'infini que vous portez en vous !</p>","reference":"Femmes damnées (2), Charles Baudelaire"},"frequence":{"cite":25,"sanctuaire":25,"plaines":20,"pont":20,"collines":15,"foret":15,"monts":10,"desert":10,"fleuve":5,"lac":5,"marais":2,"gouffre":2,"necropole":0,"desolation":0,"mauvaise":0},"description":""},"effects":[],"flags":{"core":{"sourceId":"Item.Ffk9pio1qy4Z28Lc"}},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.1.0","coreVersion":"10.288","createdTime":1667846036337,"modifiedTime":1668036933995,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"},"_id":"0IQLIYklxPIGjHT8","folder":null,"sort":0,"ownership":{"default":0,"Hp9ImM4o9YRTSdfu":3}}
|
||||
{"name":"Messager des Rêves","type":"rencontre","img":"systems/foundryvtt-reve-de-dragon/icons/tete_dragon.webp","system":{"genre":"m","formule":"2d4","refoulement":0,"presentCite":true,"mauvaiseRencontre":false,"ordreTri":1,"force":0,"coord":"","date":"","heure":"","succes":{"effets":["messager"],"message":"Le Messager des rêves propose d'emmener votre message {{#if actor.system.reve.tmrpos.cache}}, mais vous ne savez pas où vous êtes{{else}} à {{rencontre.system.force}} cases de {{tmr.label}}{{/if}}.","poesie":"<p>J'irai là-bas où l'arbre et l'homme, pleins de sève,<br>Se pâment longuement sous l'ardeur des climats ;<br>Fortes tresses, soyez la houle qui m'enlève !</p>","reference":"La chevelure, Charles Baudelaire"},"echec":{"effets":[],"message":"Le Messager des Rêves est pressé et continue son chemin d'une traite sans vous accorder un regard.","poesie":"<p>En réalité, tous les éléments du rêve des Dragons expriment<br>le Draconic : chaque pierre, chaque fleur, chaque goutte d'eau,<br>chaque nuage est porteur d'un message dans la langue des Dragons</p>","reference":"Rêve de Dragon, Denis Gerfaud"},"frequence":{"cite":25,"sanctuaire":25,"plaines":20,"pont":20,"collines":15,"foret":15,"monts":10,"desert":10,"fleuve":5,"lac":5,"marais":2,"gouffre":2,"necropole":0,"desolation":0,"mauvaise":0},"description":""},"effects":[],"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.rencontres.Ffk9pio1qy4Z28Lc"}},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.1.0","coreVersion":"10.288","createdTime":1667846036337,"modifiedTime":1668036933994,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"},"_id":"0MwHtPpFV2lTeCtt","folder":null,"sort":0,"ownership":{"default":0,"Hp9ImM4o9YRTSdfu":3}}
|
||||
{"name":"Briseur de Rêve","type":"rencontre","img":"systems/foundryvtt-reve-de-dragon/icons/tete_dragon.webp","system":{"genre":"m","formule":"2d6","refoulement":1,"presentCite":false,"mauvaiseRencontre":false,"ordreTri":6,"force":0,"coord":"","date":"","heure":"","succes":{"effets":[],"message":"Le {{rencontre.name}} tente vainement de vous déconcentrer, avant de fuir sans demander son reste.","poesie":"<p>La légende affirme que ce sont les Gnomes qui furent les premiers haut-rêvants. En observant les pierres précieuses, les gemmes qui sont les larmes de joie des Dragons, ils parvinrent à en comprendre la langue. Et l'ayant comprise, ils purent s'en servir pour influencer le cours du rêve.</p>","reference":"Rêve de Dragon, Denis Gerfaud"},"echec":{"effets":["rompu"],"message":"Le {{rencontre.name}} vous déconcentre au point de briser votre demi-rêve.","poesie":"<p>Quand le rêve se brise,<br>Dans la plainte du jour,<br>Ma mémoire devient grise<br>Et sombre, tour à tour,<br>Dans le puits du silence<br>Et de la solitude ;<br>Elle reprend son errance<br>Parmi la multitude.</p>","reference":"Quand le rêve se brise, Cypora Sebagh"},"frequence":{"cite":5,"sanctuaire":5,"plaines":7,"pont":7,"collines":13,"foret":13,"monts":16,"desert":16,"fleuve":16,"lac":16,"marais":21,"gouffre":21,"necropole":20,"desolation":20,"mauvaise":0},"description":""},"effects":[],"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.rencontres.dvEiIk0HFGsvyb5F"}},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.1.0","coreVersion":"10.288","createdTime":1667846036340,"modifiedTime":1668036933993,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"},"_id":"3e6jIvyy1e7OzYcB","folder":null,"sort":0,"ownership":{"default":0,"Hp9ImM4o9YRTSdfu":3}}
|
||||
{"name":"Reflet d'ancien Rêve","type":"rencontre","img":"systems/foundryvtt-reve-de-dragon/icons/tete_dragon.webp","system":{"genre":"m","formule":"2d6","refoulement":1,"presentCite":false,"mauvaiseRencontre":false,"ordreTri":7,"force":"0","coord":"","date":"","heure":"","succes":{"effets":[],"message":"Le {{rencontre.name}} s'estompe dans l'oubli.","poesie":"<p>Les formes s'effaçaient et n'étaient plus qu'un rêve,<br>Une ébauche lente à venir<br>Sur la toile oubliée, et que l'artiste achève<br>Seulement par le souvenir.</p>","reference":"Une charogne, Charles Baudelaire"},"echec":{"effets":["persistant"],"message":"Vous êtes submergé par un {{rencontre.name}}, les souvenirs vous retiennent tant qu'il ne sera pas vaincu!","poesie":"<p>Longtemps ! toujours ! ma main dans ta crinière lourde<br>Sèmera le rubis, la perle et le saphir,<br>Afin qu'à mon désir tu ne sois jamais sourde !<br>N'es-tu pas l'oasis où je rêve, et la gourde<br>Où je hume à longs traits le vin du souvenir</p>","reference":"La chevelure, Charles Baudelaire"},"frequence":{"cite":5,"sanctuaire":5,"plaines":6,"pont":6,"collines":6,"foret":6,"monts":10,"desert":10,"fleuve":14,"lac":14,"marais":15,"gouffre":15,"necropole":15,"desolation":15,"mauvaise":0},"description":""},"effects":[],"ownership":{"default":0,"Hp9ImM4o9YRTSdfu":3},"flags":{"core":{"sourceId":"Item.drXUmMGrrY9jyJPp"}},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.1.0","coreVersion":"10.288","createdTime":1667773074055,"modifiedTime":1668036933995,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"},"folder":null,"sort":0,"_id":"5IEjrkpQ2YNFiUP4"}
|
||||
{"name":"Tourbillon noir","type":"rencontre","img":"systems/foundryvtt-reve-de-dragon/icons/tete_dragon.webp","system":{"genre":"m","formule":"2d8","refoulement":1,"presentCite":false,"mauvaiseRencontre":false,"ordreTri":9,"force":0,"coord":"","date":"","heure":"","succes":{"effets":[],"message":"Le {{rencontre.name}} orageux vous enveloppe de fureur et d'éclairs, vous tenez bon face à la tempête qui s'éloigne sans vous éloigner de votre chemin.","poesie":"<p>Car le Second Âge fut bel et bien celui des Magiciens. Durant cette période, les Gnomes s'enfoncèrent profondément sous les montagnes et la magie passa aux mains des Humains qui en usèrent et abusèrent, se croyant devenus les maîtres du monde</p>","reference":"Rêve de Dragon, Denis Gerfaud"},"echec":{"effets":["reve-1","reve-1","aleatoire","aleatoire","persistant"],"message":"Le {{rencontre.name}} furieux vous secoue tel un fichu de paille malmené par les vents, et vous emporte dans la tourmente.","poesie":"<p>Elle aurait pas cru sans le voir<br>Que la couleur du désespoir<br>Là-bas aussi ce fût le noir.</p>","reference":"Lily, Pierre Perret"},"frequence":{"cite":3,"sanctuaire":3,"plaines":4,"pont":4,"collines":4,"foret":4,"monts":5,"desert":5,"fleuve":8,"lac":8,"marais":11,"gouffre":11,"necropole":17,"desolation":17,"mauvaise":0},"description":""},"effects":[],"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.rencontres.81b2cjAzl9hfK7Zt"}},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.1.0","coreVersion":"10.288","createdTime":1667846036336,"modifiedTime":1668036933995,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"},"_id":"89NtInRn4uWArlct","folder":null,"sort":0,"ownership":{"default":0,"Hp9ImM4o9YRTSdfu":3}}
|
||||
{"name":"Reflet d'ancien Rêve","type":"rencontre","img":"systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp","system":{"genre":"m","formule":"2d6+4","refoulement":2,"presentCite":false,"mauvaiseRencontre":true,"ordreTri":3,"force":0,"coord":"","date":"","heure":"","succes":{"effets":[],"message":"Le {{rencontre.name}} s'estompe dans l'oubli.","poesie":"<p>Les formes s'effaçaient et n'étaient plus qu'un rêve,<br>Une ébauche lente à venir<br>Sur la toile oubliée, et que l'artiste achève<br>Seulement par le souvenir.</p>","reference":"Une charogne, Charles Baudelaire"},"echec":{"effets":["persistant"],"message":"Vous êtes submergé par un {{rencontre.name}}, les souvenirs vous retiennent tant qu'il ne sera pas vaincu!","poesie":"<p>Longtemps ! toujours ! ma main dans ta crinière lourde<br>Sèmera le rubis, la perle et le saphir,<br>Afin qu'à mon désir tu ne sois jamais sourde !<br>N'es-tu pas l'oasis où je rêve, et la gourde<br>Où je hume à longs traits le vin du souvenir</p>","reference":"La chevelure, Charles Baudelaire"},"frequence":{"cite":5,"sanctuaire":5,"plaines":6,"pont":6,"collines":6,"foret":6,"monts":10,"desert":10,"fleuve":14,"lac":14,"marais":15,"gouffre":15,"necropole":15,"desolation":15,"mauvaise":1},"description":""},"effects":[],"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.rencontres.MB2qOlTsEUTQkRVL"}},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.8","coreVersion":"10.290","createdTime":1667846036338,"modifiedTime":1669471919738,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"},"_id":"U6WoTkHRwC4DicuZ","folder":null,"sort":0,"ownership":{"default":0,"Hp9ImM4o9YRTSdfu":3}}
|
||||
{"name":"Changeur de Rêve","type":"rencontre","img":"systems/foundryvtt-reve-de-dragon/icons/tete_dragon.webp","system":{"genre":"m","formule":"2d6","refoulement":1,"presentCite":false,"mauvaiseRencontre":false,"ordreTri":5,"force":0,"coord":"","date":"","heure":"","succes":{"effets":["teleport"],"message":"Le {{rencontre.name}} vaincu accepte de vous déplacer sur une autre case {{caseTmr-type tmr.coord}} de votre choix en échange de sa liberté.","poesie":"<p>Allez, que le caprice emporte<br>Chaque âme selon son désir,<br>Et que, close après vous, la porte<br>Ne se rouvre plus qu'au plaisir.</p>","reference":"Caligula - IIIème chant, Gérard de Nerval"},"echec":{"effets":["teleport-aleatoire"],"message":"Le {{rencontre.name}} vous embobine avec des promesses, et vous transporte sur une autre case {{caseTmr-type tmr.coord}} sans attendre votre avis.","poesie":"<p>Les sages ont encore coutume de dire : <br>« Mais comment les Dragons peuvent-ils être influencés par une créature qui, tout bien considéré, n'existe pas vraiment pour eux, qui n'est que le fantasme de leur activité nocturne ? »</p>","reference":"Rêve de Dragon, Denis Gerfaud"},"frequence":{"cite":10,"sanctuaire":10,"plaines":15,"pont":15,"collines":15,"foret":15,"monts":15,"desert":15,"fleuve":12,"lac":12,"marais":10,"gouffre":10,"necropole":10,"desolation":10,"mauvaise":0},"description":""},"effects":[],"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.rencontres.q4uyAZoFPyc4x8XI"}},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.1.0","coreVersion":"10.288","createdTime":1667846036340,"modifiedTime":1668036933994,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"},"_id":"WeCnQirDR1r3TUFw","folder":null,"sort":0,"ownership":{"default":0,"Hp9ImM4o9YRTSdfu":3}}
|
||||
{"name":"Rêve de Dragon","type":"rencontre","img":"systems/foundryvtt-reve-de-dragon/styles/img/rdd_pause.webp","system":{"genre":"m","formule":"1dr+7","refoulement":2,"presentCite":false,"mauvaiseRencontre":false,"ordreTri":10,"force":0,"coord":"","date":"","heure":"","succes":{"effets":["reve+f","part+tete","part+xp","seuil"],"message":"A tout seigneur, tout honneur, vous faites face à un {{rencontre.name}}. Vous le maîtrisez et gagnez ses {{rencontre.system.force}} points de rêve.","poesie":"<p>Le monde est Rêve de Dragons, mais nous ne savons <br>Ni leur apparence ni qui sont les dragons. <br>En dépit de l'iconographie qui les clame <br>Immenses créatures ailées crachant des flammes</p>","reference":"Rêve de Dragon, Denis Gerfaud"},"echec":{"effets":["echec-queue"],"message":"A tout seigneur, tout honneur, vous faites face à un {{rencontre.name}}. La rencontre tourne au cauchemar, dans la lutte épique, vous subissez {{#if rolled.isETotal}}deux queues{{else}}une queue{{/if}} de dragon!","poesie":"<p>Je suis le Ténébreux, – le Veuf, – l'Inconsolé, <br>Le Prince d'Aquitaine à la Tour abolie : <br>Ma seule Etoile est morte, – et mon luth constellé <br>Porte le Soleil noir de la Mélancolie.</p>","reference":"El Desdichado, Gérard de Nerval"},"frequence":{"cite":3,"sanctuaire":3,"plaines":3,"pont":3,"collines":3,"foret":3,"monts":3,"desert":3,"fleuve":3,"lac":3,"marais":3,"gouffre":3,"necropole":3,"desolation":3,"mauvaise":0},"description":""},"effects":[],"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.rencontres.Hw40Q8jS9wmukgU4"}},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.1.0","coreVersion":"10.288","createdTime":1667846036338,"modifiedTime":1668036933995,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"},"_id":"dWKuUc29ysrlPZFg","folder":null,"sort":0,"ownership":{"default":0,"Hp9ImM4o9YRTSdfu":3}}
|
||||
{"name":"Passeur fou","type":"rencontre","img":"systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp","system":{"genre":"m","formule":"2d8","refoulement":2,"presentCite":false,"mauvaiseRencontre":true,"ordreTri":26,"force":0,"coord":"","date":"","heure":"","succes":{"effets":[],"message":"Le Passeur fou tente vainement de découvrir où vous avez caché vos réserves. Vous le chassez, et en déroute il part harceler un autre voyageur du rêve.","poesie":"<p>Certain Fou poursuivait à coups de pierre un Sage.<br>Le Sage se retourne et lui dit : Mon ami,<br>C'est fort bien fait à toi ; reçois cet écu-ci :<br>Tu fatigues assez pour gagner davantage.</p>","reference":"Un Fou et un Sage, Jean de La Fontaine"},"echec":{"effets":["sort-aleatoire"],"message":"{{#if sortReserve}}Le Passeur fou dérobe la clé de vos sorts. Vous vous saisissez de lui, mais dans un nuage violet, il vous emporte {{newTMR.label}} déclencher votre sort en réserve de {{sortReserve.name}}.{{else}}Le Passeur fou tente de vous dérober la clé de vos sorts. Ne la trouvant pas, il déclenche un nuage violet et vous emporte en {{newTMR.label}}.{{/if}}","poesie":"<p>Je la voyais passer de ma demeure,<br>Et c'était tout.<br>Mais à présent je m'ennuie à toute heure,<br>Plein de dégoût,<br>Rêveur oisif, l'âme dans la campagne,<br>La dague au clou ... –<br>Le vent qui vient à travers la montagne<br>M'a rendu fou !</p>","reference":"Guitare, Victor Hugo"},"frequence":{"cite":0,"sanctuaire":0,"plaines":0,"pont":0,"collines":0,"foret":0,"monts":0,"desert":0,"fleuve":0,"lac":0,"marais":0,"gouffre":0,"necropole":0,"desolation":0,"mauvaise":1},"description":""},"effects":[],"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.rencontres.HkYBb3Ls4W15tKwo"}},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.1.0","coreVersion":"10.288","createdTime":1667846036338,"modifiedTime":1668036933995,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"},"_id":"eVxv2FMRZOo7aTWB","folder":null,"sort":0,"ownership":{"default":0,"Hp9ImM4o9YRTSdfu":3}}
|
||||
{"name":"Mangeur de Rêve","type":"rencontre","img":"systems/foundryvtt-reve-de-dragon/icons/tete_dragon.webp","system":{"genre":"m","formule":"1d6","refoulement":1,"presentCite":false,"mauvaiseRencontre":false,"ordreTri":4,"force":0,"coord":"","date":"","heure":"","succes":{"effets":[],"message":"Le {{rencontre.name}} claque de sa machoire dans le vide avant de fuir.","poesie":"<p>Rois ! la bure est souvent jalouse du velours.<br>Le peuple a froid l'hiver, le peuple a faim toujours.<br>Rendez-lui son sort plus facile.<br>Le peuple souvent porte un bien rude collier.<br>Ouvrez l'école aux fils, aux pères l'atelier,<br>À tous vos bras, auguste asile !</p>","reference":"Conseil, Victor Hugo"},"echec":{"effets":["reve-f"],"message":"Le {{rencontre.name}} croque votre Rêve ! Il emporte {{rencontre.system.force}} de vos points de rêve actuels","poesie":"<div>\n<div>Suis-je Amour ou Phébus ?... Lusignan ou Biron ?</div>\n<div>Mon front est rouge encor du baiser de la Reine ;</div>\n<div>J'ai rêvé dans la Grotte où nage la sirène...</div>\n</div>","reference":"El Desdichado, Gérard de Nerval"},"frequence":{"cite":5,"sanctuaire":5,"plaines":5,"pont":5,"collines":12,"foret":12,"monts":18,"desert":18,"fleuve":24,"lac":24,"marais":24,"gouffre":24,"necropole":20,"desolation":20,"mauvaise":1},"description":""},"effects":[],"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.rencontres.3SA5An6kPlpcDEIj"}},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.1.0","coreVersion":"10.288","createdTime":1667846036336,"modifiedTime":1668036933994,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"},"_id":"fd89RWxlO8BF1FFJ","folder":null,"sort":0,"ownership":{"default":0,"Hp9ImM4o9YRTSdfu":3}}
|
||||
{"name":"Tourbillon noir","type":"rencontre","img":"systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp","system":{"genre":"m","formule":"2d8+4","refoulement":2,"presentCite":false,"mauvaiseRencontre":true,"ordreTri":25,"force":0,"coord":"","date":"","heure":"","succes":{"effets":[],"message":"Le {{rencontre.name}} orageux vous enveloppe de fureur et d'éclairs, vous tenez bon face à la tempête qui s'éloigne sans vous éloigner de votre chemin.","poesie":"<p>Car le Second Âge fut bel et bien celui des Magiciens. Durant cette période, les Gnomes s'enfoncèrent profondément sous les montagnes et la magie passa aux mains des Humains qui en usèrent et abusèrent, se croyant devenus les maîtres du monde</p>","reference":"Rêve de Dragon, Denis Gerfaud"},"echec":{"effets":["reve-1","reve-1","aleatoire","aleatoire","persistant"],"message":"Le {{rencontre.name}} furieux vous secoue tel un fichu de paille malmené par les vents, et vous emporte dans la tourmente.","poesie":"<p>Elle aurait pas cru sans le voir<br>Que la couleur du désespoir<br>Là-bas aussi ce fût le noir.</p>","reference":"Lily, Pierre Perret"},"frequence":{"cite":3,"sanctuaire":3,"plaines":4,"pont":4,"collines":4,"foret":4,"monts":5,"desert":5,"fleuve":8,"lac":8,"marais":11,"gouffre":11,"necropole":17,"desolation":17,"mauvaise":1},"description":""},"effects":[],"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.rencontres.D0gbC3plAesQx3uq"}},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.1.0","coreVersion":"10.288","createdTime":1667846036336,"modifiedTime":1668036933995,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"},"_id":"hmeuLiLh5nkuQ4eD","folder":null,"sort":0,"ownership":{"default":0,"Hp9ImM4o9YRTSdfu":3}}
|
||||
{"name":"Fleur des rêves","type":"rencontre","img":"systems/foundryvtt-reve-de-dragon/icons/tete_dragon.webp","system":{"genre":"f","formule":"1d6","refoulement":0,"presentCite":true,"mauvaiseRencontre":false,"ordreTri":3,"force":"0","coord":"","date":"","heure":"","succes":{"effets":["reve+f"],"message":"Vous cueillez la {{rencontre.name}}, son parfum vous apporte {{rencontre.system.force}} points de Rêve.","poesie":"<p>Et qui sait si les fleurs nouvelles que je rêve<br>Trouveront dans ce sol lavé comme une grève<br>Le mystique aliment qui ferait leur vigueur ?</p>","reference":"L'Ennemi, Charles Baudelaire","effet":["reve+f"]},"echec":{"effets":[],"message":"La {{rencontre.name}} se fane et disparaît entre vos doigts.","poesie":"<p>Et le ciel regardait la carcasse superbe<br>Comme une fleur s'épanouir.<br>La puanteur était si forte, que sur l'herbe<br>Vous crûtes vous évanouir.</p>","reference":"Une charogne, Charles Baudelaire"},"frequence":{"cite":15,"sanctuaire":15,"plaines":15,"pont":15,"collines":12,"foret":12,"monts":6,"desert":6,"fleuve":3,"lac":3,"marais":1,"gouffre":1,"necropole":0,"desolation":0,"mauvaise":0},"description":"","onSucces":{"effets":[],"message":"","poesie":"","reference":""},"onEchec":{"effets":[],"message":"","poesie":"","reference":""},"descriptionmj":"","code":"","onSuccess":{"effets":[],"message":"","poesie":"","reference":""}},"effects":[],"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.rencontres.2ywduc2BHGpVvUbz"}},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.1.0","coreVersion":"10.288","createdTime":1667846036335,"modifiedTime":1668036933994,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"},"_id":"jtJk1ptJXsdsGZHA","folder":null,"sort":0,"ownership":{"default":0,"Hp9ImM4o9YRTSdfu":3}}
|
||||
{"name":"Tourbillon rouge","type":"rencontre","img":"systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp","system":{"genre":"m","formule":"2d8","refoulement":3,"presentCite":false,"mauvaiseRencontre":true,"ordreTri":27,"force":0,"coord":"","date":"","heure":"","succes":{"effets":[],"message":"Le {{rencontre.name}} s'abat avec violence mais vous êtes plus rapide et parvenez à lui échapper.","poesie":"<p>Qu'est-ce de votre vie ? un tourbillon rouant<br>De fumière à flot gris, parmi l'air se jouant,<br>Qui passe plus soudain que foudre meurtrière.</p>","reference":"Qu'est-ce de votre vie ? une bouteille molle, Jean-Baptiste Chassignet"},"echec":{"effets":["aleatoire","aleatoire","aleatoire","aleatoire","reve-1","reve-1","vie-1","persistant"],"message":"Le {{rencontre.name}} vous frappe de milliers de morsure et vous malmène à travers les terres médianes.","poesie":"<p>Cris de l'enfer! voix qui hurle et qui pleure !<br>L'horrible essaim, poussé par l'aquilon,<br>Sans doute, ô ciel ! s'abat sur ma demeure.<br>Le mur fléchit sous le noir bataillon.<br>La maison crie et chancelle penchée,<br>Et l'on dirait que, du sol arrachée,<br>Ainsi qu'il chasse une feuille séchée,<br>Le vent la roule avec leur tourbillon !</p>","reference":"Les Djinns, poème Victor Hugo"},"frequence":{"cite":0,"sanctuaire":0,"plaines":0,"pont":0,"collines":0,"foret":0,"monts":0,"desert":0,"fleuve":0,"lac":0,"marais":0,"gouffre":0,"necropole":0,"desolation":0,"mauvaise":1},"description":""},"effects":[],"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.rencontres.WiyUvZX4oTAd82s3"}},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.1.0","coreVersion":"10.288","createdTime":1667846036339,"modifiedTime":1668036933996,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"},"_id":"nD7p8ROloR6ElTpW","folder":null,"sort":0,"ownership":{"default":0,"Hp9ImM4o9YRTSdfu":3}}
|
||||
{"name":"Tourbillon blanc","type":"rencontre","img":"systems/foundryvtt-reve-de-dragon/icons/tete_dragon.webp","system":{"genre":"m","formule":"2d6","refoulement":1,"presentCite":false,"mauvaiseRencontre":false,"ordreTri":8,"force":"0","coord":"","date":"","heure":"","succes":{"effets":[],"message":"Le {{rencontre.name}} souleve une poussière blanche, vous tenez bon, et il tourbillonne en s'éloignant.","poesie":"<p>Le Premier Âge fut appelé l'Âge des Dragons. Ce fut le commencement<br>des temps, le commencement des rêves. Durant cette période plus mythique<br>que réellement historique, les Dragons aimaient à se rêver eux-mêmes.</p>","reference":"Rêve de Dragon, Denis Gerfaud"},"echec":{"effets":["reve-1","aleatoire","persistant"],"message":"Le souffle du {{rencontre.name}} vous déstabilise et vous emmène dans un nuage de poussière.","poesie":"<p>C'est l'essaim des Djinns qui passe,<br>Et tourbillonne en sifflant !<br>Les ifs, que leur vol fracasse,<br>Craquent comme un pin brûlant.</p>","reference":"Les Djinns, Victor Hugo"},"frequence":{"cite":4,"sanctuaire":4,"plaines":5,"pont":5,"collines":5,"foret":5,"monts":7,"desert":7,"fleuve":10,"lac":10,"marais":11,"gouffre":11,"necropole":15,"desolation":15,"mauvaise":0},"description":""},"effects":[],"ownership":{"default":0,"Hp9ImM4o9YRTSdfu":3},"flags":{"core":{"sourceId":"Item.GIG8SbYrl60p50u3"}},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.1.0","coreVersion":"10.288","createdTime":1667773090153,"modifiedTime":1668036933995,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"},"folder":null,"sort":0,"_id":"ph6qZi1yDgh68Y5l"}
|
||||
{"name":"Mangeur de Rêve","type":"rencontre","img":"systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp","system":{"genre":"m","formule":"1d6","refoulement":2,"presentCite":false,"mauvaiseRencontre":true,"ordreTri":21,"force":0,"coord":"","date":"","heure":"","succes":{"effets":[],"message":"Le {{rencontre.name}} claque de sa machoire dans le vide avant de fuir.","poesie":"<p>Rois ! la bure est souvent jalouse du velours.<br>Le peuple a froid l'hiver, le peuple a faim toujours.<br>Rendez-lui son sort plus facile.<br>Le peuple souvent porte un bien rude collier.<br>Ouvrez l'école aux fils, aux pères l'atelier,<br>À tous vos bras, auguste asile !</p>","reference":"Conseil, Victor Hugo"},"echec":{"effets":["reve-f"],"message":"Le {{rencontre.name}} croque votre Rêve ! Il emporte {{rencontre.system.force}} de vos points de rêve actuels","poesie":"<div>\n<div>Suis-je Amour ou Phébus ?... Lusignan ou Biron ?</div>\n<div>Mon front est rouge encor du baiser de la Reine ;</div>\n<div>J'ai rêvé dans la Grotte où nage la sirène...</div>\n</div>","reference":"El Desdichado, Gérard de Nerval"},"frequence":{"cite":5,"sanctuaire":5,"plaines":5,"pont":5,"collines":12,"foret":12,"monts":18,"desert":18,"fleuve":24,"lac":24,"marais":24,"gouffre":24,"necropole":20,"desolation":20,"mauvaise":1},"description":""},"effects":[],"flags":{"core":{"sourceId":"Item.3SA5An6kPlpcDEIj"}},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.1.0","coreVersion":"10.288","createdTime":1667846036340,"modifiedTime":1668036933994,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"},"_id":"uhdiBoim26qSmVJ7","folder":null,"sort":0,"ownership":{"default":0,"Hp9ImM4o9YRTSdfu":3}}
|
||||
{"name":"Mangeur de Rêve","type":"rencontre","img":"systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp","system":{"genre":"m","formule":"2d6","refoulement":2,"presentCite":false,"mauvaiseRencontre":true,"ordreTri":22,"force":0,"coord":"","date":"","heure":"","succes":{"effets":[],"message":"Le {{rencontre.name}} claque de sa machoire dans le vide avant de fuir.","poesie":"<p>Rois ! la bure est souvent jalouse du velours.<br>Le peuple a froid l'hiver, le peuple a faim toujours.<br>Rendez-lui son sort plus facile.<br>Le peuple souvent porte un bien rude collier.<br>Ouvrez l'école aux fils, aux pères l'atelier,<br>À tous vos bras, auguste asile !</p>","reference":"Conseil, Victor Hugo"},"echec":{"effets":["reve-f"],"message":"Le {{rencontre.name}} croque votre Rêve ! Il emporte {{rencontre.system.force}} de vos points de rêve actuels","poesie":"<div>\n<div>Suis-je Amour ou Phébus ?... Lusignan ou Biron ?</div>\n<div>Mon front est rouge encor du baiser de la Reine ;</div>\n<div>J'ai rêvé dans la Grotte où nage la sirène...</div>\n</div>","reference":"El Desdichado, Gérard de Nerval"},"frequence":{"cite":5,"sanctuaire":5,"plaines":5,"pont":5,"collines":12,"foret":12,"monts":18,"desert":18,"fleuve":24,"lac":24,"marais":24,"gouffre":24,"necropole":20,"desolation":20,"mauvaise":1},"description":""},"effects":[],"flags":{"core":{"sourceId":"Item.3SA5An6kPlpcDEIj"}},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.1.0","coreVersion":"10.288","createdTime":1667846036340,"modifiedTime":1668036933994,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"},"_id":"yHm1Rqa8CP5qhg69","folder":null,"sort":0,"ownership":{"default":0,"Hp9ImM4o9YRTSdfu":3}}
|
||||
{"name":"Tourbillon blanc","type":"rencontre","img":"systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp","system":{"genre":"m","formule":"2d6+4","refoulement":2,"presentCite":false,"mauvaiseRencontre":true,"ordreTri":24,"force":0,"coord":"","date":"","heure":"","succes":{"effets":[],"message":"Le {{rencontre.name}} souleve une poussière blanche, vous tenez bon, et il tourbillonne en s'éloignant.","poesie":"<p>Le Premier Âge fut appelé l'Âge des Dragons. Ce fut le commencement<br>des temps, le commencement des rêves. Durant cette période plus mythique<br>que réellement historique, les Dragons aimaient à se rêver eux-mêmes.</p>","reference":"Rêve de Dragon, Denis Gerfaud"},"echec":{"effets":["reve-1","aleatoire","persistant"],"message":"Le souffle du {{rencontre.name}} vous déstabilise et vous emmène dans un nuage de poussière.","poesie":"<p>C'est l'essaim des Djinns qui passe,<br>Et tourbillonne en sifflant !<br>Les ifs, que leur vol fracasse,<br>Craquent comme un pin brûlant.</p>","reference":"Les Djinns, Victor Hugo"},"frequence":{"cite":4,"sanctuaire":4,"plaines":5,"pont":5,"collines":5,"foret":5,"monts":7,"desert":7,"fleuve":10,"lac":10,"marais":11,"gouffre":11,"necropole":15,"desolation":15,"mauvaise":1},"description":""},"effects":[],"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.rencontres.GIG8SbYrl60p50u3"}},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.1.0","coreVersion":"10.288","createdTime":1667846036337,"modifiedTime":1668036933995,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"},"_id":"yXZW5cDrGoZxD9lK","folder":null,"sort":0,"ownership":{"default":0,"Hp9ImM4o9YRTSdfu":3}}
|
||||
{"name":"Passeur des Rêves","type":"rencontre","img":"systems/foundryvtt-reve-de-dragon/icons/tete_dragon.webp","system":{"genre":"m","formule":"2d4","refoulement":0,"presentCite":true,"mauvaiseRencontre":false,"ordreTri":2,"force":0,"coord":"","date":"","heure":"","succes":{"effets":["passeur"],"message":"Le Passeur des Rêves propose de vous transporter{{#if actor.system.reve.tmrpos.cache}}, mais vous ne savez pas où vous êtes{{else}} à {{rencontre.system.force}} cases de {{{tmr.label}}}{{/if}}.","poesie":"<p>Comme je descendais des Fleuves impassibles,<br>Je ne me sentis plus guidé par les haleurs :<br>Des Peaux-Rouges criards les avaient pris pour cibles,<br>Les ayant cloués nus aux poteaux de couleurs.</p>","reference":"Le bateau ivre, Arthur Rimbaud"},"echec":{"effets":[],"message":"Le prix que demande le Passeur des Rêves est trop élevé, vous êtes réduit à poursuivre votre chemin par vos propres moyens.","poesie":"<p>Loin des peuples vivants, errantes, condamnées,<br>A travers les déserts courez comme les loups ;<br>Faites votre destin, âmes désordonnées,<br>Et fuyez l'infini que vous portez en vous !</p>","reference":"Femmes damnées (2), Charles Baudelaire"},"frequence":{"cite":25,"sanctuaire":25,"plaines":20,"pont":20,"collines":15,"foret":15,"monts":10,"desert":10,"fleuve":5,"lac":5,"marais":2,"gouffre":2,"necropole":0,"desolation":0,"mauvaise":0},"description":""},"effects":[],"flags":{"core":{"sourceId":"Item.Ffk9pio1qy4Z28Lc"}},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.1.0","coreVersion":"10.288","createdTime":1667846036337,"modifiedTime":1668036933995,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"},"_id":"0IQLIYklxPIGjHT8","folder":null,"sort":0,"ownership":{"default":0,"Hp9ImM4o9YRTSdfu":3}}
|
||||
{"name":"Messager des Rêves","type":"rencontre","img":"systems/foundryvtt-reve-de-dragon/icons/tete_dragon.webp","system":{"genre":"m","formule":"2d4","refoulement":0,"presentCite":true,"mauvaiseRencontre":false,"ordreTri":1,"force":0,"coord":"","date":"","heure":"","succes":{"effets":["messager"],"message":"Le Messager des rêves propose d'emmener votre message {{#if actor.system.reve.tmrpos.cache}}, mais vous ne savez pas où vous êtes{{else}} à {{rencontre.system.force}} cases de {{{tmr.label}}}{{/if}}.","poesie":"<p>J'irai là-bas où l'arbre et l'homme, pleins de sève,<br>Se pâment longuement sous l'ardeur des climats ;<br>Fortes tresses, soyez la houle qui m'enlève !</p>","reference":"La chevelure, Charles Baudelaire"},"echec":{"effets":[],"message":"Le Messager des Rêves est pressé et continue son chemin d'une traite sans vous accorder un regard.","poesie":"<p>En réalité, tous les éléments du rêve des Dragons expriment<br>le Draconic : chaque pierre, chaque fleur, chaque goutte d'eau,<br>chaque nuage est porteur d'un message dans la langue des Dragons</p>","reference":"Rêve de Dragon, Denis Gerfaud"},"frequence":{"cite":25,"sanctuaire":25,"plaines":20,"pont":20,"collines":15,"foret":15,"monts":10,"desert":10,"fleuve":5,"lac":5,"marais":2,"gouffre":2,"necropole":0,"desolation":0,"mauvaise":0},"description":""},"effects":[],"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.rencontres.Ffk9pio1qy4Z28Lc"}},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.1.0","coreVersion":"10.288","createdTime":1667846036337,"modifiedTime":1668036933994,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"},"_id":"0MwHtPpFV2lTeCtt","folder":null,"sort":0,"ownership":{"default":0,"Hp9ImM4o9YRTSdfu":3}}
|
||||
{"name":"Briseur de Rêve","type":"rencontre","img":"systems/foundryvtt-reve-de-dragon/icons/tete_dragon.webp","system":{"genre":"m","formule":"2d6","refoulement":1,"presentCite":false,"mauvaiseRencontre":false,"ordreTri":6,"force":0,"coord":"","date":"","heure":"","succes":{"effets":[],"message":"Le {{{rencontre.name}}} tente vainement de vous déconcentrer, avant de fuir sans demander son reste.","poesie":"<p>La légende affirme que ce sont les Gnomes qui furent les premiers haut-rêvants. En observant les pierres précieuses, les gemmes qui sont les larmes de joie des Dragons, ils parvinrent à en comprendre la langue. Et l'ayant comprise, ils purent s'en servir pour influencer le cours du rêve.</p>","reference":"Rêve de Dragon, Denis Gerfaud"},"echec":{"effets":["rompu"],"message":"Le {{{rencontre.name}}} vous déconcentre au point de briser votre demi-rêve.","poesie":"<p>Quand le rêve se brise,<br>Dans la plainte du jour,<br>Ma mémoire devient grise<br>Et sombre, tour à tour,<br>Dans le puits du silence<br>Et de la solitude ;<br>Elle reprend son errance<br>Parmi la multitude.</p>","reference":"Quand le rêve se brise, Cypora Sebagh"},"frequence":{"cite":5,"sanctuaire":5,"plaines":7,"pont":7,"collines":13,"foret":13,"monts":16,"desert":16,"fleuve":16,"lac":16,"marais":21,"gouffre":21,"necropole":20,"desolation":20,"mauvaise":0},"description":""},"effects":[],"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.rencontres.dvEiIk0HFGsvyb5F"}},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.1.0","coreVersion":"10.288","createdTime":1667846036340,"modifiedTime":1668036933993,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"},"_id":"3e6jIvyy1e7OzYcB","folder":null,"sort":0,"ownership":{"default":0,"Hp9ImM4o9YRTSdfu":3}}
|
||||
{"name":"Reflet d'ancien Rêve","type":"rencontre","img":"systems/foundryvtt-reve-de-dragon/icons/tete_dragon.webp","system":{"genre":"m","formule":"2d6","refoulement":1,"presentCite":false,"mauvaiseRencontre":false,"ordreTri":7,"force":"0","coord":"","date":"","heure":"","succes":{"effets":[],"message":"Le {{{rencontre.name}}} s'estompe dans l'oubli.","poesie":"<p>Les formes s'effaçaient et n'étaient plus qu'un rêve,<br>Une ébauche lente à venir<br>Sur la toile oubliée, et que l'artiste achève<br>Seulement par le souvenir.</p>","reference":"Une charogne, Charles Baudelaire"},"echec":{"effets":["persistant"],"message":"Vous êtes submergé par un {{{rencontre.name}}}, les souvenirs vous retiennent tant qu'il ne sera pas vaincu!","poesie":"<p>Longtemps ! toujours ! ma main dans ta crinière lourde<br>Sèmera le rubis, la perle et le saphir,<br>Afin qu'à mon désir tu ne sois jamais sourde !<br>N'es-tu pas l'oasis où je rêve, et la gourde<br>Où je hume à longs traits le vin du souvenir</p>","reference":"La chevelure, Charles Baudelaire"},"frequence":{"cite":5,"sanctuaire":5,"plaines":6,"pont":6,"collines":6,"foret":6,"monts":10,"desert":10,"fleuve":14,"lac":14,"marais":15,"gouffre":15,"necropole":15,"desolation":15,"mauvaise":0},"description":""},"effects":[],"ownership":{"default":0,"Hp9ImM4o9YRTSdfu":3},"flags":{"core":{"sourceId":"Item.drXUmMGrrY9jyJPp"}},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.1.0","coreVersion":"10.288","createdTime":1667773074055,"modifiedTime":1668036933995,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"},"folder":null,"sort":0,"_id":"5IEjrkpQ2YNFiUP4"}
|
||||
{"name":"Tourbillon noir","type":"rencontre","img":"systems/foundryvtt-reve-de-dragon/icons/tete_dragon.webp","system":{"genre":"m","formule":"2d8","refoulement":1,"presentCite":false,"mauvaiseRencontre":false,"ordreTri":9,"force":0,"coord":"","date":"","heure":"","succes":{"effets":[],"message":"Le {{{rencontre.name}}} orageux vous enveloppe de fureur et d'éclairs, vous tenez bon face à la tempête qui s'éloigne sans vous éloigner de votre chemin.","poesie":"<p>Car le Second Âge fut bel et bien celui des Magiciens. Durant cette période, les Gnomes s'enfoncèrent profondément sous les montagnes et la magie passa aux mains des Humains qui en usèrent et abusèrent, se croyant devenus les maîtres du monde</p>","reference":"Rêve de Dragon, Denis Gerfaud"},"echec":{"effets":["reve-1","reve-1","aleatoire","aleatoire","persistant"],"message":"Le {{{rencontre.name}}} furieux vous secoue tel un fichu de paille malmené par les vents, et vous emporte dans la tourmente.","poesie":"<p>Elle aurait pas cru sans le voir<br>Que la couleur du désespoir<br>Là-bas aussi ce fût le noir.</p>","reference":"Lily, Pierre Perret"},"frequence":{"cite":3,"sanctuaire":3,"plaines":4,"pont":4,"collines":4,"foret":4,"monts":5,"desert":5,"fleuve":8,"lac":8,"marais":11,"gouffre":11,"necropole":17,"desolation":17,"mauvaise":0},"description":""},"effects":[],"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.rencontres.81b2cjAzl9hfK7Zt"}},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.1.0","coreVersion":"10.288","createdTime":1667846036336,"modifiedTime":1668036933995,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"},"_id":"89NtInRn4uWArlct","folder":null,"sort":0,"ownership":{"default":0,"Hp9ImM4o9YRTSdfu":3}}
|
||||
{"name":"Reflet d'ancien Rêve","type":"rencontre","img":"systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp","system":{"genre":"m","formule":"2d6+4","refoulement":2,"presentCite":false,"mauvaiseRencontre":true,"ordreTri":3,"force":0,"coord":"","date":"","heure":"","succes":{"effets":[],"message":"Le {{{rencontre.name}}} s'estompe dans l'oubli.","poesie":"<p>Les formes s'effaçaient et n'étaient plus qu'un rêve,<br>Une ébauche lente à venir<br>Sur la toile oubliée, et que l'artiste achève<br>Seulement par le souvenir.</p>","reference":"Une charogne, Charles Baudelaire"},"echec":{"effets":["persistant"],"message":"Vous êtes submergé par un {{{rencontre.name}}}, les souvenirs vous retiennent tant qu'il ne sera pas vaincu!","poesie":"<p>Longtemps ! toujours ! ma main dans ta crinière lourde<br>Sèmera le rubis, la perle et le saphir,<br>Afin qu'à mon désir tu ne sois jamais sourde !<br>N'es-tu pas l'oasis où je rêve, et la gourde<br>Où je hume à longs traits le vin du souvenir</p>","reference":"La chevelure, Charles Baudelaire"},"frequence":{"cite":5,"sanctuaire":5,"plaines":6,"pont":6,"collines":6,"foret":6,"monts":10,"desert":10,"fleuve":14,"lac":14,"marais":15,"gouffre":15,"necropole":15,"desolation":15,"mauvaise":1},"description":""},"effects":[],"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.rencontres.MB2qOlTsEUTQkRVL"}},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.8","coreVersion":"10.290","createdTime":1667846036338,"modifiedTime":1669471919738,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"},"_id":"U6WoTkHRwC4DicuZ","folder":null,"sort":0,"ownership":{"default":0,"Hp9ImM4o9YRTSdfu":3}}
|
||||
{"name":"Changeur de Rêve","type":"rencontre","img":"systems/foundryvtt-reve-de-dragon/icons/tete_dragon.webp","system":{"genre":"m","formule":"2d6","refoulement":1,"presentCite":false,"mauvaiseRencontre":false,"ordreTri":5,"force":0,"coord":"","date":"","heure":"","succes":{"effets":["teleport"],"message":"Le {{{rencontre.name}}} vaincu accepte de vous déplacer sur une autre case {{{caseTmr-type tmr.coord}}} de votre choix en échange de sa liberté.","poesie":"<p>Allez, que le caprice emporte<br>Chaque âme selon son désir,<br>Et que, close après vous, la porte<br>Ne se rouvre plus qu'au plaisir.</p>","reference":"Caligula - IIIème chant, Gérard de Nerval"},"echec":{"effets":["teleport-aleatoire"],"message":"Le {{{rencontre.name}}} vous embobine avec des promesses, et vous transporte sur une autre case {{{caseTmr-type tmr.coord}}} sans attendre votre avis.","poesie":"<p>Les sages ont encore coutume de dire : <br>« Mais comment les Dragons peuvent-ils être influencés par une créature qui, tout bien considéré, n'existe pas vraiment pour eux, qui n'est que le fantasme de leur activité nocturne ? »</p>","reference":"Rêve de Dragon, Denis Gerfaud"},"frequence":{"cite":10,"sanctuaire":10,"plaines":15,"pont":15,"collines":15,"foret":15,"monts":15,"desert":15,"fleuve":12,"lac":12,"marais":10,"gouffre":10,"necropole":10,"desolation":10,"mauvaise":0},"description":""},"effects":[],"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.rencontres.q4uyAZoFPyc4x8XI"}},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.1.0","coreVersion":"10.288","createdTime":1667846036340,"modifiedTime":1668036933994,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"},"_id":"WeCnQirDR1r3TUFw","folder":null,"sort":0,"ownership":{"default":0,"Hp9ImM4o9YRTSdfu":3}}
|
||||
{"name":"Rêve de Dragon","type":"rencontre","img":"systems/foundryvtt-reve-de-dragon/styles/img/rdd_pause.webp","system":{"genre":"m","formule":"1dr+7","refoulement":2,"presentCite":false,"mauvaiseRencontre":false,"ordreTri":10,"force":0,"coord":"","date":"","heure":"","succes":{"effets":["reve+f","part+tete","part+xp","seuil"],"message":"A tout seigneur, tout honneur, vous faites face à un {{{rencontre.name}}}. Vous le maîtrisez et gagnez ses {{rencontre.system.force}} points de rêve.","poesie":"<p>Le monde est Rêve de Dragons, mais nous ne savons <br>Ni leur apparence ni qui sont les dragons. <br>En dépit de l'iconographie qui les clame <br>Immenses créatures ailées crachant des flammes</p>","reference":"Rêve de Dragon, Denis Gerfaud"},"echec":{"effets":["echec-queue"],"message":"A tout seigneur, tout honneur, vous faites face à un {{{rencontre.name}}}. La rencontre tourne au cauchemar, dans la lutte épique, vous subissez {{#if rolled.isETotal}}deux queues{{else}}une queue{{/if}} de dragon!","poesie":"<p>Je suis le Ténébreux, – le Veuf, – l'Inconsolé, <br>Le Prince d'Aquitaine à la Tour abolie : <br>Ma seule Etoile est morte, – et mon luth constellé <br>Porte le Soleil noir de la Mélancolie.</p>","reference":"El Desdichado, Gérard de Nerval"},"frequence":{"cite":3,"sanctuaire":3,"plaines":3,"pont":3,"collines":3,"foret":3,"monts":3,"desert":3,"fleuve":3,"lac":3,"marais":3,"gouffre":3,"necropole":3,"desolation":3,"mauvaise":0},"description":""},"effects":[],"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.rencontres.Hw40Q8jS9wmukgU4"}},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.1.0","coreVersion":"10.288","createdTime":1667846036338,"modifiedTime":1668036933995,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"},"_id":"dWKuUc29ysrlPZFg","folder":null,"sort":0,"ownership":{"default":0,"Hp9ImM4o9YRTSdfu":3}}
|
||||
{"name":"Passeur fou","type":"rencontre","img":"systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp","system":{"genre":"m","formule":"2d8","refoulement":2,"presentCite":false,"mauvaiseRencontre":true,"ordreTri":26,"force":0,"coord":"","date":"","heure":"","succes":{"effets":[],"message":"Le Passeur fou tente vainement de découvrir où vous avez caché vos réserves. Vous le chassez, et en déroute il part harceler un autre voyageur du rêve.","poesie":"<p>Certain Fou poursuivait à coups de pierre un Sage.<br>Le Sage se retourne et lui dit : Mon ami,<br>C'est fort bien fait à toi ; reçois cet écu-ci :<br>Tu fatigues assez pour gagner davantage.</p>","reference":"Un Fou et un Sage, Jean de La Fontaine"},"echec":{"effets":["sort-aleatoire"],"message":"{{#if sortReserve}}Le Passeur fou dérobe la clé de vos sorts. Vous vous saisissez de lui, mais dans un nuage violet, il vous emporte {{{newTMR.label}}} déclencher votre sort en réserve de {{sortReserve.name}}.{{else}}Le Passeur fou tente de vous dérober la clé de vos sorts. Ne la trouvant pas, il déclenche un nuage violet et vous emporte en {{{newTMR.label}}}.{{/if}}","poesie":"<p>Je la voyais passer de ma demeure,<br>Et c'était tout.<br>Mais à présent je m'ennuie à toute heure,<br>Plein de dégoût,<br>Rêveur oisif, l'âme dans la campagne,<br>La dague au clou ... –<br>Le vent qui vient à travers la montagne<br>M'a rendu fou !</p>","reference":"Guitare, Victor Hugo"},"frequence":{"cite":0,"sanctuaire":0,"plaines":0,"pont":0,"collines":0,"foret":0,"monts":0,"desert":0,"fleuve":0,"lac":0,"marais":0,"gouffre":0,"necropole":0,"desolation":0,"mauvaise":1},"description":""},"effects":[],"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.rencontres.HkYBb3Ls4W15tKwo"}},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.1.0","coreVersion":"10.288","createdTime":1667846036338,"modifiedTime":1668036933995,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"},"_id":"eVxv2FMRZOo7aTWB","folder":null,"sort":0,"ownership":{"default":0,"Hp9ImM4o9YRTSdfu":3}}
|
||||
{"name":"Mangeur de Rêve","type":"rencontre","img":"systems/foundryvtt-reve-de-dragon/icons/tete_dragon.webp","system":{"genre":"m","formule":"1d6","refoulement":1,"presentCite":false,"mauvaiseRencontre":false,"ordreTri":4,"force":0,"coord":"","date":"","heure":"","succes":{"effets":[],"message":"Le {{{rencontre.name}}} claque de sa machoire dans le vide avant de fuir.","poesie":"<p>Rois ! la bure est souvent jalouse du velours.<br>Le peuple a froid l'hiver, le peuple a faim toujours.<br>Rendez-lui son sort plus facile.<br>Le peuple souvent porte un bien rude collier.<br>Ouvrez l'école aux fils, aux pères l'atelier,<br>À tous vos bras, auguste asile !</p>","reference":"Conseil, Victor Hugo"},"echec":{"effets":["reve-f"],"message":"Le {{{rencontre.name}}} croque votre Rêve ! Il emporte {{rencontre.system.force}} de vos points de rêve actuels","poesie":"<div>\n<div>Suis-je Amour ou Phébus ?... Lusignan ou Biron ?</div>\n<div>Mon front est rouge encor du baiser de la Reine ;</div>\n<div>J'ai rêvé dans la Grotte où nage la sirène...</div>\n</div>","reference":"El Desdichado, Gérard de Nerval"},"frequence":{"cite":5,"sanctuaire":5,"plaines":5,"pont":5,"collines":12,"foret":12,"monts":18,"desert":18,"fleuve":24,"lac":24,"marais":24,"gouffre":24,"necropole":20,"desolation":20,"mauvaise":1},"description":""},"effects":[],"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.rencontres.3SA5An6kPlpcDEIj"}},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.1.0","coreVersion":"10.288","createdTime":1667846036336,"modifiedTime":1668036933994,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"},"_id":"fd89RWxlO8BF1FFJ","folder":null,"sort":0,"ownership":{"default":0,"Hp9ImM4o9YRTSdfu":3}}
|
||||
{"name":"Tourbillon noir","type":"rencontre","img":"systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp","system":{"genre":"m","formule":"2d8+4","refoulement":2,"presentCite":false,"mauvaiseRencontre":true,"ordreTri":25,"force":0,"coord":"","date":"","heure":"","succes":{"effets":[],"message":"Le {{{rencontre.name}}} orageux vous enveloppe de fureur et d'éclairs, vous tenez bon face à la tempête qui s'éloigne sans vous éloigner de votre chemin.","poesie":"<p>Car le Second Âge fut bel et bien celui des Magiciens. Durant cette période, les Gnomes s'enfoncèrent profondément sous les montagnes et la magie passa aux mains des Humains qui en usèrent et abusèrent, se croyant devenus les maîtres du monde</p>","reference":"Rêve de Dragon, Denis Gerfaud"},"echec":{"effets":["reve-1","reve-1","aleatoire","aleatoire","persistant"],"message":"Le {{{rencontre.name}}} furieux vous secoue tel un fichu de paille malmené par les vents, et vous emporte dans la tourmente.","poesie":"<p>Elle aurait pas cru sans le voir<br>Que la couleur du désespoir<br>Là-bas aussi ce fût le noir.</p>","reference":"Lily, Pierre Perret"},"frequence":{"cite":3,"sanctuaire":3,"plaines":4,"pont":4,"collines":4,"foret":4,"monts":5,"desert":5,"fleuve":8,"lac":8,"marais":11,"gouffre":11,"necropole":17,"desolation":17,"mauvaise":1},"description":""},"effects":[],"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.rencontres.D0gbC3plAesQx3uq"}},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.1.0","coreVersion":"10.288","createdTime":1667846036336,"modifiedTime":1668036933995,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"},"_id":"hmeuLiLh5nkuQ4eD","folder":null,"sort":0,"ownership":{"default":0,"Hp9ImM4o9YRTSdfu":3}}
|
||||
{"name":"Fleur des rêves","type":"rencontre","img":"systems/foundryvtt-reve-de-dragon/icons/tete_dragon.webp","system":{"genre":"f","formule":"1d6","refoulement":0,"presentCite":true,"mauvaiseRencontre":false,"ordreTri":3,"force":"0","coord":"","date":"","heure":"","succes":{"effets":["reve+f"],"message":"Vous cueillez la {{{rencontre.name}}}, son parfum vous apporte {{rencontre.system.force}} points de Rêve.","poesie":"<p>Et qui sait si les fleurs nouvelles que je rêve<br>Trouveront dans ce sol lavé comme une grève<br>Le mystique aliment qui ferait leur vigueur ?</p>","reference":"L'Ennemi, Charles Baudelaire","effet":["reve+f"]},"echec":{"effets":[],"message":"La {{{rencontre.name}}} se fane et disparaît entre vos doigts.","poesie":"<p>Et le ciel regardait la carcasse superbe<br>Comme une fleur s'épanouir.<br>La puanteur était si forte, que sur l'herbe<br>Vous crûtes vous évanouir.</p>","reference":"Une charogne, Charles Baudelaire"},"frequence":{"cite":15,"sanctuaire":15,"plaines":15,"pont":15,"collines":12,"foret":12,"monts":6,"desert":6,"fleuve":3,"lac":3,"marais":1,"gouffre":1,"necropole":0,"desolation":0,"mauvaise":0},"description":"","onSucces":{"effets":[],"message":"","poesie":"","reference":""},"onEchec":{"effets":[],"message":"","poesie":"","reference":""},"descriptionmj":"","code":"","onSuccess":{"effets":[],"message":"","poesie":"","reference":""}},"effects":[],"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.rencontres.2ywduc2BHGpVvUbz"}},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.1.0","coreVersion":"10.288","createdTime":1667846036335,"modifiedTime":1668036933994,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"},"_id":"jtJk1ptJXsdsGZHA","folder":null,"sort":0,"ownership":{"default":0,"Hp9ImM4o9YRTSdfu":3}}
|
||||
{"name":"Tourbillon rouge","type":"rencontre","img":"systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp","system":{"genre":"m","formule":"2d8","refoulement":3,"presentCite":false,"mauvaiseRencontre":true,"ordreTri":27,"force":0,"coord":"","date":"","heure":"","succes":{"effets":[],"message":"Le {{{rencontre.name}}} s'abat avec violence mais vous êtes plus rapide et parvenez à lui échapper.","poesie":"<p>Qu'est-ce de votre vie ? un tourbillon rouant<br>De fumière à flot gris, parmi l'air se jouant,<br>Qui passe plus soudain que foudre meurtrière.</p>","reference":"Qu'est-ce de votre vie ? une bouteille molle, Jean-Baptiste Chassignet"},"echec":{"effets":["aleatoire","aleatoire","aleatoire","aleatoire","reve-1","reve-1","vie-1","persistant"],"message":"Le {{{rencontre.name}}} vous frappe de milliers de morsure et vous malmène à travers les terres médianes.","poesie":"<p>Cris de l'enfer! voix qui hurle et qui pleure !<br>L'horrible essaim, poussé par l'aquilon,<br>Sans doute, ô ciel ! s'abat sur ma demeure.<br>Le mur fléchit sous le noir bataillon.<br>La maison crie et chancelle penchée,<br>Et l'on dirait que, du sol arrachée,<br>Ainsi qu'il chasse une feuille séchée,<br>Le vent la roule avec leur tourbillon !</p>","reference":"Les Djinns, poème Victor Hugo"},"frequence":{"cite":0,"sanctuaire":0,"plaines":0,"pont":0,"collines":0,"foret":0,"monts":0,"desert":0,"fleuve":0,"lac":0,"marais":0,"gouffre":0,"necropole":0,"desolation":0,"mauvaise":1},"description":""},"effects":[],"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.rencontres.WiyUvZX4oTAd82s3"}},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.1.0","coreVersion":"10.288","createdTime":1667846036339,"modifiedTime":1668036933996,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"},"_id":"nD7p8ROloR6ElTpW","folder":null,"sort":0,"ownership":{"default":0,"Hp9ImM4o9YRTSdfu":3}}
|
||||
{"name":"Tourbillon blanc","type":"rencontre","img":"systems/foundryvtt-reve-de-dragon/icons/tete_dragon.webp","system":{"genre":"m","formule":"2d6","refoulement":1,"presentCite":false,"mauvaiseRencontre":false,"ordreTri":8,"force":"0","coord":"","date":"","heure":"","succes":{"effets":[],"message":"Le {{{rencontre.name}}} souleve une poussière blanche, vous tenez bon, et il tourbillonne en s'éloignant.","poesie":"<p>Le Premier Âge fut appelé l'Âge des Dragons. Ce fut le commencement<br>des temps, le commencement des rêves. Durant cette période plus mythique<br>que réellement historique, les Dragons aimaient à se rêver eux-mêmes.</p>","reference":"Rêve de Dragon, Denis Gerfaud"},"echec":{"effets":["reve-1","aleatoire","persistant"],"message":"Le souffle du {{{rencontre.name}}} vous déstabilise et vous emmène dans un nuage de poussière.","poesie":"<p>C'est l'essaim des Djinns qui passe,<br>Et tourbillonne en sifflant !<br>Les ifs, que leur vol fracasse,<br>Craquent comme un pin brûlant.</p>","reference":"Les Djinns, Victor Hugo"},"frequence":{"cite":4,"sanctuaire":4,"plaines":5,"pont":5,"collines":5,"foret":5,"monts":7,"desert":7,"fleuve":10,"lac":10,"marais":11,"gouffre":11,"necropole":15,"desolation":15,"mauvaise":0},"description":""},"effects":[],"ownership":{"default":0,"Hp9ImM4o9YRTSdfu":3},"flags":{"core":{"sourceId":"Item.GIG8SbYrl60p50u3"}},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.1.0","coreVersion":"10.288","createdTime":1667773090153,"modifiedTime":1668036933995,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"},"folder":null,"sort":0,"_id":"ph6qZi1yDgh68Y5l"}
|
||||
{"name":"Mangeur de Rêve","type":"rencontre","img":"systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp","system":{"genre":"m","formule":"1d6","refoulement":2,"presentCite":false,"mauvaiseRencontre":true,"ordreTri":21,"force":0,"coord":"","date":"","heure":"","succes":{"effets":[],"message":"Le {{{rencontre.name}}} claque de sa machoire dans le vide avant de fuir.","poesie":"<p>Rois ! la bure est souvent jalouse du velours.<br>Le peuple a froid l'hiver, le peuple a faim toujours.<br>Rendez-lui son sort plus facile.<br>Le peuple souvent porte un bien rude collier.<br>Ouvrez l'école aux fils, aux pères l'atelier,<br>À tous vos bras, auguste asile !</p>","reference":"Conseil, Victor Hugo"},"echec":{"effets":["reve-f"],"message":"Le {{{rencontre.name}}} croque votre Rêve ! Il emporte {{rencontre.system.force}} de vos points de rêve actuels","poesie":"<div>\n<div>Suis-je Amour ou Phébus ?... Lusignan ou Biron ?</div>\n<div>Mon front est rouge encor du baiser de la Reine ;</div>\n<div>J'ai rêvé dans la Grotte où nage la sirène...</div>\n</div>","reference":"El Desdichado, Gérard de Nerval"},"frequence":{"cite":5,"sanctuaire":5,"plaines":5,"pont":5,"collines":12,"foret":12,"monts":18,"desert":18,"fleuve":24,"lac":24,"marais":24,"gouffre":24,"necropole":20,"desolation":20,"mauvaise":1},"description":""},"effects":[],"flags":{"core":{"sourceId":"Item.3SA5An6kPlpcDEIj"}},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.1.0","coreVersion":"10.288","createdTime":1667846036340,"modifiedTime":1668036933994,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"},"_id":"uhdiBoim26qSmVJ7","folder":null,"sort":0,"ownership":{"default":0,"Hp9ImM4o9YRTSdfu":3}}
|
||||
{"name":"Mangeur de Rêve","type":"rencontre","img":"systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp","system":{"genre":"m","formule":"2d6","refoulement":2,"presentCite":false,"mauvaiseRencontre":true,"ordreTri":22,"force":0,"coord":"","date":"","heure":"","succes":{"effets":[],"message":"Le {{{rencontre.name}}} claque de sa machoire dans le vide avant de fuir.","poesie":"<p>Rois ! la bure est souvent jalouse du velours.<br>Le peuple a froid l'hiver, le peuple a faim toujours.<br>Rendez-lui son sort plus facile.<br>Le peuple souvent porte un bien rude collier.<br>Ouvrez l'école aux fils, aux pères l'atelier,<br>À tous vos bras, auguste asile !</p>","reference":"Conseil, Victor Hugo"},"echec":{"effets":["reve-f"],"message":"Le {{{rencontre.name}}} croque votre Rêve ! Il emporte {{rencontre.system.force}} de vos points de rêve actuels","poesie":"<div>\n<div>Suis-je Amour ou Phébus ?... Lusignan ou Biron ?</div>\n<div>Mon front est rouge encor du baiser de la Reine ;</div>\n<div>J'ai rêvé dans la Grotte où nage la sirène...</div>\n</div>","reference":"El Desdichado, Gérard de Nerval"},"frequence":{"cite":5,"sanctuaire":5,"plaines":5,"pont":5,"collines":12,"foret":12,"monts":18,"desert":18,"fleuve":24,"lac":24,"marais":24,"gouffre":24,"necropole":20,"desolation":20,"mauvaise":1},"description":""},"effects":[],"flags":{"core":{"sourceId":"Item.3SA5An6kPlpcDEIj"}},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.1.0","coreVersion":"10.288","createdTime":1667846036340,"modifiedTime":1668036933994,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"},"_id":"yHm1Rqa8CP5qhg69","folder":null,"sort":0,"ownership":{"default":0,"Hp9ImM4o9YRTSdfu":3}}
|
||||
{"name":"Tourbillon blanc","type":"rencontre","img":"systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp","system":{"genre":"m","formule":"2d6+4","refoulement":2,"presentCite":false,"mauvaiseRencontre":true,"ordreTri":24,"force":0,"coord":"","date":"","heure":"","succes":{"effets":[],"message":"Le {{{rencontre.name}}} souleve une poussière blanche, vous tenez bon, et il tourbillonne en s'éloignant.","poesie":"<p>Le Premier Âge fut appelé l'Âge des Dragons. Ce fut le commencement<br>des temps, le commencement des rêves. Durant cette période plus mythique<br>que réellement historique, les Dragons aimaient à se rêver eux-mêmes.</p>","reference":"Rêve de Dragon, Denis Gerfaud"},"echec":{"effets":["reve-1","aleatoire","persistant"],"message":"Le souffle du {{{rencontre.name}}} vous déstabilise et vous emmène dans un nuage de poussière.","poesie":"<p>C'est l'essaim des Djinns qui passe,<br>Et tourbillonne en sifflant !<br>Les ifs, que leur vol fracasse,<br>Craquent comme un pin brûlant.</p>","reference":"Les Djinns, Victor Hugo"},"frequence":{"cite":4,"sanctuaire":4,"plaines":5,"pont":5,"collines":5,"foret":5,"monts":7,"desert":7,"fleuve":10,"lac":10,"marais":11,"gouffre":11,"necropole":15,"desolation":15,"mauvaise":1},"description":""},"effects":[],"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.rencontres.GIG8SbYrl60p50u3"}},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.1.0","coreVersion":"10.288","createdTime":1667846036337,"modifiedTime":1668036933995,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"},"_id":"yXZW5cDrGoZxD9lK","folder":null,"sort":0,"ownership":{"default":0,"Hp9ImM4o9YRTSdfu":3}}
|
||||
|
@ -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":"<p>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.</p>","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":"<p>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.</p>","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":"<p>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.</p>\n<p>Le haut-rêvant doit se trouver dans la case <em>spécifique </em>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.</p>\n<p>Pour 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.</p>\n<p>Avant 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.</p>\n<p>Pour 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.</p>","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":"<p>Les rituels de Détection d’Aura peuvent indifféremment être accomplis par n’importe laquelle des quatre voies.</p>\n<p>Toutes 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.</p>\n<p>L’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.</p>","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":"<p>Les rituels de Détection d’Aura peuvent indifféremment être accomplis par n’importe laquelle des quatre voies.</p>\n<p>Toutes 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.</p>\n<p>L’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.</p>","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":"<p>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 <em>en plus </em>de la protection physique qu'il peut avoir, laquelle ne peut être - rappelons-le - que d'un maximum de 2 points.</p>\n<p>Une 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.</p>\n<p><em>Soit 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).</em></p>\n<p>Chaque 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.</p>\n<p> </p>","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":"<p>Les rituels de Lecture d’Aura peuvent indifféremment être accomplis par n’importe laquelle des quatre voies.</p>\n<p>Ce 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.</p>\n<p>Lecture 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.</p>\n<p>Lecture 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.</p>","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":"<p>Les rituels de Lecture d’Aura peuvent indifféremment être accomplis par n’importe laquelle des quatre voies.</p>\n<p>Ce 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.</p>\n<p>Lecture 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.</p>\n<p>Lecture 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.</p>","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":"<p>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 <em>en plus </em>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.</p>\n<p>Une 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.</p>\n<p><em>Soit 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).</em></p>\n<p>Chaque 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.</p>\n<p> </p>","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":"<p>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\".</p>\n<p>La 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. <em>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.</em> 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.</p>\n<p>Un 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. <em>Note </em> : les points dépensés pour la maîtrise ne <em>vont pas</em> dans le Puis de rêve, sils ont perdus.</p>","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":"<p>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 <em>magie impossible</em>.</p>","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"}}
|
||||
|
File diff suppressed because one or more lines are too long
@ -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":"<p>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 <em>Dague de meurtre</em>. 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 : <em>Uhn Telh</em> (nom d'un personnage unique), <em>le roi de Parissy</em> (n'importe quel personnage occupant successivement cette fonction), <em>une fille blonde</em> (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.</p>\n<p>Le 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.</p>","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":"<p>INVOCATION D'UN DÉSESPOIR (Désolation) R-7 r7</p>\n<p>INVOCATION D'UNE HAINE (Marais) R-7 r7</p>\n<p>INVOCATION D'UNE PEUR (Gouffre) R-7 r7</p>\n<p>Ayant 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).</p>\n<p> </p>","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":"<p>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é.</p>","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":"<p>Les rituels de Lecture d’Aura peuvent indifféremment être accomplis par n’importe laquelle des quatre voies.</p>\n<p>Ce 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.</p>\n<p>Lecture 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.</p>\n<p>Lecture 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.</p>","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":"<p>Les rituels de Lecture d’Aura peuvent indifféremment être accomplis par n’importe laquelle des quatre voies.</p>\n<p>Ce 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.</p>\n<p>Lecture 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.</p>\n<p>Lecture 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.</p>","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":"<p>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.</p>","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":"<p>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 :<em> ne fais pas</em>. 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. <em>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.</em> 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é.</p>","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":"<p>Les rituels de Détection d’Aura peuvent indifféremment être accomplis par n’importe laquelle des quatre voies.</p>\n<p>Toutes 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.</p>\n<p>L’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.</p>","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":"<p>Les rituels de Détection d’Aura peuvent indifféremment être accomplis par n’importe laquelle des quatre voies.</p>\n<p>Toutes 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.</p>\n<p>L’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.</p>","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":"<p>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.</p>","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":"<p>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.</p>\n<p>Ses 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.</p>\n<p>La 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.</p>\n<p><em>Toute réussite. </em>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.</p>\n<p>Echec 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.</p>\n<p>Ech.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.</p>\n<p>Les 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.</p>","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":"<p>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é.</p>","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"}}
|
||||
|
File diff suppressed because one or more lines are too long
@ -160,6 +160,20 @@ i:is(.fas, .far) {
|
||||
width: fit-content;
|
||||
}
|
||||
|
||||
.system-foundryvtt-reve-de-dragon .sheet-header div.tmr-buttons {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
flex: 0;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.system-foundryvtt-reve-de-dragon .sheet-header div.tmr-buttons img.button-img {
|
||||
max-width: 32px;
|
||||
padding: 0;
|
||||
margin-top: -8px;
|
||||
margin-bottom: -8px;
|
||||
}
|
||||
|
||||
.system-foundryvtt-reve-de-dragon .sheet-header :is(.header-compteurs,.header-etats,.profile-img){
|
||||
padding: 0 3%;
|
||||
}
|
||||
@ -585,7 +599,7 @@ input:is(.blessure-premiers_soins, .blessure-soins_complets) {
|
||||
.editor {
|
||||
border: 2;
|
||||
height: fit-content;
|
||||
min-height: 8rem;
|
||||
min-height: 5rem;
|
||||
padding: 0 3px;
|
||||
}
|
||||
|
||||
@ -597,7 +611,7 @@ input:is(.blessure-premiers_soins, .blessure-soins_complets) {
|
||||
|
||||
.small-editor {
|
||||
border: 2;
|
||||
min-height: 4rem;
|
||||
min-height: 2rem;
|
||||
padding: 0 3px;
|
||||
}
|
||||
|
||||
@ -757,11 +771,41 @@ div.placeholder-resolution span.table-proba-reussite{
|
||||
input[type="date"],
|
||||
input[type="time"]) {
|
||||
color: rgba(255, 255, 255, 0.75);
|
||||
background: rgba(255, 255, 255, 0.05);
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
border: 0 none;
|
||||
margin-bottom: 0.2rem;
|
||||
}
|
||||
|
||||
input[type="number"] {
|
||||
text-align: right;
|
||||
padding-right: 0.5rem;
|
||||
max-width: 7rem;
|
||||
}
|
||||
|
||||
select:is(.number-x,.number-x2,.number-x3,.number-x4,.number-x5) {
|
||||
padding-right: 0.2rem;
|
||||
text-align: center;
|
||||
}
|
||||
input:is(.number,.number-x,.number-x2,.number-x3,.number-x4,.number-x5) {
|
||||
padding-right: 0.2rem;
|
||||
text-align: right;
|
||||
}
|
||||
:is(input,select).number-x {
|
||||
max-width: 1.4rem;
|
||||
}
|
||||
:is(input,select).number-x2 {
|
||||
max-width: 2.4rem;
|
||||
}
|
||||
:is(input,select).number-x3 {
|
||||
max-width: 3.4rem;
|
||||
}
|
||||
:is(input,select).number-x4 {
|
||||
max-width: 4.4rem;
|
||||
}
|
||||
:is(input,select).number-x5 {
|
||||
max-width: 4.4rem;
|
||||
}
|
||||
|
||||
form.rdddialogchrono input[type=datetime-local] {
|
||||
min-width: 20px;
|
||||
padding: 0;
|
||||
@ -804,7 +848,21 @@ section.sheet-body:after {
|
||||
display: block;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
a.rdd-world-content-link i {
|
||||
color: var(--color-text-dark-inactive);
|
||||
margin-right: 0.25em;
|
||||
}
|
||||
a.rdd-world-content-link {
|
||||
background: hsla(280, 50%, 50%, 0.1);
|
||||
padding: 1px 4px;
|
||||
border: 1px solid var(--color-border-dark-tertiary);
|
||||
border-radius: 2px;
|
||||
white-space: nowrap;
|
||||
word-break: break-all;
|
||||
}
|
||||
a.content-link {
|
||||
background: hsla(45, 100%, 80%, 0.2);
|
||||
}
|
||||
|
||||
li label.compteur {
|
||||
display: inline-block;
|
||||
|
13
system.json
13
system.json
@ -1,8 +1,8 @@
|
||||
{
|
||||
"id": "foundryvtt-reve-de-dragon",
|
||||
"title": "Rêve de Dragon",
|
||||
"version": "10.3.14",
|
||||
"download": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/archive/foundryvtt-reve-de-dragon-10.3.14.zip",
|
||||
"version": "10.4.5",
|
||||
"download": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/archive/foundryvtt-reve-de-dragon-10.4.5.zip",
|
||||
"manifest": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/raw/v10/system.json",
|
||||
"compatibility": {
|
||||
"minimum": "10",
|
||||
@ -161,6 +161,15 @@
|
||||
"private": false,
|
||||
"flags": {}
|
||||
},
|
||||
{
|
||||
"name": "macros",
|
||||
"label": "Macros Rêve de Dragon",
|
||||
"system": "foundryvtt-reve-de-dragon",
|
||||
"path": "packs/macros.db",
|
||||
"type": "Macro",
|
||||
"private": false,
|
||||
"flags": {}
|
||||
},
|
||||
{
|
||||
"name": "queues-de-dragon",
|
||||
"label": "Queues de Dragon",
|
||||
|
@ -97,10 +97,6 @@
|
||||
"etat": {
|
||||
"value": 0,
|
||||
"label": "Etat général"
|
||||
},
|
||||
"surenc": {
|
||||
"value": 0,
|
||||
"label": "Sur-encombrement"
|
||||
}
|
||||
},
|
||||
"attributs": {
|
||||
@ -231,10 +227,6 @@
|
||||
"etat": {
|
||||
"value": 0,
|
||||
"label": "Etat général"
|
||||
},
|
||||
"surenc": {
|
||||
"value": 0,
|
||||
"label": "Sur-encombrement"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -530,10 +522,6 @@
|
||||
"value": 0,
|
||||
"label": "Etat général"
|
||||
},
|
||||
"surenc": {
|
||||
"value": 0,
|
||||
"label": "Sur-encombrement"
|
||||
},
|
||||
"ethylisme": {
|
||||
"value": 1,
|
||||
"label": "Ethylisme",
|
||||
@ -574,6 +562,7 @@
|
||||
"recettealchimique", "musique", "chant", "danse", "jeu", "recettecuisine", "oeuvre",
|
||||
"objet", "arme", "armure", "conteneur", "herbe", "ingredient", "faune", "livre", "potion", "munition",
|
||||
"monnaie", "nourritureboisson", "gemme",
|
||||
"service",
|
||||
"meditation", "rencontre", "queue", "ombre", "souffle", "tete", "casetmr", "signedraconique", "sort", "sortreserve",
|
||||
"nombreastral", "tache", "maladie", "poison", "possession",
|
||||
"tarot", "extraitpoetique"
|
||||
@ -753,6 +742,12 @@
|
||||
"prpermanent": false,
|
||||
"prdate": 0
|
||||
},
|
||||
"service": {
|
||||
"templates": [ "description"],
|
||||
"illimite": false,
|
||||
"items": [],
|
||||
"services": []
|
||||
},
|
||||
"musique": {
|
||||
"templates": [ "description" ],
|
||||
"niveau": "",
|
||||
|
@ -60,6 +60,7 @@
|
||||
|
||||
{{!-- Equipment Tab --}}
|
||||
<div class="tab items" data-group="primary" data-tab="items">
|
||||
{{> "systems/foundryvtt-reve-de-dragon/templates/actor/inventaire-monnaie.html"}}
|
||||
{{> "systems/foundryvtt-reve-de-dragon/templates/actor/inventaire.html"}}
|
||||
</div>
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
{{>'systems/foundryvtt-reve-de-dragon/templates/scripts/autocomplete-script.hbs'}}
|
||||
<form class="{{cssClass}}" autocomplete="off">
|
||||
{{>'systems/foundryvtt-reve-de-dragon/templates/scripts/autocomplete-script.hbs'}}
|
||||
|
||||
{{!-- Sheet Header --}}
|
||||
<header class="sheet-header">
|
||||
@ -13,6 +13,7 @@
|
||||
<img class="profile-img" src="{{img}}" data-edit="img" title="{{name}}" />
|
||||
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/header-compteurs.html"}}
|
||||
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/header-etat.html"}}
|
||||
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/header-hautreve.html"}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -20,86 +21,90 @@
|
||||
|
||||
{{!-- Sheet Tab Navigation --}}
|
||||
<nav class="sheet-tabs tabs" data-group="primary">
|
||||
<a class="item" data-tab="carac">Carac.</a>
|
||||
<a class="item" data-tab="competences">Compétences</a>
|
||||
<a class="item" data-tab="combat">Combat</a>
|
||||
<a class="item" data-tab="connaissances">Savoirs&Taches</a>
|
||||
<a class="item" data-tab="hautreve">Haut-Rêve</a>
|
||||
<a class="item" data-tab="items">Équipement</a>
|
||||
<a class="item" data-tab="description">Description</a>
|
||||
</nav>
|
||||
{{!-- Sheet Body --}}
|
||||
<section class="sheet-body">
|
||||
{{!-- Carac Tab --}}
|
||||
<div class="tab items" data-group="primary" data-tab="carac">
|
||||
<div class="flexrow">
|
||||
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/vue-detaillee.html"}}
|
||||
{{#if options.isObserver}}
|
||||
<a class="item" data-tab="carac">Carac.</a>
|
||||
<a class="item" data-tab="competences">Compétences</a>
|
||||
<a class="item" data-tab="combat">Combat</a>
|
||||
<a class="item" data-tab="connaissances">Savoirs&Taches</a>
|
||||
<a class="item" data-tab="hautreve">Haut-Rêve</a>
|
||||
{{/if}}
|
||||
<a class="item" data-tab="items">Équipement</a>
|
||||
<a class="item" data-tab="description">Description</a>
|
||||
</nav>
|
||||
|
||||
{{!-- Sheet Body --}}
|
||||
<section class="sheet-body">
|
||||
{{#if options.isObserver}}{{!-- Carac Tab --}}
|
||||
<div class="tab items" data-group="primary" data-tab="carac">
|
||||
<div class="flexrow">
|
||||
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/vue-detaillee.html"}}
|
||||
</div>
|
||||
<div class="grid grid-2col">
|
||||
<div class="flex-group-left flexcol">
|
||||
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/carac-main.html"}}
|
||||
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/carac-total.html"}}
|
||||
</div>
|
||||
<div class="grid grid-2col">
|
||||
<div class="flex-group-left flexcol">
|
||||
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/carac-main.html"}}
|
||||
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/carac-total.html"}}
|
||||
</div>
|
||||
<div class="flex-group-left flexcol" >
|
||||
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/carac-derivee.html"}}
|
||||
</div>
|
||||
<div class="flex-group-left flexcol" >
|
||||
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/carac-derivee.html"}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{!-- Compétences Tab --}}
|
||||
<div class="tab competences" data-group="primary" data-tab="competences">
|
||||
<div class="flexrow">
|
||||
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/vue-detaillee.html"}}
|
||||
<span class="flexrow"><a class="show-hide-competences">
|
||||
{{#if options.showCompNiveauBase}}
|
||||
<i class="fa-regular fa-filter-slash"></i> Montrer tout
|
||||
{{else}}
|
||||
<i class="fa-regular fa-filter"></i> Filtrer
|
||||
{{/if}}
|
||||
</a></span>
|
||||
<span>
|
||||
<input class="recherche flex-grow" type="text" value="{{options.recherche.text}}" name="recherche" size="8" data-dtype="String" placeholder=""/>
|
||||
</span>
|
||||
<span>
|
||||
</span>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{#if options.isObserver}}{{!-- Compétences Tab --}}
|
||||
<div class="tab competences" data-group="primary" data-tab="competences">
|
||||
<div class="flexrow">
|
||||
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/vue-detaillee.html"}}
|
||||
<span class="flexrow"><a class="show-hide-competences">
|
||||
{{#if options.showCompNiveauBase}}
|
||||
<i class="fa-regular fa-filter-slash"></i> Montrer tout
|
||||
{{else}}
|
||||
<i class="fa-regular fa-filter"></i> Filtrer
|
||||
{{/if}}
|
||||
</a></span>
|
||||
<span>
|
||||
<input class="recherche flex-grow" type="text" value="{{options.recherche.text}}" name="recherche" size="8" data-dtype="String" placeholder=""/>
|
||||
</span>
|
||||
<span>
|
||||
</span>
|
||||
</div>
|
||||
<div class="grid grid-2col">
|
||||
<div class="competence-column">
|
||||
{{> "systems/foundryvtt-reve-de-dragon/templates/actor/competence-categorie.html" competences=(filtreTriCompetences byCateg.generale) categorie="Compétences générales"}}
|
||||
{{> "systems/foundryvtt-reve-de-dragon/templates/actor/competence-categorie.html" competences=(filtreTriCompetences byCateg.particuliere) categorie="Compétences Particulières"}}
|
||||
{{> "systems/foundryvtt-reve-de-dragon/templates/actor/competence-categorie.html" competences=(filtreTriCompetences byCateg.specialisee) categorie="Compétences Spécialisées"}}
|
||||
</div>
|
||||
<div class="grid grid-2col">
|
||||
<div class="competence-column">
|
||||
{{> "systems/foundryvtt-reve-de-dragon/templates/actor/competence-categorie.html" competences=(filtreTriCompetences byCateg.generale) categorie="Compétences générales"}}
|
||||
{{> "systems/foundryvtt-reve-de-dragon/templates/actor/competence-categorie.html" competences=(filtreTriCompetences byCateg.particuliere) categorie="Compétences Particulières"}}
|
||||
{{> "systems/foundryvtt-reve-de-dragon/templates/actor/competence-categorie.html" competences=(filtreTriCompetences byCateg.specialisee) categorie="Compétences Spécialisées"}}
|
||||
</div>
|
||||
<div class="competence-column">
|
||||
{{> "systems/foundryvtt-reve-de-dragon/templates/actor/xp-competences.html"}}
|
||||
{{> "systems/foundryvtt-reve-de-dragon/templates/actor/competence-categorie.html" competences=(filtreTriCompetences byCateg.melee) categorie="Compétences de Mêlée"}}
|
||||
{{> "systems/foundryvtt-reve-de-dragon/templates/actor/competence-categorie.html" competences=(filtreTriCompetences byCateg.tir) categorie="Compétences de Tir"}}
|
||||
{{> "systems/foundryvtt-reve-de-dragon/templates/actor/competence-categorie.html" competences=(filtreTriCompetences byCateg.lancer) categorie="Compétences de Lancer"}}
|
||||
{{> "systems/foundryvtt-reve-de-dragon/templates/actor/competence-categorie.html" competences=(filtreTriCompetences byCateg.connaissance) categorie="Connaissances"}}
|
||||
{{#if (or system.attributs.hautrevant.value options.vueDetaillee)}}
|
||||
{{> "systems/foundryvtt-reve-de-dragon/templates/actor/competence-categorie.html" competences=(filtreTriCompetences byCateg.draconic) categorie="Draconic"}}
|
||||
{{/if}}
|
||||
</div>
|
||||
<div class="competence-column">
|
||||
{{> "systems/foundryvtt-reve-de-dragon/templates/actor/xp-competences.html"}}
|
||||
{{> "systems/foundryvtt-reve-de-dragon/templates/actor/competence-categorie.html" competences=(filtreTriCompetences byCateg.melee) categorie="Compétences de Mêlée"}}
|
||||
{{> "systems/foundryvtt-reve-de-dragon/templates/actor/competence-categorie.html" competences=(filtreTriCompetences byCateg.tir) categorie="Compétences de Tir"}}
|
||||
{{> "systems/foundryvtt-reve-de-dragon/templates/actor/competence-categorie.html" competences=(filtreTriCompetences byCateg.lancer) categorie="Compétences de Lancer"}}
|
||||
{{> "systems/foundryvtt-reve-de-dragon/templates/actor/competence-categorie.html" competences=(filtreTriCompetences byCateg.connaissance) categorie="Connaissances"}}
|
||||
{{#if (or system.attributs.hautrevant.value options.vueDetaillee)}}
|
||||
{{> "systems/foundryvtt-reve-de-dragon/templates/actor/competence-categorie.html" competences=(filtreTriCompetences byCateg.draconic) categorie="Draconic"}}
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{!-- Combat Tab --}}
|
||||
<div class="tab combat" data-group="primary" data-tab="combat">
|
||||
</div>
|
||||
{{/if}}
|
||||
{{#if options.isObserver}}{{!-- Combat Tab --}}
|
||||
<div class="tab combat" data-group="primary" data-tab="combat">
|
||||
{{> "systems/foundryvtt-reve-de-dragon/templates/actor/combat.html"}}<hr>
|
||||
{{> "systems/foundryvtt-reve-de-dragon/templates/actor/blessures.html"}}
|
||||
{{> "systems/foundryvtt-reve-de-dragon/templates/actor/maladies-poisons.html"}}
|
||||
{{> "systems/foundryvtt-reve-de-dragon/templates/actor/possessions.html"}}
|
||||
|
||||
</div>
|
||||
|
||||
{{!-- Connaissances Tab --}}
|
||||
{{/if}}
|
||||
|
||||
{{#if options.isObserver}}{{!-- Connaissances Tab --}}
|
||||
<div class="tab connaissances" data-group="primary" data-tab="connaissances">
|
||||
{{> "systems/foundryvtt-reve-de-dragon/templates/actor/astrologie.html"}}
|
||||
{{> "systems/foundryvtt-reve-de-dragon/templates/actor/taches.html"}}
|
||||
{{> "systems/foundryvtt-reve-de-dragon/templates/actor/oeuvres.html"}}
|
||||
{{> "systems/foundryvtt-reve-de-dragon/templates/actor/jeux.html"}}
|
||||
{{> "systems/foundryvtt-reve-de-dragon/templates/actor/alchimie.html"}}
|
||||
</div>
|
||||
|
||||
{{!-- hautreve Tab --}}
|
||||
{{/if}}
|
||||
{{#if options.isObserver}}{{!-- hautreve Tab --}}
|
||||
<div class="tab hautreve " data-group="primary" data-tab="hautreve" style="height:200px">
|
||||
<div>
|
||||
{{#if system.attributs.hautrevant.value}}
|
||||
@ -113,10 +118,11 @@
|
||||
<br><br>
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
{{!-- Equipment Tab --}}
|
||||
<div class="tab items" data-group="primary" data-tab="items">
|
||||
|
||||
{{> "systems/foundryvtt-reve-de-dragon/templates/actor/inventaire-monnaie.html"}}
|
||||
{{> "systems/foundryvtt-reve-de-dragon/templates/actor/inventaire.html"}}
|
||||
{{> "systems/foundryvtt-reve-de-dragon/templates/actor/liens-animaux.html"}}
|
||||
{{> "systems/foundryvtt-reve-de-dragon/templates/actor/liens-suivants.html"}}
|
||||
@ -152,8 +158,10 @@
|
||||
<ul class="item-list alterne-list">
|
||||
<li class="item flexrow list-item">
|
||||
<label for="system.main">Main directrice :</label>
|
||||
<input type="text" class="selection-main-directrice" name="system.main" value="{{system.main}}" data-dtype="String"/>
|
||||
{{>'systems/foundryvtt-reve-de-dragon/templates/scripts/autocomplete.hbs' proposals=options.mainsDirectrices className='selection-main-directrice'}}
|
||||
<div class="autocomplete">
|
||||
<input type="text" class="selection-main-directrice" name="system.main" value="{{system.main}}" data-dtype="String"/>
|
||||
{{>'systems/foundryvtt-reve-de-dragon/templates/scripts/autocomplete.hbs' proposals=options.mainsDirectrices className='selection-main-directrice'}}
|
||||
</div>
|
||||
</li>
|
||||
<li class="item flexrow list-item">
|
||||
<label for="system.heure">Heure de naissance :</label>
|
||||
|
@ -91,6 +91,7 @@
|
||||
|
||||
{{!-- Equipment Tab --}}
|
||||
<div class="tab items" data-group="primary" data-tab="items">
|
||||
{{> "systems/foundryvtt-reve-de-dragon/templates/actor/inventaire-monnaie.html"}}
|
||||
{{> "systems/foundryvtt-reve-de-dragon/templates/actor/inventaire.html"}}
|
||||
</div>
|
||||
|
||||
|
@ -9,7 +9,7 @@
|
||||
<label class="flexrow derivee-label">{{system.compteurs.stress.label}}
|
||||
<a class="stress-test" title="Transformer le stress"><i class="fa-regular fa-moon"></i></a>
|
||||
</label>
|
||||
<input class="derivee-value" type="text" name="{{system.compteurs.stress.value}}" value="{{system.compteurs.stress.value}}" data-dtype="number"/>
|
||||
<input class="derivee-value" type="text" name="system.compteurs.stress.value" value="{{system.compteurs.stress.value}}" data-dtype="number"/>
|
||||
</li>
|
||||
<li class="caracteristique flexrow list-item">
|
||||
<label class="derivee-label">{{system.compteurs.moral.label}}
|
||||
|
@ -11,15 +11,6 @@
|
||||
<span class="repos">
|
||||
<a title="Repos"><img class="button-img" src="icons/svg/sleep.svg" alt="Se reposer"/></a>
|
||||
</span>
|
||||
{{#if system.attributs.hautrevant.value}}
|
||||
<span class="monte-tmr">
|
||||
<a title="Montée dans les Terres Médianes !" {{#if hautreve.isDemiReve}}disabled{{/if}}><img class="button-img" src="systems/foundryvtt-reve-de-dragon/styles/img/ui/icon-tmr-normal.svg" alt="Montée dans les Terres Médianes !"/></a></span>
|
||||
<span class="monte-tmr-rapide">
|
||||
<a title="Montée accélérée dans les Terres Médianes !"><img class="button-img" src="systems/foundryvtt-reve-de-dragon/styles/img/ui/icon-tmr-rapide.svg" alt="Montée accélérée dans les Terres Médianes !"/></a></span>
|
||||
<span class="visu-tmr">
|
||||
<a title="Regarder les Terres Médianes"><img class="button-img" src="systems/foundryvtt-reve-de-dragon/styles/img/ui/icon-tmr-view.svg" alt="Regarder les Terres Médianes"/></a>
|
||||
</span>
|
||||
{{/if}}
|
||||
{{#if @root.options.isGM}}
|
||||
<span class="remise-a-neuf">
|
||||
<a title="Remise à neuf"><img class="button-img" src="icons/svg/regen.svg" alt="Remise à neuf"/></a>
|
||||
|
@ -21,7 +21,7 @@
|
||||
<li>
|
||||
<label class="appliquerFatigue compteur tooltip">
|
||||
<span class="tooltiptext ttt-fatigue">{{{calc.fatigue.html}}}</span>
|
||||
Fatigue
|
||||
Fatigue ({{calc.fatigue.malus}})
|
||||
<a class="fatigue-moins"><i class="fas fa-minus-square"></i></a>
|
||||
<input class="resource-content" type="text" name="system.sante.fatigue.value" value="{{system.sante.fatigue.value}}" data-dtype="Number" />
|
||||
<span>/ {{system.sante.fatigue.max}}</span>
|
||||
|
@ -1,10 +1,7 @@
|
||||
<div class="flex-group-left header-etats">
|
||||
<div class="flexcol">
|
||||
<span class="appliquerFatigue tooltip tooltip-dotted">Fatigue: {{calc.fatigue.malus}}
|
||||
<span class="tooltiptext ttt-fatigue">{{{calc.fatigue.html}}}</span>
|
||||
</span>
|
||||
<span>{{system.compteurs.etat.label}}: {{system.compteurs.etat.value}}</span>
|
||||
<span>{{system.compteurs.surenc.label}}: {{system.compteurs.surenc.value}}</span>
|
||||
<span>Sur-encombrement: {{calc.surenc}}</span>
|
||||
<span>{{calc.resumeBlessures}}</span>
|
||||
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/header-effects.html"}}
|
||||
</div>
|
||||
|
17
templates/actor/header-hautreve.html
Normal file
17
templates/actor/header-hautreve.html
Normal file
@ -0,0 +1,17 @@
|
||||
{{#if system.attributs.hautrevant.value}}
|
||||
<div class="tmr-buttons">
|
||||
<span class="monte-tmr">
|
||||
<a title="Montée dans les Terres Médianes !" {{#if hautreve.isDemiReve}}disabled{{/if}}>
|
||||
<img class="button-img" src="systems/foundryvtt-reve-de-dragon/styles/img/ui/icon-tmr-normal.svg" alt="Montée dans les Terres Médianes !"/>
|
||||
</a>
|
||||
</span>
|
||||
<span class="monte-tmr-rapide">
|
||||
<a title="Montée accélérée dans les Terres Médianes !" {{#if hautreve.isDemiReve}}disabled{{/if}}>
|
||||
<img class="button-img" src="systems/foundryvtt-reve-de-dragon/styles/img/ui/icon-tmr-rapide.svg" alt="Montée accélérée dans les Terres Médianes !"/>
|
||||
</a>
|
||||
</span>
|
||||
<span class="visu-tmr">
|
||||
<a title="Regarder les Terres Médianes"><img class="button-img" src="systems/foundryvtt-reve-de-dragon/styles/img/ui/icon-tmr-view.svg" alt="Regarder les Terres Médianes"/></a>
|
||||
</span>
|
||||
</div>
|
||||
{{/if}}
|
@ -1,3 +1,4 @@
|
||||
{{#if (or @root.options.isObserver (ne item.type 'monnaie'))}}
|
||||
<li class="item flexrow list-item" data-item-id="{{item._id}}" draggable="true">
|
||||
<span class="equipement-nom {{#if (eq item.type 'conteneur')}}conteneur-name{{/if}} ">
|
||||
{{#if (eq item.type 'conteneur')}}
|
||||
@ -20,6 +21,7 @@
|
||||
</span>
|
||||
<span class="equipement-detail">{{numberFormat item.system.encTotal decimals=2}}</span>
|
||||
<span class="equipement-actions item-controls">
|
||||
{{#if @root.options.isOwner}}
|
||||
{{#unless item.estContenu}}
|
||||
{{#if (or (eq item.type 'arme') (eq item.type 'armure') )}}
|
||||
<a class="item-equip" title="Equiper">{{#if item.system.equipe}}<i class="fas fa-hand-rock"></i>{{else}}<i class="far fa-hand-paper"></i>{{/if}}</a>
|
||||
@ -31,10 +33,13 @@
|
||||
{{#if (ne item.system.quantite 0)}}
|
||||
<a class="item-vendre" title="Vendre ou donner"><i class="fas fa-comments-dollar"></i></a>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
<a class="item-montrer" title="Montrer"><i class="fas fa-comment"></i></a>
|
||||
{{#if @root.options.isOwner}}
|
||||
{{#if item.system.actionPrincipale}}
|
||||
<a class="item-action">{{item.system.actionPrincipale}}</a>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
</span>
|
||||
</li>
|
||||
|
||||
{{/if}}
|
||||
|
@ -1,4 +1,5 @@
|
||||
<span class="item-name"><h4>Argent et Monnaies (fortune: {{calc.fortune}} sols)</h4></span>
|
||||
{{#if @root.options.isObserver}}
|
||||
<span class="item-name"><h4>Argent et Monnaies (fortune: {{calc.fortune.sols}} sols {{calc.fortune.deniers}} deniers)</h4></span>
|
||||
<ul class="item-list alterne-list">
|
||||
{{#each monnaie as |piece id|}}
|
||||
<li class="item flexrow list-item" data-item-id="{{piece._id}}">
|
||||
@ -7,19 +8,26 @@
|
||||
<span class="equipement-valeur {{#unless (gt piece.system.cout 0)}}field-error{{/unless}}">
|
||||
({{piece.system.cout}} Sols)
|
||||
</span>
|
||||
{{#if @root.options.isOwner}}
|
||||
<span class="equipement-button item-controls">
|
||||
<a class="monnaie-moins"><i class="fas fa-minus-square"></i></a>
|
||||
</span>
|
||||
{{/if}}
|
||||
<span class="equipement-detail">
|
||||
<span>{{piece.system.quantite}}</span>
|
||||
</span>
|
||||
{{#if @root.options.isOwner}}
|
||||
<span class="equipement-button item-controls">
|
||||
<a class="monnaie-plus"><i class="fas fa-plus-square"></i></a>
|
||||
</span>
|
||||
<span class="equipement-actions item-controls">
|
||||
{{/if}}
|
||||
<span class="equipement-actions item-controls">
|
||||
{{#if @root.options.isOwner}}
|
||||
<a class="item-edit" title="Editer"><i class="fas fa-edit"></i></a>
|
||||
<a class="item-delete" title="Supprimer"><i class="fas fa-trash"></i></a>
|
||||
{{/if}}
|
||||
</span>
|
||||
</li>
|
||||
{{/each}}
|
||||
</ul>
|
||||
{{/if}}
|
||||
|
@ -1,5 +1,3 @@
|
||||
{{> "systems/foundryvtt-reve-de-dragon/templates/actor/inventaire-monnaie.html" monnaie=monnaie}}
|
||||
|
||||
<h4>Equipement</h4>
|
||||
<span class="item-name">
|
||||
<a class="chat-card-button creer-un-objet">Nouvel objet</a>
|
||||
|
@ -1 +1,14 @@
|
||||
<a class="content-link" draggable="true" data-pack="{{pack}}" data-uuid="Compendium.{{pack}}.{{id}}" data-id="{{id}}"><i class="fas fa-suitcase"></i>{{name}}</a>
|
||||
{{#if pack}}
|
||||
{{!-- draggable="true" --}}
|
||||
<a class="content-link"
|
||||
data-uuid="Compendium.{{pack}}.{{id}}"
|
||||
data-pack="{{pack}}"
|
||||
{{#if doctype}}data-doctype="{{doctype}}"{{/if}}
|
||||
data-id="{{id}}"
|
||||
><i class="fas fa-suitcase"></i>{{name}}</a>
|
||||
{{else}}
|
||||
<a class="rdd-world-content-link"
|
||||
{{#if doctype}}data-doctype="{{doctype}}"{{/if}}
|
||||
data-id="{{id}}"
|
||||
><i class="fas fa-suitcase"></i>{{name}}</a>
|
||||
{{/if}}
|
||||
|
@ -16,7 +16,7 @@
|
||||
<label> Jours</label>
|
||||
<select name="joursAstrologie" data-dtype="Number">
|
||||
{{#select joursSuivants}}
|
||||
{{#each dates as |date key|}}
|
||||
{{#each dates as |date key|}}
|
||||
<option value={{date.index}}>{{date.label}}</option>
|
||||
{{/each}}
|
||||
{{/select}}
|
||||
|
@ -2,15 +2,17 @@
|
||||
<div>
|
||||
<div class="flexrow flex-center">
|
||||
<div>
|
||||
{{#if vendeur}}
|
||||
{{#if service}}
|
||||
<img class="chat-icon" src="{{service.img}}" title="{{service.name}}" alt="{{service.name}}" />
|
||||
{{else if vendeur}}
|
||||
<img class="chat-icon" src="{{vendeur.img}}" title="{{vendeur.name}}" alt="{{vendeur.name}}" />
|
||||
{{else}}
|
||||
<img class="chat-icon" src="systems/foundryvtt-reve-de-dragon/styles/img/ui/icon_echoppe.webp" title="Un commerçant" alt="Vendeur MJ" />
|
||||
{{/if}}
|
||||
</div>
|
||||
<div><i class="fas fa-sign-out-alt"></i></div>
|
||||
<div><i class="fa-solid fa-arrow-right-long"></i></div>
|
||||
<div><img class="chat-icon" src="{{item.img}}" title="{{item.name}}" alt="{{item.name}}" /></div>
|
||||
<div><i class="fas fa-sign-in-alt"></i></div>
|
||||
<div><i class="fa-solid fa-arrow-right-long"></i></div>
|
||||
<div>
|
||||
{{#if acheteur}}
|
||||
<img class="chat-icon" src="{{acheteur.img}}" title="{{acheteur.name}}" alt="{{acheteur.name}}" />
|
||||
@ -40,8 +42,10 @@
|
||||
{{else}}Quantité{{/if}}
|
||||
</label>
|
||||
<div class="flexrow">
|
||||
<input name="nombreLots" class="nombreLots flex-shrink" type="number" min="1" max="{{quantiteNbLots}}"
|
||||
value="{{choix.nombreLots}}" data-dtype="Number" />
|
||||
<input name="nombreLots" class="nombreLots flex-shrink number-x2" type="number" min="1"
|
||||
{{#unless quantiteIllimite}} max="{{quantiteNbLots}}" {{/unless}}
|
||||
value="{{choix.nombreLots}}"
|
||||
data-dtype="Number" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -50,8 +54,7 @@
|
||||
|
||||
{{#if item.system.sust}}
|
||||
<p>Cette {{#if item.system.boisson}}boisson{{else}}nourriture{{/if}} vous apportera
|
||||
<span class="total-sust">{{totalSust}}</span>
|
||||
de sustantation.</p>
|
||||
<span class="total-sust">{{totalSust}}</span> de sustantation.</p>
|
||||
{{/if}}
|
||||
{{#if item.system.boisson}}
|
||||
<p>
|
||||
@ -86,9 +89,9 @@
|
||||
</div>
|
||||
<div class="flexrow flex-group-left">
|
||||
<label>Prix total</label>
|
||||
<span class="flexrow">
|
||||
<span>
|
||||
<span class="prixTotal">{{prixTotal}}</span>
|
||||
<span>Sols</span>
|
||||
Sols
|
||||
</span>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
@ -3,7 +3,7 @@
|
||||
<h4>{{item.name}}</h4>
|
||||
<div class="flexrow">
|
||||
<label class="flex-grow">Quantité à {{#if item.system.boisson}}boire{{else}}manger{{/if}}</label>
|
||||
<input class="attribute-value consommer-doses flex-shrink" type="number" name="doses" value="{{choix.doses}}"
|
||||
<input class="attribute-value consommer-doses flex-shrink number-x2" type="number" name="doses" value="{{choix.doses}}"
|
||||
min="0" max="{{item.system.quantite}}" data-dtype="Number" />
|
||||
</div>
|
||||
{{#if item.system.sust}}
|
||||
|
@ -4,7 +4,7 @@
|
||||
<label>Quantité totale : {{item.system.quantite}}</label>
|
||||
<div class="flexrow">
|
||||
<label class="flex-grow">Quantité à séparer</label>
|
||||
<input class="attribute-value choix-quantite flex-shrink" type="number" name="choix.quantite" value="{{choix.quantite}}"
|
||||
<input class="attribute-value choix-quantite flex-shrink number-x2" type="number" name="choix.quantite" value="{{choix.quantite}}"
|
||||
min="1" max="{{choix.max}}" data-dtype="Number" />
|
||||
</div>
|
||||
</form>
|
||||
|
@ -16,13 +16,13 @@
|
||||
quantiteIllimite}}checked{{/if}} />
|
||||
<label class="label-quantiteIllimite flex-shrink">Illimités</label>
|
||||
{{/unless}}
|
||||
<input name="quantiteNbLots" class="quantiteNbLots flex-shrink" type="number" min="1"
|
||||
<input name="quantiteNbLots" class="quantiteNbLots flex-shrink number-x2" type="number" min="1"
|
||||
max="{{quantiteMaxLots}}" value="{{quantiteNbLots}}" data-dtype="Number" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="flexrow flex-group-left">
|
||||
<label for="tailleLot">Taille d'un lot</label>
|
||||
<input name="tailleLot" class="tailleLot flex-shrink" type="number" min="1"
|
||||
<input name="tailleLot" class="tailleLot flex-shrink number-x2" type="number" min="1"
|
||||
max="{{quantiteMax}}" value="{{tailleLot}}" data-dtype="Number" />
|
||||
</div>
|
||||
<div class="flexrow flex-group-left">
|
||||
|
23
templates/dialog-roll.html
Normal file
23
templates/dialog-roll.html
Normal file
@ -0,0 +1,23 @@
|
||||
<form class="skill-roll-dialog">
|
||||
<h2 class="dialog-roll-title"></h2>
|
||||
{{log 'dialog-roll' this}}
|
||||
<div class="grid grid-2col">
|
||||
<div class="flex-group-left">
|
||||
<div class="flexrow">
|
||||
<label>Caractéristique</label>
|
||||
{{>"systems/foundryvtt-reve-de-dragon/templates/partial-select-carac.html"}}
|
||||
</div>
|
||||
{{>"systems/foundryvtt-reve-de-dragon/templates/partial-roll-competences.html"}}
|
||||
{{>"systems/foundryvtt-reve-de-dragon/templates/partial-roll-surenc.html"}}
|
||||
{{>"systems/foundryvtt-reve-de-dragon/templates/partial-roll-enctotal.html"}}
|
||||
</div>
|
||||
<div class="flex-group-left">
|
||||
{{>"systems/foundryvtt-reve-de-dragon/templates/partial-roll-diffLibre.html"}}
|
||||
{{>"systems/foundryvtt-reve-de-dragon/templates/partial-roll-diffCondition.html"}}
|
||||
{{>"systems/foundryvtt-reve-de-dragon/templates/partial-roll-forcer.html"}}
|
||||
{{>"systems/foundryvtt-reve-de-dragon/templates/partial-roll-moral.html"}}
|
||||
<div class="placeholder-ajustements" class="flexrow"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="placeholder-resolution"></div>
|
||||
</form>
|
@ -9,9 +9,7 @@
|
||||
<a class="item" data-tab="frequence">Fréquences</a>
|
||||
{{/unless}}
|
||||
</nav>
|
||||
|
||||
<section class="sheet-body">
|
||||
|
||||
<div class="tab items" data-group="primary" data-tab="rencontre">
|
||||
{{#if isOwned}}
|
||||
<div class="form-group">
|
||||
|
103
templates/item-service-sheet.html
Normal file
103
templates/item-service-sheet.html
Normal file
@ -0,0 +1,103 @@
|
||||
<form class="{{cssClass}}" autocomplete="off">
|
||||
{{>"systems/foundryvtt-reve-de-dragon/templates/header-item.html"}}
|
||||
|
||||
<section class="sheet-body">
|
||||
<div class="flexcol form-group small-editor">
|
||||
{{editor description target="system.description" button=true owner=owner editable=(or isGM isOwner) engine="prosemirror"}}
|
||||
</div>
|
||||
{{!--
|
||||
<div class="flexcol">
|
||||
<ul class="item-list alterne-list">
|
||||
<li class="item flexrow list-item">
|
||||
<label class="flex-grow">Service</label>
|
||||
<label>Moral</label>
|
||||
<label>Qualité</label>
|
||||
<label>Prix (sols)</label>
|
||||
<label>
|
||||
{{#unless disabled}}
|
||||
<a class="service-add"><i class="fas fa-plus-circle"></i></a>
|
||||
{{/unless}}
|
||||
</label>
|
||||
</li>
|
||||
{{#each system.services as |service key|}}
|
||||
<li class="item flexrow list-item" data-key="{{key}}">
|
||||
<input {{@root.disabled}} type="text" name="services[{{key}}].name" value="{{service.name}}" data-dtype="String" />
|
||||
<input {{@root.disabled}} type="checkbox" name="services[{{key}}].system.moral" {{#if service.system.moral}}checked{{/if}} />
|
||||
<input {{@root.disabled}} type="number" name="services[{{key}}].system.qualite" value="{{service.system.qualite}}" data-dtype="Number" min="-10" max="10"/>
|
||||
<input {{@root.disabled}} type="number" class="input-prix" name="services[{{key}}].system.cout" value="{{numberFormat service.system.cout decimals=2 sign=false}}" data-dtype="Number" min="0" />
|
||||
<div class="item-controls">
|
||||
<a class="service-acheter" title="Acheter"><i class="fa-sharp fa-solid fa-coins"></i></a>
|
||||
{{#unless @root.disabled}}
|
||||
<a class="service-vendre" title="Proposer"><i class="fas fa-comments-dollar"></i></a>
|
||||
<a class="service-delete" title="Supprimer"><i class="fas fa-trash"></i></a>
|
||||
{{/unless}}
|
||||
</div>
|
||||
</li>
|
||||
{{/each}}
|
||||
</ul>
|
||||
</div>
|
||||
<br>
|
||||
--}}
|
||||
<div class="form-group">
|
||||
<input {{@root.disabled}} class="attribute-value" type="checkbox" name="system.illimite" {{#if system.illimite}}checked{{/if}}/>
|
||||
<span for="system.illimite">Quantité en vente illimitée</span>
|
||||
</div>
|
||||
<div class="flexcol">
|
||||
<ul class="item-list alterne-list">
|
||||
<li class="item flexrow list-item">
|
||||
<label class="flex-grow">A vendre</label>
|
||||
{{#unless system.illimite}}
|
||||
<label>Quantite</label>
|
||||
{{/unless}}
|
||||
<label>Prix (sols)</label>
|
||||
<div class="item-controls">
|
||||
{{#unless disabled}}
|
||||
<a class="sub-item-info-add" title="Utiliser le drag&drop pour ajouter un objet dans la liste">
|
||||
<i class="fa-solid fa-circle-info"></i>
|
||||
</a>
|
||||
{{/unless}}
|
||||
</div>
|
||||
</li>
|
||||
{{#each system.items as |item key|}}
|
||||
<li class="item flexrow list-item service-item" data-item-id="{{item.id}}" data-pack="{{item.pack}}" data-key="{{key}}">
|
||||
<label class="flex-grow">
|
||||
{{#if item.img}}<img class="sheet-competence-img" src="{{item.img}}" title="{{item.name}}"/>{{/if}}
|
||||
{{> 'systems/foundryvtt-reve-de-dragon/templates/common/compendium-link.hbs'
|
||||
pack=item.pack id=item.id name=item.name}}
|
||||
</label>
|
||||
{{#unless @root.system.illimite}}
|
||||
<span class="flexrow">
|
||||
{{#unless @root.disabled}}
|
||||
<a class="sub-item-quantite-moins"><i class="fas fa-minus-square"></i></a>
|
||||
{{/unless}}
|
||||
<input {{@root.disabled}} type="number" class="sub-item-quantite" name="items[{{key}}].system.quantite" value="{{item.system.quantite}}" data-dtype="Number" />
|
||||
{{#unless @root.disabled}}
|
||||
<a class="sub-item-quantite-plus"><i class="fas fa-plus-square"></i></a>
|
||||
{{/unless}}
|
||||
</span>
|
||||
{{/unless}}
|
||||
<span class="flexrow">
|
||||
<input {{@root.disabled}} type="number" class="input-prix number-x3 sub-item-cout" name="items[{{key}}].system.cout" value="{{numberFormat item.system.cout decimals=2 sign=false}}" data-dtype="Number" />
|
||||
</span>
|
||||
<div class="item-controls">
|
||||
<a class="sub-item-acheter" title="Acheter"><i class="fa-regular fa-coins"></i></a>
|
||||
{{#unless @root.disabled}}
|
||||
<a class="sub-item-vendre" title="Vendre"><i class="fas fa-comments-dollar"></i></a>
|
||||
<a class="sub-item-delete" title="Supprimer"><i class="fas fa-trash"></i></a>
|
||||
{{/unless}}
|
||||
</div>
|
||||
</li>
|
||||
{{/each}}
|
||||
</ul>
|
||||
</div>
|
||||
{{#if isGM}}
|
||||
<br>
|
||||
<div class="flexcol">
|
||||
<span><label>Description (MJ seulement): </label></span>
|
||||
<div class="form-group medium-editor">
|
||||
{{editor descriptionmj target="system.descriptionmj" button=true owner=owner editable=true engine="prosemirror"}}
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
</section>
|
||||
</form>
|
@ -10,24 +10,26 @@
|
||||
<div class="form-group">
|
||||
<label>Ajouter un fréquence</label>
|
||||
<span class="flexrow">
|
||||
<input type="text" class="input-selection-milieu" placeholder="Milieu" data-dtype="String"/>
|
||||
{{>'systems/foundryvtt-reve-de-dragon/templates/scripts/autocomplete.hbs' proposals=milieux className='input-selection-milieu'}}
|
||||
<div class="autocomplete">
|
||||
<input name="saisie-nouveau-milieu" type="text" class="input-selection-milieu" placeholder="Milieu" data-dtype="String"/>
|
||||
{{>'systems/foundryvtt-reve-de-dragon/templates/scripts/autocomplete.hbs' proposals=milieux className='input-selection-milieu'}}
|
||||
</div>
|
||||
<a class="milieu-add"><i class="fas fa-plus-circle"></i></a>
|
||||
</span>
|
||||
</div>
|
||||
{{#each system.environnement as |env|}}
|
||||
{{#each system.environnement as |env key|}}
|
||||
<div class="form-group environnement-milieu" data-milieu="{{env.milieu}}">
|
||||
<label>
|
||||
{{env.milieu}}
|
||||
<a class="milieu-delete" title="Supprimer {{env.milieu}}"><i class="fas fa-trash"></i></a>
|
||||
</label>
|
||||
<span class="flexrow">
|
||||
<select class="environnement-rarete" class="flex-shrink" data-dtype="String">
|
||||
<select name="milieu-{{key}}-rarete" class="environnement-rarete" class="flex-shrink" data-dtype="String">
|
||||
{{#select env.rarete}}
|
||||
{{>"systems/foundryvtt-reve-de-dragon/templates/enum-rarete.html"}}
|
||||
{{/select}}
|
||||
</select>
|
||||
{{rangePicker name="environnement-frequence" value=env.frequence min=(getFrequenceRarete env.rarete 'min') max=(getFrequenceRarete env.rarete 'max') step=1}}
|
||||
{{rangePicker name="milieu-{{key}}-frequence" value=env.frequence min=(getFrequenceRarete env.rarete 'min') max=(getFrequenceRarete env.rarete 'max') step=1}}
|
||||
<label>[{{getFrequenceRarete env.rarete 'min'}}-{{getFrequenceRarete env.rarete 'max'}}]</label>
|
||||
</span>
|
||||
</div>
|
||||
|
@ -1,25 +1,25 @@
|
||||
<div class="form-group">
|
||||
<label for="system.qualite">Qualité</label>
|
||||
<input class="attribute-value" type="text" name="system.qualite" value="{{system.qualite}}" data-dtype="Number"
|
||||
<input class="attribute-value number-x3" type="number" name="system.qualite" value="{{system.qualite}}" data-dtype="Number"
|
||||
{{#unless (isFieldInventaireModifiable type 'qualite')}}disabled{{/unless}}/>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="system.encombrement">Encombrement</label>
|
||||
<input class="attribute-value" type="text" name="system.encombrement" value="{{system.encombrement}}" data-dtype="Number"
|
||||
<input class="attribute-value number-x3" type="number" name="system.encombrement" value="{{system.encombrement}}" data-dtype="Number"
|
||||
{{#unless (isFieldInventaireModifiable type 'encombrement')}}disabled{{/unless}}/>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="system.quantite">Quantité {{uniteQuantite id actorId}}</label>
|
||||
<input class="attribute-value" type="text" name="system.quantite" value="{{system.quantite}}" data-dtype="Number"
|
||||
<input class="attribute-value number-x3" type="number" name="system.quantite" value="{{system.quantite}}" data-dtype="Number"
|
||||
{{#unless (isFieldInventaireModifiable type 'quantite')}}disabled{{/unless}}/>
|
||||
</div>
|
||||
<div class="form-group item-cout">
|
||||
<label for="system.cout">Prix (sols)</label>
|
||||
{{#if (or (ne type 'monnaie') (gt system.cout 0))}}
|
||||
<input class="attribute-value" type="text" name="system.cout" value="{{system.cout}}" data-dtype="Number"
|
||||
<input class="input-prix attribute-value number-x3" type="number" name="system.cout" value="{{numberFormat system.cout decimals=2 sign=false}}" data-dtype="Number"
|
||||
{{#unless (isFieldInventaireModifiable type 'cout')}}disabled{{/unless}}/>
|
||||
{{else}}
|
||||
<input class="attribute-value field-error" type="text" name="system.cout" value="{{system.cout}}" data-dtype="Number"
|
||||
<input class="input-prix attribute-value field-error number-x3" type="number" name="system.cout" value="{{numberFormat system.cout decimals=2 sign=false}}" data-dtype="Number"
|
||||
{{#unless (isFieldInventaireModifiable type 'cout')}}disabled{{/unless}}/>
|
||||
{{/if}}
|
||||
</div>
|
||||
|
@ -1,7 +1,7 @@
|
||||
<select name="carac" class="flex-grow" data-dtype="String">
|
||||
{{#select carac}}
|
||||
{{#select selectedCaracName}}
|
||||
{{#each carac as |caracitem key|}}
|
||||
<option value={{key}}>{{caracitem.label}}</option>
|
||||
<option value="{{key}}">{{caracitem.label}}</option>
|
||||
{{/each}}
|
||||
{{/select}}
|
||||
</select>
|
||||
|
7
templates/post-actor.html
Normal file
7
templates/post-actor.html
Normal file
@ -0,0 +1,7 @@
|
||||
<div class="post-item">
|
||||
{{#if img}}
|
||||
<img class="chat-icon" src="{{img}}" title="{{name}}" />
|
||||
{{/if}}
|
||||
<p>{{> 'systems/foundryvtt-reve-de-dragon/templates/common/compendium-link.hbs' pack=pack id=id name=name doctype=doctype}}</p>
|
||||
<p class="card-content">{{{system.description}}}</p>
|
||||
</div>
|
8
templates/post-item-service.html
Normal file
8
templates/post-item-service.html
Normal file
@ -0,0 +1,8 @@
|
||||
<div class="post-item">
|
||||
{{#if img}}
|
||||
<img class="chat-icon" src="{{img}}" title="{{name}}" />
|
||||
{{/if}}
|
||||
<p>{{> 'systems/foundryvtt-reve-de-dragon/templates/common/compendium-link.hbs' pack=pack id=id name=name docType=docType}}</p>
|
||||
<p class="card-content">{{{system.description}}}</p>
|
||||
|
||||
</div>
|
@ -1,4 +1,4 @@
|
||||
<div class="post-item" data-transfer="{{transfer}}">
|
||||
<div class="post-item">
|
||||
<h3><b>{{name}}</b></h3>
|
||||
{{#if img}}
|
||||
<img class="chat-icon" src="{{img}}" title="{{name}}" />
|
||||
@ -10,5 +10,4 @@
|
||||
<span>{{{property}}}</span><br>
|
||||
{{/each}}
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
Reference in New Issue
Block a user