diff --git a/module/actor.js b/module/actor.js
index 75eec4e8..848368ac 100644
--- a/module/actor.js
+++ b/module/actor.js
@@ -36,6 +36,8 @@ import { ITEM_TYPES } from "./item.js";
import { RdDBaseActorSang } from "./actor/base-actor-sang.js";
import { RdDCoeur } from "./coeur/rdd-coeur.js";
import { DialogChoixXpCarac } from "./dialog-choix-xp-carac.js";
+import { RdDItemArme } from "./item-arme.js";
+import { RdDCombatManager } from "./rdd-combat.js";
export const MAINS_DIRECTRICES = ['Droitier', 'Gaucher', 'Ambidextre']
@@ -130,6 +132,23 @@ export class RdDActor extends RdDBaseActorSang {
.reduce(Misc.sum(), 0);
}
+ listActionsCombat() {
+ // Recupération des armes
+ const actions = RdDCombatManager.listActionsArmes(
+ this.itemTypes[ITEM_TYPES.arme]
+ .filter(it => RdDItemArme.isAttaque(it))
+ .concat(RdDItemArme.empoignade(this))
+ .concat(RdDItemArme.mainsNues(this))
+ ,
+ this.itemTypes[ITEM_TYPES.competence],
+ this.system.carac)
+
+ if (this.system.attributs.hautrevant.value) {
+ actions.push({ name: "Draconic", action: 'haut-reve', system: { initOnly: true, competence: "Draconic" } });
+ }
+ return actions
+ }
+
/* -------------------------------------------- */
getTache(id) { return this.findItemLike(id, 'tache') }
getMeditation(id) { return this.findItemLike(id, 'meditation') }
@@ -1548,7 +1567,7 @@ export class RdDActor extends RdDBaseActorSang {
/* -------------------------------------------- */
async appliquerAjoutExperience(rollData, hideChatMessage = 'show') {
- if (!Misc.isFirstConnectedGM()){
+ if (!Misc.isFirstConnectedGM()) {
return
}
hideChatMessage = hideChatMessage == 'hide' || (Misc.isRollModeHiddenToPlayer() && !game.user.isGM)
@@ -3067,7 +3086,7 @@ export class RdDActor extends RdDBaseActorSang {
incarnation.name = 'Réincarnation de ' + incarnation.name
incarnation.system = {
carac: foundry.utils.duplicate(this.system.carac),
- heure: RdDTimestamp.defHeure(await RdDDice.rollHeure( { rollMode: "selfroll", showDice: SHOW_DICE })).key,
+ heure: RdDTimestamp.defHeure(await RdDDice.rollHeure({ rollMode: "selfroll", showDice: SHOW_DICE })).key,
age: 18,
biographie: '',
notes: '',
diff --git a/module/actor/base-actor-reve.js b/module/actor/base-actor-reve.js
index 53b5604b..50680bb4 100644
--- a/module/actor/base-actor-reve.js
+++ b/module/actor/base-actor-reve.js
@@ -15,7 +15,7 @@ import { StatusEffects } from "../settings/status-effects.js";
import { ITEM_TYPES } from "../item.js";
import { Targets } from "../targets.js";
import { RdDPossession } from "../rdd-possession.js";
-import { RdDCombat } from "../rdd-combat.js";
+import { RdDCombat, RdDCombatManager } from "../rdd-combat.js";
import { RdDConfirm } from "../rdd-confirm.js";
import { ENTITE_INCARNE, SHOW_DICE, SYSTEM_RDD } from "../constants.js";
import { RdDItemArme } from "../item-arme.js";
@@ -83,6 +83,23 @@ export class RdDBaseActorReve extends RdDBaseActor {
getEtatGeneral(options = { ethylisme: false }) { return 0 }
isActorCombat() { return true }
+ getCaracInit(competence) {
+ if (!competence){
+ return 0
+ }
+ if (competence.type == ITEM_TYPES.competencecreature) {
+ return competence.system.carac_value
+ }
+ return this.system.carac[competence.system.defaut_carac].value;
+ }
+ listActionsCombat() {
+ return this.itemTypes[ITEM_TYPES.competencecreature]
+ .filter(it => RdDItemCompetenceCreature.isAttaque(it))
+ .map(it => RdDItemCompetenceCreature.armeCreature(it))
+ .filter(it => it != undefined);
+ }
+
+
async computeArmure(attackerRoll) { return this.getProtectionNaturelle() }
async remiseANeuf() { }
async appliquerAjoutExperience(rollData, hideChatMessage = 'show') { }
@@ -155,9 +172,6 @@ export class RdDBaseActorReve extends RdDBaseActor {
getPossession(possessionId) {
return this.itemTypes[ITEM_TYPES.possession].find(it => it.system.possessionid == possessionId);
}
- getPossessions() {
- return this.itemTypes[ITEM_TYPES.possession];
- }
getEmpoignades() {
return this.itemTypes[ITEM_TYPES.empoignade];
}
@@ -370,7 +384,7 @@ export class RdDBaseActorReve extends RdDBaseActor {
rollArme(arme, categorieArme, token) {
token = token ?? RdDUtility.getSelectedToken(this)
const compToUse = this.$getCompetenceArme(arme, categorieArme)
- if (!RdDItemArme.isArmeUtilisable(arme)) {
+ if (!RdDItemArme.isUtilisable(arme)) {
ui.notifications.warn(`Arme inutilisable: ${arme.name} a une résistance de 0 ou moins`)
return
}
@@ -452,7 +466,7 @@ export class RdDBaseActorReve extends RdDBaseActor {
alias: defenderToken?.name ?? this.name,
hasPlayerOwner: this.hasPlayerOwner,
show: show ?? {}
- }, {overwrite: false});
+ }, { overwrite: false });
await ChatUtility.createChatWithRollMode(
{
diff --git a/module/actor/base-actor.js b/module/actor/base-actor.js
index 7d8b64ab..d84a9a20 100644
--- a/module/actor/base-actor.js
+++ b/module/actor/base-actor.js
@@ -710,4 +710,19 @@ export class RdDBaseActor extends Actor {
getItemUse(itemId) { return 0; }
async finDeRound(options = { terminer: false }) { }
isActorCombat() { return false }
+ getCaracInit(competence) { return 0 }
+ listActionsCombat() { return [] }
+ listActionsPossessions() {
+ return this.itemTypes[ITEM_TYPES.possession]
+ .map(p => {
+ return {
+ name: p.name,
+ action: 'possession',
+ system: {
+ competence: p.name,
+ possessionid: p.system.possessionid,
+ }
+ }
+ })
+ }
}
\ No newline at end of file
diff --git a/module/actor/export-scriptarium/mapping.js b/module/actor/export-scriptarium/mapping.js
index 8a4cd515..6d1fc29b 100644
--- a/module/actor/export-scriptarium/mapping.js
+++ b/module/actor/export-scriptarium/mapping.js
@@ -152,8 +152,8 @@ export class Mapping {
}
static prepareArme(actor, arme, maniement) {
- const nameCompArme = RdDItemArme.getCompetenceArme(arme, maniement)
- const competence = actor.getCompetence(nameCompArme)
+ const nameCompetenceArme = RdDItemArme.getCompetenceArme(arme, maniement)
+ const competence = actor.getCompetence(nameCompetenceArme)
if (RdDItemCompetence.isNiveauBase(competence)) {
return undefined
}
diff --git a/module/item-arme.js b/module/item-arme.js
index 86255aa6..6d9c7a17 100644
--- a/module/item-arme.js
+++ b/module/item-arme.js
@@ -206,7 +206,7 @@ export class RdDItemArme extends Item {
return arme.system.competence.replace(" 1 main", " 2 mains");
}
- static isArmeUtilisable(arme) {
+ static isUtilisable(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
@@ -214,6 +214,26 @@ export class RdDItemArme extends Item {
return false
}
+ static isAttaque(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 arme.system.iscombat && RdDItemCompetenceCreature.isAttaque(item)
+ }
+ return false
+ }
+
+ static isParade(arme) {
+ switch (arme.type) {
+ case ITEM_TYPES.arme:
+ return arme.system.equipe && arme.system.resistance > 0 && true/* TODO: regarder la categorie d'arme?*/
+ case ITEM_TYPES.competencecreature:
+ return arme.system.iscombat && RdDItemCompetenceCreature.isParade(arme)
+ }
+ return false
+ }
+
static ajoutCorpsACorps(armes, actor) {
armes.push(RdDItemArme.mainsNues(actor));
armes.push(RdDItemArme.empoignade(actor));
diff --git a/module/item-competencecreature.js b/module/item-competencecreature.js
index 7e1ab4b5..6828fd48 100644
--- a/module/item-competencecreature.js
+++ b/module/item-competencecreature.js
@@ -27,29 +27,28 @@ export class RdDItemCompetenceCreature extends Item {
static armeCreature(item) {
const categorieAttaque = RdDItemCompetenceCreature.getCategorieAttaque(item)
if (categorieAttaque != undefined) {
- // si c'est un Item compétence: cloner pour ne pas modifier la compétence
- let arme = item.clone();
- return foundry.utils.mergeObject(arme, {
+ // cloner pour ne pas modifier la compétence
+ return foundry.utils.mergeObject(item, {
action: item.isCompetencePossession() ? 'possession' : 'attaque',
system: {
- competence: arme.name,
+ competence: item.name,
cac: categorieAttaque == "naturelle" ? "naturelle" : "",
niveau: item.system.niveau,
initiative: RdDCombatManager.calculInitiative(item.system.niveau, item.system.carac_value),
equipe: true,
resistance: 100,
- dommagesReels: arme.system.dommages,
+ dommagesReels: item.system.dommages,
penetration: 0,
force: 0,
rapide: true,
}
- }, { inplace: false });
+ }, { inplace: false, });
}
return undefined;
}
/* -------------------------------------------- */
- static isCompetenceAttaque(item) {
+ static isAttaque(item) {
if (item.type == ITEM_TYPES.competencecreature) {
switch (item.system.categorie) {
case "melee":
@@ -60,7 +59,7 @@ export class RdDItemCompetenceCreature extends Item {
return true
}
}
- return undefined
+ return false
}
static getCategorieAttaque(item) {
@@ -77,6 +76,7 @@ export class RdDItemCompetenceCreature extends Item {
}
return undefined
}
+
static isDommages(item) {
if (item.type == ITEM_TYPES.competencecreature) {
switch (item.system.categorie) {
@@ -89,6 +89,7 @@ export class RdDItemCompetenceCreature extends Item {
}
return false
}
+
static isParade(item) {
if (item.type == ITEM_TYPES.competencecreature) {
switch (item.system.categorie) {
@@ -101,8 +102,4 @@ export class RdDItemCompetenceCreature extends Item {
return false
}
- /* -------------------------------------------- */
- static isCompetenceParade(item) {
- return item.type == 'competencecreature' && item.system.categorie_parade !== "";
- }
-}
+}
diff --git a/module/rdd-combat.js b/module/rdd-combat.js
index 35b6bf9f..e02260ae 100644
--- a/module/rdd-combat.js
+++ b/module/rdd-combat.js
@@ -72,19 +72,24 @@ export class RdDCombatManager extends Combat {
/* -------------------------------------------- */
async finDeRound(options = { terminer: false }) {
+ this.combatants.map(it => RdDCombatManager.getActorCombatant(it))
+ .filter(it => it != undefined)
+ .forEach(async actor => {
+ await actor.finDeRound(options)
+ await actor.resetItemUse()
+ })
+ }
- for (let combatant of this.combatants) {
- if (!combatant.actor) {
- ui.notifications.warn(`Le combatant ${combatant.name} n'est pas associé à un acteur!`)
- }
- else if (!combatant.actor.isActorCombat()) {
- ui.notifications.warn(`Le combatant ${combatant.name} ne peut pas combattre!`)
- }
- else {
- await combatant.actor.finDeRound(options)
- await combatant.actor.resetItemUse()
- }
+ static getActorCombatant(combatant) {
+ if (!combatant.actor) {
+ ui.notifications.warn(`Le combatant ${combatant.name} n'est pas associé à un acteur!`)
+ return undefined
}
+ else if (!combatant.actor.isActorCombat()) {
+ ui.notifications.warn(`${combatant.name} ne peut pas combattre!`)
+ return undefined
+ }
+ return combatant.actor
}
static calculAjustementInit(actor, arme) {
@@ -107,7 +112,7 @@ export class RdDCombatManager extends Combat {
if (!formula) {
if (combatant.actor.type == 'creature' || combatant.actor.type == 'entite') {
- const competence = combatant.actor.items.find(it => RdDItemCompetenceCreature.isCompetenceAttaque(it))
+ const competence = combatant.actor.items.find(it => RdDItemCompetenceCreature.isAttaque(it))
if (competence) {
rollFormula = RdDCombatManager.formuleInitiative(2, competence.system.carac_value, competence.system.niveau, etatGeneral);
}
@@ -156,7 +161,7 @@ export class RdDCombatManager extends Combat {
alias: combatant.token.name,
sound: CONFIG.sounds.dice,
},
- flavor: `${combatant.token.name} a fait son jet d'Initiative (${messageOptions.initInfo})
`,
+ flavor: `${combatant.token.name} a fait son jet d'Initiative (${messageOptions.info})
`,
},
messageOptions);
roll.toMessage(messageData, { rollMode, create: true });
@@ -247,61 +252,6 @@ export class RdDCombatManager extends Combat {
return attaque;
}
- /* -------------------------------------------- */
- static listActionsCombat(combatant) {
- const actor = combatant.actor;
- if (!actor.isActorCombat()) {
- return
- }
- let actions = RdDCombatManager.listActionsPossessions(actor);
- if (actions.length > 0) {
- return actions;
- }
- if (actor.isCreatureEntite()) {
- actions = RdDCombatManager.listActionsCreature(actor.itemTypes['competencecreature']);
- } else if (actor.isPersonnage()) {
- // Recupération des items 'arme'
- 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);
-
- if (actor.system.attributs.hautrevant.value) {
- actions.push({ name: "Draconic", action: 'haut-reve', system: { initOnly: true, competence: "Draconic" } });
- }
- }
-
- return RdDCombatManager._indexActions(actions);
- }
-
- static listActionsCreature(competences) {
- return competences
- .filter(it => RdDItemCompetenceCreature.isCompetenceAttaque(it))
- .map(it => RdDItemCompetenceCreature.armeCreature(it))
- .filter(it => it != undefined);
- }
-
- static listActionsPossessions(actor) {
- return RdDCombatManager._indexActions(actor.getPossessions().map(p => {
- return {
- name: p.name,
- action: 'possession',
- system: {
- competence: p.name,
- possessionid: p.system.possessionid,
- }
- }
- }));
- }
-
- static _indexActions(actions) {
- for (let index = 0; index < actions.length; index++) {
- actions[index].index = index;
- }
- return actions;
- }
-
/* -------------------------------------------- */
static processPremierRoundInit() {
// Check if we have the whole init !
@@ -339,13 +289,13 @@ export class RdDCombatManager extends Combat {
/* -------------------------------------------- */
static pushInitiativeOptions(html, options) {
for (let i = 0; i < options.length; i++) {
- let option = options[i];
+ let option = options[i]
if (option.name == 'COMBAT.CombatantReroll') { // Replace !
- option.name = "Sélectionner l'initiative...";
- option.condition = true;
- option.icon = '';
+ option.name = "Sélectionner l'initiative..."
+ option.condition = true
+ option.icon = ''
option.callback = target => {
- RdDCombatManager.displayInitiativeMenu(html, target.data('combatant-id'));
+ RdDCombatManager.displayInitiativeMenu(html, target.data('combatant-id'))
}
}
}
@@ -356,96 +306,84 @@ export class RdDCombatManager extends Combat {
}
/* -------------------------------------------- */
static rollInitiativeAction(combatantId, action) {
- const combatant = game.combat.combatants.get(combatantId);
- if (combatant.actor == undefined) {
- ui.notifications.warn(`Le combatant ${combatant.name} n'est pas associé à un acteur, impossible de déterminer ses actions de combat!`)
- return [];
- }
- let initInfo = "";
- let initOffset = 0;
- let caracForInit = 0;
- let compNiveau = 0;
- let compData = { name: "Aucune" };
- if (combatant.actor.getSurprise() == "totale") {
- initOffset = -1; // To force 0
- initInfo = "Surprise Totale"
- } else if (combatant.actor.getSurprise() == "demi") {
- initOffset = 0;
- initInfo = "Demi Surprise"
- } else if (action.action == 'possession') {
- initOffset = 10;
- caracForInit = combatant.actor.getReveActuel();
- initInfo = "Possession"
- } else if (action.action == 'autre') {
- initOffset = 2;
- initInfo = "Autre Action"
- } else if (action.action == 'haut-reve') {
- initOffset = 9;
- initInfo = "Draconic"
- } else {
- compData = RdDItemCompetence.findCompetence(combatant.actor.items, action.system.competence);
- compNiveau = compData.system.niveau;
- initInfo = action.name + " / " + action.system.competence;
+ const combatant = game.combat.combatants.get(combatantId)
+ const actor = RdDCombatManager.getActorCombatant(combatant)
+ if (actor == undefined) { return [] }
- if (combatant.actor.type == 'creature' || combatant.actor.type == 'entite') {
- caracForInit = compData.system.carac_value;
- } else {
- caracForInit = combatant.actor.system.carac[compData.system.defaut_carac].value;
- }
- initOffset = RdDCombatManager._baseInitOffset(compData.system.categorie, action);
- }
-
- // Cas des créatures et entités vs personnages
- const ajustement = RdDCombatManager.calculAjustementInit(combatant.actor, action)
- let rollFormula = RdDCombatManager.formuleInitiative(initOffset, caracForInit, compNiveau, ajustement);
- // Garder la trace de l'arme/compétence utilisée pour l'iniative
combatant.initiativeData = { arme: action } // pour reclasser l'init au round 0
- game.combat.rollInitiative(combatantId, rollFormula, { initInfo: initInfo });
+
+ const init = RdDCombatManager.getInitData(actor, action)
+ const ajustement = RdDCombatManager.calculAjustementInit(actor, action)
+ const rollFormula = RdDCombatManager.formuleInitiative(init.offset, init.carac, init.niveau, ajustement);
+
+ game.combat.rollInitiative(combatantId, rollFormula, init);
}
- /* -------------------------------------------- */
- static _baseInitOffset(categorie, arme) {
- if (categorie == "tir") { // Offset de principe pour les armes de jet
- return 8;
+ static getInitData(actor, action) {
+ if (actor.getSurprise() == "totale") { return { offset: -1, info: "Surprise Totale", carac: 0, niveau: 0 } }
+ if (actor.getSurprise() == "demi") { return { offset: 0, info: "Demi Surprise", carac: 0, niveau: 0 } }
+ if (action.action == 'autre') { return { offset: 2, info: "Autre Action", carac: 0, 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 } }
+
+ const comp = RdDItemCompetence.findCompetence(actor.items, action.system.competence);
+ return {
+ offset: RdDCombatManager.initOffset(comp?.system.categorie, action),
+ info: action.name + " / " + action.system.competence,
+ carac: actor.getCaracInit(comp),
+ niveau: comp?.system.niveau ?? -8
}
- if (categorie == "lancer") { // Offset de principe pour les armes de jet
- return 7;
+ }
+
+ static initOffset(categorie, arme) {
+ switch (categorie) {
+ case "tir": return 8
+ case "lancer": return 7
+ default:
+ switch (arme.system.cac) {
+ case "empoignade": return 3
+ case "pugilat": return 4
+ case "naturelle": return 4
+ default: return 5
+ }
}
- switch (arme.system.cac) {
- case "empoignade":
- return 3;
- case "pugilat":
- case "naturelle":
- return 4;
- }
- return 5;
}
/* -------------------------------------------- */
static displayInitiativeMenu(html, combatantId) {
- console.log("Combatant ; ", combatantId);
- const combatant = game.combat.combatants.get(combatantId);
- if (!(combatant?.actor)) {
- ui.notifications.warn(`Le combatant ${combatant.name ?? combatantId} n'est pas associé à un acteur, impossible de déterminer ses actions de combat!`)
- return;
- }
-
- let actions = RdDCombatManager.listActionsCombat(combatant);
-
+ const combatant = game.combat.combatants.get(combatantId)
+ const actions = RdDCombatManager.listActionsCombatant(combatant);
// Build the relevant submenu
- if (actions) {
- let menuItems = [];
- for (let action of actions) {
- menuItems.push({
- name: action.system.competence,
- icon: "",
- callback: target => { RdDCombatManager.rollInitiativeAction(combatantId, action) }
- });
+ const menuItems = actions.map(action => {
+ return {
+ name: action.system.competence,
+ icon: "",
+ callback: target => { RdDCombatManager.rollInitiativeAction(combatantId, action) }
}
+ })
+ if (menuItems.length > 0) {
new ContextMenu(html, ".directory-list", menuItems).render();
}
}
+ /* -------------------------------------------- */
+ static listActionsCombatant(combatant) {
+ const actor = RdDCombatManager.getActorCombatant(combatant)
+ if (actor) {
+ const possessions = actor.listActionsPossessions()
+ const actions = possessions.length > 0
+ ? possessions
+ : actor.listActionsCombat()
+
+ for (let index = 0; index < actions.length; index++) {
+ actions[index].index = index
+ }
+ return actions
+ }
+ return []
+ }
+
+
}
/* -------------------------------------------- */
@@ -992,13 +930,13 @@ export class RdDCombat {
}
/* -------------------------------------------- */
- _filterArmesParade(defender, competence, arme) {
- let defenses = defender.items.filter(it => RdDItemArme.isArmeUtilisable(it) || RdDItemCompetenceCreature.isCompetenceParade(it))
+ _filterArmesParade(defender, competence, armeAttaque) {
+ let defenses = defender.items.filter(it => RdDItemArme.isParade(it))
defenses = foundry.utils.duplicate(defenses)
defenses.forEach(armeDefense => {
// Ajout du # d'utilisation ce round
armeDefense.nbUsage = defender.getItemUse(armeDefense.id)
- armeDefense.typeParade = RdDItemArme.defenseArmeParade(arme, armeDefense)
+ armeDefense.typeParade = RdDItemArme.defenseArmeParade(armeAttaque, armeDefense)
})
switch (competence.system.categorie) {
@@ -1353,7 +1291,7 @@ export class RdDCombat {
if (!actor?.isActorCombat()) {
return
}
- let formData = {
+ const formData = {
combatId: combat._id,
alias: token.name ?? actor.name,
etatGeneral: actor.getEtatGeneral(),
@@ -1374,6 +1312,6 @@ export class RdDCombat {
content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-actor-turn-sante.hbs`, formData),
whisper: ChatUtility.getOwners(actor),
alias: token.name ?? actor.name
- });
+ })
}
}
\ No newline at end of file
diff --git a/module/rdd-token-hud.js b/module/rdd-token-hud.js
index a230f8ee..d0040f0b 100644
--- a/module/rdd-token-hud.js
+++ b/module/rdd-token-hud.js
@@ -33,7 +33,7 @@ export class RdDTokenHud {
ui.notifications.warn(`Le combatant ${token.name} n'est pas associé à un acteur, impossible de déterminer ses actions de combat!`)
return;
}
- let actions = RdDCombatManager.listActionsCombat(combatant);
+ let actions = RdDCombatManager.listActionsCombatant(combatant);
// initiative
await RdDTokenHud.addExtensionHudInit(html, combatant, actions);
// combat