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, competenceName) { switch (arme.type) { case ITEM_TYPES.competencecreature: return arme.name case ITEM_TYPES.arme: switch (competenceName) { 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 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 = foundry.utils.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 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 } }