Compare commits

..

9 Commits

Author SHA1 Message Date
d1b1b2a341 Portrait dans les feuilles simplifiées 2024-10-26 23:10:45 +02:00
e05753fc0b Fix: niveau de compétence non défini
- quand le niveau de compétence n'était pas défini, la feuille de
personnage simplifiée et l'export scriptarium ne marchaient pas
- on pouvait saisitr une compétence avec un niveau non défini
2024-10-26 23:08:13 +02:00
3de6179e9b Move to v12.0.17 2024-10-26 23:08:13 +02:00
a7e7eec261 Utilisation du nom du Nom du token
suite (pour les encaissements)
2024-10-26 01:53:38 +02:00
5c78ecb64e Localisation des blessures en regle optionnelle 2024-10-26 01:33:20 +02:00
c150dee6de Amélioration message encaissement 2024-10-26 01:20:03 +02:00
c8afb6e98a Afficher le nom du token au lieu du nom d'Acteur
Dans les messages d'automatisation de combat, le nom des
tokens est utilisé au lieu d'utiliser le nom de l'acteur.

Ceci permet de ne pas dévoiler un nom générique (Villageois)
si le token a un nom personnalisé.
2024-10-26 00:10:47 +02:00
2429f5b20a Version 12.0.16 2024-10-23 23:51:19 +02:00
4eabb58a89 Fix: Message uniquement MJ
L'utilisation de firstConnectedGM renvoie le GM, pas true si
un GM est connecté.
2024-10-23 23:44:49 +02:00
1403 changed files with 566 additions and 226641 deletions

View File

@@ -1,63 +0,0 @@
name: Release Creation
on:
release:
types: [published]
jobs:
build:
runs-on: ubuntu-latest
steps:
- run: echo "💡 The ${{ gitea.repository }} repository will cloned to the runner."
#- uses: actions/checkout@v3
- uses: RouxAntoine/checkout@v3.5.4
# get part of the tag after the `v`
- name: Extract tag version number
id: get_version
uses: battila7/get-version-action@v2
# Substitute the Manifest and Download URLs in the module.json
- name: Substitute Manifest and Download Links For Versioned Ones
id: sub_manifest_link_version
uses: microsoft/variable-substitution@v1
with:
files: 'system.json'
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}}/rddsystem.zip
- name: Set up Node.js
uses: actions/setup-node@v2
with:
node-version: '18' # Use the node version your project requires
- name: Install dependencies
run: npm install
- name: Build the compendiums
run: node ./tools/packCompendiumsToDist.mjs
# Create a zip file with all files required by the module to add to the release
- run: |
apt update -y
apt install -y zip
- 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
with:
go-version: '>=1.20.1'
- name: Use Go Action
id: use-go-action
uses: https://gitea.com/actions/release-action@main
with:
files: |-
./rddsystem.zip
system.json
api_key: '${{secrets.ALLOW_PUSH_RELEASE}}'

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.3 KiB

View File

@@ -1,47 +1,6 @@
# 12.0 # 12.0
## 12.0.23 - La bibliothèque d'Astrobazzarh
- corrections mineures
- meilleure gestion de la parade des armes naturelles
- cas de "User lacks permission to update" pour les blessures et les StatusEffects
- risque de message d'encaissement non affiché
- support de sorts à voies multiples
- correction de compendiums
- résistance des armes mise à jour
- voies multiples pour las sorts de Lecture d'aura, Détection d'aura et Annulation de magie
- améliorations "Scriptarium"
- recherche des compétences sans accents pour permettre les noms accentués (standard Scriptarium)
- affichage r1+ des sorts à coût variable dans la feuille simplifiée
- affichage de Corps à corps pour le combat à mains nues dans la feuille simplifiée
- dans les compendiums, les compétences Écriture et Épée ont une majuscule accentuée. Les Épée dans le compendium d'équipements référence le nom de compétence accentué.
## 12.0.21 - La nomination d'Astrobazzarh
- Les noms pour les messages dans le tchat sont maintenant ceux des tokens plutôt que ceux des acteurs
- Fix: le choix des effets dans les options s'affiche correctement
## 12.0.20 - Le tableau d'Astrobazzarh
- Ecran d'accueil officiel Scriptarium
## 12.0.19 - La témérité d'Astrobazzarh
- Fix
- les défenses des créatures sont correctement filtrées
- le lancer d'initiative pour tous les personnages/PNJs fonctionne correctement
- les lieux et commerces n'ont pas d'initiative
## 12.0.18 - A la barbe d'Astrobazzarh ## 12.0.18 - A la barbe d'Astrobazzarh
- Améliorations sur la feuille de PNJ simplifiée - Ajout du portrait sur les feuilles simplifiées
- Ajout du portrait
- Ajout du corps à corps
- Affichage du niveau d'esquive
- Un clic sur l'initiative permet de lancer l'initiative
- les boutons +/- pour la vie, l'endurance et la fatigue changent si on est à la valeur normale
- un clic sur l'endurance effectue un jet d'endurance
- Fix
- les achats des commerces sont de nouveau possibles
- la commande /astro fonctionne de nouveau
- le nombre d'utilisations d'items est réinitialisé à chaque round et fin de combat
- la difficulté de parade pour les armes à distances n'est plus indiquée
- les propositions d'armes de parade sont corrigées
- Ajout d'un indicateur pour les armes de parade nécessitant une significative
## 12.0.16 - Le secret d'Astrobazzarh ## 12.0.16 - Le secret d'Astrobazzarh
- Fix: les jets envoyés messages uniquement au MJ ne sont plus envoyés à tous les autres joueurs (et dupliqués) - Fix: les jets envoyés messages uniquement au MJ ne sont plus envoyés à tous les autres joueurs (et dupliqués)

61
dev-notes.md Normal file
View File

@@ -0,0 +1,61 @@
# Actor notes
> The Actor#getData default implementation gives you the following for use in sheet rendering:
```
actor -> the Actor instance
data -> a cloned copy of Actor#data
items -> a cloned copy of Actor#data#items
effects -> a cloned copy of Actor#data#effects
```
> if all you need is a safe copy of `Actor#data`, you'll be much better off by simply defining your own function and avoiding all the wasted work that the parent class does which will slow down your sheet
```js
getData(options) {
return {
data: foundry.utils.deepClone(this.object.data)
}
}
```
who knows, maybe you don't even need to copy your actor data, skip the copy and it's even faster:
```js
getData(options) {
return {
data: this.object.data
}
}
```
Atropos19/02/2021
There are two recommended ways to create owned items in 0.8.0:
```js
await Item.create(itemData, {parent: actor});
await actor.createEmbeddedDocuments("Item", itemDataArray);
```
You can update an embedded item in one of two ways:
```js
//Method 1:
const item = actor.items.get(itemId);
item.update(data);
//Method 2:
actor.updateEmbeddedDocuments("Item", [{_id: itemId, ...}]);
```
I noticed adding an ActiveEffect to an actor in code using
```js
this.createEmbeddedDocuments('ActiveEffect', [effet], options);
this.applyActiveEffects();
```
Atropos — Aujourdhui à 14:42
Two notes on this:
1. You don't actually need to call this.applyActiveEffects() because this will happen automatically whenever an effect is created/updated/deleted
2. If you want to suppress the automatic display of the sheet for the newly created document, you can pass options.renderSheet = false as part of your options object

View File

