mirror of
https://github.com/Foundryborne/daggerheart.git
synced 2026-01-17 07:36:26 +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
|
fields
|
||||||
};
|
};
|
||||||
|
|
||||||
|
game.system.registeredTriggers = new RegisteredTriggers();
|
||||||
|
|
||||||
const { DocumentSheetConfig } = foundry.applications.apps;
|
const { DocumentSheetConfig } = foundry.applications.apps;
|
||||||
DocumentSheetConfig.unregisterSheet(TokenDocument, 'core', foundry.applications.sheets.TokenConfig);
|
DocumentSheetConfig.unregisterSheet(TokenDocument, 'core', foundry.applications.sheets.TokenConfig);
|
||||||
DocumentSheetConfig.registerSheet(TokenDocument, SYSTEM.id, applications.sheetConfigs.DhTokenConfig, {
|
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('renderCompendiumDirectory', (app, html) => applications.ui.ItemBrowser.injectSidebarButton(html));
|
||||||
Hooks.on('renderDocumentDirectory', (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": {
|
"WeaponFeature": {
|
||||||
"barrier": {
|
"barrier": {
|
||||||
"name": "Barrier",
|
"name": "Barrier",
|
||||||
|
|
@ -2057,7 +2061,8 @@
|
||||||
"itemFeatures": "Item Features",
|
"itemFeatures": "Item Features",
|
||||||
"questions": "Questions",
|
"questions": "Questions",
|
||||||
"configuration": "Configuration",
|
"configuration": "Configuration",
|
||||||
"base": "Base"
|
"base": "Base",
|
||||||
|
"triggers": "Triggers"
|
||||||
},
|
},
|
||||||
"Tiers": {
|
"Tiers": {
|
||||||
"singular": "Tier",
|
"singular": "Tier",
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,9 @@ export default class DHActionBaseConfig extends DaggerheartSheet(ApplicationV2)
|
||||||
removeElement: this.removeElement,
|
removeElement: this.removeElement,
|
||||||
editEffect: this.editEffect,
|
editEffect: this.editEffect,
|
||||||
addDamage: this.addDamage,
|
addDamage: this.addDamage,
|
||||||
removeDamage: this.removeDamage
|
removeDamage: this.removeDamage,
|
||||||
|
addTrigger: this.addTrigger,
|
||||||
|
removeTrigger: this.removeTrigger
|
||||||
},
|
},
|
||||||
form: {
|
form: {
|
||||||
handler: this.updateForm,
|
handler: this.updateForm,
|
||||||
|
|
@ -55,6 +57,10 @@ export default class DHActionBaseConfig extends DaggerheartSheet(ApplicationV2)
|
||||||
effect: {
|
effect: {
|
||||||
id: 'effect',
|
id: 'effect',
|
||||||
template: 'systems/daggerheart/templates/sheets-settings/action-settings/effect.hbs'
|
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',
|
id: 'effect',
|
||||||
icon: null,
|
icon: null,
|
||||||
label: 'DAGGERHEART.GENERAL.Tabs.effects'
|
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.baseSaveDifficulty = this.action.actor?.baseSaveDifficulty;
|
||||||
context.baseAttackBonus = this.action.actor?.system.attack?.roll.bonus;
|
context.baseAttackBonus = this.action.actor?.system.attack?.roll.bonus;
|
||||||
context.hasRoll = this.action.hasRoll;
|
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;
|
const settingsTiers = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.LevelTiers).tiers;
|
||||||
context.tierOptions = [
|
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) });
|
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 **/
|
/** Specific implementation in extending classes **/
|
||||||
static async addEffect(_event) {}
|
static async addEffect(_event) {}
|
||||||
static removeEffect(_event, _button) {}
|
static removeEffect(_event, _button) {}
|
||||||
|
|
|
||||||
|
|
@ -10,3 +10,4 @@ export * as itemConfig from './itemConfig.mjs';
|
||||||
export * as settingsConfig from './settingsConfig.mjs';
|
export * as settingsConfig from './settingsConfig.mjs';
|
||||||
export * as systemConfig from './system.mjs';
|
export * as systemConfig from './system.mjs';
|
||||||
export * as itemBrowserConfig from './itemBrowserConfig.mjs';
|
export * as itemBrowserConfig from './itemBrowserConfig.mjs';
|
||||||
|
export * as triggerConfig from './triggerConfig.mjs';
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,3 @@
|
||||||
const hooksConfig = {
|
export const hooksConfig = {
|
||||||
effectDisplayToggle: 'DHEffectDisplayToggle'
|
effectDisplayToggle: 'DHEffectDisplayToggle'
|
||||||
};
|
};
|
||||||
|
|
||||||
export default hooksConfig;
|
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,8 @@ import * as SETTINGS from './settingsConfig.mjs';
|
||||||
import * as EFFECTS from './effectConfig.mjs';
|
import * as EFFECTS from './effectConfig.mjs';
|
||||||
import * as ACTIONS from './actionConfig.mjs';
|
import * as ACTIONS from './actionConfig.mjs';
|
||||||
import * as FLAGS from './flagsConfig.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';
|
import * as ITEMBROWSER from './itemBrowserConfig.mjs';
|
||||||
|
|
||||||
export const SYSTEM_ID = 'daggerheart';
|
export const SYSTEM_ID = 'daggerheart';
|
||||||
|
|
@ -24,5 +25,6 @@ export const SYSTEM = {
|
||||||
ACTIONS,
|
ACTIONS,
|
||||||
FLAGS,
|
FLAGS,
|
||||||
HOOKS,
|
HOOKS,
|
||||||
|
TRIGGER,
|
||||||
ITEMBROWSER
|
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 D20RollDialog from '../../applications/dialogs/d20RollDialog.mjs';
|
||||||
import { ActionMixin } from '../fields/actionField.mjs';
|
import { ActionMixin } from '../fields/actionField.mjs';
|
||||||
import { originItemField } from '../chat-message/actorRoll.mjs';
|
import { originItemField } from '../chat-message/actorRoll.mjs';
|
||||||
|
import TriggerField from '../fields/triggerField.mjs';
|
||||||
|
|
||||||
const fields = foundry.data.fields;
|
const fields = foundry.data.fields;
|
||||||
|
|
||||||
|
|
@ -34,7 +35,8 @@ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel
|
||||||
nullable: false,
|
nullable: false,
|
||||||
required: true
|
required: true
|
||||||
}),
|
}),
|
||||||
targetUuid: new fields.StringField({ initial: undefined })
|
targetUuid: new fields.StringField({ initial: undefined }),
|
||||||
|
triggers: new fields.ArrayField(new TriggerField())
|
||||||
};
|
};
|
||||||
|
|
||||||
this.extraSchemas.forEach(s => {
|
this.extraSchemas.forEach(s => {
|
||||||
|
|
@ -343,6 +345,10 @@ export class ResourceUpdateMap extends Map {
|
||||||
}
|
}
|
||||||
|
|
||||||
addResources(resources) {
|
addResources(resources) {
|
||||||
|
if (!resources?.length) return;
|
||||||
|
const invalidResources = resources.some(resource => !resource.key);
|
||||||
|
if (invalidResources) return;
|
||||||
|
|
||||||
for (const resource of resources) {
|
for (const resource of resources) {
|
||||||
if (!resource.key) continue;
|
if (!resource.key) continue;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,5 +2,6 @@ export { ActionCollection } from './actionField.mjs';
|
||||||
export { default as FormulaField } from './formulaField.mjs';
|
export { default as FormulaField } from './formulaField.mjs';
|
||||||
export { default as ForeignDocumentUUIDField } from './foreignDocumentUUIDField.mjs';
|
export { default as ForeignDocumentUUIDField } from './foreignDocumentUUIDField.mjs';
|
||||||
export { default as ForeignDocumentUUIDArrayField } from './foreignDocumentUUIDArrayField.mjs';
|
export { default as ForeignDocumentUUIDArrayField } from './foreignDocumentUUIDArrayField.mjs';
|
||||||
|
export { default as TriggerField } from './triggerField.mjs';
|
||||||
export { default as MappingField } from './mappingField.mjs';
|
export { default as MappingField } from './mappingField.mjs';
|
||||||
export * as ActionFields from './action/_module.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
|
* @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 { ActionsField } from '../fields/actionField.mjs';
|
||||||
import FormulaField from '../fields/formulaField.mjs';
|
import FormulaField from '../fields/formulaField.mjs';
|
||||||
|
|
||||||
|
|
@ -135,6 +135,26 @@ export default class BaseDataItem extends foundry.abstract.TypeDataModel {
|
||||||
return data;
|
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) {
|
async _preCreate(data, options, user) {
|
||||||
// Skip if no initial action is required or actions already exist
|
// Skip if no initial action is required or actions already exist
|
||||||
if (this.metadata.hasInitialAction && foundry.utils.isEmpty(this.actions)) {
|
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 super.buildPost(roll, config, message);
|
||||||
|
|
||||||
await DualityRoll.dualityUpdate(config);
|
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) {
|
static async addDualityResourceUpdates(config) {
|
||||||
|
|
|
||||||
|
|
@ -545,6 +545,10 @@
|
||||||
font-size: var(--font-size-12);
|
font-size: var(--font-size-12);
|
||||||
padding-left: 3px;
|
padding-left: 3px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
code-mirror {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.application.setting.dh-style {
|
.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