Macros pour le corps à corps

Cas particulier car 3 utilisations possibles, et pas d'armes
This commit is contained in:
Vincent Vandemeulebrouck 2023-10-23 23:40:03 +02:00
parent b74fc27079
commit 0ed90f6177
9 changed files with 92 additions and 47 deletions

View File

@ -81,9 +81,12 @@ export class RdDActorSheet extends RdDBaseActorSheet {
}); });
// toujours avoir une liste d'armes (pour mettre esquive et corps à corps) // toujours avoir une liste d'armes (pour mettre esquive et corps à corps)
formData.combat = duplicate(formData.armes ?? []); const actor = this.actor;
formData.combat = duplicate(formData.armes);
RdDItemArme.computeNiveauArmes(formData.combat, formData.competences); RdDItemArme.computeNiveauArmes(formData.combat, formData.competences);
RdDItemArme.ajoutCorpsACorps(formData.combat, formData.competences, formData.system.carac); formData.combat.push(RdDItemArme.mainsNues(actor));
formData.combat.push(RdDItemArme.empoignade(actor));
formData.esquives = this.actor.getCompetences("Esquive"); formData.esquives = this.actor.getCompetences("Esquive");
formData.combat = RdDCombatManager.listActionsArmes(formData.combat, formData.competences, formData.system.carac); formData.combat = RdDCombatManager.listActionsArmes(formData.combat, formData.competences, formData.system.carac);
formData.empoignades = this.actor.getEmpoignades(); formData.empoignades = this.actor.getEmpoignades();

View File

