Borders: Fix borders on active combat change

A scene can have multiple combat encounters, but only one
can be active at a time.
Changing from one to the other does not trigger any of the regular
combat hooks, but it can be detected using a combat /document/ hook.

Register on the combat document update hook and update the borders
when the active state of the encounter is changed.

Both the previous and new active combats produce an update, and
the previous combat becoming inactive always comes first.
This means that we can safely set all token borders from the
previous document to the default border and they will be
updated accordingly by the new combat becoming active.

Update the comment of the data member for
`combat_hook_update_token_borders()`, as we re-use it for
the combat switch and we didn't use the `turn` member anymore.
This commit is contained in:
trotFunky 2025-06-02 22:11:14 +01:00
parent 383f66e297
commit cc7db632d1
2 changed files with 26 additions and 9 deletions

View file

@ -36,14 +36,6 @@ The module supports going back and forth in the combat rounds, as well as going
- An image to use for the default/idle border - An image to use for the default/idle border
- An image to use for the took turn/played/inactive border - An image to use for the took turn/played/inactive border
### Limitations
There are currently one minor issue that might be fixed :
1. The token borders will be incorrect when switching between different encounters in the same scene
- Producing a combat event or switching away and back to the scene will fix it.
- It doesn't appear that there is an event on combat switch that could be hooked into, which makes fixing the
issue uncertain.
## Token UI adjustments ## Token UI adjustments
Given that we add a border *on* the tokens, it conflicts with the base attribute bars which are drawn over the token's Given that we add a border *on* the tokens, it conflicts with the base attribute bars which are drawn over the token's

View file

@ -199,7 +199,7 @@ function token_combat_visibility_remote_update(scene_id, token_id, round) {
/** /**
* Called by turn and round hooks, so the borders can be updated when going backwards as well as forwards. * Called by turn and round hooks, so the borders can be updated when going backwards as well as forwards.
* @param {Combat} combat The combat in which the token is active * @param {Combat} combat The combat in which the token is active
* @param {{round: number, turn: number}} data The turn data for this update * @param {{round: number}} data The turn data for this update
*/ */
function combat_hook_update_token_borders(combat, data) { function combat_hook_update_token_borders(combat, data) {
// Turns is the array of *tokens having turns in this encounter*. // Turns is the array of *tokens having turns in this encounter*.
@ -239,6 +239,31 @@ function combat_border_main() {
Hooks.on("combatTurn", combat_hook_update_token_borders); Hooks.on("combatTurn", combat_hook_update_token_borders);
Hooks.on("combatRound", combat_hook_update_token_borders); Hooks.on("combatRound", combat_hook_update_token_borders);
// Hook on the combat document update directly to handle active combat switches.
Hooks.on("updateCombat", (combat, changed) => {
// We only care about switching active combats
if (!("active" in changed)) {
return;
}
/*
* The *previous* active combat is switched to inactive *first*, so we can
* just revert all borders to the default state.
* When the new combat becomes active, we can just check as if it were a
* regular combat update.
* This makes sure to handle tokens which were in the previous combat, but not
* in the new one.
*/
if (!changed.active) {
for (let combatant of combat.combatants) {
socket.executeForEveryone(SocketMessages.SetBorder,
combatant.sceneId, combatant.tokenId, false).then();
}
} else {
combat_hook_update_token_borders(combat, {round: combat.round})
}
})
// No Foundry hook on end of combat, so use Fabula Ultima's. // No Foundry hook on end of combat, so use Fabula Ultima's.
Hooks.on(FUHooks.COMBAT_EVENT, (combat_event) => { Hooks.on(FUHooks.COMBAT_EVENT, (combat_event) => {
if (combat_event.type === FU.combatEvent.endOfCombat) { if (combat_event.type === FU.combatEvent.endOfCombat) {