mirror of
https://github.com/Foundryborne/daggerheart.git
synced 2026-01-11 19:25:21 +01:00
Initial
This commit is contained in:
parent
bca7e0d3c9
commit
36eac51041
14 changed files with 171 additions and 8 deletions
|
|
@ -84,6 +84,8 @@ Hooks.once('init', () => {
|
|||
fields
|
||||
};
|
||||
|
||||
game.system.registeredTriggers = new RegisteredTriggers();
|
||||
|
||||
const { DocumentSheetConfig } = foundry.applications.apps;
|
||||
DocumentSheetConfig.unregisterSheet(TokenDocument, 'core', foundry.applications.sheets.TokenConfig);
|
||||
DocumentSheetConfig.registerSheet(TokenDocument, SYSTEM.id, applications.sheetConfigs.DhTokenConfig, {
|
||||
|
|
@ -378,3 +380,33 @@ Hooks.on('moveToken', async (movedToken, data) => {
|
|||
|
||||
Hooks.on('renderCompendiumDirectory', (app, html) => applications.ui.ItemBrowser.injectSidebarButton(html));
|
||||
Hooks.on('renderDocumentDirectory', (app, html) => applications.ui.ItemBrowser.injectSidebarButton(html));
|
||||
|
||||
class RegisteredTriggers extends Map {
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
|
||||
async registerTriggers(trigger, actor, uuid, commands) {
|
||||
const existingTrigger = this.get(trigger);
|
||||
if (!existingTrigger) this.set(trigger, new Map());
|
||||
|
||||
this.get(trigger).set(uuid, { actor, commands });
|
||||
}
|
||||
|
||||
async runTrigger(trigger, currentActor, ...args) {
|
||||
const updates = [];
|
||||
const dualityTrigger = this.get(trigger);
|
||||
if (dualityTrigger) {
|
||||
for (let { actor, commands } of dualityTrigger.values()) {
|
||||
if (currentActor?.uuid !== actor) continue;
|
||||
|
||||
for (let command of commands) {
|
||||
const commandUpdates = await command(...args);
|
||||
if (commandUpdates?.length) updates.push(...commandUpdates);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return updates;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1217,6 +1217,10 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"Triggers": {
|
||||
"dualityRoll": "Duality Roll",
|
||||
"fearRoll": "Fear Roll"
|
||||
},
|
||||
"WeaponFeature": {
|
||||
"barrier": {
|
||||
"name": "Barrier",
|
||||
|
|
@ -2057,7 +2061,8 @@
|
|||
"itemFeatures": "Item Features",
|
||||
"questions": "Questions",
|
||||
"configuration": "Configuration",
|
||||
"base": "Base"
|
||||
"base": "Base",
|
||||
"triggers": "Triggers"
|
||||
},
|
||||
"Tiers": {
|
||||
"singular": "Tier",
|
||||
|
|
|
|||
|
|
@ -29,7 +29,9 @@ export default class DHActionBaseConfig extends DaggerheartSheet(ApplicationV2)
|
|||
removeElement: this.removeElement,
|
||||
editEffect: this.editEffect,
|
||||
addDamage: this.addDamage,
|
||||
removeDamage: this.removeDamage
|
||||
removeDamage: this.removeDamage,
|
||||
addTrigger: this.addTrigger,
|
||||
removeTrigger: this.removeTrigger
|
||||
},
|
||||
form: {
|
||||
handler: this.updateForm,
|
||||
|
|
@ -55,6 +57,10 @@ export default class DHActionBaseConfig extends DaggerheartSheet(ApplicationV2)
|
|||
effect: {
|
||||
id: 'effect',
|
||||
template: 'systems/daggerheart/templates/sheets-settings/action-settings/effect.hbs'
|
||||
},
|
||||
trigger: {
|
||||
id: 'trigger',
|
||||
template: 'systems/daggerheart/templates/sheets-settings/action-settings/trigger.hbs'
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -82,6 +88,14 @@ export default class DHActionBaseConfig extends DaggerheartSheet(ApplicationV2)
|
|||
id: 'effect',
|
||||
icon: null,
|
||||
label: 'DAGGERHEART.GENERAL.Tabs.effects'
|
||||
},
|
||||
trigger: {
|
||||
active: false,
|
||||
cssClass: '',
|
||||
group: 'primary',
|
||||
id: 'trigger',
|
||||
icon: null,
|
||||
label: 'DAGGERHEART.GENERAL.Tabs.triggers'
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -111,6 +125,7 @@ export default class DHActionBaseConfig extends DaggerheartSheet(ApplicationV2)
|
|||
context.baseSaveDifficulty = this.action.actor?.baseSaveDifficulty;
|
||||
context.baseAttackBonus = this.action.actor?.system.attack?.roll.bonus;
|
||||
context.hasRoll = this.action.hasRoll;
|
||||
context.triggerOptions = CONFIG.DH.TRIGGER.triggers;
|
||||
|
||||
const settingsTiers = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.LevelTiers).tiers;
|
||||
context.tierOptions = [
|
||||
|
|
@ -224,6 +239,18 @@ export default class DHActionBaseConfig extends DaggerheartSheet(ApplicationV2)
|
|||
this.constructor.updateForm.bind(this)(null, null, { object: foundry.utils.flattenObject(data) });
|
||||
}
|
||||
|
||||
static addTrigger() {
|
||||
const data = this.action.toObject();
|
||||
data.triggers.push({ hook: CONFIG.DH.TRIGGER.triggers.dualityRoll.id });
|
||||
this.constructor.updateForm.bind(this)(null, null, { object: foundry.utils.flattenObject(data) });
|
||||
}
|
||||
|
||||
static removeTrigger(_event, button) {
|
||||
const data = this.action.toObject();
|
||||
data.triggers = data.triggers.filter((_, index) => index !== Number.parseInt(button.dataset.index));
|
||||
this.constructor.updateForm.bind(this)(null, null, { object: foundry.utils.flattenObject(data) });
|
||||
}
|
||||
|
||||
/** Specific implementation in extending classes **/
|
||||
static async addEffect(_event) {}
|
||||
static removeEffect(_event, _button) {}
|
||||
|
|
|
|||
|
|
@ -10,3 +10,4 @@ export * as itemConfig from './itemConfig.mjs';
|
|||
export * as settingsConfig from './settingsConfig.mjs';
|
||||
export * as systemConfig from './system.mjs';
|
||||
export * as itemBrowserConfig from './itemBrowserConfig.mjs';
|
||||
export * as triggerConfig from './triggerConfig.mjs';
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
const hooksConfig = {
|
||||
export const hooksConfig = {
|
||||
effectDisplayToggle: 'DHEffectDisplayToggle'
|
||||
};
|
||||
|
||||
export default hooksConfig;
|
||||
|
|
|
|||
|
|
@ -7,7 +7,8 @@ import * as SETTINGS from './settingsConfig.mjs';
|
|||
import * as EFFECTS from './effectConfig.mjs';
|
||||
import * as ACTIONS from './actionConfig.mjs';
|
||||
import * as FLAGS from './flagsConfig.mjs';
|
||||
import HOOKS from './hooksConfig.mjs';
|
||||
import * as HOOKS from './hooksConfig.mjs';
|
||||
import * as TRIGGER from './triggerConfig.mjs';
|
||||
import * as ITEMBROWSER from './itemBrowserConfig.mjs';
|
||||
|
||||
export const SYSTEM_ID = 'daggerheart';
|
||||
|
|
@ -24,5 +25,6 @@ export const SYSTEM = {
|
|||
ACTIONS,
|
||||
FLAGS,
|
||||
HOOKS,
|
||||
TRIGGER,
|
||||
ITEMBROWSER
|
||||
};
|
||||
|
|
|
|||
10
module/config/triggerConfig.mjs
Normal file
10
module/config/triggerConfig.mjs
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
export const triggers = {
|
||||
dualityRoll: {
|
||||
id: 'dualityRoll',
|
||||
label: 'DAGGERHEART.CONFIG.Triggers.dualityRoll'
|
||||
},
|
||||
fearRoll: {
|
||||
id: 'fearRoll',
|
||||
label: 'DAGGERHEART.CONFIG.Triggers.fearRoll'
|
||||
}
|
||||
};
|
||||
|
|
@ -2,6 +2,7 @@ import DhpActor from '../../documents/actor.mjs';
|
|||
import D20RollDialog from '../../applications/dialogs/d20RollDialog.mjs';
|
||||
import { ActionMixin } from '../fields/actionField.mjs';
|
||||
import { originItemField } from '../chat-message/actorRoll.mjs';
|
||||
import TriggerField from '../fields/triggerField.mjs';
|
||||
|
||||
const fields = foundry.data.fields;
|
||||
|
||||
|
|
@ -34,7 +35,8 @@ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel
|
|||
nullable: false,
|
||||
required: true
|
||||
}),
|
||||
targetUuid: new fields.StringField({ initial: undefined })
|
||||
targetUuid: new fields.StringField({ initial: undefined }),
|
||||
triggers: new fields.ArrayField(new TriggerField())
|
||||
};
|
||||
|
||||
this.extraSchemas.forEach(s => {
|
||||
|
|
@ -343,6 +345,10 @@ export class ResourceUpdateMap extends Map {
|
|||
}
|
||||
|
||||
addResources(resources) {
|
||||
if (!resources?.length) return;
|
||||
const invalidResources = resources.some(resource => !resource.key);
|
||||
if (invalidResources) return;
|
||||
|
||||
for (const resource of resources) {
|
||||
if (!resource.key) continue;
|
||||
|
||||
|
|
|
|||
|
|
@ -2,5 +2,6 @@ export { ActionCollection } from './actionField.mjs';
|
|||
export { default as FormulaField } from './formulaField.mjs';
|
||||
export { default as ForeignDocumentUUIDField } from './foreignDocumentUUIDField.mjs';
|
||||
export { default as ForeignDocumentUUIDArrayField } from './foreignDocumentUUIDArrayField.mjs';
|
||||
export { default as TriggerField } from './triggerField.mjs';
|
||||
export { default as MappingField } from './mappingField.mjs';
|
||||
export * as ActionFields from './action/_module.mjs';
|
||||
|
|
|
|||
15
module/data/fields/triggerField.mjs
Normal file
15
module/data/fields/triggerField.mjs
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
export default class TriggerField extends foundry.data.fields.SchemaField {
|
||||
constructor(context) {
|
||||
super(
|
||||
{
|
||||
trigger: new foundry.data.fields.StringField({
|
||||
nullable: false,
|
||||
initial: CONFIG.DH.TRIGGER.triggers.dualityRoll.id,
|
||||
choices: CONFIG.DH.TRIGGER.triggers
|
||||
}),
|
||||
command: new foundry.data.fields.JavaScriptField({ async: true })
|
||||
},
|
||||
context
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -8,7 +8,7 @@
|
|||
* @property {boolean} isInventoryItem- Indicates whether items of this type is a Inventory Item
|
||||
*/
|
||||
|
||||
import { addLinkedItemsDiff, createScrollText, getScrollTextData, updateLinkedItemApps } from '../../helpers/utils.mjs';
|
||||
import { addLinkedItemsDiff, getScrollTextData, updateLinkedItemApps } from '../../helpers/utils.mjs';
|
||||
import { ActionsField } from '../fields/actionField.mjs';
|
||||
import FormulaField from '../fields/formulaField.mjs';
|
||||
|
||||
|
|
@ -135,6 +135,26 @@ export default class BaseDataItem extends foundry.abstract.TypeDataModel {
|
|||
return data;
|
||||
}
|
||||
|
||||
prepareBaseData() {
|
||||
super.prepareBaseData();
|
||||
|
||||
for (const action of this.actions) {
|
||||
const actionsToRegister = [];
|
||||
for (let i = 0; i < action.triggers.length; i++) {
|
||||
const trigger = action.triggers[i];
|
||||
const fn = new foundry.utils.AsyncFunction('roll', 'actor', `{${trigger.command}\n}`);
|
||||
actionsToRegister.push(fn.bind(action));
|
||||
if (i === action.triggers.length - 1)
|
||||
game.system.registeredTriggers.registerTriggers(
|
||||
trigger.trigger,
|
||||
action.actor?.uuid,
|
||||
this.parent.uuid,
|
||||
actionsToRegister
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async _preCreate(data, options, user) {
|
||||
// Skip if no initial action is required or actions already exist
|
||||
if (this.metadata.hasInitialAction && foundry.utils.isEmpty(this.actions)) {
|
||||
|
|
|
|||
|
|
@ -224,6 +224,30 @@ export default class DualityRoll extends D20Roll {
|
|||
await super.buildPost(roll, config, message);
|
||||
|
||||
await DualityRoll.dualityUpdate(config);
|
||||
await DualityRoll.handleTriggers(roll, config);
|
||||
}
|
||||
|
||||
static async handleTriggers(roll, config) {
|
||||
const updates = [];
|
||||
const dualityUpdates = await game.system.registeredTriggers.runTrigger(
|
||||
CONFIG.DH.TRIGGER.triggers.dualityRoll.id,
|
||||
roll.data?.parent,
|
||||
roll,
|
||||
roll.data?.parent
|
||||
);
|
||||
if (dualityUpdates?.length) updates.push(...dualityUpdates);
|
||||
|
||||
if (config.roll.result.duality === -1) {
|
||||
const fearUpdates = await game.system.registeredTriggers.runTrigger(
|
||||
CONFIG.DH.TRIGGER.triggers.fearRoll.id,
|
||||
roll.data?.parent,
|
||||
roll,
|
||||
roll.data?.parent
|
||||
);
|
||||
if (fearUpdates?.length) updates.push(...fearUpdates);
|
||||
}
|
||||
|
||||
config.resourceUpdates.addResources(updates);
|
||||
}
|
||||
|
||||
static async addDualityResourceUpdates(config) {
|
||||
|
|
|
|||
|
|
@ -545,6 +545,10 @@
|
|||
font-size: var(--font-size-12);
|
||||
padding-left: 3px;
|
||||
}
|
||||
|
||||
code-mirror {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.application.setting.dh-style {
|
||||
|
|
|
|||
18
templates/sheets-settings/action-settings/trigger.hbs
Normal file
18
templates/sheets-settings/action-settings/trigger.hbs
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
<section
|
||||
class="tab {{this.tabs.trigger.cssClass}}"
|
||||
data-group="primary"
|
||||
data-tab="trigger"
|
||||
>
|
||||
<button data-action="addTrigger">{{localize "Add Trigger"}} <i class="fa-solid fa-plus icon-button"></i></button>
|
||||
|
||||
{{#each @root.source.triggers as |trigger index|}}
|
||||
<fieldset class="one-column">
|
||||
<legend><a data-action="removeTrigger" data-index="{{index}}"><i class="fa-solid fa-trash"></i></a></legend>
|
||||
|
||||
<select id="triggerOptionSelect">
|
||||
{{selectOptions @root.triggerOptions seleced=trigger.trigger localize=true}}
|
||||
</select>
|
||||
{{formInput @root.fields.triggers.element.fields.command value=trigger.command elementType="code-mirror" name=(concat "triggers." index ".command") aria=(object label=(localize "Test"))}}
|
||||
</fieldset>
|
||||
{{/each}}
|
||||
</section>
|
||||
Loading…
Add table
Add a link
Reference in a new issue