Ajout d'Item rencontre

Pour l'instant, pas utilisée. Une rencontre permettra de
définir les différents effets de la rencontre.

Un compendium dédié donnera les rencontres possibles.
This commit is contained in:
Vincent Vandemeulebrouck
2022-11-05 18:19:53 +01:00
parent 73c490a91d
commit d77f046a6a
11 changed files with 524 additions and 12 deletions

View File

@ -0,0 +1,109 @@
import { SYSTEM_RDD } from "./constants.js";
import { RdDRencontre } from "./item-rencontre.js";
/**
* Item sheet pour configurer les rencontres
* @extends {ItemSheet}
*/
export class RdDRencontreItemSheet extends ItemSheet {
/** @override */
static get defaultOptions() {
return mergeObject(super.defaultOptions, {
classes: ["rdd", "sheet", "item"],
template: "systems/foundryvtt-reve-de-dragon/templates/item-rencontre-sheet.html",
width: 500,
height: 500,
tabs: [{ navSelector: ".sheet-tabs", contentSelector: ".sheet-body", initial: "carac" }]
});
}
/* -------------------------------------------- */
_getHeaderButtons() {
let buttons = super._getHeaderButtons();
buttons.unshift({ class: "post", icon: "fas fa-comment", onclick: ev => this.item.postItem() });
return buttons;
}
/* -------------------------------------------- */
/** @override */
setPosition(options = {}) {
const position = super.setPosition(options);
const sheetHeader = this.element.find(".sheet-header");
const sheetBody = this.element.find(".sheet-body");
sheetBody.css("height", position.height - sheetHeader[0].clientHeight)
return position;
}
/* -------------------------------------------- */
async getData() {
const formData = duplicate(this.item);
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(),
select: RdDRencontre.mapEffets(this.item.system.succes.effets)
},
echec: {
liste: RdDRencontre.getEffetsEchec(),
select: RdDRencontre.mapEffets(this.item.system.echec.effets)
}
}
});
return formData;
}
/* -------------------------------------------- */
/** @override */
activateListeners(html) {
super.activateListeners(html);
if (!this.options.editable) return;
html.find("a.effet-add").click(event => this.onAddEffet(event));
html.find("a.effet-delete").click(event => this.onDeleteEffet(event));
}
async onAddEffet(event) {
const resultat = $(event.currentTarget)?.data("effet-resultat");
const keyEffets = `system.${resultat}.effets`;
const code = $(event.currentTarget)?.data("effet-code");
const liste = RdDRencontre.getListeEffets(this.item, resultat);
liste.push(code);
await this._updateEffetsRencontre(keyEffets, liste);
}
async onDeleteEffet(event) {
const resultat = $(event.currentTarget)?.data("effet-resultat");
const keyEffets = `system.${resultat}.effets`;
const pos = $(event.currentTarget)?.data("effet-pos");
const liste = RdDRencontre.getListeEffets(this.item, resultat);
liste.splice(pos, 1);
await this._updateEffetsRencontre(keyEffets, liste);
}
async _updateEffetsRencontre(key, liste) {
const updates = {};
updates[key] = liste;
this.item.update(updates);
}
get template() {
/* -------------------------------------------- */
return `systems/foundryvtt-reve-de-dragon/templates/item-rencontre-sheet.html`;
}
get title() {
return `Rencontre: ${this.object.name}`;
}
}

60
module/item-rencontre.js Normal file
View File

