Implements actions management
All checks were successful
Release Creation / build (release) Successful in 53s
All checks were successful
Release Creation / build (release) Successful in 53s
This commit is contained in:
@ -232,32 +232,6 @@ export default class LethalFantasyCharacterSheet extends LethalFantasyActorSheet
|
||||
super._onRender();
|
||||
}
|
||||
|
||||
getBestWeaponClassSkill(skills, rollType, multiplier = 1.0) {
|
||||
let maxValue = 0
|
||||
let goodSkill = skills[0]
|
||||
for (let s of skills) {
|
||||
if (rollType === "weapon-attack") {
|
||||
if (s.system.weaponBonus.attack > maxValue) {
|
||||
maxValue = Number(s.system.weaponBonus.attack)
|
||||
goodSkill = s
|
||||
}
|
||||
}
|
||||
if (rollType === "weapon-defense") {
|
||||
if (s.system.weaponBonus.defense > maxValue) {
|
||||
maxValue = Number(s.system.weaponBonus.defense)
|
||||
goodSkill = s
|
||||
}
|
||||
}
|
||||
if (rollType.includes("weapon-damage")) {
|
||||
if (s.system.weaponBonus.damage > maxValue) {
|
||||
maxValue = Number(s.system.weaponBonus.damage)
|
||||
goodSkill = s
|
||||
}
|
||||
}
|
||||
}
|
||||
goodSkill.weaponSkillModifier = maxValue * multiplier
|
||||
return goodSkill
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the roll action triggered by user interaction.
|
||||
@ -277,118 +251,11 @@ export default class LethalFantasyCharacterSheet extends LethalFantasyActorSheet
|
||||
async _onRoll(event, target) {
|
||||
if (this.isEditMode) return
|
||||
const rollType = event.target.dataset.rollType
|
||||
let rollTarget
|
||||
let rollKey = event.target.dataset.rollKey
|
||||
switch (rollType) {
|
||||
case "granted":
|
||||
rollTarget = {
|
||||
name: rollKey,
|
||||
formula: foundry.utils.duplicate(this.document.system.granted[rollKey]),
|
||||
rollKey: rollKey
|
||||
}
|
||||
if ( rollTarget.formula === "" || rollTarget.formula === undefined) {
|
||||
rollTarget.formula = 0
|
||||
}
|
||||
break;
|
||||
case "challenge":
|
||||
rollTarget = foundry.utils.duplicate(this.document.system.challenges[rollKey])
|
||||
rollTarget.rollKey = rollKey
|
||||
break
|
||||
case "save":
|
||||
rollTarget = foundry.utils.duplicate(this.document.system.saves[rollKey])
|
||||
rollTarget.rollKey = rollKey
|
||||
rollTarget.rollDice = event.target.dataset?.rollDice
|
||||
break
|
||||
case "spell":
|
||||
rollTarget = this.actor.items.find((i) => i.type === "spell" && i.id === rollKey)
|
||||
rollTarget.rollKey = rollKey
|
||||
break
|
||||
case "miracle":
|
||||
rollTarget = this.actor.items.find((i) => i.type === "miracle" && i.id === rollKey)
|
||||
rollTarget.rollKey = rollKey
|
||||
break
|
||||
case "skill":
|
||||
rollTarget = this.actor.items.find((i) => i.type === "skill" && i.id === rollKey)
|
||||
rollTarget.rollKey = rollKey
|
||||
if (rollTarget.system.category === "weapon") {
|
||||
ui.notifications.warn(game.i18n.localize("LETHALFANTASY.Notifications.rollFromWeapon"))
|
||||
return
|
||||
}
|
||||
break
|
||||
case "miracle-attack":
|
||||
case "miracle-power":
|
||||
rollTarget = this.actor.items.find((i) => i.type === "miracle" && i.id === rollKey)
|
||||
rollTarget.rollKey = rollKey
|
||||
break
|
||||
case "spell-attack":
|
||||
case "spell-power":
|
||||
rollTarget = this.actor.items.find((i) => i.type === "spell" && i.id === rollKey)
|
||||
rollTarget.rollKey = rollKey
|
||||
break
|
||||
case "shield-roll":
|
||||
rollTarget = this.actor.items.find((i) => i.type === "shield" && i.id === rollKey)
|
||||
let shieldSkill = this.actor.items.find((i) => i.type === "skill" && i.name.toLowerCase() === rollTarget.name.toLowerCase())
|
||||
rollTarget.skill = shieldSkill
|
||||
rollTarget.rollKey = rollKey
|
||||
break;
|
||||
case "weapon-damage-small":
|
||||
case "weapon-damage-medium":
|
||||
case "weapon-attack":
|
||||
case "weapon-defense":
|
||||
let weapon = this.actor.items.find((i) => i.type === "weapon" && i.id === rollKey)
|
||||
let skill
|
||||
let skills = this.actor.items.filter((i) => i.type === "skill" && i.name.toLowerCase() === weapon.name.toLowerCase())
|
||||
if (skills.length > 0) {
|
||||
skill = this.getBestWeaponClassSkill(skills, rollType, 1.0)
|
||||
} else {
|
||||
skills = this.actor.items.filter((i) => i.type === "skill" && i.name.toLowerCase().replace(" skill", "") === weapon.name.toLowerCase())
|
||||
if (skills.length > 0) {
|
||||
skill = this.getBestWeaponClassSkill(skills, rollType, 1.0)
|
||||
} else {
|
||||
skills = this.actor.items.filter((i) => i.type === "skill" && i.system.weaponClass === weapon.system.weaponClass)
|
||||
if (skills.length > 0) {
|
||||
skill = this.getBestWeaponClassSkill(skills, rollType, 0.5)
|
||||
} else {
|
||||
skills = this.actor.items.filter((i) => i.type === "skill" && i.system.weaponClass.includes(SYSTEM.WEAPON_CATEGORIES[weapon.system.weaponClass]))
|
||||
if (skills.length > 0) {
|
||||
skill = this.getBestWeaponClassSkill(skills, rollType, 0.25)
|
||||
} else {
|
||||
ui.notifications.warn(game.i18n.localize("LETHALFANTASY.Notifications.skillNotFound"))
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!weapon || !skill) {
|
||||
console.error("Weapon or skill not found", weapon, skill)
|
||||
ui.notifications.warn(game.i18n.localize("LETHALFANTASY.Notifications.skillNotFound"))
|
||||
return
|
||||
}
|
||||
rollTarget = skill
|
||||
rollTarget.weapon = weapon
|
||||
rollTarget.weaponSkillModifier = skill.weaponSkillModifier
|
||||
rollTarget.rollKey = rollKey
|
||||
rollTarget.combat = foundry.utils.duplicate(this.actor.system.combat)
|
||||
if ( rollType === "weapon-damage-small" || rollType === "weapon-damage-medium") {
|
||||
rollTarget.grantedDice = this.actor.system.granted.damageDice
|
||||
}
|
||||
if ( rollType === "weapon-attack") {
|
||||
rollTarget.grantedDice = this.actor.system.granted.attackDice
|
||||
}
|
||||
if ( rollType === "weapon-defense") {
|
||||
rollTarget.grantedDice = this.actor.system.granted.defenseDice
|
||||
}
|
||||
break
|
||||
default:
|
||||
ui.notifications.error(game.i18n.localize("LETHALFANTASY.Notifications.rollTypeNotFound") + String(rollType))
|
||||
break
|
||||
}
|
||||
let rollKey = event.target.dataset.rollKey;
|
||||
let rollDice = event.target.dataset?.rollDice;
|
||||
|
||||
this.actor.prepareRoll(rollType, rollKey, rollDice)
|
||||
|
||||
// In all cases
|
||||
rollTarget.magicUser = this.actor.system.biodata.magicUser
|
||||
rollTarget.actorModifiers = foundry.utils.duplicate(this.actor.system.modifiers)
|
||||
rollTarget.actorLevel = this.actor.system.biodata.level
|
||||
await this.document.system.roll(rollType, rollTarget)
|
||||
}
|
||||
// #endregion
|
||||
}
|
||||
|
@ -41,4 +41,144 @@ export default class LethalFantasyActor extends Actor {
|
||||
}
|
||||
}
|
||||
|
||||
getBestWeaponClassSkill(skills, rollType, multiplier = 1.0) {
|
||||
let maxValue = 0
|
||||
let goodSkill = skills[0]
|
||||
for (let s of skills) {
|
||||
if (rollType === "weapon-attack") {
|
||||
if (s.system.weaponBonus.attack > maxValue) {
|
||||
maxValue = Number(s.system.weaponBonus.attack)
|
||||
goodSkill = s
|
||||
}
|
||||
}
|
||||
if (rollType === "weapon-defense") {
|
||||
if (s.system.weaponBonus.defense > maxValue) {
|
||||
maxValue = Number(s.system.weaponBonus.defense)
|
||||
goodSkill = s
|
||||
}
|
||||
}
|
||||
if (rollType.includes("weapon-damage")) {
|
||||
if (s.system.weaponBonus.damage > maxValue) {
|
||||
maxValue = Number(s.system.weaponBonus.damage)
|
||||
goodSkill = s
|
||||
}
|
||||
}
|
||||
}
|
||||
goodSkill.weaponSkillModifier = maxValue * multiplier
|
||||
return goodSkill
|
||||
}
|
||||
|
||||
async prepareRoll(rollType, rollKey, rollDice ) {
|
||||
let rollTarget
|
||||
switch (rollType) {
|
||||
case "granted":
|
||||
rollTarget = {
|
||||
name: rollKey,
|
||||
formula: foundry.utils.duplicate(this.system.granted[rollKey]),
|
||||
rollKey: rollKey
|
||||
}
|
||||
if ( rollTarget.formula === "" || rollTarget.formula === undefined) {
|
||||
rollTarget.formula = 0
|
||||
}
|
||||
break;
|
||||
case "challenge":
|
||||
rollTarget = foundry.utils.duplicate(this.system.challenges[rollKey])
|
||||
rollTarget.rollKey = rollKey
|
||||
break
|
||||
case "save":
|
||||
rollTarget = foundry.utils.duplicate(this.system.saves[rollKey])
|
||||
rollTarget.rollKey = rollKey
|
||||
rollTarget.rollDice = rollDice
|
||||
break
|
||||
case "spell":
|
||||
rollTarget = this.items.find((i) => i.type === "spell" && i.id === rollKey)
|
||||
rollTarget.rollKey = rollKey
|
||||
break
|
||||
case "miracle":
|
||||
rollTarget = this.items.find((i) => i.type === "miracle" && i.id === rollKey)
|
||||
rollTarget.rollKey = rollKey
|
||||
break
|
||||
case "skill":
|
||||
rollTarget = this.items.find((i) => i.type === "skill" && i.id === rollKey)
|
||||
rollTarget.rollKey = rollKey
|
||||
if (rollTarget.system.category === "weapon") {
|
||||
ui.notifications.warn(game.i18n.localize("LETHALFANTASY.Notifications.rollFromWeapon"))
|
||||
return
|
||||
}
|
||||
break
|
||||
case "spell-attack":
|
||||
case "spell-power":
|
||||
case "miracle-attack":
|
||||
case "miracle-power":
|
||||
rollTarget = this.items.find((i) => (i.type === "miracle" || i.type == "spell") && i.id === rollKey)
|
||||
rollTarget.rollKey = rollKey
|
||||
break
|
||||
case "shield-roll": {
|
||||
rollTarget = this.items.find((i) => i.type === "shield" && i.id === rollKey)
|
||||
let shieldSkill = this.items.find((i) => i.type === "skill" && i.name.toLowerCase() === rollTarget.name.toLowerCase())
|
||||
rollTarget.skill = shieldSkill
|
||||
rollTarget.rollKey = rollKey
|
||||
}
|
||||
break;
|
||||
case "weapon-damage-small":
|
||||
case "weapon-damage-medium":
|
||||
case "weapon-attack":
|
||||
case "weapon-defense": {
|
||||
let weapon = this.items.find((i) => i.type === "weapon" && i.id === rollKey)
|
||||
let skill
|
||||
let skills = this.items.filter((i) => i.type === "skill" && i.name.toLowerCase() === weapon.name.toLowerCase())
|
||||
if (skills.length > 0) {
|
||||
skill = this.getBestWeaponClassSkill(skills, rollType, 1.0)
|
||||
} else {
|
||||
skills = this.items.filter((i) => i.type === "skill" && i.name.toLowerCase().replace(" skill", "") === weapon.name.toLowerCase())
|
||||
if (skills.length > 0) {
|
||||
skill = this.getBestWeaponClassSkill(skills, rollType, 1.0)
|
||||
} else {
|
||||
skills = this.items.filter((i) => i.type === "skill" && i.system.weaponClass === weapon.system.weaponClass)
|
||||
if (skills.length > 0) {
|
||||
skill = this.getBestWeaponClassSkill(skills, rollType, 0.5)
|
||||
} else {
|
||||
skills = this.items.filter((i) => i.type === "skill" && i.system.weaponClass.includes(SYSTEM.WEAPON_CATEGORIES[weapon.system.weaponClass]))
|
||||
if (skills.length > 0) {
|
||||
skill = this.getBestWeaponClassSkill(skills, rollType, 0.25)
|
||||
} else {
|
||||
ui.notifications.warn(game.i18n.localize("LETHALFANTASY.Notifications.skillNotFound"))
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!weapon || !skill) {
|
||||
console.error("Weapon or skill not found", weapon, skill)
|
||||
ui.notifications.warn(game.i18n.localize("LETHALFANTASY.Notifications.skillNotFound"))
|
||||
return
|
||||
}
|
||||
rollTarget = skill
|
||||
rollTarget.weapon = weapon
|
||||
rollTarget.weaponSkillModifier = skill.weaponSkillModifier
|
||||
rollTarget.rollKey = rollKey
|
||||
rollTarget.combat = foundry.utils.duplicate(this.system.combat)
|
||||
if ( rollType === "weapon-damage-small" || rollType === "weapon-damage-medium") {
|
||||
rollTarget.grantedDice = this.system.granted.damageDice
|
||||
}
|
||||
if ( rollType === "weapon-attack") {
|
||||
rollTarget.grantedDice = this.system.granted.attackDice
|
||||
}
|
||||
if ( rollType === "weapon-defense") {
|
||||
rollTarget.grantedDice = this.system.granted.defenseDice
|
||||
}
|
||||
}
|
||||
break
|
||||
default:
|
||||
ui.notifications.error(game.i18n.localize("LETHALFANTASY.Notifications.rollTypeNotFound") + String(rollType))
|
||||
break
|
||||
}
|
||||
|
||||
// In all cases
|
||||
rollTarget.magicUser = this.system.biodata.magicUser
|
||||
rollTarget.actorModifiers = foundry.utils.duplicate(this.system.modifiers)
|
||||
rollTarget.actorLevel = this.system.biodata.level
|
||||
await this.system.roll(rollType, rollTarget)
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -247,7 +247,7 @@ export default class LethalFantasyRoll extends Roll {
|
||||
hasChangeDice = false
|
||||
hasMaxValue = false
|
||||
hasExplode = false
|
||||
options.rollTarget.value = 0
|
||||
options.rollTarget.value = 0
|
||||
|
||||
} else if (options.rollType.includes("weapon-damage")) {
|
||||
options.rollName = options.rollTarget.name
|
||||
@ -602,6 +602,230 @@ export default class LethalFantasyRoll extends Roll {
|
||||
|
||||
}
|
||||
|
||||
static async promptCombatAction(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 combatant = game.combats.get(options.combatId)?.combatants?.get(options.combatantId)
|
||||
if (!combatant) {
|
||||
console.error("No combatant found for this combat")
|
||||
return
|
||||
}
|
||||
let currentAction = combatant.getFlag(SYSTEM.id, "currentAction")
|
||||
|
||||
let dialogContext = {
|
||||
progressionDiceId: "",
|
||||
fieldRollMode,
|
||||
rollModes,
|
||||
currentAction,
|
||||
...options
|
||||
}
|
||||
|
||||
const content = await renderTemplate("systems/fvtt-lethal-fantasy/templates/combat-action-dialog.hbs", dialogContext)
|
||||
|
||||
let buttons = []
|
||||
if (currentAction) {
|
||||
if (currentAction.type === "weapon") {
|
||||
buttons.push({
|
||||
action: "roll",
|
||||
label: "Roll progression dice",
|
||||
callback: (event, button, dialog) => {
|
||||
return "rollProgressionDice"
|
||||
},
|
||||
})
|
||||
} else if (currentAction.type === "spell" || currentAction.type === "miracle") {
|
||||
let label = ""
|
||||
if ( currentAction.castingDone) {
|
||||
label = "Roll lethargy dice"
|
||||
} else {
|
||||
label = "Wait casting time"
|
||||
}
|
||||
buttons.push({
|
||||
action: "roll",
|
||||
label: label,
|
||||
callback: (event, button, dialog) => {
|
||||
return "rollLethargyDice"
|
||||
},
|
||||
})
|
||||
}
|
||||
} else {
|
||||
buttons.push({
|
||||
action: "roll",
|
||||
label: "Select action",
|
||||
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
|
||||
},
|
||||
},
|
||||
)
|
||||
}
|
||||
buttons.push({
|
||||
action: "cancel",
|
||||
label: "Other action, not listed here",
|
||||
callback: (event, button, dialog) => {
|
||||
return null;
|
||||
}
|
||||
})
|
||||
|
||||
const rollContext = await foundry.applications.api.DialogV2.wait({
|
||||
window: { title: "Combat Action Dialog" },
|
||||
classes: ["lethalfantasy"],
|
||||
content,
|
||||
buttons,
|
||||
rejectClose: false // Click on Close button will not launch an error
|
||||
})
|
||||
|
||||
console.log("RollContext", dialogContext, rollContext)
|
||||
// If action is cancelled, exit
|
||||
if (rollContext === null || rollContext === "cancel") {
|
||||
await combatant.setFlag(SYSTEM.id, "currentAction", "")
|
||||
let message = `${combatant.name} : Other action, progression reset`
|
||||
ChatMessage.create({ content: message, speaker: ChatMessage.getSpeaker({ actor: combatant.actor }) })
|
||||
return
|
||||
}
|
||||
|
||||
// Setup the current action
|
||||
if (!currentAction || currentAction === "") {
|
||||
// Get the item from the returned selectedChoice value
|
||||
let selectedChoice = rollContext.selectedChoice
|
||||
let rangedMode
|
||||
if (selectedChoice.match("simpleAim")) {
|
||||
selectedChoice = selectedChoice.replace("simpleAim", "")
|
||||
rangedMode = "simpleAim"
|
||||
}
|
||||
if (selectedChoice.match("carefulAim")) {
|
||||
selectedChoice = selectedChoice.replace("carefulAim", "")
|
||||
rangedMode = "carefulAim"
|
||||
}
|
||||
if (selectedChoice.match("focusedAim")) {
|
||||
selectedChoice = selectedChoice.replace("focusedAim", "")
|
||||
rangedMode = "focusedAim"
|
||||
}
|
||||
let selectedItem = combatant.actor.items.find(i => i.id === selectedChoice)
|
||||
// Setup flag for combat action usage
|
||||
let actionItem = foundry.utils.duplicate(selectedItem)
|
||||
actionItem.progressionCount = 1
|
||||
actionItem.rangedMode = rangedMode
|
||||
actionItem.castingTime = 1
|
||||
actionItem.castingDone = false
|
||||
// Set the flag on the combatant
|
||||
await combatant.setFlag(SYSTEM.id, "currentAction", actionItem)
|
||||
let message = `${combatant.name} action : ${selectedItem.name}`
|
||||
ChatMessage.create({ content: message, speaker: ChatMessage.getSpeaker({ actor: combatant.actor }) })
|
||||
|
||||
combatant.actor.prepareRoll(actionItem.type === "weapon" ? "weapon-attack" : "spell-attack", selectedChoice)
|
||||
return
|
||||
}
|
||||
|
||||
if (currentAction) {
|
||||
if (rollContext === "rollLethargyDice") {
|
||||
if ( !currentAction.castingDone) {
|
||||
if ( currentAction.castingTime <= currentAction.system.castingTime) {
|
||||
let message = `Casting time : ${currentAction.name}, count : ${currentAction.castingTime}/${currentAction.system.castingTime}`
|
||||
ChatMessage.create({ content: message, speaker: ChatMessage.getSpeaker({ actor: combatant.actor }) })
|
||||
currentAction.castingTime += 1
|
||||
await combatant.setFlag(SYSTEM.id, "currentAction", foundry.utils.duplicate(currentAction))
|
||||
return
|
||||
} else {
|
||||
let message = `Spell ${currentAction.name} has ben casted !`
|
||||
ChatMessage.create({ content: message, speaker: ChatMessage.getSpeaker({ actor: combatant.actor }) })
|
||||
currentAction.castingTime = 1
|
||||
currentAction.castingDone = true
|
||||
await combatant.setFlag(SYSTEM.id, "currentAction", foundry.utils.duplicate(currentAction))
|
||||
return
|
||||
}
|
||||
} else {
|
||||
// Roll lethargy dice
|
||||
let dice = LethalFantasyUtils.getLethargyDice(currentAction.system.level)
|
||||
let roll = new Roll(dice)
|
||||
await roll.evaluate()
|
||||
let max = roll.dice[0].faces - 1
|
||||
let toCompare = Math.min(options.rollProgressionCount, max)
|
||||
if (roll.total <= toCompare) {
|
||||
// Notify that the player can act now with a chat message
|
||||
let message = game.i18n.format("LETHALFANTASY.Notifications.messageLethargyOK", { name: combatant.actor.name, weapon: currentAction.name, roll: roll.total })
|
||||
ChatMessage.create({ content: message, speaker: ChatMessage.getSpeaker({ actor: combatant.actor }) })
|
||||
// Update the combatant progression count
|
||||
await combatant.setFlag(SYSTEM.id, "currentAction", "")
|
||||
// Display the action selection window again
|
||||
combatant.actor.system.rollProgressionDice(options.combatId, options.combatantId )
|
||||
} else {
|
||||
// Notify that the player cannot act now with a chat message
|
||||
currentAction.progressionCount += 1
|
||||
combatant.setFlag(SYSTEM.id, "currentAction", foundry.utils.duplicate(currentAction))
|
||||
let message = game.i18n.format("LETHALFANTASY.Notifications.messageLethargyKO", { name: combatant.actor.name, weapon: currentAction.name, roll: roll.total })
|
||||
ChatMessage.create({ content: message, speaker: ChatMessage.getSpeaker({ actor: combatant.actor }) })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (rollContext === "rollProgressionDice") {
|
||||
let formula = currentAction.system.combatProgressionDice
|
||||
if (currentAction?.rangedMode) {
|
||||
let toSplit = currentAction.system.speed[currentAction.rangedMode]
|
||||
let split = toSplit.split("+")
|
||||
currentAction.rangedLoad = Number(split[0]) || 0
|
||||
formula = split[1]
|
||||
console.log("Ranged Mode", currentAction.rangedMode, currentAction.rangedLoad, formula)
|
||||
}
|
||||
// Range weapon loading
|
||||
if (!currentAction.weaponLoaded && currentAction.rangedLoad) {
|
||||
if (currentAction.progressionCount <= currentAction.rangedLoad) {
|
||||
let message = `Ranged weapon ${currentAction.name} is loading, loading count : ${currentAction.progressionCount}/${currentAction.rangedLoad}`
|
||||
ChatMessage.create({ content: message, speaker: ChatMessage.getSpeaker({ actor: combatant.actor }) })
|
||||
currentAction.progressionCount += 1
|
||||
await combatant.setFlag(SYSTEM.id, "currentAction", foundry.utils.duplicate(currentAction))
|
||||
} else {
|
||||
let message = `Ranged weapon ${currentAction.name} is loaded !`
|
||||
ChatMessage.create({ content: message, speaker: ChatMessage.getSpeaker({ actor: combatant.actor }) })
|
||||
currentAction.weaponLoaded = true
|
||||
currentAction.progressionCount = 1
|
||||
await combatant.setFlag(SYSTEM.id, "currentAction", foundry.utils.duplicate(currentAction))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Melee mode
|
||||
let isMonster = combatant.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(currentAction.progressionCount, max)
|
||||
let msg = await roll.toMessage({ flavor: `Progression Roll for ${currentAction.name}, progression count : ${currentAction.progressionCount}/${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: combatant.actor.name, weapon: currentAction.name, roll: roll.total })
|
||||
ChatMessage.create({ content: message, speaker: ChatMessage.getSpeaker({ actor: combatant.actor }) })
|
||||
// Update the combatant progression count
|
||||
await combatant.setFlag(SYSTEM.id, "currentAction", "")
|
||||
// Display the action selection window again
|
||||
combatant.actor.system.rollProgressionDice(options.combatId, options.combatantId )
|
||||
} else {
|
||||
// Notify that the player cannot act now with a chat message
|
||||
currentAction.progressionCount += 1
|
||||
combatant.setFlag(SYSTEM.id, "currentAction", foundry.utils.duplicate(currentAction))
|
||||
let message = game.i18n.format("LETHALFANTASY.Notifications.messageProgressionKO", { isMonster, name: combatant.actor.name, weapon: currentAction.name, roll: roll.total })
|
||||
ChatMessage.create({ content: message, speaker: ChatMessage.getSpeaker({ actor: combatant.actor }) })
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static async promptProgressionDice(options = {}) {
|
||||
|
||||
const rollModes = Object.fromEntries(Object.entries(CONFIG.Dice.rollModes).map(([key, value]) => [key, game.i18n.localize(value)]))
|
||||
@ -654,11 +878,11 @@ export default class LethalFantasyRoll extends Roll {
|
||||
rejectClose: false // Click on Close button will not launch an error
|
||||
})
|
||||
|
||||
console.log("RollContext", dialogContext,rollContext)
|
||||
console.log("RollContext", dialogContext, rollContext)
|
||||
let combat = game.combats.get(options.combatId)
|
||||
let actor = game.actors.get(options.actorId)
|
||||
|
||||
if ( rollContext === "casting") {
|
||||
if (rollContext === "casting") {
|
||||
combat.setCasting(options.combatantId)
|
||||
let message = `Starting casting a spell !`
|
||||
ChatMessage.create({ content: message, speaker: ChatMessage.getSpeaker({ actor: actor }) })
|
||||
@ -677,25 +901,25 @@ export default class LethalFantasyRoll extends Roll {
|
||||
// Get the weapons from the actor items
|
||||
let rangedMode
|
||||
let searchId = rollContext.progressionDiceId
|
||||
if ( searchId.match("simpleAim")) {
|
||||
if (searchId.match("simpleAim")) {
|
||||
searchId = searchId.replace("simpleAim", "")
|
||||
rangedMode = "simpleAim"
|
||||
rangedMode = "simpleAim"
|
||||
}
|
||||
if ( searchId.match("carefulAim")) {
|
||||
if (searchId.match("carefulAim")) {
|
||||
searchId = searchId.replace("carefulAim", "")
|
||||
rangedMode = "carefulAim"
|
||||
rangedMode = "carefulAim"
|
||||
}
|
||||
if ( searchId.match("focusedAim")) {
|
||||
if (searchId.match("focusedAim")) {
|
||||
searchId = searchId.replace("focusedAim", "")
|
||||
rangedMode = "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)
|
||||
let dice = LethalFantasyUtils.getLethargyDice(spell.system.level)
|
||||
if (combat.isCasting(options.combatantId)) {
|
||||
if (options.rollProgressionCount <= spell.system.castingTime ) {
|
||||
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
|
||||
@ -707,7 +931,7 @@ export default class LethalFantasyRoll extends Roll {
|
||||
combat.resetProgression(options.combatantId)
|
||||
return
|
||||
}
|
||||
} else{
|
||||
} else {
|
||||
let formula = dice
|
||||
let roll = new Roll(formula)
|
||||
await roll.evaluate()
|
||||
@ -740,7 +964,7 @@ export default class LethalFantasyRoll extends Roll {
|
||||
console.log("Ranged Mode", rangedMode, rangedLoad, formula, options.rollProgressionCount)
|
||||
}
|
||||
|
||||
if (rangedLoad && options.rollProgressionCount <= rangedLoad ) {
|
||||
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
|
||||
|
@ -73,7 +73,7 @@ export default class LethalFantasyCharacter extends foundry.abstract.TypeDataMod
|
||||
{ description: "", value: 0, duration: 0 }, { description: "", value: 0, duration: 0 }, { description: "", value: 0, duration: 0 }, { description: "", value: 0, duration: 0 },
|
||||
{ description: "", value: 0, duration: 0 }, { description: "", value: 0, duration: 0 }], min: 8
|
||||
}),
|
||||
damageResistance: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 })
|
||||
damageResistance: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 })
|
||||
})
|
||||
|
||||
schema.perception = new fields.SchemaField({
|
||||
@ -299,11 +299,11 @@ export default class LethalFantasyCharacter extends foundry.abstract.TypeDataMod
|
||||
let spells = this.parent.items.filter(i => i.type === "spell" || i.type === "miracle")
|
||||
for (let s of spells) {
|
||||
let dice = LethalFantasyUtils.getLethargyDice(s.system.level)
|
||||
weaponsChoices.push({ id: `spell${s.id}`, name: `${s.name} (Time: ${s.system.castingTime}, Lethargy: ${dice})`, combatProgressionDice: `${s.system.castingTime}+${dice}` })
|
||||
weaponsChoices.push({ id: s.id, name: `${s.name} (Time: ${s.system.castingTime}, Lethargy: ${dice})`, combatProgressionDice: `${s.system.castingTime}+${dice}` })
|
||||
}
|
||||
}
|
||||
|
||||
let roll = await LethalFantasyRoll.promptProgressionDice({
|
||||
let roll = await LethalFantasyRoll.promptCombatAction({
|
||||
actorId: this.parent.id,
|
||||
actorName: this.parent.name,
|
||||
actorImage: this.parent.img,
|
||||
|
Reference in New Issue
Block a user