Compétences & herbes personalisées

* permettre d'ajouter des compétences dans un monde, qui seront
  ajoutés aux acteurs créés dans ce monde
* les herbes de repos/soins du monde sont bien considérées comme
  des herbes pour les potions
This commit is contained in:
Vincent Vandemeulebrouck 2022-10-08 14:25:31 +02:00
parent 6d0e5321a2
commit 18039e905b
8 changed files with 95 additions and 78 deletions

View File

@ -120,7 +120,7 @@ export class RdDActor extends Actor {
}
if (isPersonnage) {
const competences = await RdDUtility.loadCompendium(RdDItemCompetence.actorCompendium(actorData.type));
const competences = await RdDUtility.loadItems(it => it.isCompetencePersonnage(), 'foundryvtt-reve-de-dragon.competences');
actorData.items = competences.map(i => i.toObject());
actorData.items = actorData.items.concat(Monnaie.monnaiesStandard());
}
@ -343,7 +343,7 @@ export class RdDActor extends Actor {
}
/* -------------------------------------------- */
getDraconicList() {
return this.items.filter(it => it.type == 'competence' && it.system.categorie == 'draconic')
return this.items.filter(it => it.isCompetencePersonnage() && it.system.categorie == 'draconic')
}
/* -------------------------------------------- */
getBestDraconic() {
@ -2317,7 +2317,7 @@ export class RdDActor extends Actor {
case "detection d'aura":
return draconicList;
case "annulation de magie":
return draconicList.filter(it => !Grammar.toLowerCaseNoAccent(it.name).includes('thanatos'));
return draconicList.filter(it => !RdDItemCompetence.isThanatos(it));
}
return [RdDItemCompetence.getVoieDraconic(draconicList, sort.system.draconic)];
}
@ -4140,7 +4140,7 @@ export class RdDActor extends Actor {
/* -------------------------------------------- */
async onPreUpdateItem(item, change, options, id) {
if (item.type == 'competence' && item.system.defaut_carac && item.system.xp) {
if (item.isCompetencePersonnage() && item.system.defaut_carac && item.system.xp) {
await this.checkCompetenceXP(item.name, item.system.xp);
}
}

View File

@ -57,8 +57,8 @@ const competence_xp_cumul = _buildCumulXP();
export class RdDItemCompetence extends Item {
/* -------------------------------------------- */
static actorCompendium(actorType) {
return compendiumCompetences[actorType];
static actorCompendium(actorType = undefined) {
return compendiumCompetences[actorType ?? 'personnage'];
}
/* -------------------------------------------- */
@ -89,22 +89,28 @@ export class RdDItemCompetence extends Item {
/* -------------------------------------------- */
static isCompetenceArme(competence) {
switch (competence.system.categorie) {
case 'melee':
return competence.name != 'Esquive';
case 'tir':
case 'lancer':
return true;
if (competence.isCompetence()) {
switch (competence.system.categorie) {
case 'melee':
return !Grammar.toLowerCaseNoAccent(competence.name).includes('esquive');
case 'tir':
case 'lancer':
return true;
}
}
return false;
}
/* -------------------------------------------- */
static isArmeUneMain(competence) {
return competence.name.toLowerCase().includes("1 main");
return RdDItemCompetence.isCompetenceArme(competence) && competence.name.toLowerCase().includes("1 main");
}
static isArme2Main(competence) {
return competence.name.toLowerCase().includes("2 main");
return RdDItemCompetence.isCompetenceArme(competence) && competence.name.toLowerCase().includes("2 main");
}
static isThanatos(competence) {
return competence.isCompetencePersonnage() && Grammar.toLowerCaseNoAccent(competence.name).includes('thanatos');
}
/* -------------------------------------------- */
@ -133,7 +139,7 @@ export class RdDItemCompetence extends Item {
/* -------------------------------------------- */
static computeXP(competence) {
const factor = competence.name.includes('Thanatos') ? 2 : 1; // Thanatos compte double !
const factor = RdDItemCompetence.isThanatos(competence) ? 2 : 1; // Thanatos compte double !
const xpNiveau = RdDItemCompetence.computeDeltaXP(competence.system.base, competence.system.niveau ?? competence.system.base);
const xp = competence.system.xp ?? 0;
const xpSort = competence.system.xp_sort ?? 0;
@ -213,21 +219,14 @@ export class RdDItemCompetence extends Item {
if (idOrName == undefined) {
return undefined;
}
options = mergeObject(options, {
preFilter: it => RdDItemCompetence.isCompetence(it),
description: 'compétence',
});
return list.find(it => it.id == idOrName && RdDItemCompetence.isCompetence(it))
options = mergeObject(options, { preFilter: it => it.isCompetence(), description: 'compétence', });
return list.find(it => it.id == idOrName && it.isCompetence())
?? Misc.findFirstLike(idOrName, list, options);
}
/* -------------------------------------------- */
static findCompetences(list, name) {
return Misc.findAllLike(name, list, { filter: it => RdDItemCompetence.isCompetence(it), description: 'compétence' });
}
static isCompetence(item) {
return item.type == 'competence' || item.type == 'competencecreature';
return Misc.findAllLike(name, list, { filter: it => it.isCompetence(), description: 'compétence' });
}
/* -------------------------------------------- */

View File

@ -90,11 +90,10 @@ export class RdDItemSheet extends ItemSheet {
if (this.item.type == 'tache' || this.item.type == 'livre' || this.item.type == 'meditation' || this.item.type == 'oeuvre') {
formData.caracList = duplicate(game.system.model.Actor.personnage.carac)
formData.caracList["reve-actuel"] = duplicate(game.system.model.Actor.personnage.reve.reve)
formData.competences = await RdDUtility.loadCompendium('foundryvtt-reve-de-dragon.competences')
formData.competences = await RdDUtility.loadItems(it => it.isCompetencePersonnage(), RdDItemCompetence.actorCompendium(this.actor?.type))
}
if (this.item.type == 'arme') {
formData.competences = await RdDUtility.loadCompendium('foundryvtt-reve-de-dragon.competences', it => RdDItemCompetence.isCompetenceArme(it));
console.log(formData.competences)
formData.competences = await RdDUtility.loadItems(it => RdDItemCompetence.isCompetenceArme(it), RdDItemCompetence.actorCompendium(this.actor?.type))
}
if (this.item.type == 'recettecuisine') {
formData.ingredients = await TextEditor.enrichHTML(this.object.system.ingredients, {async: true})
@ -115,7 +114,7 @@ export class RdDItemSheet extends ItemSheet {
formData.system.prdate = this.dateUpdated;
this.dateUpdated = undefined;
}
RdDHerbes.updatePotionData(formData);
await RdDHerbes.updatePotionData(formData);
}
if (formData.isOwned && this.item.type == 'herbe' && (formData.system.categorie == 'Soin' || formData.system.categorie == 'Repos')) {
formData.isIngredientPotionBase = true;
@ -160,7 +159,7 @@ export class RdDItemSheet extends ItemSheet {
html.find(".categorie").change(event => this._onSelectCategorie(event));
html.find('.sheet-competence-xp').change((event) => {
if (this.item.type == 'competence') {
if (this.item.isCompetencePersonnage()) {
RdDUtility.checkThanatosXP(this.item.name);
}
});

View File

@ -77,6 +77,9 @@ export class RdDItem extends Item {
return typesObjetsOeuvres
}
isCompetencePersonnage() {
return this.type == 'competence'
}
isCompetence() {
return typesObjetsCompetence.includes(this.type)
}
@ -180,8 +183,8 @@ export class RdDItem extends Item {
this.system.magique = categorie.includes('enchante');
if (this.system.magique) {
if (categorie.includes('soin') || categorie.includes('repos')) {
// TODO: utiliser calculePointsRepos / calculePointsGuerison
this.system.puissance = RdDHerbes.calculePuissancePotion(this);
// TODO: utiliser calculPointsRepos / calculPointsGuerison
this.system.puissance = RdDHerbes.calculPuissancePotion(this);
}
}
}

View File

@ -1,74 +1,73 @@
import { RdDUtility } from "./rdd-utility.js";
import { RdDCalendrier } from "./rdd-calendrier.js";
import { Grammar } from "./grammar.js";
/* -------------------------------------------- */
export class RdDHerbes extends Item {
/* -------------------------------------------- */
static isHerbeSoin( botaniqueItem ) {
return botaniqueItem.categorie == 'Soin';
}
/* -------------------------------------------- */
static isHerbeRepos( botaniqueItem ) {
return botaniqueItem.categorie == 'Repos';
static async initializeHerbes() {
this.herbesSoins = await RdDHerbes.listCategorieHerbes('Soin');
this.herbesRepos = await RdDHerbes.listCategorieHerbes('Repos');
}
/* -------------------------------------------- */
static async initializeHerbes( ) {
this.herbesSoins = await RdDUtility.loadCompendium('foundryvtt-reve-de-dragon.botanique', item => this.isHerbeSoin(item));
this.herbesRepos = await RdDUtility.loadCompendium('foundryvtt-reve-de-dragon.botanique', item => this.isHerbeRepos(item));
static async listCategorieHerbes(categorie) {
return await RdDUtility.loadItems(
it => it.type == 'herbe' && it.system.categorie.toLowerCase() == categorie.toLowerCase(),
'foundryvtt-reve-de-dragon.botanique');
}
/* -------------------------------------------- */
static buildHerbesList(listeHerbes, max) {
let list = {}
for ( let herbe of listeHerbes) {
for (let herbe of listeHerbes) {
let brins = max - herbe.system.niveau;
list[herbe.system.name] = `${herbe.system.name} (Bonus: ${herbe.system.niveau}, Brins: ${brins})`;
list[herbe.name] = `${herbe.name} (Bonus: ${herbe.system.niveau}, Brins: ${brins})`;
}
list['Autre'] = 'Autre (Bonus: variable, Brins: variable)'
return list;
}
/* -------------------------------------------- */
static updatePotionData( formData ) {
formData.herbesSoins = this.buildHerbesList(this.herbesSoins, 12);
formData.herbesRepos = this.buildHerbesList(this.herbesRepos, 7);
static async updatePotionData(formData) {
formData.isSoins = formData.system.categorie.includes('Soin');
formData.isRepos = formData.system.categorie.includes('Repos');
if (formData.isSoins) {
RdDHerbes.calculBonusHerbe(formData, this.herbesSoins, 12);
}
if (formData.isRepos) {
RdDHerbes.calculBonusHerbe(formData, this.herbesRepos, 7);
}
formData.herbesSoins = RdDHerbes.buildHerbesList(this.herbesSoins, 12);
formData.herbesRepos = RdDHerbes.buildHerbesList(this.herbesRepos, 7);
formData.jourMoisOptions = RdDCalendrier.buildJoursMois();
formData.dateActuelle = game.system.rdd.calendrier.getDateFromIndex();
formData.splitDate = game.system.rdd.calendrier.getNumericDateFromIndex(formData.system.prdate);
if (formData.system.categorie.includes('Soin') ) {
formData.isHerbe = true;
this.computeHerbeBonus(formData, this.herbesSoins, 12);
} else if (formData.system.categorie.includes('Repos')) {
formData.isRepos = true;
this.computeHerbeBonus(formData, this.herbesRepos, 7);
}
}
/* -------------------------------------------- */
static calculePuissancePotion( potion ) {
static calculPuissancePotion(potion) {
return potion.system.herbebonus * potion.system.pr;
}
/* -------------------------------------------- */
static calculePointsRepos( potion ) {
static calculPointsRepos(potion) {
return potion.system.herbebonus * potion.system.pr;
}
/* -------------------------------------------- */
static calculePointsGuerison( potion ){
static calculPointsGuerison(potion) {
return potion.system.herbebonus * potion.system.pr;
}
/* -------------------------------------------- */
static computeHerbeBonus( formData, herbesList, max) {
if ( Number(formData.system.herbebrins) ) {
let herbe = herbesList.find(item => item.name.toLowerCase() == formData.system.herbe.toLowerCase() );
if( herbe ) {
let brinsBase = max - herbe.system.niveau;
formData.system.herbebonus = Math.max(herbe.system.niveau - Math.max(brinsBase - formData.system.herbebrins, 0), 0);
static calculBonusHerbe(formData, herbesList, max) {
if (Number(formData.system.herbebrins)) {
let herbe = herbesList.find(item => item.name.toLowerCase() == formData.system.herbe.toLowerCase());
if (herbe) {
const brinsRequis = max - herbe.system.niveau;
const brinsManquants = Math.max(brinsRequis - formData.system.herbebrins, 0);
formData.system.herbebonus = Math.max(herbe.system.niveau - brinsManquants, 0);
}
}
}

View File

@ -2,16 +2,22 @@ export class RdDRollTables {
/* -------------------------------------------- */
static async genericGetTableResult(tableName, toChat) {
let table = game.tables.find(table => table.name.toLowerCase() == tableName.toLowerCase())
if ( !table) {
const pack = game.packs.get("foundryvtt-reve-de-dragon.tables-diverses");
const index = await pack.getIndex();
const entry = index.find(e => e.name === tableName);
table = await pack.getDocument(entry._id);
}
let table = RdDRollTables.getWorldTable() ?? (await RdDRollTables.getSystemTable(tableName));
const draw = await table.draw({ displayChat: toChat, rollMode: "gmroll"});
//console.log("RdDRollTables", tableName, toChat, ":", draw);
return draw.results.length > 0 ? draw.results[0] : undefined;
}
static getWorldTable() {
return game.tables.find(table => table.name.toLowerCase() == tableName.toLowerCase());
}
static async getSystemTable(tableName) {
const pack = game.packs.get("foundryvtt-reve-de-dragon.tables-diverses");
const index = await pack.getIndex();
const entry = index.find(e => e.name === tableName);
return await pack.getDocument(entry._id);
}
/* -------------------------------------------- */

View File

@ -683,17 +683,28 @@ export class RdDUtility {
}
/* -------------------------------------------- */
static async loadCompendiumData(compendium) {
const pack = game.packs.get(compendium);
return await pack?.getDocuments() ?? [];
static async loadItems(filter, compendium) {
let items = game.items.filter(filter);
if (compendium) {
const ids = items.map(it => it.id);
const names = items.map(it => it.name.toLowerCase());
items = items.concat(await RdDUtility.loadCompendium(compendium, it => !ids.includes(it.id) && !names.includes(it.name.toLowerCase()) && filter(it)));
}
return items;
}
/* -------------------------------------------- */
static async loadCompendium(compendium, filter = item => true) {
static async loadCompendium(compendium, filter = it => true) {
let compendiumData = await RdDUtility.loadCompendiumData(compendium);
return compendiumData.filter(filter);
}
/* -------------------------------------------- */
static async loadCompendiumData(compendium) {
const pack = game.packs.get(compendium);
return await pack?.getDocuments() ?? [];
}
/* -------------------------------------------- */
static async responseNombreAstral(callData) {
let actor = game.actors.get(callData.id);

View File

@ -41,7 +41,7 @@
{{/select}}
</select>
</div>
{{#if isHerbe}}
{{#if isSoins}}
<div class="form-group">
<label>Herbe</label>
<select name="system.herbe" class="herbe" data-dtype="String">
@ -86,7 +86,7 @@
<label for="xp">Permanente ? </label>
<input class="attribute-value" type="checkbox" name="system.prpermanent" {{#if system.prpermanent}}checked{{/if}}/>
</div>
{{#if isHerbe}}
{{#if isSoins}}
<div class="form-group">
<label for="xp">Points de guérison </label>
<label for="xp">{{pointsGuerison}}</label>