foundryvtt-reve-de-dragon/module/item-arme.js

263 lines
8.6 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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": "Sans arme",
"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 => 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 dhast 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 isArmeUtilisable(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 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
}
}