@ -0,0 +1,60 @@
import { RdDRollTables } from "./rdd-rolltables.js";
const tableEffets = [
{ code: "messager", resultat: "succes", description: "Envoie un message à (force) cases" },
{ code: "passeur", resultat: "succes", description: "Déplacer le demi-rêve à (force) cases" },
{ code: "reve+f", resultat: "succes", description: "Gain de (force) points de rêve" },
{ code: "teleport", resultat: "succes", description: "Déplacer le demi-rêve (même type de case)" },
{ code: "part+tete", resultat: "succes", description: "Tête de dragon sur réussite particulière" },
{ code: "part+xp", resultat: "succes", description: "Expérience sur réussite particulière" },
{ code: "reve-1", resultat: "echec", description: "Perte de 1 point de rêve" },
{ code: "reve-f", resultat: "echec", description: "Perte de (force) points de rêve" },
{ code: "vie-1", resultat: "echec", description: "Perte de 1 point de vie" },
{ code: "reinsere", resultat: "echec", description: "Réinsertion aléatoire" },
{ code: "declenhe", resultat: "echec", description: "Déclenche un sort aléatoire" },
{ code: "persistant", resultat: "echec", description: "Bloque le demi-rêve" },
{ code: "teleport-aleatoire", resultat: "echec", description: "Déplacement aléatoire (même type de case)" },
{ code: "aleatoire", resultat: "echec", description: "Déplacement aléatoire" },
{ code: "sort-aleatoire", resultat: "echec", description: "Déplacement pour déclencher un sort en réserve aléatoire" },
{ code: "rompu", resultat: "echec", description: "Demi-rêve interrompu" },
{ code: "echec-queue", resultat: "echec", description: "Queue de dragon sur échec" },
{ code: "etotal-queue", resultat: "echec", description: "Queue de dragon sur échec total" },
{ code: "moral+1", resultat: "succes", description: "Gain de 1 point de moral" },
{ code: "reve+1", resultat: "succes", description: "Gain de 1 point de rêve" },
{ code: "vie-f", resultat: "echec", description: "Perte de (force) point de vie" },
{ code: "endurance-1", resultat: "echec", description: "Perte de 1 point d'endurance" },
{ code: "endurance-f", resultat: "echec", description: "Perte de (force) point d'endurance" },
{ code: "fatigue-1", resultat: "echec", description: "Perte de 1 point de fatigue" },
{ code: "fatigue-f", resultat: "echec", description: "Perte de (force) point de fatigue" },
{ code: "moral-1", resultat: "echec", description: "Perte de 1 point de moral" },
{ code: "chance-1", resultat: "echec", description: "Perte de 1 point de chance actuelle" },
{ code: "chance-f", resultat: "echec", description: "Perte de (force) point de chance" },
{ code: "epart-queue", resultat: "echec", description: "Queue de dragon sur échec particulier" },
{ code: "etotal-souffle", resultat: "echec", description: "Souffle de dragon sur échec total" },
{ code: "epart-souffle", resultat: "echec", description: "Souffle de dragon sur échec particulier" },
];
export class RdDRencontre {
static getEffets(resultat) {
return tableEffets.filter(e => resultat == e.resultat);
}
static getEffetsSucces() { return RdDRencontre.getEffets("succes"); }
static getEffetsEchec() { return RdDRencontre.getEffets("echec"); }
static mapEffets(liste) {
return liste.map(it => tableEffets.find(e => it == e.code));
}
static getListeEffets(item, reussite) {
if (reussite == 'echec') {
return [...item.system.echec.effets];
}
if (reussite == 'succes') {
return [...item.system.succes.effets];
}
return [];
}
}

View File

