Vincent Vandemeulebrouck
37c2b6432d
Les créatures peuvent avoir des compétences d'armes (lancer, mêlée, tir, armes naturelles), de parade, de possession, et générales. Les initiatives sont cohérentes. Les possessions sont en phase 10 d'initiative.
208 lines
7.3 KiB
JavaScript
208 lines
7.3 KiB
JavaScript
import { RdDItemCompetenceCreature } from "./item-competencecreature.js"
|
||
import { 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 RdDItemCompetenceCreature.getCategorieAttaque(item) || item.type == 'arme';
|
||
}
|
||
|
||
/* -------------------------------------------- */
|
||
static getArme(arme) {
|
||
switch (arme ? arme.type : '') {
|
||
case 'arme': return arme;
|
||
case 'competencecreature':
|
||
return RdDItemCompetenceCreature.armeCreature(arme);
|
||
}
|
||
return RdDItemArme.mainsNues();
|
||
}
|
||
|
||
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 == '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 '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 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 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 armeUneOuDeuxMains(armeData, aUneMain) {
|
||
if (armeData && !armeData.system.cac) {
|
||
armeData.system.unemain = armeData.system.unemain || !armeData.system.deuxmains;
|
||
const uneOuDeuxMains = armeData.system.unemain && armeData.system.deuxmains;
|
||
const containsSlash = !Number.isInteger(armeData.system.dommages) && armeData.system.dommages.includes("/");
|
||
if (containsSlash) { // Sanity check
|
||
armeData = duplicate(armeData);
|
||
|
||
const tableauDegats = armeData.system.dommages.split("/");
|
||
if (aUneMain)
|
||
armeData.system.dommagesReels = Number(tableauDegats[0]);
|
||
else // 2 mains
|
||
armeData.system.dommagesReels = Number(tableauDegats[1]);
|
||
}
|
||
else {
|
||
armeData.system.dommagesReels = Number(armeData.system.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(arme) {
|
||
return arme.type == 'arme' && arme.system.equipe && (arme.system.resistance > 0 || arme.system.portee_courte > 0);
|
||
}
|
||
|
||
static ajoutCorpsACorps(armes, competences, carac) {
|
||
let corpsACorps = competences.find(it => it.name == 'Corps à corps') ?? { system: { niveau: -6 } };
|
||
let init = RdDCombatManager.calculInitiative(corpsACorps.system.niveau, carac['melee'].value);
|
||
armes.push(RdDItemArme.mainsNues({ niveau: corpsACorps.system.niveau, initiative: init }));
|
||
armes.push(RdDItemArme.empoignade({ niveau: corpsACorps.system.niveau, initiative: init }));
|
||
}
|
||
|
||
static corpsACorps(mainsNuesActor) {
|
||
const corpsACorps = {
|
||
name: 'Corps à corps',
|
||
img: 'systems/foundryvtt-reve-de-dragon/icons/competence_corps_a_corps.webp',
|
||
system: {
|
||
equipe: true,
|
||
rapide: true,
|
||
force: 0,
|
||
dommages: "0",
|
||
dommagesReels: 0,
|
||
mortalite: 'non-mortel',
|
||
competence: 'Corps à corps',
|
||
categorie_parade: 'sans-armes'
|
||
}
|
||
};
|
||
mergeObject(corpsACorps.system, mainsNuesActor ?? {}, { overwrite: false });
|
||
return corpsACorps;
|
||
}
|
||
|
||
static mainsNues(mainsNuesActor) {
|
||
const mainsNues = RdDItemArme.corpsACorps(mainsNuesActor)
|
||
mainsNues.name = 'Mains nues'
|
||
mainsNues.system.cac = 'pugilat'
|
||
mainsNues.system.baseInit = 4
|
||
return mainsNues;
|
||
}
|
||
|
||
static empoignade(mainsNuesActor) {
|
||
const empoignade = RdDItemArme.corpsACorps(mainsNuesActor)
|
||
empoignade.name = 'Empoignade'
|
||
empoignade.system.cac = 'empoignade'
|
||
empoignade.system.baseInit = 3
|
||
empoignade.system.mortalite = 'empoignade'
|
||
return empoignade
|
||
}
|
||
}
|