diff --git a/module/actor-sheet.js b/module/actor-sheet.js
index f78ff592..57ee081c 100644
--- a/module/actor-sheet.js
+++ b/module/actor-sheet.js
@@ -94,7 +94,7 @@ export class RdDActorSheet extends ActorSheet {
RdDItemArme.computeNiveauArmes(formData.combat, formData.competences);
RdDItemArme.ajoutCorpsACorps(formData.combat, formData.competences, formData.data.carac);
formData.esquives = this.actor.getCompetences("Esquive").map(i => foundry.utils.deepClone(i.data));
- formData.combat = RdDCombatManager.finalizeArmeList(formData.combat, formData.competences, formData.data.carac);
+ formData.combat = RdDCombatManager.listActionsArmes(formData.combat, formData.competences, formData.data.carac);
this.armesList = formData.combat;
@@ -335,8 +335,8 @@ export class RdDActorSheet extends ActorSheet {
html.find('.arme-initiative a').click(async event => {
let combatant = game.combat.data.combatants.find(c => c.actor.data._id == this.actor.data._id);
if (combatant) {
- let arme = this._getEventArmeCombat(event);
- RdDCombatManager.rollInitiativeCompetence(combatant._id, arme);
+ let action = this._getEventArmeCombat(event);
+ RdDCombatManager.rollInitiativeAction(combatant._id, action);
} else {
ui.notifications.info("Impossible de lancer l'initiative sans être dans un combat.");
}
diff --git a/module/actor.js b/module/actor.js
index de4ec700..ea056810 100644
--- a/module/actor.js
+++ b/module/actor.js
@@ -394,6 +394,9 @@ export class RdDActor extends Actor {
getPossession(possessionId) {
return this.items.find(it => it.type == 'possession' && it.data.data.possessionid == possessionId);
}
+ getPossessions() {
+ return this.items.filter(it => it.type == 'possession');
+ }
getDemiReve() {
return Misc.templateData(this).reve.tmrpos.coord;
@@ -2555,7 +2558,7 @@ export class RdDActor extends Actor {
if (rollData.competence.data.ispossession) {
RdDPossession.onAttaquePossession(this, rollData.competence)
} else {
- const arme = RdDItemCompetenceCreature.toArme(rollData.competence)
+ const arme = RdDItemCompetenceCreature.toActionArme(rollData.competence)
RdDCombat.createUsingTarget(this)?.attaque(competence, arme)
}
return
@@ -3145,7 +3148,7 @@ export class RdDActor extends Actor {
return carac.chance;
}
let entry = Misc.findFirstLike(name, Object.entries(carac), { mapper: it => it[1].label, description: 'caractéristique' });
- return entry.length > 0 ? carac[entry[0]] : undefined;
+ return entry && entry.length > 0 ? carac[entry[0]] : undefined;
}
/* -------------------------------------------- */
diff --git a/module/item-arme.js b/module/item-arme.js
index b1f1aafa..4f245bac 100644
--- a/module/item-arme.js
+++ b/module/item-arme.js
@@ -30,7 +30,7 @@ export class RdDItemArme extends Item {
switch (armeData ? armeData.type : '') {
case 'arme': return armeData;
case 'competencecreature':
- return RdDItemCompetenceCreature.toArme(armeData);
+ return RdDItemCompetenceCreature.toActionArme(armeData);
}
return RdDItemArme.mainsNues();
}
@@ -189,7 +189,7 @@ export class RdDItemArme extends Item {
categorie_parade: 'sans-armes'
}
};
- mergeObject(corpsACorps.data, actorData ??{}, { overwrite: false });
+ mergeObject(corpsACorps.data, actorData ?? {}, { overwrite: false });
return corpsACorps;
}
diff --git a/module/item-competence.js b/module/item-competence.js
index 5c7f3156..0bfe17b1 100644
--- a/module/item-competence.js
+++ b/module/item-competence.js
@@ -212,8 +212,11 @@ export class RdDItemCompetence extends Item {
/* -------------------------------------------- */
static findCompetence(list, idOrName, options = {}) {
+ if (idOrName == undefined) {
+ return undefined;
+ }
options = mergeObject(options, {
- filter: it => RdDItemCompetence.isCompetence(it),
+ preFilter: it => RdDItemCompetence.isCompetence(it),
description: 'compétence',
});
return list.find(it => it.id == idOrName && RdDItemCompetence.isCompetence(it))
diff --git a/module/item-competencecreature.js b/module/item-competencecreature.js
index 760b7f1e..d78abf22 100644
--- a/module/item-competencecreature.js
+++ b/module/item-competencecreature.js
@@ -11,14 +11,14 @@ export class RdDItemCompetenceCreature extends Item {
rollData.competence.data.categorie = "creature"
rollData.selectedCarac = rollData.carac.carac_creature
if (rollData.competence.data.iscombat) {
- rollData.arme = RdDItemCompetenceCreature.toArme(rollData.competence);
+ rollData.arme = RdDItemCompetenceCreature.toActionArme(rollData.competence);
}
}
/* -------------------------------------------- */
- static toArme(item) {
+ static toActionArme(item) {
if (RdDItemCompetenceCreature.isCompetenceAttaque(item)) {
- // si c'est un Item compétence: cloner pour ne pas modifier lma compétence
+ // si c'est un Item compétence: cloner pour ne pas modifier la compétence
let arme = Misc.data( (item instanceof Item) ? item.clone(): item);
mergeObject(arme.data,
{
@@ -28,11 +28,12 @@ export class RdDItemCompetenceCreature extends Item {
dommagesReels: arme.data.dommages,
penetration: 0,
force: 0,
- rapide: true
+ rapide: true,
+ action: 'attaque'
});
return arme;
}
- console.error("RdDItemCompetenceCreature.toArme(", item, ") : impossible de transformer l'Item en arme");
+ console.error("RdDItemCompetenceCreature.toActionArme(", item, ") : impossible de transformer l'Item en arme");
return undefined;
}
diff --git a/module/misc.js b/module/misc.js
index 59fc080c..3b6dbb40 100644
--- a/module/misc.js
+++ b/module/misc.js
@@ -192,7 +192,7 @@ export class Misc {
if (!single) {
single = subset[0];
const choices = Misc.join(subset.map(it => options.mapper(it)), '
');
- options.info(`Plusieurs choix de ${options.description}s possibles:
${choices}
Le premier sera choisi: ${mapToValue(single)}`);
+ options.onMessage(`Plusieurs choix de ${options.description}s possibles:
${choices}
Le premier sera choisi: ${options.mapper(single)}`);
}
return single;
}
@@ -211,7 +211,7 @@ export class Misc {
}
value = Grammar.toLowerCaseNoAccent(value);
const subset = elements.filter(options.preFilter)
- .filter(it => Grammar.toLowerCaseNoAccent(options.mapper(it)).includes(value));
+ .filter(it => Grammar.toLowerCaseNoAccent(options.mapper(it))?.includes(value));
if (subset.length == 0) {
options.onMessage(`Pas de ${options.description} correspondant à ${value}`);
}
diff --git a/module/rdd-combat.js b/module/rdd-combat.js
index 1f42618e..c057fbaa 100644
--- a/module/rdd-combat.js
+++ b/module/rdd-combat.js
@@ -1,5 +1,6 @@
import { ChatUtility } from "./chat-utility.js";
import { HIDE_DICE, SYSTEM_RDD, SYSTEM_SOCKET_ID } from "./constants.js";
+import { Grammar } from "./grammar.js";
import { RdDItemArme } from "./item-arme.js";
import { RdDItemCompetence } from "./item-competence.js";
import { RdDItemCompetenceCreature } from "./item-competencecreature.js";
@@ -26,7 +27,7 @@ const premierRoundInit = [
{ pattern: 'epeegnome', init: 5.35 },
{ pattern: 'masse', init: 5.30 },
{ pattern: 'gourdin', init: 5.25 },
- { pattern: 'fléau', init: 5.20 },
+ { pattern: 'fleau', init: 5.20 },
{ pattern: 'dague', init: 5.15 },
{ pattern: 'autre', init: 5.10 },
];
@@ -84,28 +85,23 @@ export class RdDCombatManager extends Combat {
// calculate initiative
for (let cId = 0; cId < ids.length; cId++) {
const combatant = this.combatants.get(ids[cId]);
- //if (!c) return results;
-
- let rollFormula = formula; // Init per default
- if (!rollFormula) {
- let armeCombat, competence;
+ let rollFormula = formula ?? RdDCombatManager.formuleInitiative(2, 10, 0, 0);
+ if (!formula) {
if (combatant.actor.data.type == 'creature' || combatant.actor.data.type == 'entite') {
- for (const competenceItemData of combatant.actor.data.items) {
- if (competenceItemData.data.data.iscombat) {
- competence = duplicate(competenceItemData);
- }
+ const competence = combatant.actor.data.items.find(it => it.data.data.iscombat)
+ if (competence) {
+ rollFormula = RdDCombatManager.formuleInitiative(2, competence.data.carac_value, competence.data.niveau, 0);
}
- rollFormula = "2+( (" + RdDCombatManager.calculInitiative(competence.data.niveau, competence.data.carac_value) + ")/100)";
} else {
- for (const itemData of combatant.actor.data.items) {
- if (itemData.type == "arme" && itemData.data.equipe) {
- armeCombat = duplicate(itemData);
- }
+ const armeCombat = combatant.actor.data.items.find(it => it.type == 'arme' && itemData.data.equipe)
+ const compName = (armeCombat == undefined) ? "Corps à corps" : armeCombat.data.competence;
+ const competence = RdDItemCompetence.findCompetence(combatant.actor.data.items, compName);
+ if (competence) {
+ const carac = combatant.actor.data.data.carac[competence.data.defaut_carac].value;
+ const niveau = competence.data.niveau;
+ const bonusEcaille = (armeCombat?.data.magique) ? armeCombat.data.ecaille_efficacite : 0;
+ rollFormula = RdDCombatManager.formuleInitiative(2, carac, niveau, bonusEcaille);
}
- let compName = (armeCombat == undefined) ? "Corps à corps" : armeCombat.data.competence;
- competence = RdDItemCompetence.findCompetence(combatant.actor.data.items, compName);
- let bonusEcaille = (armeCombat && armeCombat.data.magique) ? armeCombat.data.ecaille_efficacite : 0;
- rollFormula = "2+( (" + RdDCombatManager.calculInitiative(competence.data.niveau, Misc.data(combatant.actor).data.carac[competence.data.defaut_carac].value, bonusEcaille) + ")/100)";
}
}
//console.log("Combatat", c);
@@ -142,6 +138,10 @@ export class RdDCombatManager extends Combat {
return this;
};
+ static formuleInitiative(rang, carac, niveau, bonusMalus) {
+ return `${rang} +( (${RdDCombatManager.calculInitiative(niveau, carac, bonusMalus)} )/100)`;
+ }
+
/* -------------------------------------------- */
static calculInitiative(niveau, caracValue, bonusEcaille = 0) {
let base = niveau + Math.floor(caracValue / 2);
@@ -150,63 +150,77 @@ export class RdDCombatManager extends Combat {
}
/* -------------------------------------------- */
- /** Retourne une liste triée d'armes avec le split arme1 main / arme 2 main */
- static finalizeArmeList(armes, competences, carac) {
+ /** Retourne une liste triée d'actions d'armes avec le split arme1 main / arme 2 main */
+ static listActionsArmes(armes, competences, carac) {
// Gestion des armes 1/2 mains
- let armesEquipe = [];
+ let actionsArme = [];
for (const arme of armes) {
- let armeData = duplicate(Misc.data(arme));
- if (armeData.data.equipe) {
- let compData = competences.map(c => Misc.data(c)).find(c => c.name == armeData.data.competence);
+ let action = duplicate(Misc.data(arme));
+ if (action.data.equipe) {
+ let compData = competences.map(c => Misc.data(c)).find(c => c.name == action.data.competence);
- armesEquipe.push(armeData);
- armeData.data.dommagesReels = Number(armeData.data.dommages);
- armeData.data.niveau = compData.data.niveau;
- armeData.data.initiative = RdDCombatManager.calculInitiative(compData.data.niveau, carac[compData.data.defaut_carac].value);
+ actionsArme.push(action);
+ action.action = 'attaque';
+ action.data.dommagesReels = Number(action.data.dommages);
+ action.data.niveau = compData.data.niveau;
+ action.data.initiative = RdDCombatManager.calculInitiative(compData.data.niveau, carac[compData.data.defaut_carac].value);
// Dupliquer les armes pouvant être à 1 main et 2 mains en patchant la compétence
- if (armeData.data.unemain && !armeData.data.deuxmains) {
- armeData.data.mainInfo = "(1m)";
- } else if (!armeData.data.unemain && armeData.data.deuxmains) {
- armeData.data.mainInfo = "(2m)";
- } else if (armeData.data.unemain && armeData.data.deuxmains) {
- armeData.data.mainInfo = "(1m)";
+ if (action.data.unemain && !action.data.deuxmains) {
+ action.data.mainInfo = "(1m)";
+ } else if (!action.data.unemain && action.data.deuxmains) {
+ action.data.mainInfo = "(2m)";
+ } else if (action.data.unemain && action.data.deuxmains) {
+ action.data.mainInfo = "(1m)";
- const comp2m = armeData.data.competence.replace(" 1 main", " 2 mains"); // Replace !
+ const comp2m = action.data.competence.replace(" 1 main", " 2 mains"); // Replace !
const comp = Misc.data(competences.find(c => c.name == comp2m));
- const arme2main = duplicate(armeData);
+ const arme2main = duplicate(action);
arme2main.data.mainInfo = "(2m)";
arme2main.data.niveau = comp.data.niveau;
arme2main.data.competence = comp2m;
arme2main.data.initiative = RdDCombatManager.calculInitiative(arme2main.data.niveau, carac[comp.data.defaut_carac].value);
- armesEquipe.push(arme2main);
- const containsSlash = armeData.data.dommages.includes("/");
+ actionsArme.push(arme2main);
+ const containsSlash = action.data.dommages.includes("/");
if (containsSlash) {
- const tableauDegats = armeData.data.dommages.split("/");
- armeData.data.dommagesReels = Number(tableauDegats[0]);
+ const tableauDegats = action.data.dommages.split("/");
+ action.data.dommagesReels = Number(tableauDegats[0]);
arme2main.data.dommagesReels = Number(tableauDegats[1]);
}
else{
- ui.notifications.info("Les dommages de l'arme à 1/2 mains " + armeData.name + " ne sont pas corrects (ie sous la forme X/Y)");
+ ui.notifications.info("Les dommages de l'arme à 1/2 mains " + action.name + " ne sont pas corrects (ie sous la forme X/Y)");
}
}
}
}
- return armesEquipe.sort(Misc.ascending(armeData => armeData.name + (armeData.data.mainInfo ?? '')));
+ return actionsArme.sort(Misc.ascending(armeData => armeData.name + (armeData.data.mainInfo ?? '')));
+ }
+
+ static listActionsPossessions(actor) {
+ return RdDCombatManager._indexActions(actor.getPossessions().map(p =>
+ {
+ return {
+ name: p.name,
+ action: 'conjurer',
+ data: {
+ competence: p.name,
+ possessionid: p.data.data.possessionid,
+ }
+ }
+ }));
}
/* -------------------------------------------- */
- static buildListeActionsCombat(combatant) {
- if (combatant.actor == undefined) {
- ui.notifications.warn(`Le combatant ${combatant.name} n'est pas associé à un acteur, impossible de déterminer ses actions de combat!`)
- return [];
+ static listActionsCombat(combatant) {
+ const actor = combatant.actor;
+ let actions = RdDCombatManager.listActionsPossessions(actor);
+ if (actions.length>0) {
+ return actions;
}
- const actorData = Misc.data(combatant.actor);
- let items = combatant.actor.data.items;
- let actions = []
- if (combatant.actor.isCreature()) {
+ let items = actor.data.items;
+ if (actor.isCreature()) {
actions = actions.concat(items.filter(it => RdDItemCompetenceCreature.isCompetenceAttaque(it))
- .map(competence => RdDItemCompetenceCreature.toArme(competence)));
+ .map(competence => RdDItemCompetenceCreature.toActionArme(competence)));
} else {
// Recupération des items 'arme'
let armes = items.filter(it => RdDItemArme.isArmeUtilisable(it))
@@ -214,14 +228,17 @@ export class RdDCombatManager extends Combat {
.concat(RdDItemArme.mainsNues());
let competences = items.filter(it => it.type == 'competence');
- actions = actions.concat(RdDCombatManager.finalizeArmeList(armes, competences, actorData.data.carac));
+ actions = actions.concat(RdDCombatManager.listActionsArmes(armes, competences, actor.data.data.carac));
- if (actorData.data.attributs.hautrevant.value) {
- actions.push({ name: "Draconic", data: { initOnly: true, competence: "Draconic" } });
+ if (actor.data.data.attributs.hautrevant.value) {
+ actions.push({ name: "Draconic", action: 'haut-reve', data: { initOnly: true, competence: "Draconic" } });
}
}
- actions.push({ name: "Autre action", data: { initOnly: true, competence: "Autre action" } });
+ return RdDCombatManager._indexActions(actions);
+ }
+
+ static _indexActions(actions) {
for (let index = 0; index < actions.length; index++) {
actions[index].index = index;
}
@@ -235,15 +252,15 @@ export class RdDCombatManager extends Combat {
let initMissing = game.combat.data.combatants.find(it => !it.initiative);
if (!initMissing) { // Premier round !
for (let combatant of game.combat.data.combatants) {
- let arme = combatant.initiativeData?.arme;
+ let action = combatant.initiativeData?.arme;
//console.log("Parsed !!!", combatant, initDone, game.combat.current, arme);
- if (arme && arme.type == "arme") {
+ if (action && action.type == "arme") {
for (let initData of premierRoundInit) {
- if (arme.data.initpremierround.toLowerCase().includes(initData.pattern)) {
+ if (Grammar.toLowerCaseNoAccentNoSpace(action.data.initpremierround).includes(initData.pattern)) {
let msg = `