2024-11-26 22:35:05 +01:00
|
|
|
|
import { Grammar } from "./grammar.js";
|
2021-01-04 00:17:22 +01:00
|
|
|
|
import { RdDItemCompetenceCreature } from "./item-competencecreature.js"
|
2024-09-25 22:56:24 +02:00
|
|
|
|
import { ITEM_TYPES } from "./item.js";
|
2021-03-18 23:55:26 +01:00
|
|
|
|
import { RdDCombatManager } from "./rdd-combat.js";
|
2021-01-02 04:28:43 +01:00
|
|
|
|
|
2021-01-05 18:43:13 +01:00
|
|
|
|
const nomCategorieParade = {
|
2021-06-28 15:52:20 +02:00
|
|
|
|
"sans-armes": "Sans arme",
|
2024-11-24 00:59:35 +01:00
|
|
|
|
"armes-naturelles": "Armes naturelles",
|
2021-01-02 04:28:43 +01:00
|
|
|
|
"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",
|
|
|
|
|
}
|
|
|
|
|
|
2021-01-04 00:17:22 +01:00
|
|
|
|
/* -------------------------------------------- */
|
2020-12-12 21:58:44 +01:00
|
|
|
|
export class RdDItemArme extends Item {
|
|
|
|
|
|
2022-09-07 18:47:56 +02:00
|
|
|
|
static isArme(item) {
|
2024-09-25 22:56:24 +02:00
|
|
|
|
return item.type == ITEM_TYPES.arme || RdDItemCompetenceCreature.getCategorieAttaque(item);
|
2021-01-04 00:17:22 +01:00
|
|
|
|
}
|
|
|
|
|
|
2020-12-12 21:58:44 +01:00
|
|
|
|
/* -------------------------------------------- */
|
2022-09-07 18:47:56 +02:00
|
|
|
|
static getArme(arme) {
|
|
|
|
|
switch (arme ? arme.type : '') {
|
2024-09-25 22:56:24 +02:00
|
|
|
|
case ITEM_TYPES.arme: return arme;
|
|
|
|
|
case ITEM_TYPES.competencecreature:
|
2023-06-13 01:55:38 +02:00
|
|
|
|
return RdDItemCompetenceCreature.armeCreature(arme);
|
2021-01-01 22:25:32 +01:00
|
|
|
|
}
|
2024-11-26 23:23:34 +01:00
|
|
|
|
return RdDItemArme.corpsACorps();
|
2021-01-01 22:25:32 +01:00
|
|
|
|
}
|
|
|
|
|
|
2024-09-27 02:32:13 +02:00
|
|
|
|
static getCompetenceArme(arme, maniement) {
|
2024-09-25 22:56:24 +02:00
|
|
|
|
switch (arme.type) {
|
|
|
|
|
case ITEM_TYPES.competencecreature:
|
|
|
|
|
return arme.name
|
|
|
|
|
case ITEM_TYPES.arme:
|
2024-09-27 02:32:13 +02:00
|
|
|
|
switch (maniement) {
|
2024-09-25 22:56:24 +02:00
|
|
|
|
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
|
|
|
|
|
}
|
|
|
|
|
|
2021-03-18 23:55:26 +01:00
|
|
|
|
static computeNiveauArmes(armes, competences) {
|
|
|
|
|
for (const arme of armes) {
|
2022-06-12 08:17:59 +02:00
|
|
|
|
arme.system.niveau = RdDItemArme.niveauCompetenceArme(arme, competences);
|
2021-03-18 23:55:26 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static niveauCompetenceArme(arme, competences) {
|
2024-11-26 22:35:05 +01:00
|
|
|
|
const compArme = competences.find(it => Grammar.equalsInsensitive(it.name, arme.system.competence))
|
|
|
|
|
return compArme?.system.niveau ?? -8
|
2021-03-18 23:55:26 +01:00
|
|
|
|
}
|
|
|
|
|
|
2021-01-02 04:28:43 +01:00
|
|
|
|
/* -------------------------------------------- */
|
2021-01-05 18:43:13 +01:00
|
|
|
|
static getNomCategorieParade(arme) {
|
2022-06-12 08:17:59 +02:00
|
|
|
|
const categorie = arme?.system ? RdDItemArme.getCategorieParade(arme) : arme;
|
2021-01-05 18:43:13 +01:00
|
|
|
|
return nomCategorieParade[categorie];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------- */
|
|
|
|
|
static needArmeResist(armeAttaque, armeParade) {
|
2021-03-18 23:55:26 +01:00
|
|
|
|
if (!armeAttaque || !armeParade) {
|
2021-01-05 18:43:13 +01:00
|
|
|
|
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)/);
|
2021-01-02 04:28:43 +01:00
|
|
|
|
}
|
2021-01-04 00:17:22 +01:00
|
|
|
|
|
2021-01-01 22:23:58 +01:00
|
|
|
|
/* -------------------------------------------- */
|
2021-03-22 20:10:37 +01:00
|
|
|
|
static getCategorieParade(armeData) {
|
2022-06-12 08:17:59 +02:00
|
|
|
|
if (armeData.system.categorie_parade) {
|
2024-11-04 00:19:21 +01:00
|
|
|
|
return armeData.system.categorie_parade
|
2021-01-01 22:23:58 +01:00
|
|
|
|
}
|
|
|
|
|
// pour compatibilité avec des personnages existants
|
2024-09-25 22:56:24 +02:00
|
|
|
|
if (armeData.type == ITEM_TYPES.competencecreature || armeData.system.categorie == 'creature') {
|
2024-11-04 00:19:21 +01:00
|
|
|
|
return armeData.system.categorie_parade || (armeData.system.isparade ? 'armes-naturelles' : '')
|
2021-01-01 22:23:58 +01:00
|
|
|
|
}
|
2021-03-22 20:10:37 +01:00
|
|
|
|
if (!armeData.type.match(/arme|competencecreature/)) {
|
2024-11-04 00:19:21 +01:00
|
|
|
|
return ''
|
2021-01-01 22:23:58 +01:00
|
|
|
|
}
|
2022-06-12 08:17:59 +02:00
|
|
|
|
if (armeData.system.competence == undefined) {
|
2024-09-25 22:56:24 +02:00
|
|
|
|
return ITEM_TYPES.competencecreature;
|
2020-12-12 21:58:44 +01:00
|
|
|
|
}
|
2022-06-12 08:17:59 +02:00
|
|
|
|
let compname = armeData.system.competence.toLowerCase();
|
2024-11-04 00:19:21 +01:00
|
|
|
|
if (compname.match(/^(dague de jet|javelot|fouet|arc|arbalête|fronde|hache de jet|fléau)$/)) {
|
|
|
|
|
return ''
|
|
|
|
|
}
|
2020-12-12 21:58:44 +01:00
|
|
|
|
|
2024-11-04 00:19:21 +01:00
|
|
|
|
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'
|
2021-01-01 22:23:58 +01:00
|
|
|
|
if (compname.match('epée') || compname.match('épée')) {
|
2021-03-22 20:10:37 +01:00
|
|
|
|
if (armeData.name.toLowerCase().match(/(gnome)/))
|
2024-11-04 00:19:21 +01:00
|
|
|
|
return 'epees-courtes'
|
2021-03-22 20:10:37 +01:00
|
|
|
|
if (armeData.name.toLowerCase().match(/((e|é)pée dragone|esparlongue|demi-dragonne)/))
|
2024-11-04 00:19:21 +01:00
|
|
|
|
return 'epees-longues'
|
|
|
|
|
return 'epees-lourdes'
|
2020-12-12 21:58:44 +01:00
|
|
|
|
}
|
2021-01-01 22:23:58 +01:00
|
|
|
|
if (compname.match('dague')) {
|
2024-11-04 00:19:21 +01:00
|
|
|
|
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'
|
2020-12-12 21:58:44 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------- */
|
|
|
|
|
static needParadeSignificative(armeAttaque, armeParade) {
|
2021-03-18 23:55:26 +01:00
|
|
|
|
if (!armeAttaque || !armeParade) {
|
2021-01-05 18:43:13 +01:00
|
|
|
|
return false;
|
|
|
|
|
}
|
2021-01-02 04:28:43 +01:00
|
|
|
|
// categories d'armes à la parade (cf. page 115 )
|
2024-11-04 00:19:21 +01:00
|
|
|
|
const attCategory = RdDItemArme.getCategorieParade(armeAttaque)
|
|
|
|
|
const defCategory = RdDItemArme.getCategorieParade(armeParade)
|
2021-01-01 22:23:58 +01:00
|
|
|
|
// bouclier et mêmes catégorie: peuvent se parer sans difficulté
|
2021-01-02 04:28:43 +01:00
|
|
|
|
if (defCategory == 'boucliers') {
|
2021-01-01 22:23:58 +01:00
|
|
|
|
return false;
|
|
|
|
|
}
|
2021-06-22 23:28:32 +02:00
|
|
|
|
// Parer avec une hache ou une arme d’hast exige toujours une significative
|
2021-01-02 04:28:43 +01:00
|
|
|
|
if (defCategory.match(/(hast|haches)/)) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
if (defCategory == attCategory) {
|
2021-01-01 22:23:58 +01:00
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
// les épées se parent entre elles
|
2021-01-02 04:28:43 +01:00
|
|
|
|
if (defCategory.match(/epees-/) && attCategory.match(/epees-/)) {
|
2021-01-01 22:23:58 +01:00
|
|
|
|
return false;
|
|
|
|
|
}
|
2021-01-02 04:28:43 +01:00
|
|
|
|
// l'épée gnome pare la dague
|
|
|
|
|
if (defCategory == 'epees-courtes' && attCategory == 'dagues') {
|
2020-12-12 21:58:44 +01:00
|
|
|
|
return false;
|
|
|
|
|
}
|
2021-01-02 04:28:43 +01:00
|
|
|
|
// la dague pare les épées courtes et légères
|
|
|
|
|
if (defCategory == 'dagues' && attCategory.match(/epees-(courtes|legeres)/)) {
|
2020-12-12 21:58:44 +01:00
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2024-09-27 02:32:13 +02:00
|
|
|
|
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)
|
2020-12-16 23:02:15 +01:00
|
|
|
|
}
|
2024-09-27 02:32:13 +02:00
|
|
|
|
const tableauDegats = arme.system.dommages.split("/");
|
|
|
|
|
return Number(tableauDegats[maniement == 'unemain' ? 0 : 1])
|
|
|
|
|
}
|
|
|
|
|
return Number(arme.system.dommages);
|
|
|
|
|
}
|
2020-12-12 21:58:44 +01:00
|
|
|
|
|
2024-09-27 02:32:13 +02:00
|
|
|
|
/* -------------------------------------------- */
|
|
|
|
|
static armeUneOuDeuxMains(arme, aUneMain) {
|
|
|
|
|
if (arme && !arme.system.cac) {
|
|
|
|
|
arme = foundry.utils.duplicate(arme);
|
|
|
|
|
arme.system.dommagesReels = RdDItemArme.dommagesReels(arme, aUneMain ? 'unemain' : 'deuxmains')
|
2020-12-12 21:58:44 +01:00
|
|
|
|
}
|
2024-09-27 02:32:13 +02:00
|
|
|
|
return arme;
|
2020-12-12 21:58:44 +01:00
|
|
|
|
}
|
2023-10-23 22:04:45 +02:00
|
|
|
|
|
|
|
|
|
static competence1Mains(arme) {
|
|
|
|
|
return arme.system.competence.replace(" 2 mains", " 1 main");
|
|
|
|
|
}
|
2020-12-12 21:58:44 +01:00
|
|
|
|
|
2024-09-25 22:56:24 +02:00
|
|
|
|
static competence2Mains(arme) {
|
|
|
|
|
return arme.system.competence.replace(" 1 main", " 2 mains");
|
|
|
|
|
}
|
|
|
|
|
|
2024-11-06 23:24:53 +01:00
|
|
|
|
static isUtilisable(arme) {
|
2023-11-22 22:16:48 +01:00
|
|
|
|
switch (arme.type) {
|
2024-09-25 22:56:24 +02:00
|
|
|
|
case ITEM_TYPES.arme: return arme.system.equipe && (arme.system.resistance > 0 || arme.system.portee_courte > 0)
|
|
|
|
|
case ITEM_TYPES.competencecreature: return true
|
2023-11-22 22:16:48 +01:00
|
|
|
|
}
|
|
|
|
|
return false
|
2021-03-18 23:55:26 +01:00
|
|
|
|
}
|
|
|
|
|
|
2024-11-06 23:24:53 +01:00
|
|
|
|
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
|
|
|
|
|
}
|
|
|
|
|
|
2023-10-23 23:40:03 +02:00
|
|
|
|
static corpsACorps(actor) {
|
|
|
|
|
let competence = actor?.getCompetenceCorpsACorps() ?? { system: { niveau: -6 } };
|
2024-09-27 02:32:13 +02:00
|
|
|
|
let melee = actor ? actor.system.carac['melee'].value : 0
|
2023-10-23 23:40:03 +02:00
|
|
|
|
return {
|
|
|
|
|
_id: competence?.id,
|
2021-06-28 16:08:45 +02:00
|
|
|
|
name: 'Corps à corps',
|
2024-09-25 22:56:24 +02:00
|
|
|
|
type: ITEM_TYPES.arme,
|
2021-11-20 01:19:29 +01:00
|
|
|
|
img: 'systems/foundryvtt-reve-de-dragon/icons/competence_corps_a_corps.webp',
|
2022-05-01 00:38:09 +02:00
|
|
|
|
system: {
|
2023-10-23 23:40:03 +02:00
|
|
|
|
initiative: RdDCombatManager.calculInitiative(competence.system.niveau, melee),
|
2021-01-04 00:17:22 +01:00
|
|
|
|
equipe: true,
|
|
|
|
|
rapide: true,
|
|
|
|
|
force: 0,
|
2022-11-18 03:38:17 +01:00
|
|
|
|
dommages: "0",
|
2021-01-04 00:17:22 +01:00
|
|
|
|
dommagesReels: 0,
|
|
|
|
|
mortalite: 'non-mortel',
|
|
|
|
|
competence: 'Corps à corps',
|
2023-11-20 17:17:29 +01:00
|
|
|
|
resistance: 1,
|
2024-11-26 23:23:34 +01:00
|
|
|
|
baseInit: 4,
|
|
|
|
|
cac: 'pugilat',
|
2023-10-23 22:04:45 +02:00
|
|
|
|
deuxmains: true,
|
2021-01-04 00:17:22 +01:00
|
|
|
|
categorie_parade: 'sans-armes'
|
|
|
|
|
}
|
2023-10-23 23:40:03 +02:00
|
|
|
|
}
|
2021-06-28 16:08:45 +02:00
|
|
|
|
}
|
|
|
|
|
|
2023-10-23 23:40:03 +02:00
|
|
|
|
static mainsNues(actor) {
|
|
|
|
|
const mainsNues = RdDItemArme.corpsACorps(actor)
|
2022-06-12 08:17:59 +02:00
|
|
|
|
mainsNues.name = 'Mains nues'
|
2021-05-24 22:12:37 +02:00
|
|
|
|
return mainsNues;
|
2020-12-16 23:02:15 +01:00
|
|
|
|
}
|
2023-10-23 22:04:45 +02:00
|
|
|
|
|
2023-10-23 23:40:03 +02:00
|
|
|
|
static empoignade(actor) {
|
|
|
|
|
const empoignade = RdDItemArme.corpsACorps(actor)
|
2022-06-12 08:17:59 +02:00
|
|
|
|
empoignade.name = 'Empoignade'
|
|
|
|
|
empoignade.system.cac = 'empoignade'
|
|
|
|
|
empoignade.system.baseInit = 3
|
|
|
|
|
empoignade.system.mortalite = 'empoignade'
|
|
|
|
|
return empoignade
|
2021-06-28 16:08:45 +02:00
|
|
|
|
}
|
2021-03-18 23:55:26 +01:00
|
|
|
|
}
|