Vincent Vandemeulebrouck
b7cb0f0752
La recherche était case-sensitive, du coup corriger le nom de la compétence 'Epées' dans le compendium des compétences rend les Épées inutilisable (et échec au chargement de la fiche)
284 lines
9.3 KiB
JavaScript
284 lines
9.3 KiB
JavaScript
import { Grammar } from "./grammar.js";
|
||
import { RdDItemCompetenceCreature } from "./item-competencecreature.js"
|
||
import { ITEM_TYPES } from "./item.js";
|
||
import { RdDCombatManager } from "./rdd-combat.js";
|
||
|
||
const nomCategorieParade = {
|
||
"sans-armes": "Sans arme",
|
||
"armes-naturelles": "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(item) {
|
||
return item.type == ITEM_TYPES.arme || RdDItemCompetenceCreature.getCategorieAttaque(item);
|
||
}
|
||
|
||
/* -------------------------------------------- */
|
||
static getArme(arme) {
|
||
switch (arme ? arme.type : '') {
|
||
case ITEM_TYPES.arme: return arme;
|
||
case ITEM_TYPES.competencecreature:
|
||
return RdDItemCompetenceCreature.armeCreature(arme);
|
||
}
|
||
return RdDItemArme.mainsNues();
|
||
}
|
||
|
||
static getCompetenceArme(arme, maniement) {
|
||
switch (arme.type) {
|
||
case ITEM_TYPES.competencecreature:
|
||
return arme.name
|
||
case ITEM_TYPES.arme:
|
||
switch (maniement) {
|
||
case 'competence': return arme.system.competence;
|
||
case 'unemain': return RdDItemArme.competence1Mains(arme);
|
||
case 'deuxmains': return RdDItemArme.competence2Mains(arme);
|
||
case 'tir': return arme.system.tir;
|
||
case 'lancer': return arme.system.lancer;
|
||
}
|
||
}
|
||
return undefined
|
||
}
|
||
|
||
static computeNiveauArmes(armes, competences) {
|
||
for (const arme of armes) {
|
||
arme.system.niveau = RdDItemArme.niveauCompetenceArme(arme, competences);
|
||
}
|
||
}
|
||
|
||
static niveauCompetenceArme(arme, competences) {
|
||
const compArme = competences.find(it => Grammar.equalsInsensitive(it.name, arme.system.competence))
|
||
return compArme?.system.niveau ?? -8
|
||
}
|
||
|
||
/* -------------------------------------------- */
|
||
static getNomCategorieParade(arme) {
|
||
const categorie = arme?.system ? 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) {
|
||
if (armeData.system.categorie_parade) {
|
||
return armeData.system.categorie_parade
|
||
}
|
||
// pour compatibilité avec des personnages existants
|
||
if (armeData.type == ITEM_TYPES.competencecreature || armeData.system.categorie == 'creature') {
|
||
return armeData.system.categorie_parade || (armeData.system.isparade ? 'armes-naturelles' : '')
|
||
}
|
||
if (!armeData.type.match(/arme|competencecreature/)) {
|
||
return ''
|
||
}
|
||
if (armeData.system.competence == undefined) {
|
||
return ITEM_TYPES.competencecreature;
|
||
}
|
||
let compname = armeData.system.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 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'
|
||
}
|
||
}
|
||
|
||
/* -------------------------------------------- */
|
||
static needParadeSignificative(armeAttaque, armeParade) {
|
||
if (!armeAttaque || !armeParade) {
|
||
return false;
|
||
}
|
||
// categories d'armes à la parade (cf. page 115 )
|
||
const attCategory = RdDItemArme.getCategorieParade(armeAttaque)
|
||
const 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 significative
|
||
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 dommagesReels(arme, maniement) {
|
||
switch (maniement) {
|
||
case 'tir':
|
||
case 'lancer':
|
||
case 'competence':
|
||
return Number(arme.system.dommages)
|
||
}
|
||
if (arme.system.unemain && arme.system.deuxmains) {
|
||
const containsSlash = !Number.isInteger(arme.system.dommages) && arme.system.dommages.includes("/")
|
||
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);
|
||
}
|
||
|
||
/* -------------------------------------------- */
|
||
static armeUneOuDeuxMains(arme, aUneMain) {
|
||
if (arme && !arme.system.cac) {
|
||
arme = foundry.utils.duplicate(arme);
|
||
arme.system.dommagesReels = RdDItemArme.dommagesReels(arme, aUneMain ? 'unemain' : 'deuxmains')
|
||
}
|
||
return arme;
|
||
}
|
||
|
||
static competence1Mains(arme) {
|
||
return arme.system.competence.replace(" 2 mains", " 1 main");
|
||
}
|
||
|
||
static competence2Mains(arme) {
|
||
return arme.system.competence.replace(" 1 main", " 2 mains");
|
||
}
|
||
|
||
static isUtilisable(arme) {
|
||
switch (arme.type) {
|
||
case ITEM_TYPES.arme: return arme.system.equipe && (arme.system.resistance > 0 || arme.system.portee_courte > 0)
|
||
case ITEM_TYPES.competencecreature: return true
|
||
}
|
||
return false
|
||
}
|
||
|
||
static isAttaque(arme) {
|
||
switch (arme.type) {
|
||
case ITEM_TYPES.arme:
|
||
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 ajoutCorpsACorps(armes, actor) {
|
||
armes.push(RdDItemArme.mainsNues(actor));
|
||
armes.push(RdDItemArme.empoignade(actor));
|
||
}
|
||
|
||
static corpsACorps(actor) {
|
||
let competence = actor?.getCompetenceCorpsACorps() ?? { system: { niveau: -6 } };
|
||
let melee = actor ? actor.system.carac['melee'].value : 0
|
||
return {
|
||
_id: competence?.id,
|
||
name: 'Corps à corps',
|
||
type: ITEM_TYPES.arme,
|
||
img: 'systems/foundryvtt-reve-de-dragon/icons/competence_corps_a_corps.webp',
|
||
system: {
|
||
initiative: RdDCombatManager.calculInitiative(competence.system.niveau, melee),
|
||
equipe: true,
|
||
rapide: true,
|
||
force: 0,
|
||
dommages: "0",
|
||
dommagesReels: 0,
|
||
mortalite: 'non-mortel',
|
||
competence: 'Corps à corps',
|
||
resistance: 1,
|
||
deuxmains: true,
|
||
categorie_parade: 'sans-armes'
|
||
}
|
||
}
|
||
}
|
||
|
||
static mainsNues(actor) {
|
||
const mainsNues = RdDItemArme.corpsACorps(actor)
|
||
mainsNues.name = 'Mains nues'
|
||
mainsNues.system.cac = 'pugilat'
|
||
mainsNues.system.baseInit = 4
|
||
return mainsNues;
|
||
}
|
||
|
||
static empoignade(actor) {
|
||
const empoignade = RdDItemArme.corpsACorps(actor)
|
||
empoignade.name = 'Empoignade'
|
||
empoignade.system.cac = 'empoignade'
|
||
empoignade.system.baseInit = 3
|
||
empoignade.system.mortalite = 'empoignade'
|
||
return empoignade
|
||
}
|
||
}
|