diff --git a/src/lang/en.json b/src/lang/en.json index 382cc4b..31da6dc 100644 --- a/src/lang/en.json +++ b/src/lang/en.json @@ -2,6 +2,13 @@ "OSE.Edit": "Edit", "OSE.Delete": "Delete", "OSE.Add": "Add", + "OSE.Cancel": "Cancel", + "OSE.Roll": "Roll", + + "OSE.Formula": "Formula", + "OSE.SitMod": "Situational Modifier", + "OSE.RollMod": "Roll Mode", + "OSE.RollExample": "Roll Example", "OSE.Name": "Name", "OSE.Class": "Class", @@ -27,16 +34,17 @@ "OSE.scores.cha.long": "Charisma", "OSE.scores.cha.short": "CHA", + "OSE.SavingThrow": "Saving Throw", "OSE.saves.death.short": "D", "OSE.saves.death.long": "Death, Poison", - "OSE.saves.wands.short": "W", - "OSE.saves.wands.long": "Wand", + "OSE.saves.wand.short": "W", + "OSE.saves.wand.long": "Wand", "OSE.saves.paralysis.short": "P", "OSE.saves.paralysis.long": "Paralysis, Petrify", "OSE.saves.breath.short": "B", "OSE.saves.breath.long": "Dragon Breath", - "OSE.saves.spells.short": "S", - "OSE.saves.spells.long": "Rod, Staff, Spell", + "OSE.saves.spell.short": "S", + "OSE.saves.spell.long": "Rod, Staff, Spell", "OSE.Health": "Hit Points", "OSE.HealthShort": "HP", diff --git a/src/module/actor/actor-sheet.js b/src/module/actor/actor-sheet.js index 6168c30..d9dc311 100644 --- a/src/module/actor/actor-sheet.js +++ b/src/module/actor/actor-sheet.js @@ -8,10 +8,14 @@ export class OseActorSheet extends ActorSheet { /* -------------------------------------------- */ activateListeners(html) { - super.activateListeners(html); - html.find('.saving-throw .attribute-name').click(ev => { - console.log('hey'); + html.find('.saving-throw .attribute-name a').click(ev => { + let actorObject = this.actor; + let element = event.currentTarget; + let save = element.parentElement.parentElement.dataset.save; + actorObject.rollSave(save, { event: event }); }) + + super.activateListeners(html); } // Override to set resizable initial size diff --git a/src/module/actor/entity.js b/src/module/actor/entity.js index 42d55c8..752f305 100644 --- a/src/module/actor/entity.js +++ b/src/module/actor/entity.js @@ -1,20 +1,29 @@ +import { OseDice } from '../dice.js'; + export class OseActor extends Actor { /** * Extends data from base Actor class */ - prepareData() { - super.prepareData(); - return this.data; - } - /* -------------------------------------------- */ + + /* -------------------------------------------- */ /* Socket Listeners and Handlers /* -------------------------------------------- */ - /** @override */ - async createOwnedItem(itemData, options) { - return super.createOwnedItem(itemData, options); - } /* -------------------------------------------- */ /* Rolls */ /* -------------------------------------------- */ + rollSave(save, options = {}) { + const label = game.i18n.localize(`OSE.saves.${save}.long`); + const rollParts = ['1d20']; + + // Roll and return + return OseDice.Roll({ + event: options.event, + parts: rollParts, + data: this.data, + speaker: ChatMessage.getSpeaker({ actor: this }), + flavor: `${label} ${game.i18n.localize('OSE.SavingThrow')}`, + title: `${label} ${game.i18n.localize('OSE.SavingThrow')}`, + }); + } } diff --git a/src/module/dice.js b/src/module/dice.js new file mode 100644 index 0000000..0a33078 --- /dev/null +++ b/src/module/dice.js @@ -0,0 +1,78 @@ +export class OseDice { + // eslint-disable-next-line no-unused-vars + static async Roll({ + parts = [], + data = {}, + options = {}, + event = null, + speaker = null, + flavor = null, + title = null, + item = false, + } = {}) { + let rollMode = game.settings.get("core", "rollMode"); + let rolled = false; + let filtered = parts.filter(function (el) { + return el != "" && el; + }); + + const _roll = (form = null, raise = false) => { + // Optionally include a situational bonus + if (form !== null) data["bonus"] = form.bonus.value; + if (data["bonus"]) filtered.push(data["bonus"]); + + const roll = new Roll(filtered.join(""), data).roll(); + // Convert the roll to a chat message and return the roll + rollMode = form ? form.rollMode.value : rollMode; + roll.toMessage( + { + speaker: speaker, + flavor: flavor, + }, + { rollMode } + ); + rolled = true; + return roll; + }; + + const template = "systems/ose/templates/chat/roll-dialog.html"; + let dialogData = { + formula: filtered.join(" "), + data: data, + rollMode: rollMode, + rollModes: CONFIG.Dice.rollModes, + }; + + let buttons = { + ok: { + label: game.i18n.localize("OSE.Roll"), + icon: '', + callback: (html) => { + roll = _roll(html[0].children[0]); + }, + }, + cancel: { + icon: '', + label: game.i18n.localize("OSE.Cancel"), + }, + }; + + if (!item) delete buttons.raise; + + const html = await renderTemplate(template, dialogData); + let roll; + + //Create Dialog window + return new Promise((resolve) => { + new Dialog({ + title: title, + content: html, + buttons: buttons, + default: "ok", + close: () => { + resolve(rolled ? roll : false) + }, + }).render(true); + }); + } +} diff --git a/src/template.json b/src/template.json index f2cd2e6..042ad9f 100644 --- a/src/template.json +++ b/src/template.json @@ -120,11 +120,11 @@ "morale": 0 }, "saves": { - "D": 10, - "W": 10, - "P": 10, - "B": 10, - "S": 10 + "death": 10, + "wand": 10, + "paralysis": 10, + "breath": 10, + "spell": 10 }, "thac0": { "value": 19, diff --git a/src/templates/actors/partials/character-attributes-tab.html b/src/templates/actors/partials/character-attributes-tab.html index 85804b3..44a6fa8 100644 --- a/src/templates/actors/partials/character-attributes-tab.html +++ b/src/templates/actors/partials/character-attributes-tab.html @@ -129,34 +129,34 @@ {{!-- Saving throws --}}