Enhance rolls and fix dialog position
This commit is contained in:
@ -223,7 +223,7 @@ export default class LethalFantasyRoll extends Roll {
|
||||
options.rollTarget.charModifier = options.rollTarget.actorModifiers.intSpellModifier
|
||||
hasStaticModifier = options.rollType === "spell-power"
|
||||
//hasModifier = options.rollType !== "spell-attack"
|
||||
if ( hasStaticModifier ) {
|
||||
if (hasStaticModifier) {
|
||||
options.rollTarget.staticModifier = options.rollTarget.actorLevel
|
||||
} else {
|
||||
options.rollTarget.staticModifier = 0
|
||||
@ -240,7 +240,7 @@ export default class LethalFantasyRoll extends Roll {
|
||||
options.rollTarget.charModifier = options.rollTarget.actorModifiers.chaMiracleModifier
|
||||
hasStaticModifier = options.rollType === "miracle-power"
|
||||
//hasModifier = options.rollType !== "miracle-attack"
|
||||
if ( hasStaticModifier ) {
|
||||
if (hasStaticModifier) {
|
||||
options.rollTarget.staticModifier = options.rollTarget.actorLevel
|
||||
} else {
|
||||
options.rollTarget.staticModifier = 0
|
||||
@ -331,16 +331,19 @@ export default class LethalFantasyRoll extends Roll {
|
||||
}
|
||||
const content = await renderTemplate("systems/fvtt-lethal-fantasy/templates/roll-dialog.hbs", dialogContext)
|
||||
|
||||
const title = LethalFantasyRoll.createTitle(options.rollType, options.rollTarget)
|
||||
let position = game.user.getFlag(SYSTEM.id, "roll-dialog-pos") || { top: -1, left: -1 }
|
||||
const label = game.i18n.localize("LETHALFANTASY.Roll.roll")
|
||||
const rollContext = await foundry.applications.api.DialogV2.wait({
|
||||
window: { title: title },
|
||||
window: { title: "Roll dialog" },
|
||||
classes: ["lethalfantasy"],
|
||||
content,
|
||||
position,
|
||||
buttons: [
|
||||
{
|
||||
label: label,
|
||||
callback: (event, button, dialog) => {
|
||||
let position = $(dialog).position()
|
||||
game.user.setFlag(SYSTEM.id, "roll-dialog-pos", foundry.utils.duplicate(position))
|
||||
const output = Array.from(button.form.elements).reduce((obj, input) => {
|
||||
if (input.name) obj[input.name] = input.value
|
||||
return obj
|
||||
@ -352,6 +355,15 @@ export default class LethalFantasyRoll extends Roll {
|
||||
actions: {
|
||||
"selectGranted": (event, button, dialog) => {
|
||||
hasGrantedDice = true
|
||||
},
|
||||
"gotoToken" : (event, button, dialog) => {
|
||||
let tokenId = $(button).data("tokenId")
|
||||
let token = canvas.tokens?.get(tokenId)
|
||||
if (token) {
|
||||
canvas.animatePan({ x: token.x, y: token.y, duration: 200 })
|
||||
canvas.tokens.releaseAll();
|
||||
token.control({ releaseOthers: true });
|
||||
}
|
||||
}
|
||||
},
|
||||
rejectClose: false // Click on Close button will not launch an error
|
||||
@ -630,6 +642,8 @@ export default class LethalFantasyRoll extends Roll {
|
||||
}
|
||||
let currentAction = combatant.getFlag(SYSTEM.id, "currentAction")
|
||||
|
||||
let position = game.user.getFlag(SYSTEM.id, "combat-action-dialog-pos") || { top: -1, left: -1 }
|
||||
|
||||
let dialogContext = {
|
||||
progressionDiceId: "",
|
||||
fieldRollMode,
|
||||
@ -647,24 +661,34 @@ export default class LethalFantasyRoll extends Roll {
|
||||
action: "roll",
|
||||
label: "Roll progression dice",
|
||||
callback: (event, button, dialog) => {
|
||||
let pos = $('#combat-action-dialog').position()
|
||||
game.user.setFlag(SYSTEM.id, "combat-action-dialog-pos", pos)
|
||||
return "rollProgressionDice"
|
||||
},
|
||||
})
|
||||
} else if (currentAction.type === "spell" || currentAction.type === "miracle") {
|
||||
let label = ""
|
||||
if (currentAction.spellStatus === "castingTime") {
|
||||
let pos = $('#combat-action-dialog').position()
|
||||
game.user.setFlag(SYSTEM.id, "combat-action-dialog-pos", pos)
|
||||
label = "Wait casting time"
|
||||
}
|
||||
if (currentAction.spellStatus === "toBeCasted") {
|
||||
let pos = $('#combat-action-dialog').position()
|
||||
game.user.setFlag(SYSTEM.id, "combat-action-dialog-pos", pos)
|
||||
label = "Cast spell/miracle"
|
||||
}
|
||||
if (currentAction.spellStatus === "lethargy") {
|
||||
let pos = $('#combat-action-dialog').position()
|
||||
game.user.setFlag(SYSTEM.id, "combat-action-dialog-pos", pos)
|
||||
label = "Roll lethargy dice"
|
||||
}
|
||||
buttons.push({
|
||||
action: "roll",
|
||||
label: label,
|
||||
callback: (event, button, dialog) => {
|
||||
let pos = $('#combat-action-dialog').position()
|
||||
game.user.setFlag(SYSTEM.id, "combat-action-dialog-pos", foundry.utils.duplicate(pos))
|
||||
return "rollLethargyDice"
|
||||
},
|
||||
})
|
||||
@ -674,6 +698,8 @@ export default class LethalFantasyRoll extends Roll {
|
||||
action: "roll",
|
||||
label: "Select action",
|
||||
callback: (event, button, dialog) => {
|
||||
let pos = $('#combat-action-dialog').position()
|
||||
game.user.setFlag(SYSTEM.id, "combat-action-dialog-pos", foundry.utils.duplicate(pos))
|
||||
const output = Array.from(button.form.elements).reduce((obj, input) => {
|
||||
if (input.name) obj[input.name] = input.value
|
||||
return obj
|
||||
@ -687,13 +713,17 @@ export default class LethalFantasyRoll extends Roll {
|
||||
action: "cancel",
|
||||
label: "Other action, not listed here",
|
||||
callback: (event, button, dialog) => {
|
||||
let pos = $('#combat-action-dialog').position()
|
||||
game.user.setFlag(SYSTEM.id, "combat-action-dialog-pos", foundry.utils.duplicate(pos))
|
||||
return null;
|
||||
}
|
||||
})
|
||||
|
||||
let rollContext = await foundry.applications.api.DialogV2.wait({
|
||||
window: { title: "Combat Action Dialog" },
|
||||
id: "combat-action-dialog",
|
||||
classes: ["lethalfantasy"],
|
||||
position,
|
||||
content,
|
||||
buttons,
|
||||
rejectClose: false // Click on Close button will not launch an error
|
||||
@ -854,178 +884,6 @@ export default class LethalFantasyRoll extends Roll {
|
||||
}
|
||||
}
|
||||
|
||||
/* ***********************************************************/
|
||||
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
|
||||
}
|
||||
|
||||
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: "Roll Progression Dice or Continue Loading",
|
||||
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: "cast",
|
||||
label: "Cast a spell/Miracle",
|
||||
callback: (event, button, dialog) => {
|
||||
return "casting"
|
||||
},
|
||||
},
|
||||
{
|
||||
action: "cancel",
|
||||
label: "Other action, no progression dice",
|
||||
callback: (event, button, dialog) => {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
],
|
||||
rejectClose: false // Click on Close button will not launch an error
|
||||
})
|
||||
|
||||
console.log("RollContext", dialogContext, rollContext)
|
||||
let combat = game.combats.get(options.combatId)
|
||||
let actor = game.actors.get(options.actorId)
|
||||
|
||||
if (rollContext === "casting") {
|
||||
combat.setCasting(options.combatantId)
|
||||
let message = `Starting casting a spell !`
|
||||
ChatMessage.create({ content: message, speaker: ChatMessage.getSpeaker({ actor: actor }) })
|
||||
return
|
||||
}
|
||||
|
||||
if (rollContext === null || !rollContext?.progressionDiceId) {
|
||||
c.resetCasting(options.combatantId)
|
||||
combat.resetProgression(options.combatantId)
|
||||
let message = `${actor.name} : Other action, progression reset`
|
||||
ChatMessage.create({ content: message, speaker: ChatMessage.getSpeaker({ actor: actor }) })
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
// Get the weapons from the actor items
|
||||
let rangedMode
|
||||
let searchId = rollContext.progressionDiceId
|
||||
if (searchId.match("simpleAim")) {
|
||||
searchId = searchId.replace("simpleAim", "")
|
||||
rangedMode = "simpleAim"
|
||||
}
|
||||
if (searchId.match("carefulAim")) {
|
||||
searchId = searchId.replace("carefulAim", "")
|
||||
rangedMode = "carefulAim"
|
||||
}
|
||||
if (searchId.match("focusedAim")) {
|
||||
searchId = searchId.replace("focusedAim", "")
|
||||
rangedMode = "focusedAim"
|
||||
}
|
||||
|
||||
if (searchId.match("spell")) {
|
||||
searchId = searchId.replace("spell", "")
|
||||
let spell = actor.items.find(i => i.type === "spell" && i.id === searchId)
|
||||
let dice = LethalFantasyUtils.getLethargyDice(spell.system.level)
|
||||
if (combat.isCasting(options.combatantId)) {
|
||||
if (options.rollProgressionCount <= spell.system.castingTime) {
|
||||
let message = `Spell casting time : ${spell.name}, count : ${options.rollProgressionCount}/${spell.system.castingTime}`
|
||||
ChatMessage.create({ content: message, speaker: ChatMessage.getSpeaker({ actor: actor }) })
|
||||
return
|
||||
}
|
||||
if (options.rollProgressionCount > spell.system.castingTime) {
|
||||
let message = `Spell ${spell.name} has been cast !`
|
||||
ChatMessage.create({ content: message, speaker: ChatMessage.getSpeaker({ actor: actor }) })
|
||||
combat.resetCasting(options.combatantId)
|
||||
combat.resetProgression(options.combatantId)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
let formula = dice
|
||||
let roll = new Roll(formula)
|
||||
await roll.evaluate()
|
||||
let max = roll.dice[0].faces - 1
|
||||
let toCompare = Math.min(options.rollProgressionCount, max)
|
||||
let message
|
||||
if (roll.total > toCompare) {
|
||||
message = `Spell Lethargy ongoing ... (${roll.total}/${toCompare}, spell level ${spell.system.level})`
|
||||
} else {
|
||||
combat.resetProgression(options.combatantId)
|
||||
message = `Spell Lethargy ended ! (${roll.total}/${toCompare}, spell level ${spell.system.level})<br>${actor.name} can return to normal actions.`
|
||||
}
|
||||
let msg = await roll.toMessage({ flavor: message }, { rollMode: rollContext.visibility })
|
||||
if (game?.dice3d) {
|
||||
await game.dice3d.waitFor3DAnimationByMessageID(msg.id)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
let weapon = actor.items.find(i => i.type === "weapon" && i.id === searchId)
|
||||
let formula = weapon.system.combatProgressionDice
|
||||
|
||||
let rangedLoad
|
||||
if (rangedMode) {
|
||||
let toSplit = weapon.system.speed[rangedMode]
|
||||
let split = toSplit.split("+")
|
||||
rangedLoad = Number(split[0]) || 0
|
||||
formula = split[1]
|
||||
console.log("Ranged Mode", rangedMode, rangedLoad, formula, options.rollProgressionCount)
|
||||
}
|
||||
|
||||
if (rangedLoad && options.rollProgressionCount <= rangedLoad) {
|
||||
let message = `Ranged weapon ${weapon.name} is loading, loading count : ${options.rollProgressionCount}/${rangedLoad}`
|
||||
ChatMessage.create({ content: message, speaker: ChatMessage.getSpeaker({ actor: actor }) })
|
||||
return
|
||||
}
|
||||
|
||||
let isMonster = actor.type === "monster"
|
||||
// Get the dice and roll it if
|
||||
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 })
|
||||
if (game?.dice3d) {
|
||||
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", { isMonster, 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", { isMonster, name: actor.name, weapon: weapon.name, roll: roll.total })
|
||||
ChatMessage.create({ content: message, speaker: ChatMessage.getSpeaker({ actor: actor }) })
|
||||
}
|
||||
}
|
||||
|
||||
/* ***********************************************************/
|
||||
static async promptRangedDefense(rollTarget) {
|
||||
|
||||
|
Reference in New Issue
Block a user