Les rencontres sont configurables #572
@ -101,7 +101,6 @@ export class RdDActorSheet extends ActorSheet {
|
||||
|
||||
formData.hautreve = {
|
||||
isDemiReve: this.actor.getEffect(STATUSES.StatusDemiReve),
|
||||
rencontres: duplicate(formData.system.reve.rencontre.list),
|
||||
cacheTMR: this.actor.isTMRCache()
|
||||
}
|
||||
|
||||
@ -170,9 +169,6 @@ export class RdDActorSheet extends ActorSheet {
|
||||
const item = RdDSheetUtility.getItem(event, this.actor);
|
||||
item.sheet.render(true);
|
||||
});
|
||||
html.find('.rencontre-delete').click(async event => {
|
||||
this.actor.deleteTMRRencontre(RdDSheetUtility.getItemId(event));
|
||||
});
|
||||
html.find('.item-delete').click(async event => {
|
||||
const li = RdDSheetUtility.getEventElement(event);
|
||||
const item = this.actor.getObjet(li.data("item-id"));
|
||||
|
@ -36,6 +36,7 @@ import { RdDPossession } from "./rdd-possession.js";
|
||||
import { ENTITE_BLURETTE, ENTITE_INCARNE, ENTITE_NONINCARNE, HIDE_DICE, SHOW_DICE, SYSTEM_RDD, SYSTEM_SOCKET_ID } from "./constants.js";
|
||||
import { RdDConfirm } from "./rdd-confirm.js";
|
||||
import { DialogValidationEncaissement } from "./dialog-validation-encaissement.js";
|
||||
import { RdDRencontre } from "./item-rencontre.js";
|
||||
|
||||
const POSSESSION_SANS_DRACONIC = {
|
||||
img: 'systems/foundryvtt-reve-de-dragon/icons/entites/possession.webp',
|
||||
@ -757,25 +758,24 @@ export class RdDActor extends Actor {
|
||||
actor: this,
|
||||
competence: duplicate(this.getDraconicOuPossession()),
|
||||
canClose: false,
|
||||
rencontre: duplicate(TMRRencontres.getRencontre('rdd')),
|
||||
rencontre: await TMRRencontres.getReveDeDragon(force),
|
||||
tmr: true,
|
||||
use: { libre: false, conditions: false },
|
||||
forceCarac: { 'reve-actuel': { label: "Rêve Actuel", value: this.getReveActuel() } }
|
||||
}
|
||||
rollData.rencontre.force = force;
|
||||
rollData.competence.system.defaut_carac = 'reve-actuel';
|
||||
|
||||
const dialog = await RdDRoll.create(this, rollData,
|
||||
{
|
||||
html: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-reve-de-dragon.html',
|
||||
options: { height: 400 }
|
||||
options: { height: 'fit-content' }
|
||||
},
|
||||
{
|
||||
name: 'maitrise',
|
||||
label: 'Maîtriser le Rêve de Dragon',
|
||||
callbacks: [
|
||||
this.createCallbackExperience(),
|
||||
{ action: async r => this.resultCombatReveDeDragon(r) }
|
||||
{ action: async r =>
|
||||
this.resultCombatReveDeDragon(r) }
|
||||
]
|
||||
}
|
||||
);
|
||||
@ -784,27 +784,11 @@ export class RdDActor extends Actor {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async resultCombatReveDeDragon(rollData) {
|
||||
rollData.queues = [];
|
||||
if (rollData.rolled.isEchec) {
|
||||
rollData.queues.push(await this.ajouterQueue());
|
||||
}
|
||||
if (rollData.rolled.isETotal) {
|
||||
rollData.queues.push(await this.ajouterQueue());
|
||||
}
|
||||
if (rollData.rolled.isSuccess) {
|
||||
await this.updatePointDeSeuil();
|
||||
await this.reveActuelIncDec(rollData.rencontre.force);
|
||||
}
|
||||
if (rollData.rolled.isPart) {
|
||||
// TODO: un dialogue pour demander le type de tête?
|
||||
rollData.tete = true;
|
||||
}
|
||||
rollData.poesie = await Poetique.getExtrait();
|
||||
const result = rollData.rolled.isSuccess
|
||||
? rollData.rencontre.system.succes
|
||||
: rollData.rencontre.system.echec;
|
||||
|
||||
ChatMessage.create({
|
||||
whisper: ChatUtility.getWhisperRecipientsAndGMs(this.name),
|
||||
content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-resultat-reve-de-dragon.html`, rollData)
|
||||
});
|
||||
RdDRencontre.appliquer(result.effets, {}, rollData)
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
@ -1541,42 +1525,27 @@ export class RdDActor extends Actor {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
getTMRRencontres() {
|
||||
return this.system.reve.rencontre.list;
|
||||
return this.itemTypes['rencontre'];
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async deleteTMRRencontreAtPosition() {
|
||||
let rencontres = this.getTMRRencontres();
|
||||
let newRencontres = rencontres.filter(it => it.coord != this.getDemiReve());
|
||||
if (newRencontres.length != rencontres.length) {
|
||||
await this.update({ "system.reve.rencontre.list": newRencontres });
|
||||
const demiReve = this.getDemiReve()
|
||||
let rencontreIds = this.items.filter(it => it.type == 'rencontre' && it.system.coord == demiReve).map(it => it.id);
|
||||
if (rencontreIds.length>0) {
|
||||
await this.deleteEmbeddedDocuments('Item', rencontreIds);
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async addTMRRencontre(currentRencontre) {
|
||||
let rencontres = this.getTMRRencontres();
|
||||
let newRencontres = rencontres.filter(it => it.coord != this.getDemiReve());
|
||||
if (newRencontres.length == rencontres.length) {
|
||||
newRencontres.push(currentRencontre);
|
||||
await this.update({ "system.reve.rencontre.list": newRencontres });
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async deleteTMRRencontre(rencontreKey) {
|
||||
let list = duplicate(this.system.reve.rencontre.list);
|
||||
let newList = [];
|
||||
for (let i = 0; i < list.length; i++) {
|
||||
if (i != rencontreKey)
|
||||
newList.push(list[i]);
|
||||
}
|
||||
await this.update({ "system.reve.rencontre.list": newList });
|
||||
const toCreate = currentRencontre.toObject();
|
||||
console.log('actor.addTMRRencontre(', toCreate,')');
|
||||
this.createEmbeddedDocuments('Item', [toCreate]);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async updateCoordTMR(coord) {
|
||||
//console.log("UPDATE TMR", coord);
|
||||
await this.update({ "system.reve.tmrpos.coord": coord });
|
||||
}
|
||||
|
||||
@ -2383,7 +2352,7 @@ export class RdDActor extends Actor {
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
isRencontreSpeciale() { // Gestion queue/souffle 'Mauvaise Rencontre en Perpective'
|
||||
isMauvaiseRencontre() { // Gestion queue/souffle 'Mauvaise Rencontre en Perpective'
|
||||
let addMsg = "";
|
||||
let rencSpecial = EffetsDraconiques.mauvaiseRencontre(this);
|
||||
if (rencSpecial) {
|
||||
@ -3825,7 +3794,7 @@ export class RdDActor extends Actor {
|
||||
/* -------------------------------------------- */
|
||||
_buildActorLinksList(links, actorTransformation = it => RdDActor._buildActorData(it)) {
|
||||
return links.map(link => game.actors.get(link.id))
|
||||
.filter(it => it != null)
|
||||
.filter(it => it != undefined)
|
||||
.map(actorTransformation);
|
||||
}
|
||||
|
||||
|
111
module/effets-rencontres.js
Normal file
111
module/effets-rencontres.js
Normal file
@ -0,0 +1,111 @@
|
||||
import { ChatUtility } from "./chat-utility.js";
|
||||
import { Poetique } from "./poetique.js";
|
||||
import { RdDDice } from "./rdd-dice.js";
|
||||
import { TMRUtility } from "./tmr-utility.js";
|
||||
|
||||
export class EffetsRencontre {
|
||||
|
||||
static messager = async (dialog, context) => {
|
||||
dialog.setRencontreState('messager', TMRUtility.getTMRPortee(context.tmr.coord, context.rencontre.system.force));
|
||||
}
|
||||
|
||||
static passeur = async (dialog, context) => {
|
||||
dialog.setRencontreState('passeur', TMRUtility.getTMRPortee(context.tmr.coord, context.rencontre.system.force));
|
||||
}
|
||||
|
||||
static teleportation_typecase = async (dialog, context) => {
|
||||
dialog.setRencontreState('changeur', TMRUtility.getCasesType(context.tmr.type));
|
||||
}
|
||||
|
||||
static rencontre_persistante = async (dialog, context) => {
|
||||
dialog.setRencontreState('persistant', []);
|
||||
}
|
||||
|
||||
static reve_plus_f = async (dialog, context) => { await EffetsRencontre.$reve_plus(context.actor, context.rencontre.system.force) }
|
||||
static reve_plus_1 = async (dialog, context) => { await EffetsRencontre.$reve_plus(context.actor, 1) }
|
||||
static reve_moins_f = async (dialog, context) => { await EffetsRencontre.$reve_plus(context.actor, -context.rencontre.system.force) }
|
||||
static reve_moins_1 = async (dialog, context) => { await EffetsRencontre.$reve_plus(context.actor, -1) }
|
||||
|
||||
static vie_moins_1 = async (dialog, context) => { await EffetsRencontre.$vie_plus(context.actor, -1) }
|
||||
|
||||
|
||||
static reinsertion = async (dialog, context) => {
|
||||
await EffetsRencontre.$reinsertion(dialog, context.actor, it => true)
|
||||
}
|
||||
|
||||
static teleportation_aleatoire_typecase = async (dialog, context) => {
|
||||
await EffetsRencontre.$reinsertion(dialog, context.actor, it => it.type == context.tmr.type && it.coord != context.tmr.coord)
|
||||
}
|
||||
|
||||
static demireve_rompu = async (dialog, context) => {
|
||||
dialog.close()
|
||||
}
|
||||
|
||||
static sort_aleatoire = async (dialog, context) => {
|
||||
context.sortReserve = await RdDDice.rollOneOf(context.actor.itemTypes['sortreserve']);
|
||||
if (context.sortReserve) {
|
||||
context.newTMR = TMRUtility.getTMR(context.sortReserve.system.coord);
|
||||
await dialog.positionnerDemiReve(context.newTMR.coord);
|
||||
await dialog.processSortReserve(context.sortReserve);
|
||||
dialog.close();
|
||||
}
|
||||
else {
|
||||
await EffetsRencontre.$reinsertion(dialog, context.actor, it => true);
|
||||
}
|
||||
}
|
||||
|
||||
static deplacement_aleatoire = async (dialog, context) => {
|
||||
const oldCoord = context.actor.system.reve.tmrpos.coord;
|
||||
const newTmr = await TMRUtility.deplaceTMRAleatoire(context.actor, oldCoord);
|
||||
await dialog.positionnerDemiReve(newTmr.coord)
|
||||
}
|
||||
|
||||
static rdd_part_tete = async (dialog, context) => {
|
||||
mergeObject(context, {
|
||||
tete: context.rolled.isPart,
|
||||
poesie: await Poetique.getExtrait()
|
||||
})
|
||||
ChatMessage.create({
|
||||
whisper: ChatUtility.getWhisperRecipientsAndGMs(context.actor.name),
|
||||
content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-resultat-reve-de-dragon.html`, context)
|
||||
});
|
||||
}
|
||||
|
||||
static rdd_echec_queue = async (dialog, context) => {
|
||||
mergeObject(context, {
|
||||
queues: [await context.actor.ajouterQueue()],
|
||||
poesie: await Poetique.getExtrait()
|
||||
})
|
||||
if (context.rolled.isETotal) {
|
||||
context.queues.push(await context.actor.ajouterQueue());
|
||||
}
|
||||
|
||||
ChatMessage.create({
|
||||
whisper: ChatUtility.getWhisperRecipientsAndGMs(this.name),
|
||||
content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-resultat-reve-de-dragon.html`, context)
|
||||
});
|
||||
}
|
||||
|
||||
static experience_particuliere = async (dialog, context) => {
|
||||
await context.actor.appliquerAjoutExperience(context)
|
||||
}
|
||||
|
||||
static regain_seuil = async (dialog, context) => {
|
||||
await context.actor.regainPointDeSeuil()
|
||||
}
|
||||
|
||||
static $reve_plus = async (actor, valeur) => {
|
||||
await actor.reveActuelIncDec(valeur);
|
||||
}
|
||||
|
||||
static $vie_plus = async (actor, valeur) => {
|
||||
await actor.santeIncDec("vie", valeur);
|
||||
}
|
||||
|
||||
static async $reinsertion(dialog, actor, filter) {
|
||||
const newTMR = await TMRUtility.getTMRAleatoire(filter);
|
||||
await actor.forcerPositionTMRInconnue(newTMR);
|
||||
await dialog.positionnerDemiReve(newTMR.coord);
|
||||
}
|
||||
|
||||
}
|
@ -1,4 +1,3 @@
|
||||
import { SYSTEM_RDD } from "./constants.js";
|
||||
import { RdDRencontre } from "./item-rencontre.js";
|
||||
|
||||
/**
|
||||
|
@ -1,50 +1,36 @@
|
||||
import { RdDRollTables } from "./rdd-rolltables.js";
|
||||
import { EffetsRencontre } from "./effets-rencontres.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: "messager", resultat: "succes", description: "Envoie un message à (force) cases", method: EffetsRencontre.messager },
|
||||
{ code: "passeur", resultat: "succes", description: "Déplacer le demi-rêve à (force) cases", method: EffetsRencontre.passeur},
|
||||
{ code: "reve+f", resultat: "succes", description: "Gain de (force) points de rêve" , method: EffetsRencontre.reve_plus_f},
|
||||
{ code: "teleport", resultat: "succes", description: "Déplacer le demi-rêve (même type)", method: EffetsRencontre.teleportation_typecase },
|
||||
{ code: "part+tete", resultat: "succes", description: "Tête de dragon sur réussite particulière", method: EffetsRencontre.rdd_part_tete },
|
||||
{ code: "part+xp", resultat: "succes", description: "Expérience sur réussite particulière", method: EffetsRencontre.experience_particuliere },
|
||||
{ code: "seuil", resultat: "succes", description: "Récupération de seuil de rêve", method: EffetsRencontre.regain_seuil },
|
||||
|
||||
{ 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" },
|
||||
{ code: "reve-1", resultat: "echec", description: "Perte de 1 point de rêve", method: EffetsRencontre.reve_moins_1 },
|
||||
{ code: "reve-f", resultat: "echec", description: "Perte de (force) points de rêve", method: EffetsRencontre.reve_moins_f },
|
||||
{ code: "vie-1", resultat: "echec", description: "Perte de 1 point de vie", method: EffetsRencontre.vie_moins_1 },
|
||||
{ code: "reinsere", resultat: "echec", description: "Réinsertion aléatoire", method: EffetsRencontre.reinsertion },
|
||||
{ code: "persistant", resultat: "echec", description: "Bloque le demi-rêve", method: EffetsRencontre.rencontre_persistante },
|
||||
{ code: "teleport-aleatoire", resultat: "echec", description: "Déplacement aléatoire (même type)", method: EffetsRencontre.teleportation_aleatoire_typecase },
|
||||
{ code: "aleatoire", resultat: "echec", description: "Déplacement aléatoire", method: EffetsRencontre.deplacement_aleatoire },
|
||||
{ code: "sort-aleatoire", resultat: "echec", description: "Déclenche un sort en réserve aléatoire", method: EffetsRencontre.sort_aleatoire },
|
||||
{ code: "rompu", resultat: "echec", description: "Demi-rêve interrompu", method: EffetsRencontre.demireve_rompu },
|
||||
{ code: "echec-queue", resultat: "echec", description: "Queue(s) de dragon sur échec", method: EffetsRencontre.rdd_echec_queue },
|
||||
];
|
||||
|
||||
export class RdDRencontre {
|
||||
|
||||
static getEffetsSucces() { return RdDRencontre.getEffets("succes"); }
|
||||
static getEffetsEchec() { return RdDRencontre.getEffets("echec"); }
|
||||
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));
|
||||
return liste.map(it => RdDRencontre.getEffet(it));
|
||||
}
|
||||
|
||||
static getListeEffets(item, reussite) {
|
||||
@ -57,4 +43,14 @@ export class RdDRencontre {
|
||||
return [];
|
||||
}
|
||||
|
||||
static getEffet(code) {
|
||||
return tableEffets.find(it => code == it.code)
|
||||
}
|
||||
|
||||
static async appliquer(codes, tmrDialog, rencData) {
|
||||
for(const effet of RdDRencontre.mapEffets(codes)){
|
||||
await effet.method(tmrDialog, rencData);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -43,7 +43,7 @@ class _10_0_16_MigrationSortsReserve extends Migration {
|
||||
await actor.createEmbeddedDocuments("Item", sortsReserve, {
|
||||
renderSheet: false,
|
||||
});
|
||||
await actor.update({ 'system.reve.reserve.list': [] })
|
||||
await actor.update({ 'system.reve.reserve': undefined })
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -86,14 +86,14 @@ export class RdDCalendrier extends Application {
|
||||
|
||||
getCalendrier(index) {
|
||||
index = index ?? this.getCurrentDayIndex();
|
||||
const moisRdD = Math.floor(index / RDD_JOUR_PAR_MOIS) % RDD_MOIS_PAR_AN;
|
||||
const mois = Math.floor(index / RDD_JOUR_PAR_MOIS) % RDD_MOIS_PAR_AN;
|
||||
return {
|
||||
heureRdD: 0, // Index dans heuresList / heuresDef[x].heure
|
||||
minutesRelative: 0,
|
||||
indexJour: index,
|
||||
annee: Math.floor(index / (RDD_JOUR_PAR_MOIS * RDD_MOIS_PAR_AN)),
|
||||
moisRdD: RdDCalendrier.getDefSigne(moisRdD),
|
||||
moisLabel: RdDCalendrier.getDefSigne(moisRdD).label,
|
||||
moisRdD: RdDCalendrier.getDefSigne(mois),
|
||||
moisLabel: RdDCalendrier.getDefSigne(mois).label,
|
||||
jour: (index % RDD_JOUR_PAR_MOIS) // Le calendrier stocke le jour en 0-27, mais en 1-28 à l'affichage
|
||||
}
|
||||
}
|
||||
@ -138,7 +138,7 @@ export class RdDCalendrier extends Application {
|
||||
/* -------------------------------------------- */
|
||||
getDateFromIndex(index) {
|
||||
const dateRdD = this.getCalendrier(index);
|
||||
return (dateRdD.jour + 1) + ' ' + RdDCalendrier.getDefSigne(dateRdD.moisRdD).label;
|
||||
return (dateRdD.jour + 1) + ' ' + dateRdD.moisLabel;
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
|
@ -221,7 +221,6 @@ Hooks.once("init", async function () {
|
||||
RddCompendiumOrganiser.init();
|
||||
EffetsDraconiques.init()
|
||||
TMRUtility.init();
|
||||
TMRRencontres.init();
|
||||
RdDHotbar.initDropbar();
|
||||
RdDPossession.init();
|
||||
});
|
||||
|
@ -1,3 +1,4 @@
|
||||
import { SHOW_DICE } from "./constants.js";
|
||||
import { RollDataAjustements } from "./rolldata-ajustements.js";
|
||||
import { RdDUtility } from "./rdd-utility.js";
|
||||
import { TMRUtility } from "./tmr-utility.js";
|
||||
@ -11,11 +12,12 @@ import { Poetique } from "./poetique.js";
|
||||
import { EffetsDraconiques } from "./tmr/effets-draconiques.js";
|
||||
import { PixiTMR } from "./tmr/pixi-tmr.js";
|
||||
import { Draconique } from "./tmr/draconique.js";
|
||||
import { Misc } from "./misc.js";
|
||||
import { HtmlUtility } from "./html-utility.js";
|
||||
import { ReglesOptionelles } from "./settings/regles-optionelles.js";
|
||||
import { RdDDice } from "./rdd-dice.js";
|
||||
import { STATUSES } from "./settings/status-effects.js";
|
||||
import { RdDRencontre } from "./item-rencontre.js";
|
||||
|
||||
/* -------------------------------------------- */
|
||||
|
||||
export class RdDTMRDialog extends Dialog {
|
||||
@ -146,7 +148,7 @@ export class RdDTMRDialog extends Dialog {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
_tokenRencontre(rencontre) {
|
||||
return EffetsDraconiques.rencontre.token(this.pixiTMR, rencontre, () => rencontre.coord);
|
||||
return EffetsDraconiques.rencontre.token(this.pixiTMR, rencontre, () => rencontre.system.coord);
|
||||
}
|
||||
_tokenCaseSpeciale(casetmr) {
|
||||
const caseData = casetmr;
|
||||
@ -280,25 +282,44 @@ export class RdDTMRDialog extends Dialog {
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async onActionRencontre(action, tmr) {
|
||||
switch (action) {
|
||||
case 'derober':
|
||||
await this.derober();
|
||||
return;
|
||||
case 'refouler':
|
||||
await this.refouler();
|
||||
break;
|
||||
case 'maitriser':
|
||||
await this.maitriserRencontre();
|
||||
break;
|
||||
case 'ignorer':
|
||||
await this.ignorerRencontre();
|
||||
break;
|
||||
}
|
||||
await this.postRencontre(tmr);
|
||||
}
|
||||
|
||||
async derober() {
|
||||
await this.actor.addTMRRencontre(this.currentRencontre);
|
||||
console.log("-> derober", this.currentRencontre);
|
||||
await this.actor.addTMRRencontre(this.currentRencontre);
|
||||
this._tellToGM(this.actor.name + " s'est dérobé et quitte les TMR.");
|
||||
this.close();
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async refouler() {
|
||||
await this.actor.ajouterRefoulement(this.currentRencontre.refoulement ?? 1, `une rencontre ${this.currentRencontre.name}`);
|
||||
console.log("-> refouler", this.currentRencontre);
|
||||
await this.actor.ajouterRefoulement(this.currentRencontre.system.refoulement, `${this.currentRencontre.system.genre == 'f' ? 'une' : 'un'} ${this.currentRencontre.name}`);
|
||||
await this.actor.deleteTMRRencontreAtPosition(); // Remove the stored rencontre if necessary
|
||||
this.updateTokens();
|
||||
console.log("-> refouler", this.currentRencontre)
|
||||
this.updateValuesDisplay();
|
||||
this.nettoyerRencontre();
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async ignorerRencontre() {
|
||||
console.log("-> ignorer", this.currentRencontre);
|
||||
this._tellToGM(this.actor.name + " a ignoré: " + this.currentRencontre.name);
|
||||
await this.actor.deleteTMRRencontreAtPosition(); // Remove the stored rencontre if necessary
|
||||
this.updateTokens();
|
||||
@ -307,7 +328,14 @@ export class RdDTMRDialog extends Dialog {
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
colorierZoneRencontre(listCoordTMR) {
|
||||
// garder la trace de l'état en cours
|
||||
setRencontreState(state, listCoordTMR) {
|
||||
this.rencontreState = state;
|
||||
this.$marquerCasesTMR(listCoordTMR ?? []);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
$marquerCasesTMR(listCoordTMR) {
|
||||
this.currentRencontre.graphics = []; // Keep track of rectangles to delete it
|
||||
this.currentRencontre.locList = duplicate(listCoordTMR); // And track of allowed location
|
||||
for (let coordTMR of listCoordTMR) {
|
||||
@ -323,23 +351,6 @@ export class RdDTMRDialog extends Dialog {
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
// garder la trace de l'état en cours
|
||||
setStateRencontre(state) {
|
||||
this.rencontreState = state;
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async choisirCasePortee(coord, portee) {
|
||||
// Récupère la liste des cases à portées
|
||||
this.colorierZoneRencontre(TMRUtility.getTMRPortee(coord, portee));
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async choisirCaseType(type) {
|
||||
this.colorierZoneRencontre(TMRUtility.filterTMR(it => it.type == type).map(it => it.coord));
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
checkQuitterTMR() {
|
||||
|
||||
@ -370,7 +381,9 @@ export class RdDTMRDialog extends Dialog {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async maitriserRencontre() {
|
||||
this.actor.deleteTMRRencontreAtPosition();
|
||||
console.log("-> maitriser", this.currentRencontre);
|
||||
|
||||
await this.actor.deleteTMRRencontreAtPosition();
|
||||
this.updateTokens();
|
||||
|
||||
let rencontreData = {
|
||||
@ -390,8 +403,6 @@ export class RdDTMRDialog extends Dialog {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async _tentativeMaitrise(rencData) {
|
||||
console.log("-> matriser", rencData);
|
||||
|
||||
rencData.reve = this.actor.getReveActuel();
|
||||
rencData.etat = this.actor.getEtatGeneral();
|
||||
|
||||
@ -401,27 +412,35 @@ export class RdDTMRDialog extends Dialog {
|
||||
? this._rollPresentCite(rencData)
|
||||
: await RdDResolutionTable.roll(rencData.reve, RollDataAjustements.sum(rencData.ajustements));
|
||||
|
||||
let postProcess = await TMRRencontres.gererRencontre(this, rencData);
|
||||
const result = rencData.rolled.isSuccess
|
||||
? rencData.rencontre.system.succes
|
||||
: rencData.rencontre.system.echec;
|
||||
|
||||
await RdDRencontre.appliquer(result.effets, this, rencData);
|
||||
|
||||
rencData.poesie = { extrait: result.poesie, reference: result.reference };
|
||||
rencData.message = this.formatMessageRencontre(rencData, result.message);
|
||||
|
||||
ChatMessage.create({
|
||||
whisper: ChatUtility.getWhisperRecipientsAndGMs(game.user.name),
|
||||
content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-rencontre-tmr.html`, rencData)
|
||||
});
|
||||
|
||||
if (postProcess) {
|
||||
/** Gère les rencontres avec du post-processing (passeur, messagers, tourbillons, ...) */
|
||||
await postProcess(this, rencData);
|
||||
}
|
||||
else {
|
||||
this.currentRencontre = undefined;
|
||||
}
|
||||
|
||||
this.updateValuesDisplay();
|
||||
if (this.checkQuitterTMR()) {
|
||||
return;
|
||||
}
|
||||
else if (rencData.rolled.isEchec && rencData.rencontre.isPersistant) {
|
||||
if (this.rencontreState == 'persistant') {
|
||||
this._nouvelleTentativeMaitrise(rencData);
|
||||
}
|
||||
else if (!this.isRencontreDeplacement()) {
|
||||
this.nettoyerRencontre();
|
||||
}
|
||||
}
|
||||
|
||||
_nouvelleTentativeMaitrise(rencData) {
|
||||
setTimeout(() => {
|
||||
// TODO: remplacer par une boucle while(this.currentRencontre) ?
|
||||
rencData.nbRounds++;
|
||||
if (ReglesOptionelles.isUsing("appliquer-fatigue")) {
|
||||
this.cumulFatigue += this.fatigueParCase;
|
||||
@ -429,13 +448,31 @@ export class RdDTMRDialog extends Dialog {
|
||||
this._tentativeMaitrise(rencData);
|
||||
this._deleteTmrMessages(rencData.actor, rencData.nbRounds);
|
||||
}, 2000);
|
||||
this.rencontreState == 'normal';
|
||||
}
|
||||
|
||||
formatMessageRencontre(rencData, template) {
|
||||
let messageDuree = ''
|
||||
if (rencData.nbRounds > 1) {
|
||||
if (rencData.rolled.isSuccess) {
|
||||
messageDuree = ` Au total, vous avez passé ${rencData.nbRounds} rounds à vous battre!`;
|
||||
}
|
||||
else {
|
||||
messageDuree = ` Vous avez passé ${rencData.nbRounds} rounds à lutter!`;
|
||||
}
|
||||
}
|
||||
try {
|
||||
const compiled = Handlebars.compile(template);
|
||||
return compiled(rencData) + messageDuree ;
|
||||
} catch (error) {
|
||||
return template + messageDuree ;
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
_rollPresentCite(rencontreData) {
|
||||
let rolled = RdDResolutionTable.computeChances(rencontreData.reve, 0);
|
||||
mergeObject(rolled, { caracValue: rencontreData.reve, finalLevel: 0, roll: rolled.score });
|
||||
_rollPresentCite(rencData) {
|
||||
let rolled = RdDResolutionTable.computeChances(rencData.reve, 0);
|
||||
mergeObject(rolled, { caracValue: rencData.reve, finalLevel: 0, roll: rolled.score });
|
||||
RdDResolutionTable.succesRequis(rolled);
|
||||
return rolled;
|
||||
}
|
||||
@ -479,16 +516,17 @@ export class RdDTMRDialog extends Dialog {
|
||||
if (this._presentCite(tmr)) {
|
||||
return;
|
||||
}
|
||||
let rencontre = await this._jetDeRencontre(tmr);
|
||||
|
||||
if (rencontre) { // Manages it
|
||||
if (rencontre.rencontre) rencontre = rencontre.rencontre; // Manage stored rencontres
|
||||
console.log("manageRencontre", rencontre);
|
||||
this.currentRencontre = duplicate(rencontre);
|
||||
|
||||
let dialog = new RdDTMRRencontreDialog(this, this.currentRencontre, () => this.postRencontre(tmr));
|
||||
this.currentRencontre = await this._jetDeRencontre(tmr);
|
||||
if (this.currentRencontre) {
|
||||
if (this.rencontresExistantes.find(it => it.id == this.currentRencontre.id)){
|
||||
// rencontre en attente suite à dérobade
|
||||
await this.maitriserRencontre();
|
||||
}
|
||||
else {
|
||||
let dialog = new RdDTMRRencontreDialog(this, this.currentRencontre, tmr);
|
||||
dialog.render(true);
|
||||
}
|
||||
}
|
||||
else {
|
||||
this.postRencontre(tmr);
|
||||
}
|
||||
@ -500,15 +538,18 @@ export class RdDTMRDialog extends Dialog {
|
||||
if (presentCite) {
|
||||
this.minimize();
|
||||
const caseData = presentCite;
|
||||
EffetsDraconiques.presentCites.choisirUnPresent(caseData, (type => this._utiliserPresentCite(presentCite, type, tmr)));
|
||||
EffetsDraconiques.presentCites.choisirUnPresent(caseData, (present => this._utiliserPresentCite(presentCite, present, tmr)));
|
||||
}
|
||||
return presentCite;
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async _utiliserPresentCite(presentCite, typeRencontre, tmr) {
|
||||
this.currentRencontre = TMRRencontres.getRencontre(typeRencontre);
|
||||
await TMRRencontres.evaluerForceRencontre(this.currentRencontre);
|
||||
async _utiliserPresentCite(presentCite, present, tmr) {
|
||||
this.currentRencontre = present.clone({
|
||||
'system.force': await RdDDice.rollTotal(present.system.formule),
|
||||
'system.coord': tmr.coord
|
||||
}, {save: false});
|
||||
|
||||
await EffetsDraconiques.presentCites.ouvrirLePresent(this.actor, presentCite);
|
||||
this.removeToken(tmr, presentCite);
|
||||
|
||||
@ -530,32 +571,27 @@ export class RdDTMRDialog extends Dialog {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async _jetDeRencontre(tmr) {
|
||||
let rencontre = this.rencontresExistantes.find(prev => prev.coord == tmr.coord);
|
||||
let rencontre = this.lookupRencontreExistente(tmr);
|
||||
if (rencontre) {
|
||||
return rencontre;
|
||||
return TMRRencontres.calculRencontre(rencontre, tmr);
|
||||
}
|
||||
let locTMR = (this.isDemiReveCache()
|
||||
? Misc.upperFirst(tmr.type) + " ??"
|
||||
? TMRUtility.getTMRType(tmr.coord) + " ??"
|
||||
: tmr.label + " (" + tmr.coord + ")");
|
||||
|
||||
let myRoll = await RdDDice.rollTotal("1dt");
|
||||
if (TMRUtility.isForceRencontre() || myRoll == 7) {
|
||||
let myRoll = await RdDDice.rollTotal("1dt", { showDice: SHOW_DICE });
|
||||
console.warn('// TODO: remettre myRoll==7');
|
||||
if (myRoll <= 7) {
|
||||
this._tellToUser(myRoll + ": Rencontre en " + locTMR);
|
||||
return await this.rencontreTMRRoll(tmr, this.actor.isRencontreSpeciale());
|
||||
return await TMRRencontres.getRencontreAleatoire(tmr, this.actor.isMauvaiseRencontre())
|
||||
} else {
|
||||
this._tellToUser(myRoll + ": Pas de rencontre en " + locTMR);
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async rencontreTMRRoll(tmr, isMauvaise = false) {
|
||||
let rencontre = (isMauvaise
|
||||
? await TMRRencontres.getMauvaiseRencontre()
|
||||
: await TMRRencontres.getRencontreAleatoire(tmr));
|
||||
rencontre.coord = tmr.coord;
|
||||
rencontre.date = game.system.rdd.calendrier.getDateFromIndex();
|
||||
rencontre.heure = game.system.rdd.calendrier.getCurrentHeure();
|
||||
return rencontre;
|
||||
lookupRencontreExistente(tmr) {
|
||||
return this.rencontresExistantes.find(it => it.system.coord == tmr.coord)
|
||||
?? this.rencontresExistantes.find(it => it.system.coord == "");
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
@ -875,15 +911,13 @@ export class RdDTMRDialog extends Dialog {
|
||||
if (this.isDemiReveCache()) {
|
||||
if (this.isTerreAttache(targetCoord)
|
||||
|| this.isConnaissanceFleuve(currentCoord, targetCoord)
|
||||
|| deplacementType == 'changeur')
|
||||
{
|
||||
|| deplacementType == 'changeur') {
|
||||
// déplacement possible
|
||||
await this.actor.setTMRVisible(true);
|
||||
this.demiReve = this._tokenDemiReve();
|
||||
this._trackToken(this.demiReve);
|
||||
}
|
||||
else
|
||||
{
|
||||
else {
|
||||
ui.notifications.error(`Vous ne connaissez plus votre position dans les TMR.
|
||||
Vous devez utiliser les boutons de direction pour vous déplacer.
|
||||
Une fois que vous aurez retrouvé votre demi-rêve, demandez au gardien de vérifier et rendre les TMR visibles.
|
||||
@ -894,15 +928,13 @@ export class RdDTMRDialog extends Dialog {
|
||||
|
||||
switch (deplacementType) {
|
||||
case 'normal':
|
||||
case 'changeur':
|
||||
case 'passeur':
|
||||
await this._deplacerDemiReve(targetCoord, deplacementType);
|
||||
break;
|
||||
case 'messager':
|
||||
await this._messagerDemiReve(targetCoord);
|
||||
break;
|
||||
case 'changeur':
|
||||
case 'passeur':
|
||||
await this._deplacerDemiReve(targetCoord, deplacementType);
|
||||
break;
|
||||
default:
|
||||
ui.notifications.error("Vous ne pouvez pas vous déplacer que sur des cases adjacentes à votre position ou valides dans le cas d'une rencontre");
|
||||
console.log("STATUS :", this.rencontreState, this.currentRencontre);
|
||||
@ -913,19 +945,23 @@ export class RdDTMRDialog extends Dialog {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
_calculDeplacement(targetCoord, currentCoord, fromOddq, toOddq) {
|
||||
|
||||
const isInArea = this.rencontreState == 'aucune'
|
||||
? (this.isTerreAttache(targetCoord) || this.isConnaissanceFleuve(currentCoord, targetCoord) || TMRUtility.distanceOddq(fromOddq, toOddq) <= 1)
|
||||
: this.currentRencontre?.locList?.find(coord => coord == targetCoord) ?? false
|
||||
if (isInArea) {
|
||||
switch (this.rencontreState) {
|
||||
case 'aucune': return 'normal';
|
||||
case 'passeur': case 'changeur': case 'messager': return this.rencontreState;
|
||||
if (this.isRencontreDeplacement()) {
|
||||
if (this.currentRencontre?.locList?.find(coord => coord == targetCoord)) {
|
||||
return this.rencontreState;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (this.isTerreAttache(targetCoord) || this.isConnaissanceFleuve(currentCoord, targetCoord) || TMRUtility.distanceOddq(fromOddq, toOddq) <= 1) {
|
||||
return 'normal'
|
||||
}
|
||||
}
|
||||
return 'erreur';
|
||||
}
|
||||
|
||||
isRencontreDeplacement() {
|
||||
return ['passeur', 'changeur', 'messager'].includes(this.rencontreState);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async _messagerDemiReve(targetCoord) {
|
||||
/*
|
||||
|
@ -2,20 +2,22 @@
|
||||
export class RdDTMRRencontreDialog extends Dialog {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
constructor(tmrApp, rencontre, postRencontre) {
|
||||
constructor(tmrApp, rencontre, tmr) {
|
||||
const dialogConf = {
|
||||
title: "Rencontre en TMR!",
|
||||
content: "Vous rencontrez un " + rencontre.name + " de force " + rencontre.force + "<br>",
|
||||
content: "Vous rencontrez un " + rencontre.name + " de force " + rencontre.system.force + "<br>",
|
||||
buttons: {
|
||||
derober: { icon: '<i class="fas fa-check"></i>', label: "Se dérober", callback: () => { this.onButtonFuir(() => tmrApp.derober()); } },
|
||||
refouler: { icon: '<i class="fas fa-check"></i>', label: "Refouler", callback: () => this.onButtonAction(() => tmrApp.refouler()) },
|
||||
maitiser: { icon: '<i class="fas fa-check"></i>', label: "Maîtriser", callback: () => this.onButtonAction(() => tmrApp.maitriserRencontre()) }
|
||||
derober: { icon: '<i class="fas fa-check"></i>', label: "Se dérober", callback: () => this.onButtonAction('derober') },
|
||||
maitiser: { icon: '<i class="fas fa-check"></i>', label: "Maîtriser", callback: () => this.onButtonAction('maitriser') }
|
||||
},
|
||||
default: "derober"
|
||||
};
|
||||
if (rencontre.ignorer) {
|
||||
dialogConf.buttons.ignorer = { icon: '<i class="fas fa-check"></i>', label: "Ignorer", callback: () => this.onButtonAction(() => tmrApp.ignorerRencontre()) }
|
||||
};
|
||||
}
|
||||
if ((rencontre.system.refoulement ?? 0) == 0) {
|
||||
dialogConf.buttons.ignorer = { icon: '<i class="fas fa-check"></i>', label: "Ignorer", callback: () => this.onButtonAction('ignorer') }
|
||||
}
|
||||
else {
|
||||
dialogConf.buttons.refouler = { icon: '<i class="fas fa-check"></i>', label: "Refouler", callback: () => this.onButtonAction('refouler') }
|
||||
}
|
||||
|
||||
const dialogOptions = {
|
||||
classes: ["tmrrencdialog"],
|
||||
@ -25,21 +27,14 @@ export class RdDTMRRencontreDialog extends Dialog {
|
||||
super(dialogConf, dialogOptions);
|
||||
|
||||
this.toClose = false;
|
||||
this.rencontreData = duplicate(rencontre);
|
||||
this.postRencontre = postRencontre;
|
||||
this.tmr = tmr;
|
||||
this.tmrApp = tmrApp;
|
||||
this.tmrApp.minimize();
|
||||
}
|
||||
|
||||
async onButtonAction(action) {
|
||||
this.toClose = true;
|
||||
await action();
|
||||
this.postRencontre();
|
||||
}
|
||||
|
||||
async onButtonFuir(action) {
|
||||
this.toClose = true;
|
||||
await action();
|
||||
this.tmrApp.onActionRencontre(action, this.tmr)
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
|
@ -120,7 +120,7 @@ export const referenceAjustements = {
|
||||
isVisible: (rollData, actor) => rollData.tmr && rollData.rencontre?.name,
|
||||
isUsed: (rollData, actor) => rollData.tmr && rollData.rencontre?.name,
|
||||
getLabel: (rollData, actor) => rollData.rencontre?.name,
|
||||
getValue: (rollData, actor) => - (rollData.rencontre?.force ?? 0)
|
||||
getValue: (rollData, actor) => - (rollData.rencontre?.system.force ?? 0)
|
||||
},
|
||||
ethylismeAlcool: {
|
||||
isVisible: (rollData, actor) => rollData.nbDoses != undefined,
|
||||
|
@ -48,8 +48,7 @@ export class SystemCompendiums extends FormApplication {
|
||||
|
||||
static async getContent(compendium, docType) {
|
||||
const pack = SystemCompendiums.getPack(compendium);
|
||||
if (pack.metadata.type == docType)
|
||||
{
|
||||
if (pack.metadata.type == docType) {
|
||||
return await pack.getDocuments();
|
||||
}
|
||||
return [];
|
||||
@ -59,6 +58,14 @@ export class SystemCompendiums extends FormApplication {
|
||||
return await SystemCompendiums.getContent(compendium, 'Item')
|
||||
}
|
||||
|
||||
static async getDefaultItems(compendium) {
|
||||
const pack = game.packs.get(SystemCompendiums._getDefaultCompendium(compendium));
|
||||
if (pack.metadata.type == 'Item') {
|
||||
return await pack.getDocuments();
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
static getCompendium(compendium) {
|
||||
const setting = CONFIGURABLE_COMPENDIUMS[compendium]?.setting;
|
||||
return setting ? game.settings.get(SYSTEM_RDD, setting) : SystemCompendiums._getDefaultCompendium(compendium);
|
||||
|
@ -1,335 +1,22 @@
|
||||
import { Grammar } from "./grammar.js";
|
||||
import { Misc } from "./misc.js";
|
||||
import { RdDDice } from "./rdd-dice.js";
|
||||
import { SystemCompendiums } from "./settings/system-compendiums.js";
|
||||
import { TMRUtility } from "./tmr-utility.js";
|
||||
import { TMRType } from "./tmr-utility.js";
|
||||
|
||||
/* -------------------------------------------- */
|
||||
const typeRencontres = {
|
||||
|
||||
messager: {
|
||||
msgSucces: async (rencData) => {
|
||||
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 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) => {
|
||||
tmrDialog.setStateRencontre(rencData.rencontre.type);
|
||||
tmrDialog.choisirCasePortee(rencData.tmr.coord, rencData.rencontre.force);
|
||||
},
|
||||
poesieSucces: {
|
||||
reference: "La chevelure, Charles Baudelaire",
|
||||
extrait: `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 !`
|
||||
},
|
||||
poesieEchec: {
|
||||
reference: "Rêve de Dragon, Denis Gerfaud",
|
||||
extrait: `En réalité, tous les éléments du rêve des Dragons expriment
|
||||
le Draconic : chaque pierre, chaque fleur, chaque goutte d'eau,
|
||||
chaque nuage est porteur d'un message dans la langue des Dragons`}
|
||||
},
|
||||
|
||||
passeur: {
|
||||
msgSucces: async (rencData) => {
|
||||
if (rencData.actor.isTMRCache()){
|
||||
return `Le ${rencData.rencontre.name} vous propose de vous transporter, mais vous ne savez pas où vous êtes.`;
|
||||
}
|
||||
return `Le ${rencData.rencontre.name} vous propose de vous transporter à ${rencData.rencontre.force} cases des ${rencData.tmr.label}.`;
|
||||
},
|
||||
msgEchec: async (rencData)=> `Le prix que demande le ${rencData.rencontre.name} est trop élevé, vous êtes réduit à poursuivre votre chemin par vos propres moyens.`,
|
||||
postSucces: async (tmrDialog, rencData) => {
|
||||
tmrDialog.setStateRencontre(rencData.rencontre.type);
|
||||
tmrDialog.choisirCasePortee(rencData.tmr.coord, rencData.rencontre.force);
|
||||
},
|
||||
poesieSucces: {
|
||||
reference: "Le bateau ivre, Arthur Rimbaud",
|
||||
extrait: `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.`},
|
||||
poesieEchec: {
|
||||
reference: "Femmes damnées (2), Charles Baudelaire",
|
||||
extrait: `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 !`}
|
||||
},
|
||||
|
||||
fleur: {
|
||||
msgSucces: async (rencData) => `Vous cueillez la ${rencData.rencontre.name}, son parfum vous apporte ${rencData.rencontre.force} points de Rêve.`,
|
||||
msgEchec: async (rencData)=> `La ${rencData.rencontre.name} se fâne et disparaît entre vos doigts.`,
|
||||
postSucces: async (tmrDialog, rencData) => tmrDialog.actor.reveActuelIncDec(rencData.rencontre.force),
|
||||
poesieSucces: {
|
||||
reference: "L'Ennemi, Charles Baudelaire",
|
||||
extrait: `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 ?`},
|
||||
poesieEchec: {
|
||||
reference: "Une charogne, Charles Baudelaire",
|
||||
extrait: `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.`},
|
||||
},
|
||||
|
||||
mangeur: {
|
||||
msgSucces: async (rencData) => `Le ${rencData.rencontre.name} claque de sa machoire dans le vide avant de fuir.`,
|
||||
msgEchec: async (rencData)=> `Le ${rencData.rencontre.name} croque votre Rêve ! Il emporte ${rencData.rencontre.force} de vos points de rêve actuels`,
|
||||
postEchec: async (tmrDialog, rencData) => tmrDialog.actor.reveActuelIncDec(-rencData.rencontre.force),
|
||||
poesieSucces: {
|
||||
reference: "Conseil, Victor Hugo",
|
||||
extrait: `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 !`},
|
||||
poesieEchec: {
|
||||
reference: "El Desdichado, Gérard de Nerval",
|
||||
extrait: `Suis-je Amour ou Phébus ?... Lusignan ou Biron ?
|
||||
<br>Mon front est rouge encor du baiser de la Reine ;
|
||||
<br>J'ai rêvé dans la Grotte où nage la sirène...`}
|
||||
},
|
||||
|
||||
changeur: {
|
||||
msgSucces: async (rencData) => `Le ${rencData.rencontre.name} vaincu accepte de vous déplacer sur une autre ${TMRType[rencData.tmr.type].name} de votre choix en échange de sa liberté.`,
|
||||
msgEchec: async (rencData) => `Le ${rencData.rencontre.name} vous embobine avec des promesses, et vous transporte sur une autre ${TMRType[rencData.tmr.type].name} sans attendre votre avis.`,
|
||||
postSucces: async (tmrDialog, rencData) => {
|
||||
tmrDialog.setStateRencontre(rencData.rencontre.type);
|
||||
tmrDialog.choisirCaseType(rencData.tmr.type);
|
||||
},
|
||||
postEchec: async (tmrDialog, rencData) => {
|
||||
const newTMR = await TMRUtility.getTMRAleatoire(it => it.type == rencData.tmr.type && it.coord != rencData.tmr.coord);
|
||||
await tmrDialog.actor.forcerPositionTMRInconnue(newTMR);
|
||||
tmrDialog.positionnerDemiReve(newTMR.coord);
|
||||
},
|
||||
poesieSucces: {
|
||||
reference: "Caligula - IIIème chant, Gérard de Nerval",
|
||||
extrait: `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.`},
|
||||
poesieEchec: {
|
||||
reference: "Rêve de Dragon, Denis Gerfaud",
|
||||
extrait: `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 ? »`}
|
||||
},
|
||||
|
||||
briseur: {
|
||||
msgSucces: async (rencData) => `Le ${rencData.rencontre.name} tente vainement de vous déconcentrer, avant de fuir sans demander son reste.`,
|
||||
msgEchec: async (rencData)=> `Le ${rencData.rencontre.name} vous déconcentre au point de briser votre demi-rêve.`,
|
||||
postEchec: async (tmrDialog, rencData) => tmrDialog.close(),
|
||||
poesieSucces: {
|
||||
reference: "Rêve de Dragon, Denis Gerfaud",
|
||||
extrait: `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`},
|
||||
poesieEchec: {
|
||||
reference: "Quand le rêve se brise, Cypora Sebagh",
|
||||
extrait: `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.`}
|
||||
},
|
||||
|
||||
reflet: {
|
||||
msgSucces: async (rencData) => `Le ${rencData.rencontre.name} s'estompe dans l'oubli.`,
|
||||
msgEchec: async (rencData)=> `Vous êtes submergé par un ${rencData.rencontre.name}, les souvenirs vous retiennent tant qu'il ne sera pas vaincu!`,
|
||||
poesieSucces: {
|
||||
reference: "Une charogne, Charles Baudelaire",
|
||||
extrait: `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.`},
|
||||
poesieEchec: {
|
||||
reference: "La chevelure, Charles Baudelaire",
|
||||
extrait: `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`}
|
||||
},
|
||||
|
||||
passeurfou: {
|
||||
msgSucces: async (rencData) => `Le ${rencData.rencontre.name} 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.`,
|
||||
msgEchec: async (rencData)=> TMRRencontres.msgEchecPasseurFou(rencData),
|
||||
postEchec: async (tmrDialog, rencData) => TMRRencontres.postEchecPasseurFou(tmrDialog, rencData),
|
||||
poesieSucces: {
|
||||
reference: "Un Fou et un Sage, Jean de La Fontaine",
|
||||
extrait: `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.`},
|
||||
poesieEchec: {
|
||||
reference: "Guitare, Victor Hugo",
|
||||
extrait: `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 !`}
|
||||
},
|
||||
|
||||
tbblanc: {
|
||||
msgSucces: async (rencData) => `Le ${rencData.rencontre.name} souleve une poussière blanche, vous tenez bon, et il tourbillonne en s'éloignant.`,
|
||||
msgEchec: async (rencData)=> `Le souffle du ${rencData.rencontre.name} vous déstabilise et vous emmène dans un nuage de poussière.`,
|
||||
postEchec: async (tmrDialog, rencData) => TMRRencontres.onPostEchecTourbillon(tmrDialog, rencData, 1),
|
||||
poesieSucces: {
|
||||
reference: "Rêve de Dragon, Denis Gerfaud",
|
||||
extrait: `Le Premier Âge fut appelé l'Âge des Dragons. Ce fut le commencement
|
||||
des temps, le commencement des rêves. Durant cette période plus mythique
|
||||
que réellement historique, les Dragons aimaient à se rêver eux-mêmes.`},
|
||||
poesieEchec: {
|
||||
reference: "Les Djinns, Victor Hugo",
|
||||
extrait: `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.`},
|
||||
},
|
||||
|
||||
tbnoir: {
|
||||
msgSucces: async (rencData) => `Le ${rencData.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.`,
|
||||
msgEchec: async (rencData)=> `Le ${rencData.rencontre.name} furieux vous secoue tel un fichu de paille malmené par les vents, et vous emporte dans la tourmente.`,
|
||||
postEchec: async (tmrDialog, rencData) => TMRRencontres.onPostEchecTourbillon(tmrDialog, rencData, 2),
|
||||
poesieSucces: {
|
||||
reference: "Rêve de Dragon, Denis Gerfaud",
|
||||
extrait: `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`},
|
||||
poesieEchec: {
|
||||
reference: "Lily, Pierre Perret",
|
||||
extrait: `Elle aurait pas cru sans le voir
|
||||
<br>Que la couleur du désespoir
|
||||
<br>Là-bas aussi ce fût le noir.`},
|
||||
},
|
||||
|
||||
tbrouge: {
|
||||
msgSucces: async (rencData) => `Le ${rencData.rencontre.name} s'abat avec violence mais vous êtes plus rapide et parvenez à lui échapper.`,
|
||||
msgEchec: async (rencData)=> `Le ${rencData.rencontre.name} vous frappe de milliers de morsure et vous malmène à travers les terres médianes.`,
|
||||
postEchec: async (tmrDialog, rencData) => TMRRencontres.onPostEchecTourbillonRouge(tmrDialog, rencData),
|
||||
poesieSucces: {
|
||||
reference: "Qu'est-ce de votre vie ? une bouteille molle, Jean-Baptiste Chassignet",
|
||||
extrait: `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.`},
|
||||
poesieEchec: {
|
||||
reference: "Les Djinns, poème Victor Hugo",
|
||||
extrait: `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 !`},
|
||||
},
|
||||
|
||||
rdd: {
|
||||
msgSucces: async (rencData) => `A tout seigneur, tout honneur, vous faites face à un ${rencData.rencontre.name}. Vous le maîtrisez et récupérez ses rêves. Vous gagnez ses ${rencData.rencontre.force} points de rêve`,
|
||||
msgEchec: async (rencData)=> `A tout seigneur, tout honneur, vous faites face à un ${rencData.rencontre.name}. La rencontre tourne au cauchemar, dans la lutte épique, vous subissez ${rencData.rolled.isETotal ? 'deux queues' : 'une queue'} de dragon!`,
|
||||
postSucces: async (tmrDialog, rencData) => TMRRencontres.onPostSuccessReveDeDragon(tmrDialog, rencData),
|
||||
postEchec: async (tmrDialog, rencData) => TMRRencontres.onPostEchecReveDeDragon(tmrDialog, rencData),
|
||||
poesieSucces: {
|
||||
reference: "Rêve de Dragon, Denis Gerfaud",
|
||||
extrait: `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`},
|
||||
poesieEchec: {
|
||||
reference: "El Desdichado, Gérard de Nerval",
|
||||
extrait: `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.`}
|
||||
},
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
const mauvaisesRencontres = [
|
||||
{ code: "mangeur", name: "Mangeur de Rêve", type: "mangeur", genre: "m", force: "1d6", refoulement: 2, isMauvaise: true },
|
||||
{ code: "mangeur2d6", name: "Mangeur de Rêve", type: "mangeur", genre: "m", force: "2d6", refoulement: 2, isMauvaise: true },
|
||||
{ code: "reflet+4", name: "Reflet d'ancien Rêve", type: "reflet", genre: "m", force: "2d6+4", refoulement: 2, isPersistant: true, isMauvaise: true },
|
||||
{ code: "tbblanc+4", name: "Tourbillon blanc", type: "tbblanc", genre: "m", force: "2d6+4", refoulement: 2, isPersistant: true, isMauvaise: true },
|
||||
{ code: "tbnoir+4", name: "Tourbillon noir", type: "tbnoir", genre: "m", force: "2d8+4", refoulement: 2, isPersistant: true, isMauvaise: true },
|
||||
{ code: "passfou", name: "Passeur fou", type: "passeurfou", genre: "m", force: "2d8", refoulement: 2, isMauvaise: true },
|
||||
{ code: "tbrouge", name: "Tourbillon rouge", type: "tbrouge", genre: "m", force: "2d8", refoulement: 3, isPersistant: true, isMauvaise: true }
|
||||
]
|
||||
|
||||
/* -------------------------------------------- */
|
||||
const rencontresStandard = [
|
||||
{ code: "messager", name: "Messager des Rêves", type: "messager", genre: "m", force: "2d4", ignorer: true },
|
||||
{ code: "passeur", name: "Passeur des Rêves", type: "passeur", genre: "m", force: "2d4", ignorer: true },
|
||||
{ code: "fleur", name: "Fleur des Rêves", type: "fleur", genre: "f", force: "1d6", ignorer: true },
|
||||
{ code: "mangeur", name: "Mangeur de Rêve", type: "mangeur", genre: "m", force: "1d6" },
|
||||
{ code: "changeur", name: "Changeur de Rêve", type: "changeur", genre: "m", force: "2d6" },
|
||||
{ code: "briseur", name: "Briseur de Rêve", type: "briseur", genre: "m", force: "2d6", quitterTMR: true },
|
||||
{ code: "reflet", name: "Reflet d'ancien Rêve", type: "reflet", genre: "m", force: "2d6", isPersistant: true },
|
||||
{ code: "tbblanc", name: "Tourbillon blanc", type: "tbblanc", genre: "m", force: "2d6", isPersistant: true },
|
||||
{ code: "tbnoir", name: "Tourbillon noir", type: "tbnoir", genre: "m", force: "2d8", isPersistant: true },
|
||||
{ code: "rdd", name: "Rêve de Dragon", type: "rdd", genre: "m", force: "1dr + 7", refoulement: 2, quitterTMR: true }
|
||||
];
|
||||
|
||||
const rencontresPresentCite = [
|
||||
{ code: "messager2d6", name: "Messager des Rêves", type: "messager", genre: "m", force: "2d6", ignorer: true },
|
||||
{ code: "passeur2d6", name: "Passeur des Rêves", type: "passeur", genre: "m", force: "2d6", ignorer: true },
|
||||
{ code: "fleur2d6", name: "Fleur des Rêves", type: "fleur", genre: "f", force: "2d6", ignorer: true }
|
||||
]
|
||||
const rencontresAll = [].concat(rencontresStandard).concat(mauvaisesRencontres).concat(rencontresPresentCite);
|
||||
|
||||
const tableRencontres = {
|
||||
cite: [{ code: 'messager', range: [1, 25] }, { code: 'passeur', range: [26, 50] }, { code: 'fleur', range: [51, 65] }, { code: 'mangeur', range: [66, 70] }, { code: 'changeur', range: [71, 80] }, { code: 'briseur', range: [81, 85] }, { code: 'reflet', range: [86, 90] }, { code: 'tbblanc', range: [91, 94] }, { code: 'tbnoir', range: [95, 97] }, { code: 'rdd', range: [98, 100] }],
|
||||
sanctuaire: [{ code: 'messager', range: [1, 25] }, { code: 'passeur', range: [26, 50] }, { code: 'fleur', range: [51, 65] }, { code: 'mangeur', range: [66, 70] }, { code: 'changeur', range: [71, 80] }, { code: 'briseur', range: [81, 85] }, { code: 'reflet', range: [86, 90] }, { code: 'tbblanc', range: [91, 94] }, { code: 'tbnoir', range: [95, 97] }, { code: 'rdd', range: [98, 100] }],
|
||||
plaines: [{ code: 'messager', range: [1, 20] }, { code: 'passeur', range: [21, 40] }, { code: 'fleur', range: [41, 55] }, { code: 'mangeur', range: [56, 60] }, { code: 'changeur', range: [61, 75] }, { code: 'briseur', range: [76, 82] }, { code: 'reflet', range: [83, 88] }, { code: 'tbblanc', range: [89, 93] }, { code: 'tbnoir', range: [94, 97] }, { code: 'rdd', range: [98, 100] }],
|
||||
pont: [{ code: 'messager', range: [1, 20] }, { code: 'passeur', range: [21, 40] }, { code: 'fleur', range: [41, 55] }, { code: 'mangeur', range: [56, 60] }, { code: 'changeur', range: [61, 75] }, { code: 'briseur', range: [76, 82] }, { code: 'reflet', range: [83, 88] }, { code: 'tbblanc', range: [89, 93] }, { code: 'tbnoir', range: [94, 97] }, { code: 'rdd', range: [98, 100] }],
|
||||
collines: [{ code: 'messager', range: [1, 15] }, { code: 'passeur', range: [16, 30] }, { code: 'fleur', range: [31, 42] }, { code: 'mangeur', range: [43, 54] }, { code: 'changeur', range: [55, 69] }, { code: 'briseur', range: [70, 82] }, { code: 'reflet', range: [83, 88] }, { code: 'tbblanc', range: [89, 93] }, { code: 'tbnoir', range: [94, 97] }, { code: 'rdd', range: [98, 100] }],
|
||||
foret: [{ code: 'messager', range: [1, 15] }, { code: 'passeur', range: [16, 30] }, { code: 'fleur', range: [31, 42] }, { code: 'mangeur', range: [43, 54] }, { code: 'changeur', range: [55, 69] }, { code: 'briseur', range: [70, 82] }, { code: 'reflet', range: [83, 88] }, { code: 'tbblanc', range: [89, 93] }, { code: 'tbnoir', range: [94, 97] }, { code: 'rdd', range: [98, 100] }],
|
||||
monts: [{ code: 'messager', range: [1, 10] }, { code: 'passeur', range: [11, 20] }, { code: 'fleur', range: [21, 26] }, { code: 'mangeur', range: [27, 44] }, { code: 'changeur', range: [45, 59] }, { code: 'briseur', range: [60, 75] }, { code: 'reflet', range: [76, 85] }, { code: 'tbblanc', range: [86, 92] }, { code: 'tbnoir', range: [93, 97] }, { code: 'rdd', range: [98, 100] }],
|
||||
desert: [{ code: 'messager', range: [1, 10] }, { code: 'passeur', range: [11, 20] }, { code: 'fleur', range: [21, 26] }, { code: 'mangeur', range: [27, 44] }, { code: 'changeur', range: [45, 59] }, { code: 'briseur', range: [60, 75] }, { code: 'reflet', range: [76, 85] }, { code: 'tbblanc', range: [86, 92] }, { code: 'tbnoir', range: [93, 97] }, { code: 'rdd', range: [98, 100] }],
|
||||
fleuve: [{ code: 'messager', range: [1, 5] }, { code: 'passeur', range: [6, 10] }, { code: 'fleur', range: [11, 13] }, { code: 'mangeur', range: [14, 37] }, { code: 'changeur', range: [38, 49] }, { code: 'briseur', range: [50, 65] }, { code: 'reflet', range: [66, 79] }, { code: 'tbblanc', range: [80, 89] }, { code: 'tbnoir', range: [90, 97] }, { code: 'rdd', range: [98, 100] }],
|
||||
lac: [{ code: 'messager', range: [1, 5] }, { code: 'passeur', range: [6, 10] }, { code: 'fleur', range: [11, 13] }, { code: 'mangeur', range: [14, 37] }, { code: 'changeur', range: [38, 49] }, { code: 'briseur', range: [50, 65] }, { code: 'reflet', range: [66, 79] }, { code: 'tbblanc', range: [80, 89] }, { code: 'tbnoir', range: [90, 97] }, { code: 'rdd', range: [98, 100] }],
|
||||
marais: [{ code: 'messager', range: [1, 2] }, { code: 'passeur', range: [3, 4] }, { code: 'fleur', range: [5, 5] }, { code: 'mangeur', range: [6, 29] }, { code: 'changeur', range: [30, 39] }, { code: 'briseur', range: [40, 60] }, { code: 'reflet', range: [61, 75] }, { code: 'tbblanc', range: [76, 86] }, { code: 'tbnoir', range: [87, 97] }, { code: 'rdd', range: [98, 100] }],
|
||||
gouffre: [{ code: 'messager', range: [1, 2] }, { code: 'passeur', range: [3, 4] }, { code: 'fleur', range: [5, 5] }, { code: 'mangeur', range: [6, 29] }, { code: 'changeur', range: [30, 39] }, { code: 'briseur', range: [40, 60] }, { code: 'reflet', range: [61, 75] }, { code: 'tbblanc', range: [76, 86] }, { code: 'tbnoir', range: [87, 97] }, { code: 'rdd', range: [98, 100] }],
|
||||
necropole: [{ code: 'mangeur', range: [1, 20] }, { code: 'changeur', range: [21, 30] }, { code: 'briseur', range: [31, 50] }, { code: 'reflet', range: [51, 65] }, { code: 'tbblanc', range: [66, 80] }, { code: 'tbnoir', range: [81, 97] }, { code: 'rdd', range: [98, 100] }],
|
||||
desolation: [{ code: 'mangeur', range: [1, 20] }, { code: 'changeur', range: [21, 30] }, { code: 'briseur', range: [31, 50] }, { code: 'reflet', range: [51, 65] }, { code: 'tbblanc', range: [66, 80] }, { code: 'tbnoir', range: [81, 97] }, { code: 'rdd', range: [98, 100] }]
|
||||
}
|
||||
|
||||
|
||||
/* -------------------------------------------- */
|
||||
export class TMRRencontres {
|
||||
static gestionRencontre = {}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static init() {
|
||||
for (let type in typeRencontres) {
|
||||
TMRRencontres.register(type, typeRencontres[type]);
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static register(type, rencontre) {
|
||||
TMRRencontres.gestionRencontre[type] = rencontre;
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
/**
|
||||
* Retourne une recontre en fonction de la case et du tirage
|
||||
* @param {*} terrain
|
||||
* @param {*} roll
|
||||
* @param {*} forcedRoll
|
||||
*/
|
||||
static async rollRencontre(terrain, roll = undefined) {
|
||||
static async rollRencontre(terrain, forcedRoll) {
|
||||
// TODO: recherche parmi les types de terrains + mauvaise, rejet si plusieurs choix
|
||||
const codeTerrain = Grammar.toLowerCaseNoAccent(terrain);
|
||||
if (!terrain) {
|
||||
ChatMessage.create({
|
||||
user: game.user.id,
|
||||
@ -338,170 +25,118 @@ export class TMRRencontres {
|
||||
});
|
||||
return false;
|
||||
}
|
||||
TMRRencontres.selectRencontre(terrain);
|
||||
const codeTerrain = Grammar.toLowerCaseNoAccent(terrain);
|
||||
|
||||
if (!roll || roll <= 0 || roll > 100) {
|
||||
roll = await RdDDice.rollTotal("1d100");
|
||||
if (forcedRoll && (forcedRoll <= 0 || forcedRoll > 100)) {
|
||||
forcedRoll = undefined;
|
||||
}
|
||||
|
||||
let rencontre = await TMRRencontres.getRencontreAleatoire({type: codeTerrain, coord:''}, roll);
|
||||
ChatMessage.create({
|
||||
user: game.user.id,
|
||||
whisper: [game.user.id],
|
||||
content: `Rencontre en ${terrain} (jet : ${roll}%)<br>Vous rencontrez un ${rencontre.name} de ${rencontre.force} Points de Rêve`
|
||||
});
|
||||
const table = await TMRRencontres.$buildTableRencontre(codeTerrain);
|
||||
const [selected, roll] = await TMRRencontres.$selectRencontre(codeTerrain, table, forcedRoll);
|
||||
const rencontre = await TMRRencontres.createRencontre(selected.rencontre);
|
||||
TMRRencontres.$chatRolledRencontre(rencontre, terrain, table, roll, true);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static getRencontre(index) {
|
||||
let rencontre;
|
||||
if (isNaN(index)) {
|
||||
rencontre = rencontresAll.find(r => r.type == index) ?? rencontresAll.find(r => r.code == index)
|
||||
}
|
||||
else if (0 <= index && index < rencontresAll.length) {
|
||||
rencontre = rencontresAll[index];
|
||||
}
|
||||
if (rencontre) {
|
||||
return duplicate(rencontre);
|
||||
}
|
||||
else {
|
||||
ui.notifications.info(`Pas de rencontre pour ${index}, seulement ${rencontresAll.length} rencontres sont connues.<br>Vous pouvez aussi essayer par type (ie: mangeur, fleur, fleur2d6, ...)`)
|
||||
static async $buildTableRencontre(codeTerrain) {
|
||||
let max = 0;
|
||||
const items = await SystemCompendiums.getItems('rencontres');
|
||||
const filtreMauvaise = codeTerrain == 'mauvaise' ? it => it.system.mauvaiseRencontre : it => !it.system.mauvaiseRencontre;
|
||||
const rencontres = items.filter(it => it.type == 'rencontre')
|
||||
.filter(filtreMauvaise)
|
||||
.filter(it => it.system.frequence[codeTerrain] > 0)
|
||||
.sort(Misc.ascending(it => it.system.ordreTri))
|
||||
.map(it => {
|
||||
const frequence = it.system.frequence[codeTerrain];
|
||||
max += frequence;
|
||||
return { rencontre: it, min: max - frequence + 1, max: max,frequence: frequence };
|
||||
});
|
||||
return rencontres;
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static async $selectRencontre(terrain, table, roll = undefined) {
|
||||
const total = table.map(it => it.frequence).reduce(Misc.sum(), 0);
|
||||
if (total == 0){
|
||||
ui.notifications.warn(`Pas de rencontres définies pour ${terrain}`);
|
||||
return undefined;
|
||||
}
|
||||
if (roll != undefined && (roll > total || roll <= 0)) {
|
||||
ui.notifications.warn(`Jet de rencontre ${roll} en dehors de la table [1..${total}], le jet est relancé`);
|
||||
roll = undefined;
|
||||
}
|
||||
if (!roll) {
|
||||
roll = await RdDDice.rollTotal(`1d${total}`);
|
||||
}
|
||||
return [table.find(it => it.min <= roll && roll <= it.max), roll];
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static async getRencontreAleatoire(tmr, roll = undefined) {
|
||||
if (!roll || roll <= 0 || roll > 100) {
|
||||
roll = await RdDDice.rollTotal("1d100");
|
||||
static async createRencontre(rencontre, tmr = undefined) {
|
||||
return rencontre.clone({
|
||||
'system.force': await RdDDice.rollTotal(rencontre.system.formule),
|
||||
'system.coord': tmr?.coord,
|
||||
'system.date': game.system.rdd.calendrier.getDateFromIndex(),
|
||||
'system.heure': game.system.rdd.calendrier.getCurrentHeure()
|
||||
}, {save: false});
|
||||
}
|
||||
|
||||
static async calculRencontre(rencontre, tmr = undefined) {
|
||||
if (rencontre.system.coord == ""){
|
||||
rencontre.system.coord = tmr?.coord;
|
||||
}
|
||||
if (rencontre.system.force == 0){
|
||||
rencontre.system.force = await RdDDice.rollTotal(rencontre.system.formule);
|
||||
}
|
||||
if (rencontre.system.date == "" ) {
|
||||
rencontre.system.date = game.system.rdd.calendrier.getDateFromIndex();
|
||||
}
|
||||
if (rencontre.system.heure == "") {
|
||||
rencontre.system.heure = game.system.rdd.calendrier.getCurrentHeure();
|
||||
}
|
||||
const codeTerrain = Grammar.toLowerCaseNoAccent(tmr.type);
|
||||
const code = tableRencontres[codeTerrain].find(it => it.range[0] <= roll && roll <= it.range[1]).code;
|
||||
const rencontre = duplicate(rencontresStandard.find(it => it.code == code));
|
||||
rencontre.roll = roll;
|
||||
await TMRRencontres.evaluerForceRencontre(rencontre);
|
||||
return rencontre;
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static async getMauvaiseRencontre(index = undefined) {
|
||||
const rencontre = duplicate(
|
||||
(index && index >= 0 && index < mauvaisesRencontres.length)
|
||||
? mauvaisesRencontres[index]
|
||||
: await RdDDice.rollOneOf(mauvaisesRencontres));
|
||||
await TMRRencontres.evaluerForceRencontre(rencontre);
|
||||
static $chatRolledRencontre(rencontre, terrain, table, roll = 0, displayTable=false){
|
||||
const total = table.map(it => it.frequence).reduce(Misc.sum(), 0);
|
||||
const namesPercent = displayTable ?
|
||||
table.map(it => `<br>${it.rencontre.name} : ${it.frequence}${total == 100 ? '%' : ''} (${it.min} - ${it.max})`).reduce((a, b) => a + b, '<hr>')
|
||||
: '';
|
||||
const chances = game.user.isGM
|
||||
? (roll ? `Jet: ${roll} / ${total}` : `Valeurs: [1..${total}]`)
|
||||
: (roll ? `Jet: ${Math.ceil(roll*100/total)} / 100` : '');
|
||||
ChatMessage.create({
|
||||
user: game.user.id,
|
||||
whisper: [game.user.id],
|
||||
content: `Compendium: ${SystemCompendiums.getCompendium('rencontres')}
|
||||
<br>Rencontre en ${terrain}:
|
||||
${namesPercent}<hr>
|
||||
<br>${chances}
|
||||
<br>Rencontre: ${rencontre.name} ${rencontre.system.force} (${rencontre.system.formule})`
|
||||
});
|
||||
}
|
||||
|
||||
static async getPresentsCite() {
|
||||
const rencontres = await SystemCompendiums.getDefaultItems('rencontres');
|
||||
return rencontres.filter(it => !it.system.mauvaiseRencontre && it.system.presentCite).map(it =>
|
||||
it.clone({ 'system.formule': "2d6" }, {save: false}));
|
||||
}
|
||||
|
||||
static async getReveDeDragon(force) {
|
||||
const rencontres = await SystemCompendiums.getDefaultItems('rencontres');
|
||||
const reveDeDragon = rencontres.find(it => Grammar.equalsInsensitive(it.name, 'Rêve de Dragon'));
|
||||
return reveDeDragon?.clone({ 'system.force': force }, {save: false});
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static async getRencontreAleatoire(tmr, mauvaise) {
|
||||
const codeTerrain = mauvaise ? 'mauvaise' : tmr.type;
|
||||
const table = await TMRRencontres.$buildTableRencontre(codeTerrain);
|
||||
const [selected, roll] = await TMRRencontres.$selectRencontre(codeTerrain, table);
|
||||
const rencontre = await TMRRencontres.createRencontre(selected.rencontre, tmr);
|
||||
TMRRencontres.$chatRolledRencontre(rencontre, TMRUtility.getTMRType(tmr.coord), table, roll);
|
||||
return rencontre;
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static async evaluerForceRencontre(rencontre) {
|
||||
const rollForce = new Roll(rencontre.force);
|
||||
await rollForce.evaluate({ async: true });
|
||||
rencontre.force = rollForce.total;
|
||||
return rencontre.force;
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static isReveDeDragon(rencontre) {
|
||||
return rencontre.type == "rdd";
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static getGestionRencontre(name) {
|
||||
let gestion = TMRRencontres.gestionRencontre[name];
|
||||
if (!gestion) {
|
||||
ui.notifications.error(`La rencontre ${name} est inconnue, pas de méthode de gestion associée`)
|
||||
gestion = TMRRencontres.gestionRencontre['messager'];
|
||||
}
|
||||
return gestion;
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static async gererRencontre(tmrDialog, rencData) {
|
||||
let gestion = TMRRencontres.getGestionRencontre(rencData.rencontre.type);
|
||||
if (rencData.rolled.isSuccess) {
|
||||
rencData.message = await gestion.msgSucces(rencData);
|
||||
if (rencData.nbRounds > 1) {
|
||||
rencData.message += ` Au total, vous avez passé ${rencData.nbRounds} rounds à vous battre!`;
|
||||
}
|
||||
rencData.poesie = gestion.poesieSucces;
|
||||
return gestion.postSucces;
|
||||
}
|
||||
|
||||
rencData.message = await gestion.msgEchec(rencData);
|
||||
if (rencData.nbRounds > 1) {
|
||||
rencData.message += ` Vous avez passé ${rencData.nbRounds} rounds à lutter!`;
|
||||
}
|
||||
rencData.poesie = gestion.poesieEchec;
|
||||
return gestion.postEchec;
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static async msgEchecPasseurFou(tmrData) {
|
||||
tmrData.sortReserve = RdDDice.rollOneOf(tmrData.actor.itemTypes['sortreserve']);
|
||||
if (tmrData.sortReserve) {
|
||||
// Passeur fou positionne sur la case d'un sort en réserve
|
||||
tmrData.newTMR = TMRUtility.getTMR(tmrData.sortReserve.coord);
|
||||
} else {
|
||||
// Déplacement aléatoire de la force du Passeur Fou
|
||||
const newCoord = await RdDDice.rollOneOf(TMRUtility.getTMRPortee(tmrData.tmr.coord, tmrData.rencontre.force));
|
||||
tmrData.newTMR = TMRUtility.getTMR(newCoord);
|
||||
}
|
||||
if (tmrData.sortReserve) {
|
||||
return `Le ${tmrData.rencontre.name} vous dérobe la clé de vos sorts. Vous vous saisissez de lui, mais dans un nuage violet, il vous emporte en ${tmrData.newTMR.label} déclencher votre sort en réserve de ${tmrData.sortReserve.name}.`;
|
||||
}
|
||||
else {
|
||||
return `Le ${tmrData.rencontre.name} tente de vous dérober la clé de vos sorts. Ne la trouvant pas, il déclenche un nuage violet et vous emporte en ${tmrData.newTMR.label}`;
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static async postEchecPasseurFou(tmrDialog, tmrData) {
|
||||
if (tmrData.sortReserve) {
|
||||
await tmrDialog.processSortReserve(tmrData.sortReserve);
|
||||
}
|
||||
await tmrDialog.positionnerDemiReve(tmrData.newTMR.coord);
|
||||
if (tmrData.sortReserve) {
|
||||
tmrDialog.close();
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static async onPostEchecTourbillon(tmrDialog, tmrData, cases) {
|
||||
await tmrData.actor.reveActuelIncDec(-cases);
|
||||
await TMRRencontres._toubillonner(tmrDialog, tmrData.actor, cases);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static async onPostEchecTourbillonRouge(tmrDialog, rencontre) {
|
||||
await rencontre.actor.reveActuelIncDec(-2); // -2 pts de Reve a chaque itération
|
||||
TMRRencontres._toubillonner(tmrDialog, rencontre.actor, 4);
|
||||
await rencontre.actor.santeIncDec("vie", -1); // Et -1 PV
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static async _toubillonner(tmrDialog, actor, cases) {
|
||||
let coord = actor.system.reve.tmrpos.coord;
|
||||
for (let i = 0; i < cases; i++) {
|
||||
coord = await TMRUtility.deplaceTMRAleatoire(actor, coord).coord;
|
||||
}
|
||||
await tmrDialog.positionnerDemiReve(coord)
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static async onPostSuccessReveDeDragon(tmrDialog, tmrData) {
|
||||
if (tmrData.rolled.isPart) {
|
||||
await tmrData.actor.appliquerAjoutExperience(tmrData);
|
||||
}
|
||||
await tmrData.actor.resultCombatReveDeDragon(tmrData);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static async onPostEchecReveDeDragon(tmrDialog, tmrData) {
|
||||
await tmrData.actor.resultCombatReveDeDragon(tmrData);
|
||||
tmrDialog.close();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -314,24 +314,15 @@ export class TMRUtility {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static async deplaceTMRAleatoire(actor, coord) {
|
||||
return TMRUtility.deplaceTMRSelonPattern(actor, coord, await TMRUtility.getDirectionPattern(), 1);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static async deplaceTMRSelonPattern(actor, coordTMR, direction, nTime) {
|
||||
let coord;
|
||||
for (let i = 0; i < nTime; i++) {
|
||||
let currentOddq = TMRUtility.coordTMRToOddq(coordTMR);
|
||||
const currentOddq = TMRUtility.coordTMRToOddq(coord);
|
||||
const direction = await TMRUtility.getDirectionPattern();
|
||||
currentOddq.col = currentOddq.col + direction.col;
|
||||
currentOddq.row = currentOddq.row + direction.row;
|
||||
if (this.isOddqInTMR(currentOddq)) { // Sortie de carte ! Ré-insertion aléatoire
|
||||
coord = TMRUtility.getTMR(TMRUtility.oddqToCoordTMR(currentOddq));
|
||||
return TMRUtility.getTMR(TMRUtility.oddqToCoordTMR(currentOddq));
|
||||
} else {
|
||||
coord = await actor.reinsertionAleatoire('Sortie de carte');
|
||||
return await actor.reinsertionAleatoire('Sortie de carte');
|
||||
}
|
||||
console.log("Nouvelle case iteration !!!", i, coord);
|
||||
}
|
||||
return coord;
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
@ -343,6 +334,10 @@ export class TMRUtility {
|
||||
return Object.values(TMRMapping).filter(filter);
|
||||
}
|
||||
|
||||
static getCasesType(type) {
|
||||
return TMRUtility.filterTMR(it => it.type == type).map(it => it.coord);
|
||||
}
|
||||
|
||||
static findTMR(search) {
|
||||
const labelSearch = Grammar.toLowerCaseNoAccent(search)
|
||||
return TMRUtility.filterTMR(it => Grammar.toLowerCaseNoAccent(it.label).match(labelSearch) || it.coord == search);
|
||||
|
@ -3,6 +3,7 @@ import { Grammar } from "../grammar.js";
|
||||
import { TMRUtility } from "../tmr-utility.js";
|
||||
import { tmrConstants, tmrTokenZIndex } from "../tmr-constants.js";
|
||||
import { Draconique } from "./draconique.js";
|
||||
import { TMRRencontres } from "../tmr-rencontres.js";
|
||||
|
||||
export class PresentCites extends Draconique {
|
||||
|
||||
@ -46,15 +47,13 @@ export class PresentCites extends Draconique {
|
||||
}
|
||||
|
||||
async choisirUnPresent(casetmr, onChoixPresent) {
|
||||
const presents = await TMRRencontres.getPresentsCite()
|
||||
const buttons = {};
|
||||
presents.forEach(r => buttons['present'+r.id] = { icon: '<i class="fas fa-check"></i>', label: r.name, callback: async () => onChoixPresent(r) });
|
||||
let d = new Dialog({
|
||||
title: "Présent des cités",
|
||||
content: `La ${this.tmrLabel(casetmr)} vous offre un présent, faite votre choix`,
|
||||
buttons: {
|
||||
messager: { icon: '<i class="fas fa-check"></i>', label: "Un Messager des rêves", callback: () => onChoixPresent('messager2d6') },
|
||||
passeur: { icon: '<i class="fas fa-check"></i>', label: "Un Passeur des rêves", callback: () => onChoixPresent('passeur2d6') },
|
||||
fleur: { icon: '<i class="fas fa-check"></i>', label: "Une Fleur des rêves", callback: () => onChoixPresent('fleur2d6') },
|
||||
},
|
||||
default: "fleur"
|
||||
content: `La ${this.tmrLabel(casetmr)} vous offre un présent, faites votre choix`,
|
||||
buttons: buttons
|
||||
});
|
||||
d.render(true);
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ export class Rencontre extends Draconique {
|
||||
async onActorCreateOwned(actor, item) { }
|
||||
|
||||
code() { return 'rencontre' }
|
||||
tooltip(rencontre) { return `${rencontre.name} de force ${rencontre.force}` }
|
||||
tooltip(rencontre) { return `${rencontre.name} de force ${rencontre.system.force}` }
|
||||
img() { return 'systems/foundryvtt-reve-de-dragon/icons/heures/hd06.webp' }
|
||||
|
||||
createSprite(pixiTMR) {
|
||||
|
@ -467,12 +467,6 @@
|
||||
"label": "Position TMR",
|
||||
"cache": false
|
||||
},
|
||||
"reserve": {
|
||||
"list": []
|
||||
},
|
||||
"rencontre": {
|
||||
"list": []
|
||||
},
|
||||
"refoulement": {
|
||||
"value": 0,
|
||||
"label": "Points de Refoulement"
|
||||
|
@ -1,28 +1,12 @@
|
||||
{{#if hautreve.rencontres.length}}
|
||||
<h3>Rencontres en attente dans les TMR</h3>
|
||||
<ul class="item-list">
|
||||
{{#each hautreve.rencontres as |rencontre key|}}
|
||||
<li class="item flexrow" data-item-id="{{key}}" data-attribute="{{key}}">
|
||||
<span class="display-label"><a data-item-id="{{key}}">{{rencontre.name}} r{{rencontre.force}}</a></span>
|
||||
<span class="flex-shrink">{{rencontre.coord}} - {{caseTmr-label rencontre.coord}}</span>
|
||||
{{#if rencontre.date}}
|
||||
<span>{{upperFirst rencontre.heure}}, le {{rencontre.date}}</span>
|
||||
{{/if}}
|
||||
<div class="item-controls flex-shrink">
|
||||
<a class="rencontre-delete" title="Supprimer"><i class="fas fa-trash"></i></a>
|
||||
</div>
|
||||
</li>
|
||||
{{/each}}
|
||||
</ul>
|
||||
{{/if}}
|
||||
{{#if rencontres.length}}
|
||||
<h3>Rencontres en attente dans les TMR</h3>
|
||||
<ul class="item-list">
|
||||
{{#each rencontres as |rencontre key|}}
|
||||
<li class="item flexrow" data-item-id="{{rencontre._id}}" data-attribute="{{key}}">
|
||||
<img class="sheet-competence-img" src="{{rencontre.img}}" />
|
||||
<span class="display-label"><a>{{rencontre.name}} r{{rencontre.system.force}}</a></span>
|
||||
<span class="flex-shrink">{{rencontre.system.coord}} - {{caseTmr-label rencontre.system.coord}}</span>
|
||||
<span class="display-label flex-grow"><a>
|
||||
{{rencontre.name}} r{{rencontre.system.force}} ({{rencontre.system.coord}} - {{caseTmr-label rencontre.system.coord}})
|
||||
</a></span>
|
||||
{{#if rencontre.system.date}}
|
||||
<span class="flex-shrink">{{upperFirst rencontre.system.heure}}, le {{rencontre.system.date}}</span>
|
||||
{{/if}}
|
||||
@ -33,4 +17,3 @@
|
||||
{{/each}}
|
||||
</ul>
|
||||
{{/if}}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
<img class="chat-icon" src="{{competence.img}}" alt="{{competence.name}}"/>
|
||||
<h4 data-categorie="tmr" data-actor-id="{{actor._id}}" data-rencontre-round="{{nbRounds}}">
|
||||
{{alias}} rencontre {{#if (eq genre 'f')}}une{{else}}un{{/if}} {{rencontre.name}} de force {{rencontre.force}}
|
||||
{{alias}} rencontre {{#if (eq rencontre.system.genre 'f')}}une{{else}}un{{/if}} {{rencontre.name}} de force {{rencontre.system.force}}
|
||||
</h4>
|
||||
{{> "systems/foundryvtt-reve-de-dragon/templates/chat-infojet.html"}}
|
||||
<hr>
|
||||
|
@ -6,7 +6,7 @@
|
||||
<hr>
|
||||
<span>
|
||||
{{#if rolled.isSuccess}}
|
||||
{{alias}} maîtrise le Rêve de Dragon! ll gagne {{rencontre.force}} points de Rêve.
|
||||
{{alias}} maîtrise le Rêve de Dragon! ll gagne {{rencontre.system.force}} points de Rêve.
|
||||
{{#if tete}}
|
||||
<br>{{alias}} doit <strong>demander au Gardien des Rêves</strong> de faire un tirage sur une des
|
||||
tables des têtes de dragon (Haut-rêvant ou Tous personnages).
|
||||
|
@ -1,5 +1,5 @@
|
||||
<form class="skill-roll-dialog">
|
||||
<h2>Rêve de Dragon de force {{rencontre.force}}!</h2>
|
||||
<h2>{{rencontre.name}} de force {{rencontre.system.force}}!</h2>
|
||||
<div class="grid grid-2col">
|
||||
<div class="flex-group-left">
|
||||
<img class="chat-icon" src="{{competence.img}}" alt="{{competence.name}}"/>
|
||||
|
Loading…
Reference in New Issue
Block a user