forked from public/foundryvtt-reve-de-dragon
Remplacement progressif rencontres
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
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 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 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});
|
||||
}
|
||||
|
||||
let rencontre = await TMRRencontres.getRencontreAleatoire({type: codeTerrain, coord:''}, roll);
|
||||
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();
|
||||
}
|
||||
return 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: `Rencontre en ${terrain} (jet : ${roll}%)<br>Vous rencontrez un ${rencontre.name} de ${rencontre.force} Points de Rêve`
|
||||
content: `Compendium: ${SystemCompendiums.getCompendium('rencontres')}
|
||||
<br>Rencontre en ${terrain}:
|
||||
${namesPercent}<hr>
|
||||
<br>${chances}
|
||||
<br>Rencontre: ${rencontre.name} ${rencontre.system.force} (${rencontre.system.formule})`
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
||||
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 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, ...)`)
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static async getRencontreAleatoire(tmr, roll = undefined) {
|
||||
if (!roll || roll <= 0 || roll > 100) {
|
||||
roll = await RdDDice.rollTotal("1d100");
|
||||
}
|
||||
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);
|
||||
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 getMauvaiseRencontre(index = undefined) {
|
||||
const rencontre = duplicate(
|
||||
(index && index >= 0 && index < mauvaisesRencontres.length)
|
||||
? mauvaisesRencontres[index]
|
||||
: await RdDDice.rollOneOf(mauvaisesRencontres));
|
||||
await TMRRencontres.evaluerForceRencontre(rencontre);
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user