@@ -80,7 +80,7 @@ export class RdDActorSheet extends RdDBaseActorSangSheet {
const actor = this.actor; const actor = this.actor;
formData.combat = foundry.utils.duplicate(formData.armes); formData.combat = foundry.utils.duplicate(formData.armes);
RdDItemArme.computeNiveauArmes(formData.combat, formData.competences); RdDItemArme.computeNiveauArmes(formData.combat, formData.competences);
formData.combat.push(RdDItemArme.corpsACorps(actor)); formData.combat.push(RdDItemArme.mainsNues(actor));
formData.combat.push(RdDItemArme.empoignade(actor)); formData.combat.push(RdDItemArme.empoignade(actor));
formData.esquives = this.actor.getCompetences("Esquive"); formData.esquives = this.actor.getCompetences("Esquive");
@@ -224,7 +224,7 @@ export class RdDActorSheet extends RdDBaseActorSangSheet {
this.html.find('.roll-arme').click(async event => this.actor.rollArme(foundry.utils.duplicate(this._getEventArmeCombat(event)), 'competence')) this.html.find('.roll-arme').click(async event => this.actor.rollArme(foundry.utils.duplicate(this._getEventArmeCombat(event)), 'competence'))
// Initiative pour l'arme // Initiative pour l'arme
this.html.find('.roll-init-arme').click(async event => { this.html.find('.arme-initiative a').click(async event => {
let combatant = game.combat.combatants.find(c => c.actor.id == this.actor.id) let combatant = game.combat.combatants.find(c => c.actor.id == this.actor.id)
if (combatant) { if (combatant) {
RdDCombatManager.rollInitiativeAction(combatant._id, this._getEventArmeCombat(event)); RdDCombatManager.rollInitiativeAction(combatant._id, this._getEventArmeCombat(event));

View File

@@ -36,8 +36,6 @@ import { ITEM_TYPES } from "./item.js";
import { RdDBaseActorSang } from "./actor/base-actor-sang.js"; import { RdDBaseActorSang } from "./actor/base-actor-sang.js";
import { RdDCoeur } from "./coeur/rdd-coeur.js"; import { RdDCoeur } from "./coeur/rdd-coeur.js";
import { DialogChoixXpCarac } from "./dialog-choix-xp-carac.js"; import { DialogChoixXpCarac } from "./dialog-choix-xp-carac.js";
import { RdDItemArme } from "./item-arme.js";
import { RdDCombatManager } from "./rdd-combat.js";
export const MAINS_DIRECTRICES = ['Droitier', 'Gaucher', 'Ambidextre'] export const MAINS_DIRECTRICES = ['Droitier', 'Gaucher', 'Ambidextre']
@@ -132,23 +130,6 @@ export class RdDActor extends RdDBaseActorSang {
.reduce(Misc.sum(), 0); .reduce(Misc.sum(), 0);
} }
listActionsCombat() {
// Recupération des armes
const actions = RdDCombatManager.listActionsArmes(
this.itemTypes[ITEM_TYPES.arme]
.filter(it => RdDItemArme.isAttaque(it))
.concat(RdDItemArme.corpsACorps(this))
.concat(RdDItemArme.empoignade(this))
,
this.itemTypes[ITEM_TYPES.competence],
this.system.carac)
if (this.system.attributs.hautrevant.value) {
actions.push({ name: "Draconic", action: 'haut-reve', system: { initOnly: true, competence: "Draconic" } });
}
return actions
}
/* -------------------------------------------- */ /* -------------------------------------------- */
getTache(id) { return this.findItemLike(id, 'tache') } getTache(id) { return this.findItemLike(id, 'tache') }
getMeditation(id) { return this.findItemLike(id, 'meditation') } getMeditation(id) { return this.findItemLike(id, 'meditation') }
@@ -181,7 +162,7 @@ export class RdDActor extends RdDBaseActorSang {
whisper: ChatUtility.getOwners(this), whisper: ChatUtility.getOwners(this),
content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-potionenchantee-chateaudormant.html`, { content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-potionenchantee-chateaudormant.html`, {
pr: nouveauReve, pr: nouveauReve,
alias: this.getAlias(), alias: this.name,
potionName: it.name, potionName: it.name,
potionImg: it.img potionImg: it.img
}) })
@@ -1341,7 +1322,7 @@ export class RdDActor extends RdDBaseActorSang {
const etat = this.getEtatGeneral({ ethylisme: true }); const etat = this.getEtatGeneral({ ethylisme: true });
const nbDoses = Number(this.system.compteurs.ethylisme.nb_doses || 0); const nbDoses = Number(this.system.compteurs.ethylisme.nb_doses || 0);
const ethylismeData = { const ethylismeData = {
alias: this.getAlias(), alias: this.name,
actor: this, actor: this,
vie: this.system.sante.vie.max, vie: this.system.sante.vie.max,
alcool: alcool, alcool: alcool,
@@ -1426,7 +1407,7 @@ export class RdDActor extends RdDBaseActorSang {
const perteDissolution = Math.max(0, Math.min(dissolution, conversion)); const perteDissolution = Math.max(0, Math.min(dissolution, conversion));
let stressRollData = { let stressRollData = {
alias: this.getAlias(), alias: this.name,
selectedCarac: this.system.carac.reve, selectedCarac: this.system.carac.reve,
rolled: stressRoll, rolled: stressRoll,
stress: fromStress, stress: fromStress,
@@ -1517,7 +1498,7 @@ export class RdDActor extends RdDBaseActorSang {
carac.value = niveauSuivant; carac.value = niveauSuivant;
let checkXp = { let checkXp = {
alias: this.getAlias(), alias: this.name,
carac: caracName, carac: caracName,
value: niveauSuivant, value: niveauSuivant,
xp: carac.xp xp: carac.xp
@@ -1547,7 +1528,7 @@ export class RdDActor extends RdDBaseActorSang {
newCompData.system.niveau += 1; newCompData.system.niveau += 1;
newCompData.system.xp = newXP; newCompData.system.xp = newXP;
let checkXp = { let checkXp = {
alias: this.getAlias(), alias: this.name,
competence: newCompData.name, competence: newCompData.name,
niveau: newCompData.system.niveau, niveau: newCompData.system.niveau,
xp: newCompData.system.xp, xp: newCompData.system.xp,
@@ -1567,7 +1548,7 @@ export class RdDActor extends RdDBaseActorSang {
/* -------------------------------------------- */ /* -------------------------------------------- */
async appliquerAjoutExperience(rollData, hideChatMessage = 'show') { async appliquerAjoutExperience(rollData, hideChatMessage = 'show') {
if (!Misc.isFirstConnectedGM()) { if (!Misc.isFirstConnectedGM()){
return return
} }
hideChatMessage = hideChatMessage == 'hide' || (Misc.isRollModeHiddenToPlayer() && !game.user.isGM) hideChatMessage = hideChatMessage == 'hide' || (Misc.isRollModeHiddenToPlayer() && !game.user.isGM)
@@ -1784,7 +1765,7 @@ export class RdDActor extends RdDBaseActorSang {
} }
const competence = this.getCompetence(compName); const competence = this.getCompetence(compName);
let rollData = { let rollData = {
alias: this.getAlias(), alias: this.name,
caracValue: Number(carac.value), caracValue: Number(carac.value),
selectedCarac: carac, selectedCarac: carac,
competence: competence, competence: competence,
@@ -1857,7 +1838,7 @@ export class RdDActor extends RdDBaseActorSang {
label: 'Jet ' + Grammar.apostrophe('de', competence.name), label: 'Jet ' + Grammar.apostrophe('de', competence.name),
template: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-competence.html', template: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-competence.html',
rollData: { rollData: {
alias: this.getAlias(), alias: this.name,
carac: this.system.carac, carac: this.system.carac,
selectedCarac: this.getCaracByName(caracName), selectedCarac: this.getCaracByName(caracName),
selectedCaracName: caracName, selectedCaracName: caracName,
@@ -2634,7 +2615,7 @@ export class RdDActor extends RdDBaseActorSang {
/* -------------------------------------------- */ /* -------------------------------------------- */
async resetItemUse() { async resetItemUse() {
await this.unsetFlag(SYSTEM_RDD, 'itemUse'); await this.setFlag(SYSTEM_RDD, 'itemUse', {});
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
@@ -2930,7 +2911,7 @@ export class RdDActor extends RdDBaseActorSang {
let newQuantite = herbeData.system.quantite - herbeData.nbBrins; let newQuantite = herbeData.system.quantite - herbeData.nbBrins;
let messageData = { let messageData = {
alias: this.getAlias(), alias: this.name,
nbBrinsReste: newQuantite, nbBrinsReste: newQuantite,
potion: newPotion, potion: newPotion,
herbe: herbeData herbe: herbeData
@@ -3086,7 +3067,7 @@ export class RdDActor extends RdDBaseActorSang {
incarnation.name = 'Réincarnation de ' + incarnation.name incarnation.name = 'Réincarnation de ' + incarnation.name
incarnation.system = { incarnation.system = {
carac: foundry.utils.duplicate(this.system.carac), carac: foundry.utils.duplicate(this.system.carac),
heure: RdDTimestamp.defHeure(await RdDDice.rollHeure({ rollMode: "selfroll", showDice: SHOW_DICE })).key, heure: RdDTimestamp.defHeure(await RdDDice.rollHeure( { rollMode: "selfroll", showDice: SHOW_DICE })).key,
age: 18, age: 18,
biographie: '', biographie: '',
notes: '', notes: '',

View File

@@ -15,7 +15,7 @@ import { StatusEffects } from "../settings/status-effects.js";
import { ITEM_TYPES } from "../item.js"; import { ITEM_TYPES } from "../item.js";
import { Targets } from "../targets.js"; import { Targets } from "../targets.js";
import { RdDPossession } from "../rdd-possession.js"; import { RdDPossession } from "../rdd-possession.js";
import { RdDCombat, RdDCombatManager } from "../rdd-combat.js"; import { RdDCombat } from "../rdd-combat.js";
import { RdDConfirm } from "../rdd-confirm.js"; import { RdDConfirm } from "../rdd-confirm.js";
import { ENTITE_INCARNE, SHOW_DICE, SYSTEM_RDD } from "../constants.js"; import { ENTITE_INCARNE, SHOW_DICE, SYSTEM_RDD } from "../constants.js";
import { RdDItemArme } from "../item-arme.js"; import { RdDItemArme } from "../item-arme.js";
@@ -78,27 +78,8 @@ export class RdDBaseActorReve extends RdDBaseActor {
} }
async jetEndurance(resteEndurance = undefined) { return { jetEndurance: 0, sonne: false } } async jetEndurance(resteEndurance = undefined) { return { jetEndurance: 0, sonne: false } }
isDead() { return false } isDead() { return false }
isSonne() { return false }
blessuresASoigner() { return [] } blessuresASoigner() { return [] }
getEtatGeneral(options = { ethylisme: false }) { return 0 } getEtatGeneral(options = { ethylisme: false }) { return 0 }
isActorCombat() { return true }
getCaracInit(competence) {
if (!competence){
return 0
}
if (competence.type == ITEM_TYPES.competencecreature) {
return competence.system.carac_value
}
return this.system.carac[competence.system.defaut_carac].value;
}
listActionsCombat() {
return this.itemTypes[ITEM_TYPES.competencecreature]
.filter(it => RdDItemCompetenceCreature.isAttaque(it))
.map(it => RdDItemCompetenceCreature.armeCreature(it))
.filter(it => it != undefined);
}
async computeArmure(attackerRoll) { return this.getProtectionNaturelle() } async computeArmure(attackerRoll) { return this.getProtectionNaturelle() }
async remiseANeuf() { } async remiseANeuf() { }
@@ -117,7 +98,7 @@ export class RdDBaseActorReve extends RdDBaseActor {
for (let effect of this.getEffects()) { for (let effect of this.getEffects()) {
if (effect.duration.type !== 'none' && (effect.duration.remaining <= 0 || options.terminer)) { if (effect.duration.type !== 'none' && (effect.duration.remaining <= 0 || options.terminer)) {
await effect.delete(); await effect.delete();
ChatMessage.create({ content: `${this.getAlias()} n'est plus ${Misc.lowerFirst(game.i18n.localize(effect.system.label))} !` }); ChatMessage.create({ content: `${this.name} n'est plus ${Misc.lowerFirst(game.i18n.localize(effect.system.label))} !` });
} }
} }
} }
@@ -172,6 +153,9 @@ export class RdDBaseActorReve extends RdDBaseActor {
getPossession(possessionId) { getPossession(possessionId) {
return this.itemTypes[ITEM_TYPES.possession].find(it => it.system.possessionid == possessionId); return this.itemTypes[ITEM_TYPES.possession].find(it => it.system.possessionid == possessionId);
} }
getPossessions() {
return this.itemTypes[ITEM_TYPES.possession];
}
getEmpoignades() { getEmpoignades() {
return this.itemTypes[ITEM_TYPES.empoignade]; return this.itemTypes[ITEM_TYPES.empoignade];
} }
@@ -288,7 +272,7 @@ export class RdDBaseActorReve extends RdDBaseActor {
await this.openRollDialog({ await this.openRollDialog({
name: `jet-${this.id}`, name: `jet-${this.id}`,
label: `Jet de ${this.getAlias()}`, label: `Jet de ${this.name}`,
template: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll.html', template: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll.html',
rollData: { rollData: {
carac: carac, carac: carac,
@@ -384,7 +368,7 @@ export class RdDBaseActorReve extends RdDBaseActor {
rollArme(arme, categorieArme, token) { rollArme(arme, categorieArme, token) {
token = token ?? RdDUtility.getSelectedToken(this) token = token ?? RdDUtility.getSelectedToken(this)
const compToUse = this.$getCompetenceArme(arme, categorieArme) const compToUse = this.$getCompetenceArme(arme, categorieArme)
if (!RdDItemArme.isUtilisable(arme)) { if (!RdDItemArme.isArmeUtilisable(arme)) {
ui.notifications.warn(`Arme inutilisable: ${arme.name} a une résistance de 0 ou moins`) ui.notifications.warn(`Arme inutilisable: ${arme.name} a une résistance de 0 ou moins`)
return return
} }
@@ -421,7 +405,12 @@ export class RdDBaseActorReve extends RdDBaseActor {
return RdDItemArme.getCompetenceArme(arme, competenceName) return RdDItemArme.getCompetenceArme(arme, competenceName)
} }
verifierForceMin(item) { } verifierForceMin(item) {
}
/* -------------------------------------------- */
async resetItemUse() { }
async incDecItemUse(itemId, inc = 1) { }
getItemUse(itemId) { return 0; }
/* -------------------------------------------- */ /* -------------------------------------------- */
async encaisser() { await RdDEncaisser.encaisser(this) } async encaisser() { await RdDEncaisser.encaisser(this) }
@@ -463,10 +452,10 @@ export class RdDBaseActorReve extends RdDBaseActor {
async $afficherEncaissement(encaissement, show, defenderToken) { async $afficherEncaissement(encaissement, show, defenderToken) {
foundry.utils.mergeObject(encaissement, { foundry.utils.mergeObject(encaissement, {
alias: defenderToken?.name ?? this.getAlias(), alias: defenderToken?.name ?? this.name,
hasPlayerOwner: this.hasPlayerOwner, hasPlayerOwner: this.hasPlayerOwner,
show: show ?? {} show: show ?? {}
}, { overwrite: false }); }, {overwrite: false});
await ChatUtility.createChatWithRollMode( await ChatUtility.createChatWithRollMode(
{ {
@@ -496,7 +485,7 @@ export class RdDBaseActorReve extends RdDBaseActor {
} }
const rolled = await RdDResolutionTable.roll(this.getReveActuel(), - Number(entite.system.carac.niveau.value)); const rolled = await RdDResolutionTable.roll(this.getReveActuel(), - Number(entite.system.carac.niveau.value));
const rollData = { const rollData = {
alias: this.getAlias(), alias: this.name,
rolled: rolled, rolled: rolled,
entite: entite.name, entite: entite.name,
selectedCarac: this.system.carac.reve selectedCarac: this.system.carac.reve
@@ -516,7 +505,7 @@ export class RdDBaseActorReve extends RdDBaseActor {
isEntiteAccordee(attacker) { return true } isEntiteAccordee(attacker) { return true }
async setEntiteReveAccordee(actor) { async setEntiteReveAccordee(actor) {
ui.notifications.error("Impossible de s'accorder à " + this.getAlias() + ": ce n'est pas une entité incarnée"); ui.notifications.error("Impossible de s'accorder à " + this.name + ": ce n'est pas une entité incarnée");
} }
} }

View File

@@ -191,7 +191,7 @@ export class RdDBaseActorSang extends RdDBaseActorReve {
encaissement.mort = true; encaissement.mort = true;
ChatMessage.create({ ChatMessage.create({
content: `<img class="chat-icon" src="icons/svg/skull.svg" data-tooltip="charge" /> content: `<img class="chat-icon" src="icons/svg/skull.svg" data-tooltip="charge" />
<strong>${this.getAlias()} vient de succomber à une seconde blessure critique ! Que les Dragons gardent son Archétype en paix !</strong>` <strong>${this.name} vient de succomber à une seconde blessure critique ! Que les Dragons gardent son Archétype en paix !</strong>`
}); });
} }
return blessure; return blessure;
@@ -218,7 +218,7 @@ export class RdDBaseActorSang extends RdDBaseActorReve {
async jetDeVie() { async jetDeVie() {
if (this.isDead()) { if (this.isDead()) {
ChatMessage.create({ ChatMessage.create({
content: `Jet de Vie: ${this.getAlias()} est déjà mort, ce n'est pas la peine d'en rajouter !!!!!`, content: `Jet de Vie: ${this.name} est déjà mort, ce n'est pas la peine d'en rajouter !!!!!`,
whisper: ChatUtility.getOwners(this) whisper: ChatUtility.getOwners(this)
}) })
return return
@@ -242,7 +242,7 @@ export class RdDBaseActorSang extends RdDBaseActorReve {
await this.santeIncDec("vie", -perte); await this.santeIncDec("vie", -perte);
} }
if (this.isDead()) { if (this.isDead()) {
msgText += `<br><strong>${this.getAlias()} est mort !!!!</strong>`; msgText += `<br><strong>${this.name} est mort !!!!</strong>`;
} }
else if (prochainJet > 0) { else if (prochainJet > 0) {
msgText += `<br>Prochain jet de vie dans ${prochainJet} ${isCritique ? 'round' : 'minute'}${prochainJet > 1 ? 's' : ''} ${isCritique ? '(état critique)' : '(état grave)'}` msgText += `<br>Prochain jet de vie dans ${prochainJet} ${isCritique ? 'round' : 'minute'}${prochainJet > 1 ? 's' : ''} ${isCritique ? '(état critique)' : '(état grave)'}`
@@ -273,14 +273,14 @@ export class RdDBaseActorSang extends RdDBaseActorReve {
async setSonne(sonne = true) { async setSonne(sonne = true) {
if (!game.combat && sonne) { if (!game.combat && sonne) {
ui.notifications.info(`${this.getAlias()} est hors combat, il ne reste donc pas sonné`); ui.notifications.info(`${this.name} est hors combat, il ne reste donc pas sonné`);
return; return;
} }
await this.setEffect(STATUSES.StatusStunned, sonne) await this.setEffect(STATUSES.StatusStunned, sonne);
} }
isSonne() { getSonne() {
return this.getEffect(STATUSES.StatusStunned) return this.getEffect(STATUSES.StatusStunned);
} }
isEffectAllowed(effectId) { return true } isEffectAllowed(effectId) { return true }

View File

@@ -78,13 +78,6 @@ export class RdDBaseActor extends Actor {
return game.actors.get(actorId) return game.actors.get(actorId)
} }
getAlias() {
if (this.token?.name != null && this.token != this.prototypeToken) {
return this.token.name
}
return this.name
}
isPersonnageJoueur() { return false } isPersonnageJoueur() { return false }
static extractActorMin = (actor) => { return { id: actor?.id, type: actor?.type, name: actor?.name, img: actor?.img }; }; static extractActorMin = (actor) => { return { id: actor?.id, type: actor?.type, name: actor?.name, img: actor?.img }; };
@@ -212,8 +205,11 @@ export class RdDBaseActor extends Actor {
/* -------------------------------------------- */ /* -------------------------------------------- */
async onPreUpdateItem(item, change, options, id) { } async onPreUpdateItem(item, change, options, id) { }
async onCreateItem(item, options, id) { } async onCreateItem(item, options, id) { }
async onDeleteItem(item, options, id) { } async onDeleteItem(item, options, id) { }
async onUpdateActor(update, options, actorId) { } async onUpdateActor(update, options, actorId) { }
async onTimeChanging(oldTimestamp, newTimestamp) { async onTimeChanging(oldTimestamp, newTimestamp) {
@@ -321,7 +317,7 @@ export class RdDBaseActor extends Actor {
RdDAudio.PlayContextAudio("argent"); // Petit son RdDAudio.PlayContextAudio("argent"); // Petit son
ChatMessage.create({ ChatMessage.create({
whisper: ChatUtility.getOwners(this), whisper: ChatUtility.getOwners(this.name),
content: `Vous avez reçu <strong>${sols} Sols</strong> ${fromActor ? " de " + fromActor.name : ''}, qui ont été ajoutés à votre argent.` content: `Vous avez reçu <strong>${sols} Sols</strong> ${fromActor ? " de " + fromActor.name : ''}, qui ont été ajoutés à votre argent.`
}); });
} }
@@ -374,7 +370,7 @@ export class RdDBaseActor extends Actor {
chatAchatItem.quantiteTotal = quantite; chatAchatItem.quantiteTotal = quantite;
ChatMessage.create({ ChatMessage.create({
user: achat.userId, user: achat.userId,
speaker: { alias: (acheteur ?? vendeur).getAlias() }, speaker: { alias: (acheteur ?? vendeur).name },
whisper: ChatUtility.getOwners(this), whisper: ChatUtility.getOwners(this),
content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-achat-item.html', chatAchatItem) content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-achat-item.html', chatAchatItem)
}); });
@@ -690,7 +686,7 @@ export class RdDBaseActor extends Actor {
type: this.type, type: this.type,
img: this.img, img: this.img,
pack: this.pack, pack: this.pack,
name: this.getAlias(), name: this.name,
system: { description: this.system.description } system: { description: this.system.description }
} }
renderTemplate('systems/foundryvtt-reve-de-dragon/templates/post-actor.html', chatData) renderTemplate('systems/foundryvtt-reve-de-dragon/templates/post-actor.html', chatData)
@@ -698,10 +694,10 @@ export class RdDBaseActor extends Actor {
} }
actionImpossible(action) { actionImpossible(action) {
ui.notifications.info(`${this.getAlias()} ne peut pas faire cette action: ${action}`) ui.notifications.info(`${this.name} ne peut pas faire cette action: ${action}`)
} }
async roll() { this.actionImpossible("jet de caractéristiques") }
async jetEthylisme() { this.actionImpossible("jet d'éthylisme") } async jetEthylisme() { this.actionImpossible("jet d'éthylisme") }
async rollAppelChance() { this.actionImpossible("appel à la chance") } async rollAppelChance() { this.actionImpossible("appel à la chance") }
async jetDeMoral() { this.actionImpossible("jet de moral") } async jetDeMoral() { this.actionImpossible("jet de moral") }
@@ -712,24 +708,5 @@ export class RdDBaseActor extends Actor {
} }
return undefined return undefined
} }
async resetItemUse() { }
async incDecItemUse(itemId, inc = 1) { }
getItemUse(itemId) { return 0; }
async finDeRound(options = { terminer: false }) { }
isActorCombat() { return false }
getCaracInit(competence) { return 0 }
listActionsCombat() { return [] }
listActionsPossessions() {
return this.itemTypes[ITEM_TYPES.possession]
.map(p => {
return {
name: p.name,
action: 'possession',
system: {
competence: p.name,
possessionid: p.system.possessionid,
}
}
})
}
} }

View File

@@ -73,7 +73,7 @@ export class RdDCommerceSheet extends RdDBaseActorSheet {
} }
const disponible = this.actor.getQuantiteDisponible(item) const disponible = this.actor.getQuantiteDisponible(item)
if (disponible == 0) { if (disponible == 0) {
ui.notifications.warn(`${this.getAlias()} n'a plus de ${item.name} en vente`); ui.notifications.warn(`${this.name} n'a plus de ${item.name} en vente`);
return; return;
} }

View File

@@ -84,7 +84,7 @@ const MAPPING_BASE = [
{ column: "malus_armure", getter: (actor, context) => Mapping.getMalusArmure(actor, context) }, { column: "malus_armure", getter: (actor, context) => Mapping.getMalusArmure(actor, context) },
{ column: "reve_actuel", rollClass: 'roll-reve-actuel', colName: 'Rêve actuel', getter: (actor, context) => actor.system.reve.reve.value }, { column: "reve_actuel", rollClass: 'roll-reve-actuel', colName: 'Rêve actuel', getter: (actor, context) => actor.system.reve.reve.value },
{ column: "vie_actuel", rollClass: 'jet-vie', getter: (actor, context) => actor.system.sante.vie.value }, { column: "vie_actuel", rollClass: 'jet-vie', getter: (actor, context) => actor.system.sante.vie.value },
{ column: "endurance_actuel", rollClass: 'jet-endurance', getter: (actor, context) => actor.system.sante.endurance.value }, { column: "endurance_actuel", rollClass: 'jet-vie', getter: (actor, context) => actor.system.sante.endurance.value },
{ column: "esquive", getter: (actor, context) => Mapping.getEsquive(context) }, { column: "esquive", getter: (actor, context) => Mapping.getEsquive(context) },
{ column: "esquive_armure", getter: (actor, context) => Mapping.getEsquiveArmure(context) }, { column: "esquive_armure", getter: (actor, context) => Mapping.getEsquiveArmure(context) },
{ column: "competences", getter: (actor, context) => Mapping.getCompetences(actor, CATEGORIES_COMPETENCES) }, { column: "competences", getter: (actor, context) => Mapping.getCompetences(actor, CATEGORIES_COMPETENCES) },
@@ -140,53 +140,45 @@ export class Mapping {
static prepareArmes(actor) { static prepareArmes(actor) {
const armes = actor.items.filter(it => it.type == ITEM_TYPES.arme) const armes = actor.items.filter(it => it.type == ITEM_TYPES.arme)
armes.push(RdDItemArme.corpsACorps(actor)); return armes.map(arme =>
armes.push(RdDItemArme.empoignade(actor)); [
return armes.map(arme => [ arme.system.unemain ? Mapping.prepareArme(actor, arme, 'unemain') : undefined,
arme.system.unemain ? Mapping.prepareArme(actor, arme, 'unemain') : undefined, arme.system.deuxmains ? Mapping.prepareArme(actor, arme, 'deuxmains') : undefined,
arme.system.deuxmains ? Mapping.prepareArme(actor, arme, 'deuxmains') : undefined, !(arme.system.unemain || arme.system.deuxmains) ? Mapping.prepareArme(actor, arme, 'competence') : undefined,
!(arme.system.unemain || arme.system.deuxmains) ? Mapping.prepareArme(actor, arme, 'competence') : undefined, arme.system.lancer != "" ? Mapping.prepareArme(actor, arme, 'lancer') : undefined,
arme.system.lancer != "" ? Mapping.prepareArme(actor, arme, 'lancer') : undefined, arme.system.tir != "" ? Mapping.prepareArme(actor, arme, 'tir') : undefined
arme.system.tir != "" ? Mapping.prepareArme(actor, arme, 'tir') : undefined] ]
.filter(it => it != undefined)) .filter(it => it != undefined)
.reduce((a, b) => a.concat(b), []) ).reduce((a, b) => a.concat(b), [])
} }
static prepareArme(actor, arme, maniement) { static prepareArme(actor, arme, maniement) {
const nameCompetenceArme = RdDItemArme.getCompetenceArme(arme, maniement) const nameCompArme = RdDItemArme.getCompetenceArme(arme, maniement)
const competence = actor.getCompetence(nameCompetenceArme) const competence = actor.getCompetence(nameCompArme)
if (RdDItemCompetence.isNiveauBase(competence)) { if (RdDItemCompetence.isNiveauBase(competence)) {
return undefined return undefined
} }
const dmgArme = RdDItemArme.dommagesReels(arme, maniement)
const dommages = dmgArme + RdDBonus.bonusDmg(actor, maniement, dmgArme)
const categorie = Mapping.complementCategorie(arme, maniement) const categorie = Mapping.complementCategorie(arme, maniement)
const dommages = Mapping.dommagesArme(actor, arme, maniement)
return { return {
name: arme.name + categorie, name: arme.name + categorie,
niveau: Misc.toSignedString(competence.system.niveau), niveau: Misc.toSignedString(competence.system.niveau),
init: Mapping.calculBaseInit(actor, competence.system.categorie) + competence.system.niveau, init: Mapping.calculBaseInit(actor, competence.system.categorie) + competence.system.niveau,
dommages: dommages, dommages: Misc.toSignedString(dommages),
competence: competence, competence: competence,
arme: arme arme: arme
} }
} }
static dommagesArme(actor, arme, maniement){
const dmgArme = RdDItemArme.dommagesReels(arme, maniement)
const dommages = Misc.toSignedString(dmgArme + RdDBonus.bonusDmg(actor, maniement, dmgArme))
switch(arme.system.mortalite) {
case 'non-mortel': return `(${dommages})`
case 'empoignade': return '-'
}
return dommages
}
static complementCategorie(arme, maniement) { static complementCategorie(arme, maniement) {
switch (maniement) { switch (maniement) {
case 'unemain': return (arme.system.deuxmains) ? ' 1 main' : (arme.system.lancer || arme.system.tir) ? ' mêlée' : '' case 'unemain': return (arme.system.deuxmains) ? ' 1 main' : (arme.system.lancer||arme.system.tir) ? ' mêlée': ''
case 'deuxmains': return (arme.system.unemain) ? ' 2 mains' : (arme.system.lancer || arme.system.tir) ? ' mêlée' : '' case 'deuxmains': return (arme.system.unemain) ? ' 2 mains' : (arme.system.lancer||arme.system.tir) ? ' mêlée': ''
case 'lancer': return (arme.system.unemain || arme.system.deuxmains || arme.system.tir) ? ' jet' : '' case 'lancer': return (arme.system.unemain || arme.system.deuxmains || arme.system.tir) ? ' jet' : ''
case 'tir': return (arme.system.unemain || arme.system.deuxmains || arme.system.lancer) ? ' tir' : '' case 'tir': return (arme.system.unemain || arme.system.deuxmains || arme.system.lancer) ? ' tir' : ''
} }
return '' return ''
} }
static calculBaseInit(actor, categorie) { static calculBaseInit(actor, categorie) {
@@ -261,7 +253,7 @@ export class Mapping {
} }
static addSpaceToNonNumeric(value) { static addSpaceToNonNumeric(value) {
return Number.isNumeric(value) || /[-\d].*/.match(String(value)) ? value : ' ' + Mapping.toVar(value) return Number.isNumeric(value) ? value : ' ' + Mapping.toVar(value)
} }
static toVar(value) { static toVar(value) {

View File

@@ -19,7 +19,7 @@ const PATHS = [
const RANDOM_VALUES = { const RANDOM_VALUES = {
'system.sexe': { 'masculin': 1, 'féminin': 1 }, 'system.sexe': { 'masculin': 1, 'féminin': 1 },
'system.main': { 'droitier': 51, 'gaucher': 15, 'ambidextre': 6 }, 'system.main': { 'droitier': 51, 'gaucher': 15, 'ambidectre': 6 },
'system.cheveux': { 'noirs': 2, 'bruns': 5, 'châtains clair': 5, 'blonds': 4, 'blonds très clair': 1, 'roux carotte': 1, 'roux cuivré': 3 }, 'system.cheveux': { 'noirs': 2, 'bruns': 5, 'châtains clair': 5, 'blonds': 4, 'blonds très clair': 1, 'roux carotte': 1, 'roux cuivré': 3 },
'system.yeux': { 'noirs': 2, 'noisettes': 3, 'bruns vert': 4, 'verts': 3, 'bleus clair': 3, 'bleus gris': 2, 'gris': 1, 'mauves': 1, 'indigos': 1 }, 'system.yeux': { 'noirs': 2, 'noisettes': 3, 'bruns vert': 4, 'verts': 3, 'bleus clair': 3, 'bleus gris': 2, 'gris': 1, 'mauves': 1, 'indigos': 1 },
} }

View File

@@ -1,433 +0,0 @@
/************************************************************************************/
import "./xregexp-all.js";
import { SystemCompendiums } from "../settings/system-compendiums.js";
import { RdDBaseActorReve } from "../actor/base-actor-reve.js";
/************************************************************************************/
// Some internal test strings
let statBlock01 = `+$16(/, baron de Sylvedire, né à lheure du
Roseau, 40 ans, 1m78, 65 kg, Beauté 13.
TAILLE
10
Mêlée
14
APPARENCE
13
Tir
11
CONSTITUTION
12
Lancer
11
FORCE
12
Dérobée
13
AGILITÉ
16
Vie
11
DEXTÉRITÉ
13
Endurance
25
VUE
10
+dom
0
OUÏE
11
Protection
2 ou 4
ODO-GOÛT
9
cuir souple
VOLONTÉ
14
ou cuir / métal
INTELLECT
9
EMPATHIE
11
RÊVE
13
CHANCE
10
niv
init
+dom
Épée dragonne
+5
12
+3
Hache de bataille
+6
13
+3
Bouclier moyen
+5
Dague mêlée
+4
11
+1
Corps à corps
+4
11
(0)
Esquive
+8
Escalade +4 / Saut +5 / 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
`;
let statBlock02 = `/HVJDUGHV
TAILLE
11
Mêlée
12
CONSTITUTION
11
Tir
11
FORCE
12
Lancer
11
AGILITÉ
12
Dérobée
11
DEXTERITÉ
11
Vie
11
VUE
11
Endurance
22
OUÏE
11
Vitesse
12
VOLONTÉ
10
+dom
0
Protection
4
cuir / métal
niv
init
+dom
Hache de bataille
+4
10
+3
Bouclier moyen
+4
Dague mêlée
+3
9
+1
Arc
+5
10
+2
Corps à corps
+3
9
(0)
Esquive avec armure
+2
Course +1/ Vigilance +4
`;
let statBlock03 = `rencontres sont laissées à /HVFKLHQVORXSVGXEDURQ
chaque gardien des rêves.
TAILLE
8
Vie
10
CONSTITUTION FORCE
12
11
Endurance
Vitesse
12/38
21
/HVFKLHQV]RPELV
PERCEPTION 13
+dom
0
VOLONTÉ
10
Protection
0
Les « monstres » apparaîtront un soir, durant
RÊVE
10
lheure du Serpent, et attaqueront les voya-
niv
init
+dom
geurs à leur campement. Si ces derniers ne
Morsure
13
+4
10
+1
campent pas, ils apparaîtront tout de même à
Esquive
11
+3
lheure du Serpent. Le feu ne les effraie pas. Ils
Course, Saut
12
+3
ne sont pas très rapides, mais en revanche, très
Discrétion
12
+3
silencieux : ils naboient pas. Les voyageurs
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);
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -51,7 +51,7 @@ export class DialogCreateSigneDraconique extends Dialog {
whisper: ChatUtility.getOwners(actor), whisper: ChatUtility.getOwners(actor),
content: await renderTemplate("systems/foundryvtt-reve-de-dragon/templates/chat-signe-draconique-actor.html", { content: await renderTemplate("systems/foundryvtt-reve-de-dragon/templates/chat-signe-draconique-actor.html", {
signe: signe, signe: signe,
alias: actor.getAlias() alias: actor.name
}) })
}); });
} }

View File

@@ -24,7 +24,7 @@ export class Grammar {
} }
static includesLowerCaseNoAccent(value, content) { static includesLowerCaseNoAccent(value, content) {
return Grammar.toLowerCaseNoAccent(value)?.includes(Grammar.toLowerCaseNoAccent(content)); return Grammar.toLowerCaseNoAccent(value).includes(Grammar.toLowerCaseNoAccent(content));
} }
/* -------------------------------------------- */ /* -------------------------------------------- */

View File

@@ -1,11 +1,10 @@
import { Grammar } from "./grammar.js";
import { RdDItemCompetenceCreature } from "./item-competencecreature.js" import { RdDItemCompetenceCreature } from "./item-competencecreature.js"
import { ITEM_TYPES } from "./item.js"; import { ITEM_TYPES } from "./item.js";
import { RdDCombatManager } from "./rdd-combat.js"; import { RdDCombatManager } from "./rdd-combat.js";
const nomCategorieParade = { const nomCategorieParade = {
"sans-armes": "Sans arme", "sans-armes": "Sans arme",
"armes-naturelles": "Armes naturelles", "armes-naturelles": "Sans arme",
"hast": "Armes d'hast", "hast": "Armes d'hast",
"batons": "Bâtons", "batons": "Bâtons",
"boucliers": "Boucliers", "boucliers": "Boucliers",
@@ -31,7 +30,7 @@ export class RdDItemArme extends Item {
case ITEM_TYPES.competencecreature: case ITEM_TYPES.competencecreature:
return RdDItemCompetenceCreature.armeCreature(arme); return RdDItemCompetenceCreature.armeCreature(arme);
} }
return RdDItemArme.corpsACorps(); return RdDItemArme.mainsNues();
} }
static getCompetenceArme(arme, maniement) { static getCompetenceArme(arme, maniement) {
@@ -57,8 +56,8 @@ export class RdDItemArme extends Item {
} }
static niveauCompetenceArme(arme, competences) { static niveauCompetenceArme(arme, competences) {
const compArme = competences.find(it => Grammar.equalsInsensitive(it.name, arme.system.competence)) const compArme = competences.find(it => it.name == arme.system.competence);
return compArme?.system.niveau ?? -8 return compArme?.system.niveau ?? -8;
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
@@ -82,59 +81,37 @@ export class RdDItemArme extends Item {
/* -------------------------------------------- */ /* -------------------------------------------- */
static getCategorieParade(armeData) { static getCategorieParade(armeData) {
if (armeData.system.categorie_parade) { if (armeData.system.categorie_parade) {
return armeData.system.categorie_parade return armeData.system.categorie_parade;
} }
// pour compatibilité avec des personnages existants // pour compatibilité avec des personnages existants
if (armeData.type == ITEM_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' : '') return armeData.system.categorie_parade || (armeData.system.isparade ? 'armes-naturelles' : '');
} }
if (!armeData.type.match(/arme|competencecreature/)) { if (!armeData.type.match(/arme|competencecreature/)) {
return '' return '';
} }
if (armeData.system.competence == undefined) { if (armeData.system.competence == undefined) {
return ITEM_TYPES.competencecreature; return ITEM_TYPES.competencecreature;
} }
let compname = armeData.system.competence.toLowerCase(); let compname = armeData.system.competence.toLowerCase();
if (compname.match(/^(dague de jet|javelot|fouet|arc|arbalête|fronde|hache de jet|fléau)$/)) { if (compname.match(/^(dague de jet|javelot|fouet|arc|arbalête|fronde|hache de jet|fléau)$/)) return '';
return ''
}
if (compname.match('hache')) return 'haches' if (compname.match('hache')) return 'haches';
if (compname.match('hast')) return 'hast' if (compname.match('hast')) return 'hast';
if (compname.match('lance')) return 'lances' if (compname.match('lance')) return 'lances';
if (compname.match('bouclier')) return 'boucliers' if (compname.match('bouclier')) return 'boucliers';
if (compname.match('masse')) return 'masses' if (compname.match('masse')) return 'masses';
if (compname.match('epée') || compname.match('épée')) { if (compname.match('epée') || compname.match('épée')) {
if (armeData.name.toLowerCase().match(/(gnome)/)) if (armeData.name.toLowerCase().match(/(gnome)/))
return 'epees-courtes' return 'epees-courtes';
if (armeData.name.toLowerCase().match(/((e|é)pée dragone|esparlongue|demi-dragonne)/)) if (armeData.name.toLowerCase().match(/((e|é)pée dragone|esparlongue|demi-dragonne)/))
return 'epees-longues' return 'epees-longues';
return 'epees-lourdes' return 'epees-lourdes';
} }
if (compname.match('dague')) { if (compname.match('dague')) {
return 'dagues' return 'dagues';
}
return 'sans-armes'
}
static defenseArmeParade(armeAttaque, armeParade) {
const defCategory = RdDItemArme.getCategorieParade(armeParade)
if (defCategory == 'bouclier') {
return 'norm'
}
if (armeAttaque.system.competence.toLowerCase().match(/(fléau)/)) {
return ''
}
if (armeParade.system.tir) {
return ''
}
const attCategory = RdDItemArme.getCategorieParade(armeAttaque)
switch (attCategory) {
case 'armes-naturelles': case 'sans-armes':
return defCategory == 'sans-armes' ? 'norm' : ''
default:
return RdDItemArme.needParadeSignificative(armeAttaque, armeParade) ? 'sign' : 'norm'
} }
return 'sans-armes';
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
@@ -143,8 +120,8 @@ export class RdDItemArme extends Item {
return false; return false;
} }
// categories d'armes à la parade (cf. page 115 ) // categories d'armes à la parade (cf. page 115 )
const attCategory = RdDItemArme.getCategorieParade(armeAttaque) let attCategory = RdDItemArme.getCategorieParade(armeAttaque);
const defCategory = RdDItemArme.getCategorieParade(armeParade) let defCategory = RdDItemArme.getCategorieParade(armeParade);
// bouclier et mêmes catégorie: peuvent se parer sans difficulté // bouclier et mêmes catégorie: peuvent se parer sans difficulté
if (defCategory == 'boucliers') { if (defCategory == 'boucliers') {
return false; return false;
@@ -207,7 +184,7 @@ export class RdDItemArme extends Item {
return arme.system.competence.replace(" 1 main", " 2 mains"); return arme.system.competence.replace(" 1 main", " 2 mains");
} }
static isUtilisable(arme) { static isArmeUtilisable(arme) {
switch (arme.type) { switch (arme.type) {
case ITEM_TYPES.arme: return arme.system.equipe && (arme.system.resistance > 0 || arme.system.portee_courte > 0) case ITEM_TYPES.arme: return arme.system.equipe && (arme.system.resistance > 0 || arme.system.portee_courte > 0)
case ITEM_TYPES.competencecreature: return true case ITEM_TYPES.competencecreature: return true
@@ -215,24 +192,9 @@ export class RdDItemArme extends Item {
return false return false
} }
static isAttaque(arme) { static ajoutCorpsACorps(armes, actor) {
switch (arme.type) { armes.push(RdDItemArme.mainsNues(actor));
case ITEM_TYPES.arme: armes.push(RdDItemArme.empoignade(actor));
return arme.system.equipe && (arme.system.resistance > 0 || arme.system.portee_courte > 0)
case ITEM_TYPES.competencecreature:
return arme.system.iscombat && RdDItemCompetenceCreature.isAttaque(item)
}
return false
}
static isParade(arme) {
switch (arme.type) {
case ITEM_TYPES.arme:
return arme.system.equipe && arme.system.resistance > 0 && true/* TODO: regarder la categorie d'arme?*/
case ITEM_TYPES.competencecreature:
return arme.system.iscombat && RdDItemCompetenceCreature.isParade(arme)
}
return false
} }
static corpsACorps(actor) { static corpsACorps(actor) {
@@ -253,8 +215,6 @@ export class RdDItemArme extends Item {
mortalite: 'non-mortel', mortalite: 'non-mortel',
competence: 'Corps à corps', competence: 'Corps à corps',
resistance: 1, resistance: 1,
baseInit: 4,
cac: 'pugilat',
deuxmains: true, deuxmains: true,
categorie_parade: 'sans-armes' categorie_parade: 'sans-armes'
} }
@@ -264,6 +224,8 @@ export class RdDItemArme extends Item {
static mainsNues(actor) { static mainsNues(actor) {
const mainsNues = RdDItemArme.corpsACorps(actor) const mainsNues = RdDItemArme.corpsACorps(actor)
mainsNues.name = 'Mains nues' mainsNues.name = 'Mains nues'
mainsNues.system.cac = 'pugilat'
mainsNues.system.baseInit = 4
return mainsNues; return mainsNues;
} }

View File

@@ -27,29 +27,40 @@ export class RdDItemCompetenceCreature extends Item {
static armeCreature(item) { static armeCreature(item) {
const categorieAttaque = RdDItemCompetenceCreature.getCategorieAttaque(item) const categorieAttaque = RdDItemCompetenceCreature.getCategorieAttaque(item)
if (categorieAttaque != undefined) { if (categorieAttaque != undefined) {
// cloner pour ne pas modifier la compétence // si c'est un Item compétence: cloner pour ne pas modifier la compétence
return foundry.utils.mergeObject(item, { let arme = item.clone();
return foundry.utils.mergeObject(arme, {
action: item.isCompetencePossession() ? 'possession' : 'attaque', action: item.isCompetencePossession() ? 'possession' : 'attaque',
system: { system: {
competence: item.name, competence: arme.name,
cac: categorieAttaque == "naturelle" ? "naturelle" : "", cac: categorieAttaque == "naturelle" ? "naturelle" : "",
niveau: item.system.niveau, niveau: item.system.niveau,
initiative: RdDCombatManager.calculInitiative(item.system.niveau, item.system.carac_value), initiative: RdDCombatManager.calculInitiative(item.system.niveau, item.system.carac_value),
equipe: true, equipe: true,
resistance: 100, resistance: 100,
dommagesReels: item.system.dommages, dommagesReels: arme.system.dommages,
penetration: 0, penetration: 0,
force: 0, force: 0,
rapide: true, rapide: true,
} }
}, { inplace: false, }); }, { inplace: false });
} }
return undefined; return undefined;
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
static isAttaque(item) { static isCompetenceAttaque(item) {
return RdDItemCompetenceCreature.getCategorieAttaque(item) != undefined if (item.type == ITEM_TYPES.competencecreature) {
switch (item.system.categorie) {
case "melee":
case "tir":
case "lancer":
case "naturelle":
case "possession":
return true
}
}
return undefined
} }
static getCategorieAttaque(item) { static getCategorieAttaque(item) {
@@ -60,12 +71,12 @@ export class RdDItemCompetenceCreature extends Item {
case "lancer": case "lancer":
case "naturelle": case "naturelle":
case "possession": case "possession":
case "parade":
return item.system.categorie return item.system.categorie
} }
} }
return undefined return undefined
} }
static isDommages(item) { static isDommages(item) {
if (item.type == ITEM_TYPES.competencecreature) { if (item.type == ITEM_TYPES.competencecreature) {
switch (item.system.categorie) { switch (item.system.categorie) {
@@ -78,12 +89,20 @@ export class RdDItemCompetenceCreature extends Item {
} }
return false return false
} }
static isParade(item) { static isParade(item) {
if (item.type == ITEM_TYPES.competencecreature) { if (item.type == ITEM_TYPES.competencecreature) {
return armeData.system.categorie_parade || armeData.system.isparade switch (item.system.categorie) {
case "melee":
case "naturelle":
case "parade":
return true
}
} }
return false return false
} }
} /* -------------------------------------------- */
static isCompetenceParade(item) {
return item.type == 'competencecreature' && item.system.categorie_parade !== "";
}
}

View File

@@ -16,17 +16,15 @@ const VOIES_DRACONIC = [
/* -------------------------------------------- */ /* -------------------------------------------- */
export class RdDItemSort extends Item { export class RdDItemSort extends Item {
static getDraconicsSort(competencesDraconic, sort) { static getDraconicsSort(draconicList, sort) {
// se baser sur la voie du sort?
switch (Grammar.toLowerCaseNoAccent(sort.name)) { switch (Grammar.toLowerCaseNoAccent(sort.name)) {
case "lecture d'aura": case "lecture d'aura":
case "detection d'aura": case "detection d'aura":
return competencesDraconic; return draconicList;
case "annulation de magie": case "annulation de magie":
return competencesDraconic.filter(it => !RdDItemCompetence.isThanatos(it)); return draconicList.filter(it => !RdDItemCompetence.isThanatos(it));
} }
const voies = sort.system.draconic.split('/') return [RdDItemCompetence.getVoieDraconic(draconicList, sort.system.draconic)];
return voies.map(voie => RdDItemCompetence.getVoieDraconic(competencesDraconic, voie))
} }
static getOrdreCode(code) { static getOrdreCode(code) {
@@ -49,6 +47,7 @@ export class RdDItemSort extends Item {
return voie?.code ?? sort.system.draconic return voie?.code ?? sort.system.draconic
} }
static $voiesConnues(voiesSort, voies) { static $voiesConnues(voiesSort, voies) {
const codes = voies.filter(it => voiesSort.includes(it)) const codes = voies.filter(it => voiesSort.includes(it))
.sort(Misc.ascending(it => RdDItemSort.getOrdreCode(it))) .sort(Misc.ascending(it => RdDItemSort.getOrdreCode(it)))

View File

@@ -67,7 +67,7 @@ export class RdDItemBlessure extends RdDItem {
} }
static async createBlessure(actor, gravite, localisation = '', attackerToken) { static async createBlessure(actor, gravite, localisation = '', attacker) {
const definition = RdDItemBlessure.getDefinition(gravite) const definition = RdDItemBlessure.getDefinition(gravite)
const blessure = { const blessure = {
name: definition.label, name: definition.label,
@@ -77,7 +77,7 @@ export class RdDItemBlessure extends RdDItem {
gravite: gravite, gravite: gravite,
difficulte: - gravite, difficulte: - gravite,
localisation: localisation, localisation: localisation,
origine: attackerToken?.name ?? "" origine: attacker?.name ?? ""
} }
} }
const blessures = await actor.createEmbeddedDocuments('Item', [blessure]) const blessures = await actor.createEmbeddedDocuments('Item', [blessure])

View File

@@ -139,7 +139,7 @@ export class Misc {
} }
static join(params, separator = '') { static join(params, separator = '') {
return (!params || params.length == 0) ? '' : params.reduce(Misc.joining(separator)) return params?.reduce(Misc.joining(separator)) ?? '';
} }
static joining(separator = '') { static joining(separator = '') {
@@ -189,7 +189,13 @@ export class Misc {
* and there is no connected GM * and there is no connected GM
*/ */
static documentIfResponsible(document) { static documentIfResponsible(document) {
if (Misc.isFirstConnectedGM() || (Misc.connectedGMs().length == 0 && Misc.isFirstOwnerPlayer(document))) { if (foundry.utils.isNewerVersion(game.release.version, '12.0')) {
if (game.users.activeGM || (Misc.connectedGMs().length == 0 && Misc.isOwnerPlayer(document)))
{
return document
}
}
else if (Misc.isFirstConnectedGM() || (Misc.connectedGMs().length == 0 && Misc.isOwnerPlayer(document))) {
return document return document
} }
return undefined return undefined
@@ -199,15 +205,8 @@ export class Misc {
return document.testUserPermission && document.testUserPermission(game.user, CONST.DOCUMENT_OWNERSHIP_LEVELS.OWNER) return document.testUserPermission && document.testUserPermission(game.user, CONST.DOCUMENT_OWNERSHIP_LEVELS.OWNER)
} }
static isFirstOwnerPlayer(document) {
if (!document.testUserPermission){
return false
}
return game.users.filter(u => document.testUserPermission(u, CONST.DOCUMENT_OWNERSHIP_LEVELS.OWNER)) == game.user
}
static isOwnerPlayerOrUniqueConnectedGM(actor) { static isOwnerPlayerOrUniqueConnectedGM(actor) {
return Misc.isFirstOwnerPlayer(actor) ?? Misc.isFirstConnectedGM(); return Misc.isOwnerPlayer(actor) ?? Misc.isFirstConnectedGM();
} }
/** /**

View File

@@ -53,14 +53,9 @@ export class RdDCarac {
return selectedCarac?.label?.toLowerCase()?.match(/r(e|ê)ve(( |-)actuel)?/); return selectedCarac?.label?.toLowerCase()?.match(/r(e|ê)ve(( |-)actuel)?/);
} }
/**
* Lappel à la chance nest possible que pour recommencer les jets dactions physiques :
* tous les jets de combat, de FORCE, dAGILITÉ, de DEXTÉRITÉ, de Dérobée, dAPPARENCE,
* ainsi que de Perception active et volontaire.
*/
static isActionPhysique(selectedCarac) { static isActionPhysique(selectedCarac) {
return Grammar.toLowerCaseNoAccent(selectedCarac?.label) return !selectedCarac ||
?.match(/(apparence|force|agilite|dexterite|vue|ouie|gout|odorat|empathie|melee|tir|lancer|derobee)/) != null selectedCarac?.label.match(/(Apparence|Force|Agilité|Dextérité|Vue|Ouïe|Odorat-Goût|Empathie|Dérobée|Mêlée|Tir|Lancer)/);
} }
static getCaracDerivee(value) { static getCaracDerivee(value) {
@@ -95,4 +90,15 @@ export class RdDCarac {
static getCaracXp(targetValue) { static getCaracXp(targetValue) {
return RdDCarac.getCaracDerivee(targetValue)?.xp ?? 200; return RdDCarac.getCaracDerivee(targetValue)?.xp ?? 200;
} }
/**
* Lappel à la chance nest possible que pour recommencer les jets dactions physiques :
* tous les jets de combat, de FORCE, dAGILITÉ, de DEXTÉRITÉ, de Dérobée, dAPPARENCE,
* ainsi que de Perception active et volontaire.
*/
static isActionPhysique(selectedCarac) {
return Grammar.toLowerCaseNoAccent(selectedCarac?.label)?.match(/(apparence|force|agilite|dexterite|vue|ouie|odorat|empathie|melee|tir|lancer|derobee)/);
}
} }

View File

@@ -42,8 +42,7 @@ export class RdDCombatManager extends Combat {
/* -------------------------------------------- */ /* -------------------------------------------- */
Hooks.on("getCombatTrackerEntryContext", (html, options) => { RdDCombatManager.pushInitiativeOptions(html, options); }); Hooks.on("getCombatTrackerEntryContext", (html, options) => { RdDCombatManager.pushInitiativeOptions(html, options); });
Hooks.on("updateCombat", (combat, change, options, userId) => { RdDCombat.onUpdateCombat(combat, change, options, userId) }); Hooks.on("updateCombat", (combat, change, options, userId) => { RdDCombat.onUpdateCombat(combat, change, options, userId) });
Hooks.on("preDeleteCombat", (combat, html, id) => { combat.onPreDeleteCombat() }) Hooks.on("preDeleteCombat", (combat, html, id) => { combat.onPreDeleteCombat() });
Hooks.on("deleteCombat", (combat, html, id) => { combat.onDeleteCombat() })
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
@@ -62,40 +61,20 @@ export class RdDCombatManager extends Combat {
RdDEmpoignade.deleteAllEmpoignades() RdDEmpoignade.deleteAllEmpoignades()
} }
} }
async onDeleteCombat() {
if (Misc.isFirstConnectedGM()) {
if (game.combats.size <= 1) {
game.actors.forEach(actor => actor.resetItemUse())
}
}
}
/* -------------------------------------------- */ /* -------------------------------------------- */
async finDeRound(options = { terminer: false }) { async finDeRound(options = { terminer: false }) {
this.combatants.map(it => RdDCombatManager.getActorCombatant(it, { warning: false })) this.turns.forEach(turn => turn.actor.resetItemUse());
.filter(it => it != undefined)
.forEach(async actor => {
await actor.finDeRound(options)
await actor.resetItemUse()
})
}
static getActorCombatant(combatant, options = { warning: true }) { for (let combatant of this.combatants) {
if (!combatant.actor) { if (combatant.actor) {
if (options.warning) { await combatant.actor.finDeRound(options);
}
else {
ui.notifications.warn(`Le combatant ${combatant.name} n'est pas associé à un acteur!`) ui.notifications.warn(`Le combatant ${combatant.name} n'est pas associé à un acteur!`)
} }
return undefined
} }
else if (!combatant.actor.isActorCombat()) {
if (options.warning) {
ui.notifications.warn(`${combatant.name} ne peut pas combattre!`)
}
return undefined
}
return combatant.actor
} }
static calculAjustementInit(actor, arme) { static calculAjustementInit(actor, arme) {
const efficacite = (arme?.system.magique) ? arme.system.ecaille_efficacite : 0 const efficacite = (arme?.system.magique) ? arme.system.ecaille_efficacite : 0
const etatGeneral = actor.getEtatGeneral() ?? 0 const etatGeneral = actor.getEtatGeneral() ?? 0
@@ -104,27 +83,57 @@ export class RdDCombatManager extends Combat {
} }
/************************************************************************************/ /************************************************************************************/
async rollInitiative(ids, messageOptions = {}) { async rollInitiative(ids, formula = undefined, messageOptions = {}) {
console.log(`${game.system.title} | Combat.rollInitiative()`, ids, messageOptions) console.log(`${game.system.title} | Combat.rollInitiative()`, ids, formula, messageOptions);
ids = typeof ids === "string" ? [ids] : ids
ids.forEach(async id =>
await this.rollInitRdD(id, undefined, messageOptions)
)
return this
}
async rollInitRdD(id, formula, messageOptions = {}) { ids = typeof ids === "string" ? [ids] : ids;
const combatant = this.combatants.get(id); // calculate initiative
const actor = RdDCombatManager.getActorCombatant(combatant) for (let cId = 0; cId < ids.length; cId++) {
if (actor) { const combatant = this.combatants.get(ids[cId]);
const rollFormula = formula ?? RdDCombatManager.getFirstInitRollFormula(actor) const ajustement = RdDCombatManager.calculAjustementInit(combatant.actor, undefined);
let rollFormula = formula ?? RdDCombatManager.formuleInitiative(2, 10, 0, ajustement);
if (!formula) {
if (combatant.actor.type == 'creature' || combatant.actor.type == 'entite') {
const competence = combatant.actor.items.find(it => RdDItemCompetenceCreature.isCompetenceAttaque(it))
if (competence) {
rollFormula = RdDCombatManager.formuleInitiative(2, competence.system.carac_value, competence.system.niveau, etatGeneral);
}
} else {
const armeCombat = combatant.actor.itemTypes['arme'].find(it => it.system.equipe)
let compName = "Corps à corps"
if (armeCombat) {
if (armeCombat.system.competence != "") {
compName = armeCombat.system.competence
}
if (armeCombat.system.lancer != "") {
compName = armeCombat.system.lancer
}
if (armeCombat.system.tir != "") {
compName = armeCombat.system.tir
}
}
const competence = RdDItemCompetence.findCompetence(combatant.actor.items, compName);
if (competence && competence.system.defaut_carac) {
const carac = combatant.actor.system.carac[competence.system.defaut_carac].value;
const niveau = competence.system.niveau;
const ajustement = RdDCombatManager.calculAjustementInit(combatant.actor, armeCombat)
rollFormula = RdDCombatManager.formuleInitiative(2, carac, niveau, ajustement);
} else {
ui.notifications.warn(`Votre arme ${armeCombat.name} n'a pas de compétence renseignée`);
}
}
}
//console.log("Combatat", c);
const roll = combatant.getInitiativeRoll(rollFormula); const roll = combatant.getInitiativeRoll(rollFormula);
if (!roll.total) { if (!roll.total) {
await roll.evaluate(); await roll.evaluate();
} }
const total = Math.max(roll.total, 0.00); const total = Math.max(roll.total, 0.00);
console.log("Compute init for", rollFormula, roll, total, combatant); console.log("Compute init for", rollFormula, roll, total, combatant);
await this.updateEmbeddedDocuments("Combatant", [{ _id: combatant._id || combatant.id, initiative: total }]); let id = combatant._id || combatant.id;
await this.updateEmbeddedDocuments("Combatant", [{ _id: id, initiative: total }]);
// Send a chat message // Send a chat message
let rollMode = messageOptions.rollMode || game.settings.get("core", "rollMode"); let rollMode = messageOptions.rollMode || game.settings.get("core", "rollMode");
@@ -133,10 +142,10 @@ export class RdDCombatManager extends Combat {
scene: canvas.scene._id, scene: canvas.scene._id,
actor: combatant.actor?._id, actor: combatant.actor?._id,
token: combatant.token._id, token: combatant.token._id,
alias: combatant.token?.name, alias: combatant.token.name,
sound: CONFIG.sounds.dice, sound: CONFIG.sounds.dice,
}, },
flavor: `${combatant.token?.name} a fait son jet d'Initiative (${messageOptions.info})<br>` flavor: `${combatant.token.name} a fait son jet d'Initiative (${messageOptions.initInfo})<br>`,
}, },
messageOptions); messageOptions);
roll.toMessage(messageData, { rollMode, create: true }); roll.toMessage(messageData, { rollMode, create: true });
@@ -144,20 +153,7 @@ export class RdDCombatManager extends Combat {
RdDCombatManager.processPremierRoundInit(); RdDCombatManager.processPremierRoundInit();
} }
return this; return this;
} };
static getFirstInitRollFormula(actor) {
const actions = actor.listActionsCombat()
if (actions.length > 0) {
const action = actions[0]
const init = RdDCombatManager.getInitData(actor, action)
const ajustement = RdDCombatManager.calculAjustementInit(actor, action)
return RdDCombatManager.formuleInitiative(init.offset, init.carac, init.niveau, ajustement);
}
let ajustement = RdDCombatManager.calculAjustementInit(actor, undefined);
return RdDCombatManager.formuleInitiative(2, 10, 0, ajustement);
}
static formuleInitiative(rang, carac, niveau, bonusMalus) { static formuleInitiative(rang, carac, niveau, bonusMalus) {
return `${rang} +( (${RdDCombatManager.calculInitiative(niveau, carac, bonusMalus)} )/100)`; return `${rang} +( (${RdDCombatManager.calculInitiative(niveau, carac, bonusMalus)} )/100)`;
@@ -226,7 +222,7 @@ export class RdDCombatManager extends Combat {
} }
static $prepareAttaqueArme(infoAttaque) { static $prepareAttaqueArme(infoAttaque) {
const comp = infoAttaque.competences.find(it => Grammar.equalsInsensitive(it.name, infoAttaque.competence)) const comp = infoAttaque.competences.find(c => c.name == infoAttaque.competence);
const arme = infoAttaque.arme; const arme = infoAttaque.arme;
const attaque = foundry.utils.duplicate(arme); const attaque = foundry.utils.duplicate(arme);
attaque.action = 'attaque'; attaque.action = 'attaque';
@@ -240,6 +236,58 @@ export class RdDCombatManager extends Combat {
return attaque; return attaque;
} }
static listActionsCreature(competences) {
return competences
.filter(it => RdDItemCompetenceCreature.isCompetenceAttaque(it))
.map(it => RdDItemCompetenceCreature.armeCreature(it))
.filter(it => it != undefined);
}
static listActionsPossessions(actor) {
return RdDCombatManager._indexActions(actor.getPossessions().map(p => {
return {
name: p.name,
action: 'possession',
system: {
competence: p.name,
possessionid: p.system.possessionid,
}
}
}));
}
/* -------------------------------------------- */
static listActionsCombat(combatant) {
const actor = combatant.actor;
let actions = RdDCombatManager.listActionsPossessions(actor);
if (actions.length > 0) {
return actions;
}
if (actor.isCreatureEntite()) {
actions = RdDCombatManager.listActionsCreature(actor.itemTypes['competencecreature']);
} else if (actor.isPersonnage()) {
// Recupération des items 'arme'
const competences = actor.itemTypes['competence'];
const armes = actor.itemTypes['arme'].filter(it => RdDItemArme.isArmeUtilisable(it))
.concat(RdDItemArme.empoignade(actor))
.concat(RdDItemArme.mainsNues(actor));
actions = RdDCombatManager.listActionsArmes(armes, competences, actor.system.carac);
if (actor.system.attributs.hautrevant.value) {
actions.push({ name: "Draconic", action: 'haut-reve', system: { initOnly: true, competence: "Draconic" } });
}
}
return RdDCombatManager._indexActions(actions);
}
static _indexActions(actions) {
for (let index = 0; index < actions.length; index++) {
actions[index].index = index;
}
return actions;
}
/* -------------------------------------------- */ /* -------------------------------------------- */
static processPremierRoundInit() { static processPremierRoundInit() {
// Check if we have the whole init ! // Check if we have the whole init !
@@ -252,7 +300,7 @@ export class RdDCombatManager extends Combat {
if (action && action.type == "arme") { if (action && action.type == "arme") {
for (let initData of premierRoundInit) { for (let initData of premierRoundInit) {
if (Grammar.toLowerCaseNoAccentNoSpace(action.system.initpremierround).includes(initData.pattern)) { if (Grammar.toLowerCaseNoAccentNoSpace(action.system.initpremierround).includes(initData.pattern)) {
let msg = `<h4>L'initiative de ${combatant.actor.getAlias()} a été modifiée !</h4> let msg = `<h4>L'initiative de ${combatant.actor.name} a été modifiée !</h4>
<hr> <hr>
<div> <div>
Etant donné son ${action.name}, son initative pour ce premier round est désormais de ${initData.init}. Etant donné son ${action.name}, son initative pour ce premier round est désormais de ${initData.init}.
@@ -277,13 +325,13 @@ export class RdDCombatManager extends Combat {
/* -------------------------------------------- */ /* -------------------------------------------- */
static pushInitiativeOptions(html, options) { static pushInitiativeOptions(html, options) {
for (let i = 0; i < options.length; i++) { for (let i = 0; i < options.length; i++) {
let option = options[i] let option = options[i];
if (option.name == 'COMBAT.CombatantReroll') { // Replace ! if (option.name == 'COMBAT.CombatantReroll') { // Replace !
option.name = "Sélectionner l'initiative..." option.name = "Sélectionner l'initiative...";
option.condition = true option.condition = true;
option.icon = '<i class="far fa-question-circle"></i>' option.icon = '<i class="far fa-question-circle"></i>';
option.callback = target => { option.callback = target => {
RdDCombatManager.displayInitiativeMenu(html, target.data('combatant-id')) RdDCombatManager.displayInitiativeMenu(html, target.data('combatant-id'));
} }
} }
} }
@@ -294,83 +342,96 @@ export class RdDCombatManager extends Combat {
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
static rollInitiativeAction(combatantId, action) { static rollInitiativeAction(combatantId, action) {
const combatant = game.combat.combatants.get(combatantId) const combatant = game.combat.combatants.get(combatantId);
const actor = RdDCombatManager.getActorCombatant(combatant) if (combatant.actor == undefined) {
if (actor == undefined) { return [] } ui.notifications.warn(`Le combatant ${combatant.name} n'est pas associé à un acteur, impossible de déterminer ses actions de combat!`)
return [];
}
let initInfo = "";
let initOffset = 0;
let caracForInit = 0;
let compNiveau = 0;
let compData = { name: "Aucune" };
if (combatant.actor.getSurprise() == "totale") {
initOffset = -1; // To force 0
initInfo = "Surprise Totale"
} else if (combatant.actor.getSurprise() == "demi") {
initOffset = 0;
initInfo = "Demi Surprise"
} else if (action.action == 'possession') {
initOffset = 10;
caracForInit = combatant.actor.getReveActuel();
initInfo = "Possession"
} else if (action.action == 'autre') {
initOffset = 2;
initInfo = "Autre Action"
} else if (action.action == 'haut-reve') {
initOffset = 9;
initInfo = "Draconic"
} else {
compData = RdDItemCompetence.findCompetence(combatant.actor.items, action.system.competence);
compNiveau = compData.system.niveau;
initInfo = action.name + " / " + action.system.competence;
if (combatant.actor.type == 'creature' || combatant.actor.type == 'entite') {
caracForInit = compData.system.carac_value;
} else {
caracForInit = combatant.actor.system.carac[compData.system.defaut_carac].value;
}
initOffset = RdDCombatManager._baseInitOffset(compData.system.categorie, action);
}
// Cas des créatures et entités vs personnages
const ajustement = RdDCombatManager.calculAjustementInit(combatant.actor, action)
let rollFormula = RdDCombatManager.formuleInitiative(initOffset, caracForInit, compNiveau, ajustement);
// Garder la trace de l'arme/compétence utilisée pour l'iniative
combatant.initiativeData = { arme: action } // pour reclasser l'init au round 0 combatant.initiativeData = { arme: action } // pour reclasser l'init au round 0
game.combat.rollInitiative(combatantId, rollFormula, { initInfo: initInfo });
const init = RdDCombatManager.getInitData(actor, action)
const ajustement = RdDCombatManager.calculAjustementInit(actor, action)
const rollFormula = RdDCombatManager.formuleInitiative(init.offset, init.carac, init.niveau, ajustement);
game.combat.rollInitRdD(combatantId, rollFormula, init);
} }
static getInitData(actor, action) { /* -------------------------------------------- */
if (actor.getSurprise() == "totale") { return { offset: -1, info: "Surprise Totale", carac: 0, niveau: 0 } } static _baseInitOffset(categorie, arme) {
if (actor.getSurprise() == "demi") { return { offset: 0, info: "Demi Surprise", carac: 0, niveau: 0 } } if (categorie == "tir") { // Offset de principe pour les armes de jet
if (action.action == 'autre') { return { offset: 2, info: "Autre Action", carac: 0, niveau: 0 } } return 8;
if (action.action == 'possession') { return { offset: 10, info: "Possession", carac: actor.getReveActuel(), niveau: 0 } }
if (action.action == 'haut-reve') { return { offset: 9, info: "Draconic", carac: actor.getReveActuel(), niveau: 0 } }
const comp = RdDItemCompetence.findCompetence(actor.items, action.system.competence);
return {
offset: RdDCombatManager.initOffset(comp?.system.categorie, action),
info: action.name + " / " + action.system.competence,
carac: actor.getCaracInit(comp),
niveau: comp?.system.niveau ?? -8
} }
} if (categorie == "lancer") { // Offset de principe pour les armes de jet
return 7;
static initOffset(categorie, arme) {
switch (categorie) {
case "tir": return 8
case "lancer": return 7
default:
switch (arme.system.cac) {
case "empoignade": return 3
case "pugilat": return 4
case "naturelle": return 4
default: return 5
}
} }
switch (arme.system.cac) {
case "empoignade":
return 3;
case "pugilat":
case "naturelle":
return 4;
}
return 5;
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
static displayInitiativeMenu(html, combatantId) { static displayInitiativeMenu(html, combatantId) {
const combatant = game.combat.combatants.get(combatantId) console.log("Combatant ; ", combatantId);
const actor = RdDCombatManager.getActorCombatant(combatant, { warning: false }) const combatant = game.combat.combatants.get(combatantId);
if (actor) { if (!(combatant?.actor)) {
const actions = RdDCombatManager.listActionsActorCombatant(actor) ui.notifications.warn(`Le combatant ${combatant.name ?? combatantId} n'est pas associé à un acteur, impossible de déterminer ses actions de combat!`)
// Build the relevant submenu return;
const menuItems = actions.map(action => { }
return {
let actions = RdDCombatManager.listActionsCombat(combatant);
// Build the relevant submenu
if (actions) {
let menuItems = [];
for (let action of actions) {
menuItems.push({
name: action.system.competence, name: action.system.competence,
icon: "<i class='fas fa-dice-d6'></i>", icon: "<i class='fas fa-dice-d6'></i>",
callback: target => { RdDCombatManager.rollInitiativeAction(combatantId, action) } callback: target => { RdDCombatManager.rollInitiativeAction(combatantId, action) }
} });
})
if (menuItems.length > 0) {
new ContextMenu(html, ".directory-list", menuItems).render();
} }
new ContextMenu(html, ".directory-list", menuItems).render();
} }
} }
/* -------------------------------------------- */
static listActionsActorCombatant( actor) {
const possessions = actor.listActionsPossessions()
const actions = possessions.length > 0
? possessions
: actor.listActionsCombat()
for (let index = 0; index < actions.length; index++) {
actions[index].index = index
}
return actions
}
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
@@ -396,8 +457,8 @@ export class RdDCombat {
if (Misc.isFirstConnectedGM()) { if (Misc.isFirstConnectedGM()) {
let turn = combat.turns.find(t => t.token?.id == combat.current.tokenId); let turn = combat.turns.find(t => t.token?.id == combat.current.tokenId);
if (turn?.actor) { if (turn?.actor) {
// TODO Playaudio for player??
RdDCombat.displayActorCombatStatus(combat, turn.actor, turn.token); RdDCombat.displayActorCombatStatus(combat, turn.actor, turn.token);
// TODO Playaudio for player??
} }
} }
} }
@@ -435,10 +496,11 @@ export class RdDCombat {
/* -------------------------------------------- */ /* -------------------------------------------- */
static onMsgEncaisser(msg) { static onMsgEncaisser(msg) {
let defender = canvas.tokens.get(msg.defenderToken.id).actor; if (Misc.isOwnerPlayerOrUniqueConnectedGM()) {
if (Misc.isOwnerPlayerOrUniqueConnectedGM(defender)) {
let attackerRoll = msg.attackerRoll; let attackerRoll = msg.attackerRoll;
let attacker = msg.attackerId ? game.actors.get(msg.attackerId) : undefined; let attacker = msg.attackerId ? game.actors.get(msg.attackerId) : undefined;
let defender = canvas.tokens.get(msg.defenderToken.id).actor;
defender.encaisserDommages(attackerRoll, attacker, msg.attackerToken); defender.encaisserDommages(attackerRoll, attacker, msg.attackerToken);
const rddCombat = RdDCombat.rddCombatForAttackerAndDefender(msg.attackerId, msg.attackerToken.id, msg.defenderToken.id); const rddCombat = RdDCombat.rddCombatForAttackerAndDefender(msg.attackerId, msg.attackerToken.id, msg.defenderToken.id);
rddCombat?.removeChatMessageActionsPasseArme(attackerRoll.passeArme); rddCombat?.removeChatMessageActionsPasseArme(attackerRoll.passeArme);
@@ -512,15 +574,15 @@ export class RdDCombat {
static $extractAttackerTokenData(attacker, attackerTokenId) { static $extractAttackerTokenData(attacker, attackerTokenId) {
const token = canvas.tokens.get(attackerTokenId); const token = canvas.tokens.get(attackerTokenId);
return token ? Targets.extractTokenData(token) : Targets.buildActorTokenData(attackerTokenId, attacker) return token ? Targets.extractTokenData(token) : Targets.buildActorTokenData(attackerTokenId, attacker)
} }
static $extractDefenderTokenData(defender, defenderTokenId, target) { static $extractDefenderTokenData(defender, defenderTokenId, target) {
if (target) { if (target) {
return Targets.extractTokenData(target) return Targets.extractTokenData(target)
} }
const token = canvas.tokens.get(defenderTokenId); const token = canvas.tokens.get(defenderTokenId);
return token ? Targets.extractTokenData(token) : Targets.buildActorTokenData(defenderTokenId, defender) return token ? Targets.extractTokenData(token) : Targets.buildActorTokenData(defenderTokenId, defender)
} }
@@ -749,11 +811,11 @@ export class RdDCombat {
dialog.render(true); dialog.render(true);
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
_prepareAttaque(competence, arme) { _prepareAttaque(competence, arme) {
let rollData = { let rollData = {
alias: this.attacker?.getAlias(), alias: this.attackerToken.name,
passeArme: foundry.utils.randomID(16), passeArme: foundry.utils.randomID(16),
mortalite: arme?.system.mortalite, mortalite: arme?.system.mortalite,
competence: competence, competence: competence,
@@ -763,7 +825,7 @@ export class RdDCombat {
targetToken: this.defenderToken, targetToken: this.defenderToken,
essais: {} essais: {}
}; };
if (this.attacker.isCreatureEntite()) { if (this.attacker.isCreatureEntite()) {
RdDItemCompetenceCreature.setRollDataCreature(rollData); RdDItemCompetenceCreature.setRollDataCreature(rollData);
} }
@@ -773,9 +835,9 @@ export class RdDCombat {
} }
else { else {
// sans armes: à mains nues // sans armes: à mains nues
rollData.arme = RdDItemArme.corpsACorps(this.attacker) const niveau = competence.system.niveau;
rollData.arme.system.niveau = competence.system.niveau const init = RdDCombatManager.calculInitiative(niveau, this.attacker.system.carac['melee'].value);
rollData.arme.system.initiative = RdDCombatManager.calculInitiative(competence.system.niveau, this.attacker.system.carac['melee'].value); rollData.arme = RdDItemArme.mainsNues({ niveau: niveau, initiative: init });
} }
return rollData; return rollData;
} }
@@ -802,10 +864,10 @@ export class RdDCombat {
} }
const choixParticuliere = await ChatMessage.create({ const choixParticuliere = await ChatMessage.create({
alias: this.attacker.getAlias(), alias: this.attacker.name,
whisper: ChatUtility.getOwners(this.attacker), whisper: ChatUtility.getOwners(this.attacker),
content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-demande-attaque-particuliere.html', { content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-demande-attaque-particuliere.html', {
alias: this.attacker.getAlias(), alias: this.attackerToken.name,
attackerId: this.attackerId, attackerId: this.attackerId,
attackerToken: this.attackerToken, attackerToken: this.attackerToken,
defenderToken: this.defenderToken, defenderToken: this.defenderToken,
@@ -825,7 +887,7 @@ export class RdDCombat {
attackerRoll.dmg = RdDBonus.dmg(attackerRoll, this.attacker, this.defender.isEntite()); attackerRoll.dmg = RdDBonus.dmg(attackerRoll, this.attacker, this.defender.isEntite());
let defenderRoll = { attackerRoll: attackerRoll, passeArme: attackerRoll.passeArme, show: {} } let defenderRoll = { attackerRoll: attackerRoll, passeArme: attackerRoll.passeArme, show: {} }
attackerRoll.show = { attackerRoll.show = {
cible: this.defender?.getAlias() ?? 'la cible', cible: this.defenderToken?.name ?? 'la cible',
isRecul: (attackerRoll.particuliere == 'force' || attackerRoll.tactique == 'charge') isRecul: (attackerRoll.particuliere == 'force' || attackerRoll.tactique == 'charge')
} }
await RdDResolutionTable.displayRollData(attackerRoll, this.attacker, 'chat-resultat-attaque.html'); await RdDResolutionTable.displayRollData(attackerRoll, this.attacker, 'chat-resultat-attaque.html');
@@ -856,7 +918,7 @@ export class RdDCombat {
// # utilisation esquive // # utilisation esquive
const corpsACorps = this.defender.getCompetenceCorpsACorps({ onMessage: it => console.info(it, this.defender) }); const corpsACorps = this.defender.getCompetenceCorpsACorps({ onMessage: it => console.info(it, this.defender) });
const esquives = foundry.utils.duplicate(this.defender.getCompetencesEsquive()) const esquives = foundry.utils.duplicate(this.defender.getCompetencesEsquive())
esquives.forEach(e => e.nbUsage = e?._id ? this.defender.getItemUse(e._id) : 0); esquives.forEach(e => e.system.nbUsage = e?._id ? this.defender.getItemUse(e._id) : 0);
const paramChatDefense = { const paramChatDefense = {
passeArme: attackerRoll.passeArme, passeArme: attackerRoll.passeArme,
@@ -891,7 +953,7 @@ export class RdDCombat {
const choixDefense = await ChatMessage.create({ const choixDefense = await ChatMessage.create({
// message privé: du défenseur à lui même (et aux GMs) // message privé: du défenseur à lui même (et aux GMs)
speaker: ChatMessage.getSpeaker(this.defender, canvas.tokens.get(this.defenderTokenId)), speaker: ChatMessage.getSpeaker(this.defender, canvas.tokens.get(this.defenderTokenId)),
alias: this.attacker?.getAlias(), alias: this.attackerToken.name,
whisper: ChatUtility.getOwners(this.defender), whisper: ChatUtility.getOwners(this.defender),
content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-demande-defense.html', paramDemandeDefense), content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-demande-defense.html', paramDemandeDefense),
}); });
@@ -916,21 +978,20 @@ export class RdDCombat {
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
_filterArmesParade(defender, competence, armeAttaque) { _filterArmesParade(defender, competence) {
let defenses = defender.items.filter(it => RdDItemArme.isParade(it)) let items = defender.items.filter(it => RdDItemArme.isArmeUtilisable(it) || RdDItemCompetenceCreature.isCompetenceParade(it))
defenses = foundry.utils.duplicate(defenses) items.forEach(item => item.system.nbUsage = defender.getItemUse(item.id)); // Ajout du # d'utilisation ce round
defenses.forEach(armeDefense => {
// Ajout du # d'utilisation ce round
armeDefense.nbUsage = defender.getItemUse(armeDefense.id)
armeDefense.typeParade = RdDItemArme.defenseArmeParade(armeAttaque, armeDefense)
})
switch (competence.system.categorie) { switch (competence.system.categorie) {
case 'tir': case 'tir':
case 'lancer': case 'lancer':
return defenses.filter(armeDefense => RdDItemArme.getCategorieParade(armeDefense) == 'boucliers') return items.filter(item => RdDItemArme.getCategorieParade(item) == 'boucliers')
default: default:
return defenses.filter(armeDefense => armeDefense.typeParade != '') // Le fléau ne peut être paré quau bouclier p115
if (competence.name == "Fléau") {
return items.filter(item => RdDItemArme.getCategorieParade(item) == 'boucliers')
}
return items.filter(item => RdDItemArme.getCategorieParade(item));
} }
} }
@@ -1014,7 +1075,7 @@ export class RdDCombat {
/* -------------------------------------------- */ /* -------------------------------------------- */
_prepareParade(attackerRoll, armeParade, competenceParade) { _prepareParade(attackerRoll, armeParade, competenceParade) {
let defenderRoll = { let defenderRoll = {
alias: this.defender?.getAlias(), alias: this.defenderToken?.name,
passeArme: attackerRoll.passeArme, passeArme: attackerRoll.passeArme,
diffLibre: attackerRoll.diffLibre, diffLibre: attackerRoll.diffLibre,
attackerToken: this.attackerToken, attackerToken: this.attackerToken,
@@ -1071,7 +1132,7 @@ export class RdDCombat {
async esquive(attackerRoll, compId, compName) { async esquive(attackerRoll, compId, compName) {
const esquive = this.defender.getCompetence(compId) ?? this.defender.getCompetence(compName) const esquive = this.defender.getCompetence(compId) ?? this.defender.getCompetence(compName)
if (esquive == undefined) { if (esquive == undefined) {
ui.notifications.error(this.defender.getAlias() + " n'a pas de compétence " + compName); ui.notifications.error(this.defender.name + " n'a pas de compétence " + compName);
return; return;
} }
console.log("RdDCombat.esquive >>>", attackerRoll, esquive); console.log("RdDCombat.esquive >>>", attackerRoll, esquive);
@@ -1098,7 +1159,7 @@ export class RdDCombat {
/* -------------------------------------------- */ /* -------------------------------------------- */
_prepareEsquive(attackerRoll, competence) { _prepareEsquive(attackerRoll, competence) {
let rollData = { let rollData = {
alias: this.defender.getAlias(), alias: this.defenderToken?.name,
passeArme: attackerRoll.passeArme, passeArme: attackerRoll.passeArme,
diffLibre: attackerRoll.diffLibre, diffLibre: attackerRoll.diffLibre,
attackerToken: this.attackerToken, attackerToken: this.attackerToken,
@@ -1274,15 +1335,11 @@ export class RdDCombat {
/* -------------------------------------------- */ /* -------------------------------------------- */
static async displayActorCombatStatus(combat, actor, token) { static async displayActorCombatStatus(combat, actor, token) {
if (!actor?.isActorCombat()) { let formData = {
return
}
const alias = token?.name ?? actor.getAlias();
const formData = {
combatId: combat._id, combatId: combat._id,
alias: alias, alias: token.name ?? actor.name,
etatGeneral: actor.getEtatGeneral(), etatGeneral: actor.getEtatGeneral(),
isSonne: actor.isSonne(), isSonne: actor.getSonne(),
blessuresStatus: actor.computeResumeBlessure(), blessuresStatus: actor.computeResumeBlessure(),
SConst: actor.getSConst(), SConst: actor.getSConst(),
actorId: actor.id, actorId: actor.id,
@@ -1293,12 +1350,12 @@ export class RdDCombat {
} }
await ChatMessage.create({ await ChatMessage.create({
content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-actor-turn-acteur.hbs`, formData), content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-actor-turn-acteur.hbs`, formData),
alias: alias alias: token.name ?? actor.name
}) })
await ChatMessage.create({ await ChatMessage.create({
content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-actor-turn-sante.hbs`, formData), content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-actor-turn-sante.hbs`, formData),
whisper: ChatUtility.getOwners(actor), whisper: ChatUtility.getOwners(actor),
alias: alias alias: token.name ?? actor.name
}) });
} }
} }

View File

@@ -121,7 +121,7 @@ export class RdDHotbar {
if (item.isCorpsACorps()) { if (item.isCorpsACorps()) {
switch (categorieArme) { switch (categorieArme) {
case 'pugilat': case 'pugilat':
return actor.rollArme(RdDItemArme.corpsACorps(actor), 'competence'); return actor.rollArme(RdDItemArme.mainsNues(actor), 'competence');
case 'empoignade': case 'empoignade':
return actor.rollArme(RdDItemArme.empoignade(actor), 'competence'); return actor.rollArme(RdDItemArme.empoignade(actor), 'competence');
} }

View File

@@ -68,7 +68,6 @@ import { OptionsAvancees } from "./settings/options-avancees.js"
import { ExportScriptarium } from "./actor/export-scriptarium/export-scriptarium.js" import { ExportScriptarium } from "./actor/export-scriptarium/export-scriptarium.js"
import { AppPersonnageAleatoire } from "./actor/random/app-personnage-aleatoire.js" import { AppPersonnageAleatoire } from "./actor/random/app-personnage-aleatoire.js"
import { RdDActorExportSheet } from "./actor/export-scriptarium/actor-encart-sheet.js" import { RdDActorExportSheet } from "./actor/export-scriptarium/actor-encart-sheet.js"
import { RdDStatBlockParser } from "./apps/rdd-import-stats.js"
/** /**
* RdD system * RdD system
@@ -88,7 +87,6 @@ export class SystemReveDeDragon {
this.config = RDD_CONFIG this.config = RDD_CONFIG
this.RdDUtility = RdDUtility this.RdDUtility = RdDUtility
this.RdDHotbar = RdDHotbar this.RdDHotbar = RdDHotbar
this.RdDStatBlockParser = RdDStatBlockParser
this.itemClasses = { this.itemClasses = {
armure: RdDItemArmure, armure: RdDItemArmure,
blessure: RdDItemBlessure, blessure: RdDItemBlessure,
@@ -274,16 +272,6 @@ export class SystemReveDeDragon {
}) })
} }
static async setupAccueil() {
let exists = game.scenes.find(j => j.name == "Accueil RdD");
if (!exists) {
const scenes = await SystemCompendiums.loadCompendium("foundryvtt-reve-de-dragon.scenes-rdd")
let newDocuments = scenes.filter(i => i.name == "Accueil RdD");
await game.scenes.documentClass.create(newDocuments);
game.scenes.find(i => i.name == "Accueil RdD").activate();
}
}
async onReady() { async onReady() {
/* -------------------------------------------- */ /* -------------------------------------------- */
@@ -304,8 +292,6 @@ export class SystemReveDeDragon {
StatusEffects.onReady() StatusEffects.onReady()
RdDHerbes.onReady() RdDHerbes.onReady()
RdDDice.onReady() RdDDice.onReady()
RdDStatBlockParser.parseStatBlock()
/* -------------------------------------------- */ /* -------------------------------------------- */
/* Affiche/Init le calendrier */ /* Affiche/Init le calendrier */
game.system.rdd.calendrier.display() game.system.rdd.calendrier.display()
@@ -317,8 +303,6 @@ export class SystemReveDeDragon {
user: game.user.id user: game.user.id
}) })
} }
SystemReveDeDragon.setupAccueil()
} }
/* -------------------------------------------- */ /* -------------------------------------------- */

View File

@@ -7,7 +7,6 @@ import { RdDBonus } from "./rdd-bonus.js";
import { RdDCarac } from "./rdd-carac.js"; import { RdDCarac } from "./rdd-carac.js";
import { RdDResolutionTable } from "./rdd-resolution-table.js"; import { RdDResolutionTable } from "./rdd-resolution-table.js";
import { ReglesOptionnelles } from "./settings/regles-optionnelles.js"; import { ReglesOptionnelles } from "./settings/regles-optionnelles.js";
import { Grammar } from "./grammar.js";
/** /**
* Extend the base Dialog entity to select roll parameters * Extend the base Dialog entity to select roll parameters
@@ -33,7 +32,7 @@ export class RdDRoll extends Dialog {
/* -------------------------------------------- */ /* -------------------------------------------- */
static _setDefaultOptions(actor, rollData) { static _setDefaultOptions(actor, rollData) {
let defaultRollData = { let defaultRollData = {
alias: actor.getAlias(), alias: actor.name,
ajustementsConditions: CONFIG.RDD.ajustementsConditions, ajustementsConditions: CONFIG.RDD.ajustementsConditions,
difficultesLibres: CONFIG.RDD.difficultesLibres, difficultesLibres: CONFIG.RDD.difficultesLibres,
etat: actor.getEtatGeneral(), etat: actor.getEtatGeneral(),
@@ -174,8 +173,8 @@ export class RdDRoll extends Dialog {
this.html.find("[name='diffLibre']").val(this.rollData.diffLibre); this.html.find("[name='diffLibre']").val(this.rollData.diffLibre);
}); });
this.html.find('.roll-carac-competence').change((event) => { this.html.find('.roll-carac-competence').change((event) => {
const competence = event.currentTarget.value const competence = event.currentTarget.value;
this.rollData.competence = this.rollData.competences.find(it => Grammar.equalsInsensitive(it.name, competence)) this.rollData.competence = this.rollData.competences.find(it => it.name == competence);
this.updateRollResult(html); this.updateRollResult(html);
}); });
this.html.find('.select-suivant-coeur').change((event) => { this.html.find('.select-suivant-coeur').change((event) => {
@@ -346,25 +345,24 @@ export class RdDRoll extends Dialog {
/* -------------------------------------------- */ /* -------------------------------------------- */
_getTitle(rollData) { _getTitle(rollData) {
const alias = rollData.alias
const carac = rollData.selectedCarac.label; const carac = rollData.selectedCarac.label;
if (!rollData.competence) { if (!rollData.competence) {
return `${alias}: ${carac}` return carac;
} }
const compName = rollData.competence.name; const compName = rollData.competence.name;
const niveau = Misc.toSignedString(rollData.competence.system.niveau) const niveau = Misc.toSignedString(rollData.competence.system.niveau)
if (compName == carac) { if (compName == carac) {
// cas des créatures // cas des créatures
return `${alias}: ${carac} Niveau ${niveau}` return `${carac} Niveau ${niveau}`
} }
if (rollData.draconicList && rollData.selectedSort) { if (rollData.draconicList && rollData.selectedSort) {
// cas de lancer de sort // cas de lancer de sort
return `${alias}: ${rollData.competence.name} Niveau ${niveau} ${rollData.selectedSort.name}` return `${rollData.competence.name} Niveau ${niveau} ${rollData.selectedSort.name}`
} }
if (rollData.arme && rollData.arme.name != compName) { if (rollData.arme && rollData.arme.name != compName) {
// ajouter l'arme au titre si son nom n'est pas la compétence // ajouter l'arme au titre si son nom n'est pas la compétence
return `${alias}: ${carac} / ${compName} (${rollData.arme.name}) Niveau ${niveau}` return `${carac} / ${compName} (${rollData.arme.name}) Niveau ${niveau}`
} }
return `${alias}: ${carac} / ${compName} Niveau ${niveau}` return `${carac} / ${compName} Niveau ${niveau}`
} }
} }

View File

@@ -1,3 +1,4 @@
import { Grammar } from "./grammar.js";
import { CompendiumTable, CompendiumTableHelpers, SystemCompendiums } from "./settings/system-compendiums.js"; import { CompendiumTable, CompendiumTableHelpers, SystemCompendiums } from "./settings/system-compendiums.js";
export class RdDRollTables { export class RdDRollTables {

View File

@@ -460,7 +460,7 @@ export class RdDTMRDialog extends Dialog {
let rencontreData = { let rencontreData = {
actor: this.actor, actor: this.actor,
alias: this.actor.getAlias(), alias: this.actor.name,
reveDepart: this.actor.getReveActuel(), reveDepart: this.actor.getReveActuel(),
competence: this.actor.getBestDraconic(), competence: this.actor.getBestDraconic(),
rencontre: this.currentRencontre, rencontre: this.currentRencontre,
@@ -641,7 +641,7 @@ export class RdDTMRDialog extends Dialog {
// simuler une rencontre // simuler une rencontre
let rencontreData = { let rencontreData = {
actor: this.actor, actor: this.actor,
alias: this.actor.getAlias(), alias: this.actor.name,
reveDepart: this.actor.getReveActuel(), reveDepart: this.actor.getReveActuel(),
competence: this.actor.getBestDraconic(), competence: this.actor.getBestDraconic(),
rencontre: this.currentRencontre, rencontre: this.currentRencontre,
@@ -1098,10 +1098,7 @@ export class RdDTMRDialog extends Dialog {
if (!this.viewOnly && this.actor.isResonanceSigneDraconique(coord)) { if (!this.viewOnly && this.actor.isResonanceSigneDraconique(coord)) {
ChatMessage.create({ ChatMessage.create({
whisper: ChatUtility.getOwners(this.actor), whisper: ChatUtility.getOwners(this.actor),
content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-signe-draconique-resonance.html`, { content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-signe-draconique-resonance.html`, { alias: this.actor.name, typeTMR: TMRUtility.getTMRType(coord) })
alias: this.actor.getAlias(),
typeTMR: TMRUtility.getTMRType(coord)
})
}); });
} }
} }

View File

@@ -28,15 +28,16 @@ export class RdDTokenHud {
await RdDTokenHud.addExtensionHudSoins(html, actor); await RdDTokenHud.addExtensionHudSoins(html, actor);
if (isCombat) { if (isCombat) {
const combatant = game.combat.combatants.find(c => c.tokenId == tokenId) let combatant = game.combat.combatants.find(c => c.tokenId == tokenId);
const actor = RdDCombatManager.getActorCombatant(combatant, { warning: false }) if (!(combatant?.actor)) {
if (actor) { ui.notifications.warn(`Le combatant ${token.name} n'est pas associé à un acteur, impossible de déterminer ses actions de combat!`)
let actions = RdDCombatManager.listActionsActorCombatant(actor) return;
// initiative
await RdDTokenHud.addExtensionHudInit(html, combatant, actions)
// combat
await RdDTokenHud.addExtensionHudCombat(html, combatant, token, actions)
} }
let actions = RdDCombatManager.listActionsCombat(combatant);
// initiative
await RdDTokenHud.addExtensionHudInit(html, combatant, actions);
// combat
await RdDTokenHud.addExtensionHudCombat(html, combatant, token, actions);
} }

View File

@@ -609,12 +609,12 @@ export class RdDUtility {
const encaissement = RdDUtility._selectEncaissement(jetTotal, rollData.dmg.mortalite); const encaissement = RdDUtility._selectEncaissement(jetTotal, rollData.dmg.mortalite);
const over20 = Math.max(jetTotal - 20, 0); const over20 = Math.max(jetTotal - 20, 0);
encaissement.dmg = rollData.dmg encaissement.dmg = rollData.dmg
if (ReglesOptionnelles.isUsing('localisation-aleatoire')) { if (ReglesOptionnelles.isUsing('localisation-aleatoire')){
encaissement.dmg.loc = rollData.dmg.loc ?? await RdDUtility.getLocalisation(actor.type) encaissement.dmg.loc = rollData.dmg.loc ?? await RdDUtility.getLocalisation(actor.type)
encaissement.dmg.loc.label = encaissement.dmg.loc.label ?? 'Corps;' encaissement.dmg.loc.label = encaissement.dmg.loc.label ?? 'Corps;'
} }
else { else{
encaissement.dmg.loc = { label: '' } encaissement.dmg.loc = {label:''}
} }
encaissement.dmg.bonusDegatsDiffLibre = bonusDegatsDiffLibre encaissement.dmg.bonusDegatsDiffLibre = bonusDegatsDiffLibre
encaissement.roll = roll; encaissement.roll = roll;
@@ -749,7 +749,7 @@ export class RdDUtility {
static getSelectedToken(actor) { static getSelectedToken(actor) {
if (canvas.tokens.controlled.length > 0) { if (canvas.tokens.controlled.length > 0) {
const tokens = canvas.tokens.controlled const tokens = canvas.tokens.controlled
.filter(it => it.actor.id == actor.id) .filter(it => it.actor.id == actor.id)
return tokens[0] return tokens[0]
} }
return undefined return undefined
@@ -881,10 +881,10 @@ export class RdDUtility {
/* -------------------------------------------- */ /* -------------------------------------------- */
static afficherHeuresChanceMalchance(heureNaissance) { static afficherHeuresChanceMalchance(heureNaissance) {
if (game.user.isGM) { if (game.user.isGM) {
const heure = RdDTimestamp.findHeure(heureNaissance) const heure = RdDTimestamp.findHeure(heureNaissance - 1);
if (heureNaissance && heure) { if (heureNaissance && heure) {
const ajustement = game.system.rdd.calendrier.getAjustementAstrologique(heureNaissance) let ajustement = game.system.rdd.calendrier.getAjustementAstrologique(heureNaissance);
const current = game.system.rdd.calendrier.heureCourante() const current = game.system.rdd.calendrier.heureCourante();
ChatMessage.create({ ChatMessage.create({
content: `A l'heure de <strong>${current.label}</strong>, le modificateur de Chance/Malchance est de <strong>${Misc.toSignedString(ajustement)}</strong> pour l'heure de naissance <strong>${heure.label}</strong>.`, content: `A l'heure de <strong>${current.label}</strong>, le modificateur de Chance/Malchance est de <strong>${Misc.toSignedString(ajustement)}</strong> pour l'heure de naissance <strong>${heure.label}</strong>.`,
whisper: ChatUtility.getGMs() whisper: ChatUtility.getGMs()

View File

@@ -15,17 +15,17 @@ export const STATUSES = {
} }
const rddStatusEffects = [ const rddStatusEffects = [
{ rdd: true, id: STATUSES.StatusStunned, name: 'EFFECT.StatusStunned', img: 'icons/svg/stoned.svg', "duration.rounds": 1 }, { rdd: true, id: STATUSES.StatusStunned, label: 'EFFECT.StatusStunned', icon: 'icons/svg/stoned.svg', "duration.rounds": 1 },
{ rdd: true, id: STATUSES.StatusBleeding, name: 'EFFECT.StatusBleeding', img: 'icons/svg/blood.svg' }, { rdd: true, id: STATUSES.StatusBleeding, label: 'EFFECT.StatusBleeding', icon: 'icons/svg/blood.svg' },
{ rdd: true, id: STATUSES.StatusProne, name: 'EFFECT.StatusProne', img: 'icons/svg/falling.svg' }, { rdd: true, id: STATUSES.StatusProne, label: 'EFFECT.StatusProne', icon: 'icons/svg/falling.svg' },
{ rdd: true, id: STATUSES.StatusGrappling, tint: '#33cc33', name: 'EFFECT.StatusGrappling', img: 'systems/foundryvtt-reve-de-dragon/icons/empoignade.webp' }, { rdd: true, id: STATUSES.StatusGrappling, tint: '#33cc33', label: 'EFFECT.StatusGrappling', icon: 'systems/foundryvtt-reve-de-dragon/icons/empoignade.webp' },
{ rdd: true, id: STATUSES.StatusGrappled, tint: '#ff9900', name: 'EFFECT.StatusGrappled', img: 'systems/foundryvtt-reve-de-dragon/icons/empoignade.webp' }, { rdd: true, id: STATUSES.StatusGrappled, tint: '#ff9900', label: 'EFFECT.StatusGrappled', icon: 'systems/foundryvtt-reve-de-dragon/icons/empoignade.webp' },
{ rdd: true, id: STATUSES.StatusRestrained, name: 'EFFECT.StatusRestrained', img: 'icons/svg/net.svg' }, { rdd: true, id: STATUSES.StatusRestrained, label: 'EFFECT.StatusRestrained', icon: 'icons/svg/net.svg' },
{ rdd: true, id: STATUSES.StatusUnconscious, name: 'EFFECT.StatusUnconscious', img: 'icons/svg/unconscious.svg' }, { rdd: true, id: STATUSES.StatusUnconscious, label: 'EFFECT.StatusUnconscious', icon: 'icons/svg/unconscious.svg' },
{ rdd: true, id: STATUSES.StatusBlind, name: 'EFFECT.StatusBlind', img: 'icons/svg/blind.svg' }, { rdd: true, id: STATUSES.StatusBlind, label: 'EFFECT.StatusBlind', icon: 'icons/svg/blind.svg' },
{ rdd: true, id: STATUSES.StatusComma, name: 'EFFECT.StatusComma', img: 'icons/svg/skull.svg' }, { rdd: true, id: STATUSES.StatusComma, label: 'EFFECT.StatusComma', icon: 'icons/svg/skull.svg' },
{ rdd: true, id: STATUSES.StatusDead, name: 'EFFECT.StatusDead', img: 'icons/svg/skull.svg' }, { rdd: true, id: STATUSES.StatusDead, label: 'EFFECT.StatusDead', icon: 'icons/svg/skull.svg' },
{ rdd: true, id: STATUSES.StatusDemiReve, name: 'EFFECT.StatusDemiReve', img: 'systems/foundryvtt-reve-de-dragon/icons/heures/hd12.svg' } { rdd: true, id: STATUSES.StatusDemiReve, label: 'EFFECT.StatusDemiReve', icon: 'systems/foundryvtt-reve-de-dragon/icons/heures/hd12.svg' }
]; ];
const demiReveStatusEffect = rddStatusEffects.find(it => it.id == STATUSES.StatusDemiReve); const demiReveStatusEffect = rddStatusEffects.find(it => it.id == STATUSES.StatusDemiReve);
@@ -57,7 +57,7 @@ export class StatusEffects extends FormApplication {
restricted: true restricted: true
}); });
CONFIG.RDD.allEffects = rddStatusEffects.concat(CONFIG.statusEffects.filter(it => !rddEffectIds.includes(it.id))) CONFIG.RDD.allEffects = rddStatusEffects.concat(CONFIG.statusEffects.filter(it => !rddEffectIds.includes(it.id)));
StatusEffects._setUseStatusEffects(StatusEffects._getUseStatusEffects()); StatusEffects._setUseStatusEffects(StatusEffects._getUseStatusEffects());
console.log('statusEffects', CONFIG.statusEffects); console.log('statusEffects', CONFIG.statusEffects);

View File

@@ -112,19 +112,6 @@ export class SystemCompendiums extends FormApplication {
return elements; return elements;
} }
/* -------------------------------------------- */
static async loadCompendiumData(compendium) {
const pack = game.packs.get(compendium);
return await pack?.getDocuments() ?? [];
}
/* -------------------------------------------- */
static async loadCompendium(compendium, filter = item => true) {
let compendiumData = await SystemCompendiums.loadCompendiumData(compendium);
return compendiumData.filter(filter);
}
static async getDefaultItems(compendium) { static async getDefaultItems(compendium) {
const pack = game.packs.get(SystemCompendiums._getDefaultCompendium(compendium)); const pack = game.packs.get(SystemCompendiums._getDefaultCompendium(compendium));
if (pack.metadata.type == 'Item') { if (pack.metadata.type == 'Item') {

View File

@@ -15,7 +15,7 @@ export class AutoAdjustDarkness {
} }
static async adjust(darkness) { static async adjust(darkness) {
if (game.user.isGM && AutoAdjustDarkness.isAuto()) { if (AutoAdjustDarkness.isAuto()) {
const scene = game.scenes.viewed; const scene = game.scenes.viewed;
if (scene?.environment?.globalLight?.enabled && scene?.tokenVision) { if (scene?.environment?.globalLight?.enabled && scene?.tokenVision) {
await scene.update({ darkness }); await scene.update({ darkness });

View File

@@ -160,21 +160,15 @@ export class RdDTimestamp {
} }
static findHeure(heure) { static findHeure(heure) {
let filtered heure = Grammar.toLowerCaseNoAccentNoSpace(heure);
if (Number.isInteger(Number(heure))) { let parHeureOuLabel = DEFINITION_HEURES.filter(it => Grammar.toLowerCaseNoAccentNoSpace(it.label) == heure || it.heure == Misc.modulo(parseInt(heure), RDD_HEURES_PAR_JOUR));
filtered = DEFINITION_HEURES.filter(it => it.heure == Misc.modulo(Number(heure) - 1, RDD_HEURES_PAR_JOUR)) if (parHeureOuLabel.length == 1) {
return parHeureOuLabel[0];
} }
else { let parLabelPartiel = DEFINITION_HEURES.filter(it => Grammar.toLowerCaseNoAccentNoSpace(it.label).includes(heure));
heure = Grammar.toLowerCaseNoAccentNoSpace(heure); if (parLabelPartiel.length > 0) {
filtered = DEFINITION_HEURES.filter(it => Grammar.toLowerCaseNoAccentNoSpace(it.label) == heure || it.heure == Misc.modulo(parseInt(heure), RDD_HEURES_PAR_JOUR)); parLabelPartiel.sort(Misc.ascending(h => h.label.length));
} return parLabelPartiel[0];
if (filtered.length == 1) {
return filtered[0]
}
filtered = DEFINITION_HEURES.filter(it => Grammar.toLowerCaseNoAccentNoSpace(it.label).includes(heure));
if (filtered.length > 0) {
filtered.sort(Misc.ascending(h => h.label.length));
return filtered[0]
} }
return undefined; return undefined;
} }

Binary file not shown.

View File

@@ -1 +0,0 @@
MANIFEST-000022

View File

View File

@@ -1,3 +0,0 @@
2024/11/10-18:39:00.183093 7fed63e006c0 Recovering log #21
2024/11/10-18:39:00.195436 7fed63e006c0 Delete type=0 #21
2024/11/10-18:39:00.195482 7fed63e006c0 Delete type=3 #20

View File

@@ -1,3 +0,0 @@
2024/11/10-18:38:41.533242 7f4c0b8006c0 Recovering log #19
2024/11/10-18:38:41.547823 7f4c0b8006c0 Delete type=0 #19
2024/11/10-18:38:41.547917 7f4c0b8006c0 Delete type=3 #18

Binary file not shown.

Binary file not shown.

View File

@@ -1 +0,0 @@
MANIFEST-000010

View File

@@ -1,3 +0,0 @@
2024/11/10-18:39:00.253481 7fed62a006c0 Recovering log #8
2024/11/10-18:39:00.263751 7fed62a006c0 Delete type=3 #6
2024/11/10-18:39:00.263866 7fed62a006c0 Delete type=0 #8

View File

@@ -1,8 +0,0 @@
2024/11/08-19:40:34.139501 7f9d7f4006c0 Recovering log #4
2024/11/08-19:40:34.182207 7f9d7f4006c0 Delete type=3 #2
2024/11/08-19:40:34.182311 7f9d7f4006c0 Delete type=0 #4
2024/11/08-19:56:45.129455 7f9d7d6006c0 Level-0 table #9: started
2024/11/08-19:56:45.129487 7f9d7d6006c0 Level-0 table #9: 0 bytes OK
2024/11/08-19:56:45.135738 7f9d7d6006c0 Delete type=0 #7
2024/11/08-19:56:45.142639 7f9d7d6006c0 Manual compaction at level-0 from '!actors!1Nng9d8r6lrPHCaJ' @ 72057594037927935 : 1 .. '!actors.items!ryUZTa17LzNv25UY.zyNYa3hYtrOcF2jA' @ 0 : 0; will stop at (end)
2024/11/08-19:56:45.142697 7f9d7d6006c0 Manual compaction at level-1 from '!actors!1Nng9d8r6lrPHCaJ' @ 72057594037927935 : 1 .. '!actors.items!ryUZTa17LzNv25UY.zyNYa3hYtrOcF2jA' @ 0 : 0; will stop at (end)

Binary file not shown.

View File

@@ -1 +0,0 @@
MANIFEST-000010

View File

@@ -1,3 +0,0 @@
2024/11/10-18:39:00.448675 7fed63e006c0 Recovering log #8
2024/11/10-18:39:00.460061 7fed63e006c0 Delete type=3 #6
2024/11/10-18:39:00.460115 7fed63e006c0 Delete type=0 #8

View File

@@ -1,8 +0,0 @@
2024/11/08-19:40:32.605216 7f9d7fe006c0 Recovering log #4
2024/11/08-19:40:32.664872 7f9d7fe006c0 Delete type=3 #2
2024/11/08-19:40:32.665020 7f9d7fe006c0 Delete type=0 #4
2024/11/08-19:56:44.948429 7f9d7d6006c0 Level-0 table #9: started
2024/11/08-19:56:44.948495 7f9d7d6006c0 Level-0 table #9: 0 bytes OK
2024/11/08-19:56:44.954943 7f9d7d6006c0 Delete type=0 #7
2024/11/08-19:56:44.975424 7f9d7d6006c0 Manual compaction at level-0 from '!items!240HPtZsgZQERFMF' @ 72057594037927935 : 1 .. '!items!zRQ5WnPI483CKm9Q' @ 0 : 0; will stop at (end)
2024/11/08-19:56:44.975473 7f9d7d6006c0 Manual compaction at level-1 from '!items!240HPtZsgZQERFMF' @ 72057594037927935 : 1 .. '!items!zRQ5WnPI483CKm9Q' @ 0 : 0; will stop at (end)

View File

@@ -1 +0,0 @@
MANIFEST-000010

View File

@@ -1,3 +0,0 @@
2024/11/10-18:39:00.493027 7fed63e006c0 Recovering log #8
2024/11/10-18:39:00.503119 7fed63e006c0 Delete type=3 #6
2024/11/10-18:39:00.503242 7fed63e006c0 Delete type=0 #8

View File

@@ -1,8 +0,0 @@
2024/11/08-19:40:32.670029 7f9d7ea006c0 Recovering log #4
2024/11/08-19:40:32.734322 7f9d7ea006c0 Delete type=3 #2
2024/11/08-19:40:32.734474 7f9d7ea006c0 Delete type=0 #4
2024/11/08-19:56:44.968549 7f9d7d6006c0 Level-0 table #9: started
2024/11/08-19:56:44.968601 7f9d7d6006c0 Level-0 table #9: 0 bytes OK
2024/11/08-19:56:44.975299 7f9d7d6006c0 Delete type=0 #7
2024/11/08-19:56:44.975466 7f9d7d6006c0 Manual compaction at level-0 from '!items!0zRL8bOpCXNQnIR4' @ 72057594037927935 : 1 .. '!items!yDHZfK4RmwQW4YaW' @ 0 : 0; will stop at (end)
2024/11/08-19:56:44.975488 7f9d7d6006c0 Manual compaction at level-1 from '!items!0zRL8bOpCXNQnIR4' @ 72057594037927935 : 1 .. '!items!yDHZfK4RmwQW4YaW' @ 0 : 0; will stop at (end)

View File

@@ -1 +0,0 @@
MANIFEST-000010

View File

@@ -1,3 +0,0 @@
2024/11/10-18:39:00.509122 7fed634006c0 Recovering log #8
2024/11/10-18:39:00.519320 7fed634006c0 Delete type=3 #6
2024/11/10-18:39:00.519377 7fed634006c0 Delete type=0 #8

View File

@@ -1,8 +0,0 @@
2024/11/08-19:40:32.738419 7f9d7f4006c0 Recovering log #4
2024/11/08-19:40:32.795459 7f9d7f4006c0 Delete type=3 #2
2024/11/08-19:40:32.795589 7f9d7f4006c0 Delete type=0 #4
2024/11/08-19:56:44.996588 7f9d7d6006c0 Level-0 table #9: started
2024/11/08-19:56:44.996618 7f9d7d6006c0 Level-0 table #9: 0 bytes OK
2024/11/08-19:56:45.003008 7f9d7d6006c0 Delete type=0 #7
2024/11/08-19:56:45.003203 7f9d7d6006c0 Manual compaction at level-0 from '!items!0Ms9iKxqigNNpZEx' @ 72057594037927935 : 1 .. '!items!wDHR5UHWq568lfGa' @ 0 : 0; will stop at (end)
2024/11/08-19:56:45.003226 7f9d7d6006c0 Manual compaction at level-1 from '!items!0Ms9iKxqigNNpZEx' @ 72057594037927935 : 1 .. '!items!wDHR5UHWq568lfGa' @ 0 : 0; will stop at (end)

Binary file not shown.

View File

@@ -1 +0,0 @@
MANIFEST-000010

View File

@@ -1,3 +0,0 @@
2024/11/10-18:39:00.471288 7fed63e006c0 Recovering log #8
2024/11/10-18:39:00.481737 7fed63e006c0 Delete type=3 #6
2024/11/10-18:39:00.481786 7fed63e006c0 Delete type=0 #8

View File

@@ -1,8 +0,0 @@
2024/11/08-19:40:32.544114 7f9d7e0006c0 Recovering log #4
2024/11/08-19:40:32.600711 7f9d7e0006c0 Delete type=3 #2
2024/11/08-19:40:32.600809 7f9d7e0006c0 Delete type=0 #4
2024/11/08-19:56:44.962085 7f9d7d6006c0 Level-0 table #9: started
2024/11/08-19:56:44.962125 7f9d7d6006c0 Level-0 table #9: 0 bytes OK
2024/11/08-19:56:44.968340 7f9d7d6006c0 Delete type=0 #7
2024/11/08-19:56:44.975455 7f9d7d6006c0 Manual compaction at level-0 from '!items!2JLK5e97WbTM5WxX' @ 72057594037927935 : 1 .. '!items!zyNYa3hYtrOcF2jA' @ 0 : 0; will stop at (end)
2024/11/08-19:56:44.975495 7f9d7d6006c0 Manual compaction at level-1 from '!items!2JLK5e97WbTM5WxX' @ 72057594037927935 : 1 .. '!items!zyNYa3hYtrOcF2jA' @ 0 : 0; will stop at (end)

Binary file not shown.

View File

@@ -1 +0,0 @@
MANIFEST-000010

View File

@@ -1,3 +0,0 @@
2024/11/10-18:39:00.523722 7fed690006c0 Recovering log #8
2024/11/10-18:39:00.533930 7fed690006c0 Delete type=3 #6
2024/11/10-18:39:00.533977 7fed690006c0 Delete type=0 #8

View File

@@ -1,8 +0,0 @@
2024/11/08-19:40:34.274388 7f9d7f4006c0 Recovering log #4
2024/11/08-19:40:34.331636 7f9d7f4006c0 Delete type=3 #2
2024/11/08-19:40:34.331841 7f9d7f4006c0 Delete type=0 #4
2024/11/08-19:56:45.135878 7f9d7d6006c0 Level-0 table #9: started
2024/11/08-19:56:45.135910 7f9d7d6006c0 Level-0 table #9: 0 bytes OK
2024/11/08-19:56:45.142458 7f9d7d6006c0 Delete type=0 #7
2024/11/08-19:56:45.142680 7f9d7d6006c0 Manual compaction at level-0 from '!actors!47YUryMgpq1UnLuB' @ 72057594037927935 : 1 .. '!actors.items!xngqS9HtwWOLf3Vo.iwfr7ekbLFzDCayP' @ 0 : 0; will stop at (end)
2024/11/08-19:56:45.142706 7f9d7d6006c0 Manual compaction at level-1 from '!actors!47YUryMgpq1UnLuB' @ 72057594037927935 : 1 .. '!actors.items!xngqS9HtwWOLf3Vo.iwfr7ekbLFzDCayP' @ 0 : 0; will stop at (end)

Binary file not shown.

View File

@@ -1 +0,0 @@
MANIFEST-000010

View File

@@ -1,3 +0,0 @@
2024/11/10-18:39:00.544474 7fed690006c0 Recovering log #8
2024/11/10-18:39:00.555177 7fed690006c0 Delete type=3 #6
2024/11/10-18:39:00.555255 7fed690006c0 Delete type=0 #8

View File

@@ -1,8 +0,0 @@
2024/11/08-19:40:33.076530 7f9d7e0006c0 Recovering log #4
2024/11/08-19:40:33.128870 7f9d7e0006c0 Delete type=3 #2
2024/11/08-19:40:33.128972 7f9d7e0006c0 Delete type=0 #4
2024/11/08-19:56:45.003377 7f9d7d6006c0 Level-0 table #9: started
2024/11/08-19:56:45.003402 7f9d7d6006c0 Level-0 table #9: 0 bytes OK
2024/11/08-19:56:45.009778 7f9d7d6006c0 Delete type=0 #7
2024/11/08-19:56:45.031135 7f9d7d6006c0 Manual compaction at level-0 from '!items!0I30m9qcYJk6UR6o' @ 72057594037927935 : 1 .. '!items!zlDa1vwmls6Uf4pt' @ 0 : 0; will stop at (end)
2024/11/08-19:56:45.031185 7f9d7d6006c0 Manual compaction at level-1 from '!items!0I30m9qcYJk6UR6o' @ 72057594037927935 : 1 .. '!items!zlDa1vwmls6Uf4pt' @ 0 : 0; will stop at (end)

Binary file not shown.

Binary file not shown.

View File

@@ -1 +0,0 @@
MANIFEST-000010

View File

@@ -1,3 +0,0 @@
2024/11/10-18:39:00.599542 7fed63e006c0 Recovering log #8
2024/11/10-18:39:00.610171 7fed63e006c0 Delete type=3 #6
2024/11/10-18:39:00.610222 7fed63e006c0 Delete type=0 #8

View File

@@ -1,8 +0,0 @@
2024/11/08-19:40:33.631893 7f9d7fe006c0 Recovering log #4
2024/11/08-19:40:33.691489 7f9d7fe006c0 Delete type=3 #2
2024/11/08-19:40:33.691603 7f9d7fe006c0 Delete type=0 #4
2024/11/08-19:56:45.074153 7f9d7d6006c0 Level-0 table #9: started
2024/11/08-19:56:45.074177 7f9d7d6006c0 Level-0 table #9: 0 bytes OK
2024/11/08-19:56:45.081226 7f9d7d6006c0 Delete type=0 #7
2024/11/08-19:56:45.087832 7f9d7d6006c0 Manual compaction at level-0 from '!items!1xzVPsfnO3uukbc4' @ 72057594037927935 : 1 .. '!items!yJ3m3fheGJluiGDx' @ 0 : 0; will stop at (end)
2024/11/08-19:56:45.087874 7f9d7d6006c0 Manual compaction at level-1 from '!items!1xzVPsfnO3uukbc4' @ 72057594037927935 : 1 .. '!items!yJ3m3fheGJluiGDx' @ 0 : 0; will stop at (end)

View File

@@ -1 +0,0 @@
MANIFEST-000010

Some files were not shown because too many files have changed in this diff Show More