Préparation roll-dialog attaques

Les attaques ne sont plus des armes modifiées
This commit is contained in:
2025-09-18 01:56:42 +02:00
parent 74c1f33427
commit 652c435833
17 changed files with 239 additions and 201 deletions

View File

@@ -33,7 +33,7 @@ export class RdDActorSheet extends RdDBaseActorSangSheet {
width: 550, width: 550,
showCompNiveauBase: false, showCompNiveauBase: false,
vueArchetype: false, vueArchetype: false,
}, { inplace: false }); }, { inplace: false })
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
@@ -77,14 +77,10 @@ export class RdDActorSheet extends RdDBaseActorSangSheet {
}); });
// toujours avoir une liste d'armes (pour mettre esquive et corps à corps) // toujours avoir une liste d'armes (pour mettre esquive et corps à corps)
const actor = this.actor; const actor = this.actor
formData.combat = foundry.utils.duplicate(formData.armes);
RdDItemArme.computeNiveauArmes(formData.combat, formData.competences);
formData.combat.push(RdDItemArme.corpsACorps(actor));
formData.combat.push(RdDItemArme.empoignade(actor));
formData.esquives = this.actor.getCompetencesEsquive() formData.esquives = this.actor.getCompetencesEsquive()
formData.combat = RdDCombatManager.listActionsArmes(formData.combat, formData.competences, formData.system.carac); formData.combat = actor.listActionsAttaque()
formData.empoignades = this.actor.getEmpoignades(); formData.empoignades = this.actor.getEmpoignades();
this.armesList = formData.combat; this.armesList = formData.combat;
@@ -216,13 +212,17 @@ export class RdDActorSheet extends RdDBaseActorSangSheet {
this.html.find('.roll-reve-actuel').click(async event => await this.actor.rollCarac('reve-actuel', { resistance: true })) this.html.find('.roll-reve-actuel').click(async event => await this.actor.rollCarac('reve-actuel', { resistance: true }))
this.html.find('.action-empoignade').click(async event => await RdDEmpoignade.onAttaqueEmpoignadeFromItem(RdDSheetUtility.getItem(event, this.actor))) this.html.find('.action-empoignade').click(async event => await RdDEmpoignade.onAttaqueEmpoignadeFromItem(RdDSheetUtility.getItem(event, this.actor)))
this.html.find('.roll-arme').click(async event => await this.actor.rollArme(foundry.utils.duplicate(this._getEventArmeCombat(event)), 'competence')) this.html.find('.roll-arme').click(async event => {
const action = this._getActionCombat(event);
await this.actor.rollArme(action.arme, action.main)
})
// Initiative pour l'arme // Initiative pour l'arme
this.html.find('.roll-init-arme').click(async event => { this.html.find('.roll-init-arme').click(async event => {
let combatant = game.combat.combatants.find(c => c.actor.id == this.actor.id) let combatant = game.combat.combatants.find(c => c.actor.id == this.actor.id)
if (combatant) { if (combatant) {
RdDCombatManager.rollInitiativeAction(combatant._id, this._getEventArmeCombat(event)); RdDCombatManager.rollInitiativeAction(combatant._id, this._getActionCombat(event));
} else { } else {
ui.notifications.info("Impossible de lancer l'initiative sans être dans un combat."); ui.notifications.info("Impossible de lancer l'initiative sans être dans un combat.");
} }
@@ -236,11 +236,11 @@ export class RdDActorSheet extends RdDBaseActorSangSheet {
this.html.find('.carac-xp-augmenter').click(async event => await this.actor.updateCaracXPAuto(event.currentTarget.name.replace("augmenter.", ""))) this.html.find('.carac-xp-augmenter').click(async event => await this.actor.updateCaracXPAuto(event.currentTarget.name.replace("augmenter.", "")))
this.html.find('.competence-xp-augmenter').click(async event => await this.actor.updateCompetenceXPAuto(RdDSheetUtility.getItemId(event))) this.html.find('.competence-xp-augmenter').click(async event => await this.actor.updateCompetenceXPAuto(RdDSheetUtility.getItemId(event)))
this.html.find('.competence-stress-augmenter').click(async event =>{ this.html.find('.competence-stress-augmenter').click(async event => {
await this.actor.updateCompetenceStress(RdDSheetUtility.getItemId(event)) await this.actor.updateCompetenceStress(RdDSheetUtility.getItemId(event))
this.render(true) this.render(true)
} }
) )
if (this.options.vueDetaillee) { if (this.options.vueDetaillee) {
// On carac change // On carac change
@@ -346,13 +346,17 @@ export class RdDActorSheet extends RdDBaseActorSangSheet {
await this.actor.createItem('tache', 'Nouvelle tache'); await this.actor.createItem('tache', 'Nouvelle tache');
} }
_getEventArmeCombat(event) { _getActionCombat(event) {
const li = this.html.find(event.currentTarget)?.parents(".item"); const li = this.html.find(event.currentTarget)?.parents(".item");
let armeName = li.data("arme-name"); let armeName = li.data("arme-name");
let compName = li.data('competence-name'); let compName = li.data('competence-name');
const arme = this.armesList.find(a => a.name == armeName && a.system.competence == compName); const arme = this.armesList.find(a => a.arme.name == armeName && a.comp.name == compName);
if (!arme) { if (!arme) {
return { name: armeName, system: { competence: compName } }; return {
name: armeName,
arme: { name: armeName },
comp: { name: compName }
}
} }
return arme; return arme;
} }

View File

@@ -45,6 +45,7 @@ import { DialogSelect } from "./dialog-select.js";
import { PAS_DE_DRACONIC, POSSESSION_SANS_DRACONIC } from "./item/base-items.js"; import { PAS_DE_DRACONIC, POSSESSION_SANS_DRACONIC } from "./item/base-items.js";
import { RdDRollResult } from "./rdd-roll-result.js"; import { RdDRollResult } from "./rdd-roll-result.js";
import { RdDInitiative } from "./initiative.mjs";
export const MAINS_DIRECTRICES = ['Droitier', 'Gaucher', 'Ambidextre'] export const MAINS_DIRECTRICES = ['Droitier', 'Gaucher', 'Ambidextre']
@@ -131,19 +132,13 @@ export class RdDActor extends RdDBaseActorSang {
.reduce(Misc.sum(), 0); .reduce(Misc.sum(), 0);
} }
listActionsCombat() { listActions({ isAttaque = false, isEquipe = false }) {
// Recupération des armes // Recupération des armes
const actions = RdDCombatManager.listActionsArmes( const actions = this.listActionsAttaque()
this.itemTypes[ITEM_TYPES.arme] .filter(it => !isEquipe || it.arme.system.equipe)
.filter(it => RdDItemArme.isAttaque(it))
.concat(RdDItemArme.corpsACorps(this))
.concat(RdDItemArme.empoignade(this))
,
this.itemTypes[ITEM_TYPES.competence],
this.system.carac)
if (this.system.attributs.hautrevant.value) { if (!isAttaque && this.system.attributs.hautrevant.value) {
actions.push({ name: "Draconic", action: 'haut-reve', system: { initOnly: true, competence: "Draconic" } }); actions.push({ name: "Draconic", action: 'haut-reve', initOnly: true })
} }
return actions return actions
} }
@@ -168,6 +163,86 @@ export class RdDActor extends RdDBaseActorSang {
.find(it => true) .find(it => true)
} }
/* -------------------------------------------- */
/** Retourne une liste triée d'actions d'armes avec le split arme1 main / arme 2 main / lancer */
listActionsAttaque() {
let actions = [
this.$prepareAttaqueArme(RdDItemArme.empoignade(this)),
this.$prepareAttaqueArme(RdDItemArme.corpsACorps(this)),
]
const armes = this.itemTypes[ITEM_TYPES.arme]
.filter(it => RdDItemArme.isAttaque(it))
.sort(Misc.ascending(it => it.name));
for (const arme of armes) {
if (arme.system.unemain && arme.system.competence) {
actions.push(this.$prepareAttaqueArme(arme, '(1 main)'))
}
if (arme.system.deuxmains && arme.system.competence) {
actions.push(this.$prepareAttaqueArme(arme, '(2 mains)'))
}
if (arme.system.lancer) {
actions.push(this.$prepareAttaqueArme(arme, '(lancer)'))
}
if (arme.system.tir) {
actions.push(this.$prepareAttaqueArme(arme, '(tir)'))
}
}
return actions;
}
/* -------------------------------------------- */
$prepareAttaqueArme(arme, main) {
const comp = this.getCompetence(RdDActor.$getCompetenceAction(arme, main))
const caracCode = RdDActor.$getCaracAction(comp, main)
const caracValue = this.system.carac[caracCode].value
const dommages = arme.system.dommages.toString()
// TODO: déplacer sur RdDItemArme
if (arme.system.unemain && arme.system.deuxmains && !dommages.includes("/")) {
ui.notifications.info(`Les dommages de l'arme à 1/2 mains ${arme.name} ne sont pas corrects (ie sous la forme X/Y)`)
}
const tableauDommages = dommages.includes("/") ? dommages.split("/") : [dommages, dommages]
const dmg = main == '(2 mains)' ? tableauDommages[1] : tableauDommages[0]
const niveau = comp?.system.niveau ?? (['(lancer)', '(tir)'].includes(main) ? -8 : -6)
const ajustement = (arme.parent?.getEtatGeneral() ?? 0) + (arme.system.magique) ? arme.system.ecaille_efficacite : 0
return {
name: arme.name + (main ? ' ' + main : ''),
action: 'attaque',
initOnly: false,
arme: arme,
comp: comp,
main: main,
carac: { key: caracCode, value: caracValue },
equipe: arme.system.equipe,
dmg: dmg,
initiative: RdDInitiative.calculInitiative(niveau, caracValue, ajustement)
}
}
static $getCaracAction(comp, main) {
if (comp?.system.defaut_carac) {
return comp.system.defaut_carac
}
switch (main) {
case '(lancer)': return 'lancer'
case '(tir)': return 'tir'
default: return 'melee'
}
}
static $getCompetenceAction(arme, main) {
switch (main) {
case '(1 main)': return arme.competence1Mains()
case '(2 mains)': return arme.competence2Mains()
case '(lancer)': return arme.system.lancer
case '(tir)': return arme.system.tir
default: return arme.system.competence
}
}
/* -------------------------------------------- */ /* -------------------------------------------- */
async $perteReveEnchantementsChateauDormants() { async $perteReveEnchantementsChateauDormants() {
const toUpdate = this.items.filter(it => [ITEM_TYPES.potion, ITEM_TYPES.gemme].includes(it.type)) const toUpdate = this.items.filter(it => [ITEM_TYPES.potion, ITEM_TYPES.gemme].includes(it.type))

View File

@@ -80,6 +80,7 @@ export class RdDBaseActorReve extends RdDBaseActor {
getBonusDegat() { return RdDCarac.getCaracDerivee(this.getEncombrementMax()).plusdom } getBonusDegat() { return RdDCarac.getCaracDerivee(this.getEncombrementMax()).plusdom }
getMoralTotal() { return 0 } getMoralTotal() { return 0 }
listeAmoureux() {return []}
getProtectionNaturelle() { return Number(this.system.attributs?.protection?.value ?? 0) } getProtectionNaturelle() { return Number(this.system.attributs?.protection?.value ?? 0) }
getSConst() { return 0 } getSConst() { return 0 }
@@ -109,10 +110,11 @@ export class RdDBaseActorReve extends RdDBaseActor {
} }
return this.system.carac[competence.system.defaut_carac].value; return this.system.carac[competence.system.defaut_carac].value;
} }
listActionsCombat() {
listActions({ isAttaque = false, isEquipe = false }) {
return this.itemTypes[ITEM_TYPES.competencecreature] return this.itemTypes[ITEM_TYPES.competencecreature]
.filter(it => RdDItemCompetenceCreature.isAttaque(it)) .filter(it => RdDItemCompetenceCreature.isAttaque(it))
.map(it => RdDItemCompetenceCreature.armeCreature(it)) .map(it => RdDItemCompetenceCreature.attaqueCreature(it))
.filter(it => it != undefined); .filter(it => it != undefined);
} }
@@ -165,7 +167,9 @@ export class RdDBaseActorReve extends RdDBaseActor {
if (idOrName instanceof Item) { if (idOrName instanceof Item) {
return idOrName.isCompetence() ? idOrName : undefined return idOrName.isCompetence() ? idOrName : undefined
} }
return RdDItemCompetence.findCompetence(this.items, idOrName, options) return RdDItemCompetence.findCompetence(
this.items.filter(it => [ITEM_TYPES.competence, ITEM_TYPES.competencecreature].includes(it.type)),
idOrName, options)
} }
getCompetences(name, options = { onMessage: message => { } }) { getCompetences(name, options = { onMessage: message => { } }) {
@@ -434,9 +438,9 @@ export class RdDBaseActorReve extends RdDBaseActor {
* @param {*} categorieArme catégorie d'attaque à utiliser: competence (== melee), lancer, tir; naturelle, possession * @param {*} categorieArme catégorie d'attaque à utiliser: competence (== melee), lancer, tir; naturelle, possession
* @returns * @returns
*/ */
rollArme(arme, categorieArme, token) { rollArme(arme, categorieArme = 'competence', token = undefined) {
token = token ?? RdDUtility.getSelectedToken(this) token = token ?? RdDUtility.getSelectedToken(this)
const compToUse = this.$getCompetenceArme(arme, categorieArme) const compToUse = RdDItemArme.getCompetenceArme(arme, categorieArme)
if (!RdDItemArme.isUtilisable(arme)) { if (!RdDItemArme.isUtilisable(arme)) {
ui.notifications.warn(`Arme inutilisable: ${arme.name} a une résistance de 0 ou moins`) ui.notifications.warn(`Arme inutilisable: ${arme.name} a une résistance de 0 ou moins`)
return return
@@ -470,10 +474,6 @@ export class RdDBaseActorReve extends RdDBaseActor {
}) })
} }
$getCompetenceArme(arme, competenceName) {
return RdDItemArme.getCompetenceArme(arme, competenceName)
}
verifierForceMin(item) { } verifierForceMin(item) { }
/* -------------------------------------------- */ /* -------------------------------------------- */

View File

@@ -755,18 +755,21 @@ export class RdDBaseActor extends Actor {
isActorCombat() { return false } isActorCombat() { return false }
getCaracInit(competence) { return 0 } getCaracInit(competence) { return 0 }
listActionsCombat() { return [] } listAttaques() {
return this.listActions({ isAttaque: true, isEquipe:false })
}
listActions({ isAttaque = false, isEquipe=false }) { return [] }
listActionsPossessions() { listActionsPossessions() {
return this.itemTypes[ITEM_TYPES.possession] return this.itemTypes[ITEM_TYPES.possession]
.map(p => { .map(p => {
return { return {
name: p.name, name: p.name,
action: 'possession', action: 'possession',
system: { possessionid: p.system.possessionid,
competence: p.name,
possessionid: p.system.possessionid,
}
} }
}) })
} }
} }

View File

@@ -9,6 +9,7 @@ export class RdDActorExportSheet extends RdDActorSheet {
static init() { static init() {
foundry.applications.handlebars.loadTemplates([ foundry.applications.handlebars.loadTemplates([
"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/arme.hbs", "systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/arme.hbs",
"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/arme-titre.hbs",
"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/blessure.hbs", "systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/blessure.hbs",
"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/blessures.hbs", "systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/blessures.hbs",
"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/carac.hbs", "systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/carac.hbs",
@@ -41,6 +42,7 @@ export class RdDActorExportSheet extends RdDActorSheet {
const formData = await super.getData() const formData = await super.getData()
// Add any structured, precomputed list of data // Add any structured, precomputed list of data
formData.context = Mapping.prepareContext(this.actor) formData.context = Mapping.prepareContext(this.actor)
formData.attaques = this.actor.listActionsAttaque()
formData.export = this.getMappingValues(formData.context, this.actor) formData.export = this.getMappingValues(formData.context, this.actor)
formData.competences = this.getCompetences(CATEGORIES_COMPETENCES) formData.competences = this.getCompetences(CATEGORIES_COMPETENCES)
formData.draconic = this.getCompetences(CATEGORIES_DRACONIC) formData.draconic = this.getCompetences(CATEGORIES_DRACONIC)

View File

@@ -144,7 +144,7 @@ export class Mapping {
armes.push(RdDItemArme.corpsACorps(actor)); armes.push(RdDItemArme.corpsACorps(actor));
armes.push(RdDItemArme.empoignade(actor)); armes.push(RdDItemArme.empoignade(actor));
return armes.map(arme => [ return armes.map(arme => [
arme.system.unemain ? Mapping.prepareArme(actor, arme, 'unemain') : undefined, arme.system.unemain ? Mapping.prepareArme(actor, arme, '(1 main)') : undefined,
arme.system.deuxmains ? Mapping.prepareArme(actor, arme, 'deuxmains') : undefined, arme.system.deuxmains ? Mapping.prepareArme(actor, arme, 'deuxmains') : undefined,
!(arme.system.unemain || arme.system.deuxmains) ? Mapping.prepareArme(actor, arme, 'competence') : undefined, !(arme.system.unemain || arme.system.deuxmains) ? Mapping.prepareArme(actor, arme, 'competence') : undefined,
arme.system.lancer != "" ? Mapping.prepareArme(actor, arme, 'lancer') : undefined, arme.system.lancer != "" ? Mapping.prepareArme(actor, arme, 'lancer') : undefined,

View File

@@ -2,6 +2,7 @@
import { ITEM_TYPES } from "./constants.js"; import { ITEM_TYPES } from "./constants.js";
import { Grammar } from "./grammar.js"; import { Grammar } from "./grammar.js";
import { RdDInitiative } from "./initiative.mjs"; import { RdDInitiative } from "./initiative.mjs";
import { RdDItem } from "./item.js";
export const CATEGORIES_COMPETENCES_CREATURES = { export const CATEGORIES_COMPETENCES_CREATURES = {
"generale": { base: 0, label: "Générale" }, "generale": { base: 0, label: "Générale" },
@@ -49,6 +50,41 @@ export class RdDItemCompetenceCreature extends Item {
} }
return undefined; return undefined;
} }
static attaqueCreature(comp) {
const categorieAttaque = RdDItemCompetenceCreature.getCategorieAttaque(comp)
if (categorieAttaque != undefined) {
const initative = RdDInitiative.calculInitiative(comp.system.niveau, comp.system.carac_value);
return {
name: comp.name,
action: comp.isCompetencePossession() ? 'possession' : 'attaque',
initOnly: false,
arme: new RdDItem({
name: comp.name,
type: ITEM_TYPES.arme,
img: comp.img,
system: {
competence: comp.name,
cac: categorieAttaque == "naturelle" ? "naturelle" : "",
niveau: comp.system.niveau,
initiative: initative,
equipe: true,
resistance: 100,
dommagesReels: comp.system.dommages,
penetration: 0,
force: 0,
rapide: true,
}
}),
comp: comp,
// main: '',
carac: { key: comp.name, value: comp.system.carac_value },
equipe: true,
dmg: comp.system.dommages,
initiative: initative
}
}
return undefined;
}
/* -------------------------------------------- */ /* -------------------------------------------- */
static isAttaque(item) { static isAttaque(item) {

View File

@@ -30,20 +30,8 @@ export class RdDItemArme extends RdDItem {
//return "systems/foundryvtt-reve-de-dragon/icons/armes_armure/epee_sord.webp"; //return "systems/foundryvtt-reve-de-dragon/icons/armes_armure/epee_sord.webp";
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
static isArme(item) {
return item.type == ITEM_TYPES.arme || RdDItemCompetenceCreature.getCategorieAttaque(item);
}
static getArme(arme) { static getArme(arme) {
switch (arme ? arme.type : '') { switch (arme ? arme.type : '') {
case ITEM_TYPES.arme: return arme; case ITEM_TYPES.arme: return arme;
@@ -60,10 +48,10 @@ export class RdDItemArme extends RdDItem {
case ITEM_TYPES.arme: case ITEM_TYPES.arme:
switch (maniement) { switch (maniement) {
case 'competence': return arme.system.competence; case 'competence': return arme.system.competence;
case 'unemain': return RdDItemArme.competence1Mains(arme); case '(1 main)': return arme.competence1Mains()
case 'deuxmains': return RdDItemArme.competence2Mains(arme); case '(2 mains)': return arme.competence2Mains()
case 'tir': return arme.system.tir; case '(tir)': case 'tir': return arme.system.tir
case 'lancer': return arme.system.lancer; case '(lancer)': case 'lancer': return arme.system.lancer;
} }
} }
return undefined return undefined
@@ -204,7 +192,7 @@ export class RdDItemArme extends RdDItem {
return Number(arme.system.dommages) return Number(arme.system.dommages)
} }
const tableauDegats = arme.system.dommages.split("/"); const tableauDegats = arme.system.dommages.split("/");
return Number(tableauDegats[maniement == 'unemain' ? 0 : 1]) return Number(tableauDegats[maniement == '(1 main)' ? 0 : 1])
} }
return Number(arme.system.dommages); return Number(arme.system.dommages);
} }
@@ -213,17 +201,17 @@ export class RdDItemArme extends RdDItem {
static armeUneOuDeuxMains(arme, aUneMain) { static armeUneOuDeuxMains(arme, aUneMain) {
if (arme && !arme.system.cac) { if (arme && !arme.system.cac) {
arme = foundry.utils.duplicate(arme); arme = foundry.utils.duplicate(arme);
arme.system.dommagesReels = RdDItemArme.dommagesReels(arme, aUneMain ? 'unemain' : 'deuxmains') arme.system.dommagesReels = RdDItemArme.dommagesReels(arme, aUneMain ? '(1 main)' : '(2 mains)')
} }
return arme; return arme;
} }
static competence1Mains(arme) { competence1Mains() {
return arme.system.competence.replace(" 2 mains", " 1 main"); return this.system.competence.replace(" 2 mains", " 1 main");
} }
static competence2Mains(arme) { competence2Mains() {
return arme.system.competence.replace(" 1 main", " 2 mains"); return this.system.competence.replace(" 1 main", " 2 mains");
} }
static isUtilisable(arme) { static isUtilisable(arme) {
@@ -236,10 +224,8 @@ export class RdDItemArme extends RdDItem {
static isAttaque(arme) { static isAttaque(arme) {
switch (arme.type) { switch (arme.type) {
case ITEM_TYPES.arme: case ITEM_TYPES.arme: return arme.system.equipe && (arme.system.resistance > 0 || arme.system.portee_courte > 0)
return arme.system.equipe && (arme.system.resistance > 0 || arme.system.portee_courte > 0) case ITEM_TYPES.competencecreature: return arme.system.iscombat && RdDItemCompetenceCreature.isAttaque(item)
case ITEM_TYPES.competencecreature:
return arme.system.iscombat && RdDItemCompetenceCreature.isAttaque(item)
} }
return false return false
} }
@@ -247,7 +233,7 @@ export class RdDItemArme extends RdDItem {
static isParade(arme) { static isParade(arme) {
switch (arme.type) { switch (arme.type) {
case ITEM_TYPES.arme: case ITEM_TYPES.arme:
return arme.system.equipe && arme.system.resistance > 0 && true/* TODO: regarder la categorie d'arme?*/ return arme.system.resistance > 0 && true/* TODO: regarder la categorie d'arme?*/
case ITEM_TYPES.competencecreature: case ITEM_TYPES.competencecreature:
return arme.system.iscombat && RdDItemCompetenceCreature.isParade(arme) return arme.system.iscombat && RdDItemCompetenceCreature.isParade(arme)
} }
@@ -258,7 +244,7 @@ export class RdDItemArme extends RdDItem {
static corpsACorps(actor) { static corpsACorps(actor) {
let competence = actor?.getCompetenceCorpsACorps() ?? BASE_CORPS_A_CORPS let competence = actor?.getCompetenceCorpsACorps() ?? BASE_CORPS_A_CORPS
let melee = actor ? actor.system.carac['melee'].value : 0 let melee = actor ? actor.system.carac['melee'].value : 0
return { return new RdDItemArme({
_id: competence.id, _id: competence.id,
name: 'Corps à corps', name: 'Corps à corps',
type: ITEM_TYPES.arme, type: ITEM_TYPES.arme,
@@ -278,7 +264,7 @@ export class RdDItemArme extends RdDItem {
deuxmains: true, deuxmains: true,
categorie_parade: 'sans-armes' categorie_parade: 'sans-armes'
} }
} })
} }
static mainsNues(actor) { static mainsNues(actor) {

View File

@@ -8,7 +8,6 @@ import { RdDTimestamp } from "./time/rdd-timestamp.js";
import { RdDRaretes } from "./item/raretes.js"; import { RdDRaretes } from "./item/raretes.js";
import { VOIES_DRACONIC } from "./item-sort.js"; import { VOIES_DRACONIC } from "./item-sort.js";
import { SystemCompendiums } from "./settings/system-compendiums.js"; import { SystemCompendiums } from "./settings/system-compendiums.js";
import { Misc } from "./misc.js";
class Migration { class Migration {
get code() { return "sample"; } get code() { return "sample"; }
@@ -248,7 +247,7 @@ class _10_2_10_DesirLancinant_IdeeFixe extends Migration {
await this.applyItemsUpdates(items => items await this.applyItemsUpdates(items => items
.filter(it => ['queue', 'ombre'].includes(it.type)) .filter(it => ['queue', 'ombre'].includes(it.type))
.map(it => this.migrateQueue(it)) .map(it => this.migrateQueue(it))
); )
} }
} }

View File

@@ -151,7 +151,7 @@ export class RdDCombatManager extends Combat {
} }
static getFirstInitRollFormula(actor) { static getFirstInitRollFormula(actor) {
const actions = actor.listActionsCombat() const actions = actor.listActions({ isEquipe: true })
if (actions.length > 0) { if (actions.length > 0) {
const action = actions[0] const action = actions[0]
const init = RdDCombatManager.getInitData(actor, action) const init = RdDCombatManager.getInitData(actor, action)
@@ -167,82 +167,6 @@ export class RdDCombatManager extends Combat {
return `${rang} +( (${RdDInitiative.calculInitiative(niveau, carac, bonusMalus)} )/100)`; return `${rang} +( (${RdDInitiative.calculInitiative(niveau, carac, bonusMalus)} )/100)`;
} }
/* -------------------------------------------- */
/* -------------------------------------------- */
/** Retourne une liste triée d'actions d'armes avec le split arme1 main / arme 2 main / lancer */
static listActionsArmes(armes, competences, carac) {
let actions = [];
for (const arme of armes) {
if (arme.system.equipe) {
const dommages = arme.system.dommages.toString();
const tableauDommages = dommages.includes("/") ? dommages.split("/") : [dommages, dommages];
if (arme.system.unemain && arme.system.deuxmains && !dommages.includes("/")) {
ui.notifications.info("Les dommages de l'arme à 1/2 mains " + arme.name + " ne sont pas corrects (ie sous la forme X/Y)");
}
if (arme.system.unemain && arme.system.competence) {
actions.push(RdDCombatManager.$prepareAttaqueArme({
arme: arme,
infoMain: "(1 main)",
dommagesReel: Number(tableauDommages[0]),
competence: arme.system.competence,
carac: carac,
competences: competences
}));
}
if (arme.system.deuxmains && arme.system.competence) {
actions.push(RdDCombatManager.$prepareAttaqueArme({
arme: arme,
infoMain: "(2 mains)",
dommagesReel: Number(tableauDommages[1]),
competence: RdDItemArme.competence2Mains(arme),
carac: carac,
competences: competences
}));
}
if (arme.system.lancer) {
actions.push(RdDCombatManager.$prepareAttaqueArme({
arme: arme,
infoMain: "(lancer)",
dommagesReel: Number(tableauDommages[0]),
competence: arme.system.lancer,
carac: carac,
competences: competences
}));
}
if (arme.system.tir) {
actions.push(RdDCombatManager.$prepareAttaqueArme({
arme: arme,
infoMain: "(tir)",
dommagesReel: Number(tableauDommages[0]),
competence: arme.system.tir,
carac: carac,
competences: competences
}));
}
}
}
return actions.sort(Misc.ascending(action => action.name + (action.system.infoMain ?? '')));
}
static $prepareAttaqueArme(infoAttaque) {
const comp = infoAttaque.competences.find(it => Grammar.equalsInsensitive(it.name, infoAttaque.competence))
const arme = infoAttaque.arme;
const attaque = foundry.utils.duplicate(arme)
const carac = comp?.system.defaut_carac ?? (infoAttaque.infoMain == '(lancer)' ? 'lancer' : infoAttaque.infoMain == '(lancer)' ? 'tir' : 'melee')
const niveau = comp?.system.niveau ?? (infoAttaque.infoMain == '(lancer)' ? -8 : -6)
attaque.action = 'attaque';
attaque.system.competence = infoAttaque.competence;
attaque.system.dommagesReels = infoAttaque.dommagesReel;
attaque.system.infoMain = infoAttaque.infoMain;
attaque.system.niveau = niveau
const ajustement = (arme.parent?.getEtatGeneral() ?? 0) + (arme.system.magique) ? arme.system.ecaille_efficacite : 0
attaque.system.initiative = RdDInitiative.calculInitiative(niveau, infoAttaque.carac[carac].value, ajustement)
return attaque
}
/* -------------------------------------------- */ /* -------------------------------------------- */
static processPremierRoundInit() { static processPremierRoundInit() {
// Check if we have the whole init ! // Check if we have the whole init !
@@ -305,7 +229,7 @@ export class RdDCombatManager extends Combat {
combatant.initiativeData = { arme: action } // pour reclasser l'init au round 0 combatant.initiativeData = { arme: action } // pour reclasser l'init au round 0
const init = RdDCombatManager.getInitData(actor, action) const init = RdDCombatManager.getInitData(actor, action)
const ajustement = RdDCombatManager.calculAjustementInit(actor, action) const ajustement = RdDCombatManager.calculAjustementInit(actor, action.arme)
const rollFormula = RdDCombatManager.formuleInitiative(init.offset, init.carac, init.niveau, ajustement); const rollFormula = RdDCombatManager.formuleInitiative(init.offset, init.carac, init.niveau, ajustement);
await game.combat.rollInitRdD(combatantId, rollFormula, init); await game.combat.rollInitRdD(combatantId, rollFormula, init);
@@ -319,12 +243,12 @@ export class RdDCombatManager extends Combat {
if (action.action == 'possession') { return { offset: 10, info: "Possession", carac: actor.getReveActuel(), niveau: 0 } } if (action.action == 'possession') { return { offset: 10, info: "Possession", carac: actor.getReveActuel(), niveau: 0 } }
if (action.action == 'haut-reve') { return { offset: 9, info: "Draconic", carac: actor.getReveActuel(), niveau: 0 } } if (action.action == 'haut-reve') { return { offset: 9, info: "Draconic", carac: actor.getReveActuel(), niveau: 0 } }
const comp = RdDItemCompetence.findCompetence(actor.items, action.system.competence); const comp = action.comp
return { return {
offset: RdDCombatManager.initOffset(comp?.system.categorie, action), offset: RdDCombatManager.initOffset(comp?.system.categorie, action.arme),
info: action.name + " / " + action.system.competence, info: action.name + " / " + comp.name,
carac: actor.getCaracInit(comp), carac: actor.getCaracInit(comp),
niveau: comp?.system.niveau ?? -8 niveau: comp?.system.niveau ?? (['(lancer)', '(tir)'].includes(action.main) ? -8 : -6)
} }
} }
@@ -367,7 +291,7 @@ export class RdDCombatManager extends Combat {
const possessions = actor.listActionsPossessions() const possessions = actor.listActionsPossessions()
const actions = possessions.length > 0 const actions = possessions.length > 0
? possessions ? possessions
: actor.listActionsCombat() : actor.listActions({ isEquipe: true })
for (let index = 0; index < actions.length; index++) { for (let index = 0; index < actions.length; index++) {
actions[index].index = index actions[index].index = index

View File

@@ -22,13 +22,12 @@ export class RdDHotbar {
static $macroNameSuffix(armeCompetence) { static $macroNameSuffix(armeCompetence) {
switch (armeCompetence) { switch (armeCompetence) {
case 'unemain': return ' (1 main)'; case '(1 main)': return ' (1 main)';
case 'deuxmains': return ' (2 main)'; case '(2 mains)': return ' (2 main)';
case 'tir': return ' (tir)'; case 'tir': return ' (tir)';
case 'lancer': return ' (lancer)'; case 'lancer': return ' (lancer)';
case 'pugilat': return ' (pugilat)'; case 'pugilat': return ' (pugilat)';
case 'empoignade': return ' (empoignade)'; case 'empoignade': return ' (empoignade)';
} }
return '' return ''
} }
@@ -40,10 +39,10 @@ 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++, '(1 main)')
} }
if (item.system.deuxmains) { if (item.system.deuxmains) {
await this.createItemMacro(item, slot++, 'deuxmains') await this.createItemMacro(item, slot++, '(2 mains)')
} }
} }
if (item.system.lancer != '') { if (item.system.lancer != '') {
@@ -121,9 +120,9 @@ export class RdDHotbar {
if (item.isCorpsACorps()) { if (item.isCorpsACorps()) {
switch (categorieArme) { switch (categorieArme) {
case 'pugilat': case 'pugilat':
return actor.rollArme(RdDItemArme.corpsACorps(actor), 'competence'); return actor.rollArme(RdDItemArme.corpsACorps(actor));
case 'empoignade': case 'empoignade':
return actor.rollArme(RdDItemArme.empoignade(actor), 'competence'); return actor.rollArme(RdDItemArme.empoignade(actor));
} }
} }
return actor.rollCompetence(item); return actor.rollCompetence(item);

View File

@@ -30,11 +30,11 @@ export class RdDTokenHud {
const combatant = game.combat.combatants.find(c => c.tokenId == tokenId) const combatant = game.combat.combatants.find(c => c.tokenId == tokenId)
const actor = RdDCombatManager.getActorCombatant(combatant, { warning: false }) const actor = RdDCombatManager.getActorCombatant(combatant, { warning: false })
if (actor) { if (actor) {
let actions = RdDCombatManager.listActionsActorCombatant(actor) const actions = RdDCombatManager.listActionsActorCombatant(actor)
// initiative // initiative
await RdDTokenHud.addExtensionHudInit(html, combatant, actions) await RdDTokenHud.addExtensionHudInit(html, combatant, actions)
// combat // combat
await RdDTokenHud.addExtensionHudCombat(html, combatant, token, actions) await RdDTokenHud.addExtensionHudCombat(html, combatant, token, actions.filter(it => !it.initOnly))
} }
} }
@@ -67,18 +67,19 @@ export class RdDTokenHud {
} }
static async addExtensionHudCombat(html, combatant, token, actions) { static async addExtensionHudCombat(html, combatant, token, actions) {
const hudData = { combatant, token, actions, commandes: [] }; const hudData = { combatant, token, actions, commandes: [] };
const controlIconTarget = $(html).find('.control-icon[data-action=target]'); const controlIconTarget = $(html).find('.control-icon[data-action=target]');
await RdDTokenHud._configureSubMenu(controlIconTarget, 'systems/foundryvtt-reve-de-dragon/templates/hud-actor-attaque.hbs', hudData, await RdDTokenHud._configureSubMenu(controlIconTarget, 'systems/foundryvtt-reve-de-dragon/templates/hud-actor-attaque.hbs', hudData,
(event) => { (event) => {
const actionIndex = event.currentTarget.attributes['data-action-index']?.value; const actionIndex = event.currentTarget.attributes['data-action-index']?.value;
const action = hudData.actions[actionIndex]; const action = hudData.actions[actionIndex];
const possession = action.action == 'possession' ? combatant.actor.getPossession(action.system.possessionid) : undefined; const possession = action.action == 'possession' ? combatant.actor.getPossession(action.possessionid) : undefined;
if (possession) { if (possession) {
combatant.actor.conjurerPossession(possession); combatant.actor.conjurerPossession(possession);
} }
else { else {
combatant.actor.rollArme(action, 'competence', token) combatant.actor.rollArme(action.arme, action.main, token)
} }
}); });
} }

View File

@@ -273,7 +273,8 @@ export class RdDUtility {
Handlebars.registerHelper('linkCompendium', (pack, id, name) => RdDUtility.linkCompendium(pack, id, name)); Handlebars.registerHelper('linkCompendium', (pack, id, name) => RdDUtility.linkCompendium(pack, id, name));
Handlebars.registerHelper('regle-optionnelle', (option) => ReglesOptionnelles.isUsing(option)); Handlebars.registerHelper('regle-optionnelle', (option) => ReglesOptionnelles.isUsing(option));
Handlebars.registerHelper('plusMoins', diff => (diff > 0 ? '+' : '') + Math.round(diff)) Handlebars.registerHelper('plusMoins', diff => parseInt(diff) ? (diff > 0 ? '+' : '') + Math.round(diff) : diff)
Handlebars.registerHelper('fractionOneN', n => new Handlebars.SafeString(Misc.getFractionOneN(n)))
// Handle v12 removal of this helper // Handle v12 removal of this helper
Handlebars.registerHelper('select', function (selected, options) { Handlebars.registerHelper('select', function (selected, options) {

View File

@@ -6,26 +6,31 @@
<span class="competence-value"></span> <span class="competence-value"></span>
<span class="initiative-value">Initiative</span> <span class="initiative-value">Initiative</span>
</li> </li>
{{#each combat as |arme key|}} {{#each combat as |action key|}}
<li class="item flexrow list-item" <li class="item flexrow list-item"
data-item-id="{{arme._id}}" data-item-id="{{action._id}}"
data-arme-name="{{arme.name}}" data-arme-name="{{action.arme.name}}"
data-competence-name="{{arme.system.competence}}" data-competence-name="{{action.comp.name}}"
data-tooltip="{{arme.name}}: niveau {{plusMoins arme.system.niveau}}"> data-tooltip="{{action.name}}: niveau {{plusMoins action.comp.system.niveau}}">
<span class="list-item-label flexrow"> <span class="list-item-label flexrow">
<a class="roll-arme flexrow"> <a class="roll-arme flexrow">
{{#if arme.img}} {{#if action.arme.img}}
<img class="sheet-competence-img" src="{{arme.img}}" data-tooltip="{{arme.name}}"/> <img class="sheet-competence-img" src="{{action.arme.img}}" data-tooltip="{{action.arme.name}}"/>
{{/if}} {{/if}}
<span>{{arme.name}}</span> <span>{{action.name}}</span>
</a> </a>
({{arme.system.competence}}) ({{action.comp.name}})
{{>"systems/foundryvtt-reve-de-dragon/templates/item/icon-arme-broken.hbs" arme}} {{>"systems/foundryvtt-reve-de-dragon/templates/item/icon-arme-broken.hbs" action.arme}}
</span> </span>
<span class="competence-value">{{plusMoins arme.system.niveau}}</span> <span class="competence-value">{{plusMoins action.comp.system.niveau}}</span>
<span class="competence-value">{{plusMoins arme.system.dommagesReels}}</span> <span class="competence-value">{{plusMoins action.dmg}}</span>
<span class="competence-value"></span> <span class="competence-value"></span>
<span class="initiative-value"><a class="roll-init-arme" data-tooltip="{{arme.name}}: initiative {{arme.system.initiative}}">{{arme.system.initiative}}</a></span> <span class="initiative-value">
<a class="roll-init-arme"
data-tooltip="{{action.name}}: initiative {{action.initiative}}">
{{action.initiative}}
</a>
</span>
</li> </li>
{{/each}} {{/each}}
{{#each esquives as |esq key|}} {{#each esquives as |esq key|}}

View File

@@ -72,12 +72,9 @@
</div> </div>
<hr> <hr>
<div> <div>
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/arme.hbs" name='' niveau='Niv' init='Init' dommages='+dom'}} {{>"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/arme-titre.hbs"}}
{{#each context.armes as |arme|}} {{#each attaques as |attaque|}}
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/arme.hbs" {{>"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/arme.hbs" attaque=attaque}}
name=arme.name niveau=arme.niveau init=arme.init dommages=arme.dommages
arme=arme.arme competence=arme.competence
}}
{{/each}} {{/each}}
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/esquive.hbs" name='Esquive' niveau=context.esquive.value competence=context.esquive.competence}} {{>"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/esquive.hbs" name='Esquive' niveau=context.esquive.value competence=context.esquive.competence}}
{{#if (gt export.malue_armure.value 0)}} {{#if (gt export.malue_armure.value 0)}}

View File

@@ -0,0 +1,8 @@
<div class="flexrow item">
<div></div>
<div class="flexrow">
<div>Niv.</div>
<div>Init.</div>
<div>+dom</div>
</div>
</div>

View File

@@ -1,24 +1,22 @@
<div class="flexrow item" <div class="flexrow item"
data-item-id="{{arme._id}}" data-item-id="{{attaque.arme._id}}"
data-arme-name="{{arme.name}}" data-arme-name="{{attaque.arme.name}}"
data-competence-name="{{competence.name}}"> data-competence-name="{{attaque.comp.name}}">
{{#if name}} {{#if attaque.name}}
<a class="roll-arme">{{upperFirst name}}</a> <a class="roll-arme">{{upperFirst attaque.name}}</a>
{{else}} {{else}}
<div></div> <div></div>
{{/if}} {{/if}}
<div class="flexrow"> <div class="flexrow">
<div>{{niveau}}</div> <div>{{plusMoins attaque.comp.system.niveau}}</div>
{{#if init}} <div><a class="roll-init-arme">{{attaque.initiative}}</a></div>
{{#if name}} {{#if (eq arme.system.mortalite 'empoignade')}}
<div><a class="roll-init-arme">{{init}}</a></div>
{{else}}
<div>{{init}}</div>
{{/if}}
<div>{{dommages}}</div>
{{else}}
<div></div>
<div></div> <div></div>
{{else if (eq arme.system.mortalite 'non-mortel')}}
<div>({{plusMoins attaque.dmg}})</div>
{{else}}
<div>{{plusMoins attaque.dmg}}</div>
{{/if}} {{/if}}
</div> </div>
</div> </div>