export default class AwEActor extends Actor { /** @override */ prepareData() { super.prepareData() } /** @override */ prepareBaseData() {} /** @override */ prepareDerivedData() { const actorData = this this._prepareCharacterData(actorData) this._prepareCreatureData(actorData) } /** * Prepare character data. * @param {object} actorData - The actor data. */ _prepareCharacterData(actorData) { if (actorData.type !== "character") return } /** * Prepare creature data. * @param {object} actorData - The actor data. */ _prepareCreatureData(actorData) { if (actorData.type !== "creature") return } /** * Roll an attribute check. * @param {string} attributeId - The attribute to roll. * @param {object} options - Roll options. * @returns {Promise} The roll result. */ async rollAttribute(attributeId, options = {}) { const attribute = this.system.attributes[attributeId] if (!attribute) return null const mod = attribute.mod ?? 0 const formula = `1d20 + ${mod}` const roll = new Roll(formula) await roll.evaluate() // Determine outcome vs DC if provided let outcome = null if (options.dc !== undefined) { const total = roll.total const dc = options.dc if (total >= dc + 10) outcome = "criticalSuccess" else if (total >= dc) outcome = "success" else if (total <= dc - 10) outcome = "criticalFailure" else outcome = "failure" } // Send to chat const attrLabel = attributeId.charAt(0).toUpperCase() + attributeId.slice(1) const flavor = options.flavor || game.i18n.localize(`AWEMMY.Attribute.${attrLabel}`) await roll.toMessage({ speaker: ChatMessage.getSpeaker({ actor: this }), flavor, rollMode: game.settings.get("core", "rollMode") }) return { roll, outcome } } }