mirror of
https://github.com/Foundryborne/daggerheart.git
synced 2026-01-11 19:25:21 +01:00
[PR] Updating the logic for rangeDependencies so that paired weapons work with multiple adversaries (#1434)
* Include item effects when applying rangeDependence * Creating a new method to update range dependent effects that uses the players targets * Using debouncing to fix an issue with selected and unselecting targets * Using token destinations instead of their current location for calculation range
This commit is contained in:
parent
16f6fa98a6
commit
7926c614e3
1 changed files with 51 additions and 33 deletions
|
|
@ -246,52 +246,70 @@ Hooks.on('chatMessage', (_, message) => {
|
|||
}
|
||||
});
|
||||
|
||||
Hooks.on('moveToken', async (movedToken, data) => {
|
||||
const effectsAutomation = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation).effects;
|
||||
if (!effectsAutomation.rangeDependent) return;
|
||||
const updateActorsRangeDependentEffects = async (token) => {
|
||||
const rangeMeasurement = game.settings.get(
|
||||
CONFIG.DH.id,
|
||||
CONFIG.DH.SETTINGS.gameSettings.variantRules
|
||||
).rangeMeasurement;
|
||||
|
||||
const rangeDependantEffects = movedToken.actor.effects.filter(effect => effect.system.rangeDependence?.enabled);
|
||||
for (let effect of token.actor.allApplicableEffects()) {
|
||||
if (!effect.system.rangeDependence?.enabled) continue;
|
||||
const { target, range, type } = effect.system.rangeDependence;
|
||||
|
||||
const updateEffects = async (disposition, token, effects, effectUpdates) => {
|
||||
const rangeMeasurement = game.settings.get(
|
||||
CONFIG.DH.id,
|
||||
CONFIG.DH.SETTINGS.gameSettings.variantRules
|
||||
).rangeMeasurement;
|
||||
|
||||
for (let effect of effects.filter(x => x.system.rangeDependence?.enabled)) {
|
||||
const { target, range, type } = effect.system.rangeDependence;
|
||||
if ((target === 'friendly' && disposition !== 1) || (target === 'hostile' && disposition !== -1))
|
||||
return false;
|
||||
// If there are no targets, assume false. Otherwise, start with the effect enabled.
|
||||
let enabledEffect = game.user.targets.size !== 0;
|
||||
// Expect all targets to meet the rangeDependence requirements
|
||||
for (let userTarget of game.user.targets) {
|
||||
const disposition = userTarget.document.disposition;
|
||||
if ((target === 'friendly' && disposition !== 1) || (target === 'hostile' && disposition !== -1)) {
|
||||
enabledEffect = false;
|
||||
break;
|
||||
}
|
||||
|
||||
const distanceBetween = canvas.grid.measurePath([
|
||||
{ ...movedToken.toObject(), x: data.destination.x, y: data.destination.y },
|
||||
token
|
||||
userTarget.document.movement.destination,
|
||||
token.movement.destination
|
||||
]).distance;
|
||||
const distance = rangeMeasurement[range];
|
||||
|
||||
const reverse = type === CONFIG.DH.GENERAL.rangeInclusion.outsideRange.id;
|
||||
const newDisabled = reverse ? distanceBetween <= distance : distanceBetween > distance;
|
||||
const oldDisabled = effectUpdates[effect.uuid] ? effectUpdates[effect.uuid].disabled : newDisabled;
|
||||
effectUpdates[effect.uuid] = {
|
||||
disabled: oldDisabled || newDisabled,
|
||||
value: effect
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
const effectUpdates = {};
|
||||
for (let token of game.scenes.find(x => x.active).tokens) {
|
||||
if (token.id !== movedToken.id) {
|
||||
await updateEffects(token.disposition, token, rangeDependantEffects, effectUpdates);
|
||||
if (reverse ? distanceBetween <= distance : distanceBetween > distance) {
|
||||
enabledEffect = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (token.actor) await updateEffects(movedToken.disposition, token, token.actor.effects, effectUpdates);
|
||||
await effect.update({ disabled: !enabledEffect });
|
||||
}
|
||||
}
|
||||
|
||||
for (let key in effectUpdates) {
|
||||
const effect = effectUpdates[key];
|
||||
await effect.value.update({ disabled: effect.disabled });
|
||||
const updateAllRangeDependentEffects = async () => {
|
||||
const effectsAutomation = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation).effects;
|
||||
if (!effectsAutomation.rangeDependent) return;
|
||||
|
||||
// Only consider tokens on the active scene
|
||||
const tokens = game.scenes.find(x => x.active).tokens;
|
||||
if (game.user.character) {
|
||||
// The character updates their character's token. There can be only one token.
|
||||
const characterToken = tokens.find(x => x.actor === game.user.character);
|
||||
updateActorsRangeDependentEffects(characterToken);
|
||||
} else if (game.user.isGM) {
|
||||
// The GM is responsible for all other tokens.
|
||||
const playerCharacters = game.users.players.filter(x => x.active).map(x => x.character);
|
||||
for (let token of tokens.filter(x => !playerCharacters.includes(x.actor))) {
|
||||
updateActorsRangeDependentEffects(token);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const debouncedRangeEffectCall = foundry.utils.debounce(updateAllRangeDependentEffects, 50);
|
||||
|
||||
Hooks.on('targetToken', async (user, token, targeted) => {
|
||||
debouncedRangeEffectCall();
|
||||
});
|
||||
|
||||
Hooks.on('moveToken', async (movedToken, data) => {
|
||||
debouncedRangeEffectCall();
|
||||
});
|
||||
|
||||
Hooks.on('renderCompendiumDirectory', (app, html) => applications.ui.ItemBrowser.injectSidebarButton(html));
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue