Export csv pour Scriptarium
Activable dans les options avancées du système Un menu contextuel permet d'écrire dans les logs
This commit is contained in:
parent
91be2761f5
commit
7e8f642d87
73
module/actor/export-scriptarium/export-scriptarium.js
Normal file
73
module/actor/export-scriptarium/export-scriptarium.js
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
import { LOG_HEAD } from "../../constants.js"
|
||||||
|
import { ACTOR_TYPES } from "../../item.js"
|
||||||
|
import { Misc } from "../../misc.js"
|
||||||
|
import { EXPORT_CSV_SCRIPTARIUM, OptionsAvancees } from "../../settings/options-avancees.js"
|
||||||
|
import { Mapping } from "./mapping.js"
|
||||||
|
|
||||||
|
const IMG_SCRIPTARIUM = '<img class="context-menu-img" src="systems/foundryvtt-reve-de-dragon/styles/img/ui/scriptarium.svg">'
|
||||||
|
|
||||||
|
export class ExportScriptarium {
|
||||||
|
|
||||||
|
static init() {
|
||||||
|
ExportScriptarium.INSTANCE = new ExportScriptarium()
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this.mapping = Mapping.getMapping()
|
||||||
|
Hooks.on("getActorDirectoryFolderContext", (actorDirectory, menus) => { ExportScriptarium.INSTANCE.onActorDirectoryMenu(actorDirectory, menus) })
|
||||||
|
Hooks.on("getActorDirectoryEntryContext", (actorDirectory, menus) => { ExportScriptarium.INSTANCE.onActorDirectoryMenu(actorDirectory, menus) })
|
||||||
|
}
|
||||||
|
|
||||||
|
onActorDirectoryMenu(actorDirectory, menus) {
|
||||||
|
menus.push({
|
||||||
|
name: 'Export Personnages',
|
||||||
|
icon: IMG_SCRIPTARIUM,
|
||||||
|
condition: (target) => game.user.isGM &&
|
||||||
|
OptionsAvancees.isUsing(EXPORT_CSV_SCRIPTARIUM) &&
|
||||||
|
this.$getActors(actorDirectory, target).length > 0,
|
||||||
|
callback: target => this.exportActors(this.$getActors(actorDirectory, target))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
$getActors(actorDirectory, target) {
|
||||||
|
const li = target.closest(".directory-item")
|
||||||
|
const folderId = li.data("folderId")
|
||||||
|
const actorId = li.data("documentId")
|
||||||
|
const actors = actorId
|
||||||
|
? [game.actors.get(actorId)]
|
||||||
|
: folderId
|
||||||
|
? actorDirectory.folders.find(it => it.id == folderId).contents
|
||||||
|
: []
|
||||||
|
return actors.filter(it => it.type == ACTOR_TYPES.personnage)
|
||||||
|
}
|
||||||
|
|
||||||
|
exportActors(actors) {
|
||||||
|
console.log(LOG_HEAD + 'exportActors', actors)
|
||||||
|
const header = Misc.join(this.getHeaderLine(), ';')
|
||||||
|
console.log(header)
|
||||||
|
actors.forEach(actor => {
|
||||||
|
const actorLine = Misc.join(this.getActorLine(actor), ';')
|
||||||
|
console.log(actorLine)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
getHeaderLine() {
|
||||||
|
return this.mapping.map(it => it.column)
|
||||||
|
}
|
||||||
|
|
||||||
|
getActorLine(actor) {
|
||||||
|
const context = Mapping.prepareContext(actor)
|
||||||
|
return this.mapping.map(it => it.getter(actor, context))
|
||||||
|
.map(it => this.$escapeQuotes(it))
|
||||||
|
.map(it => it.replaceAll("\n", " ").replaceAll("\r", ""))
|
||||||
|
}
|
||||||
|
|
||||||
|
$escapeQuotes(it) {
|
||||||
|
it = '' + it
|
||||||
|
if (it.includes('"') || it.includes(';')) {
|
||||||
|
return `"${it.replaceAll('"', '\\"')}"`
|
||||||
|
}
|
||||||
|
return it
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
303
module/actor/export-scriptarium/mapping.js
Normal file
303
module/actor/export-scriptarium/mapping.js
Normal file
@ -0,0 +1,303 @@
|
|||||||
|
import { Grammar } from "../../grammar.js"
|
||||||
|
import { RdDItemArme } from "../../item-arme.js"
|
||||||
|
import { RdDItemCompetence } from "../../item-competence.js"
|
||||||
|
import { RdDItemSort } from "../../item-sort.js"
|
||||||
|
import { ITEM_TYPES } from "../../item.js"
|
||||||
|
import { Misc } from "../../misc.js"
|
||||||
|
import { RdDTimestamp } from "../../time/rdd-timestamp.js"
|
||||||
|
import { TMRConstants } from "../../tmr-constants.js"
|
||||||
|
import { TMRUtility } from "../../tmr-utility.js"
|
||||||
|
|
||||||
|
const CATEGORIES_COMPETENCES = [
|
||||||
|
"generale",
|
||||||
|
"particuliere",
|
||||||
|
"specialisee",
|
||||||
|
"connaissance",
|
||||||
|
]
|
||||||
|
const CATEGORIES_DRACONIC = [
|
||||||
|
"draconic",
|
||||||
|
]
|
||||||
|
|
||||||
|
const CATEGORIES_COMBAT = [
|
||||||
|
"melee",
|
||||||
|
"tir",
|
||||||
|
"lancer"
|
||||||
|
]
|
||||||
|
|
||||||
|
const NIVEAU_BASE = {
|
||||||
|
"generale": -4,
|
||||||
|
"particuliere": -8,
|
||||||
|
"specialisee": -11,
|
||||||
|
"connaissance": -11,
|
||||||
|
"draconic": -11,
|
||||||
|
"melee": -6,
|
||||||
|
"tir": -8,
|
||||||
|
"lancer": -8,
|
||||||
|
}
|
||||||
|
|
||||||
|
class ColumnMappingFactory {
|
||||||
|
static createMappingArme(part, i) {
|
||||||
|
return { column: `arme-${part}-${i}`, getter: (actor, context) => Mapping.getArme(actor, context, part, i) }
|
||||||
|
}
|
||||||
|
|
||||||
|
static createMappingSort(part, i) {
|
||||||
|
return { column: `sort-${part}-${i}`, getter: (actor, context) => Mapping.getSort(actor, context, part, i) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const NB_ARMES = 10
|
||||||
|
const NB_SORTS = 20
|
||||||
|
const TABLEAU_ARMES = [...Array(NB_ARMES).keys()]
|
||||||
|
const TABLEAU_SORTS = [...Array(NB_SORTS).keys()]
|
||||||
|
|
||||||
|
const MAPPING_BASE = [
|
||||||
|
{ column: "ID", getter: (actor, context) => actor.id },
|
||||||
|
{ column: "name", getter: (actor, context) => actor.name },
|
||||||
|
// { column: "biographie", getter: (actor, context) => actor.system.biographie },
|
||||||
|
{ column: "taille", getter: (actor, context) => actor.system.carac.taille.value },
|
||||||
|
{ column: "apparence", getter: (actor, context) => actor.system.carac.apparence.value },
|
||||||
|
{ column: "constitution", getter: (actor, context) => actor.system.carac.constitution.value },
|
||||||
|
{ column: "force", getter: (actor, context) => actor.system.carac.force.value },
|
||||||
|
{ column: "agilite", getter: (actor, context) => actor.system.carac.agilite.value },
|
||||||
|
{ column: "dexterite", getter: (actor, context) => actor.system.carac.dexterite.value },
|
||||||
|
{ column: "vue", getter: (actor, context) => actor.system.carac.vue.value },
|
||||||
|
{ column: "ouie", getter: (actor, context) => actor.system.carac.ouie.value },
|
||||||
|
{ column: "odoratgout", getter: (actor, context) => actor.system.carac.odoratgout.value },
|
||||||
|
{ column: "volonte", getter: (actor, context) => actor.system.carac.volonte.value },
|
||||||
|
{ column: "intellect", getter: (actor, context) => actor.system.carac.intellect.value },
|
||||||
|
{ column: "empathie", getter: (actor, context) => actor.system.carac.empathie.value },
|
||||||
|
{ column: "reve", getter: (actor, context) => actor.system.carac.reve.value },
|
||||||
|
{ column: "chance", getter: (actor, context) => actor.system.carac.chance.value },
|
||||||
|
{ column: "melee", getter: (actor, context) => actor.system.carac.melee.value },
|
||||||
|
{ column: "tir", getter: (actor, context) => actor.system.carac.tir.value },
|
||||||
|
{ column: "lancer", getter: (actor, context) => actor.system.carac.lancer.value },
|
||||||
|
{ column: "derobee", getter: (actor, context) => actor.system.carac.derobee.value },
|
||||||
|
{ column: "vie", getter: (actor, context) => actor.system.sante.vie.max },
|
||||||
|
{ column: "plusdom", getter: (actor, context) => actor.system.attributs.plusdom.value },
|
||||||
|
{ column: "protectionnaturelle", getter: (actor, context) => actor.system.attributs.protection.value },
|
||||||
|
{ column: "endurance", getter: (actor, context) => actor.system.sante.endurance.max },
|
||||||
|
{ column: "description", getter: (actor, context) => Mapping.getDescription(actor) },
|
||||||
|
{ column: "armure", getter: (actor, context) => Mapping.getArmure(actor, context) },
|
||||||
|
{ column: "protection", getter: (actor, context) => Mapping.getProtectionArmure(actor, context) },
|
||||||
|
{ column: "malus-armure", getter: (actor, context) => Mapping.getMalusArmure(actor, context) },
|
||||||
|
{ column: "esquive", getter: (actor, context) => Mapping.getEsquive(actor, context) },
|
||||||
|
{ column: "esquive-niv", getter: (actor, context) => Mapping.getEsquiveNiveau(context) },
|
||||||
|
{ column: "competences", getter: (actor, context) => Mapping.getCompetences(actor, CATEGORIES_COMPETENCES) },
|
||||||
|
{ column: "draconic", getter: (actor, context) => Mapping.getCompetences(actor, CATEGORIES_DRACONIC) },
|
||||||
|
]
|
||||||
|
|
||||||
|
const MAPPING_ARMES = TABLEAU_ARMES.map(i => ColumnMappingFactory.createMappingArme('name', i))
|
||||||
|
.concat(TABLEAU_ARMES.map(i => ColumnMappingFactory.createMappingArme('niveau', i)))
|
||||||
|
.concat(TABLEAU_ARMES.map(i => ColumnMappingFactory.createMappingArme('init', i)))
|
||||||
|
.concat(TABLEAU_ARMES.map(i => ColumnMappingFactory.createMappingArme('dom', i)))
|
||||||
|
const MAPPING_SORTS = TABLEAU_SORTS.map(i => ColumnMappingFactory.createMappingSort('voie', i))
|
||||||
|
.concat(TABLEAU_SORTS.map(i => ColumnMappingFactory.createMappingSort('description', i)))
|
||||||
|
.concat(TABLEAU_SORTS.map(i => ColumnMappingFactory.createMappingSort('bonus', i)))
|
||||||
|
const MAPPING = MAPPING_BASE
|
||||||
|
.concat(MAPPING_ARMES)
|
||||||
|
.concat(MAPPING_SORTS)
|
||||||
|
|
||||||
|
export class Mapping {
|
||||||
|
|
||||||
|
static getMapping() {
|
||||||
|
return MAPPING
|
||||||
|
}
|
||||||
|
|
||||||
|
static prepareContext(actor) {
|
||||||
|
return {
|
||||||
|
armes: Mapping.prepareArmes(actor),
|
||||||
|
armure: Mapping.prepareArmure(actor),
|
||||||
|
esquive: Mapping.prepareEsquive(actor),
|
||||||
|
sorts: Mapping.prepareSorts(actor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static prepareArmes(actor) {
|
||||||
|
return actor.items.filter(it => it.type == ITEM_TYPES.arme)
|
||||||
|
.map(arme => {
|
||||||
|
const compToUse = RdDItemArme.getCompetenceArme(arme, 'competence');
|
||||||
|
const comp = actor.getCompetence(compToUse);
|
||||||
|
const bonusDom = Mapping.calculBonusDom(comp, actor)
|
||||||
|
return {
|
||||||
|
name: arme.name,
|
||||||
|
niveau: comp.system.niveau,
|
||||||
|
init: Mapping.calculBaseInit(actor, comp.system.categorie) + comp.system.niveau,
|
||||||
|
dom: Number(arme.system.dommages) + bonusDom
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
static calculBonusDom(comp, actor) {
|
||||||
|
// TODO: reuse dmg calc?
|
||||||
|
const appliesBonusDom = ['melee', 'lancer'].includes(comp.system.categorie)
|
||||||
|
return appliesBonusDom ? Number(actor.system.attributs.plusdom.value) : 0
|
||||||
|
}
|
||||||
|
|
||||||
|
static calculBaseInit(actor, categorie) {
|
||||||
|
// TODO: reuse init calc?
|
||||||
|
const mapping = MAPPING_BASE.find(it => it.column == categorie)
|
||||||
|
if (mapping) {
|
||||||
|
switch (categorie) {
|
||||||
|
case 'melee':
|
||||||
|
case 'tir':
|
||||||
|
case 'lancer':
|
||||||
|
const caracteristique = Number(actor.system.carac[categorie].value)
|
||||||
|
return Math.floor(caracteristique / 2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
static prepareArmure(actor) {
|
||||||
|
const armures = actor.itemTypes[ITEM_TYPES.armure].filter(it => it.system.equipe)
|
||||||
|
if (armures.length > 1) {
|
||||||
|
console.warn(`${actor.name} a équipé ${armures.length} armures, seule la première sera considérée`)
|
||||||
|
}
|
||||||
|
if (armures.length > 0) {
|
||||||
|
const armure = armures[0]
|
||||||
|
return {
|
||||||
|
name: armure.name,
|
||||||
|
protection: armure.system.protection,
|
||||||
|
malus: armure.system.malus ?? 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
name: '',
|
||||||
|
protection: actor.system.attributs.protection.value,
|
||||||
|
malus: 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static prepareEsquive(actor) {
|
||||||
|
const esquives = actor.getCompetences("Esquive")
|
||||||
|
if (esquives.length > 0) {
|
||||||
|
const esquive = esquives[0]
|
||||||
|
return {
|
||||||
|
name: esquive.name,
|
||||||
|
niveau: esquive.system.niveau
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
|
||||||
|
static prepareSorts(actor) {
|
||||||
|
return actor.itemTypes[ITEM_TYPES.sort].map(it => {
|
||||||
|
return {
|
||||||
|
voie: it.system.voie,
|
||||||
|
description: Mapping.descriptionSort(it),
|
||||||
|
bonus: Mapping.bonusCase(it)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
static descriptionSort(sort) {
|
||||||
|
const ptSeuil = Array(sort.system.coutseuil).map(it => '*')
|
||||||
|
const caseTMR = sort.system.caseTMRspeciale.length > 0 ? sort.system.caseTMRspeciale : sort.system.caseTMR
|
||||||
|
return `${sort.name}${ptSeuil} (${caseTMR}) R${sort.system.difficulte} r${sort.system.ptreve}`
|
||||||
|
}
|
||||||
|
|
||||||
|
static bonusCase(sort) {
|
||||||
|
const list = RdDItemSort.buildBonusCaseList(sort.system.bonuscase, false).sort(Misc.descending(it => it.bonus))
|
||||||
|
if (list.length > 0) {
|
||||||
|
const bonus = list[0]
|
||||||
|
return `+${bonus.bonus}% en ${bonus.case}`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static getDescription(actor) {
|
||||||
|
const sexe = actor.system.sexe
|
||||||
|
const sexeFeminin = sexe.length > 0 && sexe.charAt(0).toLowerCase() == 'f' ? 'Née' : 'Né'
|
||||||
|
const race = ['', 'humain'].includes(Grammar.toLowerCaseNoAccent(actor.system.race)) ? '' : (actor.system.race + ' ')
|
||||||
|
const heure = actor.system.heure
|
||||||
|
const hn = `${sexeFeminin} à l'heure ${RdDTimestamp.definition(heure).avecArticle}`
|
||||||
|
const age = actor.system.age ? `${actor.system.age} ans` : undefined
|
||||||
|
const taille = actor.system.taille
|
||||||
|
const poids = actor.system.poids
|
||||||
|
const cheveux = actor.system.cheveux ? `cheveux ${actor.system.cheveux}` : undefined
|
||||||
|
const yeux = actor.system.yeux ? `yeux ${actor.system.yeux}` : undefined
|
||||||
|
const beaute = actor.system.beaute ? `Beauté ${actor.system.beaute}` : undefined
|
||||||
|
const list = [race, hn, age, taille, poids, cheveux, yeux, beaute]
|
||||||
|
return Misc.join(list.filter(it => it), ', ')
|
||||||
|
}
|
||||||
|
|
||||||
|
static getArmure(actor, context) {
|
||||||
|
return context.armure?.name ?? ''
|
||||||
|
}
|
||||||
|
|
||||||
|
static getProtectionArmure(actor, context) {
|
||||||
|
return Number(context?.armure?.protection ?? 0) + Number(actor.system.attributs.protection.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
static getMalusArmure(actor, context) {
|
||||||
|
return context?.armure?.malus ?? 0
|
||||||
|
}
|
||||||
|
|
||||||
|
static getEsquive(actor, context) {
|
||||||
|
return context.esquive?.name ?? ''
|
||||||
|
}
|
||||||
|
|
||||||
|
static getEsquiveNiveau(context) {
|
||||||
|
if (context.esquive) {
|
||||||
|
const niveau = context.esquive.niveau + context.armure.malus
|
||||||
|
return niveau > 0 ? ('+' + niveau) : ('' + niveau)
|
||||||
|
}
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
|
||||||
|
static getCompetences(actor, categories) {
|
||||||
|
const competences = Mapping.getCompetencesCategorie(actor, categories)
|
||||||
|
if (competences.length == 0) {
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
const byCartegories = Mapping.competencesByCategoriesByNiveau(competences, categories)
|
||||||
|
const txtByCategories = Object.values(byCartegories)
|
||||||
|
.map(it => it.competencesParNiveau)
|
||||||
|
.map(byNiveau => {
|
||||||
|
const niveaux = Object.keys(byNiveau).map(it => Number(it)).sort(Misc.ascending())
|
||||||
|
if (niveaux.length == 0) {
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
const txtCategorieByNiveau = niveaux.map(niveau => {
|
||||||
|
const names = Misc.join(byNiveau[niveau].map(it => it.name).sort(Misc.ascending()), ', ')
|
||||||
|
return names + ': ' + Misc.toSignedString(niveau)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
const txtCategorie = Misc.join(txtCategorieByNiveau, ' / ')
|
||||||
|
return txtCategorie
|
||||||
|
}).filter(it => it != '')
|
||||||
|
|
||||||
|
return Misc.join(txtByCategories, ' / ')
|
||||||
|
}
|
||||||
|
|
||||||
|
static competencesByCategoriesByNiveau(competences, categories) {
|
||||||
|
return categories.map(c => {
|
||||||
|
return {
|
||||||
|
categorie: c,
|
||||||
|
competencesParNiveau: Misc.classify(
|
||||||
|
competences.filter(comp => comp.system.categorie == c),
|
||||||
|
comp => comp.system.niveau)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
static getArme(actor, context, part, numero) {
|
||||||
|
if (numero < context.armes.length) {
|
||||||
|
return context.armes[numero][part] ?? ''
|
||||||
|
}
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
|
||||||
|
static getCompetencesCategorie(actor, categories) {
|
||||||
|
return actor.itemTypes[ITEM_TYPES.competence]
|
||||||
|
.filter(it => categories.includes(it.system.categorie))
|
||||||
|
.filter(it => !RdDItemCompetence.isNiveauBase(it))
|
||||||
|
}
|
||||||
|
|
||||||
|
static getSort(actor, context, part, numero) {
|
||||||
|
if (numero < context.sorts.length) {
|
||||||
|
return context.sorts[numero][part]
|
||||||
|
}
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -65,6 +65,8 @@ import { AutoAdjustDarkness as AutoAdjustDarkness } from "./time/auto-adjust-dar
|
|||||||
import { RdDCreature } from "./actor/creature.js"
|
import { RdDCreature } from "./actor/creature.js"
|
||||||
import { RdDTMRDialog } from "./rdd-tmr-dialog.js"
|
import { RdDTMRDialog } from "./rdd-tmr-dialog.js"
|
||||||
import { RdDActorExportSheet } from "./actor/actor-export-sheet.js"
|
import { RdDActorExportSheet } from "./actor/actor-export-sheet.js"
|
||||||
|
import { OptionsAvancees } from "./settings/options-avancees.js"
|
||||||
|
import { ExportScriptarium } from "./actor/export-scriptarium/export-scriptarium.js"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* RdD system
|
* RdD system
|
||||||
@ -197,6 +199,7 @@ export class SystemReveDeDragon {
|
|||||||
SystemCompendiums.init()
|
SystemCompendiums.init()
|
||||||
DialogChronologie.init()
|
DialogChronologie.init()
|
||||||
ReglesOptionnelles.init()
|
ReglesOptionnelles.init()
|
||||||
|
OptionsAvancees.init()
|
||||||
RdDUtility.init()
|
RdDUtility.init()
|
||||||
RdDDice.init()
|
RdDDice.init()
|
||||||
RdDCommands.init()
|
RdDCommands.init()
|
||||||
@ -211,6 +214,7 @@ export class SystemReveDeDragon {
|
|||||||
RdDPossession.init()
|
RdDPossession.init()
|
||||||
TMRRencontres.init()
|
TMRRencontres.init()
|
||||||
Environnement.init()
|
Environnement.init()
|
||||||
|
ExportScriptarium.init()
|
||||||
}
|
}
|
||||||
|
|
||||||
initSystemSettings() {
|
initSystemSettings() {
|
||||||
|
91
module/settings/options-avancees.js
Normal file
91
module/settings/options-avancees.js
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
import { SYSTEM_RDD } from "../constants.js"
|
||||||
|
import { Misc } from "../misc.js"
|
||||||
|
|
||||||
|
export const EXPORT_CSV_SCRIPTARIUM = 'export-csv-scriptarium'
|
||||||
|
|
||||||
|
const OPTIONS_AVANCEES = [
|
||||||
|
{ group: 'Menus', name: EXPORT_CSV_SCRIPTARIUM, descr: "Proposer le menu d'export csv Scriptarium (raffraichissement requis)" },
|
||||||
|
]
|
||||||
|
|
||||||
|
export class OptionsAvancees extends FormApplication {
|
||||||
|
static init() {
|
||||||
|
for (const regle of OPTIONS_AVANCEES) {
|
||||||
|
const name = regle.name
|
||||||
|
const id = OptionsAvancees._getId(name)
|
||||||
|
game.settings.register(SYSTEM_RDD, id, { name: id, scope: regle.scope ?? "world", config: false, default: regle.default == undefined ? true : regle.default, type: Boolean })
|
||||||
|
}
|
||||||
|
|
||||||
|
game.settings.registerMenu(SYSTEM_RDD, "rdd-options-avancees", {
|
||||||
|
name: "Configurer les options avancées",
|
||||||
|
label: "Options avancées",
|
||||||
|
hint: "Ouvre la fenêtre de configuration des options avancées",
|
||||||
|
icon: "fas fa-bars",
|
||||||
|
type: OptionsAvancees
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(...args) {
|
||||||
|
super(...args)
|
||||||
|
}
|
||||||
|
|
||||||
|
static _getId(name) {
|
||||||
|
return `rdd-advanced-${name}`
|
||||||
|
}
|
||||||
|
|
||||||
|
static get defaultOptions() {
|
||||||
|
return foundry.utils.mergeObject(super.defaultOptions, {
|
||||||
|
id: "options-avancees",
|
||||||
|
template: "systems/foundryvtt-reve-de-dragon/templates/settings/options-avancees.hbs",
|
||||||
|
height: 650,
|
||||||
|
width: 550,
|
||||||
|
minimizable: false,
|
||||||
|
closeOnSubmit: true,
|
||||||
|
title: "Options avancées"
|
||||||
|
}, { inplace: false })
|
||||||
|
}
|
||||||
|
|
||||||
|
getData() {
|
||||||
|
let formData = super.getData()
|
||||||
|
const regles = OPTIONS_AVANCEES.filter(it => game.user.isGM || it.scope == "client")
|
||||||
|
.map(it => {
|
||||||
|
it = foundry.utils.duplicate(it)
|
||||||
|
it.id = OptionsAvancees._getId(it.name)
|
||||||
|
it.active = OptionsAvancees.isSet(it.name)
|
||||||
|
return it
|
||||||
|
})
|
||||||
|
formData.regles = regles
|
||||||
|
formData.groups = Misc.classify(regles, it => it.group)
|
||||||
|
return formData
|
||||||
|
}
|
||||||
|
|
||||||
|
static getSettingKey(name){
|
||||||
|
return `${SYSTEM_RDD}.${this._getId(name)}`
|
||||||
|
}
|
||||||
|
|
||||||
|
static isUsing(name) {
|
||||||
|
return OptionsAvancees.isSet(name)
|
||||||
|
}
|
||||||
|
|
||||||
|
static isSet(name) {
|
||||||
|
return game.settings.get(SYSTEM_RDD, OptionsAvancees._getId(name))
|
||||||
|
}
|
||||||
|
|
||||||
|
static set(name, value) {
|
||||||
|
return game.settings.set(SYSTEM_RDD, OptionsAvancees._getId(name), value ? true : false)
|
||||||
|
}
|
||||||
|
|
||||||
|
activateListeners(html) {
|
||||||
|
html.find(".select-option").click((event) => {
|
||||||
|
if (event.currentTarget.attributes.name) {
|
||||||
|
let id = event.currentTarget.attributes.name.value
|
||||||
|
let isChecked = event.currentTarget.checked
|
||||||
|
game.settings.set(SYSTEM_RDD, id, isChecked)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
async _updateObject(event, formData) {
|
||||||
|
this.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -15,18 +15,18 @@ export const RDD_MINUTES_PAR_JOUR = 1440; //RDD_HEURES_PAR_JOUR * RDD_MINUTES_PA
|
|||||||
const ROUNDS_PAR_MINUTE = 10;
|
const ROUNDS_PAR_MINUTE = 10;
|
||||||
|
|
||||||
const DEFINITION_HEURES = [
|
const DEFINITION_HEURES = [
|
||||||
{ key: "vaisseau", label: "Vaisseau", lettreFont: 'v', saison: "Printemps", darkness: 0.9 },
|
{ key: "vaisseau", article: "du ", label: "Vaisseau", lettreFont: 'v', saison: "Printemps", darkness: 0.9 },
|
||||||
{ key: "sirene", label: "Sirène", lettreFont: 'i', saison: "Printemps", darkness: 0.1 },
|
{ key: "sirene", article: "de la ", label: "Sirène", lettreFont: 'i', saison: "Printemps", darkness: 0.1 },
|
||||||
{ key: "faucon", label: "Faucon", lettreFont: 'f', saison: "Printemps", darkness: 0 },
|
{ key: "faucon", article: "du ", label: "Faucon", lettreFont: 'f', saison: "Printemps", darkness: 0 },
|
||||||
{ key: "couronne", label: "Couronne", lettreFont: '', saison: "Eté", darkness: 0 },
|
{ key: "couronne", article: "de la ", label: "Couronne", lettreFont: '', saison: "Eté", darkness: 0 },
|
||||||
{ key: "dragon", label: "Dragon", lettreFont: 'd', saison: "Eté", darkness: 0 },
|
{ key: "dragon", article: "du ", label: "Dragon", lettreFont: 'd', saison: "Eté", darkness: 0 },
|
||||||
{ key: "epees", label: "Epées", lettreFont: 'e', saison: "Eté", darkness: 0 },
|
{ key: "epees", article: "des ", label: "Epées", lettreFont: 'e', saison: "Eté", darkness: 0 },
|
||||||
{ key: "lyre", label: "Lyre", lettreFont: 'l', saison: "Automne", darkness: 0.1 },
|
{ key: "lyre", article: "de la ", label: "Lyre", lettreFont: 'l', saison: "Automne", darkness: 0.1 },
|
||||||
{ key: "serpent", label: "Serpent", lettreFont: 's', saison: "Automne", darkness: 0.9 },
|
{ key: "serpent", article: "du ", label: "Serpent", lettreFont: 's', saison: "Automne", darkness: 0.9 },
|
||||||
{ key: "poissonacrobate", label: "Poisson Acrobate", lettreFont: 'p', saison: "Automne", darkness: 1 },
|
{ key: "poissonacrobate", article: "du ", label: "Poisson Acrobate", lettreFont: 'p', saison: "Automne", darkness: 1 },
|
||||||
{ key: "araignee", label: "Araignée", lettreFont: 'a', saison: "Hiver", darkness: 1 },
|
{ key: "araignee", article: "de l'", label: "Araignée", lettreFont: 'a', saison: "Hiver", darkness: 1 },
|
||||||
{ key: "roseau", label: "Roseau", lettreFont: 'r', saison: "Hiver", darkness: 1 },
|
{ key: "roseau", article: "du ", label: "Roseau", lettreFont: 'r', saison: "Hiver", darkness: 1 },
|
||||||
{ key: "chateaudormant", label: "Château Dormant", lettreFont: 'c', saison: "Hiver", darkness: 1 },
|
{ key: "chateaudormant", article: "du ", label: "Château Dormant", lettreFont: 'c', saison: "Hiver", darkness: 1 },
|
||||||
]
|
]
|
||||||
|
|
||||||
const FORMULES_DUREE = [
|
const FORMULES_DUREE = [
|
||||||
@ -64,6 +64,7 @@ export class RdDTimestamp {
|
|||||||
DEFINITION_HEURES[i].hh = RdDTimestamp.hh(i);
|
DEFINITION_HEURES[i].hh = RdDTimestamp.hh(i);
|
||||||
DEFINITION_HEURES[i].icon = RdDTimestamp.iconeHeure(i);
|
DEFINITION_HEURES[i].icon = RdDTimestamp.iconeHeure(i);
|
||||||
DEFINITION_HEURES[i].webp = DEFINITION_HEURES[i].icon.replace(".svg", ".webp");
|
DEFINITION_HEURES[i].webp = DEFINITION_HEURES[i].icon.replace(".svg", ".webp");
|
||||||
|
DEFINITION_HEURES[i].avecArticle = DEFINITION_HEURES[i].article + DEFINITION_HEURES[i].label
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -241,7 +242,7 @@ export class RdDTimestamp {
|
|||||||
|
|
||||||
get darkness() {
|
get darkness() {
|
||||||
const darknessDebut = 100 * RdDTimestamp.definition(this.heure).darkness
|
const darknessDebut = 100 * RdDTimestamp.definition(this.heure).darkness
|
||||||
const darknessFin = 100 * RdDTimestamp.definition(this.heure + 1).darkness
|
const darknessFin = 100 * RdDTimestamp.definition(this.heure + 1).darkness
|
||||||
const darknessMinute = Math.round((darknessFin - darknessDebut) * this.minute / RDD_MINUTES_PAR_HEURES);
|
const darknessMinute = Math.round((darknessFin - darknessDebut) * this.minute / RDD_MINUTES_PAR_HEURES);
|
||||||
return (darknessDebut + darknessMinute) / 100
|
return (darknessDebut + darknessMinute) / 100
|
||||||
}
|
}
|
||||||
|
65
styles/img/ui/scriptarium.svg
Normal file
65
styles/img/ui/scriptarium.svg
Normal file
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 56 KiB |
@ -572,6 +572,15 @@ input:is(.blessure-premiers_soins, .blessure-soins_complets) {
|
|||||||
border: none;
|
border: none;
|
||||||
padding: 0.1rem;
|
padding: 0.1rem;
|
||||||
}
|
}
|
||||||
|
.context-menu-img {
|
||||||
|
max-width: 2rem;
|
||||||
|
max-height: 1rem;
|
||||||
|
flex-grow: 0;
|
||||||
|
margin: 0.2rem 0.3rem 0 0;
|
||||||
|
vertical-align: middle;
|
||||||
|
border: none;
|
||||||
|
padding: 0rem;
|
||||||
|
}
|
||||||
|
|
||||||
.button-img {
|
.button-img {
|
||||||
vertical-align: baseline;
|
vertical-align: baseline;
|
||||||
|
13
templates/settings/options-avancees.hbs
Normal file
13
templates/settings/options-avancees.hbs
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<form autocomplete="off" onsubmit="event.preventDefault();">
|
||||||
|
{{#each groups as |group key|}}
|
||||||
|
<h3>{{key}}</h3>
|
||||||
|
<ul>
|
||||||
|
{{#each group as |regle r|}}
|
||||||
|
<li>
|
||||||
|
<input class="select-option" type="checkbox" name="{{regle.id}}" {{#if regle.active}}checked{{/if}}/>
|
||||||
|
<label>{{regle.descr}}</label>
|
||||||
|
</li>
|
||||||
|
{{/each}}
|
||||||
|
</ul>
|
||||||
|
{{/each}}
|
||||||
|
</form>
|
Loading…
Reference in New Issue
Block a user