diff --git a/changelog.md b/changelog.md
index f830ae20..f1dab016 100644
--- a/changelog.md
+++ b/changelog.md
@@ -1,4 +1,7 @@
# 12.0
+## 12.0.9 - Le scriptorium d'Astrobazzarh
+- ajout d'une fonction avancée pour exporter les personnages dans un format csv
+
## 12.0.8 - La quincaillerie d'Astrobazzarh
- le propriétaire est indiqué dans les feuilles d'équipements/compétences/...
- Ecaille d'efficacité
diff --git a/module/actor.js b/module/actor.js
index e8c87a07..50666844 100644
--- a/module/actor.js
+++ b/module/actor.js
@@ -32,7 +32,7 @@ import { RdDItemBlessure } from "./item/blessure.js";
import { AppAstrologie } from "./sommeil/app-astrologie.js";
import { RdDEmpoignade } from "./rdd-empoignade.js";
import { ExperienceLog, XP_TOPIC } from "./actor/experience-log.js";
-import { TYPES } from "./item.js";
+import { ITEM_TYPES } from "./item.js";
import { RdDBaseActorSang } from "./actor/base-actor-sang.js";
import { RdDCoeur } from "./coeur/rdd-coeur.js";
import { DialogChoixXpCarac } from "./dialog-choix-xp-carac.js";
@@ -92,7 +92,7 @@ export class RdDActor extends RdDBaseActorSang {
/* -------------------------------------------- */
canReceive(item) {
- return ![TYPES.competencecreature, TYPES.tarot, TYPES.service].includes(item.type)
+ return ![ITEM_TYPES.competencecreature, ITEM_TYPES.tarot, ITEM_TYPES.service].includes(item.type)
}
isPersonnageJoueur() {
@@ -125,7 +125,7 @@ export class RdDActor extends RdDBaseActorSang {
/* -------------------------------------------- */
getMalusArmure() {
- return this.itemTypes[TYPES.armure].filter(it => it.system.equipe)
+ return this.itemTypes[ITEM_TYPES.armure].filter(it => it.system.equipe)
.map(it => it.system.malus)
.reduce(Misc.sum(), 0);
}
@@ -142,7 +142,7 @@ export class RdDActor extends RdDBaseActorSang {
/* -------------------------------------------- */
getDemiReve() { return this.system.reve.tmrpos.coord }
- getDraconicList() { return this.itemTypes[TYPES.competence].filter(it => it.system.categorie == 'draconic') }
+ getDraconicList() { return this.itemTypes[ITEM_TYPES.competence].filter(it => it.system.categorie == 'draconic') }
getBestDraconic() { return foundry.utils.duplicate(this.getDraconicList().sort(Misc.descending(it => it.system.niveau)).find(it => true)) }
getDraconicOuPossession() {
return [...this.getDraconicList().filter(it => it.system.niveau >= 0),
@@ -153,7 +153,7 @@ export class RdDActor extends RdDBaseActorSang {
/* -------------------------------------------- */
async $perteRevePotionsEnchantees() {
- let potions = this.itemTypes[TYPES.potion]
+ let potions = this.itemTypes[ITEM_TYPES.potion]
.filter(it => Grammar.includesLowerCaseNoAccent(it.system.categorie, 'enchanté') && !it.system.prpermanent)
const potionUpdates = await Promise.all(potions.map(async it => {
@@ -345,7 +345,7 @@ export class RdDActor extends RdDBaseActorSang {
/* -------------------------------------------- */
async _recupererBlessures(message, isMaladeEmpoisonne) {
const timestamp = game.system.rdd.calendrier.getTimestamp()
- const blessures = this.filterItems(it => it.system.gravite > 0, TYPES.blessure).sort(Misc.ascending(it => it.system.gravite))
+ const blessures = this.filterItems(it => it.system.gravite > 0, ITEM_TYPES.blessure).sort(Misc.ascending(it => it.system.gravite))
await Promise.all(blessures.map(async b => b.recuperationBlessure({
actor: this,
@@ -361,7 +361,7 @@ export class RdDActor extends RdDBaseActorSang {
/* -------------------------------------------- */
async _recupererVie(message, isMaladeEmpoisonne) {
const tData = this.system
- let blessures = this.filterItems(it => it.system.gravite > 0, TYPES.blessure);
+ let blessures = this.filterItems(it => it.system.gravite > 0, ITEM_TYPES.blessure);
if (blessures.length > 0) {
return
}
@@ -636,7 +636,7 @@ export class RdDActor extends RdDBaseActorSang {
/* -------------------------------------------- */
async sortMisEnReserve(sort, draconic, coord, ptreve) {
await this.createEmbeddedDocuments("Item", [{
- type: TYPES.sortreserve,
+ type: ITEM_TYPES.sortreserve,
name: sort.name,
img: sort.img,
system: { sortid: sort._id, draconic: (draconic?.name ?? sort.system.draconic), ptreve: ptreve, coord: coord, heurecible: 'Vaisseau' }
@@ -991,24 +991,24 @@ export class RdDActor extends RdDBaseActorSang {
/* -------------------------------------------- */
buildTMRInnaccessible() {
- return this.items.filter(it => it.type == TYPES.casetmr).filter(it => EffetsDraconiques.isInnaccessible(it)).map(it => it.system.coord)
+ return this.items.filter(it => it.type == ITEM_TYPES.casetmr).filter(it => EffetsDraconiques.isInnaccessible(it)).map(it => it.system.coord)
}
/* -------------------------------------------- */
getRencontresTMR() {
- return this.itemTypes[TYPES.rencontre];
+ return this.itemTypes[ITEM_TYPES.rencontre];
}
/* -------------------------------------------- */
async deleteRencontreTMRAtPosition() {
- const rencontreIds = this.itemTypes[TYPES.rencontre].filter(this.filterRencontreTMRDemiReve()).map(it => it.id)
+ const rencontreIds = this.itemTypes[ITEM_TYPES.rencontre].filter(this.filterRencontreTMRDemiReve()).map(it => it.id)
if (rencontreIds.length > 0) {
await this.deleteEmbeddedDocuments('Item', rencontreIds)
}
}
getRencontreTMREnAttente() {
- return this.itemTypes[TYPES.rencontre].find(this.filterRencontreTMRDemiReve())
+ return this.itemTypes[ITEM_TYPES.rencontre].find(this.filterRencontreTMRDemiReve())
}
filterRencontreTMRDemiReve() {
@@ -1160,11 +1160,11 @@ export class RdDActor extends RdDBaseActorSang {
if (result) { return result }
switch (item.type) {
- case TYPES.potion: return await this.consommerPotion(item, onActionItem);
- case TYPES.livre: return await this.actionLire(item);
- case TYPES.conteneur: return await item.sheet.render(true);
- case TYPES.herbe: return await this.actionHerbe(item, onActionItem);
- case TYPES.queue: case TYPES.ombre: return await this.actionRefoulement(item);
+ case ITEM_TYPES.potion: return await this.consommerPotion(item, onActionItem);
+ case ITEM_TYPES.livre: return await this.actionLire(item);
+ case ITEM_TYPES.conteneur: return await item.sheet.render(true);
+ case ITEM_TYPES.herbe: return await this.actionHerbe(item, onActionItem);
+ case ITEM_TYPES.queue: case ITEM_TYPES.ombre: return await this.actionRefoulement(item);
}
return undefined
}
@@ -1559,7 +1559,7 @@ export class RdDActor extends RdDBaseActorSang {
xpData
})
if (hideChatMessage) {
- ChatUtility.blindMessageToGM({ content: content });
+ ChatUtility.blindMessageToGM({ content: content })
}
else {
ChatMessage.create({
@@ -1602,7 +1602,7 @@ export class RdDActor extends RdDBaseActorSang {
computeDraconicAndSortIndex(sortList) {
let draconicList = this.getDraconicList();
for (let sort of sortList) {
- let draconicsSort = this.getDraconicsSort(draconicList, sort).map(it => it.name);
+ let draconicsSort = RdDItemSort.getDraconicsSort(draconicList, sort).map(it => it.name);
for (let index = 0; index < draconicList.length && sort.system.listIndex == undefined; index++) {
if (draconicsSort.includes(draconicList[index].name)) {
sort.system.listIndex = index;
@@ -1612,19 +1612,6 @@ export class RdDActor extends RdDBaseActorSang {
return draconicList;
}
- /* -------------------------------------------- */
- getDraconicsSort(draconicList, sort) {
- //console.log(draconicList, bestDraconic, draconic, voie);
- switch (Grammar.toLowerCaseNoAccent(sort.name)) {
- case "lecture d'aura":
- case "detection d'aura":
- return draconicList;
- case "annulation de magie":
- return draconicList.filter(it => !RdDItemCompetence.isThanatos(it));
- }
- return [RdDItemCompetence.getVoieDraconic(draconicList, sort.system.draconic)];
- }
-
/* -------------------------------------------- */
async rollUnSort(coord) {
RdDEmpoignade.checkEmpoignadeEnCours(this)
@@ -1826,7 +1813,7 @@ export class RdDActor extends RdDBaseActorSang {
}
blessuresASoigner() {
- return (this.itemTypes[TYPES.blessure])
+ return (this.itemTypes[ITEM_TYPES.blessure])
.filter(it => it.system.gravite > 0 && it.system.gravite <= 6)
.filter(it => !(it.system.premierssoins.done && it.system.soinscomplets.done))
.sort(Misc.descending(b => (b.system.premierssoins.done ? "A" : "B") + b.system.gravite))
@@ -3065,7 +3052,7 @@ export class RdDActor extends RdDBaseActorSang {
async nouvelleIncarnation() {
let incarnation = this.toObject();
- incarnation.items = Array.from(this.items.filter(it => it.type == TYPES.competence),
+ incarnation.items = Array.from(this.items.filter(it => it.type == ITEM_TYPES.competence),
it => {
it = it.toObject();
it.id = undefined;
diff --git a/module/actor/base-actor-reve.js b/module/actor/base-actor-reve.js
index 7938e58a..60ebb6f1 100644
--- a/module/actor/base-actor-reve.js
+++ b/module/actor/base-actor-reve.js
@@ -12,7 +12,7 @@ import { ReglesOptionnelles } from "../settings/regles-optionnelles.js";
import { RdDBaseActor } from "./base-actor.js";
import { RdDItemCompetenceCreature } from "../item-competencecreature.js";
import { StatusEffects } from "../settings/status-effects.js";
-import { TYPES } from "../item.js";
+import { ITEM_TYPES } from "../item.js";
import { Targets } from "../targets.js";
import { RdDPossession } from "../rdd-possession.js";
import { RdDCombat } from "../rdd-combat.js";
@@ -108,14 +108,14 @@ export class RdDBaseActorReve extends RdDBaseActor {
async $finDeRoundSupprimerObsoletes() {
const obsoletes = []
- .concat(this.itemTypes[TYPES.empoignade].filter(it => it.system.pointsemp <= 0))
- .concat(this.itemTypes[TYPES.possession].filter(it => it.system.compteur < -2 || it.system.compteur > 2))
+ .concat(this.itemTypes[ITEM_TYPES.empoignade].filter(it => it.system.pointsemp <= 0))
+ .concat(this.itemTypes[ITEM_TYPES.possession].filter(it => it.system.compteur < -2 || it.system.compteur > 2))
.map(it => it.id);
await this.deleteEmbeddedDocuments('Item', obsoletes);
}
async $finDeRoundEmpoignade() {
- const immobilisations = this.itemTypes[TYPES.empoignade].filter(it => it.system.pointsemp >= 2 && it.system.empoigneurid == this.id);
+ const immobilisations = this.itemTypes[ITEM_TYPES.empoignade].filter(it => it.system.pointsemp >= 2 && it.system.empoigneurid == this.id);
immobilisations.forEach(emp => RdDEmpoignade.onImmobilisation(this,
game.actors.get(emp.system.empoigneid),
emp
@@ -151,13 +151,13 @@ export class RdDBaseActorReve extends RdDBaseActor {
}
getPossession(possessionId) {
- return this.itemTypes[TYPES.possession].find(it => it.system.possessionid == possessionId);
+ return this.itemTypes[ITEM_TYPES.possession].find(it => it.system.possessionid == possessionId);
}
getPossessions() {
- return this.itemTypes[TYPES.possession];
+ return this.itemTypes[ITEM_TYPES.possession];
}
getEmpoignades() {
- return this.itemTypes[TYPES.empoignade];
+ return this.itemTypes[ITEM_TYPES.empoignade];
}
/* -------------------------------------------- */
@@ -322,7 +322,7 @@ export class RdDBaseActorReve extends RdDBaseActor {
RdDEmpoignade.checkEmpoignadeEnCours(this)
const competence = this.getCompetence(idOrName);
let rollData = { carac: this.system.carac, competence: competence, arme: options.arme }
- if (competence.type == TYPES.competencecreature) {
+ if (competence.type == ITEM_TYPES.competencecreature) {
const arme = RdDItemCompetenceCreature.armeCreature(competence)
if (arme && options.tryTarget && Targets.hasTargets()) {
Targets.selectOneToken(target => {
@@ -396,19 +396,7 @@ export class RdDBaseActorReve extends RdDBaseActor {
}
$getCompetenceArme(arme, competenceName) {
- switch (arme.type) {
- case TYPES.competencecreature:
- return arme.name
- case TYPES.arme:
- switch (competenceName) {
- case 'competence': return arme.system.competence;
- case 'unemain': return RdDItemArme.competence1Mains(arme);
- case 'deuxmains': return RdDItemArme.competence2Mains(arme);
- case 'tir': return arme.system.tir;
- case 'lancer': return arme.system.lancer;
- }
- }
- return undefined
+ return RdDItemArme.getCompetenceArme(arme, competenceName)
}
verifierForceMin(item) {
diff --git a/module/actor/base-actor-sang.js b/module/actor/base-actor-sang.js
index 2131666f..1a4ad1e5 100644
--- a/module/actor/base-actor-sang.js
+++ b/module/actor/base-actor-sang.js
@@ -1,7 +1,7 @@
import { MAX_ENDURANCE_FATIGUE, RdDUtility } from "../rdd-utility.js";
import { ReglesOptionnelles } from "../settings/regles-optionnelles.js";
import { STATUSES } from "../settings/status-effects.js";
-import { TYPES } from "../item.js";
+import { ITEM_TYPES } from "../item.js";
import { RdDBaseActorReve } from "./base-actor-reve.js";
import { RdDDice } from "../rdd-dice.js";
import { RdDItemBlessure } from "../item/blessure.js";
@@ -50,9 +50,9 @@ export class RdDBaseActorSang extends RdDBaseActorReve {
isDead() { return this.system.sante.vie.value < -this.getSConst() }
- nbBlessuresLegeres() { return this.itemTypes[TYPES.blessure].filter(it => it.isLegere()).length }
- nbBlessuresGraves() { return this.itemTypes[TYPES.blessure].filter(it => it.isGrave()).length }
- nbBlessuresCritiques() { return this.itemTypes[TYPES.blessure].filter(it => it.isCritique()).length }
+ nbBlessuresLegeres() { return this.itemTypes[ITEM_TYPES.blessure].filter(it => it.isLegere()).length }
+ nbBlessuresGraves() { return this.itemTypes[ITEM_TYPES.blessure].filter(it => it.isGrave()).length }
+ nbBlessuresCritiques() { return this.itemTypes[ITEM_TYPES.blessure].filter(it => it.isCritique()).length }
/* -------------------------------------------- */
computeResumeBlessure() {
@@ -197,7 +197,7 @@ export class RdDBaseActorSang extends RdDBaseActorReve {
}
async supprimerBlessures(filterToDelete) {
- const toDelete = this.filterItems(filterToDelete, TYPES.blessure)
+ const toDelete = this.filterItems(filterToDelete, ITEM_TYPES.blessure)
.map(it => it.id);
await this.deleteEmbeddedDocuments('Item', toDelete);
}
diff --git a/module/actor/base-actor-sheet.js b/module/actor/base-actor-sheet.js
index 8af1c89e..c83106b7 100644
--- a/module/actor/base-actor-sheet.js
+++ b/module/actor/base-actor-sheet.js
@@ -3,7 +3,7 @@ import { Misc } from "../misc.js";
import { DialogSplitItem } from "../dialog-split-item.js";
import { RdDSheetUtility } from "../rdd-sheet-utility.js";
import { Monnaie } from "../item-monnaie.js";
-import { RdDItem, TYPES } from "../item.js";
+import { RdDItem, ITEM_TYPES } from "../item.js";
import { RdDItemCompetenceCreature } from "../item-competencecreature.js";
/* -------------------------------------------- */
@@ -51,7 +51,7 @@ export class RdDBaseActorSheet extends ActorSheet {
this.objetVersConteneur = RdDUtility.buildArbreDeConteneurs(formData.conteneurs, formData.inventaires);
this._appliquerRechercheObjets(formData.conteneurs, formData.inventaires);
formData.conteneurs = RdDUtility.conteneursRacine(formData.conteneurs);
- formData.competences.filter(it => it.type == TYPES.competencecreature)
+ formData.competences.filter(it => it.type == ITEM_TYPES.competencecreature)
.forEach(it => it.isdommages = RdDItemCompetenceCreature.isDommages(it))
return formData;
}
diff --git a/module/actor/base-actor.js b/module/actor/base-actor.js
index 4b35d754..228181ad 100644
--- a/module/actor/base-actor.js
+++ b/module/actor/base-actor.js
@@ -3,7 +3,7 @@ import { ChatUtility } from "../chat-utility.js";
import { SYSTEM_SOCKET_ID } from "../constants.js";
import { Grammar } from "../grammar.js";
import { Monnaie } from "../item-monnaie.js";
-import { TYPES } from "../item.js";
+import { ITEM_TYPES } from "../item.js";
import { Misc } from "../misc.js";
import { RdDAudio } from "../rdd-audio.js";
import { RdDConfirm } from "../rdd-confirm.js";
@@ -542,7 +542,7 @@ export class RdDBaseActor extends Actor {
// Calculer le total actuel des contenus
const encContenu = dest.getEncContenu();
const newEnc = moved.getEncTotal(); // Calculer le total actuel du nouvel objet
- const placeDisponible = Math.roundDecimals(dest.system.capacite - encContenu - newEnc, 4)
+ const placeDisponible = Misc.keepDecimals(dest.system.capacite - encContenu - newEnc, 4)
// Teste si le conteneur de destination a suffisament de capacité pour recevoir le nouvel objet
if (placeDisponible < 0) {
@@ -704,7 +704,7 @@ export class RdDBaseActor extends Actor {
async actionPrincipale(item, onActionItem = async () => { }) {
switch (item.type) {
- case TYPES.conteneur: return await item.sheet.render(true);
+ case ITEM_TYPES.conteneur: return await item.sheet.render(true);
}
return undefined
}
diff --git a/module/actor/creature.js b/module/actor/creature.js
index 67b36168..d0307e66 100644
--- a/module/actor/creature.js
+++ b/module/actor/creature.js
@@ -1,5 +1,5 @@
import { ENTITE_INCARNE } from "../constants.js";
-import { TYPES } from "../item.js";
+import { ITEM_TYPES } from "../item.js";
import { STATUSES } from "../settings/status-effects.js";
import { RdDBaseActorSang } from "./base-actor-sang.js";
@@ -12,7 +12,7 @@ export class RdDCreature extends RdDBaseActorSang {
isCreature() { return true }
canReceive(item) {
- return item.type == TYPES.competencecreature || item.isInventaire();
+ return item.type == ITEM_TYPES.competencecreature || item.isInventaire();
}
async remiseANeuf() {
diff --git a/module/actor/entite.js b/module/actor/entite.js
index ca63f334..70bc0577 100644
--- a/module/actor/entite.js
+++ b/module/actor/entite.js
@@ -1,5 +1,5 @@
import { ENTITE_INCARNE, ENTITE_NONINCARNE } from "../constants.js";
-import { TYPES } from "../item.js";
+import { ITEM_TYPES } from "../item.js";
import { Misc } from "../misc.js";
import { RdDEncaisser } from "../rdd-roll-encaisser.js";
import { STATUSES } from "../settings/status-effects.js";
@@ -12,7 +12,7 @@ export class RdDEntite extends RdDBaseActorReve {
}
canReceive(item) {
- return item.type == TYPES.competencecreature
+ return item.type == ITEM_TYPES.competencecreature
}
isEntite(typeentite = []) {
@@ -29,7 +29,7 @@ export class RdDEntite extends RdDBaseActorReve {
getChance() { return this.getReve() }
getDraconicOuPossession() {
- return this.itemTypes[TYPES.competencecreature]
+ return this.itemTypes[ITEM_TYPES.competencecreature]
.filter(it => it.system.categorie == 'possession')
.sort(Misc.descending(it => it.system.niveau))
.find(it => true);
diff --git a/module/actor/export-scriptarium/export-scriptarium.js b/module/actor/export-scriptarium/export-scriptarium.js
new file mode 100644
index 00000000..e6cd20ce
--- /dev/null
+++ b/module/actor/export-scriptarium/export-scriptarium.js
@@ -0,0 +1,80 @@
+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 = ''
+
+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), this.$getTargetName(actorDirectory, target))
+ })
+ }
+
+ $getTargetName(actorDirectory, target) {
+ const li = target.closest(".directory-item")
+ const folderId = li.data("folderId")
+ const actorId = li.data("documentId")
+ return actorId
+ ? game.actors.get(actorId).name
+ : actorDirectory.folders.find(it => it.id == folderId).name
+ }
+
+ $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, targetName) {
+ const eol = '\n'
+ const header = Misc.join(this.getHeaderLine(), ';')
+ const actorLines = actors.map(actor => Misc.join(this.getActorLine(actor), ';'))
+ const data = Misc.join([header, ...actorLines], eol)
+ const filename = `scriptatium-${targetName?.slugify()}.csv`;
+ saveDataToFile(data, "text/csv", `${filename}`);
+ }
+
+ 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 => JSON.stringify(it))
+ .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
+ }
+}
diff --git a/module/actor/export-scriptarium/mapping.js b/module/actor/export-scriptarium/mapping.js
new file mode 100644
index 00000000..e667d81b
--- /dev/null
+++ b/module/actor/export-scriptarium/mapping.js
@@ -0,0 +1,308 @@
+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 { RdDBonus } from "../../rdd-bonus.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.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('dommages', 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) {
+ const armes = actor.items.filter(it => it.type == ITEM_TYPES.arme)
+ return armes.map(arme =>
+ [
+ arme.system.tir != "" ? Mapping.prepareArme(actor, arme, 'tir') : undefined,
+ arme.system.lancer = "" ? Mapping.prepareArme(actor, arme, 'lancer') : undefined,
+ arme.system.unemain ? Mapping.prepareArme(actor, arme, 'unemain') : undefined,
+ arme.system.deuxmains ? Mapping.prepareArme(actor, arme, 'deuxmains') : undefined,
+ !(arme.system.unemain || arme.system.deuxmains) ? Mapping.prepareArme(actor, arme, 'competence') : undefined
+ ]
+ .filter(it => it != undefined)
+ ).reduce((a, b) => a.concat(b), [])
+ }
+
+ static prepareArme(actor, arme, maniement) {
+ const nameCompArme = RdDItemArme.getCompetenceArme(arme, maniement)
+ const competence = actor.getCompetence(nameCompArme)
+ if (RdDItemCompetence.isNiveauBase(competence)) {
+ return undefined
+ }
+ const dmgArme = RdDItemArme.dommagesReels(arme, maniement)
+ const dommages = dmgArme + RdDBonus.bonusDmg(actor, maniement, dmgArme)
+ return {
+ name: arme.name,
+ niveau: Misc.toSignedString(competence.system.niveau),
+ init: Mapping.calculBaseInit(actor, competence.system.categorie) + competence.system.niveau,
+ dommages: Misc.toSignedString(dommages)
+ }
+ }
+
+ static calculBaseInit(actor, categorie) {
+ 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: Misc.toSignedString(esquive.system.niveau)
+ }
+ }
+ return undefined
+ }
+
+ static prepareSorts(actor) {
+ return actor.itemTypes[ITEM_TYPES.sort].map(it => Mapping.prepareSort(it))
+ }
+
+ static prepareSort(sort) {
+ return {
+ voie: RdDItemSort.getCodeDraconic(sort),
+ description: Mapping.descriptionSort(sort),
+ bonus: Mapping.bonusCase(sort)
+ }
+ }
+
+ 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.bonuscaseStringToList(sort.system.bonuscase).sort(Misc.descending(it => it.bonus))
+ if (list.length > 0) {
+ const bonus = list[0]
+ return `+${bonus.bonus}% en ${bonus.case}`
+ }
+ return ''
+ }
+
+ 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 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 ''
+ }
+}
+
diff --git a/module/item-arme.js b/module/item-arme.js
index 695a2bde..25cb4dd4 100644
--- a/module/item-arme.js
+++ b/module/item-arme.js
@@ -1,5 +1,5 @@
import { RdDItemCompetenceCreature } from "./item-competencecreature.js"
-import { TYPES } from "./item.js";
+import { ITEM_TYPES } from "./item.js";
import { RdDCombatManager } from "./rdd-combat.js";
const nomCategorieParade = {
@@ -20,19 +20,35 @@ const nomCategorieParade = {
export class RdDItemArme extends Item {
static isArme(item) {
- return item.type == TYPES.arme || RdDItemCompetenceCreature.getCategorieAttaque(item);
+ return item.type == ITEM_TYPES.arme || RdDItemCompetenceCreature.getCategorieAttaque(item);
}
/* -------------------------------------------- */
static getArme(arme) {
switch (arme ? arme.type : '') {
- case TYPES.arme: return arme;
- case TYPES.competencecreature:
+ case ITEM_TYPES.arme: return arme;
+ case ITEM_TYPES.competencecreature:
return RdDItemCompetenceCreature.armeCreature(arme);
}
return RdDItemArme.mainsNues();
}
+ static getCompetenceArme(arme, maniement) {
+ switch (arme.type) {
+ case ITEM_TYPES.competencecreature:
+ return arme.name
+ case ITEM_TYPES.arme:
+ switch (maniement) {
+ case 'competence': return arme.system.competence;
+ case 'unemain': return RdDItemArme.competence1Mains(arme);
+ case 'deuxmains': return RdDItemArme.competence2Mains(arme);
+ case 'tir': return arme.system.tir;
+ case 'lancer': return arme.system.lancer;
+ }
+ }
+ return undefined
+ }
+
static computeNiveauArmes(armes, competences) {
for (const arme of armes) {
arme.system.niveau = RdDItemArme.niveauCompetenceArme(arme, competences);
@@ -68,14 +84,14 @@ export class RdDItemArme extends Item {
return armeData.system.categorie_parade;
}
// pour compatibilité avec des personnages existants
- if (armeData.type == TYPES.competencecreature || armeData.system.categorie == 'creature') {
+ if (armeData.type == ITEM_TYPES.competencecreature || armeData.system.categorie == 'creature') {
return armeData.system.categorie_parade || (armeData.system.isparade ? 'armes-naturelles' : '');
}
if (!armeData.type.match(/arme|competencecreature/)) {
return '';
}
if (armeData.system.competence == undefined) {
- return TYPES.competencecreature;
+ return ITEM_TYPES.competencecreature;
}
let compname = armeData.system.competence.toLowerCase();
if (compname.match(/^(dague de jet|javelot|fouet|arc|arbalête|fronde|hache de jet|fléau)$/)) return '';
@@ -132,43 +148,46 @@ export class RdDItemArme extends Item {
return true;
}
- /* -------------------------------------------- */
- static armeUneOuDeuxMains(armeData, aUneMain) {
- if (armeData && !armeData.system.cac) {
- armeData.system.unemain = armeData.system.unemain || !armeData.system.deuxmains;
- const uneOuDeuxMains = armeData.system.unemain && armeData.system.deuxmains;
- const containsSlash = !Number.isInteger(armeData.system.dommages) && armeData.system.dommages.includes("/");
- if (containsSlash) { // Sanity check
- armeData = foundry.utils.duplicate(armeData);
-
- const tableauDegats = armeData.system.dommages.split("/");
- if (aUneMain)
- armeData.system.dommagesReels = Number(tableauDegats[0]);
- else // 2 mains
- armeData.system.dommagesReels = Number(tableauDegats[1]);
- }
- else {
- armeData.system.dommagesReels = Number(armeData.system.dommages);
- }
-
- if (uneOuDeuxMains != containsSlash) {
- ui.notifications.info("Les dommages de l'arme à 1/2 mains " + armeData.name + " ne sont pas corrects (ie sous la forme X/Y)");
- }
+ static dommagesReels(arme, maniement) {
+ switch (maniement) {
+ case 'tir':
+ case 'lancer':
+ case 'competence':
+ return Number(arme.system.dommages)
}
- return armeData;
+ if (arme.system.unemain && arme.system.deuxmains) {
+ const containsSlash = !Number.isInteger(arme.system.dommages) && arme.system.dommages.includes("/")
+ if (!containsSlash) {
+ ui.notifications.info("Les dommages de l'arme à 1/2 mains " + arme.name + " ne sont pas corrects (ie sous la forme X/Y)");
+ return Number(arme.system.dommages)
+ }
+ const tableauDegats = arme.system.dommages.split("/");
+ return Number(tableauDegats[maniement == 'unemain' ? 0 : 1])
+ }
+ return Number(arme.system.dommages);
}
- static competence2Mains(arme) {
- return arme.system.competence.replace(" 1 main", " 2 mains");
+
+ /* -------------------------------------------- */
+ static armeUneOuDeuxMains(arme, aUneMain) {
+ if (arme && !arme.system.cac) {
+ arme = foundry.utils.duplicate(arme);
+ arme.system.dommagesReels = RdDItemArme.dommagesReels(arme, aUneMain ? 'unemain' : 'deuxmains')
+ }
+ return arme;
}
static competence1Mains(arme) {
return arme.system.competence.replace(" 2 mains", " 1 main");
}
+ static competence2Mains(arme) {
+ return arme.system.competence.replace(" 1 main", " 2 mains");
+ }
+
static isArmeUtilisable(arme) {
switch (arme.type) {
- case TYPES.arme: return arme.system.equipe && (arme.system.resistance > 0 || arme.system.portee_courte > 0)
- case TYPES.competencecreature: return true
+ case ITEM_TYPES.arme: return arme.system.equipe && (arme.system.resistance > 0 || arme.system.portee_courte > 0)
+ case ITEM_TYPES.competencecreature: return true
}
return false
}
@@ -180,11 +199,11 @@ export class RdDItemArme extends Item {
static corpsACorps(actor) {
let competence = actor?.getCompetenceCorpsACorps() ?? { system: { niveau: -6 } };
- let melee = actor? actor.system.carac['melee'].value : 0
+ let melee = actor ? actor.system.carac['melee'].value : 0
return {
_id: competence?.id,
name: 'Corps à corps',
- type: TYPES.arme,
+ type: ITEM_TYPES.arme,
img: 'systems/foundryvtt-reve-de-dragon/icons/competence_corps_a_corps.webp',
system: {
initiative: RdDCombatManager.calculInitiative(competence.system.niveau, melee),
diff --git a/module/item-competencecreature.js b/module/item-competencecreature.js
index d16f8aba..19ebf2c7 100644
--- a/module/item-competencecreature.js
+++ b/module/item-competencecreature.js
@@ -1,5 +1,5 @@
-import { TYPES } from "./item.js";
+import { ITEM_TYPES } from "./item.js";
import { RdDCombatManager } from "./rdd-combat.js";
const categories = {
@@ -54,7 +54,7 @@ export class RdDItemCompetenceCreature extends Item {
/* -------------------------------------------- */
static isCompetenceAttaque(item) {
- if (item.type == TYPES.competencecreature) {
+ if (item.type == ITEM_TYPES.competencecreature) {
switch (item.system.categorie) {
case "melee":
case "tir":
@@ -68,7 +68,7 @@ export class RdDItemCompetenceCreature extends Item {
}
static getCategorieAttaque(item) {
- if (item.type == TYPES.competencecreature) {
+ if (item.type == ITEM_TYPES.competencecreature) {
switch (item.system.categorie) {
case "melee":
case "tir":
@@ -82,7 +82,7 @@ export class RdDItemCompetenceCreature extends Item {
return undefined
}
static isDommages(item) {
- if (item.type == TYPES.competencecreature) {
+ if (item.type == ITEM_TYPES.competencecreature) {
switch (item.system.categorie) {
case "melee":
case "tir":
@@ -94,7 +94,7 @@ export class RdDItemCompetenceCreature extends Item {
return false
}
static isParade(item) {
- if (item.type == TYPES.competencecreature) {
+ if (item.type == ITEM_TYPES.competencecreature) {
switch (item.system.categorie) {
case "melee":
case "naturelle":
diff --git a/module/item-sheet.js b/module/item-sheet.js
index fd8b90e3..a9292fbb 100644
--- a/module/item-sheet.js
+++ b/module/item-sheet.js
@@ -12,7 +12,7 @@ import { SystemCompendiums } from "./settings/system-compendiums.js";
import { Misc } from "./misc.js";
import { RdDTimestamp } from "./time/rdd-timestamp.js";
import { RdDItemCompetenceCreature } from "./item-competencecreature.js";
-import { TYPES } from "./item.js";
+import { ITEM_TYPES } from "./item.js";
/**
* Extend the basic ItemSheet for RdD specific items
@@ -101,7 +101,7 @@ export class RdDItemSheet extends ItemSheet {
isComestible: this.item.getUtilisationCuisine(),
options: RdDSheetUtility.mergeDocumentRights(this.options, this.item, this.isEditable),
}
- if (this.item.type == TYPES.competencecreature) {
+ if (this.item.type == ITEM_TYPES.competencecreature) {
formData.isparade = RdDItemCompetenceCreature.isParade(this.item)
formData.isdommages = RdDItemCompetenceCreature.isDommages(this.item)
}
diff --git a/module/item-sort.js b/module/item-sort.js
index 09f9be37..be1a2f66 100644
--- a/module/item-sort.js
+++ b/module/item-sort.js
@@ -1,9 +1,43 @@
+import { Grammar } from "./grammar.js";
+import { RdDItemCompetence } from "./item-competence.js";
+import { ITEM_TYPES } from "./item.js";
import { Misc } from "./misc.js";
import { TMRUtility } from "./tmr-utility.js";
+const VOIES_DRACONIC = [
+ { code: 'O', label: "Voie d'Oniros", short: 'Oniros' },
+ { code: 'H', label: "Voie d'Hypnos", short: 'Hypnos' },
+ { code: 'N', label: "Voie de Narcos", short: 'Narcos' },
+ { code: 'T', label: "Voie de Thanatos", short: 'Thanatos' },
+ { code: 'O/H/N/T', label: "Oniros/Hypnos/Narcos/Thanatos", short: 'Oniros/Hypnos/Narcos/Thanatos' },
+ { code: 'O/H/N', label: "Oniros/Hypnos/Narcos" }
+]
+
/* -------------------------------------------- */
export class RdDItemSort extends Item {
+ static getDraconicsSort(draconicList, sort) {
+ switch (Grammar.toLowerCaseNoAccent(sort.name)) {
+ case "lecture d'aura":
+ case "detection d'aura":
+ return draconicList;
+ case "annulation de magie":
+ return draconicList.filter(it => !RdDItemCompetence.isThanatos(it));
+ }
+ return [RdDItemCompetence.getVoieDraconic(draconicList, sort.system.draconic)];
+ }
+
+ static getCodeDraconic(sort) {
+ switch (Grammar.toLowerCaseNoAccent(sort.name)) {
+ case "lecture d'aura":
+ case "detection d'aura":
+ return 'O/H/N/T'
+ case "annulation de magie":
+ return 'O/H/N'
+ }
+ const voie = VOIES_DRACONIC.find(it => it.label.includes(sort.system.draconic))
+ return voie?.code ?? sort.system.draconic
+ }
/* -------------------------------------------- */
static isDifficulteVariable(sort) {
return sort && (sort.system.difficulte.toLowerCase() == "variable");
@@ -31,9 +65,9 @@ export class RdDItemSort extends Item {
/* -------------------------------------------- */
static buildBonusCaseList(bonuscase, newCase) {
- const list = RdDItemSort._bonuscaseStringToList(bonuscase)
+ const list = RdDItemSort.bonuscaseStringToList(bonuscase)
if (newCase) {
- return list.concat({ case: "Nouvelle", bonus: 0 });
+ list.push({ case: "Nouvelle", bonus: 0 })
}
return list;
}
@@ -44,7 +78,7 @@ export class RdDItemSort extends Item {
*/
static getBonusCaseList(item, newCase = false) {
// Gestion spéciale case bonus
- if (item.type == 'sort') {
+ if (item.type == ITEM_TYPES.sort) {
return RdDItemSort.buildBonusCaseList(item.system.bonuscase, newCase);
}
return undefined;
@@ -104,8 +138,11 @@ export class RdDItemSort extends Item {
.sort(Misc.ascending())
.join(',');
}
- static _bonuscaseStringToList(bonuscase) {
- return (bonuscase ?? '').split(',').map(it => {
+ static bonuscaseStringToList(bonuscase) {
+ if (bonuscase == undefined || bonuscase == '') {
+ return []
+ }
+ return bonuscase.split(',').map(it => {
const b = it.split(':');
return { case: b[0], bonus: b[1] };
});
diff --git a/module/item.js b/module/item.js
index 8569d3b9..fe6d25ad 100644
--- a/module/item.js
+++ b/module/item.js
@@ -9,7 +9,15 @@ import { RdDRaretes } from "./item/raretes.js";
import { RdDItemCompetence } from "./item-competence.js";
import { RdDItemCompetenceCreature } from "./item-competencecreature.js";
-export const TYPES = {
+export const ACTOR_TYPES = {
+ personnage: 'personnage',
+ creature: 'creature',
+ entite: 'entite',
+ commerce: 'commerce',
+ vehicule: 'vehicule'
+}
+
+export const ITEM_TYPES = {
competence: 'competence',
competencecreature: 'competencecreature',
empoignade: 'empoignade',
@@ -56,33 +64,33 @@ export const TYPES = {
}
const typesInventaireMateriel = [
- TYPES.arme,
- TYPES.armure,
- TYPES.conteneur,
- TYPES.faune,
- TYPES.gemme,
- TYPES.herbe,
- TYPES.plante,
- TYPES.ingredient,
- TYPES.livre,
- TYPES.monnaie,
- TYPES.munition,
- TYPES.nourritureboisson,
- TYPES.objet,
- TYPES.potion,
+ ITEM_TYPES.arme,
+ ITEM_TYPES.armure,
+ ITEM_TYPES.conteneur,
+ ITEM_TYPES.faune,
+ ITEM_TYPES.gemme,
+ ITEM_TYPES.herbe,
+ ITEM_TYPES.plante,
+ ITEM_TYPES.ingredient,
+ ITEM_TYPES.livre,
+ ITEM_TYPES.monnaie,
+ ITEM_TYPES.munition,
+ ITEM_TYPES.nourritureboisson,
+ ITEM_TYPES.objet,
+ ITEM_TYPES.potion,
]
const typesInventaire = {
materiel: typesInventaireMateriel,
all: ['service'].concat(typesInventaireMateriel),
}
-const typesObjetsOeuvres = [TYPES.oeuvre, TYPES.recettecuisine, TYPES.musique, TYPES.chant, TYPES.danse, TYPES.jeu]
-const typesObjetsDraconiques = [TYPES.queue, TYPES.ombre, TYPES.souffle, TYPES.tete, TYPES.signedraconique, TYPES.sortreserve, TYPES.rencontre]
-const typesObjetsConnaissance = [TYPES.meditation, TYPES.recettealchimique, TYPES.sort]
-const typesObjetsEffet = [TYPES.possession, TYPES.poison, TYPES.maladie, TYPES.blessure]
-const typesObjetsCompetence = [TYPES.competence, TYPES.competencecreature]
-const typesObjetsTemporels = [TYPES.blessure, TYPES.poison, TYPES.maladie, TYPES.queue, TYPES.ombre, TYPES.souffle, TYPES.signedraconique, TYPES.rencontre]
-const typesObjetsEquipable = [TYPES.arme, TYPES.armure, TYPES.objet];
+const typesObjetsOeuvres = [ITEM_TYPES.oeuvre, ITEM_TYPES.recettecuisine, ITEM_TYPES.musique, ITEM_TYPES.chant, ITEM_TYPES.danse, ITEM_TYPES.jeu]
+const typesObjetsDraconiques = [ITEM_TYPES.queue, ITEM_TYPES.ombre, ITEM_TYPES.souffle, ITEM_TYPES.tete, ITEM_TYPES.signedraconique, ITEM_TYPES.sortreserve, ITEM_TYPES.rencontre]
+const typesObjetsConnaissance = [ITEM_TYPES.meditation, ITEM_TYPES.recettealchimique, ITEM_TYPES.sort]
+const typesObjetsEffet = [ITEM_TYPES.possession, ITEM_TYPES.poison, ITEM_TYPES.maladie, ITEM_TYPES.blessure]
+const typesObjetsCompetence = [ITEM_TYPES.competence, ITEM_TYPES.competencecreature]
+const typesObjetsTemporels = [ITEM_TYPES.blessure, ITEM_TYPES.poison, ITEM_TYPES.maladie, ITEM_TYPES.queue, ITEM_TYPES.ombre, ITEM_TYPES.souffle, ITEM_TYPES.signedraconique, ITEM_TYPES.rencontre]
+const typesObjetsEquipable = [ITEM_TYPES.arme, ITEM_TYPES.armure, ITEM_TYPES.objet];
const typesEnvironnement = typesInventaireMateriel;
const encBrin = 0.00005; // un brin = 1 décigramme = 1/10g = 1/10000kg = 1/20000 enc
const encPepin = 0.0007; /* un pépin de gemme = 1/10 cm3 = 1/1000 l = 3.5/1000 kg = 7/2000 kg = 7/1000 enc
@@ -141,12 +149,12 @@ export class RdDItem extends Item {
static isFieldInventaireModifiable(type, field) {
switch (field) {
case 'quantite':
- if ([TYPES.conteneur].includes(type)) {
+ if ([ITEM_TYPES.conteneur].includes(type)) {
return false;
}
break;
case 'cout':
- if ([TYPES.monnaie].includes(type)) {
+ if ([ITEM_TYPES.monnaie].includes(type)) {
return game.user.isGM;
}
break;
@@ -195,15 +203,15 @@ export class RdDItem extends Item {
getUniteQuantite() {
switch (this.type) {
- case TYPES.monnaie: return "(Pièces)"
- case TYPES.herbe:
+ case ITEM_TYPES.monnaie: return "(Pièces)"
+ case ITEM_TYPES.herbe:
switch (this.system.categorie) {
case 'Alchimie': case 'Repos': case 'Soin':
return "(Brins)"
case 'Cuisine': return '';
}
return '';
- case TYPES.ingredient: return "(Pépins ou Brins)"
+ case ITEM_TYPES.ingredient: return "(Pépins ou Brins)"
}
return '';
}
@@ -212,13 +220,13 @@ export class RdDItem extends Item {
return typesObjetsEquipable.includes(this.type)
}
- isCompetencePersonnage() { return this.type == TYPES.competence }
- isCompetenceCreature() { return this.type == TYPES.competencecreature }
- isConteneur() { return this.type == TYPES.conteneur; }
- isMonnaie() { return this.type == TYPES.monnaie; }
- isPotion() { return this.type == TYPES.potion; }
- isNourritureBoisson() { return this.type == TYPES.nourritureboisson; }
- isService() { return this.type == TYPES.service; }
+ isCompetencePersonnage() { return this.type == ITEM_TYPES.competence }
+ isCompetenceCreature() { return this.type == ITEM_TYPES.competencecreature }
+ isConteneur() { return this.type == ITEM_TYPES.conteneur; }
+ isMonnaie() { return this.type == ITEM_TYPES.monnaie; }
+ isPotion() { return this.type == ITEM_TYPES.potion; }
+ isNourritureBoisson() { return this.type == ITEM_TYPES.nourritureboisson; }
+ isService() { return this.type == ITEM_TYPES.service; }
isCompetence() { return typesObjetsCompetence.includes(this.type) }
isEsquive() {
@@ -237,27 +245,27 @@ export class RdDItem extends Item {
return this.isCompetence() && ['melee', 'tir', 'lancer'].includes(this.system.categorie)
}
- isCompetencePossession() { return TYPES.competencecreature == this.type && this.system.categorie == "possession" }
+ isCompetencePossession() { return ITEM_TYPES.competencecreature == this.type && this.system.categorie == "possession" }
isTemporel() { return typesObjetsTemporels.includes(this.type) }
isOeuvre() { return typesObjetsOeuvres.includes(this.type) }
isDraconique() { return RdDItem.getItemTypesDraconiques().includes(this.type) }
- isQueueDragon() { return [TYPES.queue, TYPES.ombre].includes(this.type) }
+ isQueueDragon() { return [ITEM_TYPES.queue, ITEM_TYPES.ombre].includes(this.type) }
isEffet() { return typesObjetsEffet.includes(this.type) }
isConnaissance() { return typesObjetsConnaissance.includes(this.type) }
isInventaire(mode = 'materiel') { return RdDItem.getItemTypesInventaire(mode).includes(this.type); }
isBoisson() { return this.isNourritureBoisson() && this.system.boisson; }
isAlcool() { return this.isNourritureBoisson() && this.system.boisson && this.system.alcoolise; }
- isHerbeAPotion() { return this.type == TYPES.herbe && (this.system.categorie == 'Soin' || this.system.categorie == 'Repos'); }
- isBlessure() { return this.type == TYPES.blessure }
+ isHerbeAPotion() { return this.type == ITEM_TYPES.herbe && (this.system.categorie == 'Soin' || this.system.categorie == 'Repos'); }
+ isBlessure() { return this.type == ITEM_TYPES.blessure }
isPresentDansMilieux(milieux) {
return this.getEnvironnements(milieux).length > 0
}
getCategories() {
switch (this.type) {
- case TYPES.competence: return RdDItemCompetence.getCategories()
- case TYPES.competencecreature: return RdDItemCompetenceCreature.getCategories()
+ case ITEM_TYPES.competence: return RdDItemCompetence.getCategories()
+ case ITEM_TYPES.competencecreature: return RdDItemCompetenceCreature.getCategories()
}
return {}
}
@@ -341,15 +349,15 @@ export class RdDItem extends Item {
getUtilisation() {
switch (this.type) {
- case TYPES.potion:
+ case ITEM_TYPES.potion:
switch (this.system.categorie) {
case 'Alchimie': case 'AlchimieEnchante': case 'AlchimieAutre': return 'alchimie'
case 'Cuisine': return 'cuisine'
case 'Remede': case 'Repos': case 'ReposEnchante': case 'Soin': case 'SoinEnchante': return 'soins'
}
return '';
- case TYPES.nourritureboisson: return 'cuisine';
- case TYPES.herbe: case TYPES.faune: case TYPES.ingredient: case TYPES.plante:
+ case ITEM_TYPES.nourritureboisson: return 'cuisine';
+ case ITEM_TYPES.herbe: case ITEM_TYPES.faune: case ITEM_TYPES.ingredient: case ITEM_TYPES.plante:
switch (this.system.categorie) {
case 'Cuisine': return 'cuisine';
case 'Toxique': case 'Poison': return 'poison';
@@ -364,9 +372,9 @@ export class RdDItem extends Item {
getUtilisationCuisine() {
if (this.getUtilisation() == 'cuisine') {
switch (this.type) {
- case TYPES.nourritureboisson:
+ case ITEM_TYPES.nourritureboisson:
return 'pret';
- case TYPES.herbe: case TYPES.faune: case TYPES.ingredient: case TYPES.plante:
+ case ITEM_TYPES.herbe: case ITEM_TYPES.faune: case ITEM_TYPES.ingredient: case ITEM_TYPES.plante:
return 'brut';
}
}
@@ -374,7 +382,7 @@ export class RdDItem extends Item {
}
isCristalAlchimique() {
- return this.type == TYPES.objet && Grammar.includesLowerCaseNoAccent(this.name, 'cristal alchimique') && this.system.quantite > 0;
+ return this.type == ITEM_TYPES.objet && Grammar.includesLowerCaseNoAccent(this.name, 'cristal alchimique') && this.system.quantite > 0;
}
isMagique() {
@@ -402,11 +410,11 @@ export class RdDItem extends Item {
getEnc() {
switch (this.type) {
- case TYPES.service:
+ case ITEM_TYPES.service:
return 0;
- case TYPES.herbe:
+ case ITEM_TYPES.herbe:
return this.getEncHerbe();
- case TYPES.gemme:
+ case ITEM_TYPES.gemme:
return encPepin * this.system.taille;
}
return Math.max(this.system.encombrement ?? 0, 0);
@@ -484,7 +492,7 @@ export class RdDItem extends Item {
getActionPrincipale(options = { warnIfNot: true }) {
switch (this.type) {
- case TYPES.conteneur: return 'Ouvrir';
+ case ITEM_TYPES.conteneur: return 'Ouvrir';
}
if (this.actor?.isPersonnage()) {
const warn = options.warnIfNot;
@@ -492,11 +500,11 @@ export class RdDItem extends Item {
return 'Cuisiner';
}
switch (this.type) {
- case TYPES.nourritureboisson: return this._actionOrWarnQuantiteZero(this.system.boisson ? 'Boire' : 'Manger', warn);
- case TYPES.potion: return this._actionOrWarnQuantiteZero('Consommer', warn);
- case TYPES.livre: return this._actionOrWarnQuantiteZero('Lire', warn);
- case TYPES.herbe: return this.isHerbeAPotion() ? this._actionOrWarnQuantiteZero('Décoction', warn) : undefined;
- case TYPES.queue: case TYPES.ombre: return this.system.refoulement > 0 ? 'Refouler' : undefined;
+ case ITEM_TYPES.nourritureboisson: return this._actionOrWarnQuantiteZero(this.system.boisson ? 'Boire' : 'Manger', warn);
+ case ITEM_TYPES.potion: return this._actionOrWarnQuantiteZero('Consommer', warn);
+ case ITEM_TYPES.livre: return this._actionOrWarnQuantiteZero('Lire', warn);
+ case ITEM_TYPES.herbe: return this.isHerbeAPotion() ? this._actionOrWarnQuantiteZero('Décoction', warn) : undefined;
+ case ITEM_TYPES.queue: case ITEM_TYPES.ombre: return this.system.refoulement > 0 ? 'Refouler' : undefined;
}
}
return undefined;
diff --git a/module/migrations.js b/module/migrations.js
index 675e2088..c608d08a 100644
--- a/module/migrations.js
+++ b/module/migrations.js
@@ -2,7 +2,7 @@ import { RdDBaseActor } from "./actor/base-actor.js";
import { LOG_HEAD, SYSTEM_RDD } from "./constants.js";
import { Grammar } from "./grammar.js";
import { Monnaie } from "./item-monnaie.js";
-import { RdDItem, TYPES } from "./item.js";
+import { RdDItem, ITEM_TYPES } from "./item.js";
import { RdDTimestamp } from "./time/rdd-timestamp.js";
import { RdDRaretes } from "./item/raretes.js";
import { RdDCalendrier } from "./time/rdd-calendrier.js";
@@ -465,7 +465,7 @@ class _10_7_19_CategorieCompetenceCreature extends Migration {
async migrate() {
await this.applyItemsUpdates(items => items
- .filter(it => TYPES.competencecreature == it.type)
+ .filter(it => ITEM_TYPES.competencecreature == it.type)
.map(it => this.migrateCompetenceCreature(it))
);
}
@@ -502,7 +502,7 @@ class _10_7_19_PossessionsEntiteVictime extends Migration {
async migrate() {
await this.applyItemsUpdates(items => items
- .filter(it => TYPES.possession == it.type)
+ .filter(it => ITEM_TYPES.possession == it.type)
.map(it => this.migratePossession(it))
);
}
diff --git a/module/rdd-bonus.js b/module/rdd-bonus.js
index 93c1d36e..1d69e3ea 100644
--- a/module/rdd-bonus.js
+++ b/module/rdd-bonus.js
@@ -31,8 +31,8 @@ export class RdDBonus {
}
/* -------------------------------------------- */
- static dmg(rollData, dmgActor, isEntiteIncarnee = false) {
- const dmgArme = RdDBonus._dmgArme(rollData)
+ static dmg(rollData, actor, isEntiteIncarnee = false) {
+ const dmgArme = RdDBonus.dmgArme(rollData.arme)
let dmg = {
total: 0,
dmgArme: dmgArme,
@@ -41,7 +41,7 @@ export class RdDBonus {
dmgParticuliere: RdDBonus._dmgParticuliere(rollData),
dmgSurprise: RdDBonus.dmgBonus(rollData.ajustements?.attaqueDefenseurSurpris.used),
mortalite: RdDBonus._calculMortalite(rollData, isEntiteIncarnee),
- dmgActor: RdDBonus._dmgPerso(dmgActor, rollData.selectedCarac?.label, dmgArme)
+ dmgActor: RdDBonus.bonusDmg(actor, rollData.selectedCarac?.label.toLowerCase(), dmgArme)
}
dmg.total = dmg.dmgSurprise + dmg.dmgTactique + dmg.dmgArme + dmg.dmgActor + dmg.dmgParticuliere;
return dmg;
@@ -71,11 +71,11 @@ export class RdDBonus {
}
/* -------------------------------------------- */
- static _dmgArme(rollData) {
- if (rollData.arme) {
- let dmgBase = rollData.arme.system.dommagesReels ?? Number(rollData.arme.system.dommages ?? 0);
+ static dmgArme(arme) {
+ if (arme) {
+ let dmgBase = arme.system.dommagesReels ?? Number(arme.system.dommages ?? 0);
//Le bonus dégats magiques ne peut pas faire dépasser le bonus de l'arme (cf p.278)
- return dmgBase + Math.min(dmgBase, rollData.arme.system.magique ? rollData.arme.system.ecaille_efficacite : 0);
+ return dmgBase + Math.min(dmgBase, arme.system.magique ? arme.system.ecaille_efficacite : 0);
}
return 0;
}
@@ -86,13 +86,14 @@ export class RdDBonus {
}
/* -------------------------------------------- */
- static _dmgPerso(dmgActor, categorie, dmgArme) {
+ static bonusDmg(actor, categorie, dmgArme) {
+ const dmgActor = actor.getBonusDegat()
if (categorie == undefined) {
return 0
}
switch (categorie) {
- case "Tir": return 0;
- case "Lancer": return Math.max(0, Math.min(dmgArme, dmgActor));
+ case "tir": return 0;
+ case "lancer": return Math.max(0, Math.min(dmgArme, dmgActor));
}
return dmgActor;
}
diff --git a/module/rdd-combat.js b/module/rdd-combat.js
index 66cbe453..be55bc5a 100644
--- a/module/rdd-combat.js
+++ b/module/rdd-combat.js
@@ -864,7 +864,7 @@ export class RdDCombat {
async _onAttaqueNormale(attackerRoll) {
console.log("RdDCombat.onAttaqueNormale >>>", attackerRoll);
- attackerRoll.dmg = RdDBonus.dmg(attackerRoll, this.attacker.getBonusDegat(), this.defender.isEntite());
+ attackerRoll.dmg = RdDBonus.dmg(attackerRoll, this.attacker, this.defender.isEntite());
let defenderRoll = { attackerRoll: attackerRoll, passeArme: attackerRoll.passeArme, show: {} }
attackerRoll.show = {
cible: this.target ? this.defender.name : 'la cible',
diff --git a/module/rdd-empoignade.js b/module/rdd-empoignade.js
index 49778fd2..81c3b965 100644
--- a/module/rdd-empoignade.js
+++ b/module/rdd-empoignade.js
@@ -5,7 +5,7 @@ import { RdDItemCompetenceCreature } from "./item-competencecreature.js";
import { ChatUtility } from "./chat-utility.js";
import { STATUSES } from "./settings/status-effects.js";
import { ReglesOptionnelles } from "./settings/regles-optionnelles.js";
-import { TYPES } from "./item.js";
+import { ITEM_TYPES } from "./item.js";
/* -------------------------------------------- */
@@ -92,18 +92,18 @@ export class RdDEmpoignade {
/* -------------------------------------------- */
static isEmpoignadeEnCours(actor) {
- return actor.itemTypes[TYPES.empoignade].find(it => it.system.pointsemp > 0)
+ return actor.itemTypes[ITEM_TYPES.empoignade].find(it => it.system.pointsemp > 0)
}
/* -------------------------------------------- */
static getEmpoignadeById(actor, id) {
- let emp = actor.itemTypes[TYPES.empoignade].find(it => it.system.empoignadeid == id)
+ let emp = actor.itemTypes[ITEM_TYPES.empoignade].find(it => it.system.empoignadeid == id)
return emp && foundry.utils.duplicate(emp) || undefined;
}
/* -------------------------------------------- */
static getEmpoignade(attacker, defender) {
- let emp = attacker.itemTypes[TYPES.empoignade].find(it =>
+ let emp = attacker.itemTypes[ITEM_TYPES.empoignade].find(it =>
(it.system.empoigneurid == attacker.id && it.system.empoigneid == defender.id) ||
(it.system.empoigneurid == defender.id && it.system.empoigneid == attacker.id)
)
diff --git a/module/rdd-herbes.js b/module/rdd-herbes.js
index edcd3513..4d650e27 100644
--- a/module/rdd-herbes.js
+++ b/module/rdd-herbes.js
@@ -6,7 +6,7 @@ import { RdDTimestamp } from "./time/rdd-timestamp.js";
export class RdDHerbes extends Item {
/* -------------------------------------------- */
- static async initializeHerbes() {
+ static async onReady() {
this.herbesSoins = await RdDHerbes.listCategorieHerbes('Soin');
this.herbesRepos = await RdDHerbes.listCategorieHerbes('Repos');
}
diff --git a/module/rdd-hotbar-drop.js b/module/rdd-hotbar-drop.js
index edb8ae1e..7bb6db05 100644
--- a/module/rdd-hotbar-drop.js
+++ b/module/rdd-hotbar-drop.js
@@ -1,6 +1,6 @@
import { RdDItemArme } from "./item-arme.js";
import { RdDItemCompetenceCreature } from "./item-competencecreature.js";
-import { TYPES } from "./item.js";
+import { ITEM_TYPES } from "./item.js";
export class RdDHotbar {
@@ -35,7 +35,7 @@ export class RdDHotbar {
static async addToHotbar(item, slot) {
switch (item?.type ?? '') {
- case TYPES.arme:
+ case ITEM_TYPES.arme:
{
// Les armes peuvent avoir plusieurs usages
if (item.system.competence != '') {
@@ -54,12 +54,12 @@ export class RdDHotbar {
}
}
return
- case TYPES.competencecreature:
+ case ITEM_TYPES.competencecreature:
const categorie = RdDItemCompetenceCreature.getCategorieAttaque(item) ?? 'competence';
await this.createItemMacro(item, slot, categorie)
return
default:
- case TYPES.competence:
+ case ITEM_TYPES.competence:
await this.createItemMacro(item, slot++, 'competence')
if (item.isCorpsACorps()) {
await this.createItemMacro(item, slot++, 'pugilat')
@@ -79,7 +79,7 @@ export class RdDHotbar {
* Actor - open actor sheet
* Journal - open journal sheet
*/
- static initDropbar() {
+ static init() {
Hooks.on('hotbarDrop', (bar, documentData, slot) => {
@@ -88,9 +88,9 @@ export class RdDHotbar {
const item = fromUuidSync(documentData.uuid) ?? this.actor.items.get(documentData.uuid)
console.log('DROP', documentData, item)
switch (item?.type) {
- case TYPES.arme:
- case TYPES.competence:
- case TYPES.competencecreature:
+ case ITEM_TYPES.arme:
+ case ITEM_TYPES.competence:
+ case ITEM_TYPES.competencecreature:
this.addToHotbar(item, slot)
return false
}
@@ -116,9 +116,9 @@ export class RdDHotbar {
// Trigger the item roll
switch (item.type) {
- case TYPES.arme:
+ case ITEM_TYPES.arme:
return actor.rollArme(item, categorieArme);
- case TYPES.competence:
+ case ITEM_TYPES.competence:
if (item.isCorpsACorps()) {
switch (categorieArme) {
case 'pugilat':
@@ -128,7 +128,7 @@ export class RdDHotbar {
}
}
return actor.rollCompetence(item);
- case TYPES.competencecreature:
+ case ITEM_TYPES.competencecreature:
return item.system.iscombat && !item.system.isparade
? actor.rollArme(item, categorieArme)
: actor.rollCompetence(item);
diff --git a/module/rdd-main.js b/module/rdd-main.js
index d51f3351..ffcf00e8 100644
--- a/module/rdd-main.js
+++ b/module/rdd-main.js
@@ -1,69 +1,72 @@
-import { SYSTEM_RDD, SYSTEM_SOCKET_ID, RDD_CONFIG } from "./constants.js";
-import { Migrations } from './migrations.js';
+import { SYSTEM_RDD, SYSTEM_SOCKET_ID, RDD_CONFIG } from "./constants.js"
+import { Migrations } from './migrations.js'
-import { RdDUtility } from "./rdd-utility.js";
-import { TMRUtility } from "./tmr-utility.js";
-import { TMRRencontres } from "./tmr-rencontres.js";
-import { RdDCalendrier } from "./time/rdd-calendrier.js";
-import { RdDTimestamp } from "./time/rdd-timestamp.js";
-import { DialogChronologie } from "./dialog-chronologie.js";
+import { RdDUtility } from "./rdd-utility.js"
+import { TMRUtility } from "./tmr-utility.js"
+import { TMRRencontres } from "./tmr-rencontres.js"
+import { RdDCalendrier } from "./time/rdd-calendrier.js"
+import { RdDTimestamp } from "./time/rdd-timestamp.js"
+import { DialogChronologie } from "./dialog-chronologie.js"
-import { RdDResolutionTable } from "./rdd-resolution-table.js";
-import { RdDTokenHud } from "./rdd-token-hud.js";
-import { RdDCommands } from "./rdd-commands.js";
-import { RdDCombatManager, RdDCombat } from "./rdd-combat.js";
-import { ChatUtility } from "./chat-utility.js";
-import { StatusEffects } from "./settings/status-effects.js";
-import { RdDCompendiumOrganiser } from "./rdd-compendium-organiser.js";
-import { ReglesOptionnelles } from "./settings/regles-optionnelles.js";
+import { RdDResolutionTable } from "./rdd-resolution-table.js"
+import { RdDTokenHud } from "./rdd-token-hud.js"
+import { RdDCommands } from "./rdd-commands.js"
+import { RdDCombatManager, RdDCombat } from "./rdd-combat.js"
+import { ChatUtility } from "./chat-utility.js"
+import { StatusEffects } from "./settings/status-effects.js"
+import { RdDCompendiumOrganiser } from "./rdd-compendium-organiser.js"
+import { ReglesOptionnelles } from "./settings/regles-optionnelles.js"
import { RdDHotbar } from "./rdd-hotbar-drop.js"
-import { EffetsDraconiques } from "./tmr/effets-draconiques.js";
-import { RdDHerbes } from "./rdd-herbes.js";
-import { RdDDice } from "./rdd-dice.js";
-import { RdDPossession } from "./rdd-possession.js";
-import { Misc } from "./misc.js";
+import { EffetsDraconiques } from "./tmr/effets-draconiques.js"
+import { RdDHerbes } from "./rdd-herbes.js"
+import { RdDDice } from "./rdd-dice.js"
+import { RdDPossession } from "./rdd-possession.js"
+import { Misc } from "./misc.js"
-import { SystemCompendiums } from "./settings/system-compendiums.js";
-import { Environnement } from "./environnement.js";
+import { SystemCompendiums } from "./settings/system-compendiums.js"
+import { Environnement } from "./environnement.js"
-import { RdDActor } from "./actor.js";
-import { RdDBaseActor } from "./actor/base-actor.js";
-import { RdDCommerce } from "./actor/commerce.js";
-import { RdDEntite } from "./actor/entite.js";
-import { RdDVehicule } from "./actor/vehicule.js";
-import { RdDActorSheet } from "./actor-sheet.js";
-import { RdDCommerceSheet } from "./actor/commerce-sheet.js";
-import { RdDCreatureSheet } from "./actor/creature-sheet.js";
-import { RdDActorEntiteSheet } from "./actor/entite-sheet.js";
-import { RdDActorVehiculeSheet } from "./actor/vehicule-sheet.js";
+import { RdDActor } from "./actor.js"
+import { RdDBaseActor } from "./actor/base-actor.js"
+import { RdDCommerce } from "./actor/commerce.js"
+import { RdDEntite } from "./actor/entite.js"
+import { RdDVehicule } from "./actor/vehicule.js"
+import { RdDActorSheet } from "./actor-sheet.js"
+import { RdDCommerceSheet } from "./actor/commerce-sheet.js"
+import { RdDCreatureSheet } from "./actor/creature-sheet.js"
+import { RdDActorEntiteSheet } from "./actor/entite-sheet.js"
+import { RdDActorVehiculeSheet } from "./actor/vehicule-sheet.js"
-import { RdDItem } from "./item.js";
-import { RdDItemBlessure } from "./item/blessure.js";
-import { RdDItemService } from "./item/service.js";
-import { RdDItemMaladie } from "./item/maladie.js";
-import { RdDItemPoison } from "./item/poison.js";
-import { RdDItemSigneDraconique } from "./item/signedraconique.js";
-import { RdDItemQueue } from "./item/queue.js";
-import { RdDItemOmbre } from "./item/ombre.js";
-import { RdDItemSouffle } from "./item/souffle.js";
-import { RdDRencontre } from "./item/rencontre.js";
+import { RdDItem } from "./item.js"
+import { RdDItemBlessure } from "./item/blessure.js"
+import { RdDItemService } from "./item/service.js"
+import { RdDItemMaladie } from "./item/maladie.js"
+import { RdDItemPoison } from "./item/poison.js"
+import { RdDItemSigneDraconique } from "./item/signedraconique.js"
+import { RdDItemQueue } from "./item/queue.js"
+import { RdDItemOmbre } from "./item/ombre.js"
+import { RdDItemSouffle } from "./item/souffle.js"
+import { RdDRencontre } from "./item/rencontre.js"
-import { RdDItemSheet } from "./item-sheet.js";
-import { RdDBlessureItemSheet } from "./item/sheet-blessure.js";
-import { RdDServiceItemSheet } from "./item/sheet-service.js";
-import { RdDRencontreItemSheet } from "./item/sheet-rencontre.js";
-import { RdDHerbeItemSheet } from "./item/sheet-herbe.js";
-import { RdDPlanteItemSheet } from "./item/sheet-plante.js";
-import { RdDIngredientItemSheet } from "./item/sheet-ingredient.js";
-import { RdDFauneItemSheet } from "./item/sheet-faune.js";
-import { RdDConteneurItemSheet } from "./item/sheet-conteneur.js";
-import { RdDSigneDraconiqueItemSheet } from "./item/sheet-signedraconique.js";
-import { RdDItemInventaireSheet } from "./item/sheet-base-inventaire.js";
-import { AppAstrologie } from "./sommeil/app-astrologie.js";
-import { RdDItemArmure } from "./item/armure.js";
-import { AutoAdjustDarkness as AutoAdjustDarkness } from "./time/auto-adjust-darkness.js";
-import { RdDCreature } from "./actor/creature.js";
-import { RdDTMRDialog } from "./rdd-tmr-dialog.js";
+import { RdDItemSheet } from "./item-sheet.js"
+import { RdDBlessureItemSheet } from "./item/sheet-blessure.js"
+import { RdDServiceItemSheet } from "./item/sheet-service.js"
+import { RdDRencontreItemSheet } from "./item/sheet-rencontre.js"
+import { RdDHerbeItemSheet } from "./item/sheet-herbe.js"
+import { RdDPlanteItemSheet } from "./item/sheet-plante.js"
+import { RdDIngredientItemSheet } from "./item/sheet-ingredient.js"
+import { RdDFauneItemSheet } from "./item/sheet-faune.js"
+import { RdDConteneurItemSheet } from "./item/sheet-conteneur.js"
+import { RdDSigneDraconiqueItemSheet } from "./item/sheet-signedraconique.js"
+import { RdDItemInventaireSheet } from "./item/sheet-base-inventaire.js"
+import { AppAstrologie } from "./sommeil/app-astrologie.js"
+import { RdDItemArmure } from "./item/armure.js"
+import { AutoAdjustDarkness as AutoAdjustDarkness } from "./time/auto-adjust-darkness.js"
+import { RdDCreature } from "./actor/creature.js"
+import { RdDTMRDialog } from "./rdd-tmr-dialog.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
@@ -71,18 +74,18 @@ import { RdDTMRDialog } from "./rdd-tmr-dialog.js";
* Software License: GNU GPLv3
*/
export class SystemReveDeDragon {
-
+
static start() {
const system = new SystemReveDeDragon()
Hooks.once('init', async () => await system.onInit())
Hooks.once('diceSoNiceReady', (dice3d) => RdDDice.diceSoNiceReady(dice3d))
Hooks.once('ready', () => system.onReady())
}
-
+
constructor() {
- this.config = RDD_CONFIG;
- this.RdDUtility = RdDUtility;
- this.RdDHotbar = RdDHotbar;
+ this.config = RDD_CONFIG
+ this.RdDUtility = RdDUtility
+ this.RdDHotbar = RdDHotbar
this.itemClasses = {
armure: RdDItemArmure,
blessure: RdDItemBlessure,
@@ -108,42 +111,42 @@ export class SystemReveDeDragon {
/* Foundry VTT Initialization */
/* -------------------------------------------- */
async onInit() {
- game.system.rdd = this;
- this.AppAstrologie = AppAstrologie;
+ game.system.rdd = this
+ this.AppAstrologie = AppAstrologie
- console.log(`Initializing Reve de Dragon System`);
+ console.log(`Initializing Reve de Dragon System`)
// preload handlebars templates
- RdDUtility.preloadHandlebarsTemplates();
+ RdDUtility.preloadHandlebarsTemplates()
/* -------------------------------------------- */
- this.initSystemSettings();
+ this.initSystemSettings()
/* -------------------------------------------- */
// Set an initiative formula for the system
CONFIG.Combat.initiative = {
formula: "1+(1d6/10)",
decimals: 2
- };
+ }
/* -------------------------------------------- */
game.socket.on(SYSTEM_SOCKET_ID, async (sockmsg) => {
- console.log(">>>>> MSG RECV", sockmsg);
+ console.log(">>>>> MSG RECV", sockmsg)
try {
- RdDUtility.onSocketMessage(sockmsg);
- RdDCombat.onSocketMessage(sockmsg);
- ChatUtility.onSocketMessage(sockmsg);
- RdDBaseActor.onSocketMessage(sockmsg);
+ RdDUtility.onSocketMessage(sockmsg)
+ RdDCombat.onSocketMessage(sockmsg)
+ ChatUtility.onSocketMessage(sockmsg)
+ RdDBaseActor.onSocketMessage(sockmsg)
} catch (e) {
console.error('game.socket.on(SYSTEM_SOCKET_ID) Exception: ', sockmsg, ' => ', e)
}
- });
+ })
/* -------------------------------------------- */
// Define custom Entity classes
- CONFIG.Actor.documentClass = RdDBaseActor;
- CONFIG.Item.documentClass = RdDItem;
+ CONFIG.Actor.documentClass = RdDBaseActor
+ CONFIG.Item.documentClass = RdDItem
CONFIG.RDD = {
resolutionTable: RdDResolutionTable.resolutionTable,
carac_array: RdDUtility.getCaracArray(),
@@ -153,30 +156,31 @@ export class SystemReveDeDragon {
/* -------------------------------------------- */
// Register sheet application classes
- Actors.unregisterSheet("core", ActorSheet);
- Actors.registerSheet(SYSTEM_RDD, RdDCommerceSheet, { types: ["commerce"], makeDefault: true });
- Actors.registerSheet(SYSTEM_RDD, RdDActorSheet, { types: ["personnage"], makeDefault: true });
- Actors.registerSheet(SYSTEM_RDD, RdDCreatureSheet, { types: ["creature"], makeDefault: true });
- Actors.registerSheet(SYSTEM_RDD, RdDActorVehiculeSheet, { types: ["vehicule"], makeDefault: true });
- Actors.registerSheet(SYSTEM_RDD, RdDActorEntiteSheet, { types: ["entite"], makeDefault: true });
- Items.unregisterSheet("core", ItemSheet);
+ Actors.unregisterSheet("core", ActorSheet)
+ Actors.registerSheet(SYSTEM_RDD, RdDCommerceSheet, { types: ["commerce"], makeDefault: true })
+ Actors.registerSheet(SYSTEM_RDD, RdDActorExportSheet, { types: ["personnage"], makeDefault: false })
+ Actors.registerSheet(SYSTEM_RDD, RdDActorSheet, { types: ["personnage"], makeDefault: true })
+ Actors.registerSheet(SYSTEM_RDD, RdDCreatureSheet, { types: ["creature"], makeDefault: true })
+ Actors.registerSheet(SYSTEM_RDD, RdDActorVehiculeSheet, { types: ["vehicule"], makeDefault: true })
+ Actors.registerSheet(SYSTEM_RDD, RdDActorEntiteSheet, { types: ["entite"], makeDefault: true })
+ Items.unregisterSheet("core", ItemSheet)
- RdDItemSheet.register(RdDSigneDraconiqueItemSheet);
- RdDItemSheet.register(RdDRencontreItemSheet);
- RdDItemSheet.register(RdDConteneurItemSheet);
- RdDItemSheet.register(RdDHerbeItemSheet);
- RdDItemSheet.register(RdDFauneItemSheet);
- RdDItemSheet.register(RdDPlanteItemSheet);
- RdDItemSheet.register(RdDIngredientItemSheet);
- RdDItemSheet.register(RdDServiceItemSheet);
- RdDItemSheet.register(RdDBlessureItemSheet);
+ RdDItemSheet.register(RdDSigneDraconiqueItemSheet)
+ RdDItemSheet.register(RdDRencontreItemSheet)
+ RdDItemSheet.register(RdDConteneurItemSheet)
+ RdDItemSheet.register(RdDHerbeItemSheet)
+ RdDItemSheet.register(RdDFauneItemSheet)
+ RdDItemSheet.register(RdDPlanteItemSheet)
+ RdDItemSheet.register(RdDIngredientItemSheet)
+ RdDItemSheet.register(RdDServiceItemSheet)
+ RdDItemSheet.register(RdDBlessureItemSheet)
Items.registerSheet(SYSTEM_RDD, RdDItemInventaireSheet, {
types: [
"objet", "arme", "armure", "livre", "potion", "munition",
"monnaie", "nourritureboisson", "gemme",
], makeDefault: true
- });
+ })
Items.registerSheet(SYSTEM_RDD, RdDItemSheet, {
types: [
"competence", "competencecreature",
@@ -185,31 +189,32 @@ export class SystemReveDeDragon {
"nombreastral", "tache", "maladie", "poison", "possession",
"tarot", "extraitpoetique", "empoignade"
], makeDefault: true
- });
- CONFIG.Combat.documentClass = RdDCombatManager;
+ })
+ CONFIG.Combat.documentClass = RdDCombatManager
// préparation des différents modules
- AutoAdjustDarkness.init();
- RdDTimestamp.init();
- RdDCalendrier.init();
- SystemCompendiums.init();
- DialogChronologie.init();
- ReglesOptionnelles.init();
- RdDUtility.init();
- RdDDice.init();
- RdDCommands.init();
- RdDCombatManager.init();
- RdDTokenHud.init();
- RdDBaseActor.init();
- RdDCompendiumOrganiser.init();
+ AutoAdjustDarkness.init()
+ RdDTimestamp.init()
+ RdDCalendrier.init()
+ SystemCompendiums.init()
+ DialogChronologie.init()
+ ReglesOptionnelles.init()
+ OptionsAvancees.init()
+ RdDUtility.init()
+ RdDDice.init()
+ RdDCommands.init()
+ RdDCombatManager.init()
+ RdDTokenHud.init()
+ RdDBaseActor.init()
+ RdDCompendiumOrganiser.init()
EffetsDraconiques.init()
- TMRUtility.init();
+ TMRUtility.init()
await RdDTMRDialog.init()
- RdDHotbar.initDropbar();
- RdDPossession.init();
- TMRRencontres.init();
- Environnement.init();
-
+ RdDHotbar.init()
+ RdDPossession.init()
+ TMRRencontres.init()
+ Environnement.init()
+ ExportScriptarium.init()
}
initSystemSettings() {
@@ -225,7 +230,7 @@ export class SystemReveDeDragon {
"avant-encaissement": "Avant l'encaissement",
},
default: "avant-encaissement"
- });
+ })
/* -------------------------------------------- */
game.settings.register(SYSTEM_RDD, "supprimer-dialogues-combat-chat", {
@@ -235,7 +240,7 @@ export class SystemReveDeDragon {
config: true,
default: true,
type: Boolean
- });
+ })
/* -------------------------------------------- */
game.settings.register(SYSTEM_RDD, "activer-sons-audio", {
@@ -245,7 +250,8 @@ export class SystemReveDeDragon {
config: true,
default: true,
type: Boolean
- });
+ })
+
/* -------------------------------------------- */
game.settings.register(SYSTEM_RDD, "appliquer-famine-soif", {
name: "Notifier de la famine et la soif pour",
@@ -259,7 +265,7 @@ export class SystemReveDeDragon {
"famine-soif": "la famine et la soif",
},
default: "aucun"
- });
+ })
}
async onReady() {
@@ -267,47 +273,47 @@ export class SystemReveDeDragon {
/* -------------------------------------------- */
/* Foundry VTT Initialization */
/* -------------------------------------------- */
- game.system.rdd.calendrier = new RdDCalendrier();
+ game.system.rdd.calendrier = new RdDCalendrier()
if (Misc.isUniqueConnectedGM()) {
- new Migrations().migrate();
- this.messageDeBienvenue();
- import("https://www.uberwald.me/fvtt_appcount/count-class-ready.js").then(moduleCounter=>{
+ new Migrations().migrate()
+ this.messageDeBienvenue()
+ import("https://www.uberwald.me/fvtt_appcount/count-class-ready.js").then(moduleCounter => {
console.log("ClassCounter loaded", moduleCounter)
moduleCounter.ClassCounter.registerUsageCount()
- }).catch(err=>
+ }).catch(err =>
console.log("No stats available, giving up.")
- )
+ )
}
- StatusEffects.onReady();
- RdDHerbes.initializeHerbes();
- RdDDice.onReady();
+ StatusEffects.onReady()
+ RdDHerbes.onReady()
+ RdDDice.onReady()
/* -------------------------------------------- */
/* Affiche/Init le calendrier */
- game.system.rdd.calendrier.display();
+ game.system.rdd.calendrier.display()
// Avertissement si joueur sans personnage
if (!game.user.isGM && game.user.character == undefined) {
- ui.notifications.info("Attention ! Vous n'êtes connecté à aucun personnage !");
+ ui.notifications.info("Attention ! Vous n'êtes connecté à aucun personnage !")
ChatMessage.create({
content: "ATTENTION Le joueur " + game.user.name + " n'est connecté à aucun personnage !",
user: game.user.id
- });
+ })
}
}
/* -------------------------------------------- */
messageDeBienvenue() {
if (game.user.isGM) {
- ChatUtility.removeChatMessageContaining('
/aide
dans le chat permet de voir les commandes spécifiques à Rêve de Dragon.