Latest version | 4.1.1 |
---|---|
Minimum Core | 12 |
Compatible Core | 12 |
Last updated | 1 week ago |
Created | 9 months ago |
Authors |
|
Languages |
English |
Systems |
Dnd5e |
Project source | Project URL |
A module for dnd5e on foundryvtt that allows the effects and damage trays to be used more effectively.
Allows users to use the effect tray as much or as little as wanted by the GM, up to and including transferal to targets they do not own. User ability to transfer effects to and from any target is on by default.
Allows users to use the damage tray for selected tokens that they own, and for targeted tokens (either that they own, or ones they don't own with a setting). User ability to use the damage tray is on by default, but unless the relevant setting is selected, they cannot damage targets.
This module is NOT compatible with Midi Quality of Life Improvements (midi-qol), and I have no plans to support it.
Now includes three helper functions exposed in the global scope under effectiv
, effectiv.applyEffect
, effectiv.applyDamage
and effective.partitionTargets
. These functions have not been heavily tested and are included now in the hopes that, if someone wants to use them, they will also test them for issues.
applyEffect
, a helper function to allow users to apply effects. It allows users to apply effects via macro (or other module), and can take a variety of types of data when doing so, allowing effect data to be passed as the full ActiveEffect document, an effect Uuid, or an object (note that passing it as an object will not interact with refreshing duration or deleting effects of same origin, as determined by module setting, because creating an effect from an object will have its own unique origin). Similarly, this function allows target data to be passed as an array of Uuids, a single Uuid, an array of Tokens, or a Set, as game.user.targets
.
This helper also allows the use of the other things the effects tray does, primarily flagging effects with spellLevel, or any other arbitrary flags (via effectData), and making an effect dependent on a concentration effect (so it will be deleted when the concentration effect is). If concentration is used, because it passed as an ID, you must also pass the Uuid or Actor document of the actor the concentration effect is on.
/**
* Helper function to allow for macros or other applications to apply effects to owned and unowned targets.
* @param {string|object|ActiveEffect5e} effect The effect to apply.
* @param {Set|Token5e[]|string[]|string} targets Targeted tokens.
* @param {object} [options]
* @param {object} [options.effectData] A generic data object, which typically handles the level the originating spell was cast at,
* if it originated from a spell, if any. Use flags like { "flags.dnd5e.spellLevel": 1 }.
* @param {string} [options.concentration] The ID (not Uuid) of the concentration effect this effect is dependent on, if any.
* @param {string|Actor5e} [options.caster] The Uuid or Actor5e document of the actor that cast the spell that requires concentration, if any.
*/
async function applyEffect(
effect,
targets,
{ effectData: null, concentration: null, caster: null } = {}
)
/* in use...*/
effectiv.applyEffect(
effect,
targets,
{ effectData: null, concentration: null, caster: null } = {}
)
applyDamage
, helper function to allow users to apply damage. This function has been tested not at all and is included as a courtesy. Personally I find the way damage information must be structured to respect resistances, etc is too much of a mess to test this even a single time, but if someone really wants to do this over a socket but didn't write their own socket handler for it...here you go. Full, extensive documentation of the array that must be created is in scripts/api.mjs, copied directly from dnd5e
, with the exception that socket transmission requires the sets to be arrays. Unlike applyEffect
, this applies no damage via the requesting client, and so is basically only meant for damaging unowned targets. Users wishing to apply damage to owned targets should simply use the system's Actor#applyDamage
. See README on the repo for full documentation.
/**
* Helper function to allow for macros or other applications to apply damage via socket request.
* @param {Array} damage Array of damage objects; see above.
* @param {Array} opts Object of options (which may inlude arrays); see above.
* @param {string} id Uuid of the target.
*/
async function applyDamage(damage = [], opts = {}, id)
/* in use...*/
effectiv.applyDamage(damage = [], opts = {}, id)
partitionTargets
, a function similar to foundry's Array#partition
but specifically designed to handle game.user.targets
, a set, or an array of tokens. It sorts them into two arrays, the first array containing tokens that the user owns, and the second array containing those token's document.uuid
s. This can be useful for determining what information needs to be sent over sockets. I have no idea why anyone would use this function, but here it is.
/**
* Sort tokens into owned and unowned categories.
* @param {Set|array} targets The set or array of tokens to be sorted.
* @returns {Array} An Array of length two, the elements of which are the partitioned pieces of the original.
*/
function partitionTargets(targets)
/* in use...*/
effectiv.partitionTargets(targets)
Now includes two hooks, effectiv.preApplyEffect
and effectiv.applyEffect
. The former allows the data to be modified and explicitly returning false
will prevent the effect from being applied. The later passes the same (modified in the case of effectData), information in its final state upon application.
These hooks have not been extensively tested.
/**
* Hook called before the effect is completed and applied.
* @param {Actor5e} actor The actor to create the effect on.
* @param {ActiveEffect5e} effect The effect to create.
* @param {object} [options] Additional data that may be included with the effect.
* @param {object} [options.effectData] A generic data object that contains spellLevel in a `dnd5e` scoped flag, and whatever else.
* @param {ActiveEffect5e} [options.concentration] The concentration effect on which `effect` is dependent, if it requires concentration.
*/
Hooks.call("effectiv.preApplyEffect", actor, effect, { effectData, concentration });
/**
* Hook called before the effect is completed and applied. Same as above except for effectData.
* @param {Actor5e} actor The actor to create the effect on.
* @param {ActiveEffect5e} effect The effect to create.
* @param {object} [options] Additional data that may be included with the effect.
* @param {object} [options.effectData] The packaged effect immediately before application.
* @param {ActiveEffect5e} [options.concentration] The concentration effect on which `effect` is dependent, if it requires concentration.
*/
Hooks.callAll("effectiv.applyEffect", actor, effect, { effectData, concentration });
Scope: Replaces the effects tray in chat messages with a similar one that allows all users, not just GMs or the chat message's creator, to apply active effects to tokens they control (and have selected) by looping over all messages in the "dnd5e.renderChatMessage" hook. Extends the system's damage application element class to allow users who are not GMs to use the damage tray. Additionally, transmits target target and change data via sockets to allow an active GM client to apply effects (or damage) to a non GM user's targets.
License: MIT License.
Additional Info: Thanks to Zhell for help with adding actors to a set and lots of other stuff (and for the github action), and to Flix for much encouragement. Thanks also to ChaosOS for help with sockets, and DrentalBot for help with suppressing the system's context menu.
Some code has been adapted from dnd5e, particularly the extension of the tray custom html elements, and unifying module and system logic for collapsing or expanding trays.
To install this package, open your Foundry Setup screen and navigate to your Module tab and click the Install Module button.
From there, you can either search for the package unique name: effectivetray or copy its manifest URL:
And paste it to the input box at the bottom of your window.
You can install this package directly to your Forge account.
Necessary cookies are absolutely essential for the website to function properly. This category only includes cookies that ensures basic functionalities and security features of the website. These cookies do not store any personal information.
Functional cookies help to perform certain functionalities like sharing the content of the website on social media platforms, collect feedbacks, and other third-party features.
Performance cookies are used to understand and analyze the key performance indexes of the website which helps in delivering a better user experience for the visitors.
Advertisement cookies are used to deliver visitors with customized advertisements based on the pages they visited before and analyze the effectiveness of the ad campaign.
Analytical cookies are used to understand how visitors interact with the website. These cookies help provide information on metrics the number of visitors, bounce rate, traffic source, etc.