forked from public/foundryvtt-reve-de-dragon
Compare commits
19 Commits
33ee90c003
...
12.0.25
Author | SHA1 | Date | |
---|---|---|---|
39ce66a26c | |||
5265c013c1 | |||
a03cee5d60 | |||
296c4babbb | |||
d9c1804a08 | |||
fa375f8092 | |||
a27e3894a0 | |||
ce8616c34e | |||
bbfac286a6 | |||
c0563efcfa | |||
c481bad81a | |||
37c281b300 | |||
9b1a179a71 | |||
8be4c3343f | |||
6af5a85dc1 | |||
c6d64e09d5 | |||
56c99c5044 | |||
a7862a25e5 | |||
f4b5a4a4d2 |
@ -27,8 +27,8 @@ jobs:
|
||||
env:
|
||||
version: ${{steps.get_version.outputs.version-without-v}}
|
||||
url: https://www.uberwald.me/gitea/${{gitea.repository}}
|
||||
manifest: https://www.uberwald.me/gitea/${{gitea.repository}}/releases/download//${{github.event.release.tag_name}}/system.json
|
||||
download: https://www.uberwald.me/gitea/${{gitea.repository}}/releases/download/${{github.event.release.tag_name}}/foundryvtt-reve-de-dragon-${{github.event.release.tag_name}}.zip
|
||||
manifest: https://www.uberwald.me/gitea/${{gitea.repository}}/releases/download/${{github.event.release.tag_name}}/system.json
|
||||
download: https://www.uberwald.me/gitea/${{gitea.repository}}/releases/download/${{github.event.release.tag_name}}/rddsystem.zip
|
||||
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@v2
|
||||
@ -46,7 +46,7 @@ jobs:
|
||||
apt update -y
|
||||
apt install -y zip
|
||||
|
||||
- run: zip -r ./foundryvtt-reve-de-dragon-${{github.event.release.tag_name}}.zip system.json template.json README.md LICENSE.txt assets/ fonts/ icons lang/ module/ packs/ pic/ sounds/ styles/ templates/
|
||||
- run: zip -r ./rddsystem.zip system.json template.json README.md LICENSE.txt assets/ fonts/ icons lang/ module/ packs/ pic/ sounds/ styles/ templates/
|
||||
|
||||
- name: setup go
|
||||
uses: actions/setup-go@v3
|
||||
@ -58,6 +58,17 @@ jobs:
|
||||
uses: https://gitea.com/actions/release-action@main
|
||||
with:
|
||||
files: |-
|
||||
./foundryvtt-reve-de-dragon-${{github.event.release.tag_name}}.zip
|
||||
./rddsystem.zip
|
||||
system.json
|
||||
api_key: '${{secrets.ALLOW_PUSH_RELEASE}}'
|
||||
|
||||
- name: Publish to Foundry server
|
||||
uses: djlechuck/foundryvtt-publish-package-action@v1
|
||||
with:
|
||||
token: ${{ secrets.FOUNDRYVTT_RELEASE_TOKEN }}
|
||||
id: 'foundryvtt-reve-de-dragon'
|
||||
version: ${{github.event.release.tag_name}}
|
||||
manifest: 'https://www.uberwald.me/gitea/${{gitea.repository}}/releases/download/${{github.event.release.tag_name}}/system.json'
|
||||
notes: 'https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/raw/branch/v11/changelog.md'
|
||||
compatibility-minimum: '12'
|
||||
compatibility-verified: '12'
|
@ -1,6 +1,11 @@
|
||||
# 12.0
|
||||
## 12.0.24 - La ajustements d'Astrobazzarh
|
||||
## 12.0.24 - Les ajustements d'Astrobazzarh
|
||||
- amélioration
|
||||
- meilleure gestion des noms des voies de draconic
|
||||
- affichage du détail des sorts avec le nom de voie, 'court', la difficulté, le coût
|
||||
- corrections
|
||||
- les tas dans les conteneurs peuvent être désempilés sans rendre le conteneur inutilisable
|
||||
- les conteneurs ne peuvent plus être empilés (pour éviter que le contenu de Schroedinger quand on les sépare)
|
||||
- on peut maintenant saisir et supprimer les bonus de cases de manière intuitive
|
||||
|
||||
## 12.0.23 - La bibliothèque d'Astrobazzarh
|
||||
|
@ -3017,15 +3017,16 @@ export class RdDActor extends RdDBaseActorSang {
|
||||
case 'queue':
|
||||
case 'ombre':
|
||||
case 'souffle':
|
||||
await this.onDeleteOwnedDraconique(item, options, id);
|
||||
break;
|
||||
await this.onDeleteOwnedDraconique(item, options, id)
|
||||
break
|
||||
case 'casetmr':
|
||||
await this.onDeleteOwnedCaseTmr(item, options, id);
|
||||
break;
|
||||
await this.onDeleteOwnedCaseTmr(item, options, id)
|
||||
break
|
||||
case 'empoignade':
|
||||
await RdDEmpoignade.deleteLinkedEmpoignade(this.id, item)
|
||||
break;
|
||||
break
|
||||
}
|
||||
super.onDeleteItem(item, options, id)
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
|
@ -213,8 +213,20 @@ export class RdDBaseActor extends Actor {
|
||||
/* -------------------------------------------- */
|
||||
async onPreUpdateItem(item, change, options, id) { }
|
||||
async onCreateItem(item, options, id) { }
|
||||
async onDeleteItem(item, options, id) { }
|
||||
async onUpdateActor(update, options, actorId) { }
|
||||
async onDeleteItem(item, options, id) {
|
||||
if (item.isInventaire()) {
|
||||
this._removeItemFromConteneur(item)
|
||||
}
|
||||
}
|
||||
|
||||
_removeItemFromConteneur(item) {
|
||||
this.items.filter(it => it.isConteneur() && it.system.contenu.includes(item.id))
|
||||
.forEach(conteneur => {
|
||||
const nouveauContenu = conteneur.system.contenu.filter(id => id != item.id);
|
||||
conteneur.update({ 'system.contenu': nouveauContenu });
|
||||
});
|
||||
}
|
||||
|
||||
async onTimeChanging(oldTimestamp, newTimestamp) {
|
||||
this.items.filter(it => it.isFinPeriode(oldTimestamp, newTimestamp))
|
||||
|
@ -238,7 +238,7 @@ export class Mapping {
|
||||
|
||||
static prepareSorts(actor) {
|
||||
const codeVoies = Mapping.getCompetencesCategorie(actor, CATEGORIES_DRACONIC)
|
||||
.map(it => RdDItemSort.getVoieCode(it))
|
||||
.map(it => RdDItemSort.getCodeVoie(it.name))
|
||||
|
||||
return actor.itemTypes[ITEM_TYPES.sort].map(it => Mapping.prepareSort(it, codeVoies))
|
||||
.sort(Misc.ascending(it => `${it.voie} : ${it.description}`))
|
||||
@ -246,7 +246,7 @@ export class Mapping {
|
||||
|
||||
static prepareSort(sort, voies) {
|
||||
return {
|
||||
voie: RdDItemSort.getCodeDraconic(sort, voies),
|
||||
voie: RdDItemSort.getCode(sort, voies),
|
||||
description: Mapping.descriptionSort(sort),
|
||||
bonus: Mapping.bonusCase(sort)
|
||||
}
|
||||
@ -255,17 +255,9 @@ export class Mapping {
|
||||
static descriptionSort(sort) {
|
||||
const ptSeuil = Array(sort.system.coutseuil).map(it => '*')
|
||||
const caseTMR = sort.system.caseTMRspeciale.length > 0 ? Mapping.toVar(sort.system.caseTMRspeciale) : Misc.upperFirst(TMRType[sort.system.caseTMR].name)
|
||||
const ptreve = Mapping.addSpaceToNonNumeric(sort.system.ptreve)
|
||||
const diff = Mapping.addSpaceToNonNumeric(sort.system.difficulte)
|
||||
return `${sort.name}${ptSeuil} (${caseTMR}) R${diff} r${ptreve}`
|
||||
}
|
||||
|
||||
static addSpaceToNonNumeric(value) {
|
||||
return Number.isNumeric(value) || /[-\d].*/.match(String(value)) ? value : ' ' + Mapping.toVar(value)
|
||||
}
|
||||
|
||||
static toVar(value) {
|
||||
return value.replace('variable', 'var')
|
||||
const coutReve = 'r' + RdDItemSort.addSpaceToNonNumeric(sort.system.ptreve)
|
||||
const diff = 'R' + RdDItemSort.addSpaceToNonNumeric(sort.system.difficulte)
|
||||
return `${sort.name}${ptSeuil} (${caseTMR}) ${diff} ${coutReve}`
|
||||
}
|
||||
|
||||
static bonusCase(sort) {
|
||||
|
@ -2,6 +2,373 @@
|
||||
import "./xregexp-all.js";
|
||||
import { SystemCompendiums } from "../settings/system-compendiums.js";
|
||||
import { RdDBaseActorReve } from "../actor/base-actor-reve.js";
|
||||
import { Grammar } from "../grammar.js";
|
||||
import { Misc } from "../misc.js";
|
||||
import { ENTITE_INCARNE, ENTITE_NONINCARNE } from "../constants.js";
|
||||
|
||||
const WHITESPACES = "\\s+"
|
||||
const NUMERIC = "[\\+\\-]?\\d+"
|
||||
const NUMERIC_VALUE = "(?<value>" + NUMERIC + ")"
|
||||
|
||||
const XREGEXP_NAME = "(?<name>[A-Za-zÀ-ÖØ-öø-ÿ\\s\\-]+)"
|
||||
const XREGEXP_COMP_CREATURE = WHITESPACES + "(?<carac>\\d+)"
|
||||
+ WHITESPACES + NUMERIC_VALUE
|
||||
+ "(" + WHITESPACES + "(?<init>\\d+)?\\s+?(?<dommages>[\\+\\-]?\\d+)?" + ")?"
|
||||
|
||||
// Skill parser depending on the type of actor
|
||||
const compParser = {
|
||||
personnage: "(\\D+)*" + WHITESPACES + NUMERIC_VALUE,
|
||||
creature: XREGEXP_COMP_CREATURE,
|
||||
entite: XREGEXP_COMP_CREATURE
|
||||
}
|
||||
|
||||
const XREGEXP_SORT_VOIE = "[OHNT\\/]+"
|
||||
const XREGEXP_SORT_CASE = "\\((?<case>[A-Za-zÀ-ÖØ-öø-ÿ\\s\\-]+)\\)";
|
||||
|
||||
const XREGEXP_SORT = "(" + XREGEXP_SORT_VOIE
|
||||
+ WHITESPACES + XREGEXP_NAME
|
||||
+ WHITESPACES + XREGEXP_SORT_CASE
|
||||
+ WHITESPACES + "R(?<diff>([\\-\\d]+|(\\w|\\s)+))"
|
||||
+ WHITESPACES + "r(?<reve>(\\d+(\\+)?|\\s\\w+))"
|
||||
+ "(" + WHITESPACES + "\\+(?<bonus>\\d+)\\s?%" + WHITESPACES + "en" + WHITESPACES + "(?<bonuscase>[A-M]\\d{1,2})" + ")?"
|
||||
+ ")"
|
||||
|
||||
|
||||
// Main class for parsing a stat block
|
||||
export class RdDStatBlockParser {
|
||||
|
||||
static openInputDialog() {
|
||||
let dialog = new Dialog({
|
||||
title: "Import de stats de PNJ/Créatures",
|
||||
content: `
|
||||
<div>
|
||||
<p>Coller le texte de la stat ici</p>
|
||||
<textarea id="statBlock" style="width: 100%; height: 200px;"></textarea>
|
||||
</div>
|
||||
`,
|
||||
buttons: {
|
||||
ok: {
|
||||
label: "OK",
|
||||
callback: async (html) => {
|
||||
let statBlock = html.find("#statBlock")[0].value;
|
||||
await RdDStatBlockParser.parseStatBlock(statBlock);
|
||||
dialog.close();
|
||||
}
|
||||
},
|
||||
cancel: {
|
||||
label: "Cancel"
|
||||
}
|
||||
}
|
||||
});
|
||||
dialog.render(true);
|
||||
}
|
||||
|
||||
static fixWeirdPDF(statString) {
|
||||
// Split the statString into lines
|
||||
let lines = statString.split("\n");
|
||||
let newLines = [];
|
||||
let index = 0;
|
||||
let nextType = "string";
|
||||
// Loop through each line
|
||||
for (let i = 0; i < lines.length; i++) {
|
||||
// remove trailing spaces
|
||||
lines[i] = lines[i].trim();
|
||||
// Is it text ?
|
||||
if (lines[i].match(/^[a-zA-Zéêè\s]+/)) {
|
||||
if (nextType == "string") {
|
||||
newLines[index] = lines[i];
|
||||
nextType = "number";
|
||||
} else {
|
||||
console.log("Wrong sequence string detected...", lines[i], nextType);
|
||||
}
|
||||
}
|
||||
// Is it a number ?
|
||||
if (lines[i].match(/^[\d\s]+/)) {
|
||||
if (nextType == "number") {
|
||||
newLines[index] = newLines[index] + lines[i];
|
||||
nextType = "string";
|
||||
index++;
|
||||
} else {
|
||||
console.log("Wrong sequence number detected...", lines[i], nextType);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static getHeureKey(heure) {
|
||||
for (let h of game.system.rdd.config.heuresRdD) {
|
||||
if (h.label.toLowerCase() == heure.toLowerCase()) {
|
||||
return h.value;
|
||||
}
|
||||
}
|
||||
return "vaisseau";
|
||||
}
|
||||
|
||||
static async parseStatBlock(statString, type = "npc") {
|
||||
|
||||
//statString = statBlock03;
|
||||
if (!statString) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Special function to fix strange/weird copy/paste from PDF readers
|
||||
// Unused up to now : this.fixWeirdPDF(statString);
|
||||
|
||||
// Replace all endline by space in the statString
|
||||
statString = statString.replace(/\n/g, " ");
|
||||
// Remove all multiple spaces
|
||||
statString = statString.replace(/\s{2,}/g, " ");
|
||||
// Remove all leading and trailing spaces
|
||||
statString = statString.trim();
|
||||
|
||||
// TODO: check for entite
|
||||
let actorType = RdDStatBlockParser.parseActorType(statString);
|
||||
|
||||
// Now start carac
|
||||
let actorData = foundry.utils.deepClone(game.model.Actor[actorType]);
|
||||
for (let key in actorData.carac) {
|
||||
let caracDef = actorData.carac[key];
|
||||
// Parse the stat string for each caracteristic
|
||||
let carac = XRegExp.exec(statString, XRegExp(caracDef.label + "\\s+(?<value>\\d+)", 'giu'));
|
||||
if (carac?.value) {
|
||||
actorData.carac[key].value = Number(carac.value);
|
||||
}
|
||||
}
|
||||
|
||||
// If creature we need to setup additionnal fields
|
||||
switch (actorType) {
|
||||
case "creature":
|
||||
RdDStatBlockParser.parseCreature(statString, actorData)
|
||||
break
|
||||
case "entite":
|
||||
RdDStatBlockParser.parseEntite(statString, actorData)
|
||||
break
|
||||
}
|
||||
|
||||
let items = [];
|
||||
// Get skills from compendium
|
||||
const competences = await SystemCompendiums.getCompetences(actorType);
|
||||
//console.log("Competences : ", competences);
|
||||
for (let comp of competences) {
|
||||
let compMatch = XRegExp.exec(statString, XRegExp(comp.name + compParser[actorType], 'giu'));
|
||||
if (compMatch) {
|
||||
comp = comp.toObject()
|
||||
comp.system.niveau = Number(compMatch.value);
|
||||
if (actorType == "creature" || actorType == "entite") {
|
||||
comp.system.carac_value = Number(compMatch.carac);
|
||||
if (compMatch.dommages != undefined) {
|
||||
comp.system.dommages = Number(compMatch.dommages);
|
||||
comp.system.iscombat = true;
|
||||
}
|
||||
}
|
||||
items.push(comp)
|
||||
}
|
||||
else if (actorType == "personnage") {
|
||||
comp = comp.toObject()
|
||||
items.push(comp)
|
||||
}
|
||||
}
|
||||
|
||||
// Now process weapons
|
||||
const weapons = await SystemCompendiums.getWorldOrCompendiumItems("arme", "equipement")
|
||||
//console.log("Equipement : ", equipment);
|
||||
// TODO: les noms d'armes peuvent avoir un suffixe (à une main, lancée) qui détermine la compétence correspondante
|
||||
// TODO: une arme peut être spécifique ("fourche"), ajouter une compétence dans ces cas là?
|
||||
for (let weapon of weapons) {
|
||||
let weapMatch = XRegExp.exec(statString, XRegExp(weapon.name + "\\s+(?<value>\\+\\d+)", 'giu'));
|
||||
if (weapMatch) {
|
||||
weapon = weapon.toObject()
|
||||
weapon.system.equipe = 'true'
|
||||
items.push(weapon)
|
||||
// now process the skill
|
||||
if (weapon.system?.competence != "") {
|
||||
let wComp = items.find(i => Grammar.equalsInsensitive(i.name, weapon.system.competence))
|
||||
if (wComp) {
|
||||
wComp.system.niveau = Number(weapMatch.value);
|
||||
}
|
||||
}
|
||||
if (weapon.system?.tir != "") {
|
||||
let wComp = items.find(i => Grammar.equalsInsensitive(i.name, weapon.system.tir))
|
||||
if (wComp) {
|
||||
wComp.system.niveau = Number(weapMatch.value);
|
||||
}
|
||||
}
|
||||
if (weapon.system?.lancer != "") {
|
||||
let wComp = items.find(i => Grammar.equalsInsensitive(i.name, weapon.system.lancer))
|
||||
if (wComp) {
|
||||
wComp.system.niveau = Number(weapMatch.value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Now process armors
|
||||
const armors = await SystemCompendiums.getWorldOrCompendiumItems("armure", "equipement")
|
||||
for (let armor of armors) {
|
||||
let matchArmor = XRegExp.exec(statString, XRegExp(armor.name, 'giu'));
|
||||
if (matchArmor) {
|
||||
armor = armor.toObject()
|
||||
armor.system.equipe = true
|
||||
items.push(armor);
|
||||
}
|
||||
}
|
||||
|
||||
// Attemp to detect spell
|
||||
let hautRevant = false
|
||||
let sorts = await SystemCompendiums.getWorldOrCompendiumItems("sort", "sorts-oniros")
|
||||
sorts = sorts.concat(await SystemCompendiums.getWorldOrCompendiumItems("sort", "sorts-hypnos"))
|
||||
sorts = sorts.concat(await SystemCompendiums.getWorldOrCompendiumItems("sort", "sorts-narcos"))
|
||||
sorts = sorts.concat(await SystemCompendiums.getWorldOrCompendiumItems("sort", "sorts-thanatos"))
|
||||
|
||||
XRegExp.forEach(statString, XRegExp(XREGEXP_SORT, 'giu'),
|
||||
function (matchSort, i) {
|
||||
let sort = sorts.find(s => Grammar.equalsInsensitive(s.name, matchSort.name))
|
||||
if (sort) {
|
||||
hautRevant = true
|
||||
sort = sort.toObject();
|
||||
if (matchSort.bonus && matchSort.bonuscase) {
|
||||
sort.system.bonuscase = `${matchSort.bonuscase}:${matchSort.bonus}`
|
||||
}
|
||||
items.push(sort);
|
||||
}
|
||||
});
|
||||
|
||||
if (hautRevant) {
|
||||
let tetes = await SystemCompendiums.getWorldOrCompendiumItems("tete", "tetes-de-dragon-pour-tous-personnages")
|
||||
let donHR = tetes.find(t => Grammar.equalsInsensitive(t.name, "Don de Haut-Rêve"))
|
||||
if (donHR) {
|
||||
items.push(donHR.toObject());
|
||||
}
|
||||
}
|
||||
if (actorType == "personnage") {
|
||||
|
||||
let feminin = XRegExp.exec(statString, XRegExp("né(?<value>e?) à", 'giu'));
|
||||
actorData.sexe = (feminin?.value == 'e') ? 'féminin' : 'masculin'
|
||||
|
||||
// Get hour name : heure du XXXXX
|
||||
let heure = XRegExp.exec(statString, XRegExp("heure (du|de la|des|de l\')\\s*(?<value>[A-Za-zÀ-ÖØ-öø-ÿ\\s]+),", 'giu'));
|
||||
actorData.heure = this.getHeureKey(heure?.value || "Vaisseau");
|
||||
|
||||
// Get age
|
||||
let age = XRegExp.exec(statString, XRegExp("(?<value>\\d+) ans", 'giu'));
|
||||
if (age?.value) {
|
||||
actorData.age = Number(age.value);
|
||||
}
|
||||
// Get height
|
||||
let taille = XRegExp.exec(statString, XRegExp("(?<value>\\d+m\\d+)", 'giu'));
|
||||
if (taille?.value) {
|
||||
actorData.taille = taille.value;
|
||||
}
|
||||
// Get weight
|
||||
let poids = XRegExp.exec(statString, XRegExp("(?<value>\\d+) kg", 'giu'));
|
||||
if (poids?.value) {
|
||||
actorData.poids = poids.value;
|
||||
}
|
||||
// Get cheveux
|
||||
let cheveux = XRegExp.exec(statString, XRegExp("kg,\\s+(?<value>[A-Za-zÀ-ÖØ-öø-ÿ\\s\\-]+),\\s+yeux", 'giu'));
|
||||
if (cheveux?.value) {
|
||||
actorData.cheveux = cheveux.value;
|
||||
}
|
||||
// Get yeux
|
||||
let yeux = XRegExp.exec(statString, XRegExp("yeux\\s+(?<value>[A-Za-zÀ-ÖØ-öø-ÿ\\s\\-]+), Beau", 'giu'));
|
||||
if (yeux?.value) {
|
||||
actorData.yeux = yeux.value;
|
||||
}
|
||||
|
||||
// Get beauty
|
||||
let beaute = XRegExp.exec(statString, XRegExp("beauté\\s+(?<value>\\d+)", 'giu'));
|
||||
if (beaute?.value) {
|
||||
actorData.beaute = Number(beaute.value);
|
||||
}
|
||||
}
|
||||
|
||||
// Name is all string before ', né'
|
||||
let name = RdDStatBlockParser.extractName(actorType, statString);
|
||||
|
||||
let newActor = RdDBaseActorReve.create({ name: name || "Importé", type: actorType, system: actorData, items: items });
|
||||
|
||||
// DUmp....
|
||||
console.log(actorData);
|
||||
}
|
||||
|
||||
static parseCreature(statString, actorData) {
|
||||
let plusDom = XRegExp.exec(statString, XRegExp("\\+dom\\s+(?<value>[\\+\\-]?\\d+)", 'giu'));
|
||||
if (plusDom?.values) {
|
||||
actorData.attributs.plusdom.value = Number(plusDom.value);
|
||||
}
|
||||
let protection = XRegExp.exec(statString, XRegExp("protection\\s+(?<value>[\\-]?\\d+)", 'giu'));
|
||||
if (protection?.value) {
|
||||
actorData.attributs.protection.value = Number(protection.value);
|
||||
}
|
||||
let endurance = XRegExp.exec(statString, XRegExp("endurance\\s+(?<value>\\d+)", 'giu'));
|
||||
if (endurance?.value) {
|
||||
actorData.sante.endurance.value = Number(endurance.value);
|
||||
actorData.sante.endurance.max = Number(endurance.value);
|
||||
}
|
||||
let vie = XRegExp.exec(statString, XRegExp("vie\\s+(?<value>\\d+)", 'giu'));
|
||||
if (vie.value) {
|
||||
actorData.sante.vie.value = Number(vie.value);
|
||||
actorData.sante.vie.max = Number(vie.value);
|
||||
}
|
||||
let vitesse = XRegExp.exec(statString, XRegExp("vitesse\\s+(?<value>[\\d\\/]+)", 'giu'));
|
||||
if (vitesse?.value) {
|
||||
actorData.attributs.vitesse.value = vitesse.value;
|
||||
}
|
||||
}
|
||||
|
||||
static parseEntite(statString, actorData) {
|
||||
let plusDom = XRegExp.exec(statString, XRegExp("\\+dom\\s+(?<value>[\\+\\-]?\\d+)", 'giu'));
|
||||
if (plusDom?.values) {
|
||||
actorData.attributs.plusdom.value = Number(plusDom.value);
|
||||
}
|
||||
|
||||
actorData.definition.categorieentite = 'cauchemar'
|
||||
actorData.definition.typeentite = ENTITE_NONINCARNE
|
||||
let endurance = XRegExp.exec(statString, XRegExp("endurance\\s+(?<value>\\d+)", 'giu'));
|
||||
if (endurance?.value) {
|
||||
actorData.sante.endurance.value = Number(endurance.value);
|
||||
actorData.sante.endurance.max = Number(endurance.value);
|
||||
actorData.definition.typeentite = ENTITE_INCARNE
|
||||
}
|
||||
let vitesse = XRegExp.exec(statString, XRegExp("vitesse\\s+(?<value>[\\d\\/]+)", 'giu'));
|
||||
if (vitesse?.value) {
|
||||
actorData.attributs.vitesse.value = vitesse.value;
|
||||
}
|
||||
}
|
||||
|
||||
static parseActorType(statString) {
|
||||
let niveau = XRegExp.exec(statString, XRegExp("Niveau\\s+(?<value>[\\+\\-]?\\d+)", 'giu'))
|
||||
let perception = XRegExp.exec(statString, XRegExp("perception\\s+(?<value>\\d+)", 'giu'))
|
||||
if (perception?.value) {
|
||||
return "creature"
|
||||
}
|
||||
if (niveau?.value) {
|
||||
return "entite"
|
||||
}
|
||||
return "personnage"
|
||||
}
|
||||
|
||||
static extractName(actorType, statString) {
|
||||
switch (actorType) {
|
||||
case "personnage": return RdDStatBlockParser.extractNamePersonnage(statString);
|
||||
case "creature": return RdDStatBlockParser.extractNameCreature(statString);
|
||||
}
|
||||
return RdDStatBlockParser.extractNameCreature(statString);
|
||||
}
|
||||
|
||||
static extractNamePersonnage(statString) {
|
||||
let name = XRegExp.exec(statString, XRegExp("(?<value>[\\p{Letter}\\s\\d]+),", 'giu'));
|
||||
if (!name?.value) {
|
||||
name = XRegExp.exec(statString, XRegExp("(?<value>.+)\\s+taille", 'giu'));
|
||||
}
|
||||
return Misc.upperFirst(name?.value || "Importé");
|
||||
}
|
||||
|
||||
static extractNameCreature(statString) {
|
||||
const name = XRegExp.exec(statString, XRegExp("(?<value>.+)\\s+taille", 'giu'));
|
||||
return Misc.upperFirst(name?.value || "Importé");
|
||||
}
|
||||
}
|
||||
|
||||
/************************************************************************************/
|
||||
// Some internal test strings
|
||||
@ -76,7 +443,7 @@ Corps à corps
|
||||
(0)
|
||||
Esquive
|
||||
+8
|
||||
Escalade +4 / Saut +5 / Commerce +3 / Équitation
|
||||
Escalade, Saut +4 / Commerce +3 / Équitation
|
||||
+6 / Chirurgie 0 / Survie en extérieur +4 / Survie fo-
|
||||
rêt +6 / Acrobatie -2 / Métallurgie +2 / Natation +3 /
|
||||
Légendes -1 / Écriture -4
|
||||
@ -194,240 +561,4 @@ Discrétion
|
||||
Vigilance
|
||||
13
|
||||
+3
|
||||
`
|
||||
// Skill parser depending on the type of actor
|
||||
const compParser = { personnage: "\\s+(?<value>[\\+\\-]?\\d+)", creature: "\\s+(?<carac>\\d+)\\s+(?<value>[\\+\\-]?\\d+)\\s?(?<init>\\d+)?\\s+?(?<dommages>\\+\\d+)?" };
|
||||
|
||||
// Main class for parsing a stat block
|
||||
export class RdDStatBlockParser {
|
||||
|
||||
static openInputDialog() {
|
||||
let dialog = new Dialog({
|
||||
title: "Import de stats de PNJ/Créatures",
|
||||
content: `
|
||||
<div>
|
||||
<p>Coller le texte de la stat ici</p>
|
||||
<textarea id="statBlock" style="width: 100%; height: 200px;"></textarea>
|
||||
</div>
|
||||
`,
|
||||
buttons: {
|
||||
ok: {
|
||||
label: "OK",
|
||||
callback: async (html) => {
|
||||
let statBlock = html.find("#statBlock")[0].value;
|
||||
await RdDStatBlockParser.parseStatBlock(statBlock);
|
||||
dialog.close();
|
||||
}
|
||||
},
|
||||
cancel: {
|
||||
label: "Cancel"
|
||||
}
|
||||
}
|
||||
});
|
||||
dialog.render(true);
|
||||
}
|
||||
|
||||
static fixWeirdPDF(statString) {
|
||||
// Split the statString into lines
|
||||
let lines = statString.split("\n");
|
||||
let newLines = [];
|
||||
let index = 0;
|
||||
let nextType = "string";
|
||||
// Loop through each line
|
||||
for (let i = 0; i < lines.length; i++) {
|
||||
// remove trailing spaces
|
||||
lines[i] = lines[i].trim();
|
||||
// Is it text ?
|
||||
if (lines[i].match(/^[a-zA-Zéêè\s]+/)) {
|
||||
if ( nextType == "string" ) {
|
||||
newLines[index] = lines[i];
|
||||
nextType = "number";
|
||||
} else {
|
||||
console.log("Wrong sequence string detected...", lines[i], nextType);
|
||||
}
|
||||
}
|
||||
// Is it a number ?
|
||||
if (lines[i].match(/^[\d\s]+/)) {
|
||||
if ( nextType == "number" ) {
|
||||
newLines[index] = newLines[index] + lines[i];
|
||||
nextType = "string";
|
||||
index++;
|
||||
} else {
|
||||
console.log("Wrong sequence number detected...", lines[i], nextType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static async parseStatBlock(statString, type = "npc") {
|
||||
|
||||
//statString = statBlock03;
|
||||
if (!statString) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Special function to fix strange/weird copy/paste from PDF readers
|
||||
// Unused up to now : this.fixWeirdPDF(statString);
|
||||
|
||||
// Replace all endline by space in the statString
|
||||
statString = statString.replace(/\n/g, " ");
|
||||
// Remove all multiple spaces
|
||||
statString = statString.replace(/\s{2,}/g, " ");
|
||||
// Remove all leading and trailing spaces
|
||||
statString = statString.trim();
|
||||
|
||||
let actorType = "personnage";
|
||||
let perception = XRegExp.exec(statString.toLowerCase(), XRegExp("perception\\s+(?<value>\\d+)", 'gi'));
|
||||
if (perception?.value ) {
|
||||
actorType = "creature";
|
||||
}
|
||||
|
||||
// Now start carac
|
||||
let actorData = foundry.utils.deepClone(game.model.Actor[actorType]);
|
||||
for (let key in game.model.Actor.personnage.carac) {
|
||||
let caracDef = game.model.Actor.personnage.carac[key];
|
||||
// Parse the stat string for each caracteristic
|
||||
let carac = XRegExp.exec(statString.toLowerCase(), XRegExp(caracDef.label.toLowerCase()+"\\s+(?<value>\\d+)", 'gi'));
|
||||
if (carac?.value) {
|
||||
actorData.carac[key].value = Number(carac.value);
|
||||
}
|
||||
}
|
||||
|
||||
// If creature we need to setup additionnal fields
|
||||
if (actorType == "creature") {
|
||||
let plusDom = XRegExp.exec(statString.toLowerCase(), XRegExp("\\+dom\\s+(?<value>\\+\\d+)", 'gi'));
|
||||
if (plusDom?.values) {
|
||||
actorData.attributs.plusdom.value = Number(plusDom.value);
|
||||
}
|
||||
let protection = XRegExp.exec(statString.toLowerCase(), XRegExp("protection\\s+(?<value>\\d+)", 'gi'));
|
||||
if (protection?.value) {
|
||||
actorData.attributs.protection.value = Number(protection.value);
|
||||
}
|
||||
let endurance = XRegExp.exec(statString.toLowerCase(), XRegExp("endurance\\s+(?<value>\\d+)", 'gi'));
|
||||
if (endurance?.value) {
|
||||
actorData.sante.endurance.value = Number(endurance.value);
|
||||
actorData.sante.endurance.max = Number(endurance.value);
|
||||
}
|
||||
let vie = XRegExp.exec(statString.toLowerCase(), XRegExp("vie\\s+(?<value>\\d+)", 'gi'));
|
||||
if (vie.value) {
|
||||
actorData.sante.vie.value = Number(vie.value);
|
||||
actorData.sante.vie.max = Number(vie.value);
|
||||
}
|
||||
let vitesse = XRegExp.exec(statString.toLowerCase(), XRegExp("vitesse\\s+(?<value>[\\d\\/]+)", 'gi'));
|
||||
if (vitesse?.value) {
|
||||
actorData.attributs.vitesse.value = vitesse.value;
|
||||
}
|
||||
}
|
||||
|
||||
let items = [];
|
||||
// Get skills from compendium
|
||||
const competences = await SystemCompendiums.getCompetences(actorType);
|
||||
//console.log("Competences : ", competences);
|
||||
let allComp = competences.map(i => i.toObject())
|
||||
for (let comp of allComp) {
|
||||
let skill = XRegExp.exec(statString.toLowerCase(), XRegExp(comp.name.toLowerCase()+compParser[actorType], 'gi'));
|
||||
if (skill) {
|
||||
comp.system.niveau = Number(skill.value);
|
||||
if (actorType == "creature") {
|
||||
comp.system.carac_value = Number(skill.carac);
|
||||
if (skill.init) {
|
||||
comp.system.dommages = Number(skill.dommages);
|
||||
comp.system.iscombat = true;
|
||||
}
|
||||
items.push(comp); // Only selective push
|
||||
}
|
||||
}
|
||||
if (actorType == "personnage") {
|
||||
items.push(comp); // Always push
|
||||
}
|
||||
}
|
||||
|
||||
// Now process weapons
|
||||
const weapons = await SystemCompendiums.getWorldOrCompendiumItems("arme", "equipement")
|
||||
//console.log("Equipement : ", equipment);
|
||||
for (let w of weapons) {
|
||||
|
||||
let weapon = XRegExp.exec(statString.toLowerCase(), XRegExp(w.name.toLowerCase()+"\\s+(?<value>\\+\\d+)", 'gi'));
|
||||
if (weapon) {
|
||||
w.system.equipe = true
|
||||
items.push(w.toObject());
|
||||
// now process the skill
|
||||
if ( w.system?.competence != "") {
|
||||
let wComp = items.find(i => i.name.toLowerCase() == w.system.competence.toLowerCase());
|
||||
if (wComp) {
|
||||
wComp.system.niveau = Number(weapon.value);
|
||||
}
|
||||
}
|
||||
if ( w.system?.tir != "") {
|
||||
let wComp = items.find(i => i.name.toLowerCase() == w.system.tir.toLowerCase());
|
||||
if (wComp) {
|
||||
wComp.system.niveau = Number(weapon.value);
|
||||
}
|
||||
}
|
||||
if ( w.system?.lancer != "") {
|
||||
let wComp = items.find(i => i.name.toLowerCase() == w.system.lancer.toLowerCase());
|
||||
if (wComp) {
|
||||
wComp.system.niveau = Number(weapon.value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Now process armors
|
||||
const armors = await SystemCompendiums.getWorldOrCompendiumItems("armure", "equipement")
|
||||
for (let a of armors) {
|
||||
let armor = XRegExp.exec(statString.toLowerCase(), XRegExp(a.name.toLowerCase(), 'gi'));
|
||||
if (armor) {
|
||||
a.system.equipe = true
|
||||
items.push(a.toObject());
|
||||
}
|
||||
}
|
||||
|
||||
// Get hour name : heure du XXXXX
|
||||
let heure = XRegExp.exec(statString.toLowerCase(), XRegExp("heure du\\s+(?<value>\\w+)", 'gi'));
|
||||
if (heure?.value) {
|
||||
actorData.heure = heure.value;
|
||||
}
|
||||
// Get age
|
||||
let age = XRegExp.exec(statString.toLowerCase(), XRegExp("(?<value>\\d+) ans", 'gi'));
|
||||
if (age?.value) {
|
||||
actorData.age = Number(age.value);
|
||||
}
|
||||
// Get height
|
||||
let taille = XRegExp.exec(statString.toLowerCase(), XRegExp("(?<value>\\d+)m\\d+", 'gi'));
|
||||
if (taille?.value) {
|
||||
actorData.taille = taille.value;
|
||||
}
|
||||
// Get weight
|
||||
let poids = XRegExp.exec(statString.toLowerCase(), XRegExp("(?<value>\\d+) kg", 'gi'));
|
||||
if (poids?.value) {
|
||||
actorData.poids = poids.value;
|
||||
}
|
||||
// Get beauty
|
||||
let beaute = XRegExp.exec(statString.toLowerCase(), XRegExp("beauté\\s+(?<value>\\d+)", 'gi'));
|
||||
if (beaute?.value) {
|
||||
actorData.beaute = Number(beaute.value);
|
||||
}
|
||||
|
||||
// Name is all string before ', né'
|
||||
let name
|
||||
if (actorType == "personnage") {
|
||||
name = XRegExp.exec(statString.toLowerCase(), XRegExp("(?<value>[\\w\\s\\d]+),", 'gi'));
|
||||
if (!name?.value) {
|
||||
name = XRegExp.exec(statString.toLowerCase(), XRegExp("(?<value>.+)\\s+taille", 'gi'));
|
||||
}
|
||||
name = name?.value || "Importé";
|
||||
}
|
||||
if (actorType == "creature") {
|
||||
name = XRegExp.exec(statString.toLowerCase(), XRegExp("(?<value>.+)\\s+taille", 'gi'));
|
||||
name = name?.value || "Importé";
|
||||
}
|
||||
|
||||
let newActor = RdDBaseActorReve.create({name: name || "Importé", type:actorType, system: actorData, items: items});
|
||||
|
||||
// DUmp....
|
||||
console.log(actorData);
|
||||
}
|
||||
}
|
||||
|
||||
`
|
||||
|
@ -81,7 +81,7 @@ export class RdDItemCompetenceCreature extends Item {
|
||||
|
||||
static isParade(item) {
|
||||
if (item.type == ITEM_TYPES.competencecreature) {
|
||||
return armeData.system.categorie_parade || armeData.system.isparade
|
||||
return item.system.categorie_parade || item.system.isparade
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
@ -296,7 +296,7 @@ export class RdDItemSheet extends ItemSheet {
|
||||
))
|
||||
break
|
||||
case ITEM_TYPES.competence:
|
||||
formData['system.niveau'] = formData.system.niveau ?? formData.system.base
|
||||
formData['system.niveau'] = formData['system.niveau'] ?? formData['system.base']
|
||||
break
|
||||
}
|
||||
|
||||
|
@ -2,19 +2,32 @@ import { Grammar } from "./grammar.js";
|
||||
import { RdDItemCompetence } from "./item-competence.js";
|
||||
import { ITEM_TYPES } from "./item.js";
|
||||
import { Misc } from "./misc.js";
|
||||
import { FLEUVE_COORD, TMRType, TMRUtility } from "./tmr-utility.js";
|
||||
import { FLEUVE_COORD, TMRUtility } from "./tmr-utility.js";
|
||||
|
||||
const VOIES_DRACONIC = [
|
||||
export const VOIES_DRACONIC = [
|
||||
{ code: 'O', label: "Voie d'Oniros", short: 'Oniros', ordre: 'a' },
|
||||
{ code: 'H', label: "Voie d'Hypnos", short: 'Hypnos', ordre: 'b' },
|
||||
{ code: 'N', label: "Voie de Narcos", short: 'Narcos', ordre: 'c' },
|
||||
{ code: 'T', label: "Voie de Thanatos", short: 'Thanatos', ordre: 'd' },
|
||||
{ code: 'O/H/N/T', label: "Oniros/Hypnos/Narcos/Thanatos", short: 'Oniros/Hypnos/Narcos/Thanatos', ordre: 'e' },
|
||||
{ code: 'O/H/N', label: "Oniros/Hypnos/Narcos", short: "Oniros/Hypnos/Narcos", ordre: 'f' }
|
||||
{ code: 'O/H/N/T', label: "Oniros/Hypnos/Narcos/Thanatos", short: 'O/H/N/T', ordre: 'e' },
|
||||
{ code: 'O/H/N', label: "Oniros/Hypnos/Narcos", short: "O/H/N", ordre: 'f' }
|
||||
]
|
||||
|
||||
/* -------------------------------------------- */
|
||||
export class RdDItemSort extends Item {
|
||||
static preloadHandlebars() {
|
||||
Handlebars.registerHelper('itemSort-spaceIfText', val => RdDItemSort.addSpaceToNonNumeric(val))
|
||||
Handlebars.registerHelper('itemSort-codeDraconic', voie => RdDItemSort.getCode(voie))
|
||||
Handlebars.registerHelper('itemSort-shortDraconic', voie => RdDItemSort.getShortVoie(voie))
|
||||
}
|
||||
|
||||
static addSpaceToNonNumeric(value) {
|
||||
return Number.isNumeric(value) || ['-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'].includes( String(value).charAt[0]) ? value : ' ' + RdDItemSort.toVar(value)
|
||||
}
|
||||
|
||||
static toVar(value) {
|
||||
return value ? value.replace('variable', 'var') : ''
|
||||
}
|
||||
|
||||
static getDraconicsSort(competencesDraconic, sort) {
|
||||
// se baser sur la voie du sort?
|
||||
@ -33,20 +46,23 @@ export class RdDItemSort extends Item {
|
||||
return (VOIES_DRACONIC.find(it => it.code == code)?.ordre ?? '?')
|
||||
}
|
||||
|
||||
static getVoieCode(voie) {
|
||||
return VOIES_DRACONIC.find(it => voie.name.includes(it.short))?.code ?? '?'
|
||||
static getCodeVoie(voie) {
|
||||
return VOIES_DRACONIC.find(it => [it.code, it.short, it.label].includes(voie))?.code ?? '?'
|
||||
}
|
||||
|
||||
static getCodeDraconic(sort, voies = ['O', 'H', 'N', 'T']) {
|
||||
static getShortVoie(voie) {
|
||||
return VOIES_DRACONIC.find(it => [it.code, it.short, it.label].includes(voie))?.short ?? voie
|
||||
}
|
||||
|
||||
static getCode(sort, codeVoies = ['O', 'H', 'N', 'T']) {
|
||||
switch (Grammar.toLowerCaseNoAccent(sort.name)) {
|
||||
case "lecture d'aura":
|
||||
case "detection d'aura":
|
||||
return RdDItemSort.$voiesConnues('O/H/N/T', voies)
|
||||
return RdDItemSort.$voiesConnues('O/H/N/T', codeVoies)
|
||||
case "annulation de magie":
|
||||
return RdDItemSort.$voiesConnues('O/H/N', voies)
|
||||
return RdDItemSort.$voiesConnues('O/H/N', codeVoies)
|
||||
}
|
||||
const voie = VOIES_DRACONIC.find(it => it.label.includes(sort.system.draconic))
|
||||
return voie?.code ?? sort.system.draconic
|
||||
return RdDItemSort.getCodeVoie(sort.system.draconic)
|
||||
}
|
||||
|
||||
static $voiesConnues(voiesSort, voies) {
|
||||
|
@ -571,6 +571,7 @@ export class RdDItem extends Item {
|
||||
else {
|
||||
await this.quantiteIncDec(item.system.quantite);
|
||||
}
|
||||
// TODO: suppression dans les conteneurs!
|
||||
await item.delete();
|
||||
}
|
||||
|
||||
@ -601,6 +602,9 @@ export class RdDItem extends Item {
|
||||
if (!other || !this.isInventaire()) {
|
||||
return [false, undefined];
|
||||
}
|
||||
if (this.isConteneur()){
|
||||
return [false, `Impossible de regrouper des conteneurs, ils ne sont pas empilables`];
|
||||
}
|
||||
if (this.system.quantite == undefined) {
|
||||
return [false, `Impossible de regrouper des ${this.type}, ils ne sont pas empilables`];
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ import { Monnaie } from "./item-monnaie.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";
|
||||
import { VOIES_DRACONIC } from "./item-sort.js";
|
||||
|
||||
class Migration {
|
||||
get code() { return "sample"; }
|
||||
@ -530,6 +530,32 @@ class _11_2_20_MigrationAstrologie extends Migration {
|
||||
}
|
||||
}
|
||||
|
||||
class _12_0_24_MigrationVoieSorts extends Migration {
|
||||
get code() { return "migration-voies-sorts" }
|
||||
get version() { return "12.0.24" }
|
||||
|
||||
async migrate() {
|
||||
await this.applyItemsUpdates(items => items
|
||||
.filter(it => ITEM_TYPES.sort == it.type)
|
||||
.map(it => this.migrateSort(it))
|
||||
)
|
||||
}
|
||||
migrateSort(it) {
|
||||
return {
|
||||
_id: it.id,
|
||||
'system.draconic': this.convertDraconic(it.system.draconic),
|
||||
}
|
||||
}
|
||||
convertDraconic(draconic) {
|
||||
for (let v of VOIES_DRACONIC) {
|
||||
if ([v.label, v.short, v.code].includes(draconic)) {
|
||||
return v.short
|
||||
}
|
||||
}
|
||||
return draconic
|
||||
}
|
||||
}
|
||||
|
||||
export class Migrations {
|
||||
static getMigrations() {
|
||||
return [
|
||||
|
@ -69,6 +69,7 @@ import { ExportScriptarium } from "./actor/export-scriptarium/export-scriptarium
|
||||
import { AppPersonnageAleatoire } from "./actor/random/app-personnage-aleatoire.js"
|
||||
import { RdDActorExportSheet } from "./actor/export-scriptarium/actor-encart-sheet.js"
|
||||
import { RdDStatBlockParser } from "./apps/rdd-import-stats.js"
|
||||
import { RdDItemSort } from "./item-sort.js"
|
||||
|
||||
/**
|
||||
* RdD system
|
||||
@ -122,6 +123,7 @@ export class SystemReveDeDragon {
|
||||
// preload handlebars templates
|
||||
RdDUtility.preloadHandlebarsTemplates()
|
||||
AppPersonnageAleatoire.preloadHandlebars()
|
||||
RdDItemSort.preloadHandlebars()
|
||||
|
||||
/* -------------------------------------------- */
|
||||
ReglesOptionnelles.initSettings()
|
||||
|
@ -32,7 +32,7 @@ export class SystemCompendiums extends FormApplication {
|
||||
compendium: compendium,
|
||||
default: SystemCompendiums._getDefaultCompendium(compendium),
|
||||
setting: SystemCompendiums._getSettingCompendium(compendium)
|
||||
});
|
||||
})
|
||||
|
||||
game.settings.register(SYSTEM_RDD, definition.setting, {
|
||||
name: definition.label,
|
||||
@ -40,8 +40,8 @@ export class SystemCompendiums extends FormApplication {
|
||||
scope: "world",
|
||||
config: false,
|
||||
type: String
|
||||
});
|
||||
});
|
||||
})
|
||||
})
|
||||
|
||||
game.settings.registerMenu(SYSTEM_RDD, "compendium-settings", {
|
||||
name: "Choisir les compendiums système",
|
||||
@ -71,16 +71,18 @@ export class SystemCompendiums extends FormApplication {
|
||||
|
||||
static async getCompetences(actorType) {
|
||||
switch (actorType ?? 'personnage') {
|
||||
case 'personnage': return await SystemCompendiums.getWorldOrCompendiumItems('competence', 'competences');
|
||||
case 'creature': return await SystemCompendiums.getWorldOrCompendiumItems('competencecreature', 'competences-creatures');
|
||||
case 'entite': return await SystemCompendiums.getWorldOrCompendiumItems('competencecreature', 'competences-entites');
|
||||
case 'personnage':
|
||||
return await SystemCompendiums.getWorldOrCompendiumItems('competence', 'competences')
|
||||
case 'entite':
|
||||
case 'creature':
|
||||
return await SystemCompendiums.getWorldOrCompendiumItems('competencecreature', 'competences-creatures')
|
||||
case 'vehicule': return [];
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static async getWorldOrCompendiumItems(itemType, compendium) {
|
||||
let items = game.items.filter(it => it.type == itemType);
|
||||
let items = game.items.filter(it => it.type == itemType)
|
||||
if (compendium) {
|
||||
const ids = items.map(it => it.id);
|
||||
const names = items.map(it => it.name.toLowerCase());
|
||||
@ -284,7 +286,7 @@ export class CompendiumTableHelpers {
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static async tableRowToChatMessage(row, type, options = {showSource: true}) {
|
||||
static async tableRowToChatMessage(row, type, options = { showSource: true }) {
|
||||
if (!row) {
|
||||
return;
|
||||
}
|
||||
|
@ -6,17 +6,16 @@ effects: []
|
||||
system:
|
||||
description: ''
|
||||
descriptionmj: ''
|
||||
carac_value: 0
|
||||
niveau: 0
|
||||
default_diffLibre: 0
|
||||
categorie: generale
|
||||
carac_value: 10
|
||||
niveau: 1
|
||||
default_diffLibre: -2
|
||||
categorie: melee
|
||||
categorie_parade: ''
|
||||
iscombat: true
|
||||
isnaturelle: true
|
||||
ispossession: false
|
||||
dommages: 0
|
||||
mortalite: mortel
|
||||
carac-value: null
|
||||
isparade: false
|
||||
ownership:
|
||||
default: 0
|
@ -6,17 +6,16 @@ effects: []
|
||||
system:
|
||||
description: ''
|
||||
descriptionmj: ''
|
||||
carac_value: 0
|
||||
niveau: 0
|
||||
default_diffLibre: 0
|
||||
categorie: ''
|
||||
carac_value: 10
|
||||
niveau: 1
|
||||
default_diffLibre: -2
|
||||
categorie: melee
|
||||
categorie_parade: boucliers
|
||||
iscombat: true
|
||||
isnaturelle: true
|
||||
ispossession: false
|
||||
dommages: 0
|
||||
mortalite: mortel
|
||||
carac-value: null
|
||||
isparade: true
|
||||
ownership:
|
||||
default: 0
|
@ -1,22 +1,21 @@
|
||||
_id: WsYnwR8GcOxfuCI0
|
||||
name: Bras-Galet
|
||||
type: competencecreature
|
||||
img: systems/foundryvtt-reve-de-dragon/icons/competence_course.webp
|
||||
img: systems/foundryvtt-reve-de-dragon/icons/compcreature-pierretenue.webp
|
||||
effects: []
|
||||
system:
|
||||
description: ''
|
||||
descriptionmj: ''
|
||||
carac_value: 0
|
||||
niveau: 0
|
||||
default_diffLibre: 0
|
||||
categorie: ''
|
||||
carac_value: 10
|
||||
niveau: 1
|
||||
default_diffLibre: -2
|
||||
categorie: melee
|
||||
categorie_parade: ''
|
||||
iscombat: true
|
||||
isnaturelle: true
|
||||
ispossession: false
|
||||
dommages: 1
|
||||
mortalite: mortel
|
||||
carac-value: null
|
||||
isparade: false
|
||||
ownership:
|
||||
default: 0
|
@ -6,10 +6,10 @@ effects: []
|
||||
system:
|
||||
description: ''
|
||||
descriptionmj: ''
|
||||
carac_value: 0
|
||||
niveau: 0
|
||||
default_diffLibre: 0
|
||||
categorie: ''
|
||||
carac_value: 10
|
||||
niveau: 1
|
||||
default_diffLibre: -2
|
||||
categorie: melee
|
||||
categorie_parade: sans-armes
|
||||
iscombat: true
|
||||
isnaturelle: true
|
@ -6,17 +6,16 @@ effects: []
|
||||
system:
|
||||
description: ''
|
||||
descriptionmj: ''
|
||||
carac_value: 0
|
||||
niveau: 0
|
||||
default_diffLibre: 0
|
||||
categorie: ''
|
||||
carac_value: 10
|
||||
niveau: 1
|
||||
default_diffLibre: -2
|
||||
categorie: melee
|
||||
categorie_parade: ''
|
||||
iscombat: true
|
||||
isnaturelle: true
|
||||
ispossession: false
|
||||
dommages: 1
|
||||
mortalite: mortel
|
||||
carac-value: null
|
||||
isparade: false
|
||||
ownership:
|
||||
default: 0
|
@ -6,9 +6,9 @@ effects: []
|
||||
system:
|
||||
description: ''
|
||||
descriptionmj: ''
|
||||
carac_value: 0
|
||||
niveau: 0
|
||||
default_diffLibre: 0
|
||||
carac_value: 10
|
||||
niveau: 1
|
||||
default_diffLibre: -2
|
||||
categorie: melee
|
||||
categorie_parade: dagues
|
||||
iscombat: true
|
||||
|
@ -6,17 +6,16 @@ effects: []
|
||||
system:
|
||||
description: ''
|
||||
descriptionmj: ''
|
||||
carac_value: 0
|
||||
niveau: 0
|
||||
default_diffLibre: 0
|
||||
categorie: ''
|
||||
carac_value: 10
|
||||
niveau: 1
|
||||
default_diffLibre: -2
|
||||
categorie: melee
|
||||
categorie_parade: epees-lourdes
|
||||
iscombat: true
|
||||
isnaturelle: true
|
||||
isnaturelle: false
|
||||
ispossession: false
|
||||
dommages: 4
|
||||
mortalite: mortel
|
||||
carac-value: null
|
||||
isparade: true
|
||||
ownership:
|
||||
default: 0
|
@ -6,8 +6,8 @@ effects: []
|
||||
system:
|
||||
description: ''
|
||||
descriptionmj: ''
|
||||
carac_value: 0
|
||||
niveau: 0
|
||||
carac_value: 10
|
||||
niveau: 1
|
||||
default_diffLibre: 0
|
||||
categorie: generale
|
||||
categorie_parade: ''
|
||||
|
@ -0,0 +1,35 @@
|
||||
name: Esquive eau
|
||||
type: competencecreature
|
||||
img: systems/foundryvtt-reve-de-dragon/icons/competence_esquive.webp
|
||||
effects: []
|
||||
system:
|
||||
description: ''
|
||||
descriptionmj: ''
|
||||
carac_value: 10
|
||||
niveau: 1
|
||||
default_diffLibre: 0
|
||||
categorie: generale
|
||||
categorie_parade: ''
|
||||
iscombat: false
|
||||
isnaturelle: true
|
||||
ispossession: false
|
||||
dommages: 0
|
||||
mortalite: mortel
|
||||
isparade: false
|
||||
ownership:
|
||||
default: 0
|
||||
folder: null
|
||||
_stats:
|
||||
compendiumSource: null
|
||||
duplicateSource: null
|
||||
coreVersion: '12.331'
|
||||
systemId: foundryvtt-reve-de-dragon
|
||||
systemVersion: 12.0.24
|
||||
createdTime: 1733182927319
|
||||
modifiedTime: 1733182927336
|
||||
lastModifiedBy: Hp9ImM4o9YRTSdfu
|
||||
flags: {}
|
||||
_id: Qrg3ADB9LOhGthaO
|
||||
sort: 1300000
|
||||
_key: '!items!Qrg3ADB9LOhGthaO'
|
||||
|
@ -1,15 +1,14 @@
|
||||
_id: 0Ms9iKxqigNNpZEx
|
||||
name: Esquive
|
||||
name: Esquive sol
|
||||
type: competencecreature
|
||||
img: systems/foundryvtt-reve-de-dragon/icons/competence_esquive.webp
|
||||
effects: []
|
||||
system:
|
||||
description: ''
|
||||
descriptionmj: ''
|
||||
carac_value: 0
|
||||
niveau: 0
|
||||
carac_value: 10
|
||||
niveau: 1
|
||||
default_diffLibre: 0
|
||||
categorie: ''
|
||||
categorie: generale
|
||||
categorie_parade: ''
|
||||
iscombat: false
|
||||
isnaturelle: true
|
||||
@ -20,10 +19,17 @@ system:
|
||||
ownership:
|
||||
default: 0
|
||||
folder: null
|
||||
sort: 0
|
||||
_stats:
|
||||
systemId: foundryvtt-reve-de-dragon
|
||||
systemVersion: 12.0.22
|
||||
compendiumSource: null
|
||||
duplicateSource: null
|
||||
coreVersion: '12.331'
|
||||
_key: '!items!0Ms9iKxqigNNpZEx'
|
||||
systemId: foundryvtt-reve-de-dragon
|
||||
systemVersion: 12.0.24
|
||||
createdTime: 1733182930109
|
||||
modifiedTime: 1733182930109
|
||||
lastModifiedBy: Hp9ImM4o9YRTSdfu
|
||||
flags: {}
|
||||
_id: siPvW3hAMCJbrYvq
|
||||
sort: 0
|
||||
_key: '!items!siPvW3hAMCJbrYvq'
|
||||
|
@ -0,0 +1,35 @@
|
||||
name: Esquive vol
|
||||
type: competencecreature
|
||||
img: systems/foundryvtt-reve-de-dragon/icons/competence_esquive.webp
|
||||
effects: []
|
||||
system:
|
||||
description: ''
|
||||
descriptionmj: ''
|
||||
carac_value: 10
|
||||
niveau: 1
|
||||
default_diffLibre: 0
|
||||
categorie: generale
|
||||
categorie_parade: ''
|
||||
iscombat: false
|
||||
isnaturelle: true
|
||||
ispossession: false
|
||||
dommages: 0
|
||||
mortalite: mortel
|
||||
isparade: false
|
||||
ownership:
|
||||
default: 0
|
||||
folder: null
|
||||
_stats:
|
||||
compendiumSource: null
|
||||
duplicateSource: null
|
||||
coreVersion: '12.331'
|
||||
systemId: foundryvtt-reve-de-dragon
|
||||
systemVersion: 12.0.24
|
||||
createdTime: 1733182932133
|
||||
modifiedTime: 1733182932133
|
||||
lastModifiedBy: Hp9ImM4o9YRTSdfu
|
||||
flags: {}
|
||||
_id: 3ScoGTkQ0VBOpaX6
|
||||
sort: 0
|
||||
_key: '!items!3ScoGTkQ0VBOpaX6'
|
||||
|
@ -6,17 +6,16 @@ effects: []
|
||||
system:
|
||||
description: ''
|
||||
descriptionmj: ''
|
||||
carac_value: 0
|
||||
niveau: 0
|
||||
default_diffLibre: 0
|
||||
categorie: ''
|
||||
categorie_parade: ''
|
||||
iscombat: false
|
||||
carac_value: 10
|
||||
niveau: 1
|
||||
default_diffLibre: -2
|
||||
categorie: melee
|
||||
categorie_parade: boucliers
|
||||
iscombat: true
|
||||
isnaturelle: true
|
||||
ispossession: false
|
||||
dommages: 0
|
||||
mortalite: mortel
|
||||
carac-value: null
|
||||
isparade: false
|
||||
ownership:
|
||||
default: 0
|
@ -7,7 +7,7 @@ system:
|
||||
descriptionmj: ''
|
||||
carac_value: 14
|
||||
niveau: 2
|
||||
default_diffLibre: 0
|
||||
default_diffLibre: -4
|
||||
categorie: draconic
|
||||
categorie_parade: ''
|
||||
iscombat: true
|
||||
|
@ -1,29 +0,0 @@
|
||||
name: Possession
|
||||
type: competencecreature
|
||||
img: systems/foundryvtt-reve-de-dragon/icons/entites/possession.webp
|
||||
effects: []
|
||||
system:
|
||||
description: <p>L'entité tente de prendre possession du corps de sa victime.</p>
|
||||
descriptionmj: ''
|
||||
carac_value: 14
|
||||
niveau: 2
|
||||
default_diffLibre: 0
|
||||
categorie: draconic
|
||||
categorie_parade: ''
|
||||
iscombat: true
|
||||
isnaturelle: true
|
||||
ispossession: true
|
||||
dommages: 0
|
||||
mortalite: mortel
|
||||
isparade: false
|
||||
_id: duVgxI3Cdko0KzAj
|
||||
folder: null
|
||||
sort: 0
|
||||
ownership:
|
||||
default: 0
|
||||
_stats:
|
||||
systemId: foundryvtt-reve-de-dragon
|
||||
systemVersion: 12.0.22
|
||||
coreVersion: '12.331'
|
||||
_key: '!items!duVgxI3Cdko0KzAj'
|
||||
|
@ -6,10 +6,10 @@ effects: []
|
||||
system:
|
||||
description: <p>Attaque ou parade avec un tentacule.</p>
|
||||
descriptionmj: ''
|
||||
carac_value: 0
|
||||
niveau: 0
|
||||
default_diffLibre: 0
|
||||
categorie: ''
|
||||
carac_value: 10
|
||||
niveau: 1
|
||||
default_diffLibre: -2
|
||||
categorie: melee
|
||||
categorie_parade: boucliers
|
||||
iscombat: true
|
||||
isnaturelle: true
|
@ -6,9 +6,9 @@ effects: []
|
||||
system:
|
||||
description: ''
|
||||
descriptionmj: ''
|
||||
carac_value: 0
|
||||
niveau: 0
|
||||
default_diffLibre: 0
|
||||
carac_value: 10
|
||||
niveau: 1
|
||||
default_diffLibre: -2
|
||||
categorie: melee
|
||||
categorie_parade: ''
|
||||
iscombat: true
|
||||
|
@ -1,29 +0,0 @@
|
||||
_id: d5SZ09sFaG3cL2Rg
|
||||
name: Bec
|
||||
type: competencecreature
|
||||
img: systems/foundryvtt-reve-de-dragon/icons/compcreature-beak.webp
|
||||
effects: []
|
||||
system:
|
||||
description: ''
|
||||
descriptionmj: ''
|
||||
carac_value: 0
|
||||
niveau: 0
|
||||
default_diffLibre: 0
|
||||
categorie: ''
|
||||
categorie_parade: ''
|
||||
iscombat: true
|
||||
isnaturelle: true
|
||||
ispossession: false
|
||||
dommages: 0
|
||||
mortalite: mortel
|
||||
isparade: false
|
||||
ownership:
|
||||
default: 0
|
||||
folder: null
|
||||
sort: 0
|
||||
_stats:
|
||||
systemId: foundryvtt-reve-de-dragon
|
||||
systemVersion: 12.0.22
|
||||
coreVersion: '12.331'
|
||||
_key: '!items!d5SZ09sFaG3cL2Rg'
|
||||
|
@ -1,29 +0,0 @@
|
||||
_id: lDZ3qUPKN35ob5TH
|
||||
name: Grande morsure
|
||||
type: competencecreature
|
||||
img: systems/foundryvtt-reve-de-dragon/icons/compcreature-morsure.webp
|
||||
effects: []
|
||||
system:
|
||||
description: ''
|
||||
descriptionmj: ''
|
||||
carac_value: 0
|
||||
niveau: 0
|
||||
default_diffLibre: 0
|
||||
categorie: ''
|
||||
categorie_parade: ''
|
||||
iscombat: true
|
||||
isnaturelle: true
|
||||
ispossession: false
|
||||
dommages: 2
|
||||
mortalite: mortel
|
||||
isparade: false
|
||||
ownership:
|
||||
default: 0
|
||||
folder: null
|
||||
sort: 0
|
||||
_stats:
|
||||
systemId: foundryvtt-reve-de-dragon
|
||||
systemVersion: 12.0.22
|
||||
coreVersion: '12.331'
|
||||
_key: '!items!lDZ3qUPKN35ob5TH'
|
||||
|
@ -1,29 +0,0 @@
|
||||
_id: 6eWCVDYLXXO1Z48D
|
||||
name: Grandes griffes
|
||||
type: competencecreature
|
||||
img: systems/foundryvtt-reve-de-dragon/icons/compcreature-griffes.webp
|
||||
effects: []
|
||||
system:
|
||||
description: ''
|
||||
descriptionmj: ''
|
||||
carac_value: 0
|
||||
niveau: 0
|
||||
default_diffLibre: 0
|
||||
categorie: ''
|
||||
categorie_parade: sans-armes
|
||||
iscombat: true
|
||||
isnaturelle: true
|
||||
ispossession: false
|
||||
dommages: 2
|
||||
mortalite: mortel
|
||||
isparade: false
|
||||
ownership:
|
||||
default: 0
|
||||
folder: null
|
||||
sort: 0
|
||||
_stats:
|
||||
systemId: foundryvtt-reve-de-dragon
|
||||
systemVersion: 12.0.22
|
||||
coreVersion: '12.331'
|
||||
_key: '!items!6eWCVDYLXXO1Z48D'
|
||||
|
@ -1,30 +0,0 @@
|
||||
_id: 9Y83OsQgeyR5oCdH
|
||||
name: Griffes
|
||||
type: competencecreature
|
||||
img: systems/foundryvtt-reve-de-dragon/icons/compcreature-griffes.webp
|
||||
effects: []
|
||||
system:
|
||||
description: ''
|
||||
descriptionmj: ''
|
||||
carac_value: 0
|
||||
niveau: 0
|
||||
default_diffLibre: 0
|
||||
categorie: ''
|
||||
categorie_parade: sans-armes
|
||||
iscombat: true
|
||||
isnaturelle: true
|
||||
ispossession: false
|
||||
dommages: 1
|
||||
mortalite: mortel
|
||||
carac-value: null
|
||||
isparade: false
|
||||
ownership:
|
||||
default: 0
|
||||
folder: null
|
||||
sort: 0
|
||||
_stats:
|
||||
systemId: foundryvtt-reve-de-dragon
|
||||
systemVersion: 12.0.22
|
||||
coreVersion: '12.331'
|
||||
_key: '!items!9Y83OsQgeyR5oCdH'
|
||||
|
@ -1,29 +0,0 @@
|
||||
_id: j1xHCzfIeYKgXxoH
|
||||
name: Morsure
|
||||
type: competencecreature
|
||||
img: systems/foundryvtt-reve-de-dragon/icons/compcreature-morsure.webp
|
||||
effects: []
|
||||
system:
|
||||
description: ''
|
||||
descriptionmj: ''
|
||||
carac_value: 0
|
||||
niveau: 0
|
||||
default_diffLibre: 0
|
||||
categorie: ''
|
||||
categorie_parade: ''
|
||||
iscombat: true
|
||||
isnaturelle: true
|
||||
ispossession: false
|
||||
dommages: 1
|
||||
mortalite: mortel
|
||||
isparade: false
|
||||
ownership:
|
||||
default: 0
|
||||
folder: null
|
||||
sort: 0
|
||||
_stats:
|
||||
systemId: foundryvtt-reve-de-dragon
|
||||
systemVersion: 12.0.22
|
||||
coreVersion: '12.331'
|
||||
_key: '!items!j1xHCzfIeYKgXxoH'
|
||||
|
@ -1,29 +0,0 @@
|
||||
name: Possession
|
||||
type: competencecreature
|
||||
img: systems/foundryvtt-reve-de-dragon/icons/entites/possession.webp
|
||||
effects: []
|
||||
system:
|
||||
description: <p>L'entité tente de prendre possession du corps de sa victime.</p>
|
||||
descriptionmj: ''
|
||||
carac_value: 14
|
||||
niveau: 2
|
||||
default_diffLibre: -4
|
||||
categorie: melee
|
||||
categorie_parade: ''
|
||||
iscombat: true
|
||||
isnaturelle: true
|
||||
ispossession: true
|
||||
dommages: 0
|
||||
mortalite: mortel
|
||||
isparade: false
|
||||
ownership:
|
||||
default: 0
|
||||
folder: null
|
||||
sort: 0
|
||||
_id: wDHR5UHWq568lfGa
|
||||
_stats:
|
||||
systemId: foundryvtt-reve-de-dragon
|
||||
systemVersion: 12.0.22
|
||||
coreVersion: '12.331'
|
||||
_key: '!items!wDHR5UHWq568lfGa'
|
||||
|
46
system.json
46
system.json
@ -1,9 +1,9 @@
|
||||
{
|
||||
"id": "foundryvtt-reve-de-dragon",
|
||||
"title": "Rêve de Dragon",
|
||||
"version": "12.0.22",
|
||||
"download": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/releases/download/foundryvtt-reve-de-dragon-12.0.21/foundryvtt-reve-de-dragon-foundryvtt-reve-de-dragon-12.0.21.zip",
|
||||
"manifest": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/releases/download/latest/system.json",
|
||||
"version": "12.0.24",
|
||||
"download": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/releases/download/12.0.24/rddsystem.zip",
|
||||
"manifest": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/releases/download//12.0.24/system.json",
|
||||
"changelog": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/raw/branch/v11/changelog.md",
|
||||
"compatibility": {
|
||||
"minimum": "11",
|
||||
@ -53,7 +53,7 @@
|
||||
]
|
||||
}
|
||||
},
|
||||
"url": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/",
|
||||
"url": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon",
|
||||
"license": "LICENSE.txt",
|
||||
"esmodules": [
|
||||
"module/rdd-main.js"
|
||||
@ -115,19 +115,6 @@
|
||||
},
|
||||
"flags": {}
|
||||
},
|
||||
{
|
||||
"name": "competences-entites",
|
||||
"label": "Compétences des Entités",
|
||||
"system": "foundryvtt-reve-de-dragon",
|
||||
"path": "packs/competences-entites",
|
||||
"banner": "systems/foundryvtt-reve-de-dragon/styles/img/ui/compendium_banner.webp",
|
||||
"type": "Item",
|
||||
"ownership": {
|
||||
"PLAYER": "NONE",
|
||||
"ASSISTANT": "OWNER"
|
||||
},
|
||||
"flags": {}
|
||||
},
|
||||
{
|
||||
"name": "sorts-oniros",
|
||||
"label": "Sorts d'Oniros",
|
||||
@ -458,7 +445,7 @@
|
||||
"label": "Méditations et Ecrits",
|
||||
"system": "foundryvtt-reve-de-dragon",
|
||||
"path": "packs/meditations-et-ecrits",
|
||||
"banner": "systems/foundryvtt-reve-de-dragon/styles/img/ui/compendium_banner.webp",
|
||||
"banner": "systems/foundryvtt-reve-de-dragon/styles/img/ui/compendium_banner.webp",
|
||||
"type": "Item",
|
||||
"ownership": {
|
||||
"PLAYER": "NONE",
|
||||
@ -513,7 +500,9 @@
|
||||
"arts-et-divertissements",
|
||||
"meditations-et-ecrits",
|
||||
"recettes-alchimiques"
|
||||
]
|
||||
],
|
||||
"color": null,
|
||||
"folders": []
|
||||
},
|
||||
{
|
||||
"name": "Le Haut-rêve",
|
||||
@ -530,7 +519,9 @@
|
||||
"ombres-de-thanatos",
|
||||
"souffles-de-dragon",
|
||||
"tetes-de-dragon-pour-haut-revants"
|
||||
]
|
||||
],
|
||||
"color": null,
|
||||
"folders": []
|
||||
},
|
||||
{
|
||||
"name": "Découverte du monde",
|
||||
@ -541,9 +532,10 @@
|
||||
"entites",
|
||||
"faune-flore-mineraux",
|
||||
"competences-creatures",
|
||||
"competences-entites",
|
||||
"maladies-et-poisons"
|
||||
]
|
||||
],
|
||||
"color": null,
|
||||
"folders": []
|
||||
},
|
||||
{
|
||||
"name": "Outils du Gardien",
|
||||
@ -554,14 +546,16 @@
|
||||
"macros",
|
||||
"tarot-draconique",
|
||||
"extrait-poetique"
|
||||
]
|
||||
],
|
||||
"color": null,
|
||||
"folders": []
|
||||
}
|
||||
]
|
||||
],
|
||||
"color": null
|
||||
}
|
||||
],
|
||||
"socket": true,
|
||||
"grid": {
|
||||
"distance": 1,
|
||||
"units": "m"
|
||||
},
|
||||
"primaryTokenAttribute": "sante.vie",
|
||||
@ -590,4 +584,4 @@
|
||||
"flags": {}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
@ -4,14 +4,15 @@
|
||||
{{#each (trier sorts) as |sort key|}}
|
||||
<li class="item list-item flexrow" data-item-id="{{sort._id}}" data-attribute="{{key}}" data-tooltip="{{#if sort.system.isrituel}}Rituel{{else}}Sort{{/if}}: {{sort.name}}">
|
||||
<img class="sheet-competence-img" src="{{sort.img}}"/>
|
||||
<span class="item-edit flex-grow-3">
|
||||
<a data-item-id="{{sort._id}}">{{sort.name}}
|
||||
- {{#if sort.system.caseTMRspeciale}}{{sort.system.caseTMRspeciale}}{{else}}{{upperFirst sort.system.caseTMR}}{{/if}}
|
||||
</a>
|
||||
</span>
|
||||
<span class="flex-grow-0-5">{{#if sort.system.isrituel}}Rituel{{/if}}</span>
|
||||
<span class="flex-grow-2">{{sort.system.draconic}}/{{sort.system.difficulte}}</span>
|
||||
<span class="flex-shrink">{{itemSort-shortDraconic sort.system.draconic}}</span>
|
||||
<span class="item-edit flex-grow-3">{{sort.name}}{{#if sort.system.isrituel}}
|
||||
<i class="fa-regular fa-book-sparkles"></i>{{/if}}</span>
|
||||
<span class="flex-grow-2">
|
||||
{{#if sort.system.caseTMRspeciale}}{{sort.system.caseTMRspeciale}}{{else}}{{upperFirst sort.system.caseTMR}}{{/if}}
|
||||
</span>
|
||||
<span class="flex-grow-1">R{{itemSort-spaceIfText sort.system.difficulte}} r{{itemSort-spaceIfText sort.system.ptreve}}</span>
|
||||
<div class="item-controls flex-shrink">
|
||||
<a class="item-edit" data-tooltip="Modifier"><i class="fas fa-edit"></i></a>
|
||||
<a class="item-delete" data-tooltip="Supprimer"><i class="fas fa-trash"></i></a>
|
||||
<a class="item-montrer" data-tooltip="Montrer"><i class="fas fa-comment"></i></a>
|
||||
</div>
|
||||
|
@ -1,6 +1,6 @@
|
||||
{{#each (trier @root.competences) as |competence key|}}
|
||||
{{#if (eq competence.system.categorie 'draconic')}}
|
||||
<option value="{{competence.name}}">{{competence.name}}</option>
|
||||
<option value="{{itemSort-shortDraconic competence.name}}">{{itemSort-shortDraconic competence.name}}</option>
|
||||
{{/if}}
|
||||
{{/each}}
|
||||
<option value="O/H/N/T">Oniros/Hypnos/Narcos/Thanatos</option>
|
||||
|
Reference in New Issue
Block a user