Gestion des droits jets V2

This commit is contained in:
2025-11-12 22:10:42 +01:00
parent d9b24b0f97
commit 7baccbabb9
9 changed files with 97 additions and 65 deletions
+14
View File
@@ -1,5 +1,19 @@
# 13.0
## 13.0.19 - L'introspection d'Illysis
- Fenêtre de jet v2
- restrictions au propriétaire du personnage
- ouverture de la fenêtre de jets
- appel à la chance
- appel à la destinée
- fermeture par défaut selon le type de jets:
- jets d'attaque
- jets de défense
- jets imposés par un choix d'action
- lancer de sorts
- jets suite à appel à la chance
## 13.0.18 - Le reflet d'Illysis
- Mise à jour de la feuille de personnage pdf template (avec police correcte)
+7 -14
View File
@@ -52,7 +52,6 @@ import { PART_TACHE } from "./roll/roll-part-tache.mjs";
import { PART_COMP } from "./roll/roll-part-comp.mjs";
import { PART_OEUVRE } from "./roll/roll-part-oeuvre.mjs";
import { PART_CUISINE } from "./roll/roll-part-cuisine.mjs";
import { PART_SORT } from "./roll/roll-part-sort.mjs";
export const MAINS_DIRECTRICES = ['Droitier', 'Gaucher', 'Ambidextre']
@@ -1945,8 +1944,7 @@ export class RdDActor extends RdDBaseActorSang {
diff: { value: diff ?? 0 }
}
}
RollDialog.create(rollData, foundry.utils.mergeObject(options, { onRollDone: RollDialog.onRollDoneClose }))
return
return await RollDialog.create(rollData)
}
RdDEmpoignade.checkEmpoignadeEnCours(this)
@@ -1980,8 +1978,7 @@ export class RdDActor extends RdDBaseActorSang {
selected: { tache: { key: tache.id, forced: options.forced } },
type: { allowed: [PART_TACHE], current: PART_TACHE }
}
RollDialog.create(rollData, options)
return
return await RollDialog.create(rollData)
}
const compData = this.getCompetence(tache.system.competence)
@@ -2040,8 +2037,7 @@ export class RdDActor extends RdDBaseActorSang {
selected: { jeu: { key: jeu.id } },
type: { allowed: [ROLL_TYPE_JEU], current: ROLL_TYPE_JEU }
}
await RollDialog.create(rollData, { onRollDone: RollDialog.onRollDoneClose })
return
return await RollDialog.create(rollData)
}
const listCarac = jeu.system.caraccomp.toLowerCase().split(/[.,:\/-]/).map(it => it.trim());
@@ -2069,8 +2065,7 @@ export class RdDActor extends RdDBaseActorSang {
selected: { meditation: { key: id } },
type: { allowed: [ROLL_TYPE_MEDITATION], current: ROLL_TYPE_MEDITATION }
}
await RollDialog.create(rollData, { onRollDone: RollDialog.onRollDoneClose })
return
return await RollDialog.create(rollData)
}
const competence = foundry.utils.duplicate(this.getCompetence(meditation.system.competence));
@@ -3149,7 +3144,7 @@ export class RdDActor extends RdDBaseActorSang {
selected: { oeuvre: { key: oeuvre.id } },
type: { allowed: [PART_OEUVRE], current: PART_OEUVRE, },
}
await RollDialog.create(rollData, { onRollDone: RollDialog.onRollDoneClose })
return await RollDialog.create(rollData)
}
/* -------------------------------------------- */
@@ -3254,8 +3249,7 @@ export class RdDActor extends RdDBaseActorSang {
cuisine: { key: recette.id }
}
}
RollDialog.create(rollData, { onRollDone: RollDialog.onRollDoneClose })
return
return await RollDialog.create(rollData)
}
const artData = {
@@ -3305,8 +3299,7 @@ export class RdDActor extends RdDBaseActorSang {
cuisine: { key: item.id }
}
}
RollDialog.create(rollData, { onRollDone: RollDialog.onRollDoneClose })
return
return await RollDialog.create(rollData)
}
if (item.getUtilisationCuisine() == 'brut') {
+3 -5
View File
@@ -284,8 +284,7 @@ export class RdDBaseActorReve extends RdDBaseActor {
diff: { value: diff }
}
}
RollDialog.create(rollData, options)
return
return await RollDialog.create(rollData, options)
}
const competence = this.getCompetence(compName);
@@ -372,8 +371,7 @@ export class RdDBaseActorReve extends RdDBaseActor {
comp: options.resistance ? { key: undefined, forced: true } : undefined
}
}
RollDialog.create(rollData, options)
return
return await RollDialog.create(rollData, options)
}
foundry.utils.mergeObject(options, { resistance: false, diff: 0 }, { overwrite: false })
@@ -487,7 +485,7 @@ export class RdDBaseActorReve extends RdDBaseActor {
allowed: [ROLL_TYPE_ATTAQUE], current: ROLL_TYPE_ATTAQUE
}
};
return await RollDialog.create(rollData)
return await RollDialog.create(rollData, { onRollDone: RollDialog.onRollDoneClose })
}
})
}
+8
View File
@@ -229,6 +229,14 @@ export class Misc {
return undefined
}
static async doIfOwner(document, action, orElse = async it => { ui.notifications.warn(`Vous n'avez pas le droit d'agir pour ${it.name}`) }) {
if (Misc.isOwnerPlayer(document)) {
return await action(document)
} else {
return await orElse(document)
}
}
static isOwnerPlayer(document) {
return document.testUserPermission && document.testUserPermission(game.user, CONST.DOCUMENT_OWNERSHIP_LEVELS.OWNER)
}
+2 -2
View File
@@ -687,7 +687,7 @@ export class RdDCombat {
async doRollAttaque(rollData, callbacks = []) {
// TODO V2 await this.proposerAjustementTirLancer(rollData)
await RollDialog.create(rollData, {
return await RollDialog.create(rollData, {
onRollDone: RollDialog.onRollDoneClose,
callbacks: [
async (roll) => await this.onAttaqueV2(roll),
@@ -1072,7 +1072,7 @@ export class RdDCombat {
}
async doRollDefense(rollData, callbacks = []) {
await RollDialog.create(rollData, {
return await RollDialog.create(rollData, {
onRollDone: RollDialog.onRollDoneClose,
callbacks: [
async (roll) => {
+39 -30
View File
@@ -12,6 +12,7 @@ import { PART_DEFENSE } from "./roll-part-defense.mjs"
import { PART_ATTAQUE } from "./roll-part-attaque.mjs"
import { RdDRollTables } from "../rdd-rolltables.js"
import { RdDEmpoignade } from "../rdd-empoignade.js"
import { Misc } from "../misc.js"
export default class ChatRollResult {
static init() {
@@ -171,13 +172,14 @@ export default class ChatRollResult {
}
onClickAppelChance(event) {
event.preventDefault()
const chatMessage = ChatUtility.getChatMessage(event)
const savedRoll = this.loadChatMessageRoll(chatMessage)
const actor = game.actors.get(savedRoll.ids.actorId)
actor.rollAppelChance(
Misc.doIfOwner(actor, it => it.rollAppelChance(
() => this.onAppelChanceSuccess(savedRoll, chatMessage),
() => this.onAppelChanceEchec(savedRoll, chatMessage))
event.preventDefault()
)
}
async onAppelChanceSuccess(savedRoll, chatMessage) {
@@ -197,7 +199,7 @@ export default class ChatRollResult {
this.getCombat(reRoll)?.doRollAttaque(reRoll, callbacks)
break
default: {
RollDialog.create(reRoll, { callbacks: callbacks })
await RollDialog.create(reRoll, { onRollDone: RollDialog.onRollDoneClose, callbacks })
}
}
}
@@ -208,16 +210,18 @@ export default class ChatRollResult {
}
onClickAppelDestinee(event) {
event.preventDefault()
const chatMessage = ChatUtility.getChatMessage(event)
const savedRoll = this.loadChatMessageRoll(chatMessage)
const actor = game.actors.get(savedRoll.ids.actorId)
actor.appelDestinee(async () => {
Misc.doIfOwner(actor, it => it.appelDestinee(async () => {
const reRoll = foundry.utils.duplicate(savedRoll)
reRoll.type.retry = true
RdDResolutionTable.significativeRequise(reRoll.rolled)
await this.updateChatMessage(chatMessage, reRoll)
})
}))
}
async onClickDefense(event) {
@@ -235,36 +239,40 @@ export default class ChatRollResult {
const savedRoll = this.loadChatMessageRoll(chatMessage)
const attaque = savedRoll.attackerRoll
const defenderToken = savedRoll.ids.actorTokenId ? canvas.tokens.get(savedRoll.ids.actorTokenId) : undefined
const attackerToken = savedRoll.ids.opponentTokenId ? canvas.tokens.get(savedRoll.ids.opponentTokenId) : undefined
switch (attaque.dmg.mortalite) {
case RDD_CONFIG.encaissement.empoignade:
savedRoll.done = savedRoll.done ?? {}
savedRoll.done.empoignade = await RdDEmpoignade.ajustementEmpoignade(attackerToken.actor, defenderToken.actor)
break
case RDD_CONFIG.encaissement.entiteincarnee:
case RDD_CONFIG.encaissement.nonmortel:
case RDD_CONFIG.encaissement.mortel:
const defender = defenderToken?.actor ?? game.actors.get(savedRoll.ids.actorId)
const attacker = attackerToken?.actor ?? game.actors.get(savedRoll.ids.opponentId)
await defender?.encaisserDommages(attaque.dmg, attacker, undefined, attackerToken, defenderToken)
break
}
if (isMessageDemande) {
ChatUtility.removeChatMessageId(chatMessage.id)
} else {
savedRoll.done.encaissement = true
await this.updateChatMessage(chatMessage, savedRoll)
}
const defender = defenderToken?.actor ?? game.actors.get(savedRoll.ids.actorId)
Misc.doIfOwner(defender, async defender => {
const attackerToken = savedRoll.ids.opponentTokenId ? canvas.tokens.get(savedRoll.ids.opponentTokenId) : undefined
const attacker = attackerToken?.actor ?? game.actors.get(savedRoll.ids.opponentId)
switch (attaque.dmg.mortalite) {
case RDD_CONFIG.encaissement.empoignade:
savedRoll.done = savedRoll.done ?? {}
savedRoll.done.empoignade = await RdDEmpoignade.ajustementEmpoignade(attackerToken.actor, defenderToken.actor)
break
case RDD_CONFIG.encaissement.entiteincarnee:
case RDD_CONFIG.encaissement.nonmortel:
case RDD_CONFIG.encaissement.mortel:
await defender?.encaisserDommages(attaque.dmg, attacker, undefined, attackerToken, defenderToken)
break
}
if (isMessageDemande) {
ChatUtility.removeChatMessageId(chatMessage.id)
} else {
savedRoll.done.encaissement = true
await this.updateChatMessage(chatMessage, savedRoll)
}
})
}
async onClickRecul(event) {
const chatMessage = ChatUtility.getChatMessage(event)
const savedRoll = this.loadChatMessageRoll(chatMessage)
// TODO: gestion sur token non liés?
const defender = game.actors.get(savedRoll.ids.actorId)
const attacker = game.actors.get(savedRoll.ids.opponentId)
savedRoll.done.recul = await defender.encaisserRecul(attacker.getForce(), savedRoll.attackerRoll.dmg.dmgArme)
// const reculChoc = this.getReculChoc(savedRoll, defender, attacker)
await this.updateChatMessage(chatMessage, savedRoll)
Misc.doIfOwner(defender, async defender => {
const attacker = game.actors.get(savedRoll.ids.opponentId)
savedRoll.done.recul = await defender.encaisserRecul(attacker.getForce(), savedRoll.attackerRoll.dmg.dmgArme)
await this.updateChatMessage(chatMessage, savedRoll)
})
}
async onClickChoixParticuliere(event) {
@@ -295,6 +303,7 @@ export default class ChatRollResult {
await this.updateChatMessage(chatMessage, savedRoll)
}
}
async onClickTirerMaladresse(event) {
const chatMessage = ChatUtility.getChatMessage(event)
const typeMaladresse = event.currentTarget.attributes['data-maladresse'].value
@@ -303,4 +312,4 @@ export default class ChatRollResult {
savedRoll.type.retry = true
await this.updateChatMessage(chatMessage, savedRoll)
}
}
}
+22 -11
View File
@@ -177,19 +177,25 @@ const ROLL_PARTS = [
/* -------------------------------------------- */
export default class RollDialog extends HandlebarsApplicationMixin(ApplicationV2)
{
static onCloseDoNothing() {
}
static onCloseDoNothing() { }
static onRollDoneDoNothing(dialog, roll) {
dialog.render()
}
static onRollDoneClose(dialog, roll) {
if (roll.type.retry || !OptionsAvancees.isUsing(ROLL_DIALOG_V2_TEST))
if (roll.type.retry) {
dialog.close()
}
else {
dialog.render()
}
}
static init() {
static onRollDoneClose(dialog, roll) {
if (roll.type.retry || !OptionsAvancees.isUsing(ROLL_DIALOG_V2_TEST)) {
dialog.close()
}
}
static init() { }
static onReady() {
foundry.applications.handlebars.loadTemplates({
@@ -239,9 +245,14 @@ export default class RollDialog extends HandlebarsApplicationMixin(ApplicationV2
static async create(rollData, rollOptions = {}) {
const rollDialog = new RollDialog(rollData, rollOptions)
rollDialog.render(true)
return rollDialog
rollData = RollDialog.$prepareRollData(rollData)
return Misc.doIfOwner(rollData.active.actor,
actor => {
const rollDialog = new RollDialog(rollData, rollOptions)
rollDialog.render(true)
return rollDialog
}
)
}
static get PARTS() {
@@ -321,7 +332,7 @@ export default class RollDialog extends HandlebarsApplicationMixin(ApplicationV2
super()
this.hooks = []
this.rollData = RollDialog.$prepareRollData(rollData)
this.rollData = rollData
this.rollOptions = {
callbacks: [
async r => await r.active.actor.appliquerAjoutExperience(r),
+2 -1
View File
@@ -142,7 +142,8 @@ export class RollPartAttaque extends RollPartSelect {
comp: { key: 'Dague', forced: true },
diff: { type: DIFF.IMPOSEE, value: -4 }
}
})
},
{ onRollDone: RollDialog.onRollDoneClose })
}
impactOtherPart(part, rollData) {
@@ -1,8 +1,6 @@
import { RDD_CONFIG } from "../constants.js"
import { ATTAQUE_TYPE_MELEE } from "../item/arme.js"
import { RdDEmpoignade } from "../rdd-empoignade.js"
import { COMBAT_ROLL_TYPES } from "./roll-constants.mjs"
import { PART_ATTAQUE } from "./roll-part-attaque.mjs"
import { RollPartCheckbox } from "./roll-part-checkbox.mjs"
const EMPOIGNADE_TAILLE = "empoignade-taille"