mirror of
https://github.com/Foundryborne/daggerheart.git
synced 2026-01-12 03:31:07 +01:00
[Fix] Automation Fixes (#342)
* Initial * Split HopeFear automation by GM and Players * Fixed ActionToken automation
This commit is contained in:
parent
0dd5b53313
commit
aa2714e021
15 changed files with 87 additions and 76 deletions
|
|
@ -5,7 +5,7 @@ import * as documents from './module/documents/_module.mjs';
|
|||
import RegisterHandlebarsHelpers from './module/helpers/handlebarsHelper.mjs';
|
||||
import { DhDualityRollEnricher, DhTemplateEnricher } from './module/enrichers/_module.mjs';
|
||||
import { getCommandTarget, rollCommandToJSON } from './module/helpers/utils.mjs';
|
||||
import { NarrativeCountdowns, registerCountdownApplicationHooks } from './module/applications/ui/countdowns.mjs';
|
||||
import { NarrativeCountdowns } from './module/applications/ui/countdowns.mjs';
|
||||
import { DualityRollColor } from './module/data/settings/Appearance.mjs';
|
||||
import { DHRoll, DualityRoll, D20Roll, DamageRoll, DualityDie } from './module/dice/_module.mjs';
|
||||
import { renderDualityButton } from './module/enrichers/DualityRollEnricher.mjs';
|
||||
|
|
@ -168,7 +168,6 @@ Hooks.on('ready', () => {
|
|||
|
||||
registerCountdownHooks();
|
||||
socketRegistration.registerSocketHooks();
|
||||
registerCountdownApplicationHooks();
|
||||
registerRollDiceHooks();
|
||||
registerDHActorHooks();
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1337,9 +1337,10 @@
|
|||
"hint": "Automatically increase the GM's fear pool on a fear duality roll result."
|
||||
},
|
||||
"FIELDS": {
|
||||
"hope": {
|
||||
"label": "Hope",
|
||||
"hint": "Automatically increase a character's hope on a hope duality roll result."
|
||||
"hopeFear": {
|
||||
"label": "Hope & Fear",
|
||||
"gm": { "label": "GM" },
|
||||
"players": { "label": "Players" }
|
||||
},
|
||||
"actionPoints": {
|
||||
"label": "Action Points",
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
export default class DHTokenHUD extends TokenHUD {
|
||||
export default class DHTokenHUD extends foundry.applications.hud.TokenHUD {
|
||||
static DEFAULT_OPTIONS = {
|
||||
classes: ['daggerheart']
|
||||
};
|
||||
|
|
|
|||
|
|
@ -669,10 +669,7 @@ export default class CharacterSheet extends DHBaseActorSheet {
|
|||
} else if (item instanceof ActiveEffect) {
|
||||
item.toChat(this);
|
||||
} else {
|
||||
const wasUsed = await item.use(event);
|
||||
if (wasUsed && item.type === 'weapon') {
|
||||
Hooks.callAll(CONFIG.DH.HOOKS.characterAttack, {});
|
||||
}
|
||||
item.use(event);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -66,6 +66,11 @@ export default class DhCombatTracker extends foundry.applications.sidebar.tabs.C
|
|||
}
|
||||
|
||||
async setCombatantSpotlight(combatantId) {
|
||||
const update = {
|
||||
system: {
|
||||
'spotlight.requesting': false
|
||||
}
|
||||
};
|
||||
const combatant = this.viewed.combatants.get(combatantId);
|
||||
|
||||
const toggleTurn = this.viewed.combatants.contents
|
||||
|
|
@ -73,10 +78,18 @@ export default class DhCombatTracker extends foundry.applications.sidebar.tabs.C
|
|||
.map(x => x.id)
|
||||
.indexOf(combatantId);
|
||||
|
||||
if (this.viewed.turn !== toggleTurn) Hooks.callAll(CONFIG.DH.HOOKS.spotlight, {});
|
||||
if (this.viewed.turn !== toggleTurn) {
|
||||
const { updateCountdowns } = game.system.api.applications.ui.DhCountdowns;
|
||||
await updateCountdowns(CONFIG.DH.GENERAL.countdownTypes.spotlight.id);
|
||||
|
||||
const autoPoints = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation).actionPoints;
|
||||
if (autoPoints) {
|
||||
update.system.actionTokens = Math.max(combatant.system.actionTokens - 1, 0);
|
||||
}
|
||||
}
|
||||
|
||||
await this.viewed.update({ turn: this.viewed.turn === toggleTurn ? null : toggleTurn });
|
||||
await combatant.update({ 'system.spotlight.requesting': false });
|
||||
await combatant.update(update);
|
||||
}
|
||||
|
||||
static async requestSpotlight(_, target) {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
import { countdownTypes } from '../../config/generalConfig.mjs';
|
||||
import { GMUpdateEvent, RefreshType, socketEvent } from '../../systemRegistration/socket.mjs';
|
||||
import constructHTMLButton from '../../helpers/utils.mjs';
|
||||
import OwnershipSelection from '../dialogs/ownershipSelection.mjs';
|
||||
|
|
@ -328,43 +327,29 @@ export class EncounterCountdowns extends Countdowns {
|
|||
};
|
||||
}
|
||||
|
||||
export const registerCountdownApplicationHooks = () => {
|
||||
const updateCountdowns = async shouldProgress => {
|
||||
if (game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation).countdowns) {
|
||||
const countdownSetting = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Countdowns);
|
||||
for (let countdownCategoryKey in countdownSetting) {
|
||||
const countdownCategory = countdownSetting[countdownCategoryKey];
|
||||
for (let countdownKey in countdownCategory.countdowns) {
|
||||
const countdown = countdownCategory.countdowns[countdownKey];
|
||||
|
||||
if (shouldProgress(countdown)) {
|
||||
await countdownSetting.updateSource({
|
||||
[`${countdownCategoryKey}.countdowns.${countdownKey}.progress.current`]:
|
||||
countdown.progress.current - 1
|
||||
});
|
||||
await game.settings.set(
|
||||
CONFIG.DH.id,
|
||||
CONFIG.DH.SETTINGS.gameSettings.Countdowns,
|
||||
countdownSetting
|
||||
);
|
||||
foundry.applications.instances.get(`${countdownCategoryKey}-countdowns`)?.render();
|
||||
}
|
||||
export async function updateCountdowns(progressType) {
|
||||
const countdownSetting = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Countdowns);
|
||||
const update = Object.keys(countdownSetting).reduce((update, typeKey) => {
|
||||
return foundry.utils.mergeObject(
|
||||
update,
|
||||
Object.keys(countdownSetting[typeKey].countdowns).reduce((acc, countdownKey) => {
|
||||
const countdown = countdownSetting[typeKey].countdowns[countdownKey];
|
||||
if (countdown.progress.current > 0 && countdown.progress.type.value === progressType) {
|
||||
acc[`${typeKey}.countdowns.${countdownKey}.progress.current`] = countdown.progress.current - 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Hooks.on(CONFIG.DH.HOOKS.characterAttack, async () => {
|
||||
updateCountdowns(countdown => {
|
||||
return (
|
||||
countdown.progress.type.value === countdownTypes.characterAttack.id && countdown.progress.current > 0
|
||||
);
|
||||
});
|
||||
});
|
||||
return acc;
|
||||
}, {})
|
||||
);
|
||||
}, {});
|
||||
|
||||
Hooks.on(CONFIG.DH.HOOKS.spotlight, async () => {
|
||||
updateCountdowns(countdown => {
|
||||
return countdown.progress.type.value === countdownTypes.spotlight.id && countdown.progress.current > 0;
|
||||
});
|
||||
await countdownSetting.updateSource(update);
|
||||
await game.settings.set(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Countdowns, countdownSetting);
|
||||
|
||||
const data = { refreshType: RefreshType.Countdown };
|
||||
await game.socket.emit(`system.${CONFIG.DH.id}`, {
|
||||
action: socketEvent.Refresh,
|
||||
data
|
||||
});
|
||||
};
|
||||
Hooks.callAll(socketEvent.Refresh, data);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ export * as domainConfig from './domainConfig.mjs';
|
|||
export * as effectConfig from './effectConfig.mjs';
|
||||
export * as flagsConfig from './flagsConfig.mjs';
|
||||
export * as generalConfig from './generalConfig.mjs';
|
||||
export * as hooksConfig from './hooksConfig.mjs';
|
||||
export * as itemConfig from './itemConfig.mjs';
|
||||
export * as settingsConfig from './settingsConfig.mjs';
|
||||
export * as systemConfig from './system.mjs';
|
||||
|
|
|
|||
|
|
@ -376,15 +376,15 @@ export const abilityCosts = {
|
|||
export const countdownTypes = {
|
||||
spotlight: {
|
||||
id: 'spotlight',
|
||||
label: 'DAGGERHEART.CONFIG.CountdownTypes.Spotlight'
|
||||
label: 'DAGGERHEART.CONFIG.CountdownType.spotlight'
|
||||
},
|
||||
characterAttack: {
|
||||
id: 'characterAttack',
|
||||
label: 'DAGGERHEART.CONFIG.CountdownTypes.CharacterAttack'
|
||||
label: 'DAGGERHEART.CONFIG.CountdownType.characterAttack'
|
||||
},
|
||||
custom: {
|
||||
id: 'custom',
|
||||
label: 'DAGGERHEART.CONFIG.CountdownTypes.Custom'
|
||||
label: 'DAGGERHEART.CONFIG.CountdownType.custom'
|
||||
}
|
||||
};
|
||||
export const rollTypes = {
|
||||
|
|
|
|||
|
|
@ -1,4 +0,0 @@
|
|||
export const hooks = {
|
||||
characterAttack: 'characterAttackHook',
|
||||
spotlight: 'spotlightHook'
|
||||
};
|
||||
|
|
@ -3,7 +3,6 @@ import * as DOMAIN from './domainConfig.mjs';
|
|||
import * as ACTOR from './actorConfig.mjs';
|
||||
import * as ITEM from './itemConfig.mjs';
|
||||
import * as SETTINGS from './settingsConfig.mjs';
|
||||
import { hooks as HOOKS } from './hooksConfig.mjs';
|
||||
import * as EFFECTS from './effectConfig.mjs';
|
||||
import * as ACTIONS from './actionConfig.mjs';
|
||||
import * as FLAGS from './flagsConfig.mjs';
|
||||
|
|
@ -17,7 +16,6 @@ export const SYSTEM = {
|
|||
ACTOR,
|
||||
ITEM,
|
||||
SETTINGS,
|
||||
HOOKS,
|
||||
EFFECTS,
|
||||
ACTIONS,
|
||||
FLAGS
|
||||
|
|
|
|||
|
|
@ -38,6 +38,15 @@ export default class DHAttackAction extends DHDamageAction {
|
|||
};
|
||||
}
|
||||
|
||||
async use(event, ...args) {
|
||||
const result = await super.use(event, args);
|
||||
|
||||
const { updateCountdowns } = game.system.api.applications.ui.DhCountdowns;
|
||||
await updateCountdowns(CONFIG.DH.GENERAL.countdownTypes.characterAttack.id);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// get modifiers() {
|
||||
// return [];
|
||||
// }
|
||||
|
|
|
|||
|
|
@ -102,7 +102,7 @@ class DhCountdown extends foundry.abstract.DataModel {
|
|||
value: new fields.StringField({
|
||||
required: true,
|
||||
choices: CONFIG.DH.GENERAL.countdownTypes,
|
||||
initial: CONFIG.DH.GENERAL.countdownTypes.spotlight.id,
|
||||
initial: CONFIG.DH.GENERAL.countdownTypes.custom.id,
|
||||
label: 'DAGGERHEART.APPLICATIONS.Countdown.FIELDS.countdowns.element.progress.type.value.label'
|
||||
}),
|
||||
label: new fields.StringField({
|
||||
|
|
@ -132,7 +132,13 @@ class DhCountdown extends foundry.abstract.DataModel {
|
|||
export const registerCountdownHooks = () => {
|
||||
Hooks.on(socketEvent.Refresh, ({ refreshType, application }) => {
|
||||
if (refreshType === RefreshType.Countdown) {
|
||||
foundry.applications.instances.get(application)?.render();
|
||||
if (application) {
|
||||
foundry.applications.instances.get(application)?.render();
|
||||
} else {
|
||||
foundry.applications.instances.get('narrative-countdowns').render();
|
||||
foundry.applications.instances.get('encounter-countdowns').render();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -4,20 +4,22 @@ export default class DhAutomation extends foundry.abstract.DataModel {
|
|||
static defineSchema() {
|
||||
const fields = foundry.data.fields;
|
||||
return {
|
||||
hope: new fields.BooleanField({
|
||||
required: true,
|
||||
initial: false,
|
||||
label: 'DAGGERHEART.SETTINGS.Automation.FIELDS.hope.label'
|
||||
}), // Label need to be updated into something like "Duality Roll Auto Gain" + a hint
|
||||
hopeFear: new fields.SchemaField({
|
||||
gm: new fields.BooleanField({
|
||||
required: true,
|
||||
initial: false,
|
||||
label: 'DAGGERHEART.SETTINGS.Automation.FIELDS.hopeFear.gm.label'
|
||||
}),
|
||||
players: new fields.BooleanField({
|
||||
required: true,
|
||||
initial: false,
|
||||
label: 'DAGGERHEART.SETTINGS.Automation.FIELDS.hopeFear.players.label'
|
||||
})
|
||||
}),
|
||||
actionPoints: new fields.BooleanField({
|
||||
required: true,
|
||||
initial: false,
|
||||
label: 'DAGGERHEART.SETTINGS.Automation.FIELDS.actionPoints.label'
|
||||
}),
|
||||
countdowns: new fields.BooleanField({
|
||||
requireD: true,
|
||||
initial: false,
|
||||
label: 'DAGGERHEART.SETTINGS.Automation.FIELDS.countdowns.label'
|
||||
})
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -175,9 +175,10 @@ export default class DHRoll extends Roll {
|
|||
|
||||
export const registerRollDiceHooks = () => {
|
||||
Hooks.on(`${CONFIG.DH.id}.postRollDuality`, async (config, message) => {
|
||||
const hopeFearAutomation = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation).hopeFear;
|
||||
if (
|
||||
!config.source?.actor ||
|
||||
!game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation).hope ||
|
||||
(game.user.isGM ? !hopeFearAutomation.gm : !hopeFearAutomation.players) ||
|
||||
config.roll.type === 'reaction'
|
||||
)
|
||||
return;
|
||||
|
|
@ -185,9 +186,9 @@ export const registerRollDiceHooks = () => {
|
|||
const actor = await fromUuid(config.source.actor),
|
||||
updates = [];
|
||||
if (!actor) return;
|
||||
if (config.roll.isCritical || config.roll.result.duality === 1) updates.push({ type: 'hope', value: 1 });
|
||||
if (config.roll.isCritical) updates.push({ type: 'stress', value: -1 });
|
||||
if (config.roll.result.duality === -1) updates.push({ type: 'fear', value: 1 });
|
||||
if (config.roll.isCritical || config.roll.result.duality === 1) updates.push({ key: 'hope', value: 1 });
|
||||
if (config.roll.isCritical) updates.push({ key: 'stress', value: -1 });
|
||||
if (config.roll.result.duality === -1) updates.push({ key: 'fear', value: 1 });
|
||||
|
||||
if (updates.length) actor.modifyResource(updates);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,10 @@
|
|||
<div>
|
||||
{{formGroup settingFields.schema.fields.hope value=settingFields._source.hope localize=true}}
|
||||
<div class="form-group">
|
||||
<label>{{localize "DAGGERHEART.SETTINGS.Automation.FIELDS.hopeFear.label"}}</label>
|
||||
{{formGroup settingFields.schema.fields.hopeFear.fields.gm value=settingFields._source.hopeFear.gm localize=true}}
|
||||
{{formGroup settingFields.schema.fields.hopeFear.fields.players value=settingFields._source.hopeFear.players localize=true}}
|
||||
|
||||
</div>
|
||||
{{formGroup settingFields.schema.fields.actionPoints value=settingFields._source.actionPoints localize=true}}
|
||||
{{formGroup settingFields.schema.fields.countdowns value=settingFields._source.countdowns localize=true}}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue