More Hooks 5e

https://github.com/ElfFriend-DnD/foundryvtt-more-hooks-5e I'm going to try to use this library to hammer out the desires and API for a set of hooks to add to the system itself, I'm very keen on getting feedback about this. The hooks are named after the method which they are patched into, and here's the initial list: - Actor5e.rollAbilitySave - Actor5e.rollAbilityTest - Actor5e.rollDeathSave - Actor5e.rollSkill - Item5e.roll - Item5e.rollAttack - Item5e.rollDamage - Item5e.rollFormula - Item5e.rollRecharge - Item5e.rollToolCheck I intend to be releasing some small modules coming up which leverage these hooks to do very specific things with the item usage workflow. It's my hope that in time whichever hooks of these prove useful will be added to the core system itself.
GitHub
GitHub - ElfFriend-DnD/foundryvtt-more-hooks-5e
Contribute to ElfFriend-DnD/foundryvtt-more-hooks-5e development by creating an account on GitHub.
C
Calego940d ago
At the moment, each hook is injected via libwrapper into the method the hook is named after, and each one runs after the operation itself completes. These are all called with callAll, and they all fire on every connected client. Version 1's goal:
Enable modules that want to react to an operation's outcome to do so without relying on chat messages.
My own first usage: - When an attack roll is rolled, check if the targeted tokens are hit. If so, notify the GM. 15 minutes in, already have feedback: Need the originating user's ID somewhere on these hooks. Else I can't get the user's targets.
I
Ikaguia940d ago
and each one runs after the operation itself completes.
Would it be a good idea to add a pre version of each hook as well?
A
arbron940d ago
Having a series of pre hooks that are called after the roll data is prepared but before the roll is executed would probably be helpful, maybe as a call with the option to cancel the roll
C
Calego939d ago
I think yes, definitely feels like a useful thing.
C
Calego939d ago
Here's a sample project leveraging this library: https://github.com/ElfFriend-DnD/foundryvtt-attack-roll-check-5e Still a fair bit to wire up inside the chat card, but the hook makes this work in a clean, logical, expected way.
GitHub
GitHub - ElfFriend-DnD/foundryvtt-attack-roll-check-5e
Contribute to ElfFriend-DnD/foundryvtt-attack-roll-check-5e development by creating an account on GitHub.
B
BadIdeasBureau939d ago
Potentially being able to mutate the roll in the pre hook? It's going to be a bit limited since you'll presumably need to keep things synchronous (so no additional dialog prompts), but could be handy for e.g. "+X against giants" (check user's target, add X to roll if target is a giant)
C
Calego939d ago
I'm also unsure if having a local as well as a global hook for each of these is worth it. For the pre hooks for instance, running those through the socket wouldn't be terribly useful without also having a way to talk back to the original client (which is just a nightmare to think about). So pre would have to happen locally. But would it also make sense to have a Item5e.roll.local? I'm not convinced, because a module could easily do
Hooks.on('Item5e.roll', (_item, _chatMessage, _actor, {userId}) => {
if (userId !== game.user.id) return;
// otherwise do stuff
})
Hooks.on('Item5e.roll', (_item, _chatMessage, _actor, {userId}) => {
if (userId !== game.user.id) return;
// otherwise do stuff
})
On the other hand... A module could also 'easily' DIY the socket thing, and making all hooks local all the time would drastically reduce the complexity here. With core hooks, yeah everything must be Synchronous. But a pre hook would adopt the same syntax Core uses of return false and the rest of the function stops I think. So if you really had to do something asynchronous, you could escape hatch out of the hook and DIY the rest of the flow. Not ideal, but itssomething
B
BadIdeasBureau939d ago
... yeah, I see how that can be an option, but... Ew. I might need to make a module that does that just to hide away the ugly bit 😛
C
Calego939d ago
I haven't looked too hard at warpgate's event system, but I suspect such a thing could be used to great effect here. However, it's much more likely I can get these changes into the core system if I adopt the same patterns core uses.
UU
Unknown User939d ago
LTL
Leo The League Lion939d ago
@lukeabby gave vote LeaguePoints™ to @calego (#1 • 1238)
UU
Unknown User939d ago
C
Calego939d ago
takeDamage is an interesting idea
UU
Unknown User939d ago
C
Calego939d ago
I would probably hook into Actor5e.applyDamage
UU
Unknown User939d ago
C
Calego939d ago
there's a method, it's what's used by core when you right click on a damage roll I don't think I follow your use case here You'd do something like:
Hooks.on('Actor5e.applyDamage', (actor, damageTaken) => {
if (damageTaken.type === 'fire' && actor.resistances.includes('fire') {
return damageTaken / 2
}
})
Hooks.on('Actor5e.applyDamage', (actor, damageTaken) => {
if (damageTaken.type === 'fire' && actor.resistances.includes('fire') {
return damageTaken / 2
}
})
? Mmm this would need a pre hook actually
UU
Unknown User939d ago
C
Calego939d ago
makes sense makes sense
UU
Unknown User939d ago
C
Calego939d ago
Mmk. I guess next on my todo list is figuring out pre hooks! I ❤️ Midi for all it does, but it's just too big a module for me to want to use in the games I don't GM. My players-turned-gms are real bad at configuring things, so my endgame here is to have a bunch of tiny modules that do little pieces of Midi's workflow.
UU
Unknown User939d ago
A
arbron939d ago
Any useful damage hooks will need to involve a new damage method, because the current one only takes damage and a multiplier Maybe something like a new autoApplyDamage method that takes an array of damages with types and determines the multiplier automatically
C
Calego935d ago
Something MRE does which is one of its few claims to fame is split the damage card up by damage formula rolled and allow each individual formula to be applied. I think such a change would be a good one for the core system as well, it would at least help with this. I've reached a conundrum. Initially I thought the "run every hook on every client" was a good play.
A GM only operation can happen on the GM's hook subscription.
However, I'm coming to realize that some things I want to happen require more input on the user's which causes the trigger's side first. So now I'm wondering if these hooks should all occur on the client-side, and expect modules to handle their own socket implemention. Two examples (as they're the only two I know of using this lib so far): Attack Roll Check works when the GM client hears an Attack Roll hook. It then looks up the user's targets with game.users.get().targets, and does the monster math. At the end the GM creates a whisper to itself with the results. This works pretty nicely, though it would also be easy to switch this around to have every client listen for its own attackRoll, then do the math on that client and broadcast a message to the GM from that client. (I wasn't able to make a truly invisible chat message from a different user to the GM when I tried before but I'm sure it's possible). This implementation would not require sockets at all (assuming the chat message problem is solved). ---- Auto NPC Save is prooving to be much more intricate. On the surface it's identical to the other, except firing on Item roll instead of attack roll. But the intricacies come with measured templates. I'd like to support using a module like DF QOL's "Auto target on template drop" to get the targets before doing the saves. The hooks surrounding measured template placement don't get broadcast to all clients though, so that event sequence is much harder to detect on the GM client. For the Auto NPC Save, I would potentially need a socket event to fire when "Targeting is done" to mark when targets are available, and also allow the GM client to start prompting for saves (with core there's no fast forwarding of these saves). It wouldn't do for the player to be prompted for the NPC saves. The more I think about it, the more it makes sense to make the library consumers handle their own sockets, instead of having one in the library and also possibly needing them in the consumers. I've slept on it, and asked in dev-support about the way core thinks about hooks. I've decided to un-do the socket implementation in more-hooks-5e. This is going to be a breaking change, but we're still in pre-1.0.0 so I'm only bumping the minor version. I suspect this will be low impact as long as I update the only module i know of which relies on these hooks beforehand. <#901108458944876584> <- mothership thread if anyone's interested
Want results from more Discord servers?
Add your server
More Posts
createEmbeddedDocuments issueI'm going to throw my code in a thread so I don't clutter this channel up with a wall of textBase Item@otigon it occurs to me that the new `baseItem` property on weapons and such is probably of interestCompendium loadinghmm ghost, I added some console.time tags here and there to measure the difference between loading oSkill and Ability bonusesA massive enhancement of Skills and Ability Checks/Saves allows them to be individually affected by 150 Sheet Changes@sdenec @lordzeel Sheet Changes required: - New Cog-menu for Ability Scores and Skills to support neDocumentData shennaneginsTIL: It is possible to `update` an Actor or Item's `data.data` with arbitrary information that isn'tflag shenanneginsTIL you can set the `flags` key on a document to whatever you want to (e.g. a string). This is a surraaeAfter some discussion yesterday in #active-effects , I decided to try to create a system-agnostic modevMode json changed warningI checked the module repo and I honestly can't figure out where I would plug in my code. I'd be guesS3 File Picker SettingsCan someone with an S3 configuration give me a test of the FilePicker settings api and tell me if a item preCreate@sol.folango @mrprimate (pinging you two in particular because you do import stuff involving existinItem Macro Compendium WorkflowOkay, here's a long one that's a bit of a doozy. I'm looking at setting up some sort of tooling/workItem Specific Crit DetailsOh that critical hit thing is gonna hit MRE too isn't it... hrm...1.5.x 72%@dnd5e No action required (but suggested 🙂 ) The 1.5.0 milestone is ~72% complete. It has a due daV9 Tabs IssueIf you never figured this out, here's why this happened: A small change in `Tabs` during v9 causes sDeck Creation MacroI created a macro to fill out a 52-card deck, you set the ID of the deck and the base URL of the foldevmode-issues@arcanist figured out, the flex layout elements have `pointer-events: none`, so anything injected wifunction vs methodAnyone know of a good guide that explains the difference between a function and a method? I don't reActive Effect HelpAnd it should be the actual ActiveEffect document for the effect, not just the id. I don't have theTOL JEs@badgerwerks I haven't had a chance to poke around in TOB/BoL yet, but I wanted to ask how you did t