From 95521aebfe446fa80e2f178a02e0fa82ada266a9 Mon Sep 17 00:00:00 2001 From: U~man Date: Sun, 5 Jul 2020 23:32:51 +0200 Subject: [PATCH] ENH: Damage context --- src/module/actor/entity.js | 13 +++++++++++ src/module/chat.js | 47 ++++++++++++++++++++++++++++++++++++++ src/ose.js | 5 ++-- 3 files changed, 63 insertions(+), 2 deletions(-) create mode 100644 src/module/chat.js diff --git a/src/module/actor/entity.js b/src/module/actor/entity.js index 775bd2b..cbe9c96 100644 --- a/src/module/actor/entity.js +++ b/src/module/actor/entity.js @@ -298,6 +298,19 @@ export class OseActor extends Actor { }); } + async applyDamage(amount=0, multiplier=1) { + amount = Math.floor(parseInt(amount) * multiplier); + const hp = this.data.data.hp; + + // Remaining goes to health + const dh = Math.clamped(hp.value - amount, 0, hp.max); + + // Update the Actor + return this.update({ + "data.hp.value": dh + }); + } + static _valueToMod(val) { switch (val) { case 3: diff --git a/src/module/chat.js b/src/module/chat.js new file mode 100644 index 0000000..47b7288 --- /dev/null +++ b/src/module/chat.js @@ -0,0 +1,47 @@ +/** + * This function is used to hook into the Chat Log context menu to add additional options to each message + * These options make it easy to conveniently apply damage to controlled tokens based on the value of a Roll + * + * @param {HTMLElement} html The Chat Message being rendered + * @param {Array} options The Array of Context Menu options + * + * @return {Array} The extended options Array including new context choices + */ +export const addChatMessageContextOptions = function(html, options) { + let canApply = li => canvas.tokens.controlled.length && li.find(".dice-roll").length; + options.push( + { + name: game.i18n.localize("OSE.ChatContextDamage"), + icon: '', + condition: canApply, + callback: li => applyChatCardDamage(li, 1) + }, + { + name: game.i18n.localize("OSE.ChatContextHealing"), + icon: '', + condition: canApply, + callback: li => applyChatCardDamage(li, -1) + } + ); + return options; +}; + +/* -------------------------------------------- */ + +/** + * Apply rolled dice damage to the token or tokens which are currently controlled. + * This allows for damage to be scaled by a multiplier to account for healing, critical hits, or resistance + * + * @param {HTMLElement} roll The chat entry which contains the roll data + * @param {Number} multiplier A damage multiplier to apply to the rolled damage. + * @return {Promise} + */ +function applyChatCardDamage(roll, multiplier) { + const amount = roll.find('.dice-total').last().text(); + return Promise.all(canvas.tokens.controlled.map(t => { + const a = t.actor; + return a.applyDamage(amount, multiplier); + })); +} + +/* -------------------------------------------- */ diff --git a/src/ose.js b/src/ose.js index 664ee2a..632448a 100644 --- a/src/ose.js +++ b/src/ose.js @@ -8,6 +8,7 @@ import { OseItem } from "./module/item/entity.js"; import { OSE } from "./module/config.js"; import { registerSettings } from './module/settings.js'; import { registerHelpers } from './module/helpers.js'; +import * as chat from "./module/chat.js"; /* -------------------------------------------- */ /* Foundry VTT Initialization */ @@ -64,5 +65,5 @@ Hooks.once("setup", function () { } }); - -Hooks.on("renderChatLog", (app, html, data) => OseItem.chatListeners(html)); \ No newline at end of file +Hooks.on("renderChatLog", (app, html, data) => OseItem.chatListeners(html)); +Hooks.on("getChatLogEntryContext", chat.addChatMessageContextOptions); \ No newline at end of file