@ -241,6 +241,12 @@ export class RdDActor extends RdDBaseActor {
getCompetences(name) { getCompetences(name) {
return RdDItemCompetence.findCompetences(this.items, name) return RdDItemCompetence.findCompetences(this.items, name)
} }
getCompetenceCorpsACorps(options = {}) {
return this.getCompetence("Corps à corps", options)
}
getCompetencesEsquive() {
return this.getCompetences("esquive")
}
/* -------------------------------------------- */ /* -------------------------------------------- */
getTache(id) { getTache(id) {
return this.findItemLike(id, 'tache'); return this.findItemLike(id, 'tache');
@ -3084,7 +3090,7 @@ export class RdDActor extends RdDBaseActor {
switch (competenceName) { switch (competenceName) {
case 'competence': return arme.system.competence; case 'competence': return arme.system.competence;
case 'unemain': return RdDItemArme.competence1Mains(arme); case 'unemain': return RdDItemArme.competence1Mains(arme);
case 'deuxmains': return RdDItemArme.competence2Mains(arme); case 'deuxmains': return RdDItemArme.competence2Mains(arme);
case 'tir': return arme.system.tir; case 'tir': return arme.system.tir;
case 'lancer': return arme.system.lancer; case 'lancer': return arme.system.lancer;
} }

View File

@ -169,19 +169,21 @@ export class RdDItemArme extends Item {
return arme.type == 'arme' && arme.system.equipe && (arme.system.resistance > 0 || arme.system.portee_courte > 0); return arme.type == 'arme' && arme.system.equipe && (arme.system.resistance > 0 || arme.system.portee_courte > 0);
} }
static ajoutCorpsACorps(armes, competences, carac) { static ajoutCorpsACorps(armes, actor) {
let corpsACorps = competences.find(it => it.name == 'Corps à corps') ?? { system: { niveau: -6 } }; armes.push(RdDItemArme.mainsNues(actor));
let init = RdDCombatManager.calculInitiative(corpsACorps.system.niveau, carac['melee'].value); armes.push(RdDItemArme.empoignade(actor));
armes.push(RdDItemArme.mainsNues({ niveau: corpsACorps.system.niveau, initiative: init }));
armes.push(RdDItemArme.empoignade({ niveau: corpsACorps.system.niveau, initiative: init }));
} }
static corpsACorps(mainsNuesActor) { static corpsACorps(actor) {
const corpsACorps = { let competence = actor?.getCompetenceCorpsACorps() ?? { system: { niveau: -6 } };
let melee = actor? actor.system.carac['melee'].value : 0
return {
_id: competence?.id,
name: 'Corps à corps', name: 'Corps à corps',
type: TYPES.arme, type: TYPES.arme,
img: 'systems/foundryvtt-reve-de-dragon/icons/competence_corps_a_corps.webp', img: 'systems/foundryvtt-reve-de-dragon/icons/competence_corps_a_corps.webp',
system: { system: {
initiative: RdDCombatManager.calculInitiative(competence.system.niveau, melee),
equipe: true, equipe: true,
rapide: true, rapide: true,
force: 0, force: 0,
@ -192,21 +194,19 @@ export class RdDItemArme extends Item {
deuxmains: true, deuxmains: true,
categorie_parade: 'sans-armes' categorie_parade: 'sans-armes'
} }
}; }
mergeObject(corpsACorps.system, mainsNuesActor ?? {}, { overwrite: false });
return corpsACorps;
} }
static mainsNues(mainsNuesActor) { static mainsNues(actor) {
const mainsNues = RdDItemArme.corpsACorps(mainsNuesActor) const mainsNues = RdDItemArme.corpsACorps(actor)
mainsNues.name = 'Mains nues' mainsNues.name = 'Mains nues'
mainsNues.system.cac = 'pugilat' mainsNues.system.cac = 'pugilat'
mainsNues.system.baseInit = 4 mainsNues.system.baseInit = 4
return mainsNues; return mainsNues;
} }
static empoignade(mainsNuesActor) { static empoignade(actor) {
const empoignade = RdDItemArme.corpsACorps(mainsNuesActor) const empoignade = RdDItemArme.corpsACorps(actor)
empoignade.name = 'Empoignade' empoignade.name = 'Empoignade'
empoignade.system.cac = 'empoignade' empoignade.system.cac = 'empoignade'
empoignade.system.baseInit = 3 empoignade.system.baseInit = 3

View File

@ -79,10 +79,9 @@ export class RdDItemCompetence extends Item {
/* -------------------------------------------- */ /* -------------------------------------------- */
static isCompetenceArme(competence) { static isCompetenceArme(competence) {
if (competence.isCompetence()) { if (competence.isCompetence() && !competence.isCorpsACorps() && !competence.isEsquive()) {
switch (competence.system.categorie) { switch (competence.system.categorie) {
case 'melee': case 'melee':
return !Grammar.toLowerCaseNoAccent(competence.name).includes('esquive');
case 'tir': case 'tir':
case 'lancer': case 'lancer':
return true; return true;
@ -93,10 +92,10 @@ export class RdDItemCompetence extends Item {
/* -------------------------------------------- */ /* -------------------------------------------- */
static isArmeUneMain(competence) { static isArmeUneMain(competence) {
return RdDItemCompetence.isCompetenceArme(competence) && competence.name.toLowerCase().includes("1 main"); return competence.isCompetenceArme() && competence.name.toLowerCase().includes("1 main");
} }
static isArme2Main(competence) { static isArme2Main(competence) {
return RdDItemCompetence.isCompetenceArme(competence) && competence.name.toLowerCase().includes("2 main"); return competence.isCompetenceArme() && competence.name.toLowerCase().includes("2 main");
} }
static isThanatos(competence) { static isThanatos(competence) {

View File

@ -113,7 +113,7 @@ export class RdDItemSheet extends ItemSheet {
formData.competences = competences; formData.competences = competences;
} }
if (this.item.type == 'arme') { if (this.item.type == 'arme') {
formData.competences = competences.filter(it => RdDItemCompetence.isCompetenceArme(it)) formData.competences = competences.filter(it => it.isCompetenceArme())
} }
if (['sort', 'sortreserve'].includes(this.item.type)) { if (['sort', 'sortreserve'].includes(this.item.type)) {
formData.competences = competences.filter(it => RdDItemCompetence.isDraconic(it)); formData.competences = competences.filter(it => RdDItemCompetence.isDraconic(it));

View File

@ -220,6 +220,32 @@ export class RdDItem extends Item {
isService() { return this.type == TYPES.service; } isService() { return this.type == TYPES.service; }
isCompetence() { return typesObjetsCompetence.includes(this.type) } isCompetence() { return typesObjetsCompetence.includes(this.type) }
isEsquive() {
return (this.isCompetence()
&& this.system.categorie == 'melee'
&& Grammar.includesLowerCaseNoAccent(this.name, 'Esquive'));
}
isCorpsACorps() {
return (this.isCompetence()
&& this.system.categorie == 'melee'
&& Grammar.includesLowerCaseNoAccent(this.name, 'Corps à Corps'));
}
isCompetenceArme() {
if (this.isCompetence()) {
switch (this.system.categorie) {
case 'melee':
return !this.isCorpsACorps() && !this.isEsquive()
case 'tir':
case 'lancer':
return true;
}
}
return false;
}
isCompetencePossession() { return TYPES.competencecreature == this.type && this.system.categorie == "possession" } isCompetencePossession() { return TYPES.competencecreature == this.type && this.system.categorie == "possession" }
isTemporel() { return typesObjetsTemporels.includes(this.type) } isTemporel() { return typesObjetsTemporels.includes(this.type) }
isOeuvre() { return typesObjetsOeuvres.includes(this.type) } isOeuvre() { return typesObjetsOeuvres.includes(this.type) }

View File

@ -75,7 +75,7 @@ export class RdDCombatManager extends Combat {
} }
} }
} }
/************************************************************************************/ /************************************************************************************/
async rollInitiative(ids, formula = undefined, messageOptions = {}) { async rollInitiative(ids, formula = undefined, messageOptions = {}) {
console.log(`${game.system.title} | Combat.rollInitiative()`, ids, formula, messageOptions); console.log(`${game.system.title} | Combat.rollInitiative()`, ids, formula, messageOptions);
@ -257,11 +257,10 @@ export class RdDCombatManager extends Combat {
actions = RdDCombatManager.listActionsCreature(actor.itemTypes['competencecreature']); actions = RdDCombatManager.listActionsCreature(actor.itemTypes['competencecreature']);
} else if (actor.isPersonnage()) { } else if (actor.isPersonnage()) {
// Recupération des items 'arme' // Recupération des items 'arme'
const armes = actor.itemTypes['arme'].filter(it => RdDItemArme.isArmeUtilisable(it))
.concat(RdDItemArme.empoignade())
.concat(RdDItemArme.mainsNues());
const competences = actor.itemTypes['competence']; const competences = actor.itemTypes['competence'];
const armes = actor.itemTypes['arme'].filter(it => RdDItemArme.isArmeUtilisable(it))
.concat(RdDItemArme.empoignade(actor))
.concat(RdDItemArme.mainsNues(actor));
actions = RdDCombatManager.listActionsArmes(armes, competences, actor.system.carac); actions = RdDCombatManager.listActionsArmes(armes, competences, actor.system.carac);
if (actor.system.attributs.hautrevant.value) { if (actor.system.attributs.hautrevant.value) {
@ -884,8 +883,8 @@ export class RdDCombat {
} }
// # utilisation esquive // # utilisation esquive
const corpsACorps = this.defender.getCompetence("Corps à corps", { onMessage: it => console.info(it, this.defender) }); const corpsACorps = this.defender.getCompetenceCorpsACorps({ onMessage: it => console.info(it, this.defender) });
const esquives = duplicate(this.defender.getCompetences("esquive", { onMessage: it => console.info(it, this.defender) })) const esquives = duplicate(this.defender.getCompetencesEsquive())
esquives.forEach(e => e.system.nbUsage = e?._id ? this.defender.getItemUse(e._id) : 0); esquives.forEach(e => e.system.nbUsage = e?._id ? this.defender.getItemUse(e._id) : 0);
const paramChatDefense = { const paramChatDefense = {

View File

@ -181,7 +181,7 @@ export class RdDEmpoignade {
let rollData = { let rollData = {
mode, empoignade, attacker, defender, mode, empoignade, attacker, defender,
isEmpoignade: true, isEmpoignade: true,
competence: attacker.getCompetence("Corps à corps"), competence: attacker.getCompetenceCorpsACorps(),
selectedCarac: attacker.system.carac.melee, selectedCarac: attacker.system.carac.melee,
malusTaille: RdDEmpoignade.getMalusTaille(empoignade, attacker, defender) malusTaille: RdDEmpoignade.getMalusTaille(empoignade, attacker, defender)
} }
@ -210,7 +210,7 @@ export class RdDEmpoignade {
mode: "immobilise", mode: "immobilise",
empoignade, attacker, defender, empoignade, attacker, defender,
isEmpoignade: true, isEmpoignade: true,
competence: attacker.getCompetence("Corps à corps") competence: attacker.getCompetenceCorpsACorps()
} }
const msg = await ChatMessage.create({ const msg = await ChatMessage.create({
whisper: ChatUtility.getWhisperRecipientsAndGMs(attacker.name), whisper: ChatUtility.getWhisperRecipientsAndGMs(attacker.name),

View File

@ -1,4 +1,4 @@
import { RdDItemCompetence } from "./item-competence.js"; import { RdDItemArme } from "./item-arme.js";
import { RdDItemCompetenceCreature } from "./item-competencecreature.js"; import { RdDItemCompetenceCreature } from "./item-competencecreature.js";
import { TYPES } from "./item.js"; import { TYPES } from "./item.js";
@ -6,9 +6,9 @@ export class RdDHotbar {
static async createItemMacro(item, slot, armeCompetence = undefined) { static async createItemMacro(item, slot, armeCompetence = undefined) {
const itemName = item.name; const itemName = item.name;
let macroName = itemName + RdDHotbar.$macroNameSuffix(armeCompetence);
let command = `game.system.rdd.RdDHotbar.rollMacro("${itemName}", "${item.type}", "${armeCompetence}");` let command = `game.system.rdd.RdDHotbar.rollMacro("${itemName}", "${item.type}", "${armeCompetence}");`
let macro = game.macros.contents.find(m => (m.name === itemName) && (m.command === command)); let macro = game.macros.contents.find(m => (m.name === itemName) && (m.command === command));
let macroName = itemName + RdDHotbar.$macroNameSuffix(armeCompetence);
if (!macro) { if (!macro) {
macro = await Macro.create({ macro = await Macro.create({
name: macroName, name: macroName,
@ -20,12 +20,15 @@ export class RdDHotbar {
await game.user.assignHotbarMacro(macro, slot); await game.user.assignHotbarMacro(macro, slot);
} }
static $macroNameSuffix(armeCompetence){ static $macroNameSuffix(armeCompetence) {
switch(armeCompetence) { switch (armeCompetence) {
case 'unemain': return ' (1 main)'; case 'unemain': return ' (1 main)';
case 'deuxmains': return ' (2 main)'; case 'deuxmains': return ' (2 main)';
case 'tir': return ' (tir)'; case 'tir': return ' (tir)';
case 'lancer': return ' (lancer)'; case 'lancer': return ' (lancer)';
case 'pugilat': return ' (pugilat)';
case 'empoignade': return ' (empoignade)';
} }
return '' return ''
} }
@ -37,21 +40,17 @@ export class RdDHotbar {
// Les armes peuvent avoir plusieurs usages // Les armes peuvent avoir plusieurs usages
if (item.system.competence != '') { if (item.system.competence != '') {
if (item.system.unemain) { if (item.system.unemain) {
await this.createItemMacro(item, slot, 'unemain') await this.createItemMacro(item, slot++, 'unemain')
slot++
} }
if (item.system.deuxmains) { if (item.system.deuxmains) {
await this.createItemMacro(item, slot, 'deuxmains') await this.createItemMacro(item, slot++, 'deuxmains')
slot++
} }
} }
if (item.system.lancer != '') { if (item.system.lancer != '') {
await this.createItemMacro(item, slot, 'lancer') await this.createItemMacro(item, slot++, 'lancer')
slot++
} }
if (item.system.tir != '') { if (item.system.tir != '') {
await this.createItemMacro(item, slot, 'lancer') await this.createItemMacro(item, slot++, 'lancer')
slot++
} }
} }
return return
@ -61,10 +60,15 @@ export class RdDHotbar {
return return
default: default:
case TYPES.competence: case TYPES.competence:
if (RdDItemCompetence.isCompetenceArme(item)) { await this.createItemMacro(item, slot++, 'competence')
ui.notifications.info(`La compétence de ${item.name} est une compétence d'arme, choisissez plutôt de créer la macro depuis l'onglet combat`); if (item.isCorpsACorps()) {
await this.createItemMacro(item, slot++, 'pugilat')
await this.createItemMacro(item, slot++, 'empoignade')
}
if (item.isCompetenceArme()) {
ui.notifications.info(`${item.name} est une compétence d'arme, la macro n'est pas liée à un arme.<br>
Créez la macro depuis l'arme ou l'onglet combat pour garder les automatisations de combat.`);
} }
await this.createItemMacro(item, slot, 'competence')
return return
} }
} }
@ -115,6 +119,14 @@ export class RdDHotbar {
case TYPES.arme: case TYPES.arme:
return actor.rollArme(item, categorieArme); return actor.rollArme(item, categorieArme);
case TYPES.competence: case TYPES.competence:
if (item.isCorpsACorps()) {
switch (categorieArme) {
case 'pugilat':
return actor.rollArme(RdDItemArme.mainsNues(actor), 'competence');
case 'empoignade':
return actor.rollArme(RdDItemArme.empoignade(actor), 'competence');
}
}
return actor.rollCompetence(item); return actor.rollCompetence(item);
case TYPES.competencecreature: case TYPES.competencecreature:
return item.system.iscombat && !item.system.isparade return item.system.iscombat && !item.system.isparade