25d7a447a8
Ajout de méthode Misc.data pour accéder aux data des Actor/Item Dans le cas où on est sur un Actor/Item, retourne le document (noeud data) Dans les autres cas, retourne l'objet lkui même (donc, le document) Du coup, on devrait pouvoir facilement changer en 0.8.0
195 lines
6.7 KiB
JavaScript
195 lines
6.7 KiB
JavaScript
import { RdDItemCompetenceCreature } from "./item-competencecreature.js"
|
||
import { Misc } from "./misc.js";
|
||
import { RdDCombatManager } from "./rdd-combat.js";
|
||
|
||
const nomCategorieParade = {
|
||
"sans-armes": "Sans arme / armes naturelles",
|
||
"hast": "Armes d'hast",
|
||
"batons": "Bâtons",
|
||
"boucliers": "Boucliers",
|
||
"dagues": "Dagues",
|
||
"epees-courtes": "Epées courtes",
|
||
"epees-longues": "Epées longues",
|
||
"epees-lourdes": "Epées lourdes",
|
||
"haches": "Haches",
|
||
"lances": "Lances",
|
||
}
|
||
|
||
/* -------------------------------------------- */
|
||
export class RdDItemArme extends Item {
|
||
|
||
static isArme(itemData) {
|
||
itemData = Misc.data(itemData);
|
||
return (itemData.type == 'competencecreature' && itemData.data.iscombat) || itemData.type == 'arme';
|
||
}
|
||
|
||
/* -------------------------------------------- */
|
||
static getArmeData(armeData) {
|
||
armeData = Misc.data(armeData);
|
||
switch (armeData ? armeData.type : '') {
|
||
case 'arme': return armeData;
|
||
case 'competencecreature':
|
||
return RdDItemCompetenceCreature.toArme(armeData);
|
||
}
|
||
return RdDItemArme.mainsNues();
|
||
}
|
||
|
||
static computeNiveauArmes(armes, competences) {
|
||
for (const arme of armes) {
|
||
arme.data.niveau = RdDItemArme.niveauCompetenceArme(arme, competences);
|
||
}
|
||
}
|
||
|
||
static niveauCompetenceArme(arme, competences) {
|
||
const compArme = competences.find(it => it.name == arme.data.competence);
|
||
return compArme?.data.niveau ?? -8;
|
||
}
|
||
|
||
/* -------------------------------------------- */
|
||
static getNomCategorieParade(arme) {
|
||
const categorie = arme?.data ? RdDItemArme.getCategorieParade(arme) : arme;
|
||
return nomCategorieParade[categorie];
|
||
}
|
||
|
||
/* -------------------------------------------- */
|
||
static needArmeResist(armeAttaque, armeParade) {
|
||
if (!armeAttaque || !armeParade) {
|
||
return false;
|
||
}
|
||
// Epées parant une arme de bois (cf. page 115 ), une résistance est nécessaire
|
||
let attCategory = RdDItemArme.getCategorieParade(armeAttaque);
|
||
let defCategory = RdDItemArme.getCategorieParade(armeParade);
|
||
|
||
return attCategory.match(/epees-/) && defCategory.match(/(haches|lances)/);
|
||
}
|
||
|
||
/* -------------------------------------------- */
|
||
static getCategorieParade(armeData) {
|
||
armeData = Misc.data(armeData);
|
||
if (armeData.data.categorie_parade) {
|
||
return armeData.data.categorie_parade;
|
||
}
|
||
// pour compatibilité avec des personnages existants
|
||
if (armeData.type == 'competencecreature' || armeData.data.categorie == 'creature') {
|
||
return armeData.data.categorie_parade || (armeData.data.isparade ? 'sans-armes' : '');
|
||
}
|
||
if (!armeData.type.match(/arme|competencecreature/)) {
|
||
return '';
|
||
}
|
||
if (armeData.data.competence == undefined) {
|
||
return 'competencecreature';
|
||
}
|
||
let compname = armeData.data.competence.toLowerCase();
|
||
if (compname.match(/^(dague de jet|javelot|fouet|arc|arbalête|fronde|hache de jet|fléau)$/)) return '';
|
||
|
||
if (compname.match('hache')) return 'haches';
|
||
if (compname.match('hast')) return 'hast';
|
||
if (compname.match('lance')) return 'lances';
|
||
if (compname.match('bouclier')) return 'boucliers';
|
||
if (compname.match('masse')) return 'masses';
|
||
if (compname.match('epée') || compname.match('épée')) {
|
||
if (armeData.name.toLowerCase().match(/(gnome)/))
|
||
return 'epees-courtes';
|
||
if (armeData.name.toLowerCase().match(/((e|é)pée dragone|esparlongue|demi-dragonne)/))
|
||
return 'epees-longues';
|
||
return 'epees-lourdes';
|
||
}
|
||
if (compname.match('dague')) {
|
||
return 'dagues';
|
||
}
|
||
return 'sans-armes';
|
||
}
|
||
|
||
/* -------------------------------------------- */
|
||
static needParadeSignificative(armeAttaque, armeParade) {
|
||
if (!armeAttaque || !armeParade) {
|
||
return false;
|
||
}
|
||
// categories d'armes à la parade (cf. page 115 )
|
||
let attCategory = RdDItemArme.getCategorieParade(armeAttaque);
|
||
let defCategory = RdDItemArme.getCategorieParade(armeParade);
|
||
// bouclier et mêmes catégorie: peuvent se parer sans difficulté
|
||
if (defCategory == 'boucliers') {
|
||
return false;
|
||
}
|
||
// Parer avec une hache ou une arme d’hast exige toujours une signi$cative
|
||
if (defCategory.match(/(hast|haches)/)) {
|
||
return true;
|
||
}
|
||
if (defCategory == attCategory) {
|
||
return false;
|
||
}
|
||
// les épées se parent entre elles
|
||
if (defCategory.match(/epees-/) && attCategory.match(/epees-/)) {
|
||
return false;
|
||
}
|
||
// l'épée gnome pare la dague
|
||
if (defCategory == 'epees-courtes' && attCategory == 'dagues') {
|
||
return false;
|
||
}
|
||
// la dague pare les épées courtes et légères
|
||
if (defCategory == 'dagues' && attCategory.match(/epees-(courtes|legeres)/)) {
|
||
return false;
|
||
}
|
||
return true;
|
||
}
|
||
|
||
/* -------------------------------------------- */
|
||
static armeUneOuDeuxMains(armeData, aUneMain) {
|
||
armeData = Misc.data(armeData);
|
||
if (armeData) {
|
||
armeData.data.unemain = armeData.data.unemain || !armeData.data.deuxmains;
|
||
const uneOuDeuxMains = armeData.data.unemain && armeData.data.deuxmains;
|
||
const containsSlash = !Number.isInteger(armeData.data.dommages) && armeData.data.dommages.includes("/");
|
||
if (containsSlash) { // Sanity check
|
||
armeData = duplicate(armeData);
|
||
|
||
const tableauDegats = armeData.data.dommages.split("/");
|
||
if (aUneMain)
|
||
armeData.data.dommagesReels = Number(tableauDegats[0]);
|
||
else // 2 mains
|
||
armeData.data.dommagesReels = Number(tableauDegats[1]);
|
||
}
|
||
else {
|
||
armeData.data.dommagesReels = Number(armeData.data.dommages);
|
||
}
|
||
|
||
if (uneOuDeuxMains != containsSlash) {
|
||
ui.notifications.info("Les dommages de l'arme à 1/2 mains " + armeData.name + " ne sont pas corrects (ie sous la forme X/Y)");
|
||
}
|
||
}
|
||
return armeData;
|
||
}
|
||
|
||
static isArmeUtilisable(itemData) {
|
||
itemData = Misc.data(itemData);
|
||
return itemData.type == 'arme' && itemData.data.equipe && (itemData.data.resistance > 0 || itemData.data.portee_courte > 0);
|
||
}
|
||
|
||
static ajoutCorpsACorps(armes, competences, carac) {
|
||
let corpsACorps = competences.find(it => it.name == 'Corps à corps') ?? { data: { niveau: -6 } };
|
||
let init = RdDCombatManager.calculInitiative(corpsACorps.data.niveau, carac['melee'].value);
|
||
armes.push(RdDItemArme.mainsNues({ niveau: corpsACorps.data.niveau, initiative: init }));
|
||
}
|
||
|
||
static mainsNues(actorData = {}) {
|
||
const mainsNues = {
|
||
name: 'Mains nues',
|
||
data: {
|
||
equipe: true,
|
||
rapide: true,
|
||
force: 0,
|
||
dommages: 0,
|
||
dommagesReels: 0,
|
||
mortalite: 'non-mortel',
|
||
competence: 'Corps à corps',
|
||
categorie_parade: 'sans-armes'
|
||
}
|
||
};
|
||
if (actorData) {
|
||
mergeObject(mainsNues.data, actorData, { overwrite: false });
|
||
}
|
||
return mainsNues
|
||
}
|
||
}
|