Init/progression dice

This commit is contained in:
2025-01-18 00:00:25 +01:00
parent e12476d64f
commit 4e673913a1
45 changed files with 660 additions and 504 deletions

View File

@ -229,7 +229,7 @@ export default class LethalFantasyRoll extends Roll {
options.rollName = options.rollTarget.name
hasModifier = true
hasChangeDice = false
options.rollTarget.value = 0
options.rollTarget.value = options.rollTarget.damageModifier
options.rollTarget.charModifier = 0
dice = options.rollTarget.damageDice
dice = dice.replace("E", "")
@ -517,11 +517,95 @@ export default class LethalFantasyRoll extends Roll {
let initRoll = new Roll(`min(${rollContext.initiativeDice}, ${options.maxInit})`, options.data, rollContext)
await initRoll.evaluate()
initRoll.toMessage( {flavor: `Initiative for ${options.actorName}`}, {rollMode: rollContext.visibility} )
let msg = await initRoll.toMessage( {flavor: `Initiative for ${options.actorName}`}, {rollMode: rollContext.visibility} )
await game.dice3d.waitFor3DAnimationByMessageID(msg.id)
if (options.combatId && options.combatantId) {
let combat = game.combats.get(options.combatId)
combat.updateEmbeddedDocuments("Combatant", [ { _id: options.combatantId, initiative: initRoll.total, 'system.progressionCount': 0 } ]);
}
}
static async promptProgressionDice(options = {}) {
const rollModes = Object.fromEntries(Object.entries(CONFIG.Dice.rollModes).map(([key, value]) => [key, game.i18n.localize(value)]))
const fieldRollMode = new foundry.data.fields.StringField({
choices: rollModes,
blank: false,
default: "public",
})
let dialogContext = {
progressionDiceId: "",
fieldRollMode,
rollModes,
...options
}
console.log("CTX PROGRESSION", dialogContext)
const content = await renderTemplate("systems/fvtt-lethal-fantasy/templates/roll-progression-dice-dialog.hbs", dialogContext)
const label = game.i18n.localize("LETHALFANTASY.Label.rollProgressionDice")
const rollContext = await foundry.applications.api.DialogV2.wait({
window: { title: "Progression Roll" },
classes: ["lethalfantasy"],
content,
buttons: [
{
action: "roll",
label: label,
callback: (event, button, dialog) => {
const output = Array.from(button.form.elements).reduce((obj, input) => {
if (input.name) obj[input.name] = input.value
return obj
}, {})
return output
},
},
{
action: "cancel",
label: "Other action, no weapon progression dice",
callback: (event, button, dialog) => { return null; }
}
],
rejectClose: false // Click on Close button will not launch an error
})
console.log("RollContext", rollContext)
if (rollContext === null || !rollContext?.progressionDiceId) {
return
}
// Get the weapons from the actor items
let actor = game.actors.get(options.actorId)
let weapon = actor.items.find(i => i.type === "weapon" && i.id === rollContext.progressionDiceId)
// Get the dice and roll it
let formula = weapon.system.combatProgressionDice
let roll = new Roll(formula)
await roll.evaluate()
let max = roll.dice[0].faces - 1
max = Math.min(options.rollProgressionCount, max)
let msg = await roll.toMessage( {flavor: `Progression Roll for ${weapon.name}, progression count : ${options.rollProgressionCount}/${max}`}, {rollMode: rollContext.visibility} )
await game.dice3d.waitFor3DAnimationByMessageID(msg.id)
if (roll.total <= max ) {
// Notify that the player can act now with a chat message
let message = game.i18n.format("LETHALFANTASY.Notifications.messageProgressionOK", { name: actor.name, weapon: weapon.name, roll: roll.total })
ChatMessage.create({ content: message, speaker: ChatMessage.getSpeaker({ actor: actor }) })
// Update the combatant progression count
let combat = game.combats.get(options.combatId)
let combatant = combat.combatants.get(options.combatantId)
combatant.update({ 'system.progressionCount': 0 })
} else {
// Notify that the player cannot act now with a chat message
let message = game.i18n.format("LETHALFANTASY.Notifications.messageProgressionKO", { name: actor.name, weapon: weapon.name, roll: roll.total })
ChatMessage.create({ content: message, speaker: ChatMessage.getSpeaker({ actor: actor }) })
}
}
static async promptRangedDefense(rollTarget) {
const rollModes = Object.fromEntries(Object.entries(CONFIG.Dice.rollModes).map(([key, value]) => [key, game.i18n.localize(value)]))
const fieldRollMode = new foundry.data.fields.StringField({
@ -681,30 +765,8 @@ export default class LethalFantasyRoll extends Roll {
return await renderTemplate(this.constructor.CHAT_TEMPLATE, chatData)
}
/**
/*
* Generates the data required for rendering a roll chat card.
*
* @param {boolean} isPrivate Indicates if the chat card is private.
* @returns {Promise<Object>} A promise that resolves to an object containing the chat card data.
* @property {Array<string>} css - CSS classes for the chat card.
* @property {Object} data - The data associated with the roll.
* @property {number} diceTotal - The total value of the dice rolled.
* @property {boolean} isGM - Indicates if the user is a Game Master.
* @property {string} formula - The formula used for the roll.
* @property {number} total - The total result of the roll.
* @property {boolean} isSave - Indicates if the roll is a saving throw.
* @property {boolean} isDamage - Indicates if the roll is for damage.
* @property {boolean} isFailure - Indicates if the roll is a failure.
* @property {string} actorId - The ID of the actor performing the roll.
* @property {string} actingCharName - The name of the character performing the roll.
* @property {string} actingCharImg - The image of the character performing the roll.
* @property {string} resultType - The type of result (e.g., success, failure).
* @property {boolean} hasTarget - Indicates if the roll has a target.
* @property {string} targetName - The name of the target.
* @property {number} targetArmor - The armor value of the target.
* @property {boolean} isPrivate - Indicates if the chat card is private.
* @property {string} cssClass - The combined CSS classes as a single string.
* @property {string} tooltip - The tooltip text for the chat card.
*/
async _getChatCardData(isPrivate) {
const cardData = {