Compare commits

..

No commits in common. "6819f1c2f56744d475d1ef830f84e7a7890f9f2e" and "a62281429587ec6642b5bd20bada414b134f2c44" have entirely different histories.

8 changed files with 87 additions and 99 deletions

View File

@ -542,7 +542,7 @@ export class RdDBaseActor extends Actor {
// Calculer le total actuel des contenus // Calculer le total actuel des contenus
const encContenu = dest.getEncContenu(); const encContenu = dest.getEncContenu();
const newEnc = moved.getEncTotal(); // Calculer le total actuel du nouvel objet const newEnc = moved.getEncTotal(); // Calculer le total actuel du nouvel objet
const placeDisponible = Misc.keepDecimals(dest.system.capacite - encContenu - newEnc, 4) const placeDisponible = Math.roundDecimals(dest.system.capacite - encContenu - newEnc, 4)
// Teste si le conteneur de destination a suffisament de capacité pour recevoir le nouvel objet // Teste si le conteneur de destination a suffisament de capacité pour recevoir le nouvel objet
if (placeDisponible < 0) { if (placeDisponible < 0) {

View File

@ -1,3 +1,4 @@
import { LOG_HEAD } from "../../constants.js"
import { ACTOR_TYPES } from "../../item.js" import { ACTOR_TYPES } from "../../item.js"
import { Misc } from "../../misc.js" import { Misc } from "../../misc.js"
import { EXPORT_CSV_SCRIPTARIUM, OptionsAvancees } from "../../settings/options-avancees.js" import { EXPORT_CSV_SCRIPTARIUM, OptionsAvancees } from "../../settings/options-avancees.js"
@ -27,7 +28,6 @@ export class ExportScriptarium {
callback: target => this.exportActors(this.$getActors(actorDirectory, target), this.$getTargetName(actorDirectory, target)) callback: target => this.exportActors(this.$getActors(actorDirectory, target), this.$getTargetName(actorDirectory, target))
}) })
} }
$getTargetName(actorDirectory, target) { $getTargetName(actorDirectory, target) {
const li = target.closest(".directory-item") const li = target.closest(".directory-item")
const folderId = li.data("folderId") const folderId = li.data("folderId")
@ -36,7 +36,6 @@ export class ExportScriptarium {
? game.actors.get(actorId).name ? game.actors.get(actorId).name
: actorDirectory.folders.find(it => it.id == folderId).name : actorDirectory.folders.find(it => it.id == folderId).name
} }
$getActors(actorDirectory, target) { $getActors(actorDirectory, target) {
const li = target.closest(".directory-item") const li = target.closest(".directory-item")
const folderId = li.data("folderId") const folderId = li.data("folderId")
@ -50,7 +49,7 @@ export class ExportScriptarium {
} }
exportActors(actors, targetName) { exportActors(actors, targetName) {
const eol = '\n' const eol = '\n\r'
const header = Misc.join(this.getHeaderLine(), ';') const header = Misc.join(this.getHeaderLine(), ';')
const actorLines = actors.map(actor => Misc.join(this.getActorLine(actor), ';')) const actorLines = actors.map(actor => Misc.join(this.getActorLine(actor), ';'))
const data = Misc.join([header, ...actorLines], eol) const data = Misc.join([header, ...actorLines], eol)
@ -65,7 +64,6 @@ export class ExportScriptarium {
getActorLine(actor) { getActorLine(actor) {
const context = Mapping.prepareContext(actor) const context = Mapping.prepareContext(actor)
return this.mapping.map(it => it.getter(actor, context)) return this.mapping.map(it => it.getter(actor, context))
//.map(it => JSON.stringify(it))
.map(it => this.$escapeQuotes(it)) .map(it => this.$escapeQuotes(it))
.map(it => it.replaceAll("\n", " ").replaceAll("\r", "")) .map(it => it.replaceAll("\n", " ").replaceAll("\r", ""))
} }

View File

@ -5,8 +5,8 @@ import { RdDItemSort } from "../../item-sort.js"
import { ITEM_TYPES } from "../../item.js" import { ITEM_TYPES } from "../../item.js"
import { Misc } from "../../misc.js" import { Misc } from "../../misc.js"
import { RdDTimestamp } from "../../time/rdd-timestamp.js" import { RdDTimestamp } from "../../time/rdd-timestamp.js"
import { RdDBonus } from "../../rdd-bonus.js" import { TMRConstants } from "../../tmr-constants.js"
import { TMRUtility } from "../../tmr-utility.js"
const CATEGORIES_COMPETENCES = [ const CATEGORIES_COMPETENCES = [
"generale", "generale",
@ -80,7 +80,8 @@ const MAPPING_BASE = [
{ column: "armure", getter: (actor, context) => Mapping.getArmure(actor, context) }, { column: "armure", getter: (actor, context) => Mapping.getArmure(actor, context) },
{ column: "protection", getter: (actor, context) => Mapping.getProtectionArmure(actor, context) }, { column: "protection", getter: (actor, context) => Mapping.getProtectionArmure(actor, context) },
{ column: "malus-armure", getter: (actor, context) => Mapping.getMalusArmure(actor, context) }, { column: "malus-armure", getter: (actor, context) => Mapping.getMalusArmure(actor, context) },
{ column: "esquive", getter: (actor, context) => Mapping.getEsquiveNiveau(context) }, { column: "esquive", getter: (actor, context) => Mapping.getEsquive(actor, context) },
{ column: "esquive-niv", getter: (actor, context) => Mapping.getEsquiveNiveau(context) },
{ column: "competences", getter: (actor, context) => Mapping.getCompetences(actor, CATEGORIES_COMPETENCES) }, { column: "competences", getter: (actor, context) => Mapping.getCompetences(actor, CATEGORIES_COMPETENCES) },
{ column: "draconic", getter: (actor, context) => Mapping.getCompetences(actor, CATEGORIES_DRACONIC) }, { column: "draconic", getter: (actor, context) => Mapping.getCompetences(actor, CATEGORIES_DRACONIC) },
] ]
@ -88,7 +89,7 @@ const MAPPING_BASE = [
const MAPPING_ARMES = TABLEAU_ARMES.map(i => ColumnMappingFactory.createMappingArme('name', i)) const MAPPING_ARMES = TABLEAU_ARMES.map(i => ColumnMappingFactory.createMappingArme('name', i))
.concat(TABLEAU_ARMES.map(i => ColumnMappingFactory.createMappingArme('niveau', i))) .concat(TABLEAU_ARMES.map(i => ColumnMappingFactory.createMappingArme('niveau', i)))
.concat(TABLEAU_ARMES.map(i => ColumnMappingFactory.createMappingArme('init', i))) .concat(TABLEAU_ARMES.map(i => ColumnMappingFactory.createMappingArme('init', i)))
.concat(TABLEAU_ARMES.map(i => ColumnMappingFactory.createMappingArme('dommages', i))) .concat(TABLEAU_ARMES.map(i => ColumnMappingFactory.createMappingArme('dom', i)))
const MAPPING_SORTS = TABLEAU_SORTS.map(i => ColumnMappingFactory.createMappingSort('voie', i)) const MAPPING_SORTS = TABLEAU_SORTS.map(i => ColumnMappingFactory.createMappingSort('voie', i))
.concat(TABLEAU_SORTS.map(i => ColumnMappingFactory.createMappingSort('description', i))) .concat(TABLEAU_SORTS.map(i => ColumnMappingFactory.createMappingSort('description', i)))
.concat(TABLEAU_SORTS.map(i => ColumnMappingFactory.createMappingSort('bonus', i))) .concat(TABLEAU_SORTS.map(i => ColumnMappingFactory.createMappingSort('bonus', i)))
@ -112,36 +113,29 @@ export class Mapping {
} }
static prepareArmes(actor) { static prepareArmes(actor) {
const armes = actor.items.filter(it => it.type == ITEM_TYPES.arme) return actor.items.filter(it => it.type == ITEM_TYPES.arme)
return armes.map(arme => .map(arme => {
[ // TODO: gestion armes 1 ou 2 mains
arme.system.tir != "" ? Mapping.prepareArme(actor, arme, 'tir') : undefined, const compToUse = RdDItemArme.getCompetenceArme(arme, 'competence');
arme.system.lancer = "" ? Mapping.prepareArme(actor, arme, 'lancer') : undefined, const comp = actor.getCompetence(compToUse);
arme.system.unemain ? Mapping.prepareArme(actor, arme, 'unemain') : undefined, const bonusDom = Mapping.calculBonusDom(comp, actor)
arme.system.deuxmains ? Mapping.prepareArme(actor, arme, 'deuxmains') : undefined,
!(arme.system.unemain || arme.system.deuxmains) ? Mapping.prepareArme(actor, arme, 'competence') : undefined
]
.filter(it => it != undefined)
).reduce((a, b) => a.concat(b), [])
}
static prepareArme(actor, arme, maniement) {
const nameCompArme = RdDItemArme.getCompetenceArme(arme, maniement)
const competence = actor.getCompetence(nameCompArme)
if (RdDItemCompetence.isNiveauBase(competence)) {
return undefined
}
const dmgArme = RdDItemArme.dommagesReels(arme, maniement)
const dommages = dmgArme + RdDBonus.bonusDmg(actor, maniement, dmgArme)
return { return {
name: arme.name, name: arme.name,
niveau: Misc.toSignedString(competence.system.niveau), niveau: comp.system.niveau,
init: Mapping.calculBaseInit(actor, competence.system.categorie) + competence.system.niveau, init: Mapping.calculBaseInit(actor, comp.system.categorie) + comp.system.niveau,
dommages: Misc.toSignedString(dommages) dom: Number(arme.system.dommages) + bonusDom
};
});
} }
static calculBonusDom(comp, actor) {
// TODO: reuse dmg calc?
const appliesBonusDom = ['melee', 'lancer'].includes(comp.system.categorie)
return appliesBonusDom ? Number(actor.system.attributs.plusdom.value) : 0
} }
static calculBaseInit(actor, categorie) { static calculBaseInit(actor, categorie) {
// TODO: reuse init calc?
const mapping = MAPPING_BASE.find(it => it.column == categorie) const mapping = MAPPING_BASE.find(it => it.column == categorie)
if (mapping) { if (mapping) {
switch (categorie) { switch (categorie) {
@ -181,22 +175,20 @@ export class Mapping {
const esquive = esquives[0] const esquive = esquives[0]
return { return {
name: esquive.name, name: esquive.name,
niveau: Misc.toSignedString(esquive.system.niveau) niveau: esquive.system.niveau
} }
} }
return undefined return undefined
} }
static prepareSorts(actor) { static prepareSorts(actor) {
return actor.itemTypes[ITEM_TYPES.sort].map(it => Mapping.prepareSort(it)) return actor.itemTypes[ITEM_TYPES.sort].map(it => {
}
static prepareSort(sort) {
return { return {
voie: RdDItemSort.getCodeDraconic(sort), voie: RdDItemSort.getCodeDraconic(it),
description: Mapping.descriptionSort(sort), description: Mapping.descriptionSort(it),
bonus: Mapping.bonusCase(sort) bonus: Mapping.bonusCase(it)
} }
})
} }
static descriptionSort(sort) { static descriptionSort(sort) {
@ -206,12 +198,11 @@ export class Mapping {
} }
static bonusCase(sort) { static bonusCase(sort) {
const list = RdDItemSort.bonuscaseStringToList(sort.system.bonuscase).sort(Misc.descending(it => it.bonus)) const list = RdDItemSort.buildBonusCaseList(sort.system.bonuscase, false).sort(Misc.descending(it => it.bonus))
if (list.length > 0) { if (list.length > 0) {
const bonus = list[0] const bonus = list[0]
return `+${bonus.bonus}% en ${bonus.case}` return `+${bonus.bonus}% en ${bonus.case}`
} }
return ''
} }
static getDescription(actor) { static getDescription(actor) {
@ -242,6 +233,10 @@ export class Mapping {
return context?.armure?.malus ?? 0 return context?.armure?.malus ?? 0
} }
static getEsquive(actor, context) {
return context.esquive?.name ?? ''
}
static getEsquiveNiveau(context) { static getEsquiveNiveau(context) {
if (context.esquive) { if (context.esquive) {
const niveau = context.esquive.niveau + context.armure.malus const niveau = context.esquive.niveau + context.armure.malus
@ -265,8 +260,9 @@ export class Mapping {
} }
const txtCategorieByNiveau = niveaux.map(niveau => { const txtCategorieByNiveau = niveaux.map(niveau => {
const names = Misc.join(byNiveau[niveau].map(it => it.name).sort(Misc.ascending()), ', ') const names = Misc.join(byNiveau[niveau].map(it => it.name).sort(Misc.ascending()), ', ')
return names + ' ' + Misc.toSignedString(niveau) return names + ': ' + Misc.toSignedString(niveau)
}) }
)
const txtCategorie = Misc.join(txtCategorieByNiveau, ' / ') const txtCategorie = Misc.join(txtCategorieByNiveau, ' / ')
return txtCategorie return txtCategorie
}).filter(it => it != '') }).filter(it => it != '')

View File

@ -33,12 +33,12 @@ export class RdDItemArme extends Item {
return RdDItemArme.mainsNues(); return RdDItemArme.mainsNues();
} }
static getCompetenceArme(arme, maniement) { static getCompetenceArme(arme, competenceName) {
switch (arme.type) { switch (arme.type) {
case ITEM_TYPES.competencecreature: case ITEM_TYPES.competencecreature:
return arme.name return arme.name
case ITEM_TYPES.arme: case ITEM_TYPES.arme:
switch (maniement) { switch (competenceName) {
case 'competence': return arme.system.competence; case 'competence': return arme.system.competence;
case 'unemain': return RdDItemArme.competence1Mains(arme); case 'unemain': return RdDItemArme.competence1Mains(arme);
case 'deuxmains': return RdDItemArme.competence2Mains(arme); case 'deuxmains': return RdDItemArme.competence2Mains(arme);
@ -148,32 +148,30 @@ export class RdDItemArme extends Item {
return true; return true;
} }
static dommagesReels(arme, maniement) { /* -------------------------------------------- */
switch (maniement) { static armeUneOuDeuxMains(armeData, aUneMain) {
case 'tir': if (armeData && !armeData.system.cac) {
case 'lancer': armeData.system.unemain = armeData.system.unemain || !armeData.system.deuxmains;
case 'competence': const uneOuDeuxMains = armeData.system.unemain && armeData.system.deuxmains;
return Number(arme.system.dommages) const containsSlash = !Number.isInteger(armeData.system.dommages) && armeData.system.dommages.includes("/");
if (containsSlash) { // Sanity check
armeData = foundry.utils.duplicate(armeData);
const tableauDegats = armeData.system.dommages.split("/");
if (aUneMain)
armeData.system.dommagesReels = Number(tableauDegats[0]);
else // 2 mains
armeData.system.dommagesReels = Number(tableauDegats[1]);
} }
if (arme.system.unemain && arme.system.deuxmains) { else {
const containsSlash = !Number.isInteger(arme.system.dommages) && arme.system.dommages.includes("/") armeData.system.dommagesReels = Number(armeData.system.dommages);
if (!containsSlash) {
ui.notifications.info("Les dommages de l'arme à 1/2 mains " + arme.name + " ne sont pas corrects (ie sous la forme X/Y)");
return Number(arme.system.dommages)
}
const tableauDegats = arme.system.dommages.split("/");
return Number(tableauDegats[maniement == 'unemain' ? 0 : 1])
}
return Number(arme.system.dommages);
} }
/* -------------------------------------------- */ if (uneOuDeuxMains != containsSlash) {
static armeUneOuDeuxMains(arme, aUneMain) { ui.notifications.info("Les dommages de l'arme à 1/2 mains " + armeData.name + " ne sont pas corrects (ie sous la forme X/Y)");
if (arme && !arme.system.cac) {
arme = foundry.utils.duplicate(arme);
arme.system.dommagesReels = RdDItemArme.dommagesReels(arme, aUneMain ? 'unemain' : 'deuxmains')
} }
return arme; }
return armeData;
} }
static competence1Mains(arme) { static competence1Mains(arme) {
@ -199,7 +197,7 @@ export class RdDItemArme extends Item {
static corpsACorps(actor) { static corpsACorps(actor) {
let competence = actor?.getCompetenceCorpsACorps() ?? { system: { niveau: -6 } }; let competence = actor?.getCompetenceCorpsACorps() ?? { system: { niveau: -6 } };
let melee = actor ? actor.system.carac['melee'].value : 0 let melee = actor? actor.system.carac['melee'].value : 0
return { return {
_id: competence?.id, _id: competence?.id,
name: 'Corps à corps', name: 'Corps à corps',

View File

@ -5,11 +5,11 @@ import { Misc } from "./misc.js";
import { TMRUtility } from "./tmr-utility.js"; import { TMRUtility } from "./tmr-utility.js";
const VOIES_DRACONIC = [ const VOIES_DRACONIC = [
{ code: 'O', label: "Voie d'Oniros", short: 'Oniros' }, { code: 'O', label: "Voie d'Oniros", short: 'Oniros'},
{ code: 'H', label: "Voie d'Hypnos", short: 'Hypnos' }, { code: 'H', label: "Voie d'Hypnos" , short:'Hypnos' },
{ code: 'N', label: "Voie de Narcos", short: 'Narcos' }, { code: 'N', label: "Voie de Narcos", short: 'Narcos' },
{ code: 'T', label: "Voie de Thanatos", short: 'Thanatos' }, { code: 'T', label: "Voie de Thanatos", short:'Thanatos' },
{ code: 'O/H/N/T', label: "Oniros/Hypnos/Narcos/Thanatos", short: 'Oniros/Hypnos/Narcos/Thanatos' }, { code: 'O/H/N/T', label: "Oniros/Hypnos/Narcos/Thanatos", short:'Oniros/Hypnos/Narcos/Thanatos' },
{ code: 'O/H/N', label: "Oniros/Hypnos/Narcos" } { code: 'O/H/N', label: "Oniros/Hypnos/Narcos" }
] ]
@ -65,9 +65,9 @@ export class RdDItemSort extends Item {
/* -------------------------------------------- */ /* -------------------------------------------- */
static buildBonusCaseList(bonuscase, newCase) { static buildBonusCaseList(bonuscase, newCase) {
const list = RdDItemSort.bonuscaseStringToList(bonuscase) const list = RdDItemSort._bonuscaseStringToList(bonuscase)
if (newCase) { if (newCase) {
list.push({ case: "Nouvelle", bonus: 0 }) return list.concat({ case: "Nouvelle", bonus: 0 });
} }
return list; return list;
} }
@ -138,11 +138,8 @@ export class RdDItemSort extends Item {
.sort(Misc.ascending()) .sort(Misc.ascending())
.join(','); .join(',');
} }
static bonuscaseStringToList(bonuscase) { static _bonuscaseStringToList(bonuscase) {
if (bonuscase == undefined || bonuscase == '') { return (bonuscase ?? '').split(',').map(it => {
return []
}
return bonuscase.split(',').map(it => {
const b = it.split(':'); const b = it.split(':');
return { case: b[0], bonus: b[1] }; return { case: b[0], bonus: b[1] };
}); });

View File

@ -31,8 +31,8 @@ export class RdDBonus {
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
static dmg(rollData, actor, isEntiteIncarnee = false) { static dmg(rollData, dmgActor, isEntiteIncarnee = false) {
const dmgArme = RdDBonus.dmgArme(rollData.arme) const dmgArme = RdDBonus._dmgArme(rollData)
let dmg = { let dmg = {
total: 0, total: 0,
dmgArme: dmgArme, dmgArme: dmgArme,
@ -41,7 +41,7 @@ export class RdDBonus {
dmgParticuliere: RdDBonus._dmgParticuliere(rollData), dmgParticuliere: RdDBonus._dmgParticuliere(rollData),
dmgSurprise: RdDBonus.dmgBonus(rollData.ajustements?.attaqueDefenseurSurpris.used), dmgSurprise: RdDBonus.dmgBonus(rollData.ajustements?.attaqueDefenseurSurpris.used),
mortalite: RdDBonus._calculMortalite(rollData, isEntiteIncarnee), mortalite: RdDBonus._calculMortalite(rollData, isEntiteIncarnee),
dmgActor: RdDBonus.bonusDmg(actor, rollData.selectedCarac?.label.toLowerCase(), dmgArme) dmgActor: RdDBonus._dmgPerso(dmgActor, rollData.selectedCarac?.label, dmgArme)
} }
dmg.total = dmg.dmgSurprise + dmg.dmgTactique + dmg.dmgArme + dmg.dmgActor + dmg.dmgParticuliere; dmg.total = dmg.dmgSurprise + dmg.dmgTactique + dmg.dmgArme + dmg.dmgActor + dmg.dmgParticuliere;
return dmg; return dmg;
@ -71,11 +71,11 @@ export class RdDBonus {
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
static dmgArme(arme) { static _dmgArme(rollData) {
if (arme) { if (rollData.arme) {
let dmgBase = arme.system.dommagesReels ?? Number(arme.system.dommages ?? 0); let dmgBase = rollData.arme.system.dommagesReels ?? Number(rollData.arme.system.dommages ?? 0);
//Le bonus dégats magiques ne peut pas faire dépasser le bonus de l'arme (cf p.278) //Le bonus dégats magiques ne peut pas faire dépasser le bonus de l'arme (cf p.278)
return dmgBase + Math.min(dmgBase, arme.system.magique ? arme.system.ecaille_efficacite : 0); return dmgBase + Math.min(dmgBase, rollData.arme.system.magique ? rollData.arme.system.ecaille_efficacite : 0);
} }
return 0; return 0;
} }
@ -86,14 +86,13 @@ export class RdDBonus {
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
static bonusDmg(actor, categorie, dmgArme) { static _dmgPerso(dmgActor, categorie, dmgArme) {
const dmgActor = actor.getBonusDegat()
if (categorie == undefined) { if (categorie == undefined) {
return 0 return 0
} }
switch (categorie) { switch (categorie) {
case "tir": return 0; case "Tir": return 0;
case "lancer": return Math.max(0, Math.min(dmgArme, dmgActor)); case "Lancer": return Math.max(0, Math.min(dmgArme, dmgActor));
} }
return dmgActor; return dmgActor;
} }

View File

@ -864,7 +864,7 @@ export class RdDCombat {
async _onAttaqueNormale(attackerRoll) { async _onAttaqueNormale(attackerRoll) {
console.log("RdDCombat.onAttaqueNormale >>>", attackerRoll); console.log("RdDCombat.onAttaqueNormale >>>", attackerRoll);
attackerRoll.dmg = RdDBonus.dmg(attackerRoll, this.attacker, this.defender.isEntite()); attackerRoll.dmg = RdDBonus.dmg(attackerRoll, this.attacker.getBonusDegat(), 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.target ? this.defender.name : 'la cible', cible: this.target ? this.defender.name : 'la cible',

View File

@ -307,7 +307,7 @@ export class RdDRoll extends Dialog {
async updateRollResult(html) { async updateRollResult(html) {
const rollData = this.rollData; const rollData = this.rollData;
rollData.dmg = rollData.attackerRoll?.dmg ?? RdDBonus.dmg(rollData, this.actor) rollData.dmg = rollData.attackerRoll?.dmg ?? RdDBonus.dmg(rollData, this.actor.getBonusDegat())
rollData.caracValue = parseInt(rollData.selectedCarac.value) rollData.caracValue = parseInt(rollData.selectedCarac.value)
rollData.dmg.mortalite = rollData.dmg.mortalite ?? 'mortel'; rollData.dmg.mortalite = rollData.dmg.mortalite ?? 'mortel';
rollData.use.appelAuMoral = this.actor.isPersonnage() && RdDCarac.isActionPhysique(rollData.selectedCarac); rollData.use.appelAuMoral = this.actor.isPersonnage() && RdDCarac.isActionPhysique(rollData.selectedCarac);