Merge branch 'v1.4-signes-draconiques' into 'v1.4'
Gestion des signes draconiques See merge request LeRatierBretonnien/foundryvtt-reve-de-dragon!239
This commit is contained in:
commit
4715a75d0b
1
.gitignore
vendored
1
.gitignore
vendored
@ -2,3 +2,4 @@
|
||||
.idea
|
||||
todo.txt
|
||||
todo.md
|
||||
/.vscode
|
||||
|
BIN
icons/heures/de-heures.webp
Normal file
BIN
icons/heures/de-heures.webp
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.3 KiB |
BIN
icons/tmr/signe_draconique.webp
Normal file
BIN
icons/tmr/signe_draconique.webp
Normal file
Binary file not shown.
After Width: | Height: | Size: 35 KiB |
@ -223,6 +223,11 @@ export class RdDActorSheet extends ActorSheet {
|
||||
const item = this.actor.items.get(li.data("item-id"));
|
||||
item.sheet.render(true);
|
||||
});
|
||||
html.find('.display-label a').click((event) => {
|
||||
let myID = event.currentTarget.attributes['data-item-id'].value;
|
||||
const item = this.actor.getEmbeddedDocument('Item', myID);
|
||||
item.sheet.render(true);
|
||||
});
|
||||
html.find('.rencontre-delete').click(ev => {
|
||||
const li = $(ev.currentTarget).parents(".item");
|
||||
const rencontreKey = li.data("item-id");
|
||||
@ -428,26 +433,6 @@ export class RdDActorSheet extends ActorSheet {
|
||||
html.find('.enlever-tous-effets').click((event) => {
|
||||
this.actor.enleverTousLesEffets();
|
||||
});
|
||||
// Display info about queue
|
||||
html.find('.queuesouffle-label a').click((event) => {
|
||||
let myID = event.currentTarget.attributes['data-item-id'].value;
|
||||
const item = this.actor.getEmbeddedDocument('Item', myID);
|
||||
item.sheet.render(true);
|
||||
});
|
||||
// Info sort
|
||||
html.find('.sort-label a').click((event) => {
|
||||
let myID = event.currentTarget.attributes['data-id'].value;
|
||||
const item = this.actor.getEmbeddedDocument('Item', myID);
|
||||
item.sheet.render(true);
|
||||
});
|
||||
// Info sort
|
||||
html.find('.case-label a').click((event) => {
|
||||
let myID = event.currentTarget.attributes['data-id'].value;
|
||||
const item = this.actor.getEmbeddedDocument('Item', myID);
|
||||
item.sheet.render(true);
|
||||
});
|
||||
|
||||
// Display info about queue
|
||||
html.find('.conteneur-name a').click((event) => {
|
||||
let myID = event.currentTarget.attributes['data-item-id'].value;
|
||||
RdDUtility.toggleAfficheContenu(myID);
|
||||
|
270
module/actor.js
270
module/actor.js
@ -19,6 +19,7 @@ import { RdDItemArme } from "./item-arme.js";
|
||||
import { RdDAlchimie } from "./rdd-alchimie.js";
|
||||
import { StatusEffects } from "./status-effects.js";
|
||||
import { RdDItemCompetenceCreature } from "./item-competencecreature.js";
|
||||
import { RdDItemSigneDraconique } from "./item-signedraconique.js";
|
||||
import { ReglesOptionelles } from "./regles-optionelles.js";
|
||||
import { TMRRencontres } from "./tmr-rencontres.js";
|
||||
import { Poetique } from "./poetique.js";
|
||||
@ -193,7 +194,7 @@ export class RdDActor extends Actor {
|
||||
}
|
||||
/* -------------------------------------------- */
|
||||
isHautRevant() {
|
||||
return Misc.templateData(this).attributs.hautrevant.value != ""
|
||||
return this.isPersonnage() && Misc.templateData(this).attributs.hautrevant.value != ""
|
||||
}
|
||||
/* -------------------------------------------- */
|
||||
getFatigueActuelle() {
|
||||
@ -650,8 +651,7 @@ export class RdDActor extends Actor {
|
||||
}
|
||||
}
|
||||
else {
|
||||
const roll = new Roll("1dr").evaluate();
|
||||
let deRecuperation = roll.total;
|
||||
let deRecuperation = await RdDDice.rollTotal("1dr");
|
||||
console.log("recuperationReve", deRecuperation);
|
||||
if (deRecuperation >= 7) {
|
||||
// Rêve de Dragon !
|
||||
@ -743,7 +743,7 @@ export class RdDActor extends Actor {
|
||||
// TODO: un dialogue pour demander le type de tête?
|
||||
rollData.tete = true;
|
||||
}
|
||||
rollData.poesie = Poetique.getExtrait();
|
||||
rollData.poesie = await Poetique.getExtrait();
|
||||
|
||||
ChatMessage.create({
|
||||
whisper: ChatUtility.getWhisperRecipientsAndGMs(game.user.name),
|
||||
@ -1088,11 +1088,17 @@ export class RdDActor extends Actor {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
computeIsHautRevant() {
|
||||
const tplData = Misc.templateData(this);
|
||||
tplData.attributs.hautrevant.value = this.listItemsData('tete').find(it => Grammar.toLowerCaseNoAccent(it.name) == 'don de haut-reve')
|
||||
if (this.isPersonnage()) {
|
||||
Misc.templateData(this).attributs.hautrevant.value = this.hasItemNamed('tete', 'don de haut-reve')
|
||||
? "Haut rêvant"
|
||||
: "";
|
||||
}
|
||||
}
|
||||
|
||||
hasItemNamed(type, name) {
|
||||
name = Grammar.toLowerCaseNoAccent(name);
|
||||
return this.listItemsData(type).find(it => Grammar.toLowerCaseNoAccent(it.name) == name);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async computeEncombrementTotalEtMalusArmure() {
|
||||
@ -1184,7 +1190,7 @@ export class RdDActor extends Actor {
|
||||
/* -------------------------------------------- */
|
||||
async ajouterRefoulement(value = 1) {
|
||||
let refoulement = Misc.templateData(this).reve.refoulement.value + value;
|
||||
let total = new Roll("1d20").evaluate({ async: false }).total;
|
||||
let total = await RdDDice.rollTotal("1d20");
|
||||
if (total <= refoulement) {
|
||||
refoulement = 0;
|
||||
await this.ajouterSouffle({ chat: true });
|
||||
@ -1266,7 +1272,7 @@ export class RdDActor extends Actor {
|
||||
whisper: ChatUtility.getWhisperRecipientsAndGMs(game.user.name)
|
||||
});
|
||||
const innaccessible = this.buildTMRInnaccessible();
|
||||
let tmr = TMRUtility.getTMRAleatoire(tmr => !innaccessible.includes(tmr.coord));
|
||||
let tmr = await TMRUtility.getTMRAleatoire(tmr => !innaccessible.includes(tmr.coord));
|
||||
this.updateCoordTMR(tmr.coord);
|
||||
this.cacheTMR();
|
||||
return tmr;
|
||||
@ -1395,25 +1401,6 @@ export class RdDActor extends Actor {
|
||||
return RdDCarac.calculSConst(Misc.templateData(this).carac.constitution.value);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async testSiSonne(sante, endurance) {
|
||||
const roll = new Roll("1d20").evaluate();
|
||||
roll.showDice = true;
|
||||
RdDDice.show(roll);
|
||||
let result = {
|
||||
roll: roll,
|
||||
sonne: roll.total > endurance || roll.total == 20 // 20 is always a failure
|
||||
}
|
||||
if (roll.total == 1) {
|
||||
await this.ajoutXpConstitution(1); // +1 XP !
|
||||
ChatMessage.create({ content: `${this.name} a obenu 1 sur son Jet d'Endurance et a gagné 1 point d'Expérience en Constitution. Ce point d'XP a été ajouté automatiquement).` });
|
||||
}
|
||||
if (result.sonne) {
|
||||
await this.setSonne();
|
||||
sante.sonne.value = true;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
async ajoutXpConstitution(xp) {
|
||||
await this.update({ "data.carac.constitution.xp": Misc.toInt(Misc.templateData(this).carac.constitution.xp) + xp });
|
||||
@ -1428,48 +1415,71 @@ export class RdDActor extends Actor {
|
||||
return this.countBlessures(Misc.templateData(this).blessures[name].liste);
|
||||
}
|
||||
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async testSiSonne(sante, endurance) {
|
||||
const result = await this._jetEndurance(endurance);
|
||||
if (result.roll.total == 1) {
|
||||
ChatMessage.create({ content: await this._gainXpConstitutionJetEndurance() });
|
||||
}
|
||||
sante.sonne.value ||= result.sonne;
|
||||
return result;
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async jetEndurance() {
|
||||
let myRoll = new Roll("1d20").roll();
|
||||
myRoll.showDice = true;
|
||||
await RdDDice.show(myRoll);
|
||||
|
||||
const actorData = Misc.data(this);
|
||||
let msgText = "Jet d'Endurance : " + myRoll.total + " / " + actorData.data.sante.endurance.value + "<br>";
|
||||
if (myRoll.total == 1 || (myRoll.total != 20 && myRoll.total <= actorData.data.sante.endurance.value)) {
|
||||
msgText += `${this.name} a réussi son Jet d'Endurance !`;
|
||||
if (myRoll.total == 1) {
|
||||
await this.ajoutXpConstitution();
|
||||
msgText += `et gagne 1 Point d'Experience en Constitution`;
|
||||
}
|
||||
} else {
|
||||
await this.setSonne();
|
||||
msgText += `${this.name} a échoué son Jet d'Endurance et devient Sonné`;
|
||||
}
|
||||
const endurance = actorData.data.sante.endurance.value;
|
||||
|
||||
const result = await this._jetEndurance(actorData.data.sante.endurance.value)
|
||||
const message = {
|
||||
content: msgText,
|
||||
content: "Jet d'Endurance : " + result.roll.total + " / " + endurance + "<br>",
|
||||
whisper: ChatMessage.getWhisperRecipients(game.user.name)
|
||||
};
|
||||
if (result.sonne) {
|
||||
message.content += `${this.name} a échoué son Jet d'Endurance et devient Sonné`;
|
||||
}
|
||||
else if (result.roll.total == 1) {
|
||||
message.content += await this._gainXpConstitutionJetEndurance();
|
||||
}
|
||||
else {
|
||||
message.content += `${this.name} a réussi son Jet d'Endurance !`;
|
||||
}
|
||||
|
||||
ChatMessage.create(message);
|
||||
}
|
||||
|
||||
async _gainXpConstitutionJetEndurance() {
|
||||
await this.ajoutXpConstitution(1); // +1 XP !
|
||||
return `${this.name} a obtenu 1 sur son Jet d'Endurance et a gagné 1 point d'Expérience en Constitution. Ce point d'XP a été ajouté automatiquement.`;
|
||||
}
|
||||
|
||||
async _jetEndurance(endurance) {
|
||||
const roll = await RdDDice.roll("1d20", { showDice: true });
|
||||
let result = {
|
||||
roll: roll,
|
||||
sonne: roll.total > endurance || roll.total == 20 // 20 is always a failure
|
||||
}
|
||||
if (result.sonne) {
|
||||
await this.setSonne();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async jetVie() {
|
||||
let myRoll = new Roll("1d20").roll();
|
||||
myRoll.showDice = true;
|
||||
await RdDDice.show(myRoll);
|
||||
|
||||
let roll = await RdDDice.roll("1d20", { showDice: true });
|
||||
const actorData = Misc.data(this);
|
||||
let msgText = "Jet de Vie : " + myRoll.total + " / " + actorData.data.sante.vie.value + "<br>";
|
||||
if (myRoll.total <= actorData.data.sante.vie.value) {
|
||||
let msgText = "Jet de Vie : " + roll.total + " / " + actorData.data.sante.vie.value + "<br>";
|
||||
if (roll.total <= actorData.data.sante.vie.value) {
|
||||
msgText += "Jet réussi, pas de perte de point de vie (prochain jet dans 1 round pour 1 critique, SC minutes pour une grave)";
|
||||
if (myRoll.total == 1) {
|
||||
if (roll.total == 1) {
|
||||
msgText += "La durée entre 2 jets de vie est multipliée par 20 (20 rounds pour une critique, SCx20 minutes pour une grave)";
|
||||
}
|
||||
} else {
|
||||
msgText += "Jet échoué, vous perdez 1 point de vie";
|
||||
await this.santeIncDec("vie", -1);
|
||||
if (myRoll.total == 20) {
|
||||
if (roll.total == 20) {
|
||||
msgText += "Votre personnage est mort !!!!!";
|
||||
}
|
||||
}
|
||||
@ -1582,8 +1592,7 @@ export class RdDActor extends Actor {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async jetDeMoral(situation, messageReussi = undefined, messageManque = undefined) {
|
||||
let jetMoral = new Roll("1d20").roll();
|
||||
RdDDice.show(jetMoral);
|
||||
let jetMoral = await RdDDice.roll("1d20", { showDice: true });
|
||||
let moralActuel = Misc.toInt(Misc.templateData(this).compteurs.moral.value);
|
||||
const difficulte = 10 + moralActuel;
|
||||
const succes = jetMoral.total <= difficulte;
|
||||
@ -1687,7 +1696,7 @@ export class RdDActor extends Actor {
|
||||
RdDResolutionTable.displayRollData(jetVieView, this, 'chat-resultat-ethylisme.html');
|
||||
|
||||
if (rollEthylisme.isEchec) {
|
||||
let enduranceLostRoll = new Roll("1d6").roll();
|
||||
let enduranceLostRoll = await RdDDice.roll("1d6");
|
||||
// enduranceLostRoll.showDice = true;
|
||||
RdDDice.show(enduranceLostRoll);
|
||||
let enduranceLost = enduranceLostRoll.total;
|
||||
@ -2097,9 +2106,11 @@ export class RdDActor extends Actor {
|
||||
|
||||
let draconicList = this.computeDraconicAndSortIndex(sortList);
|
||||
const actorData = Misc.data(this);
|
||||
const reve = duplicate(actorData.data.carac.reve);
|
||||
let rollData = {
|
||||
forceCarac: { 'reve': duplicate(actorData.data.carac.reve) },
|
||||
selectedCarac: duplicate(actorData.data.carac.reve),
|
||||
carac: { 'reve': reve },
|
||||
forceCarac: { 'reve': reve },
|
||||
selectedCarac: reve,
|
||||
draconicList: draconicList,
|
||||
sortList: sortList,
|
||||
competence: draconicList[0],
|
||||
@ -2107,10 +2118,8 @@ export class RdDActor extends Actor {
|
||||
tmr: TMRUtility.getTMR(coord),
|
||||
diffLibre: RdDItemSort.getDifficulte(sortList[0], -7), // Per default at startup
|
||||
coutreve: Array(30).fill().map((item, index) => 1 + index),
|
||||
carac: { 'reve': duplicate(actorData.data.carac.reve) }
|
||||
}
|
||||
|
||||
if (this.currentTMR) this.currentTMR.minimize(); // Hide
|
||||
const dialog = await RdDRoll.create(this, rollData,
|
||||
{
|
||||
html: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-sort.html',
|
||||
@ -2320,6 +2329,11 @@ export class RdDActor extends Actor {
|
||||
dialog.render(true);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async _competenceResult(rollData) {
|
||||
RdDResolutionTable.displayRollData(rollData, this, 'chat-resultat-competence.html')
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async creerTacheDepuisLivre(item, options = { renderSheet: true }) {
|
||||
const itemData = Misc.data(item);
|
||||
@ -2544,24 +2558,15 @@ export class RdDActor extends Actor {
|
||||
/* -------------------------------------------- */
|
||||
async rollMeditation(id) {
|
||||
let meditation = Misc.data(this.getMeditation(id));
|
||||
let competence = Misc.data(this.getCompetence(meditation.data.competence));
|
||||
competence.data.defaut_carac = "intellect"; // Meditation = tjs avec intellect
|
||||
let meditationData = {
|
||||
competence: competence,
|
||||
meditation: meditation,
|
||||
conditionMeditation: {
|
||||
isHeure: false,
|
||||
isVeture: false,
|
||||
isComportement: false,
|
||||
isPurification: false,
|
||||
},
|
||||
competence: duplicate(Misc.data(this.getCompetence(meditation.data.competence))),
|
||||
meditation: duplicate(meditation),
|
||||
conditionMeditation: { isHeure: false, isVeture: false, isComportement: false, isPurification: false },
|
||||
diffConditions: 0,
|
||||
use: { libre: false, conditions: true, },
|
||||
carac: {}
|
||||
carac: { "intellect": Misc.templateData(this).carac.intellect }
|
||||
};
|
||||
meditationData.carac["intellect"] = Misc.templateData(this).carac["intellect"];
|
||||
|
||||
console.log("rollMeditation !!!", meditationData);
|
||||
meditationData.competence.data.defaut_carac = "intellect"; // Meditation = tjs avec intellect
|
||||
|
||||
const dialog = await RdDRoll.create(this, meditationData,
|
||||
{
|
||||
@ -2573,7 +2578,7 @@ export class RdDActor extends Actor {
|
||||
label: "Jet de méditation",
|
||||
callbacks: [
|
||||
this.createCallbackExperience(),
|
||||
{ condition: r => r.rolled.isETotal, action: r => this._meditationETotal(r) },
|
||||
{ condition: r => r.rolled.isEPart, action: r => this._meditationEPart(r) },
|
||||
{ action: r => this._meditationResult(r) }
|
||||
]
|
||||
});
|
||||
@ -2584,27 +2589,92 @@ export class RdDActor extends Actor {
|
||||
async _meditationResult(meditationData) {
|
||||
this.santeIncDec("fatigue", 2);
|
||||
|
||||
meditationData.diffLecture = -7;
|
||||
if (meditationData.rolled.isPart)
|
||||
meditationData.diffLecture = 0;
|
||||
else if (meditationData.rolled.isSign)
|
||||
meditationData.diffLecture = -3;
|
||||
const signeData = RdDItemSigneDraconique.prepareSigneDraconiqueMeditation(meditationData.meditation, meditationData.rolled)
|
||||
if (signeData) {
|
||||
await this.createEmbeddedDocuments("Item", [signeData]);
|
||||
}
|
||||
|
||||
RdDResolutionTable.displayRollData(meditationData, this.name, 'chat-resultat-meditation.html');
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
_meditationETotal(meditationData) {
|
||||
meditationData.meditation.data.malus--;
|
||||
this.updateEmbeddedDocuments('Item', [meditationData.meditation]);
|
||||
_meditationEPart(meditationData) {
|
||||
this.updateEmbeddedDocuments('Item', [{ _id: meditation._id, 'data.malus': meditationData.meditation.data.malus - 1 }]);
|
||||
}
|
||||
|
||||
|
||||
/* -------------------------------------------- */
|
||||
_getSignesDraconiques(coord) {
|
||||
const type = TMRUtility.getTMRType(coord);
|
||||
return this.listItemsData("signedraconique").filter(it => it.data.typesTMR.includes(type));
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async _competenceResult(rollData) {
|
||||
RdDResolutionTable.displayRollData(rollData, this, 'chat-resultat-competence.html')
|
||||
isResonanceSigneDraconique(coord) {
|
||||
return this._getSignesDraconiques(coord).length > 0;
|
||||
}
|
||||
async _moralDecrease(rollData) {
|
||||
RdDResolutionTable.displayRollData(rollData, this, 'chat-resultat-competence.html')
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async rollLireSigneDraconique(coord) {
|
||||
if (!this.isHautRevant()) {
|
||||
ui.notifications.info("Seul un haut rêvant peut lire un signe draconique!");
|
||||
return;
|
||||
}
|
||||
let signes = this._getSignesDraconiques(coord);
|
||||
if (signes.length == 0) {
|
||||
ui.notifications.info(`Aucun signe draconiques en ${coord} !`);
|
||||
return;
|
||||
}
|
||||
if (this.currentTMR) this.currentTMR.minimize(); // Hide
|
||||
|
||||
let draconicList = this.getDraconicList()
|
||||
.map(draconic => duplicate(Misc.data(draconic)))
|
||||
.map(draconic => { draconic.data.defaut_carac = "intellect"; return draconic; });
|
||||
|
||||
const intellect = Misc.templateData(this).carac.intellect;
|
||||
let rollData = {
|
||||
carac: { 'intellect': intellect },
|
||||
selectedCarac: intellect,
|
||||
competence: draconicList[0],
|
||||
draconicList: draconicList,
|
||||
signe: signes[0],
|
||||
signes: signes,
|
||||
tmr: TMRUtility.getTMR(coord),
|
||||
diffLibre: Misc.data(signes[0]).data.difficulte,
|
||||
}
|
||||
|
||||
const dialog = await RdDRoll.create(this, rollData,
|
||||
{
|
||||
html: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-signedraconique.html',
|
||||
options: { height: 600 },
|
||||
close: html => { this.currentTMR.maximize() } // Re-display TMR
|
||||
},
|
||||
{
|
||||
name: 'lire-signe-draconique',
|
||||
label: 'Lire le signe draconique',
|
||||
callbacks: [
|
||||
this.createCallbackExperience(),
|
||||
{ action: r => this._rollLireSigneDraconique(r) }
|
||||
]
|
||||
}
|
||||
);
|
||||
dialog.render(true);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async _rollLireSigneDraconique(rollData) {
|
||||
const compData = rollData.competence;
|
||||
if (!RdDItemCompetence.isDraconic(compData)) {
|
||||
ui.notifications.error(`La compétence ${compData.name} n'est pas une compétence draconique`);
|
||||
return;
|
||||
}
|
||||
rollData.xpSort = RdDItemSigneDraconique.getXpSortSigneDraconique(rollData.rolled.code, rollData.signe);
|
||||
if (rollData.xpSort > 0) {
|
||||
await this.updateEmbeddedDocuments("Item", [{ _id: compData._id, 'data.xp_sort': Misc.toInt(compData.data.xp_sort) + rollData.xpSort }]);
|
||||
}
|
||||
await this.deleteEmbeddedDocuments("Item", [rollData.signe._id]);
|
||||
RdDResolutionTable.displayRollData(rollData, this.name, 'chat-resultat-lecture-signedraconique.html');
|
||||
this.currentTMR.close();
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
@ -2840,6 +2910,7 @@ export class RdDActor extends Actor {
|
||||
fatigue: RdDUtility.calculFatigueHtml(fatigue, endurance),
|
||||
draconic: this.getDraconicList(),
|
||||
sort: this.getSortList(),
|
||||
signes: this.listItemsData("signedraconique"),
|
||||
caracReve: actorData.data.carac.reve.value,
|
||||
pointsReve: this.getReveActuel(),
|
||||
isRapide: isRapide
|
||||
@ -2904,14 +2975,14 @@ export class RdDActor extends Actor {
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
computeArmure(attackerRoll) {
|
||||
async computeArmure(attackerRoll) {
|
||||
let dmg = (attackerRoll.dmg.dmgArme ?? 0) + (attackerRoll.dmg.dmgActor ?? 0);
|
||||
let armeData = attackerRoll.arme;
|
||||
let protection = 0;
|
||||
const armures = this.items.map(it => Misc.data(it))
|
||||
.filter(it => it.type == "armure" && it.data.equipe);
|
||||
for (const itemData of armures) {
|
||||
protection += new Roll(itemData.data.protection.toString()).roll().total;
|
||||
protection += await RdDDice.rollTotal(itemData.data.protection.toString());
|
||||
if (dmg > 0) {
|
||||
this._deteriorerArmure(itemData, dmg);
|
||||
dmg = 0;
|
||||
@ -2972,7 +3043,7 @@ export class RdDActor extends Actor {
|
||||
console.log("encaisserDommages", rollData)
|
||||
|
||||
let santeOrig = duplicate(Misc.templateData(this).sante);
|
||||
let encaissement = this.jetEncaissement(rollData);
|
||||
let encaissement = await this.jetEncaissement(rollData);
|
||||
|
||||
this.ajouterBlessure(encaissement); // Will upate the result table
|
||||
const perteVie = this.isEntiteCauchemar()
|
||||
@ -3011,29 +3082,34 @@ export class RdDActor extends Actor {
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
jetEncaissement(rollData) {
|
||||
const roll = new Roll("2d10").roll();
|
||||
roll.showDice = true;
|
||||
RdDDice.show(roll, game.settings.get("core", "rollMode"));
|
||||
async jetEncaissement(rollData) {
|
||||
const roll = await RdDDice.roll("2d10", { showDice: true });
|
||||
|
||||
const armure = this.computeArmure(rollData);
|
||||
const armure = await this.computeArmure(rollData);
|
||||
const jetTotal = roll.total + rollData.dmg.total - armure;
|
||||
|
||||
let encaissement = RdDUtility.selectEncaissement(jetTotal, rollData.dmg.mortalite)
|
||||
let over20 = Math.max(jetTotal - 20, 0);
|
||||
encaissement.dmg = rollData.dmg;
|
||||
encaissement.dmg.loc = rollData.dmg.loc ?? RdDUtility.getLocalisation(this.data.type);
|
||||
encaissement.dmg.loc = rollData.dmg.loc ?? await RdDUtility.getLocalisation(this.data.type);
|
||||
encaissement.dmg.loc.label = encaissement.dmg.loc.label ?? 'Corps;'
|
||||
encaissement.roll = roll;
|
||||
encaissement.armure = armure;
|
||||
encaissement.total = jetTotal;
|
||||
encaissement.vie = RdDUtility._evaluatePerte(encaissement.vie, over20);
|
||||
encaissement.endurance = RdDUtility._evaluatePerte(encaissement.endurance, over20);
|
||||
encaissement.vie = await RdDActor._evaluatePerte(encaissement.vie, over20);
|
||||
encaissement.endurance = await RdDActor._evaluatePerte(encaissement.endurance, over20);
|
||||
encaissement.penetration = rollData.arme?.data.penetration ?? 0;
|
||||
|
||||
return encaissement;
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static async _evaluatePerte(formula, over20) {
|
||||
let perte = new Roll(formula, { over20: over20 });
|
||||
await perte.evaluate({ async: true });
|
||||
return perte.total;
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
ajouterBlessure(encaissement) {
|
||||
const actorData = Misc.data(this);
|
||||
@ -3615,7 +3691,7 @@ export class RdDActor extends Actor {
|
||||
potionData.reussiteReve = true;
|
||||
potionData.aphasiePermanente = false;
|
||||
if (potionData.data.reposalchimique) {
|
||||
let chanceAphasie = new Roll("1d100").evaluate({ async: false }).total;
|
||||
let chanceAphasie = await RdDDice.rollTotal("1d100");
|
||||
if (chanceAphasie <= potionData.data.pr) {
|
||||
potionData.aphasiePermanente = true;
|
||||
}
|
||||
|
116
module/dialog-create-signedraconique.js
Normal file
116
module/dialog-create-signedraconique.js
Normal file
@ -0,0 +1,116 @@
|
||||
import { ChatUtility } from "./chat-utility.js";
|
||||
import { HtmlUtility } from "./html-utility.js";
|
||||
import { RdDItemSigneDraconique } from "./item-signedraconique.js";
|
||||
import { Misc } from "./misc.js";
|
||||
import { RdDRollTables } from "./rdd-rolltables.js";
|
||||
import { TMRType, TMRUtility } from "./tmr-utility.js";
|
||||
|
||||
export class DialogCreateSigneDraconique extends Dialog {
|
||||
|
||||
static async createSigneForActors() {
|
||||
const signe = await RdDItemSigneDraconique.randomSigneDraconique();
|
||||
let dialogData = {
|
||||
signe: signe,
|
||||
tmrs: TMRUtility.listSelectedTMR(signe.data.typesTMR ?? []),
|
||||
actors: game.actors.filter(actor => actor.isHautRevant()).map(actor => {
|
||||
let actorData = duplicate(Misc.data(actor));
|
||||
actorData.selected = actor.hasPlayerOwner;
|
||||
return actorData;
|
||||
})
|
||||
};
|
||||
|
||||
const html = await renderTemplate("systems/foundryvtt-reve-de-dragon/templates/dialog-create-signedraconique.html", dialogData);
|
||||
new DialogCreateSigneDraconique(dialogData, html)
|
||||
.render(true);
|
||||
}
|
||||
|
||||
constructor(dialogData, html, callback) {
|
||||
let options = { classes: ["DialogCreateSigneDraconiqueActorsActors"], width: 500, height: 650, 'z-index': 99999 };
|
||||
let conf = {
|
||||
title: "Créer un signe",
|
||||
content: html,
|
||||
default: "Ajouter aux haut-rêvants",
|
||||
buttons: {
|
||||
"Ajouter aux haut-rêvants": { label: "Ajouter aux haut-rêvants", callback: it => { this._onCreerSigneActeurs(); } }
|
||||
}
|
||||
};
|
||||
super(conf, options);
|
||||
this.dialogData = dialogData;
|
||||
}
|
||||
|
||||
async _onCreerSigneActeurs() {
|
||||
this.validerSigne();
|
||||
this.dialogData.actors.filter(it => it.selected).map(it => game.actors.get(it._id))
|
||||
.forEach(actor => this._createSigneForActor(actor, this.dialogData.signe));
|
||||
}
|
||||
|
||||
async _createSigneForActor(actor, signe) {
|
||||
actor.createEmbeddedDocuments("Item", [signe]);
|
||||
ChatMessage.create({
|
||||
whisper: ChatUtility.getWhisperRecipientsAndGMs(Misc.data(actor).name),
|
||||
content: await renderTemplate("systems/foundryvtt-reve-de-dragon/templates/chat-signe-draconique-actor.html", {
|
||||
signe: signe,
|
||||
alias: Misc.data(actor).name
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
validerSigne() {
|
||||
this.dialogData.signe.name = $("[name='signe.name']").val();
|
||||
this.dialogData.signe.data.valeur.norm = $("[name='signe.data.valeur.norm']").val();
|
||||
this.dialogData.signe.data.valeur.sign = $("[name='signe.data.valeur.sign']").val();
|
||||
this.dialogData.signe.data.valeur.part = $("[name='signe.data.valeur.part']").val();
|
||||
this.dialogData.signe.data.difficulte = $("[name='signe.data.difficulte']").val();
|
||||
this.dialogData.signe.data.ephemere = $("[name='signe.data.ephemere']").prop("checked");
|
||||
this.dialogData.signe.data.duree = $("[name='signe.data.duree']").val();
|
||||
this.dialogData.signe.data.typesTMR = $(".select-tmr").val();
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
activateListeners(html) {
|
||||
super.activateListeners(html);
|
||||
this.setEphemere(this.dialogData.signe.data.ephemere);
|
||||
html.find(".signe-aleatoire").click(event => this.setSigneAleatoire());
|
||||
html.find("[name='signe.data.ephemere']").change((event) => this.setEphemere(event.currentTarget.checked));
|
||||
html.find(".select-actor").change((event) => this.onSelectActor(event));
|
||||
html.find(".signe-xp-sort").change((event) => this.onValeurXpSort(event));
|
||||
}
|
||||
async setSigneAleatoire() {
|
||||
const newSigne = await RdDItemSigneDraconique.randomSigneDraconique();
|
||||
|
||||
$("[name='signe.name']").val(newSigne.name);
|
||||
$("[name='signe.data.valeur.norm']").val(newSigne.data.valeur.norm);
|
||||
$("[name='signe.data.valeur.sign']").val(newSigne.data.valeur.sign);
|
||||
$("[name='signe.data.valeur.part']").val(newSigne.data.valeur.part);
|
||||
$("[name='signe.data.difficulte']").val(newSigne.data.difficulte);
|
||||
$("[name='signe.data.duree']").val(newSigne.data.duree);
|
||||
$("[name='signe.data.ephemere']").prop("checked", newSigne.data.ephemere);
|
||||
$(".select-tmr").val(newSigne.data.typesTMR);
|
||||
this.setEphemere(newSigne.data.ephemere);
|
||||
}
|
||||
|
||||
async setEphemere(ephemere) {
|
||||
this.dialogData.signe.data.ephemere = ephemere;
|
||||
HtmlUtility._showControlWhen($(".signe-data-duree"), ephemere);
|
||||
}
|
||||
|
||||
async onSelectActor(event) {
|
||||
event.preventDefault();
|
||||
const options = event.currentTarget.options;
|
||||
for (var i = 0; i < options.length; i++) { // looping over the options
|
||||
const actorId = options[i].attributes["data-actor-id"].value;
|
||||
const actor = this.dialogData.actors.find(it => it._id == actorId);
|
||||
if (actor) {
|
||||
actor.selected = options[i].selected;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
onValeurXpSort(event) {
|
||||
const codeReussite = event.currentTarget.attributes['data-typereussite']?.value ?? 0;
|
||||
const xp = Number(event.currentTarget.value);
|
||||
const oldValeur = this.dialogData.signe.data.valeur;
|
||||
this.dialogData.signe.data.valeur = RdDItemSigneDraconique.calculValeursXpSort(codeReussite, xp, oldValeur);
|
||||
}
|
||||
|
||||
}
|
@ -51,8 +51,9 @@ export class RdDItemSheet extends ItemSheet {
|
||||
/** @override */
|
||||
setPosition(options = {}) {
|
||||
const position = super.setPosition(options);
|
||||
const sheetHeader = this.element.find(".sheet-header");
|
||||
const sheetBody = this.element.find(".sheet-body");
|
||||
const bodyHeight = position.height - 192;
|
||||
const bodyHeight = position.height - sheetHeader[0].clientHeight;
|
||||
sheetBody.css("height", bodyHeight);
|
||||
return position;
|
||||
}
|
||||
|
104
module/item-signedraconique-sheet.js
Normal file
104
module/item-signedraconique-sheet.js
Normal file
@ -0,0 +1,104 @@
|
||||
import { RdDItemSigneDraconique } from "./item-signedraconique.js";
|
||||
import { Misc } from "./misc.js";
|
||||
import { TMRType, TMRUtility } from "./tmr-utility.js";
|
||||
|
||||
/**
|
||||
* Item sheet pour signes draconiques
|
||||
* @extends {ItemSheet}
|
||||
*/
|
||||
export class RdDSigneDraconiqueItemSheet extends ItemSheet {
|
||||
|
||||
/** @override */
|
||||
static get defaultOptions() {
|
||||
return mergeObject(super.defaultOptions, {
|
||||
classes: ["foundryvtt-reve-de-dragon", "sheet", "item"],
|
||||
template: "systems/foundryvtt-reve-de-dragon/templates/item-signedraconique-sheet.html",
|
||||
width: 550,
|
||||
height: 550
|
||||
});
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
_getHeaderButtons() {
|
||||
let buttons = super._getHeaderButtons();
|
||||
buttons.unshift({ class: "post", icon: "fas fa-comment", onclick: ev => this.item.postItem() });
|
||||
return buttons;
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
/** @override */
|
||||
setPosition(options = {}) {
|
||||
const position = super.setPosition(options);
|
||||
const sheetHeader = this.element.find(".sheet-header");
|
||||
const sheetBody = this.element.find(".sheet-body");
|
||||
const bodyHeight = position.height - sheetHeader[0].clientHeight;
|
||||
sheetBody.css("height", bodyHeight);
|
||||
return position;
|
||||
}
|
||||
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async getData() {
|
||||
const formData = duplicate(Misc.data(this.object));
|
||||
mergeObject(formData, {
|
||||
title: formData.name,
|
||||
isGM: game.user.isGM,
|
||||
owner: this.document.isOwner,
|
||||
isOwned: this.actor ? true : false,
|
||||
actorId: this.actor?.id,
|
||||
editable: this.isEditable,
|
||||
cssClass: this.isEditable ? "editable" : "locked",
|
||||
});
|
||||
formData.tmrs = TMRUtility.listSelectedTMR(formData.data.typesTMR ?? []);
|
||||
return formData;
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
/** @override */
|
||||
activateListeners(html) {
|
||||
super.activateListeners(html);
|
||||
|
||||
if (!this.options.editable) return;
|
||||
|
||||
html.find(".signe-aleatoire").click(event => this.setSigneAleatoire());
|
||||
html.find(".select-tmr").change((event) => this.onSelectTmr(event));
|
||||
html.find(".signe-xp-sort").change((event) => this.onValeurXpSort(event.currentTarget.attributes['data-typereussite']?.value, Number(event.currentTarget.value)));
|
||||
}
|
||||
|
||||
async setSigneAleatoire() {
|
||||
const newSigne = await RdDItemSigneDraconique.randomSigneDraconique();
|
||||
// $("[name='signe.name']").val(newSigne.name);
|
||||
// $("[name='signe.data.valeur.norm']").val(newSigne.data.valeur.norm);
|
||||
// $("[name='signe.data.valeur.sign']").val(newSigne.data.valeur.sign);
|
||||
// $("[name='signe.data.valeur.part']").val(newSigne.data.valeur.part);
|
||||
// $("[name='signe.data.difficulte']").val(newSigne.data.difficulte);
|
||||
// $("[name='signe.data.duree']").val(newSigne.data.duree);
|
||||
// $("[name='signe.data.ephemere']").prop("checked", newSigne.data.ephemere);
|
||||
// $(".select-tmr").val(newSigne.data.typesTMR);
|
||||
// this.setEphemere(newSigne.data.ephemere);
|
||||
this.object.update(newSigne);
|
||||
}
|
||||
|
||||
async onSelectTmr(event) {
|
||||
event.preventDefault();
|
||||
const selectedTMR = $(".select-tmr").val();
|
||||
this.object.update({ 'data.typesTMR': selectedTMR });
|
||||
}
|
||||
|
||||
async onValeurXpSort(event) {
|
||||
const codeReussite = event.currentTarget.attributes['data-typereussite']?.value ?? 0;
|
||||
const xp = Number(event.currentTarget.value);
|
||||
const oldValeur = Misc.templateData(this.object).valeur;
|
||||
const newValeur = RdDItemSigneDraconique.calculValeursXpSort(codeReussite, xp, oldValeur);
|
||||
await this.object.update({ 'data.valeur': newValeur });
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
get template() {
|
||||
return `systems/foundryvtt-reve-de-dragon/templates/item-signedraconique-sheet.html`;
|
||||
}
|
||||
|
||||
get title() {
|
||||
return `Signe draconique: ${this.object.name}`;
|
||||
}
|
||||
}
|
100
module/item-signedraconique.js
Normal file
100
module/item-signedraconique.js
Normal file
@ -0,0 +1,100 @@
|
||||
import { Misc } from "./misc.js";
|
||||
import { RdDDice } from "./rdd-dice.js";
|
||||
import { RdDRollTables } from "./rdd-rolltables.js";
|
||||
import { TMRType } from "./tmr-utility.js";
|
||||
|
||||
const tableSignesIndicatifs = [
|
||||
{ rarete: "Très facile", difficulte: 0, xp: 6, nbCases: 14 },
|
||||
{ rarete: "Facile", difficulte: -2, xp: 10, nbCases: 10 },
|
||||
{ rarete: "Moyen", difficulte: -3, xp: 15, nbCases: 7 },
|
||||
{ rarete: "Difficile", difficulte: -5, xp: 20, nbCases: 4 },
|
||||
{ rarete: "Ardu", difficulte: -8, xp: 30, nbCases: 1 }
|
||||
|
||||
]
|
||||
export class RdDItemSigneDraconique {
|
||||
|
||||
static prepareSigneDraconiqueMeditation(meditation, rolled) {
|
||||
if (rolled.isSuccess != undefined) {
|
||||
meditation = Misc.data(meditation);
|
||||
return {
|
||||
name: "de la " + meditation.name,
|
||||
type: "signedraconique",
|
||||
img: meditation.img,
|
||||
data: {
|
||||
"typesTMR": [Misc.upperFirst(meditation.data.tmr)],
|
||||
"difficulte": RdDItemSigneDraconique.getDiffSigneMeditation(rolled.code),
|
||||
"ephemere": true,
|
||||
"duree": "1 round",
|
||||
"valeur": { "norm": 3, "sign": 5, "part": 10 }
|
||||
}
|
||||
};
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
static getDiffSigneMeditation(code) {
|
||||
switch (code) {
|
||||
case "norm": return -7;
|
||||
case "sign": return -3;
|
||||
case "part": return 0;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
static getXpSortSigneDraconique(code, signe) {
|
||||
return Misc.data(signe).data.valeur[code] ?? 0;
|
||||
}
|
||||
|
||||
static calculValeursXpSort(qualite, valeur, avant) {
|
||||
switch (qualite) {
|
||||
case "norm":
|
||||
return {
|
||||
norm: valeur,
|
||||
sign: Math.max(valeur, avant.sign),
|
||||
part: Math.max(valeur, avant.part)
|
||||
}
|
||||
case "sign":
|
||||
return {
|
||||
norm: Math.min(valeur, avant.norm),
|
||||
sign: valeur,
|
||||
part: Math.max(valeur, avant.part)
|
||||
}
|
||||
case "part":
|
||||
return {
|
||||
norm: Math.min(valeur, avant.norm),
|
||||
sign: Math.min(valeur, avant.sign),
|
||||
part: valeur
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static async randomSigneDraconique() {
|
||||
let modele = await RdDDice.rollOneOf(tableSignesIndicatifs);
|
||||
return {
|
||||
name: await RdDItemSigneDraconique.randomSigneDescription(),
|
||||
type: "signedraconique",
|
||||
img: 'systems/foundryvtt-reve-de-dragon/icons/tmr/signe_draconique.webp',
|
||||
data: {
|
||||
typesTMR: await RdDItemSigneDraconique.randomTmrs(modele.nbCases),
|
||||
ephemere: true,
|
||||
duree: "1 round",
|
||||
difficulte: modele.difficulte,
|
||||
valeur: { norm: modele.xp, sign: modele.xp, part: Math.floor(modele.xp * 1.5) },
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
static async randomTmrs(nbTmr = undefined) {
|
||||
let tmrs = Object.values(TMRType).map(value => Misc.upperFirst(value.name));
|
||||
let keep = nbTmr ?? (await RdDDice.rollTotal("1d" + TMRType.length) + 1);
|
||||
for (let i = tmrs.length; i > keep; i--) {
|
||||
tmrs.splice(await RdDDice.rollTotal("1d" + i), 1);
|
||||
}
|
||||
return tmrs;
|
||||
}
|
||||
|
||||
static async randomSigneDescription() {
|
||||
return await RdDRollTables.drawTextFromRollTable("Signes draconiques", false);
|
||||
}
|
||||
|
||||
}
|
@ -25,6 +25,7 @@ export class RdDItem extends Item {
|
||||
isConteneur() {
|
||||
return Misc.data(this).type == 'conteneur';
|
||||
}
|
||||
|
||||
isVide() {
|
||||
return this.isConteneur() && (Misc.templateData(this).contenu ?? []).length == 0;
|
||||
}
|
||||
|
@ -1,3 +1,4 @@
|
||||
import { RdDDice } from "./rdd-dice.js";
|
||||
|
||||
/**
|
||||
* This class is intended as a placeholder for utility methods unrelated
|
||||
@ -92,10 +93,6 @@ export class Misc {
|
||||
}
|
||||
}
|
||||
|
||||
static rollOneOf(array) {
|
||||
return array[new Roll("1d" + array.length).evaluate({ async: false }).total - 1];
|
||||
}
|
||||
|
||||
static distinct(array) {
|
||||
return [...new Set(array)];
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { Misc } from "./misc.js"
|
||||
import { RdDDice } from "./rdd-dice.js";
|
||||
|
||||
const poesieHautReve = [
|
||||
{
|
||||
@ -64,8 +65,8 @@ const poesieHautReve = [
|
||||
]
|
||||
|
||||
export class Poetique {
|
||||
static getExtrait(){
|
||||
return Misc.rollOneOf(poesieHautReve);
|
||||
static async getExtrait(){
|
||||
return await RdDDice.rollOneOf(poesieHautReve);
|
||||
}
|
||||
|
||||
}
|
@ -5,6 +5,8 @@ import { HtmlUtility } from "./html-utility.js";
|
||||
import { RdDResolutionTable } from "./rdd-resolution-table.js";
|
||||
import { RdDUtility } from "./rdd-utility.js";
|
||||
import { Grammar } from "./grammar.js";
|
||||
import { Misc } from "./misc.js";
|
||||
import {RdDDice } from "./rdd-dice.js";
|
||||
|
||||
/* -------------------------------------------- */
|
||||
const dossierIconesHeures = 'systems/foundryvtt-reve-de-dragon/icons/heures/'
|
||||
@ -124,9 +126,9 @@ export class RdDCalendrier extends Application {
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
ajouterNombreAstral(index) {
|
||||
async ajouterNombreAstral(index) {
|
||||
return {
|
||||
nombreAstral: new Roll("1d12").evaluate( {async:false} ).total,
|
||||
nombreAstral: await RdDDice.rollTotal("1dh"),
|
||||
valeursFausses: [],
|
||||
index: index
|
||||
}
|
||||
@ -278,11 +280,10 @@ export class RdDCalendrier extends Application {
|
||||
request.isValid = true;
|
||||
if (!request.rolled.isSuccess) {
|
||||
request.isValid = false;
|
||||
let nbAstralFaux = new Roll("1d11").evaluate( { async: false} ).total;
|
||||
nbAstral = nbAstral==nbAstralFaux ? 12 : nbAstralFaux;
|
||||
nbAstral = await RdDDice.rollTotal("1dhr"+nbAstral);
|
||||
// Mise à jour des nombres astraux du joueur
|
||||
let astralData = this.listeNombreAstral.find((nombreAstral, i) => nombreAstral.index == request.date);
|
||||
astralData.valeursFausses.push({ actorId: request.id, nombreAstral: nbAstralFaux });
|
||||
astralData.valeursFausses.push({ actorId: request.id, nombreAstral: nbAstral });
|
||||
game.settings.set("foundryvtt-reve-de-dragon", "liste-nombre-astral", this.listeNombreAstral);
|
||||
}
|
||||
request.nbAstral = nbAstral;
|
||||
|
@ -1,5 +1,6 @@
|
||||
/* -------------------------------------------- */
|
||||
|
||||
import { DialogCreateSigneDraconique } from "./dialog-create-signedraconique.js";
|
||||
import { RdDItemCompetence } from "./item-competence.js";
|
||||
import { Misc } from "./misc.js";
|
||||
import { RdDCarac } from "./rdd-carac.js";
|
||||
@ -82,6 +83,17 @@ export class RdDCommands {
|
||||
descr: `Affiche les heures de chance et de malchance selon l'heure de naissance donnée en argument. Exemples:
|
||||
<br><strong>/astro Lyre</strong>`
|
||||
});
|
||||
|
||||
rddCommands.registerCommand({
|
||||
path: ["/signe", "+"], func: (content, msg, params) => rddCommands.creerSignesDraconiques(),
|
||||
descr: "Crée un signe draconique et l'ajoute aux haut-rêvants choisis."
|
||||
});
|
||||
|
||||
rddCommands.registerCommand({
|
||||
path: ["/signe", "-"], func: (content, msg, params) => rddCommands.supprimerSignesDraconiquesEphemeres(),
|
||||
descr: "Supprime les signes draconiques éphémères"
|
||||
});
|
||||
|
||||
game.system.rdd.commands = rddCommands;
|
||||
}
|
||||
}
|
||||
@ -271,16 +283,14 @@ export class RdDCommands {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async rollDeDraconique(msg) {
|
||||
let ddr = new Roll("1dr + 7").evaluate();
|
||||
ddr.showDice = true;
|
||||
await RdDDice.showDiceSoNice(ddr);
|
||||
RdDCommands._chatAnswer(msg, `Lancer d'un Dé draconique: ${ddr.total}`);
|
||||
let ddr = await RdDDice.rollTotal("1dr + 7", { showDice:true });
|
||||
RdDCommands._chatAnswer(msg, `Lancer d'un Dé draconique: ${ddr}`);
|
||||
}
|
||||
|
||||
getTMRAleatoire(msg, params) {
|
||||
async getTMRAleatoire(msg, params) {
|
||||
if (params.length < 2) {
|
||||
let type = params[0];
|
||||
const tmr = TMRUtility.getTMRAleatoire(type ? (it => it.type == type) : (it => true));
|
||||
const tmr = await TMRUtility.getTMRAleatoire(type ? (it => it.type == type) : (it => true));
|
||||
RdDCommands._chatAnswer(msg, `Case aléatoire: ${tmr.coord} - ${tmr.label}`);
|
||||
}
|
||||
else {
|
||||
@ -312,5 +322,20 @@ export class RdDCommands {
|
||||
}
|
||||
}
|
||||
|
||||
async creerSignesDraconiques() {
|
||||
DialogCreateSigneDraconique.createSigneForActors();
|
||||
return true;
|
||||
}
|
||||
|
||||
async supprimerSignesDraconiquesEphemeres() {
|
||||
game.actors.forEach(actor => {
|
||||
const ephemeres = actor.filterItems(item => Misc.data(item).type = 'signedraconique' && Misc.data(item).data.ephemere)
|
||||
.map(item => item.id);
|
||||
if (ephemeres.length > 0) {
|
||||
actor.deleteEmbeddedDocuments("Item", ephemeres);
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -36,7 +36,7 @@ export class De7 extends Die {
|
||||
super(termData);
|
||||
}
|
||||
|
||||
evaluate() {
|
||||
async evaluate() {
|
||||
super.evaluate();
|
||||
this.explode("x=8");
|
||||
return this;
|
||||
@ -73,7 +73,7 @@ export class DeDraconique extends Die {
|
||||
super(termData);
|
||||
}
|
||||
|
||||
evaluate() {
|
||||
async evaluate() {
|
||||
super.evaluate();
|
||||
this.explode("x=7");
|
||||
return this;
|
||||
@ -124,6 +124,27 @@ export class RdDDice {
|
||||
CONFIG.Dice.terms[DeHeure.DENOMINATION] = DeHeure;
|
||||
}
|
||||
|
||||
static async roll(formula, options = { showDice: false }) {
|
||||
const roll = new Roll(formula);
|
||||
await roll.evaluate({ async: true });
|
||||
if (options.showDice) {
|
||||
roll.showDice = options.showDice;
|
||||
}
|
||||
await RdDDice.show(roll, game.settings.get("core", "rollMode"));
|
||||
return roll;
|
||||
}
|
||||
|
||||
static async rollTotal(formula) {
|
||||
const roll = new Roll(formula);
|
||||
await roll.evaluate({ async: true });
|
||||
return roll.total;
|
||||
}
|
||||
|
||||
static async rollOneOf(array) {
|
||||
const roll = await RdDDice.rollTotal(`1d${array.length}`);
|
||||
return array[roll-1];
|
||||
}
|
||||
|
||||
static diceSoNiceReady(dice3d) {
|
||||
for (const system of Object.keys(dice3d.DiceFactory.systems)) {
|
||||
dice3d.addDicePreset(De7.diceSoNiceData(system));
|
||||
|
@ -31,6 +31,7 @@ import { EffetsDraconiques } from "./tmr/effets-draconiques.js";
|
||||
import { RdDHerbes } from "./rdd-herbes.js";
|
||||
import { RdDItem } from "./item.js";
|
||||
import { RdDDice } from "./rdd-dice.js";
|
||||
import { RdDSigneDraconiqueItemSheet } from "./item-signedraconique-sheet.js";
|
||||
|
||||
/* -------------------------------------------- */
|
||||
/* Foundry VTT Initialization */
|
||||
@ -167,6 +168,11 @@ Hooks.once("init", async function () {
|
||||
Actors.registerSheet("foundryvtt-reve-de-dragon", RdDActorVehiculeSheet, { types: ["vehicule"], makeDefault: true });
|
||||
Actors.registerSheet("foundryvtt-reve-de-dragon", RdDActorEntiteSheet, { types: ["entite"], makeDefault: true });
|
||||
Items.unregisterSheet("core", ItemSheet);
|
||||
Items.registerSheet("foundryvtt-reve-de-dragon", RdDSigneDraconiqueItemSheet, {
|
||||
label: "Signe draconique",
|
||||
types: ["signedraconique"],
|
||||
makeDefault: true
|
||||
});
|
||||
Items.registerSheet("foundryvtt-reve-de-dragon", RdDItemSheet, { makeDefault: true });
|
||||
CONFIG.Combat.documentClass = RdDCombatManager;
|
||||
|
||||
@ -176,7 +182,7 @@ Hooks.once("init", async function () {
|
||||
RdDDice.init();
|
||||
RdDCommands.init();
|
||||
RdDCombat.init();
|
||||
RdDCombatManager.init(),
|
||||
RdDCombatManager.init();
|
||||
RdDTokenHud.init();
|
||||
RdDActor.init();
|
||||
RddCompendiumOrganiser.init();
|
||||
|
@ -1,14 +1,17 @@
|
||||
import { Grammar } from "./grammar.js";
|
||||
import { Misc } from "./misc.js";
|
||||
import { RdDDice } from "./rdd-dice.js";
|
||||
|
||||
const words = [ 'pore', 'pre', 'flor', 'lane', 'turlu', 'pin', 'a', 'alph', 'i', 'onse', 'iane', 'ane', 'zach', 'arri', 'ba', 'bo', 'bi',
|
||||
'alta', 'par', 'pir', 'zor', 'zir', 'de', 'pol', 'tran', 'no', 'la','al' , 'pul', 'one', 'ner', 'nur' ];
|
||||
'alta', 'par', 'pir', 'zor', 'zir', 'de', 'pol', 'tran', 'no', 'la', 'al' , 'pul', 'one', 'ner', 'nur', 'mac', 'mery',
|
||||
'cat', 'do', 'di', 'der', 'er', 'el', 'far', 'fer', 'go', 'guer', 'hot', 'jor', 'jar', 'ji', 'kri', 'ket', 'lor', 'hur',
|
||||
'lar', 'lir', 'lu', 'pot', 'pro', 'pra', 'pit', 'qua', 'qui', 're', 'ral', 'sal', 'sen', 'ted', 'to', 'ta', 'lars', 'ver',
|
||||
'vin', 'ov', 'wal', 'ry', 'ly', '' ];
|
||||
|
||||
/* -------------------------------------------- */
|
||||
export class RdDNameGen {
|
||||
|
||||
static getName( msg, params ) {
|
||||
let name = Misc.upperFirst( Misc.rollOneOf(words) + Misc.rollOneOf(words) )
|
||||
static async getName( msg, params ) {
|
||||
let name = Misc.upperFirst( await RdDDice.rollOneOf(words) + await RdDDice.rollOneOf(words) )
|
||||
//console.log(name);
|
||||
ChatMessage.create( { content: `Nom : ${name}`, whisper: ChatMessage.getWhisperRecipients("GM") } );
|
||||
}
|
||||
|
@ -149,10 +149,7 @@ export class RdDResolutionTable {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static async rollChances(chances, diviseur) {
|
||||
let myRoll = new Roll("1d100").evaluate( {async: false} );
|
||||
myRoll.showDice = chances.showDice;
|
||||
await RdDDice.show(myRoll);
|
||||
chances.roll = myRoll.total;
|
||||
chances.roll = await RdDDice.rollTotal("1d100", {showDice:chances.showDice});
|
||||
mergeObject(chances, this.computeReussite(chances, chances.roll, diviseur), { overwrite: true });
|
||||
return chances;
|
||||
}
|
||||
|
@ -205,6 +205,11 @@ export class RdDRoll extends Dialog {
|
||||
this.updateRollResult();
|
||||
$("#diffLibre").val(this.rollData.diffLibre);
|
||||
});
|
||||
html.find('.roll-signedraconique').change((event) => {
|
||||
let sortKey = Misc.toInt(event.currentTarget.value);
|
||||
this.setSelectedSigneDraconique(this.rollData.signes[sortKey]);
|
||||
this.updateRollResult();
|
||||
});
|
||||
html.find('#ptreve-variable').change((event) => {
|
||||
let ptreve = Misc.toInt(event.currentTarget.value);
|
||||
this.rollData.selectedSort.data.ptreve_reel = ptreve;
|
||||
@ -276,6 +281,12 @@ export class RdDRoll extends Dialog {
|
||||
HtmlUtility._showControlWhen($(".div-sort-ptreve-fixe"), !coutVariable);
|
||||
}
|
||||
|
||||
async setSelectedSigneDraconique(signe){
|
||||
this.rollData.signe = signe;
|
||||
this.rollData.diffLibre = Misc.data(signe).data.difficulte,
|
||||
$(".signe-difficulte").text(Misc.toSignedString(this.rollData.diffLibre));
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async updateRollResult() {
|
||||
let rollData = this.rollData;
|
||||
|
@ -8,31 +8,20 @@ export class RdDRollTables {
|
||||
const table = await pack.getDocument(entry._id);
|
||||
const draw = await table.draw({ displayChat: toChat, rollMode: "gmroll"});
|
||||
console.log("RdDRollTables", tableName, toChat, ":", draw);
|
||||
return draw;
|
||||
return draw.results.length > 0 ? draw.results[0] : undefined;
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static async drawItemFromRollTable(tableName, toChat) {
|
||||
const draw = await RdDRollTables.genericGetTableResult(tableName, toChat);
|
||||
const drawnItemRef = draw.results.length > 0 ? draw.results[0] : undefined;
|
||||
if (drawnItemRef.data.collection) {
|
||||
console.log(drawnItemRef);
|
||||
const pack = game.packs.get(drawnItemRef.data.collection);
|
||||
return await pack.getDocument(drawnItemRef.data.resultId);
|
||||
}
|
||||
ui.notifications.warn("le tirage ne correspond pas à une entrée d'un Compendium")
|
||||
return drawnItemRef.text;
|
||||
static async drawItemFromRollTable(tableName, toChat = false) {
|
||||
const drawResult = await RdDRollTables.genericGetTableResult(tableName, toChat);
|
||||
const pack = game.packs.get(drawResult.data.collection);
|
||||
return await pack.getDocument(drawResult.data.resultId);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static async drawTextFromRollTable(tableName, toChat) {
|
||||
const draw = await RdDRollTables.genericGetTableResult(tableName, toChat);
|
||||
const drawnItemRef = draw.results.length > 0 ? draw.results[0] : undefined;
|
||||
if (drawnItemRef.collection) {
|
||||
ui.notifications.warn("le tirage correspond à une entrée d'un Compendium, on attendait un texte")
|
||||
return await pack.getDocument(drawnItemRef.resultId);
|
||||
}
|
||||
return drawnItemRef.text;
|
||||
const drawResult = await RdDRollTables.genericGetTableResult(tableName, toChat);
|
||||
return drawResult.data.text;
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
|
@ -13,6 +13,7 @@ import { Draconique } from "./tmr/draconique.js";
|
||||
import { Misc } from "./misc.js";
|
||||
import { HtmlUtility } from "./html-utility.js";
|
||||
import { ReglesOptionelles } from "./regles-optionelles.js";
|
||||
import { RdDDice } from "./rdd-dice.js";
|
||||
|
||||
/* -------------------------------------------- */
|
||||
export class RdDTMRDialog extends Dialog {
|
||||
@ -142,20 +143,27 @@ export class RdDTMRDialog extends Dialog {
|
||||
_tokenSortEnReserve(sortEnReserve) {
|
||||
return EffetsDraconiques.sortReserve.token(this.pixiTMR, sortEnReserve.sort, () => sortEnReserve.coord);
|
||||
}
|
||||
|
||||
_tokenDemiReve() {
|
||||
const actorData = Misc.data(this.actor);
|
||||
return EffetsDraconiques.demiReve.token(this.pixiTMR, actorData, () => actorData.data.reve.tmrpos.coord);
|
||||
}
|
||||
|
||||
_updateDemiReve() {
|
||||
this.notifierResonanceSigneDraconique(this._getActorCoord());
|
||||
|
||||
if (!this.cacheTMR) {
|
||||
this._setTokenPosition(this.demiReve);
|
||||
}
|
||||
}
|
||||
|
||||
_getActorCoord() {
|
||||
return Misc.data(this.actor).data.reve.tmrpos.coord;
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async moveFromKey(move) {
|
||||
let pos = TMRUtility.convertToCellPos(Misc.data(this.actor).data.reve.tmrpos.coord);
|
||||
let pos = TMRUtility.convertToCellPos(this._getActorCoord());
|
||||
|
||||
if (move == 'top') pos.y -= 1;
|
||||
if (move == 'bottom') pos.y += 1;
|
||||
@ -178,22 +186,25 @@ export class RdDTMRDialog extends Dialog {
|
||||
async activateListeners(html) {
|
||||
super.activateListeners(html);
|
||||
|
||||
HtmlUtility._showControlWhen($(".appliquerFatigue"), ReglesOptionelles.isUsing("appliquer-fatigue"));
|
||||
document.getElementById("tmrrow1").insertCell(0).append(this.pixiApp.view);
|
||||
|
||||
if (this.viewOnly) {
|
||||
html.find('#lancer-sort').remove();
|
||||
}
|
||||
else {
|
||||
// Roll Sort
|
||||
html.find('#lancer-sort').click((event) => {
|
||||
this.actor.rollUnSort(Misc.data(this.actor).data.reve.tmrpos.coord);
|
||||
});
|
||||
}
|
||||
if (this.viewOnly) {
|
||||
html.find('.lancer-sort').remove();
|
||||
html.find('.lire-signe-draconique').remove();
|
||||
return;
|
||||
}
|
||||
|
||||
HtmlUtility._showControlWhen($(".appliquerFatigue"), ReglesOptionelles.isUsing("appliquer-fatigue"));
|
||||
HtmlUtility._showControlWhen($(".lire-signe-draconique"), this.actor.isResonanceSigneDraconique(this._getActorCoord()));
|
||||
|
||||
// Roll Sort
|
||||
html.find('.lancer-sort').click((event) => {
|
||||
this.actor.rollUnSort(this._getActorCoord());
|
||||
});
|
||||
html.find('.lire-signe-draconique').click((event) => {
|
||||
this.actor.rollLireSigneDraconique(this._getActorCoord());
|
||||
});
|
||||
|
||||
html.find('#dir-top').click((event) => {
|
||||
this.moveFromKey("top");
|
||||
});
|
||||
@ -213,7 +224,6 @@ export class RdDTMRDialog extends Dialog {
|
||||
this.moveFromKey("bottom");
|
||||
});
|
||||
|
||||
|
||||
// Gestion du cout de montée en points de rêve
|
||||
let reveCout = ((this.tmrdata.isRapide && !EffetsDraconiques.isDeplacementAccelere(this.actor)) ? -2 : -1) - this.actor.countMonteeLaborieuse();
|
||||
if (ReglesOptionelles.isUsing("appliquer-fatigue")) {
|
||||
@ -223,24 +233,27 @@ export class RdDTMRDialog extends Dialog {
|
||||
|
||||
// Le reste...
|
||||
this.updateValuesDisplay();
|
||||
let tmr = TMRUtility.getTMR(Misc.data(this.actor).data.reve.tmrpos.coord);
|
||||
let tmr = TMRUtility.getTMR(this._getActorCoord());
|
||||
await this.manageRencontre(tmr, () => {
|
||||
this.postRencontre(tmr);
|
||||
});
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
updateValuesDisplay() {
|
||||
let ptsreve = document.getElementById("tmr-pointsreve-value");
|
||||
async updateValuesDisplay() {
|
||||
const coord = this._getActorCoord();
|
||||
const actorData = Misc.data(this.actor);
|
||||
|
||||
HtmlUtility._showControlWhen($(".lire-signe-draconique"), this.actor.isResonanceSigneDraconique(coord));
|
||||
|
||||
let ptsreve = document.getElementById("tmr-pointsreve-value");
|
||||
ptsreve.innerHTML = actorData.data.reve.reve.value;
|
||||
|
||||
let tmrpos = document.getElementById("tmr-pos");
|
||||
if (this.cacheTMR) {
|
||||
tmrpos.innerHTML = '?? ('+ TMRUtility.getTMRType( actorData.data.reve.tmrpos.coord ) + ')';
|
||||
tmrpos.innerHTML = '?? (' + TMRUtility.getTMRType(coord) + ')';
|
||||
} else {
|
||||
let tmr = TMRUtility.getTMR(actorData.data.reve.tmrpos.coord);
|
||||
tmrpos.innerHTML = actorData.data.reve.tmrpos.coord + " (" + tmr.label + ")";
|
||||
tmrpos.innerHTML = coord + " (" + TMRUtility.getTMRLabel(coord) + ")";
|
||||
}
|
||||
|
||||
let etat = document.getElementById("tmr-etatgeneral-value");
|
||||
@ -373,7 +386,7 @@ export class RdDTMRDialog extends Dialog {
|
||||
rencontre: this.currentRencontre,
|
||||
nbRounds: 1,
|
||||
canClose: false,
|
||||
tmr: TMRUtility.getTMR(Misc.data(this.actor).data.reve.tmrpos.coord)
|
||||
tmr: TMRUtility.getTMR(this._getActorCoord())
|
||||
}
|
||||
|
||||
await this._tentativeMaitrise(rencontreData);
|
||||
@ -523,7 +536,7 @@ export class RdDTMRDialog extends Dialog {
|
||||
if (rencontre) {
|
||||
return rencontre;
|
||||
}
|
||||
let myRoll = new Roll("1d7").evaluate( { async: false} ).total;
|
||||
let myRoll = await RdDDice.rollTotal("1d7");
|
||||
if (TMRUtility.isForceRencontre() || myRoll == 7) {
|
||||
return await this.rencontreTMRRoll(tmr, this.actor.isRencontreSpeciale());
|
||||
}
|
||||
@ -584,7 +597,7 @@ export class RdDTMRDialog extends Dialog {
|
||||
await this._rollMaitriseCaseHumide(rollData);
|
||||
return;
|
||||
}
|
||||
rollData.poesie = Poetique.getExtrait();
|
||||
rollData.poesie = await Poetique.getExtrait();
|
||||
ChatMessage.create({
|
||||
whisper: ChatUtility.getWhisperRecipientsAndGMs(game.user.name),
|
||||
content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-resultat-maitrise-tmr.html`, rollData)
|
||||
@ -701,7 +714,7 @@ export class RdDTMRDialog extends Dialog {
|
||||
}
|
||||
this.toclose = rollData.rolled.isEchec;
|
||||
|
||||
rollData.poesie = Poetique.getExtrait();
|
||||
rollData.poesie = await Poetique.getExtrait();
|
||||
ChatMessage.create({
|
||||
whisper: ChatUtility.getWhisperRecipientsAndGMs(game.user.name),
|
||||
content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-resultat-maitrise-tmr.html`, rollData)
|
||||
@ -852,7 +865,7 @@ export class RdDTMRDialog extends Dialog {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async _onClickTMRPos(eventPos) {
|
||||
let currentPos = TMRUtility.convertToCellPos(Misc.data(this.actor).data.reve.tmrpos.coord);
|
||||
let currentPos = TMRUtility.convertToCellPos(this._getActorCoord());
|
||||
|
||||
console.log("deplacerDemiReve >>>>", currentPos, eventPos);
|
||||
|
||||
@ -896,6 +909,7 @@ export class RdDTMRDialog extends Dialog {
|
||||
Si la case est le demi-rêve, ne pas lancer de sort.
|
||||
Si un lancement de sort est en cours, trouver un moyen de réafficher cette fenêtre si on essaie de lancer un sort (ou bloquer le lancer de sort)
|
||||
*/
|
||||
this.notifierResonanceSigneDraconique(targetCoord);
|
||||
await this.actor.rollUnSort(targetCoord);
|
||||
this.nettoyerRencontre();
|
||||
}
|
||||
@ -920,7 +934,6 @@ export class RdDTMRDialog extends Dialog {
|
||||
// Gestion cases spéciales type Trou noir, etc
|
||||
tmr = await this.manageTmrInnaccessible(tmr);
|
||||
|
||||
this.actor.updateCoordTMR(tmr.coord);
|
||||
await this.actor.updateCoordTMR(tmr.coord);
|
||||
|
||||
this._updateDemiReve();
|
||||
@ -943,6 +956,15 @@ export class RdDTMRDialog extends Dialog {
|
||||
}
|
||||
}
|
||||
|
||||
async notifierResonanceSigneDraconique(coord) {
|
||||
if (this.actor.isResonanceSigneDraconique(coord)) {
|
||||
ChatMessage.create({
|
||||
whisper: ChatUtility.getWhisperRecipientsAndGMs(game.user.name),
|
||||
content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-signe-draconique-resonance.html`, { alias: this.actor.name, typeTMR: TMRUtility.getTMRType(coord) })
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async postRencontre(tmr) {
|
||||
if (!(this.viewOnly || this.currentRencontre)) {
|
||||
|
@ -7,6 +7,7 @@ import { Grammar } from "./grammar.js";
|
||||
import { TMRUtility } from "./tmr-utility.js";
|
||||
import { DialogItemAchat } from "./dialog-item-achat.js";
|
||||
import { ReglesOptionelles } from "./regles-optionelles.js";
|
||||
import { RdDDice } from "./rdd-dice.js";
|
||||
|
||||
/* -------------------------------------------- */
|
||||
// This table starts at 0 -> niveau -10
|
||||
@ -140,6 +141,7 @@ export class RdDUtility {
|
||||
'systems/foundryvtt-reve-de-dragon/templates/item-monnaie-sheet.html',
|
||||
'systems/foundryvtt-reve-de-dragon/templates/item-meditation-sheet.html',
|
||||
'systems/foundryvtt-reve-de-dragon/templates/item-nourritureboisson-sheet.html',
|
||||
'systems/foundryvtt-reve-de-dragon/templates/item-signedraconique-sheet.html',
|
||||
'systems/foundryvtt-reve-de-dragon/templates/competence-carac-defaut.html',
|
||||
'systems/foundryvtt-reve-de-dragon/templates/competence-base.html',
|
||||
'systems/foundryvtt-reve-de-dragon/templates/enum-aspect-tarot.html',
|
||||
@ -204,7 +206,8 @@ export class RdDUtility {
|
||||
'systems/foundryvtt-reve-de-dragon/templates/chat-actor-competence-xp.html',
|
||||
'systems/foundryvtt-reve-de-dragon/templates/chat-actor-carac-xp.html',
|
||||
'systems/foundryvtt-reve-de-dragon/templates/chat-potionenchantee-chateaudormant.html',
|
||||
'systems/foundryvtt-reve-de-dragon/templates/chat-fabriquer-potion-base.html'
|
||||
'systems/foundryvtt-reve-de-dragon/templates/chat-fabriquer-potion-base.html',
|
||||
'systems/foundryvtt-reve-de-dragon/templates/chat-signe-draconique-actor.html'
|
||||
];
|
||||
|
||||
Handlebars.registerHelper('upperFirst', str => Misc.upperFirst(str ?? 'Null'));
|
||||
@ -271,6 +274,7 @@ export class RdDUtility {
|
||||
formData.munitions = this.checkNull(formData.itemsByType['munition']);
|
||||
formData.herbes = this.checkNull(formData.itemsByType['herbe']);
|
||||
formData.sorts = this.checkNull(formData.itemsByType['sort']);
|
||||
formData.signesdraconiques = this.checkNull(formData.itemsByType['signedraconique']);
|
||||
formData.queues = this.checkNull(formData.itemsByType['queue']);
|
||||
formData.souffles = this.checkNull(formData.itemsByType['souffle']);
|
||||
formData.ombres = this.checkNull(formData.itemsByType['ombre']);
|
||||
@ -441,8 +445,8 @@ export class RdDUtility {
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static getLocalisation(type = 'personnage') {
|
||||
let result = new Roll("1d20").roll().total;
|
||||
static async getLocalisation(type = 'personnage') {
|
||||
let result = await RdDDice.rollTotal("1d20");
|
||||
let txt = ""
|
||||
if (type == 'personnage') {
|
||||
if (result <= 3) txt = "Jambe, genou, pied, jarret";
|
||||
@ -474,15 +478,6 @@ export class RdDUtility {
|
||||
return duplicate(table[0]);
|
||||
}
|
||||
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static _evaluatePerte(formula, over20) {
|
||||
console.log("_evaluatePerte", formula, over20);
|
||||
let perte = new Roll(formula, { over20: over20 });
|
||||
perte.evaluate();
|
||||
return perte.total;
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static currentFatigueMalus(value, max) {
|
||||
if (ReglesOptionelles.isUsing("appliquer-fatigue")) {
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { Grammar } from "./grammar.js";
|
||||
import { Misc } from "./misc.js";
|
||||
import { RdDDice } from "./rdd-dice.js";
|
||||
import { TMRUtility } from "./tmr-utility.js";
|
||||
import { TMRType } from "./tmr-utility.js";
|
||||
|
||||
@ -268,7 +269,7 @@ const rencontresStandard = [
|
||||
{ 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: "1ddr + 7", refoulement: 2, quitterTMR: true }
|
||||
{ code: "rdd", name: "Rêve de Dragon", type: "rdd", genre: "m", force: "1dr + 7", refoulement: 2, quitterTMR: true }
|
||||
];
|
||||
|
||||
const rencontresPresentCite = [
|
||||
@ -324,7 +325,7 @@ export class TMRRencontres {
|
||||
return false;
|
||||
}
|
||||
if (!roll || roll <= 0 || roll > 100) {
|
||||
roll = new Roll("1d100").evaluate().total;
|
||||
roll = await RdDDice.rollTotal("1d100");
|
||||
}
|
||||
let rencontre = await TMRRencontres.getRencontreAleatoire(terrain, roll);
|
||||
ChatMessage.create({
|
||||
@ -356,15 +357,13 @@ export class TMRRencontres {
|
||||
/* -------------------------------------------- */
|
||||
static async getRencontreAleatoire(terrain, roll = undefined) {
|
||||
if (!roll || roll <= 0 || roll > 100) {
|
||||
roll = new Roll("1d100").evaluate({ async: false }).total;
|
||||
roll = await RdDDice.rollTotal("1d100");
|
||||
}
|
||||
terrain = Grammar.toLowerCaseNoAccent(terrain);
|
||||
//console.log("getRencontreAleatoire", terrain, roll);
|
||||
const code = tableRencontres[terrain].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);
|
||||
//console.log(rencontre);
|
||||
return rencontre;
|
||||
}
|
||||
|
||||
@ -373,20 +372,14 @@ export class TMRRencontres {
|
||||
const rencontre = duplicate(
|
||||
(index && index >= 0 && index < mauvaisesRencontres.length)
|
||||
? mauvaisesRencontres[index]
|
||||
: Misc.rollOneOf(mauvaisesRencontres));
|
||||
: await RdDDice.rollOneOf(mauvaisesRencontres));
|
||||
await TMRRencontres.evaluerForceRencontre(rencontre);
|
||||
return rencontre;
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static async evaluerForceRencontre(rencontre) {
|
||||
if (TMRRencontres.isReveDeDragon(rencontre)) {
|
||||
const ddr = new Roll("1dr + 7").evaluate();
|
||||
rencontre.force = 7 + ddr.total;
|
||||
}
|
||||
else {
|
||||
rencontre.force = new Roll(rencontre.force).evaluate({ async: false }).total;
|
||||
}
|
||||
rencontre.force = await new Roll(rencontre.force).evaluate().total;
|
||||
return rencontre.force;
|
||||
}
|
||||
|
||||
@ -426,14 +419,14 @@ export class TMRRencontres {
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static msgEchecPasseurFou(tmrData) {
|
||||
static async msgEchecPasseurFou(tmrData) {
|
||||
tmrData.sortReserve = Misc.templateData(tmrData.actor).reve.reserve.list[0];
|
||||
if (tmrData.sortReserve) {
|
||||
// Passeur fou positionne sur la case d'un ort en réserve // TODO : Choisir le sort le plus loin ou au hasard
|
||||
tmrData.newTMR = TMRUtility.getTMR(tmrData.sortReserve.coord);
|
||||
} else {
|
||||
// Déplacement aléatoire de la force du Passeur Fou
|
||||
const newCoord = Misc.rollOneOf(TMRUtility.getTMRPortee(tmrData.tmr.coord, tmrData.rencontre.force));
|
||||
const newCoord = await RdDDice.rollOneOf(TMRUtility.getTMRPortee(tmrData.tmr.coord, tmrData.rencontre.force));
|
||||
tmrData.newTMR = TMRUtility.getTMR(newCoord);
|
||||
}
|
||||
if (tmrData.sortReserve) {
|
||||
@ -472,7 +465,7 @@ export class TMRRencontres {
|
||||
static async _toubillonner(tmrDialog, actor, cases) {
|
||||
let coord = Misc.templateData(actor).reve.tmrpos.coord;
|
||||
for (let i = 0; i < cases; i++) {
|
||||
coord = TMRUtility.deplaceTMRAleatoire(actor, coord).coord;
|
||||
coord = await TMRUtility.deplaceTMRAleatoire(actor, coord).coord;
|
||||
}
|
||||
await tmrDialog.forceDemiRevePosition(coord)
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { TMRRencontres } from "./tmr-rencontres.js";
|
||||
import { Misc } from "./misc.js";
|
||||
import { Grammar } from "./grammar.js";
|
||||
import { RdDDice } from "./rdd-dice.js";
|
||||
|
||||
/* -------------------------------------------- */
|
||||
const TMRMapping = {
|
||||
@ -338,7 +339,7 @@ export class TMRUtility {
|
||||
|
||||
static getTMRType(coord) {
|
||||
const tmr = TMRMapping[coord];
|
||||
return Misc.upperFirst(tmr.type);
|
||||
return Misc.upperFirst(TMRType[tmr.type].name);
|
||||
}
|
||||
|
||||
static getTMRDescr(coord) {
|
||||
@ -346,6 +347,12 @@ export class TMRUtility {
|
||||
return Grammar.articleDetermine(tmr.type) + ' ' + tmr.label;
|
||||
}
|
||||
|
||||
static listSelectedTMR(typesTMR) {
|
||||
return Object.values(TMRType).map(value => Misc.upperFirst(value.name))
|
||||
.sort()
|
||||
.map(name => { return { name: name, selected: typesTMR.includes(name) } });
|
||||
}
|
||||
|
||||
static isCaseHumide(tmr) {
|
||||
return tmr.type == 'fleuve' || tmr.type == 'lac' || tmr.type == 'marais';
|
||||
}
|
||||
@ -380,13 +387,13 @@ export class TMRUtility {
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static getDirectionPattern() {
|
||||
return Misc.rollOneOf(tmrRandomMovePatten);
|
||||
static async getDirectionPattern() {
|
||||
return await RdDDice.rollOneOf(tmrRandomMovePatten);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static deplaceTMRAleatoire(actor, coord) {
|
||||
return TMRUtility.deplaceTMRSelonPattern(actor, coord, TMRUtility.getDirectionPattern(), 1);
|
||||
static async deplaceTMRAleatoire(actor, coord) {
|
||||
return TMRUtility.deplaceTMRSelonPattern(actor, coord, await TMRUtility.getDirectionPattern(), 1);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
@ -418,8 +425,8 @@ export class TMRUtility {
|
||||
return TMRUtility.filterTMR(filter).map(it => it.coord);
|
||||
}
|
||||
|
||||
static getTMRAleatoire(filter = it => true) {
|
||||
return Misc.rollOneOf(TMRUtility.filterTMR(filter))
|
||||
static async getTMRAleatoire(filter = it => true) {
|
||||
return await RdDDice.rollOneOf(TMRUtility.filterTMR(filter))
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { Grammar } from "../grammar.js";
|
||||
import { Misc } from "../misc.js";
|
||||
import { RdDDice } from "../rdd-dice.js";
|
||||
import { tmrColors, tmrConstants, tmrTokenZIndex, TMRUtility } from "../tmr-utility.js";
|
||||
import { Draconique } from "./draconique.js";
|
||||
|
||||
@ -31,7 +32,7 @@ export class Conquete extends Draconique {
|
||||
async _creerConquete(actor, queue) {
|
||||
let existants = actor.data.items.filter(it => this.isCase(it)).map(it => Misc.data(it).data.coord);
|
||||
let possibles = TMRUtility.filterTMR(tmr => !TMRUtility.isCaseHumide(tmr) && !existants.includes(tmr.coord));
|
||||
let conquete = Misc.rollOneOf(possibles);
|
||||
let conquete =await RdDDice.rollOneOf(possibles);
|
||||
await this.createCaseTmr(actor, 'Conquête: ' + conquete.label, conquete, queue.id);
|
||||
}
|
||||
|
||||
|
@ -13,7 +13,7 @@ export class Debordement extends Draconique {
|
||||
manualMessage() { return false }
|
||||
async onActorCreateOwned(actor, souffle) {
|
||||
const existants = actor.data.items.filter(it => this.isCase(it)).map(it => it.data.coord);
|
||||
const tmr = TMRUtility.getTMRAleatoire(it => !(TMRUtility.isCaseHumide(it) || existants.includes(it.coord)));
|
||||
const tmr = await TMRUtility.getTMRAleatoire(it => !(TMRUtility.isCaseHumide(it) || existants.includes(it.coord)));
|
||||
await this.createCaseTmr(actor, 'Debordement: ' + tmr.label, tmr, souffle.id);
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { Grammar } from "../grammar.js";
|
||||
import { Misc } from "../misc.js";
|
||||
import { RdDDice } from "../rdd-dice.js";
|
||||
import { tmrColors, tmrConstants, tmrTokenZIndex, TMRType, TMRUtility } from "../tmr-utility.js";
|
||||
import { Draconique } from "./draconique.js";
|
||||
|
||||
@ -13,7 +14,7 @@ export class Desorientation extends Draconique {
|
||||
manualMessage() { return false }
|
||||
|
||||
async onActorCreateOwned(actor, souffle) {
|
||||
const type = Misc.rollOneOf(this._typesPossibles(actor));
|
||||
const type = await RdDDice.rollOneOf(this._typesPossibles(actor));
|
||||
console.log("désorientation", type);
|
||||
souffle.name += ": " + TMRType[type].name;
|
||||
await this._creerCasesTmr(actor, type, souffle);
|
||||
|
@ -13,7 +13,7 @@ export class Pelerinage extends Draconique {
|
||||
manualMessage() { return false }
|
||||
|
||||
async onActorCreateOwned(actor, queue) {
|
||||
let tmr = TMRUtility.getTMRAleatoire();
|
||||
let tmr = await TMRUtility.getTMRAleatoire();
|
||||
await this.createCaseTmr(actor, 'Pèlerinage: ' + tmr.label, tmr, queue.id);
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { Grammar } from "../grammar.js";
|
||||
import { tmrColors, tmrConstants, tmrTokenZIndex, TMRUtility } from "../tmr-utility.js";
|
||||
import { RdDDice } from "../rdd-dice.js";
|
||||
import { tmrConstants, tmrTokenZIndex, TMRUtility } from "../tmr-utility.js";
|
||||
import { Draconique } from "./draconique.js";
|
||||
|
||||
export class Periple extends Draconique {
|
||||
@ -13,7 +14,7 @@ export class Periple extends Draconique {
|
||||
manualMessage() { return false }
|
||||
|
||||
async onActorCreateOwned(actor, souffle) {
|
||||
let terrain = new Roll("1d2").evaluate().total == 1 ? 'sanctuaire' : 'necropole';
|
||||
let terrain = (await RdDDice.rollTotal("1d2")) == 1 ? 'sanctuaire' : 'necropole';
|
||||
let tmrs = TMRUtility.getListTMR(terrain);
|
||||
for (let tmr of tmrs) {
|
||||
await this.createCaseTmr(actor, 'Périple: ' + tmr.label, tmr, souffle.id);
|
||||
|
@ -12,7 +12,7 @@ export class ReserveExtensible extends Draconique {
|
||||
manualMessage() { return "Vous pouvez re-configurer votre Réserve extensible" }
|
||||
async onActorCreateOwned(actor, tete) {
|
||||
const existants = actor.data.items.filter(it => this.isCase(it)).map(it => it.data.coord);
|
||||
const tmr = TMRUtility.getTMRAleatoire(it => !(it.type == 'fleuve' || existants.includes(it.coord)));
|
||||
const tmr = await TMRUtility.getTMRAleatoire(it => !(it.type == 'fleuve' || existants.includes(it.coord)));
|
||||
await this.createCaseTmr(actor, "Nouvelle Réserve extensible", tmr, tete.id);
|
||||
}
|
||||
|
||||
|
@ -13,7 +13,7 @@ export class TrouNoir extends Draconique {
|
||||
|
||||
async onActorCreateOwned(actor, souffle) {
|
||||
const existants = actor.data.items.filter(it => this.isCase(it)).map(it => it.data.coord);
|
||||
const tmr = TMRUtility.getTMRAleatoire(it => !(TMRUtility.isCaseHumide(it) || existants.includes(it.coord)));
|
||||
const tmr = await TMRUtility.getTMRAleatoire(it => !(TMRUtility.isCaseHumide(it) || existants.includes(it.coord)));
|
||||
await this.createCaseTmr(actor, 'Trou noir: ' + tmr.label, tmr, souffle.id);
|
||||
}
|
||||
|
||||
|
File diff suppressed because one or more lines are too long
@ -577,7 +577,7 @@
|
||||
"Item": {
|
||||
"types": ["objet", "arme", "armure", "conteneur", "competence", "sort", "herbe", "ingredient", "livre", "potion", "munition", "rencontresTMR", "queue", "ombre", "souffle",
|
||||
"tete", "competencecreature", "tarot", "monnaie", "nombreastral", "tache", "meditation", "casetmr", "recettealchimique",
|
||||
"musique", "chant", "danse", "jeu", "recettecuisine", "maladie", "poison", "oeuvre", "nourritureboisson" ],
|
||||
"musique", "chant", "danse", "jeu", "recettecuisine", "maladie", "poison", "oeuvre", "nourritureboisson", "signedraconique" ],
|
||||
"objet": {
|
||||
"description": "",
|
||||
"quantite": 1,
|
||||
@ -868,6 +868,18 @@
|
||||
"encombrement": 0,
|
||||
"quantite": 1,
|
||||
"cout": 0
|
||||
},
|
||||
"signedraconique": {
|
||||
"typesTMR": [],
|
||||
"ephemere": true,
|
||||
"duree": "1 round",
|
||||
"difficulte": 0,
|
||||
"valeur": {
|
||||
"norm": 3,
|
||||
"sign": 5,
|
||||
"part": 10
|
||||
},
|
||||
"description": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -310,7 +310,7 @@
|
||||
<ul class="item-list alterne-list">
|
||||
{{#each taches as |tache id|}}
|
||||
<li class="item flexrow list-item" data-item-id="{{tache._id}}"><span class="competence-title tache-label"><a>{{tache.name}} ({{tache.data.points_de_tache_courant}}/{{tache.data.points_de_tache}})</a></span>
|
||||
<div class="item-controls">
|
||||
<div class="item-controls flex-shrink">
|
||||
<a class="item-control item-edit" title="Edit Item"><i class="fas fa-edit"></i></a>
|
||||
<a class="item-control item-delete" title="Delete Item"><i class="fas fa-trash"></i></a>
|
||||
</div>
|
||||
@ -340,7 +340,7 @@
|
||||
<ul class="item-list alterne-list">
|
||||
{{#each jeux as |jeu id|}}
|
||||
<li class="item flexrow list-item" data-item-id="{{jeu._id}}"><span class="competence-title jeu-label"><a>{{jeu.name}} (base {{jeu.data.base}})</a></span>
|
||||
<div class="item-controls">
|
||||
<div class="item-controls flex-shrink">
|
||||
<a class="item-control item-edit" title="Edit Item"><i class="fas fa-edit"></i></a>
|
||||
<a class="item-control item-delete" title="Delete Item"><i class="fas fa-trash"></i></a>
|
||||
</div>
|
||||
@ -351,7 +351,7 @@
|
||||
<ul class="item-list alterne-list">
|
||||
{{#each recettesAlchimiques as |recette id|}}
|
||||
<li class="item flexrow list-item" data-item-id="{{recette._id}}"><span class="competence-title recette-label item-edit"><a>{{recette.name}}</a></span>
|
||||
<div class="item-controls">
|
||||
<div class="item-controls flex-shrink">
|
||||
<a class="item-control item-edit" title="Edit Item"><i class="fas fa-edit"></i></a>
|
||||
<a class="item-control item-delete" title="Delete Item"><i class="fas fa-trash"></i></a>
|
||||
</div>
|
||||
@ -384,20 +384,28 @@
|
||||
</li>
|
||||
{{/if}}
|
||||
<li class="item flexrow">
|
||||
<span class="competence-label">Demi rêve :</span>
|
||||
<span>
|
||||
{{#if options.isGM}}
|
||||
{{caseTmr-label data.reve.tmrpos.coord}}
|
||||
<span class="competence-label flex-shrink">Demi rêve :
|
||||
<span>{{caseTmr-label data.reve.tmrpos.coord}}</span>
|
||||
</span>
|
||||
<span>
|
||||
<input class="competence-value" type="text" name="data.reve.tmrpos.coord" value="{{data.reve.tmrpos.coord}}" data-dtype="String"/>
|
||||
</span>
|
||||
|
||||
{{else}}
|
||||
<span class="competence-label flex-shrink">Demi rêve :
|
||||
{{#unless hautreve.cacheTMR}}
|
||||
<span>{{caseTmr-label data.reve.tmrpos.coord}}</span>
|
||||
{{/unless}}
|
||||
</span>
|
||||
<span>
|
||||
{{#if hautreve.cacheTMR}}
|
||||
??
|
||||
{{else}}
|
||||
{{caseTmr-label data.reve.tmrpos.coord}}
|
||||
{{data.reve.tmrpos.coord}}
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
</span>
|
||||
{{/if}}
|
||||
</li>
|
||||
{{/if}}
|
||||
<li class="item flexrow">
|
||||
@ -424,13 +432,27 @@
|
||||
</div>
|
||||
<hr>
|
||||
{{#if data.attributs.hautrevant.value}}
|
||||
{{#if options.isGM}}
|
||||
<h3>Signes draconiques</h3>
|
||||
<ul class="item-list alterne-list">
|
||||
{{#each signesdraconiques as |signe key|}}
|
||||
<li class="item list-item flexrow" data-item-id="{{signe._id}}" data-attribute="{{key}}">
|
||||
<span class="display-label flex-grow"> <a data-item-id="{{signe._id}}">{{signe.name}}</a></span>
|
||||
<span class="flex-shrink">{{signe.data.difficulte}}</span>
|
||||
<div class="item-controls flex-shrink">
|
||||
<a class="item-control item-delete" title="Supprimer"><i class="fas fa-trash"></i></a>
|
||||
</div>
|
||||
</li>
|
||||
{{/each}}
|
||||
</ul>
|
||||
{{/if}}
|
||||
<h3>Sorts:</h3>
|
||||
<ul class="item-list alterne-list">
|
||||
{{#each sorts as |mysort key|}}
|
||||
<li class="item list-item flexrow" data-item-id="{{mysort._id}}" data-attribute="{{key}}">
|
||||
<span class="sort-label"> <a data-id="{{mysort._id}}">{{mysort.name}}</a></span>
|
||||
<span>{{mysort.data.draconic}} / {{mysort.data.difficulte}}</span>
|
||||
<div class="item-controls">
|
||||
{{#each sorts as |sort key|}}
|
||||
<li class="item list-item flexrow" data-item-id="{{sort._id}}" data-attribute="{{key}}">
|
||||
<span class="display-label flex-grow"> <a data-item-id="{{sort._id}}">{{sort.name}}</a></span>
|
||||
<span>{{sort.data.draconic}} / {{sort.data.difficulte}}</span>
|
||||
<div class="item-controls flex-shrink">
|
||||
<a class="item-control item-delete" title="Supprimer"><i class="fas fa-trash"></i></a>
|
||||
</div>
|
||||
</li>
|
||||
@ -440,9 +462,15 @@
|
||||
<h3>Sorts en Réserve:</h3>
|
||||
<ul class="item-list alterne-list">
|
||||
{{#each hautreve.sortsReserve as |reserve key|}}
|
||||
<li class="item list-item flexrow" data-item-id="{{mysort._id}}" data-attribute="{{key}}">
|
||||
<li class="item list-item flexrow" data-item-id="{{reserve._id}}" data-attribute="{{key}}">
|
||||
<img class="sheet-competence-img" src="{{reserve.sort.img}}" />
|
||||
<span class="sort-label"> {{reserve.sort.name}} - {{reserve.coord}} - {{caseTmr-label reserve.coord}} - r{{reserve.sort.data.ptreve_reel}}</span>
|
||||
<span class="display-label flex-grow">{{reserve.sort.name}}</span>
|
||||
<span class="flex-shrink">r{{reserve.sort.data.ptreve_reel}}</span>
|
||||
<span class="flex-shrink">{{reserve.coord}}</span>
|
||||
<span>{{caseTmr-label reserve.coord}}</span>
|
||||
<div class="item-controls flex-shrink">
|
||||
<a class="item-control item-delete flex-shrink" title="Supprimer"><i class="fas fa-trash"></i></a>
|
||||
</div>
|
||||
</li>
|
||||
{{/each}}
|
||||
</ul>
|
||||
@ -451,8 +479,8 @@
|
||||
<ul class="item-list">
|
||||
{{#each meditations as |meditation key|}}
|
||||
<li class="item flexrow" data-item-id="{{meditation._id}}" data-attribute="{{key}}">
|
||||
<span class="meditation-label"><a data-id="{{meditation._id}}">{{meditation.name}} - {{meditation.data.competence}}</a></span>
|
||||
<div class="item-controls">
|
||||
<span class="meditation-label flex-grow"><a data-item-id="{{meditation._id}}">{{meditation.name}} - {{meditation.data.competence}}</a></span>
|
||||
<div class="item-controls flex-shrink">
|
||||
<a class="item-control item-edit" title="Editer"><i class="fas fa-edit"></i></a>
|
||||
<a class="item-control item-delete" title="Supprimer"><i class="fas fa-trash"></i></a>
|
||||
</div>
|
||||
@ -466,8 +494,8 @@
|
||||
<ul class="flex-group-left">
|
||||
{{#each queues as |queue key|}}
|
||||
<li class="item flexrow" data-attribute={{key}} data-item-id="{{queue._id}}">
|
||||
<span class="queuesouffle-label"> <a data-item-id="{{queue._id}}">{{queue.name}}</a></span>
|
||||
<div class="item-controls">
|
||||
<span class="display-label flex-grow"><a data-item-id="{{queue._id}}">{{queue.name}}</a></span>
|
||||
<div class="item-controls flex-shrink">
|
||||
<a class="item-control item-delete" title="Delete Item"><i class="fas fa-trash"></i></a>
|
||||
</div>
|
||||
</li>
|
||||
@ -477,8 +505,8 @@
|
||||
<ul class="item-list">
|
||||
{{#each souffles as |souffle key|}}
|
||||
<li class="item flexrow" data-attribute={{key}} data-item-id="{{souffle._id}}">
|
||||
<span class="queuesouffle-label"> <a data-item-id="{{souffle._id}}">{{souffle.name}}</a></span>
|
||||
<div class="item-controls">
|
||||
<span class="display-label flex-grow"><a data-item-id="{{souffle._id}}">{{souffle.name}}</a></span>
|
||||
<div class="item-controls flex-shrink">
|
||||
<a class="item-control item-delete" title="Delete Item"><i class="fas fa-trash"></i></a>
|
||||
</div>
|
||||
</li>
|
||||
@ -488,8 +516,8 @@
|
||||
<ul class="item-list">
|
||||
{{#each tetes as |tete key|}}
|
||||
<li class="item flexrow" data-attribute={{key}} data-item-id="{{tete._id}}">
|
||||
<span class="queuesouffle-label"> <a data-item-id="{{tete._id}}">{{tete.name}}</a></span>
|
||||
<div class="item-controls">
|
||||
<span class="display-label flex-grow"><a data-item-id="{{tete._id}}">{{tete.name}}</a></span>
|
||||
<div class="item-controls flex-shrink">
|
||||
<a class="item-control item-delete" title="Delete Item"><i class="fas fa-trash"></i></a>
|
||||
</div>
|
||||
</li>
|
||||
@ -499,8 +527,8 @@
|
||||
<ul class="item-list">
|
||||
{{#each ombres as |ombre key|}}
|
||||
<li class="item flexrow" data-attribute={{key}} data-item-id="{{ombre._id}}">
|
||||
<span class="queuesouffle-label"> <a data-item-id="{{ombre._id}}">{{ombre.name}}</a></span>
|
||||
<div class="item-controls">
|
||||
<span class="display-label flex-grow"><a data-item-id="{{ombre._id}}">{{ombre.name}}</a></span>
|
||||
<div class="item-controls flex-shrink">
|
||||
<a class="item-control item-delete" title="Delete Item"><i class="fas fa-trash"></i></a>
|
||||
</div>
|
||||
</li>
|
||||
@ -512,8 +540,12 @@
|
||||
<ul class="item-list">
|
||||
{{#each hautreve.rencontres as |rencontre key|}}
|
||||
<li class="item flexrow" data-item-id="{{key}}" data-attribute="{{key}}">
|
||||
<span class="case-label"><a data-id="{{key}}">{{rencontre.rencontre.name}} - {{rencontre.coord}} {{#if rencontre.rencontre.date}}({{rencontre.rencontre.date}} - {{rencontre.rencontre.heure}}){{/if}}</a></span>
|
||||
<div class="item-controls">
|
||||
<span class="display-label flex-grow"><a data-item-id="{{key}}">{{rencontre.rencontre.name}} - {{rencontre.coord}}</a></span>
|
||||
<span class="flex-shrink">{{caseTmr-label reserve.coord}}</span>
|
||||
{{#if rencontre.rencontre.date}}
|
||||
<span>({{rencontre.rencontre.date}} - {{rencontre.rencontre.heure}})</span>
|
||||
{{/if}}
|
||||
<div class="item-controls flex-shrink">
|
||||
<a class="item-control rencontre-delete" title="Supprimer"><i class="fas fa-trash"></i></a>
|
||||
</div>
|
||||
</li>
|
||||
@ -523,11 +555,11 @@
|
||||
<h3>Cases Spéciales:</h3>
|
||||
<ul class="item-list">
|
||||
{{#each hautreve.casesTmr as |casetmr key|}}
|
||||
<li class="item" data-item-id="{{casetmr._id}}" data-attribute="{{key}}">
|
||||
<span class="item-controls">
|
||||
<li class="item flexrow" data-item-id="{{casetmr._id}}" data-attribute="{{key}}">
|
||||
<span class="display-label"><a data-item-id="{{casetmr._id}}">{{casetmr.name}}</a></span>
|
||||
<span class="item-controls flex-shrink">
|
||||
<a class="item-control item-delete" title="Supprimer"><i class="fas fa-trash"></i></a>
|
||||
</span>
|
||||
<span class="case-label"><a data-id="{{casetmr._id}}">{{casetmr.name}}</a></span>
|
||||
</li>
|
||||
{{/each}}
|
||||
</ul>
|
||||
@ -544,7 +576,7 @@
|
||||
<span class="competence-title competence-label">{{piece.name}}</span>
|
||||
<span class="competence-title competence-label">{{piece.data.quantite}}</span>
|
||||
<span class="competence-title"><a class="monnaie-plus">+</a><a class="monnaie-moins">-</a></span>
|
||||
<div class="item-controls">
|
||||
<div class="item-controls flex-shrink">
|
||||
<a class="item-control item-edit" title="Editer"><i class="fas fa-edit"></i></a>
|
||||
<a class="item-control item-delete" title="Supprimer"><i class="fas fa-trash"></i></a>
|
||||
</div>
|
||||
@ -589,7 +621,7 @@
|
||||
<li class="item flexrow list-item" data-actor-id="{{monture.id}}">
|
||||
<img class="sheet-competence-img" src="{{monture.img}}" title="{{monture.name}}"/>
|
||||
<span class="competence-title subacteur-label"><a>{{monture.name}}</a></span>
|
||||
<div class="item-controls">
|
||||
<div class="item-controls flex-shrink">
|
||||
<a class="item-control subacteur-delete" title="Supprimer"><i class="fas fa-trash"></i></a>
|
||||
</div>
|
||||
</li>
|
||||
@ -604,7 +636,7 @@
|
||||
<span class="competence-title subacteur-label"><a>{{vehicule.name}}</a></span>
|
||||
<span class="competence-title">{{vehicule.categorie}}</span>
|
||||
<span class="competence-title">{{vehicule.structure}}</span>
|
||||
<div class="item-controls">
|
||||
<div class="item-controls flex-shrink">
|
||||
<a class="item-control subacteur-delete" title="Supprimer"><i class="fas fa-trash"></i></a>
|
||||
</div>
|
||||
</li>
|
||||
@ -617,7 +649,7 @@
|
||||
<li class="item flexrow list-item" data-actor-id="{{suivant.id}}">
|
||||
<img class="sheet-competence-img" src="{{suivant.img}}" title="{{suivant.name}}"/>
|
||||
<span class="competence-title subacteur-label"><a>{{suivant.name}}</a></span>
|
||||
<div class="item-controls">
|
||||
<div class="item-controls flex-shrink">
|
||||
<a class="item-control subacteur-delete" title="Supprimer"><i class="fas fa-trash"></i></a>
|
||||
</div>
|
||||
</li>
|
||||
|
11
templates/chat-resultat-lecture-signedraconique.html
Normal file
11
templates/chat-resultat-lecture-signedraconique.html
Normal file
@ -0,0 +1,11 @@
|
||||
<img class="chat-icon" src="{{competence.img}}" alt="{{competence.name}}" />
|
||||
<h4>{{alias}} lit le signe {{signe.name}}</h4>
|
||||
{{> "systems/foundryvtt-reve-de-dragon/templates/chat-infojet.html"}}
|
||||
<hr>
|
||||
<div>
|
||||
{{#if rolled.isSuccess}}
|
||||
Vous avez gagné {{xpSort}} points d'expérience en sorts dans la {{competence.name}}.
|
||||
{{else}}
|
||||
Vous n'avez pas pu interpréter le signe draconique.
|
||||
{{/if}}
|
||||
</div>
|
@ -6,11 +6,10 @@
|
||||
<hr>
|
||||
<div>
|
||||
{{#if rolled.isSuccess}}
|
||||
{{alias}} aperçoit un signe Draconique fugitif, qu'il faut aller lire en <strong>{{meditation.data.tmr}}</strong> en réussissant un test <strong>d'INTELLECT/Draconic à {{diffLecture}}</strong>.
|
||||
Selon le résultat de votre lecture, vous gagnerez les points suivants en Sort: 3 pour une Normale, 5 pour une Significative, 10 pour une Particulière.
|
||||
Vous apercevez un signe draconique éphémère, qu'il faut aller lire en <strong>{{meditation.data.tmr}}</strong>.
|
||||
{{else}}
|
||||
{{alias}} a échoué dans sa méditation et ne voit aucun signe Draconique.
|
||||
Votre méditation ne porte pas ses fruits, vous ne voyez aucun signe Draconique.
|
||||
{{/if}}
|
||||
<br><span>Vous vous êtes fatigué de 2 cases.</span>
|
||||
{{#if rolled.isETotal}}<br><span>Votre échec total augmente de 1 la difficulté de la méditation!</span>{{/if~}}
|
||||
{{#if rolled.isEPart}}<br><span>Votre échec {{#if rolled.isETotal}}total{{else}}particulier{{/if}} augmente de 1 la difficulté de la méditation!</span>{{/if~}}
|
||||
</div>
|
||||
|
7
templates/chat-signe-draconique-actor.html
Normal file
7
templates/chat-signe-draconique-actor.html
Normal file
@ -0,0 +1,7 @@
|
||||
<h4><img class="chat-icon" src="{{signe.img}}" alt="{{signe.name}}" />
|
||||
{{alias}} perçoit {{signe.name}}
|
||||
</h4>
|
||||
<p>Pour le lire ce signe draconique, rendez-vous dans les
|
||||
Terres Médianes du Rêve et trouvez une case de résonnance.
|
||||
{{#if signe.data.ephemere}}C'est un signe éphémère, qui ne restera présent que pour {{signe.data.duree}}{{/if}}
|
||||
</p>
|
4
templates/chat-signe-draconique-resonance.html
Normal file
4
templates/chat-signe-draconique-resonance.html
Normal file
@ -0,0 +1,4 @@
|
||||
<h4><img class="chat-icon" src="systems/foundryvtt-reve-de-dragon/icons/tmr/signe_draconique.webp" alt="Signe draconique" />
|
||||
{{alias}} peut lire un signe draconique
|
||||
</h4>
|
||||
<p>Vous venez de trouver une terre de résonance en {{typeTMR}}, vous pouvez le lire un signe draconique.</p>
|
52
templates/dialog-create-signedraconique.html
Normal file
52
templates/dialog-create-signedraconique.html
Normal file
@ -0,0 +1,52 @@
|
||||
<form class="skill-roll-dialog">
|
||||
<div>
|
||||
<h4>Paramétrer le signe draconique
|
||||
<span class="chat-card-button-area">
|
||||
<a class="signe-aleatoire chat-card-button">Signe aléatoire</a>
|
||||
</span>
|
||||
<br><input type="text" name="signe.name" value="{{signe.name}}" data-dtype="String" />
|
||||
</h4>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="signe.data.difficulte">Difficulte</label>
|
||||
<input type="number" name="signe.data.difficulte" value="{{signe.data.difficulte}}" data-dtype="Number" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="signe.data.valeur.norm">Expérience en sorts</label>
|
||||
<div class="flexrow">
|
||||
<input class="signe-xp-sort" type="number" name="signe.data.valeur.norm" data-typereussite="norm"
|
||||
value="{{signe.data.valeur.norm}}" min="1" max="100" data-dtype="Number" />
|
||||
<span>Sign.</span>
|
||||
<input class="signe-xp-sort" type="number" name="signe.data.valeur.sign" data-typereussite="sign"
|
||||
value="{{signe.data.valeur.sign}}" min="1" max="100" data-dtype="Number" />
|
||||
<span>Part.</span>
|
||||
<input class="signe-xp-sort" type="number" name="signe.data.valeur.part" data-typereussite="part"
|
||||
value="{{signe.data.valeur.part}}" min="1" max="100" data-dtype="Number" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group flexrow">
|
||||
<label for="signe.data.ephemere">Ephémère</label>
|
||||
<input class="flex-shrink" type="checkbox" name="signe.data.ephemere" {{#if signe.data.ephemere}}checked{{/if}} />
|
||||
<span>
|
||||
<input type="text" name="signe.data.duree" value="{{signe.data.duree}}" data-dtype="String" />
|
||||
</span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="tmrs">Terres médianes</label>
|
||||
<select class="select-tmr" name="tmrs" id="tmrs" size="{{tmrs.length}}" multiple>
|
||||
{{#each tmrs as |tmr key|}}
|
||||
<option value="{{tmr.name}}" {{#if tmr.selected}}selected{{/if}}>{{tmr.name}}</option>
|
||||
{{/each}}
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="actors">Haut-rêvants concernés</label>
|
||||
<select class="select-actor" id="actors" size="7" multiple>
|
||||
{{#each actors as |actor key|}}
|
||||
<option value="{{actor.name}}" data-actor-id="{{actor._id}}" {{#if actor.selected}}selected{{/if}}>{{actor.name}}</option>
|
||||
{{/each}}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
|
||||
</form>
|
48
templates/dialog-roll-signedraconique.html
Normal file
48
templates/dialog-roll-signedraconique.html
Normal file
@ -0,0 +1,48 @@
|
||||
{{log 'lecture signe draconique' this}}
|
||||
<form class="dialog-roll-sort">
|
||||
<h2>Lire le signe draconique
|
||||
<select name="signe-draconique" class="roll-signedraconique flex-grow" data-dtype="String">
|
||||
{{#select signe}}
|
||||
{{#each signes as |signe key|}}
|
||||
<option value={{key}}>{{this.name}}</option>
|
||||
{{/each}}
|
||||
{{/select}}
|
||||
</select>
|
||||
</h2>
|
||||
<img class="chat-icon" src="{{competence.img}}" alt="{{competence.name}}" />
|
||||
<div class="grid grid-2col">
|
||||
<div class="flex-group-left">
|
||||
<div class="flexrow">
|
||||
<label for="tmr">TMR - {{tmr.coord}}:</label><label name="tmr">{{tmr.label}}</label>
|
||||
</div>
|
||||
<div class="flexrow">
|
||||
<label for="carac">{{selectedCarac.label}}:</label><label name="carac">{{selectedCarac.value}}</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex-group-left">
|
||||
<div class="flexrow">
|
||||
<label for="competence">Draconic:</label>
|
||||
<select name="competence" class="roll-draconic" data-dtype="String">
|
||||
{{#select draconic}}
|
||||
{{#each draconicList as |draconic key|}}
|
||||
<option value={{key}}>{{draconic.name}} : {{numberFormat draconic.data.niveau decimals=0 sign=true}}
|
||||
</option>
|
||||
{{/each}}
|
||||
{{/select}}
|
||||
</select>
|
||||
</div>
|
||||
<div class="flexrow">
|
||||
<label>Difficulté</label>
|
||||
<label class="signe-difficulte">{{diffLibre}}</label>
|
||||
</div>
|
||||
{{>"systems/foundryvtt-reve-de-dragon/templates/partial-roll-diffCondition.html"}}
|
||||
<div id="tableAjustements" class="flexrow"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="tableResolution"></div>
|
||||
<div id="tableProbaReussite"></div>
|
||||
</form>
|
||||
|
||||
<script>
|
||||
</script>
|
@ -1,4 +1,3 @@
|
||||
{{log 'lancer de sort' this}}
|
||||
<form class="dialog-roll-sort">
|
||||
<h2>Lancer le <span class="sort-ou-rituel">{{#if sort.data.isrituel}}rituel{{else}}sort{{/if}}</span>:
|
||||
<select name="sort" class="roll-sort flex-grow" data-dtype="String">
|
||||
|
@ -14,8 +14,11 @@
|
||||
<img class="small-button-direction" id='dir-bottom' src='systems/foundryvtt-reve-de-dragon/styles/img/ui/dir-bottom.svg'>
|
||||
<img class="small-button-direction" id='dir-bottom-right' src='systems/foundryvtt-reve-de-dragon/styles/img/ui/dir-bottom-right.svg'>
|
||||
</div>
|
||||
<div class="flex-group-center">
|
||||
<a id="lancer-sort">Lancer un Sort</a>
|
||||
<div class="flex-group-center lire-signe-draconique">
|
||||
<a>Lire un signe draconique</a>
|
||||
</div>
|
||||
<div class="flex-group-center lancer-sort">
|
||||
<a>Lancer un Sort</a>
|
||||
</div>
|
||||
<hr>
|
||||
<div class="flex-group-center">
|
||||
|
@ -29,15 +29,15 @@
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="xp">Difficulté</label>
|
||||
<input class="attribute-value" type="text" name="data.difficulte" value="{{data.difficulte}}" data-dtype="Number"/>
|
||||
<input class="attribute-value" type="number" name="data.difficulte" value="{{data.difficulte}}" data-dtype="Number"/>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="xp">Points de tâches</label>
|
||||
<input class="attribute-value" type="text" name="data.points_de_tache" value="{{data.points_de_tache}}" data-dtype="Number"/>
|
||||
<input class="attribute-value" type="number" name="data.points_de_tache" value="{{data.points_de_tache}}" data-dtype="Number"/>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="xp">Expérience</label>
|
||||
<input class="attribute-value" type="text" name="data.xp" value="{{data.xp}}" data-dtype="String"/>
|
||||
<input class="attribute-value" type="number" name="data.xp" value="{{data.xp}}" data-dtype="Number"/>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="xp">Niveau minimum</label>
|
||||
@ -49,15 +49,15 @@
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="xp">Encombrement </label>
|
||||
<input class="attribute-value" type="text" name="data.encombrement" value="{{data.encombrement}}" data-dtype="Number"/>
|
||||
<input class="attribute-value" type="number" name="data.encombrement" value="{{data.encombrement}}" data-dtype="Number"/>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Quantité </label>
|
||||
<input class="attribute-value" type="text" name="data.quantite" value="{{data.quantite}}" data-dtype="Number" />
|
||||
<input class="attribute-value" type="number" name="data.quantite" value="{{data.quantite}}" data-dtype="Number" />
|
||||
</div>
|
||||
<div class="form-group item-cout">
|
||||
<label for="xp">Prix (sols) </label>
|
||||
<input class="attribute-value" type="text" name="data.cout" value="{{data.cout}}" data-dtype="Number"/>
|
||||
<input class="attribute-value" type="number" name="data.cout" value="{{data.cout}}" data-dtype="Number"/>
|
||||
</div>
|
||||
<div class="flexcol">
|
||||
<span><label>Description : </label></span>
|
||||
|
56
templates/item-signedraconique-sheet.html
Normal file
56
templates/item-signedraconique-sheet.html
Normal file
@ -0,0 +1,56 @@
|
||||
<form class="{{cssClass}}" autocomplete="off">
|
||||
<header class="sheet-header">
|
||||
<img class="profile-img" src="{{img}}" data-edit="img" title="{{name}}" />
|
||||
<div class="header-fields">
|
||||
<h1 class="charname"><input name="name" type="text" value="{{name}}" placeholder="Name" /></h1>
|
||||
<a class="signe-aleatoire chat-card-button">Signe aléatoire</a>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
{{!-- Sheet Body --}}
|
||||
<section class="sheet-body">
|
||||
<div class="form-group">
|
||||
<label for="data.difficulte">Difficulte</label>
|
||||
<input class="attribute-value" type="number" name="data.difficulte" value="{{data.difficulte}}"
|
||||
data-dtype="Number" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="data.valeur.norm">Expérience en sorts</label>
|
||||
<div class="flexrow">
|
||||
<input class="signe-xp-sort" type="number" name="data.valeur.norm" data-typereussite="norm"
|
||||
value="{{data.valeur.norm}}" min="1" max="100" data-dtype="Number" />
|
||||
<span>Sign.</span>
|
||||
<input class="signe-xp-sort" type="number" name="data.valeur.sign" data-typereussite="sign"
|
||||
value="{{data.valeur.sign}}" min="1" max="100" data-dtype="Number" />
|
||||
<span>Part.</span>
|
||||
<input class="signe-xp-sort" type="number" name="data.valeur.part" data-typereussite="part"
|
||||
value="{{data.valeur.part}}" min="1" max="100" data-dtype="Number" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="data.ephemere">Ephémère</label>
|
||||
<input class="attribute-value" type="checkbox" name="data.ephemere" {{#if data.ephemere}}checked{{/if}} />
|
||||
</div>
|
||||
{{#if data.ephemere}}
|
||||
<div class="form-group">
|
||||
<label for="data.duree">Durée</label>
|
||||
<input class="attribute-value" type="text" name="data.duree" value="{{data.duree}}" data-dtype="String" />
|
||||
</div>
|
||||
{{/if}}
|
||||
<div class="form-group">
|
||||
<label for="tmrs">Terres médianes</label>
|
||||
<select class="select-tmr attribute-value" name="tmrs" id="tmrs" size={{tmrs.length}} multiple />
|
||||
{{#each tmrs as |tmr key|}}
|
||||
<option class="option-tmr" value="{{tmr.name}}" {{#if tmr.selected}}selected{{/if}}>{{tmr.name}}</option>
|
||||
{{/each}}
|
||||
</select>
|
||||
</div>
|
||||
<div class="flexcol">
|
||||
<span><label>Description : </label></span>
|
||||
<div class="form-group editor">
|
||||
{{editor content=data.description target="data.description" button=true owner=owner editable=editable}}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
</form>
|
Loading…
Reference in New Issue
Block a user