2021-12-25 23:26:27 +01:00
|
|
|
import { BoLUtility } from "../system/bol-utility.js";
|
|
|
|
|
2022-01-17 23:50:57 +01:00
|
|
|
const _apt2attr = { init: "mind", melee: "agility", ranged: "agility", def: "vigor" }
|
2022-01-16 22:53:41 +01:00
|
|
|
|
2022-03-10 21:05:53 +01:00
|
|
|
/* -------------------------------------------- */
|
2021-12-22 05:12:40 +01:00
|
|
|
export class BoLRoll {
|
2022-03-27 12:42:29 +02:00
|
|
|
|
2022-03-10 21:05:53 +01:00
|
|
|
/* -------------------------------------------- */
|
2022-01-01 23:32:48 +01:00
|
|
|
static options() {
|
2022-11-19 19:22:16 +01:00
|
|
|
return { classes: ["bol", "dialog"], width: 480, height: 'fit-content' };
|
2022-01-01 23:32:48 +01:00
|
|
|
}
|
2021-12-22 05:12:40 +01:00
|
|
|
|
2022-03-10 21:05:53 +01:00
|
|
|
/* -------------------------------------------- */
|
2022-01-17 23:50:57 +01:00
|
|
|
static getDefaultAttribute(key) {
|
2022-01-16 22:53:41 +01:00
|
|
|
return _apt2attr[key]
|
|
|
|
}
|
2022-03-27 12:42:29 +02:00
|
|
|
|
2022-02-18 21:58:53 +01:00
|
|
|
/* -------------------------------------------- */
|
2022-11-23 21:34:51 +01:00
|
|
|
static updateApplicableEffects(rollData) {
|
|
|
|
let appEffects = []
|
2022-12-23 23:24:09 +01:00
|
|
|
for (let effect of rollData.bolEffects) {
|
2024-02-22 18:29:04 +01:00
|
|
|
if ( (effect.system.properties.identifier == "always") ||
|
|
|
|
(effect.system.properties.identifier.includes(rollData.attribute.key)) ||
|
|
|
|
(rollData.aptitude && effect.system.properties.identifier.includes(rollData.aptitude.key)) ){
|
2022-12-23 23:24:09 +01:00
|
|
|
appEffects.push(effect)
|
2022-11-23 21:34:51 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return appEffects
|
|
|
|
}
|
2022-03-10 21:05:53 +01:00
|
|
|
|
2022-12-25 18:00:42 +01:00
|
|
|
/* -------------------------------------------- */
|
|
|
|
static buildHoroscopeGroupList() {
|
|
|
|
let horoscopes = game.settings.get("bol", "horoscope-group")
|
2023-03-15 17:35:07 +01:00
|
|
|
let horoList = [{ id: -1, name: "Aucun", type: "malus", nbDice: 0 }]
|
2022-12-25 18:00:42 +01:00
|
|
|
for (let id in horoscopes) {
|
|
|
|
let horo = horoscopes[id]
|
2023-03-15 17:35:07 +01:00
|
|
|
for (let i = 0; i < horo.availableDice; i++) {
|
|
|
|
horoList.push({ id: id, name: horo.name, type: horo.type, nbDice: i + 1 })
|
2022-12-25 18:00:42 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return horoList
|
|
|
|
}
|
|
|
|
|
2022-11-23 21:34:51 +01:00
|
|
|
/* -------------------------------------------- */
|
2022-12-23 23:24:09 +01:00
|
|
|
static getCommonRollData(actor, mode, attribute, aptitude = undefined) {
|
2022-03-10 21:05:53 +01:00
|
|
|
|
|
|
|
let rollData = {
|
2022-11-23 21:34:51 +01:00
|
|
|
mode: mode,
|
2022-04-08 23:42:01 +02:00
|
|
|
actorId: actor.id,
|
2022-11-30 12:12:44 +01:00
|
|
|
tokenId: actor.token?.id,
|
2022-05-11 22:05:35 +02:00
|
|
|
img: actor.img,
|
2022-03-10 21:05:53 +01:00
|
|
|
attribute: attribute,
|
|
|
|
attrValue: attribute.value,
|
|
|
|
aptValue: 0,
|
|
|
|
careerBonus: 0,
|
2022-12-23 23:24:09 +01:00
|
|
|
horoscopeBonus: 0,
|
|
|
|
horoscopeMalus: 0,
|
|
|
|
selectedHoroscope: [],
|
2022-03-27 12:42:29 +02:00
|
|
|
armorAgiMalus: actor.getArmorAgiMalus(),
|
2022-03-27 22:56:43 +02:00
|
|
|
armorInitMalus: actor.getArmorInitMalus(),
|
2022-12-23 23:24:09 +01:00
|
|
|
horoscopeBonusList: actor.getHoroscopesBonus(),
|
|
|
|
horoscopeMalusList: actor.getHoroscopesMalus(),
|
2024-04-26 18:00:56 +02:00
|
|
|
config: game.bol.config,
|
2022-11-23 15:27:08 +01:00
|
|
|
adv: "0",
|
2022-11-23 21:34:51 +01:00
|
|
|
mod: 0,
|
|
|
|
modRanged: 0,
|
2022-12-25 18:00:42 +01:00
|
|
|
bolEffects: actor.boleffects,
|
|
|
|
horoscopeGroupList: this.buildHoroscopeGroupList()
|
2022-11-23 21:34:51 +01:00
|
|
|
}
|
|
|
|
if (aptitude) {
|
|
|
|
rollData.aptitude = aptitude
|
|
|
|
rollData.aptValue = aptitude.value
|
2022-03-10 21:05:53 +01:00
|
|
|
}
|
2022-11-23 21:34:51 +01:00
|
|
|
rollData.bolApplicableEffects = this.updateApplicableEffects(rollData)
|
|
|
|
return rollData
|
|
|
|
}
|
|
|
|
|
|
|
|
/* -------------------------------------------- */
|
2024-01-02 23:34:38 +01:00
|
|
|
static attributeCheck(actor, key="vigor", event=undefined, combatData=undefined) {
|
2022-11-23 21:34:51 +01:00
|
|
|
|
|
|
|
let attribute = eval(`actor.system.attributes.${key}`)
|
2022-12-23 23:24:09 +01:00
|
|
|
|
2022-11-23 21:34:51 +01:00
|
|
|
let rollData = this.getCommonRollData(actor, "attribute", attribute)
|
|
|
|
rollData.description = game.i18n.localize('BOL.ui.attributeCheck') + " - " + game.i18n.localize(attribute.label)
|
|
|
|
rollData.label = (attribute.label) ? game.i18n.localize(attribute.label) : null
|
|
|
|
|
2022-04-08 23:42:01 +02:00
|
|
|
console.log(">>>>>>>>>>", rollData, actor)
|
2022-03-27 12:42:29 +02:00
|
|
|
return this.displayRollDialog(rollData)
|
2022-01-01 23:32:48 +01:00
|
|
|
}
|
2021-12-22 05:12:40 +01:00
|
|
|
|
2022-02-18 21:58:53 +01:00
|
|
|
/* -------------------------------------------- */
|
2024-01-02 23:34:38 +01:00
|
|
|
static aptitudeCheck(actor, key="init", event=undefined, combatData=undefined) {
|
2022-01-16 22:53:41 +01:00
|
|
|
|
2022-07-01 15:48:54 +02:00
|
|
|
let aptitude = eval(`actor.system.aptitudes.${key}`)
|
2022-01-16 22:53:41 +01:00
|
|
|
let attrKey = this.getDefaultAttribute(key)
|
2022-07-01 15:48:54 +02:00
|
|
|
let attribute = eval(`actor.system.attributes.${attrKey}`)
|
2022-01-16 22:53:41 +01:00
|
|
|
|
2022-11-23 21:34:51 +01:00
|
|
|
let rollData = this.getCommonRollData(actor, "aptitude", attribute, aptitude)
|
|
|
|
|
|
|
|
rollData.label = (aptitude.label) ? game.i18n.localize(aptitude.label) : null
|
|
|
|
rollData.description = game.i18n.localize('BOL.ui.aptitudeCheck') + " - " + game.i18n.localize(aptitude.label)
|
2023-03-15 17:35:07 +01:00
|
|
|
rollData.combatData = combatData // For initiative mainly
|
2022-11-23 21:34:51 +01:00
|
|
|
|
2022-12-23 23:24:09 +01:00
|
|
|
return this.displayRollDialog(rollData)
|
2021-12-25 23:26:27 +01:00
|
|
|
}
|
|
|
|
|
2022-10-08 17:43:09 +02:00
|
|
|
/* -------------------------------------------- */
|
2022-12-23 23:24:09 +01:00
|
|
|
static async detectDistance(weapon, target) {
|
2022-10-08 17:43:09 +02:00
|
|
|
let visible, dist
|
2022-12-25 18:00:42 +01:00
|
|
|
if (target && (weapon.system.properties.ranged || weapon.system.properties.throwing)) {
|
2022-10-08 17:43:09 +02:00
|
|
|
console.log("target", target, weapon)
|
|
|
|
visible = canvas.effects.visibility.testVisibility(target.center, { object: _token })
|
|
|
|
dist = Number(canvas.grid.measureDistances([{ ray: new Ray(_token.center, target.center) }], { gridSpaces: false })).toFixed(2)
|
|
|
|
let range = Number(weapon.system.properties.range)
|
|
|
|
let rangeMsg = "BOL.chat.rangeout"
|
2022-12-23 23:24:09 +01:00
|
|
|
if (dist <= range) {
|
2022-10-08 17:43:09 +02:00
|
|
|
rangeMsg = "BOL.chat.range0"
|
2022-12-23 23:24:09 +01:00
|
|
|
} else if (dist < range * 2) {
|
2022-10-08 17:43:09 +02:00
|
|
|
rangeMsg = "BOL.chat.range1"
|
2022-12-23 23:24:09 +01:00
|
|
|
} else if (dist < range * 3) {
|
2022-10-08 17:43:09 +02:00
|
|
|
rangeMsg = "BOL.chat.range2"
|
2022-12-23 23:24:09 +01:00
|
|
|
} else if (dist < range * 4) {
|
2022-10-08 17:43:09 +02:00
|
|
|
rangeMsg = "BOL.chat.range3"
|
2022-12-23 23:24:09 +01:00
|
|
|
} else if (dist < range * 5) {
|
2022-10-08 17:43:09 +02:00
|
|
|
rangeMsg = "BOL.chat.range4"
|
2022-12-23 23:24:09 +01:00
|
|
|
} else if (dist < range * 6) {
|
2022-10-08 17:43:09 +02:00
|
|
|
rangeMsg = "BOL.chat.range5"
|
2022-12-23 23:24:09 +01:00
|
|
|
} else if (dist < range * 7) {
|
2022-10-08 17:43:09 +02:00
|
|
|
rangeMsg = "BOL.chat.range6"
|
|
|
|
}
|
|
|
|
ChatMessage.create({
|
|
|
|
content: await renderTemplate('systems/bol/templates/chat/chat-info-range.hbs', {
|
|
|
|
weapon: weapon,
|
|
|
|
attackerName: _token.actor.name,
|
|
|
|
defenderName: target.actor.name,
|
|
|
|
weaponRange: weapon.system.properties.range,
|
|
|
|
visible: visible,
|
|
|
|
distance: dist,
|
|
|
|
rangeMsg: rangeMsg
|
|
|
|
})
|
|
|
|
})
|
2022-12-23 23:24:09 +01:00
|
|
|
}
|
2022-10-08 17:43:09 +02:00
|
|
|
}
|
|
|
|
|
2022-02-18 21:58:53 +01:00
|
|
|
/* -------------------------------------------- */
|
2022-03-21 23:21:05 +01:00
|
|
|
static weaponCheckWithWeapon(actor, weapon) {
|
2022-03-27 12:42:29 +02:00
|
|
|
|
2022-01-01 23:32:48 +01:00
|
|
|
let target = BoLUtility.getTarget()
|
2022-03-27 12:42:29 +02:00
|
|
|
|
2022-07-01 15:48:54 +02:00
|
|
|
let weaponData = weapon.system
|
|
|
|
let attribute = eval(`actor.system.attributes.${weaponData.properties.attackAttribute}`)
|
|
|
|
let aptitude = eval(`actor.system.aptitudes.${weaponData.properties.attackAptitude}`)
|
2022-03-27 12:42:29 +02:00
|
|
|
|
2022-11-23 21:34:51 +01:00
|
|
|
let rollData = this.getCommonRollData(actor, "weapon", attribute, aptitude)
|
|
|
|
|
2022-10-08 17:43:09 +02:00
|
|
|
// Compute distance
|
2022-12-23 23:24:09 +01:00
|
|
|
this.detectDistance(weapon, target)
|
2022-10-08 17:43:09 +02:00
|
|
|
|
2022-03-10 21:05:53 +01:00
|
|
|
// Manage specific case
|
2022-03-27 12:42:29 +02:00
|
|
|
let fightOption = actor.getActiveFightOption()
|
2023-06-22 23:05:04 +02:00
|
|
|
if (fightOption && fightOption.system.properties.fightoptiontype == "fulldefense") {
|
2022-03-10 21:05:53 +01:00
|
|
|
ui.notifications.warn(`{{actor.name}} est en Défense Totale ! Il ne peut pas attaquer ce round.`)
|
|
|
|
return
|
|
|
|
}
|
2022-12-23 23:24:09 +01:00
|
|
|
|
2022-11-23 21:34:51 +01:00
|
|
|
// Update the roll structure
|
2022-12-23 23:24:09 +01:00
|
|
|
rollData.weapon = weapon
|
2022-11-23 21:34:51 +01:00
|
|
|
rollData.isRanged = weaponData.properties.ranged || weaponData.properties.throwing
|
|
|
|
rollData.targetId = target?.id
|
|
|
|
rollData.fightOption = fightOption
|
2022-12-23 23:24:09 +01:00
|
|
|
rollData.defenderId = target?.actor.id
|
|
|
|
rollData.label = (weapon.name) ? weapon.name : game.i18n.localize('BOL.ui.noWeaponName')
|
2022-11-23 21:34:51 +01:00
|
|
|
rollData.description = game.i18n.localize('BOL.ui.weaponAttack') + " : " + weapon.name
|
|
|
|
|
|
|
|
return this.displayRollDialog(rollData)
|
2022-01-01 23:32:48 +01:00
|
|
|
}
|
2022-11-23 21:34:51 +01:00
|
|
|
|
2022-03-21 23:21:05 +01:00
|
|
|
/* -------------------------------------------- */
|
|
|
|
static weaponCheck(actor, event) {
|
|
|
|
const li = $(event.currentTarget).parents(".item")
|
2022-06-11 10:21:18 +02:00
|
|
|
let weapon = actor.items.get(li.data("item-id"))
|
2022-03-21 23:21:05 +01:00
|
|
|
if (!weapon) {
|
|
|
|
ui.notifications.warn("Unable to find weapon !")
|
|
|
|
return
|
|
|
|
}
|
2024-04-26 18:00:56 +02:00
|
|
|
weapon = foundry.utils.duplicate(weapon)
|
2022-03-21 23:21:05 +01:00
|
|
|
return this.weaponCheckWithWeapon(actor, weapon)
|
|
|
|
}
|
2021-12-22 05:12:40 +01:00
|
|
|
|
2022-02-18 21:58:53 +01:00
|
|
|
/* -------------------------------------------- */
|
2022-03-21 23:21:05 +01:00
|
|
|
static alchemyCheck(actor, event) {
|
2022-01-23 09:25:09 +01:00
|
|
|
const li = $(event.currentTarget).parents(".item");
|
2022-06-11 10:21:18 +02:00
|
|
|
let alchemy = actor.items.get(li.data("item-id"));
|
2022-01-23 09:25:09 +01:00
|
|
|
if (!alchemy) {
|
|
|
|
ui.notifications.warn("Unable to find Alchemy !");
|
|
|
|
return;
|
|
|
|
}
|
2024-04-26 18:00:56 +02:00
|
|
|
alchemy = foundry.utils.duplicate(alchemy)
|
2022-08-31 23:00:41 +02:00
|
|
|
let alchemyData = alchemy.system
|
2022-01-23 09:25:09 +01:00
|
|
|
if (alchemyData.properties.pccurrent < alchemyData.properties.pccost) {
|
2022-11-23 21:34:51 +01:00
|
|
|
ui.notifications.warn("Pas assez de Points de Création investis dans la Préparation !")
|
2022-01-23 09:25:09 +01:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2022-11-23 21:34:51 +01:00
|
|
|
let rollData = this.getCommonRollData(actor, "alchemy", actor.system.attributes.mind)
|
|
|
|
|
|
|
|
rollData.alchemy = alchemy
|
|
|
|
rollData.careerBonus = actor.getAlchemistBonus()
|
|
|
|
rollData.pcCost = Number(alchemyData.properties.pccost)
|
|
|
|
rollData.pcCostCurrent = Number(alchemyData.properties.pccurrent)
|
|
|
|
rollData.mod = Number(alchemyData.properties.difficulty)
|
|
|
|
rollData.label = alchemy.name
|
|
|
|
rollData.description = game.i18n.localize('BOL.ui.makeAlchemy') + "+" + alchemy.name
|
|
|
|
|
2022-12-23 23:24:09 +01:00
|
|
|
console.log("ALCHEMY!", rollData);
|
|
|
|
return this.displayRollDialog(rollData);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* -------------------------------------------- */
|
|
|
|
static horoscopeCheck(actor, event, horoscopeType) {
|
2023-04-29 21:48:51 +02:00
|
|
|
|
|
|
|
let target = BoLUtility.getTarget()
|
|
|
|
|
2023-03-15 17:35:07 +01:00
|
|
|
let cost = (horoscopeType == "minor") ? 1 : 2
|
|
|
|
if (cost > actor.getAstrologyPoints()) {
|
2022-12-25 18:00:42 +01:00
|
|
|
ui.notifications.warn(game.i18n.localize("BOL.ui.astrologyNoPoints"))
|
|
|
|
return
|
|
|
|
}
|
2022-12-23 23:24:09 +01:00
|
|
|
let rollData = this.getCommonRollData(actor, "horoscope", actor.system.attributes.mind)
|
|
|
|
|
|
|
|
rollData.careerBonus = actor.getAstrologerBonus()
|
|
|
|
rollData.horoscopeType = horoscopeType
|
2023-03-15 17:35:07 +01:00
|
|
|
rollData.horoscopeTypeLabel = "BOL.ui." + horoscopeType
|
2022-12-25 18:00:42 +01:00
|
|
|
rollData.astrologyPointsCost = cost
|
2022-12-23 23:24:09 +01:00
|
|
|
rollData.label = game.i18n.localize('BOL.ui.makeHoroscope')
|
|
|
|
rollData.description = game.i18n.localize('BOL.ui.makeHoroscope') + " " + game.i18n.localize(rollData.horoscopeTypeLabel)
|
2023-04-29 21:48:51 +02:00
|
|
|
rollData.targetId = target?.id
|
2022-12-23 23:24:09 +01:00
|
|
|
|
|
|
|
console.log("HOROSCOPE!", rollData);
|
|
|
|
return this.displayRollDialog(rollData);
|
2022-01-23 09:25:09 +01:00
|
|
|
}
|
|
|
|
|
2022-02-18 21:58:53 +01:00
|
|
|
/* -------------------------------------------- */
|
2022-12-23 23:24:09 +01:00
|
|
|
static spellCheckWithSpell(actor, spell) {
|
2022-11-23 21:34:51 +01:00
|
|
|
let rollData = this.getCommonRollData(actor, "spell", actor.system.attributes.mind)
|
|
|
|
|
|
|
|
rollData.spell = spell
|
|
|
|
rollData.ppCurrent = Number(actor.system.resources.power.value),
|
2022-12-23 23:24:09 +01:00
|
|
|
rollData.careerBonus = actor.getSorcererBonus(),
|
|
|
|
rollData.ppCostArmor = actor.getPPCostArmor(),
|
|
|
|
rollData.ppCost = Number(spell.system.properties.ppcost),
|
|
|
|
rollData.mod = Number(spell.system.properties.difficulty),
|
|
|
|
rollData.label = spell.name,
|
|
|
|
rollData.description = game.i18n.localize('BOL.ui.focusSpell') + " : " + spell.name
|
|
|
|
|
2022-06-11 20:56:35 +02:00
|
|
|
//console.log("SPELL!", spellDef)
|
2022-11-23 21:34:51 +01:00
|
|
|
return this.displayRollDialog(rollData)
|
2022-03-27 22:56:43 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* -------------------------------------------- */
|
|
|
|
static spellCheck(actor, event) {
|
2022-07-01 15:48:54 +02:00
|
|
|
if (actor.system.resources.power.value <= 0) {
|
2022-03-27 22:56:43 +02:00
|
|
|
ui.notifications.warn("Plus assez de points de Pouvoir !")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
const li = $(event.currentTarget).parents(".item")
|
2022-06-11 10:21:18 +02:00
|
|
|
let spell = actor.items.get(li.data("item-id"))
|
2022-03-27 22:56:43 +02:00
|
|
|
if (!spell) {
|
|
|
|
ui.notifications.warn("Impossible de trouver ce sort !")
|
|
|
|
return
|
|
|
|
}
|
2024-04-26 18:00:56 +02:00
|
|
|
spell = foundry.utils.duplicate(spell)
|
2022-12-23 23:24:09 +01:00
|
|
|
return this.spellCheckWithSpell(actor, spell)
|
2022-01-23 09:25:09 +01:00
|
|
|
}
|
|
|
|
|
2022-01-01 23:32:48 +01:00
|
|
|
/* -------------------------------------------- */
|
2022-02-18 21:58:53 +01:00
|
|
|
static updateTotalDice() {
|
2022-03-27 12:42:29 +02:00
|
|
|
|
|
|
|
this.updateArmorMalus(this.rollData)
|
|
|
|
this.updatePPCost(this.rollData)
|
|
|
|
|
2022-11-23 21:34:51 +01:00
|
|
|
// get basic dices from boons/flaws
|
|
|
|
let effectModifier = 0
|
2022-03-27 12:42:29 +02:00
|
|
|
this.rollData.bmDice = this.rollData.nbBoons - this.rollData.nbFlaws + this.rollData.bDice - this.rollData.mDice
|
2022-11-23 21:34:51 +01:00
|
|
|
// add applicable bonus/malus dices effects
|
|
|
|
for (let effect of this.rollData.bolApplicableEffects) {
|
|
|
|
if (effect.system.properties.modifier == "1B") {
|
|
|
|
this.rollData.bmDice++;
|
2023-04-06 20:15:04 +02:00
|
|
|
} else if (effect.system.properties.modifier == "2B") {
|
2022-12-23 23:24:09 +01:00
|
|
|
this.rollData.bmDice += 2;
|
2022-11-23 21:34:51 +01:00
|
|
|
} else if (effect.system.properties.modifier == "1M") {
|
|
|
|
this.rollData.bmDice--;
|
2022-12-23 23:24:09 +01:00
|
|
|
} else if (effect.system.properties.modifier == "2M") {
|
|
|
|
this.rollData.bmDice -= 2;
|
2022-11-23 21:34:51 +01:00
|
|
|
} else {
|
|
|
|
effectModifier += Number(effect.system.properties.modifier)
|
|
|
|
}
|
|
|
|
}
|
2022-12-23 23:24:09 +01:00
|
|
|
this.rollData.bmDice += this.rollData.horoscopeBonus
|
|
|
|
this.rollData.bmDice -= this.rollData.horoscopeMalus
|
2023-03-15 17:35:07 +01:00
|
|
|
if (this.rollData.selectedGroupHoroscopeIndex && this.rollData.selectedGroupHoroscopeIndex > 0) {
|
2022-12-25 18:00:42 +01:00
|
|
|
let horo = this.rollData.horoscopeGroupList[this.rollData.selectedGroupHoroscopeIndex]
|
|
|
|
this.rollData.bmDice += (horo.type == "malus") ? -horo.nbDice : horo.nbDice;
|
|
|
|
}
|
2022-11-23 21:34:51 +01:00
|
|
|
// Keep track of the final effect modifier
|
|
|
|
this.rollData.effectModifier = effectModifier
|
|
|
|
|
|
|
|
// Final number of dices
|
2022-02-18 21:58:53 +01:00
|
|
|
this.rollData.nbDice = 2 + Math.abs(this.rollData.bmDice)
|
2022-11-23 21:34:51 +01:00
|
|
|
// Bonus or Malus ?
|
2022-03-27 12:42:29 +02:00
|
|
|
if (this.rollData.bmDice == 0) {
|
|
|
|
$('#roll-nbdice').val("2")
|
|
|
|
} else {
|
|
|
|
let letter = (this.rollData.bmDice > 0) ? "B" : "M"
|
|
|
|
$('#roll-nbdice').val("2 + " + String(Math.abs(this.rollData.bmDice)) + letter)
|
2022-02-18 21:58:53 +01:00
|
|
|
}
|
2022-04-10 16:38:09 +02:00
|
|
|
let rollbase = this.rollData.attrValue + "+" + this.rollData.aptValue
|
2022-12-23 23:24:09 +01:00
|
|
|
if (this.rollData.weapon && this.rollData.weapon.system.properties.onlymodifier) {
|
2022-04-10 16:38:09 +02:00
|
|
|
rollbase = ""
|
|
|
|
}
|
|
|
|
$('#roll-modifier').val(rollbase + "+" + this.rollData.careerBonus + "+" + this.rollData.mod + "+" +
|
2022-03-27 12:42:29 +02:00
|
|
|
this.rollData.modRanged + "+" + this.rollData.weaponModifier + "-" + this.rollData.defence + "-" + this.rollData.modArmorMalus + "-" +
|
2022-11-23 21:34:51 +01:00
|
|
|
this.rollData.shieldMalus + "+" + this.rollData.attackModifier + "+" + this.rollData.appliedArmorMalus + "+" + effectModifier)
|
|
|
|
|
|
|
|
// Rebuild lits of applicable effects
|
|
|
|
let selectEffects = ""
|
2022-12-23 23:24:09 +01:00
|
|
|
for (let effect of this.rollData.bolApplicableEffects) {
|
2022-11-23 21:34:51 +01:00
|
|
|
selectEffects += `<option value="${effect.id}" selected>${effect.name}</option>`
|
|
|
|
}
|
|
|
|
$('#applicable-effects').html(selectEffects)
|
2022-03-10 21:05:53 +01:00
|
|
|
}
|
2022-03-27 12:42:29 +02:00
|
|
|
|
2022-03-10 21:05:53 +01:00
|
|
|
/* -------------------------------------------- */
|
2022-03-27 12:42:29 +02:00
|
|
|
static preProcessFightOption(rollData) {
|
2022-03-10 21:05:53 +01:00
|
|
|
rollData.damagesIgnoresArmor = false // Always reset flags
|
|
|
|
rollData.modArmorMalus = 0
|
|
|
|
rollData.attackModifier = 0
|
|
|
|
|
|
|
|
let fgItem = rollData.fightOption
|
2022-03-27 12:42:29 +02:00
|
|
|
if (fgItem) {
|
2022-03-10 21:05:53 +01:00
|
|
|
console.log(fgItem)
|
2022-07-01 15:48:54 +02:00
|
|
|
if (fgItem.system.properties.fightoptiontype == "armordefault") {
|
2022-03-10 21:05:53 +01:00
|
|
|
rollData.modArmorMalus = rollData.armorMalus // Activate the armor malus
|
|
|
|
rollData.damagesIgnoresArmor = true
|
|
|
|
}
|
2022-07-01 15:48:54 +02:00
|
|
|
if (fgItem.system.properties.fightoptiontype == "intrepid") {
|
2022-03-10 21:05:53 +01:00
|
|
|
rollData.attackModifier += 2
|
|
|
|
}
|
2022-07-01 15:48:54 +02:00
|
|
|
if (fgItem.system.properties.fightoptiontype == "defense") {
|
2022-03-10 21:05:53 +01:00
|
|
|
rollData.attackModifier += -1
|
|
|
|
}
|
2022-07-01 15:48:54 +02:00
|
|
|
if (fgItem.system.properties.fightoptiontype == "attack") {
|
2022-03-10 21:05:53 +01:00
|
|
|
rollData.attackModifier += 1
|
|
|
|
}
|
2022-07-01 15:48:54 +02:00
|
|
|
if (fgItem.system.properties.fightoptiontype == "twoweaponsdef" || fgItem.system.properties.fightoptiontype == "twoweaponsatt") {
|
2022-03-10 21:05:53 +01:00
|
|
|
rollData.attackModifier += -1
|
|
|
|
}
|
|
|
|
}
|
2022-02-18 21:58:53 +01:00
|
|
|
}
|
|
|
|
/* -------------------------------------------- */
|
2022-03-27 12:42:29 +02:00
|
|
|
static updateArmorMalus(rollData) {
|
|
|
|
rollData.appliedArmorMalus = 0
|
|
|
|
if (rollData.attribute.key == "agility") {
|
|
|
|
$("#armor-agi-malus").show()
|
|
|
|
rollData.appliedArmorMalus += rollData.armorAgiMalus
|
|
|
|
} else {
|
|
|
|
$("#armor-agi-malus").hide()
|
|
|
|
}
|
|
|
|
if (rollData.aptitude && rollData.aptitude.key == "init") {
|
|
|
|
$("#armor-init-malus").show()
|
|
|
|
rollData.appliedArmorMalus += rollData.armorInitMalus
|
|
|
|
} else {
|
|
|
|
$("#armor-init-malus").hide()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ------------------------------ -------------- */
|
|
|
|
static updatePPCost(rollData) {
|
|
|
|
$('#ppcost').html(rollData.ppCost + " + Armor(" + rollData.ppCostArmor + ")=" + Number(rollData.ppCost + rollData.ppCostArmor))
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ------------------------------ -------------- */
|
2022-02-18 21:58:53 +01:00
|
|
|
static rollDialogListener(html) {
|
2022-03-27 12:42:29 +02:00
|
|
|
|
2022-02-18 21:58:53 +01:00
|
|
|
this.updateTotalDice()
|
2022-03-27 12:42:29 +02:00
|
|
|
|
2022-01-23 09:25:09 +01:00
|
|
|
html.find('#optcond').change((event) => { // Dynamic change of PP cost of spell
|
|
|
|
let pp = BoLUtility.computeSpellCost(this.rollData.spell, event.currentTarget.selectedOptions.length)
|
|
|
|
this.rollData.ppCost = pp
|
2022-12-23 23:24:09 +01:00
|
|
|
this.updatePPCost(this.rollData)
|
2022-02-18 21:58:53 +01:00
|
|
|
})
|
|
|
|
|
|
|
|
html.find('#mod').change((event) => {
|
2022-03-27 12:42:29 +02:00
|
|
|
this.rollData.mod = Number(event.currentTarget.value)
|
2022-02-18 21:58:53 +01:00
|
|
|
this.updateTotalDice()
|
|
|
|
})
|
2022-02-23 20:39:58 +01:00
|
|
|
html.find('#modRanged').change((event) => {
|
2022-03-27 12:42:29 +02:00
|
|
|
this.rollData.modRanged = Number(event.currentTarget.value)
|
2022-02-23 20:39:58 +01:00
|
|
|
this.updateTotalDice()
|
|
|
|
})
|
2022-02-18 21:58:53 +01:00
|
|
|
|
2022-03-27 12:42:29 +02:00
|
|
|
html.find('#attr').change((event) => {
|
2022-02-18 21:58:53 +01:00
|
|
|
let attrKey = event.currentTarget.value
|
2022-11-30 12:12:44 +01:00
|
|
|
let actor = BoLUtility.getActorFromRollData(this.rollData)
|
2024-04-26 18:00:56 +02:00
|
|
|
this.rollData.attribute = foundry.utils.duplicate(actor.system.attributes[attrKey])
|
2022-07-01 15:48:54 +02:00
|
|
|
this.rollData.attrValue = actor.system.attributes[attrKey].value
|
2022-11-23 21:34:51 +01:00
|
|
|
this.rollData.bolApplicableEffects = this.updateApplicableEffects(this.rollData)
|
2022-02-18 21:58:53 +01:00
|
|
|
this.updateTotalDice()
|
2022-03-27 12:42:29 +02:00
|
|
|
})
|
|
|
|
html.find('#apt').change((event) => {
|
2022-02-18 21:58:53 +01:00
|
|
|
let aptKey = event.currentTarget.value
|
2022-11-30 12:12:44 +01:00
|
|
|
let actor = BoLUtility.getActorFromRollData(this.rollData)
|
2024-04-26 18:00:56 +02:00
|
|
|
this.rollData.aptitude = foundry.utils.duplicate(actor.system.aptitudes[aptKey])
|
2022-07-01 15:48:54 +02:00
|
|
|
this.rollData.aptValue = actor.system.aptitudes[aptKey].value
|
2022-11-23 21:34:51 +01:00
|
|
|
this.rollData.bolApplicableEffects = this.updateApplicableEffects(this.rollData)
|
2022-02-18 21:58:53 +01:00
|
|
|
this.updateTotalDice()
|
2022-03-27 12:42:29 +02:00
|
|
|
})
|
2022-02-18 21:58:53 +01:00
|
|
|
|
2022-03-27 12:42:29 +02:00
|
|
|
html.find('#applyShieldMalus').click((event) => {
|
2022-02-18 21:58:53 +01:00
|
|
|
if (event.currentTarget.checked) {
|
|
|
|
this.rollData.shieldMalus = this.rollData.shieldAttackMalus
|
|
|
|
} else {
|
|
|
|
this.rollData.shieldMalus = 0
|
|
|
|
}
|
2023-08-26 19:00:25 +02:00
|
|
|
this.updateTotalDice()
|
2022-02-18 21:58:53 +01:00
|
|
|
})
|
|
|
|
|
2022-03-27 12:42:29 +02:00
|
|
|
html.find('#career').change((event) => {
|
2022-02-18 21:58:53 +01:00
|
|
|
let careers = $('#career').val()
|
2022-03-27 12:42:29 +02:00
|
|
|
this.rollData.careerBonus = (!careers || careers.length == 0) ? 0 : Math.max(...careers.map(i => parseInt(i)))
|
2022-02-18 21:58:53 +01:00
|
|
|
this.updateTotalDice()
|
|
|
|
})
|
2022-03-27 12:42:29 +02:00
|
|
|
html.find('#boon').change((event) => {
|
2022-02-18 21:58:53 +01:00
|
|
|
let boons = $('#boon').val()
|
2022-05-23 18:38:51 +02:00
|
|
|
this.rollData.nbBoons = (!boons || boons.length == 0) ? 0 : boons.length
|
2022-02-18 21:58:53 +01:00
|
|
|
this.updateTotalDice()
|
|
|
|
})
|
2022-03-27 12:42:29 +02:00
|
|
|
html.find('#flaw').change((event) => {
|
2022-02-18 21:58:53 +01:00
|
|
|
let flaws = $('#flaw').val()
|
2022-05-23 18:38:51 +02:00
|
|
|
this.rollData.nbFlaws = (!flaws || flaws.length == 0) ? 0 : flaws.length
|
2022-02-18 21:58:53 +01:00
|
|
|
this.updateTotalDice()
|
|
|
|
})
|
|
|
|
html.find('.bdice').click((event) => {
|
|
|
|
this.rollData.mDice = 0
|
2022-03-27 12:42:29 +02:00
|
|
|
this.rollData.bDice = Number(event.currentTarget.value)
|
2022-02-18 21:58:53 +01:00
|
|
|
this.updateTotalDice()
|
|
|
|
})
|
2022-03-27 12:42:29 +02:00
|
|
|
html.find('.mdice').click((event) => {
|
2022-02-18 21:58:53 +01:00
|
|
|
this.rollData.bDice = 0
|
2022-03-27 12:42:29 +02:00
|
|
|
this.rollData.mDice = Number(event.currentTarget.value)
|
2022-02-18 21:58:53 +01:00
|
|
|
this.updateTotalDice()
|
|
|
|
})
|
2022-12-23 23:24:09 +01:00
|
|
|
html.find('#horoscope-bonus-applied').change((event) => {
|
2022-12-25 18:00:42 +01:00
|
|
|
this.rollData.selectedHoroscope = []
|
|
|
|
for (let option of event.currentTarget.selectedOptions) {
|
2024-04-26 18:00:56 +02:00
|
|
|
this.rollData.selectedHoroscope.push(foundry.utils.duplicate(this.rollData.horoscopeBonusList[Number(option.index)]))
|
2023-03-15 17:35:07 +01:00
|
|
|
}
|
2022-12-23 23:24:09 +01:00
|
|
|
let horoscopes = $('#horoscope-bonus-applied').val()
|
|
|
|
this.rollData.horoscopeBonus = (!horoscopes || horoscopes.length == 0) ? 0 : horoscopes.length
|
|
|
|
this.updateTotalDice()
|
|
|
|
})
|
2022-12-25 18:00:42 +01:00
|
|
|
|
2022-12-23 23:24:09 +01:00
|
|
|
html.find('#horoscope-malus-applied').change((event) => {
|
2022-12-25 18:00:42 +01:00
|
|
|
this.rollData.selectedHoroscope = []
|
|
|
|
for (let option of event.currentTarget.selectedOptions) {
|
2024-04-26 18:00:56 +02:00
|
|
|
this.rollData.selectedHoroscope.push(foundry.utils.duplicate(this.rollData.horoscopeBonusList[Number(option.index)]))
|
2023-03-15 17:35:07 +01:00
|
|
|
}
|
2022-12-23 23:24:09 +01:00
|
|
|
let horoscopes = $('#horoscope-malus-applied').val()
|
|
|
|
this.rollData.horoscopeMalus = (!horoscopes || horoscopes.length == 0) ? 0 : horoscopes.length
|
|
|
|
this.updateTotalDice()
|
|
|
|
})
|
2022-12-25 18:00:42 +01:00
|
|
|
html.find('#horoscope-group-applied').change((event) => {
|
|
|
|
this.rollData.selectedGroupHoroscopeIndex = event.currentTarget.value
|
|
|
|
this.updateTotalDice()
|
|
|
|
})
|
2023-03-15 17:35:07 +01:00
|
|
|
|
2022-12-23 23:24:09 +01:00
|
|
|
|
2022-01-23 09:25:09 +01:00
|
|
|
}
|
|
|
|
|
2022-03-10 21:05:53 +01:00
|
|
|
/* -------------------------------------------- */
|
2022-05-23 18:38:51 +02:00
|
|
|
static preProcessWeapon(rollData, defender) {
|
2022-03-10 21:05:53 +01:00
|
|
|
if (rollData.mode == "weapon") {
|
2022-11-23 15:27:08 +01:00
|
|
|
rollData.weaponModifier = rollData.weapon.system.properties.attackModifiers ?? 0
|
2022-07-01 15:48:54 +02:00
|
|
|
rollData.attackBonusDice = rollData.weapon.system.properties.attackBonusDice
|
2022-12-23 23:24:09 +01:00
|
|
|
if (rollData.attackBonusDice) {
|
2022-11-23 15:27:08 +01:00
|
|
|
rollData.adv = "1B"
|
|
|
|
rollData.bDice = 1
|
|
|
|
}
|
2022-05-23 18:38:51 +02:00
|
|
|
if (defender) { // If target is selected
|
|
|
|
rollData.defence = defender.defenseValue
|
|
|
|
rollData.armorMalus = defender.armorMalusValue
|
2023-09-16 09:40:08 +02:00
|
|
|
rollData.defenderHeroPoints = defender.getHeroPoints()
|
2022-03-10 21:05:53 +01:00
|
|
|
rollData.shieldBlock = 'none'
|
2022-05-23 18:38:51 +02:00
|
|
|
let shields = defender.shields
|
2023-08-26 19:00:25 +02:00
|
|
|
//console.log("Defender stats", defender)
|
2022-03-10 21:05:53 +01:00
|
|
|
for (let shield of shields) {
|
2022-07-01 15:48:54 +02:00
|
|
|
rollData.shieldBlock = (shield.system.properties.blocking.blockingAll) ? 'blockall' : 'blockone';
|
|
|
|
rollData.shieldAttackMalus = (shield.system.properties.blocking.malus) ? shield.system.properties.blocking.malus : 1;
|
2022-03-10 21:05:53 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-01-01 23:32:48 +01:00
|
|
|
/* ROLL DIALOGS */
|
|
|
|
/* -------------------------------------------- */
|
2022-01-16 22:06:49 +01:00
|
|
|
static async displayRollDialog(rollData, onEnter = "submit") {
|
2022-01-01 23:32:48 +01:00
|
|
|
|
2022-03-10 21:05:53 +01:00
|
|
|
// initialize default flags/values
|
2022-01-16 22:06:49 +01:00
|
|
|
const rollOptionTpl = `systems/bol/templates/dialogs/${rollData.mode}-roll-dialog.hbs`
|
2022-04-08 23:42:01 +02:00
|
|
|
|
2022-11-30 12:12:44 +01:00
|
|
|
let actor = BoLUtility.getActorFromRollData(rollData)
|
2022-05-23 18:38:51 +02:00
|
|
|
let defender
|
2022-12-23 23:24:09 +01:00
|
|
|
if (rollData.targetId) {
|
2022-05-23 18:38:51 +02:00
|
|
|
let token = game.scenes.current.tokens.get(rollData.targetId)
|
|
|
|
defender = token.actor
|
|
|
|
}
|
|
|
|
|
2022-04-08 23:42:01 +02:00
|
|
|
rollData.careers = actor.careers
|
|
|
|
rollData.boons = actor.bonusBoons
|
|
|
|
rollData.flaws = actor.malusFlaws
|
|
|
|
rollData.rollOwnerID = actor.id
|
2022-01-16 22:06:49 +01:00
|
|
|
rollData.defence = 0
|
2022-03-10 21:05:53 +01:00
|
|
|
rollData.attackModifier = 0 // Used for fight options
|
|
|
|
rollData.modArmorMalus = 0 // Used for fight options
|
2022-03-27 12:42:29 +02:00
|
|
|
rollData.bDice = 0
|
|
|
|
rollData.mDice = 0
|
2022-02-18 21:58:53 +01:00
|
|
|
rollData.nbBoons = 0
|
|
|
|
rollData.nbFlaws = 0
|
2022-03-27 12:42:29 +02:00
|
|
|
rollData.nbDice = 0
|
2023-04-04 13:41:22 +02:00
|
|
|
rollData.isHeroAdversary = actor.isHeroAdversary()
|
2022-02-18 21:58:53 +01:00
|
|
|
rollData.careerBonus = rollData.careerBonus ?? 0
|
2022-02-23 20:39:58 +01:00
|
|
|
rollData.modRanged = rollData.modRanged ?? 0
|
2022-02-18 21:58:53 +01:00
|
|
|
rollData.mod = rollData.mod ?? 0
|
2024-04-26 18:00:56 +02:00
|
|
|
rollData.id = foundry.utils.randomID(16)
|
2022-01-19 21:57:34 +01:00
|
|
|
rollData.weaponModifier = 0
|
|
|
|
rollData.attackBonusDice = false
|
2022-03-10 21:05:53 +01:00
|
|
|
rollData.armorMalus = 0
|
|
|
|
// Specific stuff
|
2022-05-23 18:38:51 +02:00
|
|
|
this.preProcessWeapon(rollData, defender)
|
2022-03-10 21:05:53 +01:00
|
|
|
this.preProcessFightOption(rollData)
|
2022-03-27 12:42:29 +02:00
|
|
|
this.updateArmorMalus(rollData)
|
|
|
|
this.updatePPCost(rollData)
|
2023-08-26 19:00:25 +02:00
|
|
|
// Prepare blocking case
|
|
|
|
if (rollData.shieldBlock == 'blockall') {
|
|
|
|
rollData.shieldMalus = rollData.shieldAttackMalus;
|
|
|
|
} else {
|
|
|
|
rollData.shieldMalus = 0
|
|
|
|
}
|
2022-03-10 21:05:53 +01:00
|
|
|
// Save
|
2022-02-18 21:58:53 +01:00
|
|
|
this.rollData = rollData
|
|
|
|
console.log("ROLLDATA", rollData)
|
|
|
|
|
2022-03-10 21:05:53 +01:00
|
|
|
// Then display+process the dialog
|
2022-01-16 22:06:49 +01:00
|
|
|
const rollOptionContent = await renderTemplate(rollOptionTpl, rollData);
|
2022-01-01 23:32:48 +01:00
|
|
|
let d = new Dialog({
|
2022-01-16 22:06:49 +01:00
|
|
|
title: rollData.label,
|
2022-01-01 23:32:48 +01:00
|
|
|
content: rollOptionContent,
|
2022-01-16 22:06:49 +01:00
|
|
|
rollData: rollData,
|
2022-01-23 09:25:09 +01:00
|
|
|
render: html => this.rollDialogListener(html),
|
2022-01-01 23:32:48 +01:00
|
|
|
buttons: {
|
|
|
|
cancel: {
|
|
|
|
icon: '<i class="fas fa-times"></i>',
|
|
|
|
label: game.i18n.localize("BOL.ui.cancel"),
|
|
|
|
callback: () => {
|
|
|
|
}
|
|
|
|
},
|
|
|
|
submit: {
|
|
|
|
icon: '<i class="fas fa-check"></i>',
|
|
|
|
label: game.i18n.localize("BOL.ui.submit"),
|
|
|
|
callback: (html) => {
|
2022-01-23 09:25:09 +01:00
|
|
|
if (rollData.mode == 'spell' && rollData.ppCurrent < rollData.ppCost) { // Check PP available
|
|
|
|
ui.notifications.warn("Pas assez de Points de Pouvoir !")
|
|
|
|
return
|
|
|
|
}
|
2022-02-20 10:12:25 +01:00
|
|
|
rollData.registerInit = (rollData.aptitude && rollData.aptitude.key == 'init') ? $('#register-init').is(":checked") : false;
|
2022-12-23 23:24:09 +01:00
|
|
|
|
|
|
|
const isMalus = (rollData.bmDice < 0)
|
2021-12-29 20:33:59 +01:00
|
|
|
|
2022-04-10 16:38:09 +02:00
|
|
|
let rollbase = rollData.attrValue + rollData.aptValue
|
2023-09-16 09:40:08 +02:00
|
|
|
if (rollData.weapon?.system.properties.onlymodifier) {
|
2022-04-10 16:38:09 +02:00
|
|
|
rollbase = 0
|
2022-12-23 23:24:09 +01:00
|
|
|
}
|
2023-03-15 17:35:07 +01:00
|
|
|
let diceData = BoLUtility.getDiceData()
|
2023-05-01 18:50:32 +02:00
|
|
|
let malusInit = rollData.combatData?.malusInit || 0
|
|
|
|
const modifiers = rollbase + rollData.careerBonus + rollData.mod + rollData.weaponModifier - rollData.defence - rollData.modArmorMalus + rollData.shieldMalus + rollData.attackModifier + rollData.appliedArmorMalus + rollData.effectModifier - malusInit
|
2023-01-26 20:50:56 +01:00
|
|
|
const formula = (isMalus) ? rollData.nbDice + "d" + diceData.diceFormula + "kl2 + " + modifiers : rollData.nbDice + "d" + diceData.diceFormula + "kh2 + " + modifiers
|
2022-02-18 21:58:53 +01:00
|
|
|
rollData.formula = formula
|
2022-01-17 23:50:57 +01:00
|
|
|
rollData.modifiers = modifiers
|
2023-08-26 19:00:25 +02:00
|
|
|
console.log("Rolldata before", rollData)
|
2021-12-25 23:26:27 +01:00
|
|
|
|
2022-01-16 22:06:49 +01:00
|
|
|
let r = new BoLDefaultRoll(rollData);
|
|
|
|
r.roll();
|
2022-01-01 23:32:48 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
default: onEnter,
|
|
|
|
close: () => { }
|
|
|
|
}, this.options());
|
2022-01-23 09:25:09 +01:00
|
|
|
|
2022-01-01 23:32:48 +01:00
|
|
|
return d.render(true);
|
|
|
|
}
|
2021-12-22 05:12:40 +01:00
|
|
|
}
|
|
|
|
|
2022-03-27 12:42:29 +02:00
|
|
|
/* -------------------------------------------- */
|
2021-12-22 05:12:40 +01:00
|
|
|
export class BoLDefaultRoll {
|
2022-02-18 21:58:53 +01:00
|
|
|
|
2022-01-16 22:06:49 +01:00
|
|
|
constructor(rollData) {
|
|
|
|
this.rollData = rollData
|
2022-02-18 21:58:53 +01:00
|
|
|
if (this.rollData.isSuccess == undefined) { // First init
|
2022-01-17 23:50:57 +01:00
|
|
|
this.rollData.isSuccess = false;
|
|
|
|
this.rollData.isCritical = false;
|
|
|
|
this.rollData.isFumble = false;
|
|
|
|
}
|
2022-02-18 21:58:53 +01:00
|
|
|
if (this.rollData.optionsId) {
|
2022-12-23 23:24:09 +01:00
|
|
|
BoLUtility.cleanupButtons(this.rollData.optionsId)
|
2022-02-18 21:58:53 +01:00
|
|
|
}
|
|
|
|
if (this.rollData.applyId) {
|
2022-12-23 23:24:09 +01:00
|
|
|
BoLUtility.cleanupButtons(this.rollData.applyId)
|
2022-02-18 21:58:53 +01:00
|
|
|
}
|
2024-04-26 18:00:56 +02:00
|
|
|
this.rollData.optionsId = foundry.utils.randomID(16)
|
|
|
|
this.rollData.applyId = foundry.utils.randomID(16)
|
2022-01-01 23:32:48 +01:00
|
|
|
}
|
2021-12-25 23:26:27 +01:00
|
|
|
|
2022-03-27 12:42:29 +02:00
|
|
|
/* -------------------------------------------- */
|
2022-01-01 23:32:48 +01:00
|
|
|
async roll() {
|
2022-01-16 22:06:49 +01:00
|
|
|
|
2022-03-10 21:05:53 +01:00
|
|
|
const r = new Roll(this.rollData.formula)
|
2024-04-26 18:00:56 +02:00
|
|
|
await r.roll()
|
2023-01-26 20:50:56 +01:00
|
|
|
|
|
|
|
let diceData = BoLUtility.getDiceData()
|
2023-03-15 17:35:07 +01:00
|
|
|
//console.log("DICEDATA", diceData)
|
2022-03-10 21:05:53 +01:00
|
|
|
const activeDice = r.terms[0].results.filter(r => r.active)
|
|
|
|
const diceTotal = activeDice.map(r => r.result).reduce((a, b) => a + b)
|
2022-01-17 23:50:57 +01:00
|
|
|
this.rollData.roll = r
|
2023-01-26 20:50:56 +01:00
|
|
|
this.rollData.isSuccess = (r.total >= diceData.successValue)
|
|
|
|
this.rollData.isCritical = (diceTotal >= diceData.criticalSuccessValue)
|
|
|
|
this.rollData.isRealCritical = (diceTotal >= diceData.criticalSuccessValue)
|
|
|
|
this.rollData.isHeroic = (diceTotal >= diceData.criticalSuccessValue)
|
2022-03-27 22:56:43 +02:00
|
|
|
this.rollData.isLegendary = false
|
2023-01-26 20:50:56 +01:00
|
|
|
this.rollData.isFumble = (diceTotal <= diceData.criticalFailureValue)
|
2022-01-16 22:06:49 +01:00
|
|
|
this.rollData.isFailure = !this.rollData.isSuccess
|
2022-12-23 23:24:09 +01:00
|
|
|
|
2022-11-30 12:12:44 +01:00
|
|
|
let actor = BoLUtility.getActorFromRollData(this.rollData)
|
2022-01-17 23:50:57 +01:00
|
|
|
if (this.rollData.reroll == undefined) {
|
2022-04-08 23:42:01 +02:00
|
|
|
this.rollData.reroll = actor.heroReroll()
|
2022-01-17 23:50:57 +01:00
|
|
|
}
|
2022-01-16 22:53:41 +01:00
|
|
|
if (this.rollData.registerInit) {
|
2023-05-01 18:50:32 +02:00
|
|
|
await actor.registerInit(this.rollData)
|
2022-12-02 13:15:48 +01:00
|
|
|
this.rollData.initiativeRank = actor.getInitiativeRank(this.rollData)
|
2023-03-15 17:35:07 +01:00
|
|
|
if (this.rollData.combatData) { // If combatData present
|
|
|
|
let combat = game.combats.get(this.rollData.combatData.combatId)
|
2023-05-01 18:50:32 +02:00
|
|
|
console.log("SET INIT!!!!!", this.rollData.initiativeRank)
|
2023-03-15 17:35:07 +01:00
|
|
|
combat.setInitiative(this.rollData.combatData.combatantId, this.rollData.initiativeRank)
|
|
|
|
}
|
2022-01-16 22:53:41 +01:00
|
|
|
}
|
2022-01-23 09:25:09 +01:00
|
|
|
if (this.rollData.isSuccess && this.rollData.mode == "spell") { // PP cost management
|
2022-06-11 20:56:35 +02:00
|
|
|
this.rollData.remainingPP = actor.spendPowerPoint(this.rollData.ppCost + this.rollData.ppCostArmor)
|
2022-01-23 09:25:09 +01:00
|
|
|
}
|
2022-12-25 18:00:42 +01:00
|
|
|
|
2022-01-23 09:25:09 +01:00
|
|
|
if (this.rollData.mode == "alchemy") { // PP cost management
|
2022-06-11 10:21:18 +02:00
|
|
|
actor.resetAlchemyStatus(this.rollData.alchemy._id)
|
2022-01-23 09:25:09 +01:00
|
|
|
}
|
2022-12-23 23:24:09 +01:00
|
|
|
if (this.rollData.mode == "bougette" && this.rollData.isFailure) {
|
2022-11-29 15:23:05 +01:00
|
|
|
actor.decBougette()
|
|
|
|
}
|
2022-12-25 18:00:42 +01:00
|
|
|
|
|
|
|
await this.sendChatMessage()
|
|
|
|
|
2022-12-23 23:24:09 +01:00
|
|
|
if (this.rollData.mode == "horoscope") { // PP cost management
|
|
|
|
actor.manageHoroscope(this.rollData)
|
|
|
|
}
|
|
|
|
if (this.rollData.selectedHoroscope.length > 0) { // PP cost management
|
|
|
|
actor.removeHoroscopeMinor(this.rollData)
|
|
|
|
}
|
2022-12-25 18:00:42 +01:00
|
|
|
if (this.rollData.selectedGroupHoroscopeIndex && this.rollData.selectedGroupHoroscopeIndex > 0) { // PP cost management
|
|
|
|
BoLUtility.removeGroupHoroscope(this.rollData)
|
|
|
|
}
|
2022-01-17 23:50:57 +01:00
|
|
|
}
|
|
|
|
|
2022-03-27 12:42:29 +02:00
|
|
|
/* -------------------------------------------- */
|
2022-01-17 23:50:57 +01:00
|
|
|
async sendChatMessage() {
|
2022-11-30 12:12:44 +01:00
|
|
|
let actor = BoLUtility.getActorFromRollData(this.rollData)
|
2022-12-23 23:24:09 +01:00
|
|
|
this._buildChatMessage(this.rollData).then(async msgFlavor => {
|
2023-03-29 23:04:02 +02:00
|
|
|
//console.log("MSG", msgFlavor )
|
2022-06-11 10:21:18 +02:00
|
|
|
let msg = await this.rollData.roll.toMessage({
|
2022-01-01 23:32:48 +01:00
|
|
|
user: game.user.id,
|
2022-03-27 22:56:43 +02:00
|
|
|
rollMode: game.settings.get("core", "rollMode"),
|
2022-01-01 23:32:48 +01:00
|
|
|
flavor: msgFlavor,
|
2022-04-08 23:42:01 +02:00
|
|
|
speaker: ChatMessage.getSpeaker({ actor: actor }),
|
2022-01-17 23:50:57 +01:00
|
|
|
})
|
2024-04-26 18:00:56 +02:00
|
|
|
this.rollData.roll = foundry.utils.duplicate(this.rollData.roll) // Remove object, keep data (v111 ready)
|
2022-06-11 10:21:18 +02:00
|
|
|
msg.setFlag("world", "bol-roll-data", this.rollData)
|
2022-03-27 22:56:43 +02:00
|
|
|
})
|
2022-01-09 13:23:20 +01:00
|
|
|
}
|
|
|
|
|
2022-03-27 12:42:29 +02:00
|
|
|
/* -------------------------------------------- */
|
2022-03-27 22:56:43 +02:00
|
|
|
upgradeToLegendary() {
|
2022-01-17 23:50:57 +01:00
|
|
|
// Force to Critical roll
|
2023-01-26 20:50:56 +01:00
|
|
|
let diceData = BoLUtility.getDiceData()
|
|
|
|
let maxValue = Number(diceData.diceFormula) * 2
|
|
|
|
|
2022-01-17 23:50:57 +01:00
|
|
|
this.rollData.isCritical = true
|
2022-03-27 22:56:43 +02:00
|
|
|
this.rollData.isLegendary = true
|
2022-01-17 23:50:57 +01:00
|
|
|
this.rollData.isRealCritical = false
|
|
|
|
this.rollData.isSuccess = true
|
|
|
|
this.rollData.isFailure = false
|
2023-01-26 20:50:56 +01:00
|
|
|
this.rollData.roll = new Roll(maxValue + "+" + this.rollData.modifiers)
|
2022-01-17 23:50:57 +01:00
|
|
|
this.rollData.reroll = false
|
|
|
|
this.sendChatMessage()
|
2022-01-09 13:23:20 +01:00
|
|
|
}
|
2022-01-17 23:50:57 +01:00
|
|
|
|
2022-03-27 22:56:43 +02:00
|
|
|
/* -------------------------------------------- */
|
|
|
|
upgradeToHeroic() {
|
|
|
|
// Force to Critical roll
|
2023-01-26 20:50:56 +01:00
|
|
|
let diceData = BoLUtility.getDiceData()
|
|
|
|
let maxValue = Number(diceData.diceFormula) * 2
|
|
|
|
|
2022-03-27 22:56:43 +02:00
|
|
|
this.rollData.isCritical = true
|
|
|
|
this.rollData.isHeroic = true
|
|
|
|
this.rollData.isLegendary = false
|
|
|
|
this.rollData.isRealCritical = false
|
|
|
|
this.rollData.isSuccess = true
|
|
|
|
this.rollData.isFailure = false
|
2023-01-26 20:50:56 +01:00
|
|
|
this.rollData.roll = new Roll(maxValue + "+" + this.rollData.modifiers)
|
2022-03-27 22:56:43 +02:00
|
|
|
this.rollData.reroll = false
|
|
|
|
this.sendChatMessage()
|
|
|
|
}
|
2022-12-23 23:24:09 +01:00
|
|
|
|
2022-03-27 12:42:29 +02:00
|
|
|
/* -------------------------------------------- */
|
2022-01-17 23:50:57 +01:00
|
|
|
setSuccess(flag) {
|
2022-01-16 22:06:49 +01:00
|
|
|
this.rollData.isSuccess = flag
|
|
|
|
}
|
|
|
|
|
2022-03-27 12:42:29 +02:00
|
|
|
/* -------------------------------------------- */
|
2022-01-17 23:50:57 +01:00
|
|
|
async sendDamageMessage() {
|
2022-11-30 12:12:44 +01:00
|
|
|
let actor = BoLUtility.getActorFromRollData(this.rollData)
|
2022-06-11 10:21:18 +02:00
|
|
|
this._buildDamageChatMessage(this.rollData).then(async msgFlavor => {
|
|
|
|
let msg = await this.rollData.damageRoll.toMessage({
|
2022-01-17 23:50:57 +01:00
|
|
|
user: game.user.id,
|
|
|
|
flavor: msgFlavor,
|
2022-04-08 23:42:01 +02:00
|
|
|
speaker: ChatMessage.getSpeaker({ actor: actor }),
|
2022-01-17 23:50:57 +01:00
|
|
|
flags: { msgType: "default" }
|
|
|
|
})
|
2024-04-26 18:00:56 +02:00
|
|
|
this.rollData.damageRoll = foundry.utils.duplicate(this.rollData.damageRoll)
|
2022-07-16 11:03:33 +02:00
|
|
|
this.rollData.actor = undefined // Cleanup
|
2022-06-11 10:21:18 +02:00
|
|
|
msg.setFlag("world", "bol-roll-data", this.rollData)
|
|
|
|
})
|
2022-01-17 23:50:57 +01:00
|
|
|
}
|
2022-02-18 21:58:53 +01:00
|
|
|
|
2022-03-27 12:42:29 +02:00
|
|
|
/* -------------------------------------------- */
|
2022-05-10 23:04:04 +02:00
|
|
|
getDamageAttributeValue(attrDamage, actorId = undefined) {
|
2022-11-30 12:12:44 +01:00
|
|
|
let actor = BoLUtility.getActorFromRollData(this.rollData)
|
2022-12-23 23:24:09 +01:00
|
|
|
return actor.getDamageAttributeValue(attrDamage)
|
2022-02-02 09:35:32 +01:00
|
|
|
}
|
|
|
|
|
2022-03-27 12:42:29 +02:00
|
|
|
/* -------------------------------------------- */
|
2022-01-17 23:50:57 +01:00
|
|
|
async rollDamage() {
|
|
|
|
if (this.rollData.mode != "weapon") { // Only specific process in Weapon mode
|
2022-06-11 10:21:18 +02:00
|
|
|
return
|
2022-01-16 22:06:49 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
if (this.rollData.isSuccess) {
|
2022-02-18 21:58:53 +01:00
|
|
|
if (!this.rollData.damageRoll) {
|
2022-01-17 23:50:57 +01:00
|
|
|
let bonusDmg = 0
|
2022-02-18 21:58:53 +01:00
|
|
|
if (this.rollData.damageMode == 'damage-plus-6') {
|
2022-01-17 23:50:57 +01:00
|
|
|
bonusDmg = 6
|
|
|
|
}
|
2022-02-18 21:58:53 +01:00
|
|
|
if (this.rollData.damageMode == 'damage-plus-12') {
|
2022-01-17 23:50:57 +01:00
|
|
|
bonusDmg = 12
|
|
|
|
}
|
2022-07-01 15:48:54 +02:00
|
|
|
let attrDamageValue = this.getDamageAttributeValue(this.rollData.weapon.system.properties.damageAttribute)
|
|
|
|
let weaponFormula = BoLUtility.getDamageFormula(this.rollData.weapon.system, this.rollData.fightOption)
|
2022-02-23 20:39:58 +01:00
|
|
|
|
2022-02-18 21:58:53 +01:00
|
|
|
let damageFormula = weaponFormula + "+" + bonusDmg + "+" + attrDamageValue
|
2022-01-17 23:50:57 +01:00
|
|
|
|
|
|
|
//console.log("Formula", weaponFormula, damageFormula, this.rollData.weapon.data.data.properties.damage)
|
|
|
|
this.rollData.damageFormula = damageFormula
|
|
|
|
this.rollData.damageRoll = new Roll(damageFormula)
|
2024-08-13 10:37:56 +02:00
|
|
|
await this.rollData.damageRoll.roll()
|
2022-02-23 20:39:58 +01:00
|
|
|
this.rollData.damageTotal = this.rollData.damageRoll.total
|
2023-03-18 10:24:30 +01:00
|
|
|
console.log("DAMAGE !!!", damageFormula, attrDamageValue, this.rollData)
|
2022-01-17 23:50:57 +01:00
|
|
|
}
|
2022-06-11 20:56:35 +02:00
|
|
|
BoLUtility.cleanupButtons(this.rollData.optionsId)
|
2022-01-17 23:50:57 +01:00
|
|
|
this.sendDamageMessage()
|
2021-12-29 19:15:06 +01:00
|
|
|
}
|
2022-01-01 23:32:48 +01:00
|
|
|
}
|
2021-12-25 23:26:27 +01:00
|
|
|
|
2022-03-27 12:42:29 +02:00
|
|
|
/* -------------------------------------------- */
|
2022-01-16 22:06:49 +01:00
|
|
|
_buildDamageChatMessage(rollData) {
|
|
|
|
const rollMessageTpl = 'systems/bol/templates/chat/rolls/damage-roll-card.hbs';
|
2022-03-10 21:05:53 +01:00
|
|
|
return renderTemplate(rollMessageTpl, rollData)
|
2022-01-16 22:06:49 +01:00
|
|
|
}
|
2021-12-25 23:26:27 +01:00
|
|
|
|
2022-03-27 12:42:29 +02:00
|
|
|
/* -------------------------------------------- */
|
2022-01-16 22:06:49 +01:00
|
|
|
_buildChatMessage(rollData) {
|
2022-11-29 15:23:05 +01:00
|
|
|
const rollMessageTpl = 'systems/bol/templates/chat/rolls/default-roll-card.hbs'
|
|
|
|
return renderTemplate(rollMessageTpl, rollData)
|
2022-01-16 22:06:49 +01:00
|
|
|
}
|
2021-12-25 23:26:27 +01:00
|
|
|
|
|
|
|
}
|