import { RdDItemCompetenceCreature } from "./item-competencecreature.js" import { RdDCombatManager } from "./rdd-combat.js"; const nomCategorieParade = { "sans-armes": "Sans arme / 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 == 'competencecreature' && item.data.iscombat) || item.type == 'arme'; } /* -------------------------------------------- */ static getArmeData(item) { switch (item ? item.data.type : '') { case 'arme': return item.data; case 'competencecreature': return RdDItemCompetenceCreature.toArme(item.data); } 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(arme) { if (arme.data.categorie_parade) { return arme.data.categorie_parade; } // pour compatibilité avec des personnages existants if (arme.type == 'competencecreature' || arme.data.categorie == 'creature') { return arme.data.categorie_parade || (arme.data.isparade ? 'sans-armes' : ''); } if (!arme.type.match(/arme|competencecreature/)) { return ''; } if (arme.data.competence == undefined) { return 'competencecreature'; } let compname = arme.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 (arme.name.toLowerCase().match(/(gnome)/)) return 'epees-courtes'; if (arme.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 signi$cative 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(arme, aUneMain) { if (arme) { arme.data.unemain = arme.data.unemain || !arme.data.deuxmains; const uneOuDeuxMains = arme.data.unemain && arme.data.deuxmains; const containsSlash = !Number.isInteger(arme.data.dommages) && arme.data.dommages.includes("/"); if (containsSlash) { // Sanity check arme = duplicate(arme); const tableauDegats = arme.data.dommages.split("/"); if (aUneMain) arme.data.dommagesReels = Number(tableauDegats[0]); else // 2 mains arme.data.dommagesReels = Number(tableauDegats[1]); } else { arme.data.dommagesReels = Number(arme.data.dommages); } if (uneOuDeuxMains != 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 arme; } static isArmeUtilisable(item) { return item.type == 'arme' && item.data.equipe && (item.data.resistance > 0 || item.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 })); } static mainsNues(actorData = {}) { const mainsNues = { name: 'Mains nues', data: { equipe: true, rapide: true, force: 0, dommages: 0, dommagesReels: 0, mortalite: 'non-mortel', competence: 'Corps à corps', categorie_parade: 'sans-armes' } }; if (actorData) { mergeObject(mainsNues.data, actorData, { overwrite: false }); } return mainsNues } }