Merge branch 'master-fixes' into 'master'

Afficher le jet d'endurance pour les personnages

See merge request LeRatierBretonnien/foundryvtt-reve-de-dragon!168
This commit is contained in:
Leratier Bretonnien 2021-03-15 07:42:18 +00:00
commit c58c9636d2
22 changed files with 163 additions and 137 deletions

View File

@ -33,7 +33,7 @@ export class RdDActorSheet extends ActorSheet {
/* -------------------------------------------- */
getData() {
let data = super.getData();
if ( data.actor.type == 'creature' || data.actor.type == 'humanoide') return data; // Shortcut
if (data.actor.type == 'creature' || data.actor.type == 'humanoide') return data; // Shortcut
data.data.editCaracComp = this.options.editCaracComp;
data.data.showCompNiveauBase = this.options.showCompNiveauBase;
@ -50,13 +50,13 @@ export class RdDActorSheet extends ActorSheet {
item => {
let archetypeKey = (item.data.niveau_archetype < 0) ? 0 : item.data.niveau_archetype;
if (data.data.comptageArchetype[archetypeKey] == undefined) {
data.data.comptageArchetype[archetypeKey] = { "niveau": archetypeKey, "nombreMax": 0, "nombre": 0};
data.data.comptageArchetype[archetypeKey] = { "niveau": archetypeKey, "nombreMax": 0, "nombre": 0 };
}
data.data.comptageArchetype[archetypeKey].nombre = (data.data.comptageArchetype[archetypeKey]?.nombre??0) + 1; //Comptage archetype
data.data.comptageArchetype[archetypeKey].nombre = (data.data.comptageArchetype[archetypeKey]?.nombre ?? 0) + 1; //Comptage archetype
item.data.xpNext = RdDItemCompetence.getCompetenceNextXp(item.data.niveau);
item.data.isLevelUp = item.data.xp >= item.data.xpNext; // Flag de niveau à MAJ
//this.actor.checkCompetenceXP(item.name); // Petite vérification experience
item.data.showCompetence = !data.data.showCompNiveauBase || (Number(item.data.niveau) != Number(RdDUtility.getLevelCategory(item.data.categorie)));
item.data.showCompetence = !data.data.showCompNiveauBase || (Number(item.data.niveau) != Number(RdDItemCompetence.getLevelCategory(item.data.categorie)));
// Ignorer les compétences 'troncs' à ce stade
data.data.competenceXPTotal += RdDItemCompetence.computeCompetenceXPCost(item);
return item;
@ -68,7 +68,7 @@ export class RdDActorSheet extends ActorSheet {
for (let caracName in data.data.carac) {
let currentCarac = data.data.carac[caracName];
if (!currentCarac.derivee) {
sum += parseInt(currentCarac.value);
sum += parseInt(currentCarac.value);
}
currentCarac.xpNext = RdDUtility.getCaracNextXp(currentCarac.value);
currentCarac.isLevelUp = (currentCarac.xp >= currentCarac.xpNext);
@ -98,7 +98,7 @@ export class RdDActorSheet extends ActorSheet {
data.data.combat = duplicate(RdDUtility.checkNull(data.itemsByType['arme']));
data.data.combat = RdDCombatManager.finalizeArmeList(data.data.combat, data.itemsByType.competence, data.data.carac);
data.esquive = { name: "Esquive", niveau: data.competenceByCategory?.melee.find(it => it.name == 'Esquive')?.data.niveau ?? -6};
data.esquive = { name: "Esquive", niveau: data.competenceByCategory?.melee.find(it => it.name == 'Esquive')?.data.niveau ?? -6 };
let corpsACorps = data.competenceByCategory?.melee.find(it => it.name == 'Corps à corps');
if (corpsACorps) {
let cc_init = RdDCombatManager.calculInitiative(corpsACorps.data.niveau, data.data.carac['melee'].value);
@ -113,7 +113,7 @@ export class RdDActorSheet extends ActorSheet {
// Mise à jour de l'encombrement total et du prix de l'équipement
this.actor.computeEncombrementTotalEtMalusArmure();
this.actor.computePrixTotalEquipement();
// Common data
data.data.competenceByCategory = data.competenceByCategory;
data.data.encTotal = this.actor.encTotal;
@ -131,20 +131,20 @@ export class RdDActorSheet extends ActorSheet {
RdDUtility.filterItemsPerTypeForSheet(data);
data.data.sortReserve = data.data.reve.reserve.list;
data.data.rencontres = duplicate(data.data.reve.rencontre.list);
data.data.rencontres = duplicate(data.data.reve.rencontre.list);
data.data.caseSpeciales = data.itemsByType['casetmr'];
RdDUtility.buildArbreDeConteneur(this, data);
data.data.surEncombrementMessage = (data.data.compteurs.surenc.value < 0) ? "Sur-Encombrement!" : "";
data.data.vehiculesList = this.actor.buildVehiculesList();
data.data.monturesList = this.actor.buildMonturesList();
data.data.suivantsList = this.actor.buildSuivantsList();
data.data.monturesList = this.actor.buildMonturesList();
data.data.suivantsList = this.actor.buildSuivantsList();
return data;
}
/* -------------------------------------------- */
async _onDrop(event) {
let toSuper = await RdDUtility.processItemDropEvent(this, event);
if ( toSuper) {
if (toSuper) {
super._onDrop(event);
}
}
@ -213,12 +213,12 @@ export class RdDActorSheet extends ActorSheet {
html.find('.item-delete').click(ev => {
const li = $(ev.currentTarget).parents(".item");
RdDUtility.confirmerSuppression(this, li);
});
});
html.find('.subacteur-delete').click(ev => {
const li = $(ev.currentTarget).parents(".item");
RdDUtility.confirmerSuppressionSubacteur(this, li);
});
html.find('#encaisser-direct').click(ev => {
this.actor.encaisser();
});
@ -335,12 +335,12 @@ export class RdDActorSheet extends ActorSheet {
html.find('.subacteur-label a').click((event) => {
const li = $(event.currentTarget).parents(".item");
let actorId = li.data('actor-id');
let actor = game.actors.get( actorId) ;
if ( actor ) {
let actor = game.actors.get(actorId);
if (actor) {
actor.sheet.render(true);
}
});
// Points de reve actuel
html.find('.ptreve-actuel a').click((event) => {
this.actor.rollCarac('reve-actuel');

View File

@ -113,12 +113,12 @@ export class RdDActor extends Actor {
}
/* -------------------------------------------- */
setRollWindowsOpened( flag ) {
setRollWindowsOpened(flag) {
this.rollWindowsOpened = flag;
}
/* -------------------------------------------- */
isRollWindowsOpened( ) {
isRollWindowsOpened() {
return this.rollWindowsOpened;
}
@ -315,11 +315,11 @@ export class RdDActor extends Actor {
let reserve = duplicate(this.data.data.reve.reserve);
let tmr = TMRUtility.getTMR(sortReserve.coord);
let index = reserve.list.findIndex(tmr.type == 'fleuve'
? sort => (TMRUtility.getTMR(sort.coord).type == 'fleuve' && sort.sort.name == sortReserve.sort.name)
: sort => (sort.coord == sortReserve.coord && sort.sort.name == sortReserve.sort.name)
? sort => (TMRUtility.getTMR(sort.coord).type == 'fleuve' && sort.sort.name == sortReserve.sort.name)
: sort => (sort.coord == sortReserve.coord && sort.sort.name == sortReserve.sort.name)
);
if (index >=0 ) {
reserve.list.splice(index,1);
if (index >= 0) {
reserve.list.splice(index, 1);
await this.update({ "data.reve.reserve": reserve });
}
}
@ -356,7 +356,7 @@ export class RdDActor extends Actor {
// On ne récupère un point de chance que si aucun appel à la chance dans la journée
let utilisationChance = duplicate(this.getFlag('foundryvtt-reve-de-dragon', 'utilisationChance') ?? false);
if ( !utilisationChance ) {
if (!utilisationChance) {
await this.chanceActuelleIncDec(1);
}
await this.unsetFlag('foundryvtt-reve-de-dragon', 'utilisationChance'); // Nouveau jour, suppression du flag
@ -489,7 +489,7 @@ export class RdDActor extends Actor {
async dormir(heures = 1) {
let message = {
whisper: ChatUtility.getWhisperRecipientsAndGMs(this.name),
content: `${this.name}: Vous dormez ${heures == 1 ? 'une': heures} heure${heures == 1 ? '': 's'}.`
content: `${this.name}: Vous dormez ${heures == 1 ? 'une' : heures} heure${heures == 1 ? '' : 's'}.`
};
await this.recupereEndurance(message);
for (let i = 0; i < heures; i++) {
@ -710,7 +710,7 @@ export class RdDActor extends Actor {
return;
}
let caracpath = "data.carac." + caracName + ".xp";
await this.update({ [caracpath]: caracXP });
await this.update({ [caracpath]: caracXP ?? 0 });
this.checkCaracXP(caracName);
}
@ -736,7 +736,7 @@ export class RdDActor extends Actor {
let comp = this.getCompetence(compName);
if (comp) {
let troncList = RdDItemCompetence.isTronc(compName);
let maxNiveau = compValue;
let nouveauNiveau = compValue ?? RdDItemCompetence.getLevelCategory(comp.data.categorie);
if (troncList) {
let message = "Vous avez modifié une compétence 'tronc'. Vérifiez que les compétences suivantes évoluent ensemble jusqu'au niveau 0 : ";
for (let troncName of troncList) {
@ -747,7 +747,7 @@ export class RdDActor extends Actor {
content: message
});
}
const update = { _id: comp._id, 'data.niveau': maxNiveau };
const update = { _id: comp._id, 'data.niveau': nouveauNiveau };
const updated = await this.updateEmbeddedEntity("OwnedItem", update); // Updates one EmbeddedEntity
} else {
console.log("Competence not found", compName);
@ -758,6 +758,7 @@ export class RdDActor extends Actor {
async updateCompetenceXP(compName, compValue) {
let comp = this.getCompetence(compName);
if (comp) {
compValue = compValue ?? 0;
this.checkCompetenceXP(compName, compValue);
const update = { _id: comp._id, 'data.xp': compValue };
const updated = await this.updateEmbeddedEntity("OwnedItem", update); // Updates one EmbeddedEntity
@ -771,6 +772,7 @@ export class RdDActor extends Actor {
async updateCompetenceXPSort(compName, compValue) {
let comp = this.getCompetence(compName);
if (comp) {
compValue = compValue ?? 0;
const update = { _id: comp._id, 'data.xp_sort': compValue };
const updated = await this.updateEmbeddedEntity("OwnedItem", update); // Updates one EmbeddedEntity
} else {
@ -782,6 +784,7 @@ export class RdDActor extends Actor {
async updateCompetenceArchetype(compName, compValue) {
let comp = this.getCompetence(compName);
if (comp) {
compValue = compValue ?? 0;
const update = { _id: comp._id, 'data.niveau_archetype': compValue };
const updated = await this.updateEmbeddedEntity("OwnedItem", update); // Updates one EmbeddedEntity
} else {
@ -1121,7 +1124,7 @@ export class RdDActor extends Actor {
queue = await RdDRollTables.getOmbre();
let myReve = duplicate(this.data.data.reve.reve);
myReve.thanatosused = false;
await this.update({ "data.reve.reve": myReve } );
await this.update({ "data.reve.reve": myReve });
}
else {
queue = await RdDRollTables.getQueue();
@ -1143,7 +1146,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 = TMRUtility.getTMRAleatoire(tmr => !innaccessible.includes(tmr.coord));
this.updateCoordTMR(tmr.coord);
return tmr;
}
@ -1218,8 +1221,8 @@ export class RdDActor extends Actor {
let list = duplicate(this.data.data.reve.rencontre.list);
let newList = [];
for (let i = 0; i < list.length; i++) {
if ( i != rencontreKey)
newList.push( list[i]);
if (i != rencontreKey)
newList.push(list[i]);
}
await this.update({ "data.reve.rencontre.list": newList });
}
@ -1270,13 +1273,13 @@ export class RdDActor extends Actor {
getSonneRound() {
return !this.isEntiteCauchemar() && (this.data.data.sante.sonne?.round ?? false);
}
/* -------------------------------------------- */
async verifierSonneRound( round ) {
if ( this.getSonne() ) {
if ( round >= this.getSonneRound() + 1) {
await this.setSonne( false, -1 ); // Nettoyer l'état sonné
ChatMessage.create( { content: `${this.name} n'est plus sonné ce round !`} );
async verifierSonneRound(round) {
if (this.getSonne()) {
if (round >= this.getSonneRound() + 1) {
await this.setSonne(false, -1); // Nettoyer l'état sonné
ChatMessage.create({ content: `${this.name} n'est plus sonné ce round !` });
}
}
}
@ -1322,10 +1325,10 @@ export class RdDActor extends Actor {
if (roll.total == 1) {
let xp = Misc.toInt(this.data.data.carac.constitution.xp) + 1;
this.update({ "data.carac.constitution.xp": xp }); // +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).`});
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;
}
@ -1700,15 +1703,15 @@ export class RdDActor extends Actor {
action: r => this._appliquerAjoutExperience(r, game.settings.get("core", "rollMode") != 'blindroll')
};
}
/* -------------------------------------------- */
createCallbackAppelAuMoral() { /* Si l'appel au moral est utilisé, on l'affiche dans le chat et on diminue éventuellement le moral */
return {
condition: r => r.use.appelAuMoral && game.settings.get("core", "rollMode") != 'selfroll',
action: r => { this.displayAppelAuMoral ; this._appliquerAppelMoral(r, game.settings.get("core", "rollMode") != 'blindroll') }
action: r => this._appliquerAppelMoral(r)
};
}
/* -------------------------------------------- */
async checkCaracXP(caracName) {
let carac = this.data.data.carac[caracName];
@ -1778,14 +1781,15 @@ export class RdDActor extends Actor {
if (xpResult && xpResult.xpCarac > 0 && rollData.selectedCarac) {
this.checkCaracXP(rollData.selectedCarac.name);
}
}
}
/* -------------------------------------------- */
async _appliquerAppelMoral(rollData, display = true) {
if (!this.isPersonnage()) return;
if (!rollData.rolled.isEchec) return;
this.moralIncDec(-1); /* L'appel au moral a échoué. Le personnage perd un point de moral */
rollData.jetEchouerMoralDiminuer = true;
if (rollData.rolled.isEchec || (rollData.rolled.roll * rollData.ajustements.diviseurSignificative > rollData.score)) {
this.moralIncDec(-1); /* L'appel au moral a échoué. Le personnage perd un point de moral */
rollData.perteMoralEchec = true;
}
}
/* -------------------------------------------- */
@ -1956,7 +1960,7 @@ export class RdDActor extends Actor {
if (rollData.isSortReserve) {
rollData.depenseReve++;
}
if ( rollData.competence.name.includes('Thanatos')) { // Si Thanatos
if (rollData.competence.name.includes('Thanatos')) { // Si Thanatos
myReve.thanatosused = true;
}
if (myReve.value > rollData.depenseReve) {
@ -2010,6 +2014,7 @@ export class RdDActor extends Actor {
label: 'Jet ' + Grammar.apostrophe('de', rollData.selectedCarac.label),
callbacks: [
this.createCallbackExperience(),
this.createCallbackAppelAuMoral(),
{ action: r => this._onRollCaracResult(r) }
]
}
@ -2046,7 +2051,7 @@ export class RdDActor extends Actor {
label: 'Jet ' + Grammar.apostrophe('de', name),
callbacks: [
this.createCallbackExperience(),
this.createCallbackAppelAuMoral(),
this.createCallbackAppelAuMoral(),
{ action: r => this._competenceResult(r) }
]
});
@ -2093,6 +2098,7 @@ export class RdDActor extends Actor {
label: 'Jet de Tâche ' + tache.name,
callbacks: [
this.createCallbackExperience(),
this.createCallbackAppelAuMoral(),
{ condition: r => r.rolled.isETotal, action: r => this._tacheETotal(r) },
{ action: r => this._tacheResult(r) }
]
@ -2128,7 +2134,7 @@ export class RdDActor extends Actor {
selectedCarac: duplicate(this.data.data.carac[selected])
});
artData.competence.data.defaut_carac = selected;
if ( !artData.forceCarac ) {
if (!artData.forceCarac) {
artData.forceCarac = {};
artData.forceCarac[selected] = duplicate(this.data.data.carac[selected]);
}
@ -2141,6 +2147,7 @@ export class RdDActor extends Actor {
height: 600,
callbacks: [
this.createCallbackExperience(),
this.createCallbackAppelAuMoral(),
{ action: r => callBackResult(r) }
]
});
@ -2168,17 +2175,17 @@ export class RdDActor extends Actor {
const artData = { art: 'danse', verbe: 'Danser', forceCarac: {} };
const oeuvre = duplicate(this.getOeuvre(id, artData.art));
const selectedCarac = this._getCaracDanse(oeuvre);
if ( oeuvre.data.agilite) {
artData.forceCarac['agilite'] = duplicate(this.data.data.carac.agilite );
if (oeuvre.data.agilite) {
artData.forceCarac['agilite'] = duplicate(this.data.data.carac.agilite);
}
if ( oeuvre.data.apparence) {
artData.forceCarac['apparence'] = duplicate(this.data.data.carac.apparence );
if (oeuvre.data.apparence) {
artData.forceCarac['apparence'] = duplicate(this.data.data.carac.apparence);
}
await this._rollArt(artData, selectedCarac, oeuvre);
}
/* -------------------------------------------- */
_getCaracDanse(oeuvre) {
_getCaracDanse(oeuvre) {
if (oeuvre.data.agilite) { return "agilite"; }
else if (oeuvre.data.apparence) { return "apparence"; }
const competence = this.getCompetence(oeuvre.data.competence);
@ -2289,7 +2296,7 @@ export class RdDActor extends Actor {
async rollAppelChance(onSuccess = () => { }, onEchec = () => { }) {
// Stocke si utilisation de la chance
await this.unsetFlag('foundryvtt-reve-de-dragon', 'utilisationChance');
await this.setFlag('foundryvtt-reve-de-dragon', 'utilisationChance', true );
await this.setFlag('foundryvtt-reve-de-dragon', 'utilisationChance', true);
let rollData = { selectedCarac: this.getCaracByName('chance-actuelle'), surprise: '' };
const dialog = await RdDRoll.create(this, rollData,
@ -2556,10 +2563,12 @@ export class RdDActor extends Actor {
}
/* -------------------------------------------- */
verifierForceMin( item ) {
if ( item.type == 'arme' && item.data.force > this.data.data.carac.force.value ) {
ChatMessage.create( { content: `<strong>${this.name} s'est équipé(e) de l'arme ${item.name}, mais n'a pas une force suffisante pour l'utiliser normalement </strong>
(${item.data.force} nécessaire pour une Force de ${this.data.data.carac.force.value})` } );
verifierForceMin(item) {
if (item.type == 'arme' && item.data.force > this.data.data.carac.force.value) {
ChatMessage.create({
content: `<strong>${this.name} s'est équipé(e) de l'arme ${item.name}, mais n'a pas une force suffisante pour l'utiliser normalement </strong>
(${item.data.force} nécessaire pour une Force de ${this.data.data.carac.force.value})`
});
}
}
@ -2571,8 +2580,8 @@ export class RdDActor extends Actor {
await this.updateEmbeddedEntity("OwnedItem", update);
this.computeEncombrementTotalEtMalusArmure(); // Mise à jour encombrement
this.computePrixTotalEquipement(); // Mis à jour du prix total de l'équipement
if ( item.data.data.equipe )
this.verifierForceMin( item.data );
if (item.data.data.equipe)
this.verifierForceMin(item.data);
}
}
@ -2593,10 +2602,10 @@ export class RdDActor extends Actor {
protection = Math.max(protection - penetration, 0);
protection += this.getProtectionNaturelle();
// Gestion des cas particuliers sur la fenêtre d'encaissement
if ( attackerRoll.dmg.encaisserSpecial && attackerRoll.dmg.encaisserSpecial == "noarmure") {
if (attackerRoll.dmg.encaisserSpecial && attackerRoll.dmg.encaisserSpecial == "noarmure") {
protection = 0;
}
if ( attackerRoll.dmg.encaisserSpecial && attackerRoll.dmg.encaisserSpecial == "chute" && Number(protection) > 2) {
if (attackerRoll.dmg.encaisserSpecial && attackerRoll.dmg.encaisserSpecial == "chute" && Number(protection) > 2) {
protection = 2;
}
console.log("Final protect", protection, attackerRoll);
@ -2693,7 +2702,7 @@ export class RdDActor extends Actor {
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 ?? RdDUtility.getLocalisation(this.data.type);
encaissement.dmg.loc.label = encaissement.dmg.loc.label ?? 'Corps;'
encaissement.roll = roll;
encaissement.armure = armure;
@ -2782,26 +2791,26 @@ export class RdDActor extends Actor {
}
/* -------------------------------------------- */
async resetItemUse( ) {
async resetItemUse() {
await this.unsetFlag('foundryvtt-reve-de-dragon', 'itemUse');
await this.setFlag('foundryvtt-reve-de-dragon', 'itemUse', {} );
await this.setFlag('foundryvtt-reve-de-dragon', 'itemUse', {});
}
/* -------------------------------------------- */
async incDecItemUse( itemId, inc = 1 ) {
async incDecItemUse(itemId, inc = 1) {
let itemUse = duplicate(this.getFlag('foundryvtt-reve-de-dragon', 'itemUse') ?? {});
itemUse[itemId] = (itemUse[itemId] ?? 0) + inc;
await this.setFlag( 'foundryvtt-reve-de-dragon', 'itemUse', itemUse);
await this.setFlag('foundryvtt-reve-de-dragon', 'itemUse', itemUse);
console.log("ITEM USE INC", inc, itemUse);
}
/* -------------------------------------------- */
getItemUse( itemId ) {
getItemUse(itemId) {
let itemUse = this.getFlag('foundryvtt-reve-de-dragon', 'itemUse') ?? {};
console.log("ITEM USE GET", itemUse);
return itemUse[itemId] ?? 0;
}
/* -------------------------------------------- */
/* -- entites -- */
/* retourne true si on peut continuer, false si on ne peut pas continuer */
@ -2977,6 +2986,7 @@ export class RdDActor extends Actor {
label: 'Tache Alchimique',
callbacks: [
this.createCallbackExperience(),
this.createCallbackAppelAuMoral(),
{ action: r => this._alchimieResult(r, false) }
]
}
@ -3210,10 +3220,11 @@ export class RdDActor extends Actor {
}
}
notifyGestionTeteSouffleQueue(item, manualMessage=true){
notifyGestionTeteSouffleQueue(item, manualMessage = true) {
ChatMessage.create({
whisper: ChatUtility.getWhisperRecipientsAndGMs(game.user.name),
content: `${this.name} a reçu un/une ${item.type}: ${item.name}, qui ${manualMessage ? "n'est pas" : "est" } géré automatiquement. ${manualMessage ?? ''}`
content: `${this.name} a reçu un/une ${item.type}: ${item.name}, qui ${manualMessage ? "n'est pas" : "est"} géré automatiquement. ${manualMessage ?? ''}`
});
}}
}
}

View File

@ -5,6 +5,18 @@ const competenceTroncs = [["Esquive", "Dague", "Corps à corps"],
const competence_xp_par_niveau = [5, 5, 5, 10, 10, 10, 10, 15, 15, 15, 15, 20, 20, 20, 20, 30, 30, 40, 40, 60, 60, 100, 100, 100, 100, 100, 100, 100, 100, 100];
const competence_niveau_max = competence_xp_par_niveau.length - 10;
/* -------------------------------------------- */
const categorieCompetences = {
"generale": { level: "-4", label: "Générales" },
"particuliere": { level: "-8", label: "Particulières" },
"specialisee": { level: "-11", label: "Spécialisées" },
"connaissance": { level: "-11", label: "Connaissances" },
"draconic": { level: "-11", label: "Draconics" },
"melee": { level: "-6", label: "Mêlée" },
"tir": { level: "-8", label: "Tir" },
"lancer": { level: "-8", label: "Lancer" }
}
function _buildCumulXP() {
let cumulXP = { "-11": 0 };
let cumul = 0;
@ -20,6 +32,16 @@ const competence_xp_cumul = _buildCumulXP();
export class RdDItemCompetence extends Item {
static getCategorieCompetences() {
return categorieCompetences;
}
static getLevelCategory(category) {
return categorieCompetences[category].level;
}
static getLabelCategory(category) {
return categorieCompetences[category].label;
}
/* -------------------------------------------- */
static isCompetenceArme(competence) {
switch (competence.data.categorie) {

View File

@ -48,7 +48,7 @@ export class RdDItemSheet extends ItemSheet {
/* -------------------------------------------- */
async getData() {
let data = super.getData();
data.categorieCompetences = RdDUtility.getCategorieCompetences();
data.categorieCompetences = RdDItemCompetence.getCategorieCompetences();
if ( data.item.type == 'tache' || data.item.type == 'livre' || data.item.type == 'meditation' || data.item.type == 'oeuvre') {
data.caracList = duplicate(game.system.model.Actor.personnage.carac);
data.competences = await RdDUtility.loadCompendiumNames( 'foundryvtt-reve-de-dragon.competences' );
@ -111,7 +111,7 @@ export class RdDItemSheet extends ItemSheet {
async _onClickSelectCategorie(event) {
event.preventDefault();
let level = RdDUtility.getLevelCategory(event.currentTarget.value);
let level = RdDItemCompetence.getLevelCategory(event.currentTarget.value);
this.object.data.data.base = level;
$("#base").val( level );
}

View File

@ -700,6 +700,7 @@ export class RdDCombat {
label: 'Attaque: ' + (arme?.name ?? competence.name),
callbacks: [
this.attacker.createCallbackExperience(),
this.attacker.createCallbackAppelAuMoral(),
{ action: r => this.removeChatMessageActionsPasseArme(r.passeArme) },
{ condition: r => arme && !RdDCombat.isParticuliere(r), action: r => this.attacker.incDecItemUse(arme._id) },
{ condition: r => (RdDCombat.isReussite(r) && !RdDCombat.isParticuliere(r)), action: r => this._onAttaqueNormale(r) },
@ -936,6 +937,7 @@ export class RdDCombat {
label: 'Parade: ' + (arme ? arme.name : rollData.competence.name),
callbacks: [
this.defender.createCallbackExperience(),
this.defender.createCallbackAppelAuMoral(),
{ action: r => this.removeChatMessageActionsPasseArme(r.passeArme) },
{ condition: r => !RdDCombat.isParticuliere(r), action: r => this.defender.incDecItemUse(armeParadeId) },
{ condition: RdDCombat.isReussite, action: r => this._onParadeNormale(r) },
@ -1039,6 +1041,7 @@ export class RdDCombat {
label: 'Esquiver',
callbacks: [
this.defender.createCallbackExperience(),
this.defender.createCallbackAppelAuMoral(),
{ condition: r => !RdDCombat.isParticuliere(r), action: r => this.defender.incDecItemUse(esquive._id) },
{ action: r => this.removeChatMessageActionsPasseArme(r.passeArme) },
{ condition: RdDCombat.isReussite, action: r => this._onEsquiveNormale(r) },

View File

@ -54,7 +54,7 @@ export class RdDRoll extends Dialog {
useMalusSurenc: false,
appelAuMoralPossible : false, /* Est-ce que l'appel au moral est possible ? Variable utisé pour l'affichage ou non de la ligne concernant le moral */
appelAuMoralDemander :false, /* Est-ce que le joueur demande d'utiliser le moral ? Utile si le joueur change plusieurs fois de carac associée. */
jetEchouerMoralDiminuer : false, /* Pour l'affichage dans le chat */
perteMoralEchec : false, /* Pour l'affichage dans le chat */
use: { libre: true, conditions: true, surenc: false, encTotal: false, appelAuMoral : false /* Le jet se fait ou non en utilisant l'appel au moral */},
isMalusEncombrementTotal: RdDItemCompetence.isMalusEncombrementTotal(rollData.competence),
useMalusEncTotal: false,

View File

@ -1,27 +1,10 @@
/* Common useful functions shared between objects */
import { RdDRollTables } from "./rdd-rolltables.js";
import { ChatUtility } from "./chat-utility.js";
import { RdDCombat, RdDCombatManager } from "./rdd-combat.js";
import { RdDRollResolutionTable } from "./rdd-roll-resolution-table.js";
import { RdDItemCompetenceCreature } from "./item-competencecreature.js";
import { RdDItemArme } from "./item-arme.js";
import { RdDItemCompetence } from "./item-competence.js";
import { RdDCombat } from "./rdd-combat.js";
import { Misc } from "./misc.js";
import { Grammar } from "./grammar.js";
/* -------------------------------------------- */
const categorieCompetences = {
"generale": { level: "-4", label: "Générales" },
"particuliere": { level: "-8", label: "Particulières" },
"specialisee": { level: "-11", label: "Spécialisées" },
"connaissance": { level: "-11", label: "Connaissances" },
"draconic": { level: "-11", label: "Draconics" },
"melee": { level: "-6", label: "Mêlée" },
"tir": { level: "-8", label: "Tir" },
"lancer": { level: "-8", label: "Lancer" }
}
/* -------------------------------------------- */
const limitesArchetypes = [
{ "niveau": 0, "nombreMax": 100, "nombre": 0 },
@ -403,15 +386,6 @@ export class RdDUtility {
}
/* -------------------------------------------- */
static getCategorieCompetences() {
return categorieCompetences;
}
static getLevelCategory(category) {
return categorieCompetences[category].level;
}
static getLabelCategory(category) {
return categorieCompetences[category].label;
}
static getCaracArray() {
return carac_array;
}

View File

@ -2,7 +2,7 @@
"name": "foundryvtt-reve-de-dragon",
"title": "Rêve de Dragon",
"description": "Rêve de Dragon RPG for FoundryVTT",
"version": "1.3.32",
"version": "1.3.33",
"manifestPlusVersion": "1.0.0",
"minimumCoreVersion": "0.7.5",
"compatibleCoreVersion": "0.7.9",

View File

@ -1,4 +1,8 @@
{{#if use.appelAuMoral}}<div>
{{alias}} fait appel {{#if (gt moral 0)}}au moral{{else}}à l'énergie du déspoir{{/if}} {{#if jetEchouerMoralDiminuer}}et échoue, diminuant son moral.{{else}} et réussit.{{/if}}
{{^jetEchouerMoralDiminuer}} Son moral reste inchangé à {{moral}}.{{/jetEchouerMoralDiminuer}}
<div>{{/if}}
{{#if use.appelAuMoral}}
<span>
Vous avez fait appel {{#if (gt moral 0)}}au moral{{else}}à l'énergie du déspoir{{/if}}
{{#if perteMoralEchec}}et échoué, votre moral baisse à {{moral}}.
{{else}}et réussi, votre moral reste de {{moral}}.
{{/if}}
<span>
{{/if}}

View File

@ -10,4 +10,5 @@
{{else}}
{{alias}} a raté son opération alchimique ! Sa recette est un echec.
{{/if}}
{{> "systems/foundryvtt-reve-de-dragon/templates/chat-info-appel-au-moral.html"}}
</div>

View File

@ -17,25 +17,24 @@
</div>
{{/if}}
<div>
{{#if rolled.isSuccess}}
<span><strong>{{show.cible}}</strong> doit se défendre à <strong>{{diffLibre}}</strong>, ou encaisser à
{{~#if (eq dmg.mortalite 'non-mortel')}}
<span class="rdd-roll-norm">({{numberFormat dmg.total decimals=0 sign=true}})</span> (dommages non-mortel)
{{else if (eq dmg.mortalite 'mortel')}}
<span class="rdd-roll-echec">{{numberFormat dmg.total decimals=0 sign=true}}</span>
{{else}}
<span class="rdd-roll-etotal">{{numberFormat dmg.total decimals=0 sign=true}}</span> (entités de cauchemar)
{{~/if}}.
{{#if show.isRecul}}Si votre adversaire n'esquive pas, il devra résister à l'impact ou reculer sous le choc!{{/if}}
</span>
</div>
{{#if rolled.isSuccess}}
<span><strong>{{show.cible}}</strong> doit se défendre à <strong>{{diffLibre}}</strong>, ou encaisser à
{{~#if (eq dmg.mortalite 'non-mortel')}}
<span class="rdd-roll-norm">({{numberFormat dmg.total decimals=0 sign=true}})</span> (dommages non-mortel)
{{else if (eq dmg.mortalite 'mortel')}}
<span class="rdd-roll-echec">{{numberFormat dmg.total decimals=0 sign=true}}</span>
{{else}}
<span class="rdd-roll-etotal">{{numberFormat dmg.total decimals=0 sign=true}}</span> (entités de cauchemar)
{{~/if}}.
{{#if show.isRecul}}Si votre adversaire n'esquive pas, il devra résister à l'impact ou reculer sous le choc!{{/if}}
</span>
{{#if (eq particuliere 'rapidite')}}
<div>
<span>
<br>Votre attaque rapide vous permet une deuxième attaque, ou défense supplémentaire!
</span>
{{/if}}
{{else}}
Votre attaque a échoué!
{{/if}}
{{else}}
<span>Votre attaque a échoué!</span>
{{/if}}
{{> "systems/foundryvtt-reve-de-dragon/templates/chat-info-appel-au-moral.html"}}
</div>

View File

@ -10,5 +10,6 @@
{{else}}
{{alias}} est peu inspiré(e) et son interprétation a une qualité de {{qualiteFinale}}.
{{/if}}
{{> "systems/foundryvtt-reve-de-dragon/templates/chat-info-appel-au-moral.html"}}
</div>
{{> "systems/foundryvtt-reve-de-dragon/templates/chat-poesie.html" oeuvre.data}}

View File

@ -10,5 +10,6 @@
{{else}}
{{alias}} est peu inspiré(e) et son interprétation a une qualité de {{qualiteFinale}}.
{{/if}}
{{> "systems/foundryvtt-reve-de-dragon/templates/chat-info-appel-au-moral.html"}}
</div>
{{> "systems/foundryvtt-reve-de-dragon/templates/chat-poesie.html" oeuvre.data}}

View File

@ -4,7 +4,8 @@
De plus, {{alias}} a perdu {{endurance}} points d'endurance
{{#if (ne vie 0)}}et <span class="rdd-roll-echec">{{vie}} points de vie</span>{{/if}}
{{/if}}
</span>
{{#if (gt endurance 1)}}Jet d'endurance : {{jetEndurance}} / {{resteEndurance}} {{/if}}
</span>
{{else}}
<h4>{{alias}} encaisse à
<span>
@ -36,8 +37,8 @@
{{/if}}
{{#if (ne dmg.mortalite 'cauchemar')}}
{{#if (gt endurance 1)}}et
{{#if sonne}}est <strong>sonné</strong><img class="chat-icon" src="icons/svg/stoned.svg" alt="charge" height="16" width="16" /> jusqu'à la fin du prochain round{{else}}n'est pas sonné{{/if}}
({{jetEndurance}} / {{resteEndurance}})!
{{#if sonne}}est <strong>sonné</strong><img class="chat-icon" src="icons/svg/stoned.svg" alt="charge" height="16" width="16" /> jusqu'à la fin du prochain round{{else}}n'est pas sonné{{/if}}!
{{#if hasPlayerOwner}}Jet d'endurance : Jet d'endurance : {{jetEndurance}} / {{resteEndurance}}{{/if}}
{{/if}}
{{/if}}
{{/if}}

View File

@ -13,6 +13,7 @@
{{else}}
<span>Votre esquive a échoué!</span>
{{/if}}
{{> "systems/foundryvtt-reve-de-dragon/templates/chat-info-appel-au-moral.html"}}
</div>
{{#if attackerRoll.tactique}}

View File

@ -12,6 +12,7 @@
<hr>
<div>
<span>{{#if rolled.ptTache}}{{rolled.ptTache}} points de tâche{{/if}}{{#if rolled.ptQualite}}{{#if rolled.ptTache}},{{/if}} ajustement Qualité {{numberFormat rolled.ptQualite decimals=0 sign=true}}{{/if}}</span>
{{> "systems/foundryvtt-reve-de-dragon/templates/chat-info-appel-au-moral.html"}}
</div>
{{~#if show.explications}}
<div>

View File

@ -10,5 +10,6 @@
{{else}}
{{alias}} a perdu ...
{{/if}}
{{> "systems/foundryvtt-reve-de-dragon/templates/chat-info-appel-au-moral.html"}}
</div>
{{> "systems/foundryvtt-reve-de-dragon/templates/chat-poesie.html" oeuvre.data}}

View File

@ -10,5 +10,6 @@
{{else}}
{{alias}} est peu inspiré(e) et son interprétation a une qualité de {{qualiteFinale}}.
{{/if}}
{{> "systems/foundryvtt-reve-de-dragon/templates/chat-info-appel-au-moral.html"}}
</div>
{{> "systems/foundryvtt-reve-de-dragon/templates/chat-poesie.html" oeuvre.data}}

View File

@ -11,5 +11,6 @@
{{else}}
{{alias}} est peu inspiré(e) et son interprétation a une qualité de {{qualiteFinale}}.
{{/if}}
{{> "systems/foundryvtt-reve-de-dragon/templates/chat-info-appel-au-moral.html"}}
</div>
{{> "systems/foundryvtt-reve-de-dragon/templates/chat-poesie.html" oeuvre.data}}

View File

@ -12,6 +12,7 @@
La parade a échoué!
{{/if}}
</span>
{{> "systems/foundryvtt-reve-de-dragon/templates/chat-info-appel-au-moral.html"}}
</div>
{{#if (eq show.recul 'encaisse')}}<div>{{alias}} ne recule pas malgré la violence du coup.</div>

View File

@ -4,16 +4,18 @@
</h4>
{{> "systems/foundryvtt-reve-de-dragon/templates/chat-infojet.html"}}
<hr>
{{#if rolled.isSuccess}}
<span>
{{#if rolled.isSuccess}}
{{alias}} réussit sa recette, avec un plat de qualité {{qualiteFinale}} pour {{oeuvre.data.sust}} Points de Sustentation.
{{else}}
{{else}}
{{alias}} fait un piètre cuisinier(e), et obtient {{#if (lt qualiteFinale 0)}}un plat à l'exotisme certain{{else}}un plat de qualité {{qualiteFinale}}{{/if}}.
Selon la décision du MJ, le plat peut fournir {{oeuvre.data.sust}} Points de Sustentation
{{/if}}
{{#if (lt exotismeFinal 0)}}
<br>Au vu de l'exotisme du plat, les convives devront réussir un jet de Volonté / Cuisine à {{exotismeFinal}}.
En cas d'échec, ils peuvent se forcer pour faire plaisir au Maître Queux, mais devront faire un jet de moral Malheureux.
{{/if}}
{{/if}}
{{#if (lt exotismeFinal 0)}}
<br>Au vu de l'exotisme du plat, les convives devront réussir un jet de Volonté / Cuisine à {{exotismeFinal}}.
En cas d'échec, ils peuvent se forcer pour faire plaisir au Maître Queux, mais devront faire un jet de moral Malheureux.
{{/if}}
</span>
{{> "systems/foundryvtt-reve-de-dragon/templates/chat-info-appel-au-moral.html"}}
{{> "systems/foundryvtt-reve-de-dragon/templates/chat-poesie.html" oeuvre.data}}

View File

@ -10,4 +10,5 @@
votre avancement est de <span class="rdd-roll-{{#if (gt tache.data.points_de_tache_courant 0)}}norm{{else}}etotal{{/if}}">{{tache.data.points_de_tache_courant}} sur {{tache.data.points_de_tache}}</span> point{{~#if (gt tache.data.points_de_tache_courant 1)}}s{{/if}} de tâche.
{{#if tache.data.fatigue}}<br><span>Vous vous êtes fatigué de {{tache.data.fatigue}} case{{~#if (gt tache.data.fatigue 1)}}s{{/if}}.</span>{{/if}}
{{#if rolled.isETotal}}<br><span>Votre échec total augmente de 1 la difficulté de la tâche!</span>{{/if~}}
{{> "systems/foundryvtt-reve-de-dragon/templates/chat-info-appel-au-moral.html"}}
</div>