@ -1,7 +1,6 @@
import { SYSTEM_RDD } from "./constants.js";
import { RdDItemSigneDraconique } from "./item-signedraconique.js";
import { Misc } from "./misc.js";
import { TMRType, TMRUtility } from "./tmr-utility.js";
import { TMRUtility } from "./tmr-utility.js";
/**
* Item sheet pour signes draconiques

View File

@ -18,7 +18,7 @@ const typesObjetsEquipement = [
"potion",
]
const typesObjetsOeuvres = ["oeuvre", "recettecuisine", "musique", "chant", "danse", "jeu"]
const typesObjetsDraconiques = ["queue", "ombre", "souffle", "tete", "signedraconique", "sortreserve"]
const typesObjetsDraconiques = ["queue", "ombre", "souffle", "tete", "signedraconique", "sortreserve", "rencontre"]
const typesObjetsConnaissance = ["meditation", "recettealchimique", "sort"]
const typesObjetsEffet = ["possession", "poison", "maladie"]
const typesObjetsCompetence = ["competence", "competencecreature"]
@ -38,6 +38,7 @@ export const defaultItemImg = {
ingredient: "systems/foundryvtt-reve-de-dragon/icons/objets/sable_poudre.webp",
livre: "systems/foundryvtt-reve-de-dragon/icons/objets/livre.webp",
potion: "systems/foundryvtt-reve-de-dragon/icons/objets/liqueur_de_bagdol.webp",
rencontre: "systems/foundryvtt-reve-de-dragon/icons/tete_dragon.webp",
queue: "systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp",
ombre: "systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp",
souffle: "systems/foundryvtt-reve-de-dragon/icons/souffle_dragon.webp",
@ -504,6 +505,20 @@ export class RdDItem extends Item {
]
}
/* -------------------------------------------- */
_rencontreChatData() {
if (this.system.coord) {
return [
`<b>Force</b>: ${this.system.force}`,
`<b>Coordonnées</b>: ${this.system.coord}`,
]
}
return [
`<b>Force</b>: ${this.system.force}`,
`<b>Refoulement</b>: ${this.system.refoulement}`,
`<b>Présent de cités</b>: ${this.system.presentCite}`,
]
}
/* -------------------------------------------- */
_casetmrChatData() {
return [
`<b>Coordonnée</b>: ${this.system.coord}`,

View File

@ -38,6 +38,7 @@ import { Misc } from "./misc.js";
import { Migrations } from './migrations.js';
import { DialogChronologie } from "./dialog-chronologie.js";
import { SystemCompendiums } from "./settings/system-compendiums.js";
import { RdDRencontreItemSheet } from "./item-rencontre-sheet.js";
/* -------------------------------------------- */
/* Foundry VTT Initialization */
@ -188,10 +189,21 @@ Hooks.once("init", async function () {
types: ["signedraconique"],
makeDefault: true
});
Items.registerSheet(SYSTEM_RDD, RdDRencontreItemSheet, {
label: "Rencontre",
types: ["rencontre"],
makeDefault: true
});
Items.registerSheet(SYSTEM_RDD, RdDItemSheet, {
types: ["arme", "armure", "objet", "arme", "armure", "conteneur", "competence", "sort", "herbe", "ingredient", "livre", "potion", "munition", "rencontresTMR", "queue", "ombre", "souffle",
"tete", "competencecreature", "tarot", "monnaie", "nombreastral", "tache", "meditation", "casetmr", "recettealchimique", "gemme",
"musique", "chant", "danse", "jeu", "recettecuisine", "maladie", "poison", "oeuvre", "nourritureboisson", "possession", "sortreserve"], makeDefault: true
types: [
"competence", "competencecreature",
"recettealchimique", "musique", "chant", "danse", "jeu", "recettecuisine", "oeuvre",
"objet", "arme", "armure", "conteneur", "herbe", "ingredient", "livre", "potion", "munition",
"monnaie", "nourritureboisson", "gemme",
"meditation", "rencontresTMR", "queue", "ombre", "souffle", "tete", "casetmr", "sort", "sortreserve",
"nombreastral", "tache", "maladie", "poison", "possession",
"tarot"
], makeDefault: true
});
CONFIG.Combat.documentClass = RdDCombatManager;

View File

@ -181,6 +181,7 @@ export class RdDUtility {
'systems/foundryvtt-reve-de-dragon/templates/item-livre-sheet.html',
'systems/foundryvtt-reve-de-dragon/templates/item-tache-sheet.html',
'systems/foundryvtt-reve-de-dragon/templates/item-potion-sheet.html',
'systems/foundryvtt-reve-de-dragon/templates/item-rencontre-sheet.html',
'systems/foundryvtt-reve-de-dragon/templates/item-rencontresTMR-sheet.html',
'systems/foundryvtt-reve-de-dragon/templates/item-queue-sheet.html',
'systems/foundryvtt-reve-de-dragon/templates/item-souffle-sheet.html',
@ -279,6 +280,7 @@ export class RdDUtility {
Handlebars.registerHelper('caseTmr-label', coord => TMRUtility.getTMRLabel(coord));
Handlebars.registerHelper('caseTmr-type', coord => TMRUtility.getTMRType(coord));
Handlebars.registerHelper('typeTmr-name', coord => TMRUtility.typeTmrName(coord));
Handlebars.registerHelper('effetRencontre-name', coord => TMRUtility.typeTmrName(coord));
Handlebars.registerHelper('signeHeure', (key, heure) => RdDCalendrier.getSigneAs(key, heure));
Handlebars.registerHelper('min', (...args) => Math.min(...args.slice(0, -1)));
Handlebars.registerHelper('regle-optionnelle', (option) => ReglesOptionelles.isUsing(option));

View File

@ -11,7 +11,7 @@ const typeRencontres = {
if (rencData.actor.isTMRCache()){
return `Le ${rencData.rencontre.name} vous propose d'emmener le message de votre un sort, mais vous ne savez pas où vous êtes.`;
}
return `Le ${rencData.rencontre.name} vous propose d'emmener le message de votre un sort à ${rencData.rencontre.force} cases ${rencData.tmr.label}.`;
return `Le ${rencData.rencontre.name} vous propose d'emmener le message de votre un sort à ${rencData.rencontre.force} cases de ${rencData.tmr.label}.`;
},
msgEchec: async (rencData)=> `Le ${rencData.rencontre.name} est pressé et continue son chemin d'une traite sans vous accorder un regard.`,
postSucces: async (tmrDialog, rencData) => {