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": "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(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 ? 'armes-naturelles' : ''); } 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 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) { armeData = Misc.data(armeData); if (armeData && !armeData.data.cac) { 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 })); armes.push(RdDItemArme.empoignade({ niveau: corpsACorps.data.niveau, initiative: init })); } static corpsACorps(actorData) { const corpsACorps = { name: 'Corps à corps', data: { equipe: true, rapide: true, force: 0, dommages: 0, dommagesReels: 0, mortalite: 'non-mortel', competence: 'Corps à corps', categorie_parade: 'sans-armes' } }; mergeObject(corpsACorps.data, actorData ??{}, { overwrite: false }); return corpsACorps; } static mainsNues(actorData) { const mainsNues = RdDItemArme.corpsACorps(actorData); mainsNues.name = 'Mains nues'; mainsNues.data.cac = 'pugilat'; mainsNues.data.baseInit = 4; return mainsNues; } static empoignade(actorData) { const empoignade = RdDItemArme.corpsACorps(actorData); empoignade.name = 'Empoignade'; empoignade.data.cac = 'empoignade'; empoignade.data.baseInit = 3; empoignade.data.mortalite = 'empoignade'; return empoignade; } }