mirror of
https://github.com/Foundryborne/daggerheart.git
synced 2026-01-11 19:25:21 +01:00
File Structure Rework (#262)
* Restructured all the files * Moved build/daggerheart.js to ./daggerheart.js. Changed rollup to use the css file instead of the less * Restored build/ folder * Mvoed config out form under application * Moved roll.mjs to module/dice and renamed to dhRolls.mjs * Update module/canvas/placeables/_module.mjs Co-authored-by: joaquinpereyra98 <24190917+joaquinpereyra98@users.noreply.github.com> * Le massive export update * Removed unncessary import --------- Co-authored-by: joaquinpereyra98 <24190917+joaquinpereyra98@users.noreply.github.com>
This commit is contained in:
parent
099a4576da
commit
9d76405221
203 changed files with 1556 additions and 2565 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -2,6 +2,5 @@
|
||||||
node_modules
|
node_modules
|
||||||
/packs
|
/packs
|
||||||
Build
|
Build
|
||||||
/build
|
|
||||||
foundry
|
foundry
|
||||||
styles/daggerheart.css
|
styles/daggerheart.css
|
||||||
139
daggerheart.mjs
139
daggerheart.mjs
|
|
@ -3,30 +3,23 @@ import * as applications from './module/applications/_module.mjs';
|
||||||
import * as models from './module/data/_module.mjs';
|
import * as models from './module/data/_module.mjs';
|
||||||
import * as documents from './module/documents/_module.mjs';
|
import * as documents from './module/documents/_module.mjs';
|
||||||
import RegisterHandlebarsHelpers from './module/helpers/handlebarsHelper.mjs';
|
import RegisterHandlebarsHelpers from './module/helpers/handlebarsHelper.mjs';
|
||||||
import DhCombatTracker from './module/ui/combatTracker.mjs';
|
|
||||||
import { handleSocketEvent, registerSocketHooks } from './module/helpers/socket.mjs';
|
|
||||||
import { registerDHSettings } from './module/applications/settings.mjs';
|
|
||||||
import DhpChatLog from './module/ui/chatLog.mjs';
|
|
||||||
import DhpRuler from './module/ui/ruler.mjs';
|
|
||||||
import DhpTokenRuler from './module/ui/tokenRuler.mjs';
|
|
||||||
import { DhDualityRollEnricher, DhTemplateEnricher } from './module/enrichers/_module.mjs';
|
import { DhDualityRollEnricher, DhTemplateEnricher } from './module/enrichers/_module.mjs';
|
||||||
import { getCommandTarget, rollCommandToJSON, setDiceSoNiceForDualityRoll } from './module/helpers/utils.mjs';
|
import { getCommandTarget, rollCommandToJSON } from './module/helpers/utils.mjs';
|
||||||
import { abilities } from './module/config/actorConfig.mjs';
|
import { NarrativeCountdowns, registerCountdownApplicationHooks } from './module/applications/ui/countdowns.mjs';
|
||||||
import Resources from './module/applications/resources.mjs';
|
|
||||||
import { NarrativeCountdowns, registerCountdownApplicationHooks } from './module/applications/countdowns.mjs';
|
|
||||||
import DHDualityRoll from './module/data/chat-message/dualityRoll.mjs';
|
|
||||||
import { DualityRollColor } from './module/data/settings/Appearance.mjs';
|
import { DualityRollColor } from './module/data/settings/Appearance.mjs';
|
||||||
import { DHRoll, DualityRoll, D20Roll, DamageRoll, DualityDie } from './module/applications/roll.mjs';
|
import { DHRoll, DualityRoll, D20Roll, DamageRoll, DualityDie } from './module/dice/_module.mjs';
|
||||||
import { DhMeasuredTemplate } from './module/placeables/_module.mjs';
|
|
||||||
import { renderDualityButton } from './module/enrichers/DualityRollEnricher.mjs';
|
import { renderDualityButton } from './module/enrichers/DualityRollEnricher.mjs';
|
||||||
import { renderMeasuredTemplate } from './module/enrichers/TemplateEnricher.mjs';
|
import { renderMeasuredTemplate } from './module/enrichers/TemplateEnricher.mjs';
|
||||||
import { registerCountdownHooks } from './module/data/countdowns.mjs';
|
import { registerCountdownHooks } from './module/data/countdowns.mjs';
|
||||||
|
import {
|
||||||
globalThis.SYSTEM = SYSTEM;
|
handlebarsRegistration,
|
||||||
|
settingsRegistration,
|
||||||
|
socketRegistration
|
||||||
|
} from './module/systemRegistration/_module.mjs';
|
||||||
|
import { placeables } from './module/canvas/_module.mjs';
|
||||||
|
|
||||||
Hooks.once('init', () => {
|
Hooks.once('init', () => {
|
||||||
CONFIG.daggerheart = SYSTEM;
|
CONFIG.DH = SYSTEM;
|
||||||
|
|
||||||
game.system.api = {
|
game.system.api = {
|
||||||
applications,
|
applications,
|
||||||
models,
|
models,
|
||||||
|
|
@ -60,7 +53,7 @@ Hooks.once('init', () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
CONFIG.Dice.rolls = [...CONFIG.Dice.rolls, ...[DHRoll, DualityRoll, D20Roll, DamageRoll]];
|
CONFIG.Dice.rolls = [...CONFIG.Dice.rolls, ...[DHRoll, DualityRoll, D20Roll, DamageRoll]];
|
||||||
CONFIG.MeasuredTemplate.objectClass = DhMeasuredTemplate;
|
CONFIG.MeasuredTemplate.objectClass = placeables.DhMeasuredTemplate;
|
||||||
|
|
||||||
CONFIG.Item.documentClass = documents.DHItem;
|
CONFIG.Item.documentClass = documents.DHItem;
|
||||||
|
|
||||||
|
|
@ -69,26 +62,32 @@ Hooks.once('init', () => {
|
||||||
|
|
||||||
const { Items, Actors } = foundry.documents.collections;
|
const { Items, Actors } = foundry.documents.collections;
|
||||||
Items.unregisterSheet('core', foundry.applications.sheets.ItemSheetV2);
|
Items.unregisterSheet('core', foundry.applications.sheets.ItemSheetV2);
|
||||||
Items.registerSheet(SYSTEM.id, applications.DhpAncestry, { types: ['ancestry'], makeDefault: true });
|
Items.registerSheet(SYSTEM.id, applications.sheets.items.Ancestry, { types: ['ancestry'], makeDefault: true });
|
||||||
Items.registerSheet(SYSTEM.id, applications.DhpCommunity, { types: ['community'], makeDefault: true });
|
Items.registerSheet(SYSTEM.id, applications.sheets.items.Community, { types: ['community'], makeDefault: true });
|
||||||
Items.registerSheet(SYSTEM.id, applications.DhpClassSheet, { types: ['class'], makeDefault: true });
|
Items.registerSheet(SYSTEM.id, applications.sheets.items.Class, { types: ['class'], makeDefault: true });
|
||||||
Items.registerSheet(SYSTEM.id, applications.DhpSubclass, { types: ['subclass'], makeDefault: true });
|
Items.registerSheet(SYSTEM.id, applications.sheets.items.Subclass, { types: ['subclass'], makeDefault: true });
|
||||||
Items.registerSheet(SYSTEM.id, applications.DhpFeatureSheet, { types: ['feature'], makeDefault: true });
|
Items.registerSheet(SYSTEM.id, applications.sheets.items.Feature, { types: ['feature'], makeDefault: true });
|
||||||
Items.registerSheet(SYSTEM.id, applications.DhpDomainCardSheet, { types: ['domainCard'], makeDefault: true });
|
Items.registerSheet(SYSTEM.id, applications.sheets.items.DomainCard, { types: ['domainCard'], makeDefault: true });
|
||||||
Items.registerSheet(SYSTEM.id, applications.DhpMiscellaneous, { types: ['miscellaneous'], makeDefault: true });
|
Items.registerSheet(SYSTEM.id, applications.sheets.items.Miscellaneous, {
|
||||||
Items.registerSheet(SYSTEM.id, applications.DhpConsumable, { types: ['consumable'], makeDefault: true });
|
types: ['miscellaneous'],
|
||||||
Items.registerSheet(SYSTEM.id, applications.DhpWeapon, { types: ['weapon'], makeDefault: true });
|
makeDefault: true
|
||||||
Items.registerSheet(SYSTEM.id, applications.DhpArmor, { types: ['armor'], makeDefault: true });
|
});
|
||||||
Items.registerSheet(SYSTEM.id, applications.DhBeastform, { types: ['beastform'], makeDefault: true });
|
Items.registerSheet(SYSTEM.id, applications.sheets.items.Consumable, { types: ['consumable'], makeDefault: true });
|
||||||
|
Items.registerSheet(SYSTEM.id, applications.sheets.items.Weapon, { types: ['weapon'], makeDefault: true });
|
||||||
|
Items.registerSheet(SYSTEM.id, applications.sheets.items.Armor, { types: ['armor'], makeDefault: true });
|
||||||
|
Items.registerSheet(SYSTEM.id, applications.sheets.items.Beastform, { types: ['beastform'], makeDefault: true });
|
||||||
|
|
||||||
CONFIG.Actor.documentClass = documents.DhpActor;
|
CONFIG.Actor.documentClass = documents.DhpActor;
|
||||||
CONFIG.Actor.dataModels = models.actors.config;
|
CONFIG.Actor.dataModels = models.actors.config;
|
||||||
|
|
||||||
Actors.unregisterSheet('core', foundry.applications.sheets.ActorSheetV2);
|
Actors.unregisterSheet('core', foundry.applications.sheets.ActorSheetV2);
|
||||||
Actors.registerSheet(SYSTEM.id, applications.DhCharacterSheet, { types: ['character'], makeDefault: true });
|
Actors.registerSheet(SYSTEM.id, applications.sheets.actors.Character, { types: ['character'], makeDefault: true });
|
||||||
Actors.registerSheet(SYSTEM.id, applications.DhCompanionSheet, { types: ['companion'], makeDefault: true });
|
Actors.registerSheet(SYSTEM.id, applications.sheets.actors.Companion, { types: ['companion'], makeDefault: true });
|
||||||
Actors.registerSheet(SYSTEM.id, applications.DhpAdversarySheet, { types: ['adversary'], makeDefault: true });
|
Actors.registerSheet(SYSTEM.id, applications.sheets.actors.Adversary, { types: ['adversary'], makeDefault: true });
|
||||||
Actors.registerSheet(SYSTEM.id, applications.DhpEnvironment, { types: ['environment'], makeDefault: true });
|
Actors.registerSheet(SYSTEM.id, applications.sheets.actors.Environment, {
|
||||||
|
types: ['environment'],
|
||||||
|
makeDefault: true
|
||||||
|
});
|
||||||
|
|
||||||
CONFIG.ActiveEffect.documentClass = documents.DhActiveEffect;
|
CONFIG.ActiveEffect.documentClass = documents.DhActiveEffect;
|
||||||
CONFIG.ActiveEffect.dataModels = models.activeEffects.config;
|
CONFIG.ActiveEffect.dataModels = models.activeEffects.config;
|
||||||
|
|
@ -101,7 +100,7 @@ Hooks.once('init', () => {
|
||||||
foundry.applications.apps.DocumentSheetConfig.registerSheet(
|
foundry.applications.apps.DocumentSheetConfig.registerSheet(
|
||||||
CONFIG.ActiveEffect.documentClass,
|
CONFIG.ActiveEffect.documentClass,
|
||||||
SYSTEM.id,
|
SYSTEM.id,
|
||||||
applications.DhActiveEffectConfig,
|
applications.sheetConfigs.ActiveEffectConfig,
|
||||||
{
|
{
|
||||||
makeDefault: true
|
makeDefault: true
|
||||||
}
|
}
|
||||||
|
|
@ -115,29 +114,28 @@ Hooks.once('init', () => {
|
||||||
base: models.DhCombatant
|
base: models.DhCombatant
|
||||||
};
|
};
|
||||||
|
|
||||||
CONFIG.ChatMessage.dataModels = models.messages.config;
|
CONFIG.ChatMessage.dataModels = models.chatMessages.config;
|
||||||
CONFIG.ChatMessage.documentClass = applications.DhpChatMessage;
|
CONFIG.ChatMessage.documentClass = documents.DhChatMessage;
|
||||||
|
|
||||||
CONFIG.Canvas.rulerClass = DhpRuler;
|
CONFIG.Canvas.rulerClass = placeables.DhRuler;
|
||||||
CONFIG.Combat.documentClass = documents.DhpCombat;
|
CONFIG.Combat.documentClass = documents.DhpCombat;
|
||||||
CONFIG.ui.combat = DhCombatTracker;
|
CONFIG.ui.combat = applications.ui.DhCombatTracker;
|
||||||
CONFIG.ui.chat = DhpChatLog;
|
CONFIG.ui.chat = applications.ui.DhChatLog;
|
||||||
// CONFIG.ui.players = DhpPlayers;
|
CONFIG.Token.rulerClass = placeables.DhTokenRuler;
|
||||||
CONFIG.Token.rulerClass = DhpTokenRuler;
|
|
||||||
|
|
||||||
CONFIG.ui.resources = Resources;
|
CONFIG.ui.resources = applications.ui.DhFearTracker;
|
||||||
CONFIG.ux.ContextMenu = applications.DhContextMenu;
|
CONFIG.ux.ContextMenu = applications.ux.ContextMenu;
|
||||||
CONFIG.ux.TooltipManager = applications.DhTooltipManager;
|
CONFIG.ux.TooltipManager = documents.DhTooltipManager;
|
||||||
|
|
||||||
game.socket.on(`system.${SYSTEM.id}`, handleSocketEvent);
|
game.socket.on(`system.${SYSTEM.id}`, socketRegistration.handleSocketEvent);
|
||||||
|
|
||||||
// Make Compendium Dialog resizable
|
// Make Compendium Dialog resizable
|
||||||
foundry.applications.sidebar.apps.Compendium.DEFAULT_OPTIONS.window.resizable = true;
|
foundry.applications.sidebar.apps.Compendium.DEFAULT_OPTIONS.window.resizable = true;
|
||||||
|
|
||||||
registerDHSettings();
|
settingsRegistration.registerDHSettings();
|
||||||
RegisterHandlebarsHelpers.registerHelpers();
|
RegisterHandlebarsHelpers.registerHelpers();
|
||||||
|
|
||||||
return preloadHandlebarsTemplates();
|
return handlebarsRegistration();
|
||||||
});
|
});
|
||||||
|
|
||||||
Hooks.on('ready', () => {
|
Hooks.on('ready', () => {
|
||||||
|
|
@ -152,7 +150,7 @@ Hooks.on('ready', () => {
|
||||||
);
|
);
|
||||||
|
|
||||||
registerCountdownHooks();
|
registerCountdownHooks();
|
||||||
registerSocketHooks();
|
socketRegistration.registerSocketHooks();
|
||||||
registerCountdownApplicationHooks();
|
registerCountdownApplicationHooks();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -212,7 +210,7 @@ Hooks.on('chatMessage', (_, message) => {
|
||||||
|
|
||||||
const title = traitValue
|
const title = traitValue
|
||||||
? game.i18n.format('DAGGERHEART.Chat.DualityRoll.AbilityCheckTitle', {
|
? game.i18n.format('DAGGERHEART.Chat.DualityRoll.AbilityCheckTitle', {
|
||||||
ability: game.i18n.localize(abilities[traitValue].label)
|
ability: game.i18n.localize(SYSTEM.ACTOR.abilities[traitValue].label)
|
||||||
})
|
})
|
||||||
: game.i18n.localize('DAGGERHEART.General.Duality');
|
: game.i18n.localize('DAGGERHEART.General.Duality');
|
||||||
|
|
||||||
|
|
@ -266,46 +264,3 @@ Hooks.on('renderJournalDirectory', async (tab, html, _, options) => {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const preloadHandlebarsTemplates = async function () {
|
|
||||||
return foundry.applications.handlebars.loadTemplates([
|
|
||||||
'systems/daggerheart/templates/sheets/global/tabs/tab-navigation.hbs',
|
|
||||||
'systems/daggerheart/templates/sheets/global/partials/inventory-item.hbs',
|
|
||||||
'systems/daggerheart/templates/sheets/global/partials/action-item.hbs',
|
|
||||||
'systems/daggerheart/templates/sheets/global/partials/domain-card-item.hbs',
|
|
||||||
'systems/daggerheart/templates/sheets/global/partials/inventory-fieldset-items.hbs',
|
|
||||||
'systems/daggerheart/templates/sheets/parts/attributes.hbs',
|
|
||||||
'systems/daggerheart/templates/sheets/parts/defense.hbs',
|
|
||||||
'systems/daggerheart/templates/sheets/parts/armor.hbs',
|
|
||||||
'systems/daggerheart/templates/sheets/parts/experience.hbs',
|
|
||||||
'systems/daggerheart/templates/sheets/parts/features.hbs',
|
|
||||||
'systems/daggerheart/templates/sheets/parts/gold.hbs',
|
|
||||||
'systems/daggerheart/templates/sheets/parts/health.hbs',
|
|
||||||
'systems/daggerheart/templates/sheets/parts/hope.hbs',
|
|
||||||
'systems/daggerheart/templates/sheets/parts/weapons.hbs',
|
|
||||||
'systems/daggerheart/templates/sheets/parts/domainCard.hbs',
|
|
||||||
'systems/daggerheart/templates/sheets/parts/heritage.hbs',
|
|
||||||
'systems/daggerheart/templates/sheets/parts/subclassFeature.hbs',
|
|
||||||
'systems/daggerheart/templates/sheets/parts/effects.hbs',
|
|
||||||
'systems/daggerheart/templates/sheets/items/subclass/parts/subclass-features.hbs',
|
|
||||||
'systems/daggerheart/templates/sheets/items/subclass/parts/subclass-feature.hbs',
|
|
||||||
'systems/daggerheart/templates/components/card-preview.hbs',
|
|
||||||
'systems/daggerheart/templates/views/levelup/parts/selectable-card-preview.hbs',
|
|
||||||
'systems/daggerheart/templates/sheets/global/partials/feature-section-item.hbs',
|
|
||||||
'systems/daggerheart/templates/ui/combat/combatTrackerSection.hbs',
|
|
||||||
'systems/daggerheart/templates/views/actionTypes/damage.hbs',
|
|
||||||
'systems/daggerheart/templates/views/actionTypes/healing.hbs',
|
|
||||||
'systems/daggerheart/templates/views/actionTypes/resource.hbs',
|
|
||||||
'systems/daggerheart/templates/views/actionTypes/uuid.hbs',
|
|
||||||
'systems/daggerheart/templates/views/actionTypes/uses.hbs',
|
|
||||||
'systems/daggerheart/templates/views/actionTypes/roll.hbs',
|
|
||||||
'systems/daggerheart/templates/views/actionTypes/save.hbs',
|
|
||||||
'systems/daggerheart/templates/views/actionTypes/cost.hbs',
|
|
||||||
'systems/daggerheart/templates/views/actionTypes/range-target.hbs',
|
|
||||||
'systems/daggerheart/templates/views/actionTypes/effect.hbs',
|
|
||||||
'systems/daggerheart/templates/views/actionTypes/beastform.hbs',
|
|
||||||
'systems/daggerheart/templates/settings/components/settings-item-line.hbs',
|
|
||||||
'systems/daggerheart/templates/chat/parts/damage-chat.hbs',
|
|
||||||
'systems/daggerheart/templates/chat/parts/target-chat.hbs'
|
|
||||||
]);
|
|
||||||
};
|
|
||||||
|
|
|
||||||
9
module/_module.mjs
Normal file
9
module/_module.mjs
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
export * as applications from './applications/_module.mjs';
|
||||||
|
export * as canvas from './canvas/_module.mjs';
|
||||||
|
export * as config from './config/_module.mjs';
|
||||||
|
export * as data from './data/_module.mjs';
|
||||||
|
export * as dice from './dice/_module.mjs';
|
||||||
|
export * as documents from './documents/_module.mjs';
|
||||||
|
export * as enrichers from './enrichers/_module.mjs';
|
||||||
|
export * as helpers from './helpers/_module.mjs';
|
||||||
|
export * as systemRegistration from './systemRegistration/_module.mjs';
|
||||||
|
|
@ -1,22 +1,8 @@
|
||||||
export { default as DhCharacterSheet } from './sheets/actors/character.mjs';
|
export * as characterCreation from './characterCreation/_module.mjs';
|
||||||
export { default as DhpAdversarySheet } from './sheets/actors/adversary.mjs';
|
export * as dialogs from './dialogs/_module.mjs';
|
||||||
export { default as DhCompanionSheet } from './sheets/actors/companion.mjs';
|
export * as levelup from './levelup/_module.mjs';
|
||||||
export { default as DhpClassSheet } from './sheets/items/class.mjs';
|
export * as settings from './settings/_module.mjs';
|
||||||
export { default as DhpSubclass } from './sheets/items/subclass.mjs';
|
export * as sheets from './sheets/_module.mjs';
|
||||||
export { default as DhpFeatureSheet } from './sheets/items/feature.mjs';
|
export * as sheetConfigs from './sheets-configs/_module.mjs';
|
||||||
export { default as DhpDomainCardSheet } from './sheets/items/domainCard.mjs';
|
export * as ui from './ui/_module.mjs';
|
||||||
export { default as DhpAncestry } from './sheets/items/ancestry.mjs';
|
|
||||||
export { default as DhpCommunity } from './sheets/items/community.mjs';
|
|
||||||
export { default as DhpMiscellaneous } from './sheets/items/miscellaneous.mjs';
|
|
||||||
export { default as DhpConsumable } from './sheets/items/consumable.mjs';
|
|
||||||
export { default as DhpWeapon } from './sheets/items/weapon.mjs';
|
|
||||||
export { default as DhpArmor } from './sheets/items/armor.mjs';
|
|
||||||
export { default as DhpChatMessage } from './chatMessage.mjs';
|
|
||||||
export { default as DhpEnvironment } from './sheets/actors/environment.mjs';
|
|
||||||
export { default as DhActiveEffectConfig } from './sheets/activeEffectConfig.mjs';
|
|
||||||
export { default as DhContextMenu } from './contextMenu.mjs';
|
|
||||||
export { default as DhBeastform } from './sheets/items/beastform.mjs';
|
|
||||||
export { default as DhTooltipManager } from './tooltipManager.mjs';
|
|
||||||
|
|
||||||
export * as api from './sheets/api/_modules.mjs';
|
|
||||||
export * as ux from './ux/_module.mjs';
|
export * as ux from './ux/_module.mjs';
|
||||||
|
|
|
||||||
|
|
@ -1,250 +0,0 @@
|
||||||
const { ApplicationV2, HandlebarsApplicationMixin } = foundry.applications.api;
|
|
||||||
|
|
||||||
export default class AncestrySelectionDialog extends HandlebarsApplicationMixin(ApplicationV2) {
|
|
||||||
constructor(resolve) {
|
|
||||||
super({});
|
|
||||||
|
|
||||||
this.resolve = resolve;
|
|
||||||
this.data = {
|
|
||||||
ancestries: [],
|
|
||||||
features: [],
|
|
||||||
ancestryInfo: {
|
|
||||||
name: '',
|
|
||||||
img: null,
|
|
||||||
customImg: 'icons/svg/mystery-man.svg',
|
|
||||||
description: ''
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
static DEFAULT_OPTIONS = {
|
|
||||||
tag: 'form',
|
|
||||||
classes: ['daggerheart', 'views', 'ancestry-selection'],
|
|
||||||
position: {
|
|
||||||
width: 800,
|
|
||||||
height: 'auto'
|
|
||||||
},
|
|
||||||
actions: {
|
|
||||||
selectAncestry: this.selectAncestry,
|
|
||||||
selectFeature: this.selectFeature,
|
|
||||||
viewItem: this.viewItem,
|
|
||||||
selectImage: this.selectImage,
|
|
||||||
editImage: this._onEditImage,
|
|
||||||
saveAncestry: this.saveAncestry
|
|
||||||
},
|
|
||||||
form: {
|
|
||||||
submitOnChange: true,
|
|
||||||
closeOnSubmit: false
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/** @override */
|
|
||||||
static PARTS = {
|
|
||||||
damageSelection: {
|
|
||||||
id: 'ancestrySelection',
|
|
||||||
template: 'systems/daggerheart/templates/views/ancestrySelection.hbs'
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
|
|
||||||
/** @inheritDoc */
|
|
||||||
get title() {
|
|
||||||
return `Ancestry Selection`;
|
|
||||||
}
|
|
||||||
|
|
||||||
_attachPartListeners(partId, htmlElement, options) {
|
|
||||||
super._attachPartListeners(partId, htmlElement, options);
|
|
||||||
|
|
||||||
const ancestryNameInput = $(htmlElement).find('.ancestry-name');
|
|
||||||
if (ancestryNameInput.length > 0) {
|
|
||||||
ancestryNameInput.on('change', this.setName.bind(this));
|
|
||||||
$(htmlElement).find('.ancestry-description').on('change', this.setDescription.bind(this));
|
|
||||||
}
|
|
||||||
// $(htmlElement).find(".ancestry-image").on("change", this.selectImage.bind(this));
|
|
||||||
}
|
|
||||||
|
|
||||||
async _prepareContext(_options) {
|
|
||||||
const systemAncestries = Array.from((await game.packs.get('daggerheart.ancestries')).index).map(x => ({
|
|
||||||
...x,
|
|
||||||
selected: this.data.ancestries.some(selected => selected.uuid === x.uuid)
|
|
||||||
}));
|
|
||||||
|
|
||||||
const customAncestries = game.items.reduce((acc, x) => {
|
|
||||||
if (x.type === 'ancestry') {
|
|
||||||
acc.push({
|
|
||||||
...x,
|
|
||||||
uuid: x.uuid,
|
|
||||||
selected: this.data.ancestries.some(selected => selected.uuid === x.uuid)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return acc;
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const ancestryFeatures = this.data.ancestries.flatMap(x =>
|
|
||||||
x.system.abilities.map(x => ({
|
|
||||||
...x,
|
|
||||||
selected: this.data.features.some(selected => selected.uuid === x.uuid)
|
|
||||||
}))
|
|
||||||
);
|
|
||||||
|
|
||||||
return {
|
|
||||||
systemAncestries,
|
|
||||||
customAncestries,
|
|
||||||
ancestryFeatures,
|
|
||||||
selectedAncestries: this.data.ancestries,
|
|
||||||
selectedFeatures: this.data.features,
|
|
||||||
ancestryInfo: this.data.ancestryInfo
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
static async selectAncestry(_, button) {
|
|
||||||
const newAncestries = [...this.data.ancestries];
|
|
||||||
if (!newAncestries.findSplice(x => x.uuid === button.dataset.uuid) && this.data.ancestries.length < 2) {
|
|
||||||
const ancestry = await fromUuid(button.dataset.uuid);
|
|
||||||
newAncestries.push(ancestry);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.data.ancestries = newAncestries;
|
|
||||||
this.data.features = newAncestries.length === 1 ? newAncestries[0].system.abilities : [];
|
|
||||||
|
|
||||||
this.render(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
static async selectFeature(_, button) {
|
|
||||||
const newFeatures = [...this.data.features];
|
|
||||||
if (!newFeatures.findSplice(x => x.uuid === button.dataset.uuid) && this.data.features.length < 2) {
|
|
||||||
const feature = await fromUuid(button.dataset.uuid);
|
|
||||||
newFeatures.push(feature);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.data.features = newFeatures;
|
|
||||||
this.render(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
static async viewItem(_, button) {
|
|
||||||
(await fromUuid(button.dataset.uuid)).sheet.render(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
setName(event) {
|
|
||||||
this.data.ancestryInfo.name = event.currentTarget.value;
|
|
||||||
this.render(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
setDescription(event) {
|
|
||||||
this.data.ancestryInfo.description = event.currentTarget.value;
|
|
||||||
this.render(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
static selectImage(_, button) {
|
|
||||||
this.data.ancestryInfo.img = button.dataset.img;
|
|
||||||
this.render(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
static _onEditImage() {
|
|
||||||
const fp = new foundry.applications.apps.FilePicker.implementation({
|
|
||||||
current: this.data.ancestryInfo.img,
|
|
||||||
type: 'image',
|
|
||||||
redirectToRoot: ['icons/svg/mystery-man.svg'],
|
|
||||||
callback: async path => this._updateImage.bind(this)(path),
|
|
||||||
top: this.position.top + 40,
|
|
||||||
left: this.position.left + 10
|
|
||||||
});
|
|
||||||
return fp.browse();
|
|
||||||
}
|
|
||||||
|
|
||||||
_updateImage(path) {
|
|
||||||
this.data.ancestryInfo.customImg = path;
|
|
||||||
this.data.ancestryInfo.img = path;
|
|
||||||
this.render(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
static async saveAncestry(_, button) {
|
|
||||||
if (this.data.ancestries.length === 2) {
|
|
||||||
const { name, img, description } = this.data.ancestryInfo;
|
|
||||||
|
|
||||||
this.resolve({
|
|
||||||
data: {
|
|
||||||
name: name,
|
|
||||||
img: img,
|
|
||||||
type: 'ancestry',
|
|
||||||
system: {
|
|
||||||
description: description,
|
|
||||||
abilities: this.data.features.map(x => ({
|
|
||||||
name: x.name,
|
|
||||||
img: x.img,
|
|
||||||
uuid: x.uuid,
|
|
||||||
subclassLevel: ''
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
this.resolve({ data: this.data.ancestries[0].toObject() });
|
|
||||||
}
|
|
||||||
|
|
||||||
this.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// export default class DamageSelectionDialog extends FormApplication {
|
|
||||||
// constructor(rollString, bonusDamage, resolve){
|
|
||||||
// super({}, {});
|
|
||||||
|
|
||||||
// this.data = {
|
|
||||||
// rollString,
|
|
||||||
// bonusDamage: bonusDamage.map(x => ({
|
|
||||||
// ...x,
|
|
||||||
// hopeUses: 0
|
|
||||||
// })),
|
|
||||||
// }
|
|
||||||
// this.resolve = resolve;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// get title (){
|
|
||||||
// return 'Damage Options';
|
|
||||||
// }
|
|
||||||
|
|
||||||
// static get defaultOptions() {
|
|
||||||
// const defaults = super.defaultOptions;
|
|
||||||
// const overrides = {
|
|
||||||
// height: 'auto',
|
|
||||||
// width: 400,
|
|
||||||
// id: 'damage-selection',
|
|
||||||
// template: 'systems/daggerheart/templates/views/damageSelection.hbs',
|
|
||||||
// closeOnSubmit: false,
|
|
||||||
// classes: ["daggerheart", "views", "damage-selection"],
|
|
||||||
// };
|
|
||||||
|
|
||||||
// const mergedOptions = foundry.utils.mergeObject(defaults, overrides);
|
|
||||||
|
|
||||||
// return mergedOptions;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// async getData(){
|
|
||||||
// const context = super.getData();
|
|
||||||
// context.rollString = this.data.rollString;
|
|
||||||
// context.bonusDamage = this.data.bonusDamage;
|
|
||||||
|
|
||||||
// return context;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// activateListeners(html) {
|
|
||||||
// super.activateListeners(html);
|
|
||||||
|
|
||||||
// html.find('.roll-button').click(this.finish.bind(this));
|
|
||||||
// html.find('.').change();
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // async _updateObject(_, formData) {
|
|
||||||
// // const data = foundry.utils.expandObject(formData);
|
|
||||||
// // this.data = foundry.utils.mergeObject(this.data, data);
|
|
||||||
// // this.render(true);
|
|
||||||
// // }
|
|
||||||
|
|
||||||
// finish(){
|
|
||||||
// this.resolve(this.data);
|
|
||||||
// this.close();
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
1
module/applications/characterCreation/_module.mjs
Normal file
1
module/applications/characterCreation/_module.mjs
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
export { default as CharacterCreation } from './characterCreation.mjs';
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import { abilities } from '../config/actorConfig.mjs';
|
import { abilities } from '../../config/actorConfig.mjs';
|
||||||
import { burden } from '../config/generalConfig.mjs';
|
import { burden } from '../../config/generalConfig.mjs';
|
||||||
|
|
||||||
const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api;
|
const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api;
|
||||||
|
|
||||||
|
|
@ -74,11 +74,11 @@ export default class DhCharacterCreation extends HandlebarsApplicationMixin(Appl
|
||||||
};
|
};
|
||||||
|
|
||||||
static PARTS = {
|
static PARTS = {
|
||||||
tabs: { template: 'systems/daggerheart/templates/views/characterCreation/tabs.hbs' },
|
tabs: { template: 'systems/daggerheart/templates/characterCreation/tabs.hbs' },
|
||||||
setup: { template: 'systems/daggerheart/templates/views/characterCreation/tabs/setup.hbs' },
|
setup: { template: 'systems/daggerheart/templates/characterCreation/tabs/setup.hbs' },
|
||||||
equipment: { template: 'systems/daggerheart/templates/views/characterCreation/tabs/equipment.hbs' },
|
equipment: { template: 'systems/daggerheart/templates/characterCreation/tabs/equipment.hbs' },
|
||||||
// story: { template: 'systems/daggerheart/templates/views/characterCreation/tabs/story.hbs' },
|
// story: { template: 'systems/daggerheart/templates/characterCreation/tabs/story.hbs' },
|
||||||
footer: { template: 'systems/daggerheart/templates/views/characterCreation/footer.hbs' }
|
footer: { template: 'systems/daggerheart/templates/characterCreation/footer.hbs' }
|
||||||
};
|
};
|
||||||
|
|
||||||
static TABS = {
|
static TABS = {
|
||||||
|
|
@ -176,7 +176,7 @@ export default class DhCharacterCreation extends HandlebarsApplicationMixin(Appl
|
||||||
switch (partId) {
|
switch (partId) {
|
||||||
case 'setup':
|
case 'setup':
|
||||||
const availableTraitModifiers = game.settings
|
const availableTraitModifiers = game.settings
|
||||||
.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Homebrew)
|
.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Homebrew)
|
||||||
.traitArray.map(trait => ({ key: trait, name: trait }));
|
.traitArray.map(trait => ({ key: trait, name: trait }));
|
||||||
for (let trait of Object.values(this.setup.traits).filter(x => x.value !== null)) {
|
for (let trait of Object.values(this.setup.traits).filter(x => x.value !== null)) {
|
||||||
const index = availableTraitModifiers.findIndex(x => x.key === trait.value);
|
const index = availableTraitModifiers.findIndex(x => x.key === trait.value);
|
||||||
|
|
@ -396,7 +396,7 @@ export default class DhCharacterCreation extends HandlebarsApplicationMixin(Appl
|
||||||
}
|
}
|
||||||
|
|
||||||
async _onDrop(event) {
|
async _onDrop(event) {
|
||||||
const data = TextEditor.getDragEventData(event);
|
const data = foundry.applications.ux.TextEditor.implementation.getDragEventData(event);
|
||||||
const item = await foundry.utils.fromUuid(data.uuid);
|
const item = await foundry.utils.fromUuid(data.uuid);
|
||||||
if (item.type === 'ancestry' && event.target.closest('.ancestry-card')) {
|
if (item.type === 'ancestry' && event.target.closest('.ancestry-card')) {
|
||||||
this.setup.ancestry = {
|
this.setup.ancestry = {
|
||||||
9
module/applications/dialogs/_module.mjs
Normal file
9
module/applications/dialogs/_module.mjs
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
export { default as BeastformDialog } from './beastformDialog.mjs';
|
||||||
|
export { default as costSelectionDialog } from './costSelectionDialog.mjs';
|
||||||
|
export { default as d20RollDialog } from './d20RollDialog.mjs';
|
||||||
|
export { default as DamageDialog } from './damageDialog.mjs';
|
||||||
|
export { default as DamageReductionDialog } from './damageReductionDialog.mjs';
|
||||||
|
export { default as DamageSelectionDialog } from './damageSelectionDialog.mjs';
|
||||||
|
export { default as DeathMove } from './deathMove.mjs';
|
||||||
|
export { default as Downtime } from './downtime.mjs';
|
||||||
|
export { default as OwnershipSelection } from './ownershipSelection.mjs';
|
||||||
|
|
@ -1,5 +1,3 @@
|
||||||
import { tiers } from '../config/generalConfig.mjs';
|
|
||||||
|
|
||||||
const { ApplicationV2, HandlebarsApplicationMixin } = foundry.applications.api;
|
const { ApplicationV2, HandlebarsApplicationMixin } = foundry.applications.api;
|
||||||
|
|
||||||
export default class BeastformDialog extends HandlebarsApplicationMixin(ApplicationV2) {
|
export default class BeastformDialog extends HandlebarsApplicationMixin(ApplicationV2) {
|
||||||
|
|
@ -35,7 +33,7 @@ export default class BeastformDialog extends HandlebarsApplicationMixin(Applicat
|
||||||
/** @override */
|
/** @override */
|
||||||
static PARTS = {
|
static PARTS = {
|
||||||
beastform: {
|
beastform: {
|
||||||
template: 'systems/daggerheart/templates/views/beastformDialog.hbs'
|
template: 'systems/daggerheart/templates/dialogs/beastformDialog.hbs'
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -43,7 +41,7 @@ export default class BeastformDialog extends HandlebarsApplicationMixin(Applicat
|
||||||
const context = await super._prepareContext(_options);
|
const context = await super._prepareContext(_options);
|
||||||
|
|
||||||
context.beastformTiers = game.items.reduce((acc, x) => {
|
context.beastformTiers = game.items.reduce((acc, x) => {
|
||||||
const tier = tiers[x.system.tier];
|
const tier = CONFIG.DH.GENERAL.tiers[x.system.tier];
|
||||||
if (x.type !== 'beastform' || tier.value > this.configData.tierLimit) return acc;
|
if (x.type !== 'beastform' || tier.value > this.configData.tierLimit) return acc;
|
||||||
|
|
||||||
if (!acc[tier.value]) acc[tier.value] = { label: game.i18n.localize(tier.label), values: {} };
|
if (!acc[tier.value]) acc[tier.value] = { label: game.i18n.localize(tier.label), values: {} };
|
||||||
|
|
@ -30,7 +30,7 @@ export default class CostSelectionDialog extends HandlebarsApplicationMixin(Appl
|
||||||
static PARTS = {
|
static PARTS = {
|
||||||
costSelection: {
|
costSelection: {
|
||||||
id: 'costSelection',
|
id: 'costSelection',
|
||||||
template: 'systems/daggerheart/templates/views/costSelection.hbs'
|
template: 'systems/daggerheart/templates/dialogs/costSelection.hbs'
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -41,11 +41,11 @@ export default class D20RollDialog extends HandlebarsApplicationMixin(Applicatio
|
||||||
static PARTS = {
|
static PARTS = {
|
||||||
costSelection: {
|
costSelection: {
|
||||||
id: 'costSelection',
|
id: 'costSelection',
|
||||||
template: 'systems/daggerheart/templates/views/costSelection.hbs'
|
template: 'systems/daggerheart/templates/dialogs/costSelection.hbs'
|
||||||
},
|
},
|
||||||
rollSelection: {
|
rollSelection: {
|
||||||
id: 'rollSelection',
|
id: 'rollSelection',
|
||||||
template: 'systems/daggerheart/templates/views/rollSelection.hbs'
|
template: 'systems/daggerheart/templates/dialogs/rollSelection.hbs'
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -60,7 +60,7 @@ export default class D20RollDialog extends HandlebarsApplicationMixin(Applicatio
|
||||||
}));
|
}));
|
||||||
context.selectedExperiences = this.config.experiences;
|
context.selectedExperiences = this.config.experiences;
|
||||||
context.advantage = this.config.roll?.advantage;
|
context.advantage = this.config.roll?.advantage;
|
||||||
context.diceOptions = SYSTEM.GENERAL.diceTypes;
|
context.diceOptions = CONFIG.DH.GENERAL.diceTypes;
|
||||||
context.canRoll = true;
|
context.canRoll = true;
|
||||||
context.isLite = this.config.roll?.lite;
|
context.isLite = this.config.roll?.lite;
|
||||||
if (this.config.costs?.length) {
|
if (this.config.costs?.length) {
|
||||||
|
|
@ -30,7 +30,7 @@ export default class DamageDialog extends HandlebarsApplicationMixin(Application
|
||||||
static PARTS = {
|
static PARTS = {
|
||||||
damageSelection: {
|
damageSelection: {
|
||||||
id: 'damageSelection',
|
id: 'damageSelection',
|
||||||
template: 'systems/daggerheart/templates/views/damageSelection.hbs'
|
template: 'systems/daggerheart/templates/dialogs/damageSelection.hbs'
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { damageKeyToNumber, getDamageLabel } from '../helpers/utils.mjs';
|
import { damageKeyToNumber, getDamageLabel } from '../../helpers/utils.mjs';
|
||||||
|
|
||||||
const { ApplicationV2, HandlebarsApplicationMixin } = foundry.applications.api;
|
const { ApplicationV2, HandlebarsApplicationMixin } = foundry.applications.api;
|
||||||
|
|
||||||
|
|
@ -71,7 +71,7 @@ export default class DamageReductionDialog extends HandlebarsApplicationMixin(Ap
|
||||||
static PARTS = {
|
static PARTS = {
|
||||||
damageSelection: {
|
damageSelection: {
|
||||||
id: 'damageReduction',
|
id: 'damageReduction',
|
||||||
template: 'systems/daggerheart/templates/views/damageReduction.hbs'
|
template: 'systems/daggerheart/templates/dialogs/damageReduction.hbs'
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -7,7 +7,7 @@ export default class DamageSelectionDialog extends HandlebarsApplicationMixin(Ap
|
||||||
this.data = {
|
this.data = {
|
||||||
rollString,
|
rollString,
|
||||||
bonusDamage: bonusDamage.reduce((acc, x) => {
|
bonusDamage: bonusDamage.reduce((acc, x) => {
|
||||||
if (x.appliesOn === SYSTEM.EFFECTS.applyLocations.damageRoll.id) {
|
if (x.appliesOn === CONFIG.DH.EFFECTS.applyLocations.damageRoll.id) {
|
||||||
acc.push({
|
acc.push({
|
||||||
...x,
|
...x,
|
||||||
hopeUses: 0
|
hopeUses: 0
|
||||||
|
|
@ -44,7 +44,7 @@ export default class DamageSelectionDialog extends HandlebarsApplicationMixin(Ap
|
||||||
static PARTS = {
|
static PARTS = {
|
||||||
damageSelection: {
|
damageSelection: {
|
||||||
id: 'damageSelection',
|
id: 'damageSelection',
|
||||||
template: 'systems/daggerheart/templates/views/damageSelection.hbs'
|
template: 'systems/daggerheart/templates/dialogs/damageSelection.hbs'
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -24,21 +24,21 @@ export default class DhpDeathMove extends HandlebarsApplicationMixin(Application
|
||||||
static PARTS = {
|
static PARTS = {
|
||||||
application: {
|
application: {
|
||||||
id: 'death-move',
|
id: 'death-move',
|
||||||
template: 'systems/daggerheart/templates/views/deathMove.hbs'
|
template: 'systems/daggerheart/templates/dialogs/deathMove.hbs'
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
async _prepareContext(_options) {
|
async _prepareContext(_options) {
|
||||||
const context = await super._prepareContext(_options);
|
const context = await super._prepareContext(_options);
|
||||||
context.selectedMove = this.selectedMove;
|
context.selectedMove = this.selectedMove;
|
||||||
context.options = SYSTEM.GENERAL.deathMoves;
|
context.options = CONFIG.DH.GENERAL.deathMoves;
|
||||||
|
|
||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
|
|
||||||
static selectMove(_, button) {
|
static selectMove(_, button) {
|
||||||
const move = button.dataset.move;
|
const move = button.dataset.move;
|
||||||
this.selectedMove = SYSTEM.GENERAL.deathMoves[move];
|
this.selectedMove = CONFIG.DH.GENERAL.deathMoves[move];
|
||||||
|
|
||||||
this.render();
|
this.render();
|
||||||
}
|
}
|
||||||
|
|
@ -48,7 +48,7 @@ export default class DhpDeathMove extends HandlebarsApplicationMixin(Application
|
||||||
const msg = new cls({
|
const msg = new cls({
|
||||||
user: game.user.id,
|
user: game.user.id,
|
||||||
content: await foundry.applications.handlebars.renderTemplate(
|
content: await foundry.applications.handlebars.renderTemplate(
|
||||||
'systems/daggerheart/templates/chat/deathMove.hbs',
|
'systems/daggerheart/templates/ui/chat/deathMove.hbs',
|
||||||
{
|
{
|
||||||
player: this.actor.name,
|
player: this.actor.name,
|
||||||
title: game.i18n.localize(this.selectedMove.name),
|
title: game.i18n.localize(this.selectedMove.name),
|
||||||
|
|
@ -1,5 +1,3 @@
|
||||||
import { actionsTypes } from '../data/_module.mjs';
|
|
||||||
|
|
||||||
const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api;
|
const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api;
|
||||||
|
|
||||||
export default class DhpDowntime extends HandlebarsApplicationMixin(ApplicationV2) {
|
export default class DhpDowntime extends HandlebarsApplicationMixin(ApplicationV2) {
|
||||||
|
|
@ -9,7 +7,7 @@ export default class DhpDowntime extends HandlebarsApplicationMixin(ApplicationV
|
||||||
this.actor = actor;
|
this.actor = actor;
|
||||||
this.shortrest = shortrest;
|
this.shortrest = shortrest;
|
||||||
|
|
||||||
const options = game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Homebrew).restMoves;
|
const options = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Homebrew).restMoves;
|
||||||
this.moveData = shortrest ? options.shortRest : options.longRest;
|
this.moveData = shortrest ? options.shortRest : options.longRest;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -31,7 +29,7 @@ export default class DhpDowntime extends HandlebarsApplicationMixin(ApplicationV
|
||||||
static PARTS = {
|
static PARTS = {
|
||||||
application: {
|
application: {
|
||||||
id: 'downtime',
|
id: 'downtime',
|
||||||
template: 'systems/daggerheart/templates/views/downtime.hbs'
|
template: 'systems/daggerheart/templates/dialogs/downtime.hbs'
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -88,7 +86,7 @@ export default class DhpDowntime extends HandlebarsApplicationMixin(ApplicationV
|
||||||
actor: this.actor.uuid
|
actor: this.actor.uuid
|
||||||
},
|
},
|
||||||
content: await foundry.applications.handlebars.renderTemplate(
|
content: await foundry.applications.handlebars.renderTemplate(
|
||||||
'systems/daggerheart/templates/chat/downtime.hbs',
|
'systems/daggerheart/templates/ui/chat/downtime.hbs',
|
||||||
{
|
{
|
||||||
title: `${this.actor.name} - ${game.i18n.localize(`DAGGERHEART.Downtime.${this.shortRest ? 'ShortRest' : 'LongRest'}.title`)}`,
|
title: `${this.actor.name} - ${game.i18n.localize(`DAGGERHEART.Downtime.${this.shortRest ? 'ShortRest' : 'LongRest'}.title`)}`,
|
||||||
moves: moves
|
moves: moves
|
||||||
|
|
@ -22,7 +22,7 @@ export default class OwnershipSelection extends HandlebarsApplicationMixin(Appli
|
||||||
|
|
||||||
static PARTS = {
|
static PARTS = {
|
||||||
selection: {
|
selection: {
|
||||||
template: 'systems/daggerheart/templates/views/ownershipSelection.hbs'
|
template: 'systems/daggerheart/templates/dialogs/ownershipSelection.hbs'
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
3
module/applications/levelup/_module.mjs
Normal file
3
module/applications/levelup/_module.mjs
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
export { default as CharacterLevelup } from './characterLevelup.mjs';
|
||||||
|
export { default as CompanionLevelup } from './companionLevelup.mjs';
|
||||||
|
export { default as Levelup } from './levelup.mjs';
|
||||||
|
|
@ -7,7 +7,9 @@ export default class DhCharacterLevelUp extends LevelUpBase {
|
||||||
constructor(actor) {
|
constructor(actor) {
|
||||||
super(actor);
|
super(actor);
|
||||||
|
|
||||||
this.levelTiers = this.addBonusChoices(game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.LevelTiers));
|
this.levelTiers = this.addBonusChoices(
|
||||||
|
game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.LevelTiers)
|
||||||
|
);
|
||||||
const playerLevelupData = actor.system.levelData;
|
const playerLevelupData = actor.system.levelData;
|
||||||
this.levelup = new DhLevelup(DhLevelup.initializeData(this.levelTiers, playerLevelupData));
|
this.levelup = new DhLevelup(DhLevelup.initializeData(this.levelTiers, playerLevelupData));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -43,10 +43,10 @@ export default class DhlevelUp extends HandlebarsApplicationMixin(ApplicationV2)
|
||||||
};
|
};
|
||||||
|
|
||||||
static PARTS = {
|
static PARTS = {
|
||||||
tabs: { template: 'systems/daggerheart/templates/views/levelup/tabs/tab-navigation.hbs' },
|
tabs: { template: 'systems/daggerheart/templates/levelup/tabs/tab-navigation.hbs' },
|
||||||
advancements: { template: 'systems/daggerheart/templates/views/levelup/tabs/advancements.hbs' },
|
advancements: { template: 'systems/daggerheart/templates/levelup/tabs/advancements.hbs' },
|
||||||
selections: { template: 'systems/daggerheart/templates/views/levelup/tabs/selections.hbs' },
|
selections: { template: 'systems/daggerheart/templates/levelup/tabs/selections.hbs' },
|
||||||
summary: { template: 'systems/daggerheart/templates/views/levelup/tabs/summary.hbs' }
|
summary: { template: 'systems/daggerheart/templates/levelup/tabs/summary.hbs' }
|
||||||
};
|
};
|
||||||
|
|
||||||
static TABS = {
|
static TABS = {
|
||||||
|
|
|
||||||
|
|
@ -1,80 +0,0 @@
|
||||||
/** NOT USED ANYMORE - TO BE DELETED **/
|
|
||||||
|
|
||||||
const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api;
|
|
||||||
|
|
||||||
export default class NpcRollSelectionDialog extends HandlebarsApplicationMixin(ApplicationV2) {
|
|
||||||
constructor(experiences, resolve, reject) {
|
|
||||||
super({});
|
|
||||||
|
|
||||||
this.experiences = experiences;
|
|
||||||
this.resolve = resolve;
|
|
||||||
this.reject = reject;
|
|
||||||
this.selectedExperiences = [];
|
|
||||||
this.data = {
|
|
||||||
advantage: null
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
get title() {
|
|
||||||
return game.i18n.localize('DAGGERHEART.Application.RollSelection.Title');
|
|
||||||
}
|
|
||||||
|
|
||||||
static DEFAULT_OPTIONS = {
|
|
||||||
tag: 'form',
|
|
||||||
classes: ['daggerheart', 'views', 'npc-roll-selection'],
|
|
||||||
position: { width: '500', height: 'auto' },
|
|
||||||
actions: {
|
|
||||||
updateIsAdvantage: this.updateIsAdvantage,
|
|
||||||
selectExperience: this.selectExperience
|
|
||||||
},
|
|
||||||
form: { handler: this.updateData, submitOnChange: false }
|
|
||||||
};
|
|
||||||
|
|
||||||
static PARTS = {
|
|
||||||
main: {
|
|
||||||
id: 'main',
|
|
||||||
template: 'systems/daggerheart/templates/views/npcRollSelection.hbs'
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
async _prepareContext(_options) {
|
|
||||||
const context = await super._prepareContext(_options);
|
|
||||||
context.advantage = this.data.advantage;
|
|
||||||
context.experiences = Object.values(this.experiences).map(x => ({
|
|
||||||
...x,
|
|
||||||
selected: this.selectedExperiences.find(selected => selected.id === x.id),
|
|
||||||
value: `${x.value >= 0 ? '+' : '-'}${x.value}`
|
|
||||||
}));
|
|
||||||
|
|
||||||
return context;
|
|
||||||
}
|
|
||||||
|
|
||||||
static updateIsAdvantage(_, button) {
|
|
||||||
const advantage = Boolean(button.dataset.advantage);
|
|
||||||
this.data.advantage = this.data.advantage === advantage ? null : advantage;
|
|
||||||
this.render();
|
|
||||||
}
|
|
||||||
|
|
||||||
static selectExperience(_, button) {
|
|
||||||
const experience = Object.values(this.experiences).find(experience => experience.id === button.id);
|
|
||||||
this.selectedExperiences = this.selectedExperiences.find(x => x.id === experience.id)
|
|
||||||
? this.selectedExperiences.filter(x => x.id !== experience.id)
|
|
||||||
: [...this.selectedExperiences, experience];
|
|
||||||
|
|
||||||
this.render();
|
|
||||||
}
|
|
||||||
|
|
||||||
static async updateData() {
|
|
||||||
this.resolve({ ...this.data, experiences: this.selectedExperiences });
|
|
||||||
this.close({ updateClose: true });
|
|
||||||
}
|
|
||||||
|
|
||||||
async close(options = {}) {
|
|
||||||
const { updateClose, ...baseOptions } = options;
|
|
||||||
if (!updateClose) {
|
|
||||||
this.reject();
|
|
||||||
}
|
|
||||||
|
|
||||||
await super.close(baseOptions);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,491 +0,0 @@
|
||||||
import D20RollDialog from '../dialogs/d20RollDialog.mjs';
|
|
||||||
import DamageDialog from '../dialogs/damageDialog.mjs';
|
|
||||||
import { setDiceSoNiceForDualityRoll } from '../helpers/utils.mjs';
|
|
||||||
|
|
||||||
/*
|
|
||||||
- Damage & other resources roll
|
|
||||||
- Close dialog => don't roll
|
|
||||||
*/
|
|
||||||
|
|
||||||
export class DHRoll extends Roll {
|
|
||||||
baseTerms = [];
|
|
||||||
constructor(formula, data, options) {
|
|
||||||
super(formula, data, options);
|
|
||||||
}
|
|
||||||
|
|
||||||
static messageType = 'adversaryRoll';
|
|
||||||
|
|
||||||
static DefaultDialog = D20RollDialog;
|
|
||||||
|
|
||||||
static async build(config = {}, message = {}) {
|
|
||||||
const roll = await this.buildConfigure(config, message);
|
|
||||||
if (!roll) return;
|
|
||||||
await this.buildEvaluate(roll, config, (message = {}));
|
|
||||||
await this.buildPost(roll, config, (message = {}));
|
|
||||||
return config;
|
|
||||||
}
|
|
||||||
|
|
||||||
static async buildConfigure(config = {}, message = {}) {
|
|
||||||
config.hooks = [...(config.hooks ?? []), ''];
|
|
||||||
config.dialog ??= {};
|
|
||||||
for (const hook of config.hooks) {
|
|
||||||
if (Hooks.call(`${SYSTEM.id}.preRoll${hook.capitalize()}`, config, message) === false) return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.applyKeybindings(config);
|
|
||||||
|
|
||||||
let roll = new this(config.roll.formula, config.data, config);
|
|
||||||
if (config.dialog.configure !== false) {
|
|
||||||
// Open Roll Dialog
|
|
||||||
const DialogClass = config.dialog?.class ?? this.DefaultDialog;
|
|
||||||
const configDialog = await DialogClass.configure(roll, config, message);
|
|
||||||
if (!configDialog) return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const hook of config.hooks) {
|
|
||||||
if (Hooks.call(`${SYSTEM.id}.post${hook.capitalize()}RollConfiguration`, roll, config, message) === false)
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
return roll;
|
|
||||||
}
|
|
||||||
|
|
||||||
static async buildEvaluate(roll, config = {}, message = {}) {
|
|
||||||
if (config.evaluate !== false) await roll.evaluate();
|
|
||||||
this.postEvaluate(roll, config);
|
|
||||||
}
|
|
||||||
|
|
||||||
static async buildPost(roll, config, message) {
|
|
||||||
for (const hook of config.hooks) {
|
|
||||||
if (Hooks.call(`${SYSTEM.id}.postRoll${hook.capitalize()}`, config, message) === false) return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create Chat Message
|
|
||||||
if (config.source?.message) {
|
|
||||||
} else {
|
|
||||||
const messageData = {};
|
|
||||||
config.message = await this.toMessage(roll, config);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static postEvaluate(roll, config = {}) {
|
|
||||||
if (!config.roll) config.roll = {};
|
|
||||||
config.roll.total = roll.total;
|
|
||||||
config.roll.formula = roll.formula;
|
|
||||||
config.roll.dice = [];
|
|
||||||
roll.dice.forEach(d => {
|
|
||||||
config.roll.dice.push({
|
|
||||||
dice: d.denomination,
|
|
||||||
total: d.total,
|
|
||||||
formula: d.formula,
|
|
||||||
results: d.results
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
static async toMessage(roll, config) {
|
|
||||||
const cls = getDocumentClass('ChatMessage'),
|
|
||||||
msg = {
|
|
||||||
type: this.messageType,
|
|
||||||
user: game.user.id,
|
|
||||||
sound: config.mute ? null : CONFIG.sounds.dice,
|
|
||||||
system: config,
|
|
||||||
rolls: [roll]
|
|
||||||
};
|
|
||||||
return await cls.create(msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
static applyKeybindings(config) {
|
|
||||||
if (config.event)
|
|
||||||
config.dialog.configure ??= !(config.event.shiftKey || config.event.altKey || config.event.ctrlKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
formatModifier(modifier) {
|
|
||||||
const numTerm = modifier < 0 ? '-' : '+';
|
|
||||||
return [
|
|
||||||
new foundry.dice.terms.OperatorTerm({ operator: numTerm }),
|
|
||||||
new foundry.dice.terms.NumericTerm({ number: Math.abs(modifier) })
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
getFaces(faces) {
|
|
||||||
return Number(faces.startsWith('d') ? faces.replace('d', '') : faces);
|
|
||||||
}
|
|
||||||
|
|
||||||
constructFormula(config) {
|
|
||||||
this.terms = Roll.parse(this.options.roll.formula, config.data);
|
|
||||||
|
|
||||||
if (this.options.extraFormula) {
|
|
||||||
this.terms.push(
|
|
||||||
new foundry.dice.terms.OperatorTerm({ operator: '+' }),
|
|
||||||
...this.constructor.parse(this.options.extraFormula, this.options.data)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return (this._formula = this.constructor.getFormula(this.terms));
|
|
||||||
}
|
|
||||||
|
|
||||||
static calculateTotalModifiers(roll) {
|
|
||||||
let modifierTotal = 0;
|
|
||||||
for (let i = 0; i < roll.terms.length; i++) {
|
|
||||||
if (
|
|
||||||
roll.terms[i] instanceof foundry.dice.terms.NumericTerm &&
|
|
||||||
!!roll.terms[i - 1] &&
|
|
||||||
roll.terms[i - 1] instanceof foundry.dice.terms.OperatorTerm
|
|
||||||
)
|
|
||||||
modifierTotal += Number(`${roll.terms[i - 1].operator}${roll.terms[i].total}`);
|
|
||||||
}
|
|
||||||
return modifierTotal;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class DualityDie extends foundry.dice.terms.Die {
|
|
||||||
constructor({ number = 1, faces = 12, ...args } = {}) {
|
|
||||||
super({ number, faces, ...args });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class D20Roll extends DHRoll {
|
|
||||||
constructor(formula, data = {}, options = {}) {
|
|
||||||
super(formula, data, options);
|
|
||||||
this.constructFormula();
|
|
||||||
}
|
|
||||||
|
|
||||||
static ADV_MODE = {
|
|
||||||
NORMAL: 0,
|
|
||||||
ADVANTAGE: 1,
|
|
||||||
DISADVANTAGE: -1
|
|
||||||
};
|
|
||||||
|
|
||||||
static messageType = 'adversaryRoll';
|
|
||||||
|
|
||||||
static CRITICAL_TRESHOLD = 20;
|
|
||||||
|
|
||||||
static DefaultDialog = D20RollDialog;
|
|
||||||
|
|
||||||
get d20() {
|
|
||||||
if (!(this.terms[0] instanceof foundry.dice.terms.Die)) this.createBaseDice();
|
|
||||||
return this.terms[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
set d20(faces) {
|
|
||||||
if (!(this.terms[0] instanceof foundry.dice.terms.Die)) this.createBaseDice();
|
|
||||||
this.terms[0].faces = this.getFaces(faces);
|
|
||||||
}
|
|
||||||
|
|
||||||
get dAdvantage() {
|
|
||||||
return this.dice[2];
|
|
||||||
}
|
|
||||||
|
|
||||||
get isCritical() {
|
|
||||||
if (!this.d20._evaluated) return;
|
|
||||||
return this.d20.total >= this.constructor.CRITICAL_TRESHOLD;
|
|
||||||
}
|
|
||||||
|
|
||||||
get hasAdvantage() {
|
|
||||||
return this.options.roll.advantage === this.constructor.ADV_MODE.ADVANTAGE;
|
|
||||||
}
|
|
||||||
|
|
||||||
get hasDisadvantage() {
|
|
||||||
return this.options.roll.advantage === this.constructor.ADV_MODE.DISADVANTAGE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static applyKeybindings(config) {
|
|
||||||
let keys = {
|
|
||||||
normal: true,
|
|
||||||
advantage: false,
|
|
||||||
disadvantage: false
|
|
||||||
};
|
|
||||||
|
|
||||||
if (config.event) {
|
|
||||||
keys = {
|
|
||||||
normal: config.event.shiftKey || config.event.altKey || config.event.ctrlKey,
|
|
||||||
advantage: config.event.altKey,
|
|
||||||
disadvantage: config.event.ctrlKey
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// Should the roll configuration dialog be displayed?
|
|
||||||
config.dialog.configure ??= !Object.values(keys).some(k => k);
|
|
||||||
|
|
||||||
// Determine advantage mode
|
|
||||||
const advantage = config.roll.advantage === this.ADV_MODE.ADVANTAGE || keys.advantage || config.advantage;
|
|
||||||
const disadvantage =
|
|
||||||
config.roll.advantage === this.ADV_MODE.DISADVANTAGE || keys.disadvantage || config.disadvantage;
|
|
||||||
if (advantage && !disadvantage) config.roll.advantage = this.ADV_MODE.ADVANTAGE;
|
|
||||||
else if (!advantage && disadvantage) config.roll.advantage = this.ADV_MODE.DISADVANTAGE;
|
|
||||||
else config.roll.advantage = this.ADV_MODE.NORMAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
constructFormula(config) {
|
|
||||||
// this.terms = [];
|
|
||||||
this.createBaseDice();
|
|
||||||
this.configureModifiers();
|
|
||||||
this.resetFormula();
|
|
||||||
return this._formula;
|
|
||||||
}
|
|
||||||
|
|
||||||
createBaseDice() {
|
|
||||||
if (this.terms[0] instanceof foundry.dice.terms.Die) {
|
|
||||||
this.terms = [this.terms[0]];
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.terms[0] = new foundry.dice.terms.Die({ faces: 20 });
|
|
||||||
}
|
|
||||||
|
|
||||||
configureModifiers() {
|
|
||||||
this.applyAdvantage();
|
|
||||||
this.applyBaseBonus();
|
|
||||||
|
|
||||||
this.options.experiences?.forEach(m => {
|
|
||||||
if (this.options.data.experiences?.[m])
|
|
||||||
this.options.roll.modifiers.push({
|
|
||||||
label: this.options.data.experiences[m].name,
|
|
||||||
value: this.options.data.experiences[m].total ?? this.options.data.experiences[m].value
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
this.options.roll.modifiers?.forEach(m => {
|
|
||||||
this.terms.push(...this.formatModifier(m.value));
|
|
||||||
});
|
|
||||||
|
|
||||||
this.baseTerms = foundry.utils.deepClone(this.terms);
|
|
||||||
|
|
||||||
if (this.options.extraFormula) {
|
|
||||||
this.terms.push(
|
|
||||||
new foundry.dice.terms.OperatorTerm({ operator: '+' }),
|
|
||||||
...this.constructor.parse(this.options.extraFormula, this.options.data)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
applyAdvantage() {
|
|
||||||
this.d20.modifiers.findSplice(m => ['kh', 'kl'].includes(m));
|
|
||||||
if (!this.hasAdvantage && !this.hasDisadvantage) this.number = 1;
|
|
||||||
else {
|
|
||||||
this.d20.number = 2;
|
|
||||||
this.d20.modifiers.push(this.hasAdvantage ? 'kh' : 'kl');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
applyBaseBonus() {
|
|
||||||
this.options.roll.modifiers = [];
|
|
||||||
if (!this.options.roll.bonus) return;
|
|
||||||
this.options.roll.modifiers.push({
|
|
||||||
label: 'Bonus to Hit',
|
|
||||||
value: this.options.roll.bonus
|
|
||||||
// value: Roll.replaceFormulaData('@attackBonus', this.data)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
static async buildEvaluate(roll, config = {}, message = {}) {
|
|
||||||
if (config.evaluate !== false) await roll.evaluate();
|
|
||||||
const advantageState =
|
|
||||||
config.roll.advantage == this.ADV_MODE.ADVANTAGE
|
|
||||||
? true
|
|
||||||
: config.roll.advantage == this.ADV_MODE.DISADVANTAGE
|
|
||||||
? false
|
|
||||||
: null;
|
|
||||||
setDiceSoNiceForDualityRoll(roll, advantageState);
|
|
||||||
this.postEvaluate(roll, config);
|
|
||||||
}
|
|
||||||
|
|
||||||
static postEvaluate(roll, config = {}) {
|
|
||||||
super.postEvaluate(roll, config);
|
|
||||||
if (config.targets?.length) {
|
|
||||||
config.targets.forEach(target => {
|
|
||||||
const difficulty = config.roll.difficulty ?? target.difficulty ?? target.evasion;
|
|
||||||
target.hit = this.isCritical || roll.total >= difficulty;
|
|
||||||
});
|
|
||||||
} else if (config.roll.difficulty)
|
|
||||||
config.roll.success = roll.isCritical || roll.total >= config.roll.difficulty;
|
|
||||||
config.roll.advantage = {
|
|
||||||
type: config.roll.advantage,
|
|
||||||
dice: roll.dAdvantage?.denomination,
|
|
||||||
value: roll.dAdvantage?.total
|
|
||||||
};
|
|
||||||
config.roll.isCritical = roll.isCritical;
|
|
||||||
config.roll.extra = roll.dice
|
|
||||||
.filter(d => !roll.baseTerms.includes(d))
|
|
||||||
.map(d => {
|
|
||||||
return {
|
|
||||||
dice: d.denomination,
|
|
||||||
value: d.total
|
|
||||||
};
|
|
||||||
});
|
|
||||||
config.roll.modifierTotal = this.calculateTotalModifiers(roll);
|
|
||||||
}
|
|
||||||
|
|
||||||
resetFormula() {
|
|
||||||
return (this._formula = this.constructor.getFormula(this.terms));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class DualityRoll extends D20Roll {
|
|
||||||
_advantageFaces = 6;
|
|
||||||
|
|
||||||
constructor(formula, data = {}, options = {}) {
|
|
||||||
super(formula, data, options);
|
|
||||||
}
|
|
||||||
|
|
||||||
static messageType = 'dualityRoll';
|
|
||||||
|
|
||||||
static DefaultDialog = D20RollDialog;
|
|
||||||
|
|
||||||
get dHope() {
|
|
||||||
// if ( !(this.terms[0] instanceof foundry.dice.terms.Die) ) return;
|
|
||||||
if (!(this.dice[0] instanceof CONFIG.Dice.daggerheart.DualityDie)) this.createBaseDice();
|
|
||||||
return this.dice[0];
|
|
||||||
// return this.#hopeDice;
|
|
||||||
}
|
|
||||||
|
|
||||||
set dHope(faces) {
|
|
||||||
if (!(this.dice[0] instanceof CONFIG.Dice.daggerheart.DualityDie)) this.createBaseDice();
|
|
||||||
this.terms[0].faces = this.getFaces(faces);
|
|
||||||
// this.#hopeDice = `d${face}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
get dFear() {
|
|
||||||
// if ( !(this.terms[1] instanceof foundry.dice.terms.Die) ) return;
|
|
||||||
if (!(this.dice[1] instanceof CONFIG.Dice.daggerheart.DualityDie)) this.createBaseDice();
|
|
||||||
return this.dice[1];
|
|
||||||
// return this.#fearDice;
|
|
||||||
}
|
|
||||||
|
|
||||||
set dFear(faces) {
|
|
||||||
if (!(this.dice[1] instanceof CONFIG.Dice.daggerheart.DualityDie)) this.createBaseDice();
|
|
||||||
this.dice[1].faces = this.getFaces(faces);
|
|
||||||
// this.#fearDice = `d${face}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
get dAdvantage() {
|
|
||||||
return this.dice[2];
|
|
||||||
}
|
|
||||||
|
|
||||||
get advantageFaces() {
|
|
||||||
return this._advantageFaces;
|
|
||||||
}
|
|
||||||
|
|
||||||
set advantageFaces(faces) {
|
|
||||||
this._advantageFaces = this.getFaces(faces);
|
|
||||||
}
|
|
||||||
|
|
||||||
get isCritical() {
|
|
||||||
if (!this.dHope._evaluated || !this.dFear._evaluated) return;
|
|
||||||
return this.dHope.total === this.dFear.total;
|
|
||||||
}
|
|
||||||
|
|
||||||
get withHope() {
|
|
||||||
if (!this._evaluated) return;
|
|
||||||
return this.dHope.total > this.dFear.total;
|
|
||||||
}
|
|
||||||
|
|
||||||
get withFear() {
|
|
||||||
if (!this._evaluated) return;
|
|
||||||
return this.dHope.total < this.dFear.total;
|
|
||||||
}
|
|
||||||
|
|
||||||
get hasBarRally() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
get totalLabel() {
|
|
||||||
const label = this.withHope
|
|
||||||
? 'DAGGERHEART.General.Hope'
|
|
||||||
: this.withFear
|
|
||||||
? 'DAGGERHEART.General.Fear'
|
|
||||||
: 'DAGGERHEART.General.CriticalSuccess';
|
|
||||||
|
|
||||||
return game.i18n.localize(label);
|
|
||||||
}
|
|
||||||
|
|
||||||
updateFormula() {}
|
|
||||||
|
|
||||||
createBaseDice() {
|
|
||||||
if (
|
|
||||||
this.dice[0] instanceof CONFIG.Dice.daggerheart.DualityDie &&
|
|
||||||
this.dice[1] instanceof CONFIG.Dice.daggerheart.DualityDie
|
|
||||||
) {
|
|
||||||
this.terms = [this.terms[0], this.terms[1], this.terms[2]];
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.terms[0] = new CONFIG.Dice.daggerheart.DualityDie();
|
|
||||||
this.terms[1] = new foundry.dice.terms.OperatorTerm({ operator: '+' });
|
|
||||||
this.terms[2] = new CONFIG.Dice.daggerheart.DualityDie();
|
|
||||||
}
|
|
||||||
|
|
||||||
applyAdvantage() {
|
|
||||||
const dieFaces = this.advantageFaces,
|
|
||||||
bardRallyFaces = this.hasBarRally,
|
|
||||||
advDie = new foundry.dice.terms.Die({ faces: dieFaces });
|
|
||||||
if (this.hasAdvantage || this.hasDisadvantage || bardRallyFaces)
|
|
||||||
this.terms.push(new foundry.dice.terms.OperatorTerm({ operator: this.hasDisadvantage ? '-' : '+' }));
|
|
||||||
if (bardRallyFaces) {
|
|
||||||
const rallyDie = new foundry.dice.terms.Die({ faces: bardRallyFaces });
|
|
||||||
if (this.hasAdvantage) {
|
|
||||||
this.terms.push(
|
|
||||||
new foundry.dice.terms.PoolTerm({
|
|
||||||
terms: [advDie.formula, rallyDie.formula],
|
|
||||||
modifiers: ['kh']
|
|
||||||
})
|
|
||||||
);
|
|
||||||
} else if (this.hasDisadvantage) {
|
|
||||||
this.terms.push(advDie, new foundry.dice.terms.OperatorTerm({ operator: '+' }), rallyDie);
|
|
||||||
}
|
|
||||||
} else if (this.hasAdvantage || this.hasDisadvantage) this.terms.push(advDie);
|
|
||||||
}
|
|
||||||
|
|
||||||
applyBaseBonus() {
|
|
||||||
this.options.roll.modifiers = [];
|
|
||||||
if (!this.options.roll.trait) return;
|
|
||||||
this.options.roll.modifiers.push({
|
|
||||||
label: `DAGGERHEART.Abilities.${this.options.roll.trait}.name`,
|
|
||||||
value: Roll.replaceFormulaData(`@traits.${this.options.roll.trait}.total`, this.data)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
static postEvaluate(roll, config = {}) {
|
|
||||||
super.postEvaluate(roll, config);
|
|
||||||
config.roll.hope = {
|
|
||||||
dice: roll.dHope.denomination,
|
|
||||||
value: roll.dHope.total
|
|
||||||
};
|
|
||||||
config.roll.fear = {
|
|
||||||
dice: roll.dFear.denomination,
|
|
||||||
value: roll.dFear.total
|
|
||||||
};
|
|
||||||
config.roll.result = {
|
|
||||||
duality: roll.withHope ? 1 : roll.withFear ? -1 : 0,
|
|
||||||
total: roll.dHope.total + roll.dFear.total,
|
|
||||||
label: roll.totalLabel
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class DamageRoll extends DHRoll {
|
|
||||||
constructor(formula, data = {}, options = {}) {
|
|
||||||
super(formula, data, options);
|
|
||||||
}
|
|
||||||
|
|
||||||
static messageType = 'damageRoll';
|
|
||||||
|
|
||||||
static DefaultDialog = DamageDialog;
|
|
||||||
|
|
||||||
static async postEvaluate(roll, config = {}) {
|
|
||||||
super.postEvaluate(roll, config);
|
|
||||||
config.roll.type = config.type;
|
|
||||||
config.roll.modifierTotal = this.calculateTotalModifiers(roll);
|
|
||||||
if (config.source?.message) {
|
|
||||||
const chatMessage = ui.chat.collection.get(config.source.message);
|
|
||||||
chatMessage.update({ 'system.damage': config });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
constructFormula(config) {
|
|
||||||
super.constructFormula(config);
|
|
||||||
if(config.isCritical) {
|
|
||||||
const tmpRoll = new Roll(this._formula)._evaluateSync({maximize: true}),
|
|
||||||
criticalBonus = tmpRoll.total - this.constructor.calculateTotalModifiers(tmpRoll);
|
|
||||||
this.terms.push(...this.formatModifier(criticalBonus));
|
|
||||||
}
|
|
||||||
return (this._formula = this.constructor.getFormula(this.terms));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,111 +0,0 @@
|
||||||
/** NOT USED ANYMORE - TO BE DELETED **/
|
|
||||||
|
|
||||||
const { ApplicationV2, HandlebarsApplicationMixin } = foundry.applications.api;
|
|
||||||
|
|
||||||
export default class RollSelectionDialog extends HandlebarsApplicationMixin(ApplicationV2) {
|
|
||||||
constructor(experiences, costs, action, resolve) {
|
|
||||||
super({}, {});
|
|
||||||
|
|
||||||
this.experiences = experiences;
|
|
||||||
this.costs = costs;
|
|
||||||
this.action = action;
|
|
||||||
this.resolve = resolve;
|
|
||||||
this.isNpc;
|
|
||||||
this.selectedExperiences = [];
|
|
||||||
this.data = {
|
|
||||||
diceOptions: [
|
|
||||||
{ name: 'd12', value: 'd12' },
|
|
||||||
{ name: 'd20', value: 'd20' }
|
|
||||||
],
|
|
||||||
hope: ['d12'],
|
|
||||||
fear: ['d12'],
|
|
||||||
advantage: null
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
static DEFAULT_OPTIONS = {
|
|
||||||
tag: 'form',
|
|
||||||
id: 'roll-selection',
|
|
||||||
classes: ['daggerheart', 'views', 'roll-selection'],
|
|
||||||
position: {
|
|
||||||
width: 400,
|
|
||||||
height: 'auto'
|
|
||||||
},
|
|
||||||
actions: {
|
|
||||||
updateIsAdvantage: this.updateIsAdvantage,
|
|
||||||
selectExperience: this.selectExperience,
|
|
||||||
finish: this.finish
|
|
||||||
},
|
|
||||||
form: {
|
|
||||||
handler: this.updateSelection,
|
|
||||||
submitOnChange: true,
|
|
||||||
submitOnClose: false
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/** @override */
|
|
||||||
static PARTS = {
|
|
||||||
costSelection: {
|
|
||||||
id: 'costSelection',
|
|
||||||
template: 'systems/daggerheart/templates/views/costSelection.hbs'
|
|
||||||
},
|
|
||||||
damageSelection: {
|
|
||||||
id: 'damageSelection',
|
|
||||||
template: 'systems/daggerheart/templates/views/rollSelection.hbs'
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
get title() {
|
|
||||||
return game.i18n.localize('DAGGERHEART.Application.RollSelection.Title');
|
|
||||||
}
|
|
||||||
|
|
||||||
async _prepareContext(_options) {
|
|
||||||
const context = await super._prepareContext(_options);
|
|
||||||
context.isNpc = this.isNpc;
|
|
||||||
context.diceOptions = this.data.diceOptions;
|
|
||||||
context.hope = this.data.hope;
|
|
||||||
context.fear = this.data.fear;
|
|
||||||
context.advantage = this.data.advantage;
|
|
||||||
context.experiences = Object.keys(this.experiences).map(id => ({ id, ...this.experiences[id] }));
|
|
||||||
if (this.costs?.length) {
|
|
||||||
const updatedCosts = this.action.calcCosts(this.costs);
|
|
||||||
context.costs = updatedCosts;
|
|
||||||
context.canRoll = this.action.getRealCosts(updatedCosts)?.hasCost;
|
|
||||||
} else context.canRoll = true;
|
|
||||||
|
|
||||||
return context;
|
|
||||||
}
|
|
||||||
|
|
||||||
static updateSelection(event, _, formData) {
|
|
||||||
const { ...rest } = foundry.utils.expandObject(formData.object);
|
|
||||||
this.data = foundry.utils.mergeObject(this.data, rest);
|
|
||||||
this.costs = foundry.utils.mergeObject(this.costs, rest.costs);
|
|
||||||
this.render();
|
|
||||||
}
|
|
||||||
|
|
||||||
static selectExperience(_, button) {
|
|
||||||
if (this.selectedExperiences.find(x => x.id === button.dataset.key)) {
|
|
||||||
this.selectedExperiences = this.selectedExperiences.filter(x => x.id !== button.dataset.key);
|
|
||||||
} else {
|
|
||||||
this.selectedExperiences = [...this.selectedExperiences, button.dataset.key];
|
|
||||||
}
|
|
||||||
|
|
||||||
this.render();
|
|
||||||
}
|
|
||||||
|
|
||||||
static updateIsAdvantage(_, button) {
|
|
||||||
const advantage = Boolean(button.dataset.advantage);
|
|
||||||
this.data.advantage = this.data.advantage === advantage ? null : advantage;
|
|
||||||
this.render();
|
|
||||||
}
|
|
||||||
|
|
||||||
static async finish() {
|
|
||||||
const { diceOptions, ...rest } = this.data;
|
|
||||||
this.resolve({
|
|
||||||
...rest,
|
|
||||||
experiences: this.selectedExperiences.map(x => ({ id: x, ...this.experiences[x] })),
|
|
||||||
costs: this.action.getRealCosts(this.costs)
|
|
||||||
});
|
|
||||||
this.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,13 +1,5 @@
|
||||||
import DhAppearanceSettings from './appearanceSettings.mjs';
|
export { default as DhAppearanceSettings } from './appearanceSettings.mjs';
|
||||||
import DhAutomationSettings from './automationSettings.mjs';
|
export { default as DhAutomationSettings } from './automationSettings.mjs';
|
||||||
import DhHomebrewSettings from './homebrewSettings.mjs';
|
export { default as DhHomebrewSettings } from './homebrewSettings.mjs';
|
||||||
import DhRangeMeasurementSettings from './rangeMeasurementSettings.mjs';
|
export { default as DhRangeMeasurementSettings } from './rangeMeasurementSettings.mjs';
|
||||||
import DhVariantRuleSettings from './variantRuleSettings.mjs';
|
export { default as DhVariantRuleSettings } from './variantRuleSettings.mjs';
|
||||||
|
|
||||||
export {
|
|
||||||
DhAppearanceSettings,
|
|
||||||
DhAutomationSettings,
|
|
||||||
DhHomebrewSettings,
|
|
||||||
DhRangeMeasurementSettings,
|
|
||||||
DhVariantRuleSettings
|
|
||||||
};
|
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ export default class DHAppearanceSettings extends HandlebarsApplicationMixin(App
|
||||||
super({});
|
super({});
|
||||||
|
|
||||||
this.settings = new DhAppearance(
|
this.settings = new DhAppearance(
|
||||||
game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.appearance).toObject()
|
game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.appearance).toObject()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -53,10 +53,10 @@ export default class DHAppearanceSettings extends HandlebarsApplicationMixin(App
|
||||||
}
|
}
|
||||||
|
|
||||||
static async save() {
|
static async save() {
|
||||||
await game.settings.set(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.appearance, this.settings.toObject());
|
await game.settings.set(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.appearance, this.settings.toObject());
|
||||||
document.body.classList.toggle(
|
document.body.classList.toggle(
|
||||||
'theme-colorful',
|
'theme-colorful',
|
||||||
game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.appearance).dualityColorScheme ===
|
game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.appearance).dualityColorScheme ===
|
||||||
DualityRollColor.colorful.value
|
DualityRollColor.colorful.value
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ export default class DhAutomationSettings extends HandlebarsApplicationMixin(App
|
||||||
super({});
|
super({});
|
||||||
|
|
||||||
this.settings = new DhAutomation(
|
this.settings = new DhAutomation(
|
||||||
game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Automation).toObject()
|
game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation).toObject()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -53,7 +53,7 @@ export default class DhAutomationSettings extends HandlebarsApplicationMixin(App
|
||||||
}
|
}
|
||||||
|
|
||||||
static async save() {
|
static async save() {
|
||||||
await game.settings.set(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Automation, this.settings.toObject());
|
await game.settings.set(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation, this.settings.toObject());
|
||||||
this.close();
|
this.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import { actionsTypes } from '../../../data/_module.mjs';
|
import { actionsTypes } from '../../../data/action/_module.mjs';
|
||||||
import DHActionConfig from '../../config/Action.mjs';
|
import DHActionConfig from '../../sheets-configs/action-config.mjs';
|
||||||
|
|
||||||
const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api;
|
const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api;
|
||||||
|
|
||||||
|
|
@ -96,8 +96,8 @@ export default class DhSettingsActionView extends HandlebarsApplicationMixin(App
|
||||||
|
|
||||||
async selectActionType() {
|
async selectActionType() {
|
||||||
const content = await foundry.applications.handlebars.renderTemplate(
|
const content = await foundry.applications.handlebars.renderTemplate(
|
||||||
'systems/daggerheart/templates/views/actionType.hbs',
|
'systems/daggerheart/templates/actionTypes/actionType.hbs',
|
||||||
{ types: SYSTEM.ACTIONS.actionTypes }
|
{ types: CONFIG.DH.ACTIONS.actionTypes }
|
||||||
),
|
),
|
||||||
title = 'Select Action Type',
|
title = 'Select Action Type',
|
||||||
type = 'form',
|
type = 'form',
|
||||||
|
|
@ -123,7 +123,7 @@ export default class DhSettingsActionView extends HandlebarsApplicationMixin(App
|
||||||
action = new cls({
|
action = new cls({
|
||||||
_id: foundry.utils.randomID(),
|
_id: foundry.utils.randomID(),
|
||||||
type: actionType.type,
|
type: actionType.type,
|
||||||
name: game.i18n.localize(SYSTEM.ACTIONS.actionTypes[actionType.type].name),
|
name: game.i18n.localize(CONFIG.DH.ACTIONS.actionTypes[actionType.type].name),
|
||||||
...cls.getSourceConfig(this.document)
|
...cls.getSourceConfig(this.document)
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,9 @@ export default class DhHomebrewSettings extends HandlebarsApplicationMixin(Appli
|
||||||
constructor() {
|
constructor() {
|
||||||
super({});
|
super({});
|
||||||
|
|
||||||
this.settings = new DhHomebrew(game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Homebrew).toObject());
|
this.settings = new DhHomebrew(
|
||||||
|
game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Homebrew).toObject()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
get title() {
|
get title() {
|
||||||
|
|
@ -113,7 +115,7 @@ export default class DhHomebrewSettings extends HandlebarsApplicationMixin(Appli
|
||||||
|
|
||||||
if (!confirmed) return;
|
if (!confirmed) return;
|
||||||
|
|
||||||
const fields = game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Homebrew).schema.fields;
|
const fields = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Homebrew).schema.fields;
|
||||||
|
|
||||||
const removeUpdate = Object.keys(this.settings.restMoves[target.dataset.type].moves).reduce((acc, key) => {
|
const removeUpdate = Object.keys(this.settings.restMoves[target.dataset.type].moves).reduce((acc, key) => {
|
||||||
acc[`-=${key}`] = null;
|
acc[`-=${key}`] = null;
|
||||||
|
|
@ -153,7 +155,7 @@ export default class DhHomebrewSettings extends HandlebarsApplicationMixin(Appli
|
||||||
}
|
}
|
||||||
|
|
||||||
static async save() {
|
static async save() {
|
||||||
await game.settings.set(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Homebrew, this.settings.toObject());
|
await game.settings.set(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Homebrew, this.settings.toObject());
|
||||||
this.close();
|
this.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ export default class DhRangeMeasurementSettings extends HandlebarsApplicationMix
|
||||||
super({});
|
super({});
|
||||||
|
|
||||||
this.settings = new DhRangeMeasurement(
|
this.settings = new DhRangeMeasurement(
|
||||||
game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.RangeMeasurement).toObject()
|
game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.RangeMeasurement).toObject()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -53,7 +53,11 @@ export default class DhRangeMeasurementSettings extends HandlebarsApplicationMix
|
||||||
}
|
}
|
||||||
|
|
||||||
static async save() {
|
static async save() {
|
||||||
await game.settings.set(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.RangeMeasurement, this.settings.toObject());
|
await game.settings.set(
|
||||||
|
CONFIG.DH.id,
|
||||||
|
CONFIG.DH.SETTINGS.gameSettings.RangeMeasurement,
|
||||||
|
this.settings.toObject()
|
||||||
|
);
|
||||||
this.close();
|
this.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ export default class DHVariantRuleSettings extends HandlebarsApplicationMixin(Ap
|
||||||
super({});
|
super({});
|
||||||
|
|
||||||
this.settings = new DhVariantRules(
|
this.settings = new DhVariantRules(
|
||||||
game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.variantRules).toObject()
|
game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.variantRules).toObject()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -53,7 +53,7 @@ export default class DHVariantRuleSettings extends HandlebarsApplicationMixin(Ap
|
||||||
}
|
}
|
||||||
|
|
||||||
static async save() {
|
static async save() {
|
||||||
await game.settings.set(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.variantRules, this.settings.toObject());
|
await game.settings.set(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.variantRules, this.settings.toObject());
|
||||||
this.close();
|
this.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
5
module/applications/sheets-configs/_module.mjs
Normal file
5
module/applications/sheets-configs/_module.mjs
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
export { default as ActionConfig } from './action-config.mjs';
|
||||||
|
export { default as AdversarySettings } from './adversary-settings.mjs';
|
||||||
|
export { default as CompanionSettings } from './companion-settings.mjs';
|
||||||
|
export { default as EnvironmentSettings } from './environment-settings.mjs';
|
||||||
|
export { default as ActiveEffectConfig } from './activeEffectConfig.mjs';
|
||||||
|
|
@ -34,7 +34,7 @@ export default class DHActionConfig extends DaggerheartSheet(ApplicationV2) {
|
||||||
static PARTS = {
|
static PARTS = {
|
||||||
form: {
|
form: {
|
||||||
id: 'action',
|
id: 'action',
|
||||||
template: 'systems/daggerheart/templates/views/action.hbs'
|
template: 'systems/daggerheart/templates/config/action.hbs'
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -60,7 +60,7 @@ export default class DHActionConfig extends DaggerheartSheet(ApplicationV2) {
|
||||||
context.source = this.action.toObject(false);
|
context.source = this.action.toObject(false);
|
||||||
context.openSection = this.openSection;
|
context.openSection = this.openSection;
|
||||||
context.tabs = this._getTabs();
|
context.tabs = this._getTabs();
|
||||||
context.config = SYSTEM;
|
context.config = CONFIG.DH;
|
||||||
if (!!this.action.effects) context.effects = this.action.effects.map(e => this.action.item.effects.get(e._id));
|
if (!!this.action.effects) context.effects = this.action.effects.map(e => this.action.item.effects.get(e._id));
|
||||||
if (this.action.damage?.hasOwnProperty('includeBase') && this.action.type === 'attack')
|
if (this.action.damage?.hasOwnProperty('includeBase') && this.action.type === 'attack')
|
||||||
context.hasBaseDamage = !!this.action.parent.damage;
|
context.hasBaseDamage = !!this.action.parent.damage;
|
||||||
|
|
@ -70,7 +70,7 @@ export default class DHActionConfig extends DaggerheartSheet(ApplicationV2) {
|
||||||
context.isNPC = this.action.actor && this.action.actor.type !== 'character';
|
context.isNPC = this.action.actor && this.action.actor.type !== 'character';
|
||||||
context.hasRoll = this.action.hasRoll;
|
context.hasRoll = this.action.hasRoll;
|
||||||
|
|
||||||
const settingsTiers = game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.LevelTiers).tiers;
|
const settingsTiers = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.LevelTiers).tiers;
|
||||||
context.tierOptions = [
|
context.tierOptions = [
|
||||||
{ key: 1, label: game.i18n.localize('DAGGERHEART.Tiers.tier1') },
|
{ key: 1, label: game.i18n.localize('DAGGERHEART.Tiers.tier1') },
|
||||||
...Object.values(settingsTiers).map(x => ({ key: x.tier, label: x.name }))
|
...Object.values(settingsTiers).map(x => ({ key: x.tier, label: x.name }))
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import DHActionConfig from '../../config/Action.mjs';
|
import DHActionConfig from './action-config.mjs';
|
||||||
import DHBaseItemSheet from '../api/base-item.mjs';
|
import DHBaseItemSheet from '../sheets/api/base-item.mjs';
|
||||||
import { actionsTypes } from '../../../data/_module.mjs';
|
import { actionsTypes } from '../../data/action/_module.mjs';
|
||||||
|
|
||||||
const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api;
|
const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api;
|
||||||
|
|
||||||
|
|
@ -40,24 +40,24 @@ export default class DHAdversarySettings extends HandlebarsApplicationMixin(Appl
|
||||||
static PARTS = {
|
static PARTS = {
|
||||||
header: {
|
header: {
|
||||||
id: 'header',
|
id: 'header',
|
||||||
template: 'systems/daggerheart/templates/sheets/applications/adversary-settings/header.hbs'
|
template: 'systems/daggerheart/templates/sheets-settings/adversary-settings/header.hbs'
|
||||||
},
|
},
|
||||||
tabs: { template: 'systems/daggerheart/templates/sheets/global/tabs/tab-navigation.hbs' },
|
tabs: { template: 'systems/daggerheart/templates/sheets/global/tabs/tab-navigation.hbs' },
|
||||||
details: {
|
details: {
|
||||||
id: 'details',
|
id: 'details',
|
||||||
template: 'systems/daggerheart/templates/sheets/applications/adversary-settings/details.hbs'
|
template: 'systems/daggerheart/templates/sheets-settings/adversary-settings/details.hbs'
|
||||||
},
|
},
|
||||||
attack: {
|
attack: {
|
||||||
id: 'attack',
|
id: 'attack',
|
||||||
template: 'systems/daggerheart/templates/sheets/applications/adversary-settings/attack.hbs'
|
template: 'systems/daggerheart/templates/sheets-settings/adversary-settings/attack.hbs'
|
||||||
},
|
},
|
||||||
experiences: {
|
experiences: {
|
||||||
id: 'experiences',
|
id: 'experiences',
|
||||||
template: 'systems/daggerheart/templates/sheets/applications/adversary-settings/experiences.hbs'
|
template: 'systems/daggerheart/templates/sheets-settings/adversary-settings/experiences.hbs'
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
id: 'actions',
|
id: 'actions',
|
||||||
template: 'systems/daggerheart/templates/sheets/applications/adversary-settings/actions.hbs'
|
template: 'systems/daggerheart/templates/sheets-settings/adversary-settings/actions.hbs'
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -139,7 +139,7 @@ export default class DHAdversarySettings extends HandlebarsApplicationMixin(Appl
|
||||||
{
|
{
|
||||||
_id: foundry.utils.randomID(),
|
_id: foundry.utils.randomID(),
|
||||||
type: actionType,
|
type: actionType,
|
||||||
name: game.i18n.localize(SYSTEM.ACTIONS.actionTypes[actionType].name),
|
name: game.i18n.localize(CONFIG.DH.ACTIONS.actionTypes[actionType].name),
|
||||||
...cls.getSourceConfig(this.actor)
|
...cls.getSourceConfig(this.actor)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import { GMUpdateEvent, socketEvent } from '../../../helpers/socket.mjs';
|
import { GMUpdateEvent, socketEvent } from '../../systemRegistration/socket.mjs';
|
||||||
import DhCompanionlevelUp from '../../levelup/companionLevelup.mjs';
|
import DhCompanionlevelUp from '../levelup/companionLevelup.mjs';
|
||||||
|
|
||||||
const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api;
|
const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api;
|
||||||
|
|
||||||
|
|
@ -35,20 +35,20 @@ export default class DHCompanionSettings extends HandlebarsApplicationMixin(Appl
|
||||||
static PARTS = {
|
static PARTS = {
|
||||||
header: {
|
header: {
|
||||||
id: 'header',
|
id: 'header',
|
||||||
template: 'systems/daggerheart/templates/sheets/applications/companion-settings/header.hbs'
|
template: 'systems/daggerheart/templates/sheets-settings/companion-settings/header.hbs'
|
||||||
},
|
},
|
||||||
tabs: { template: 'systems/daggerheart/templates/sheets/global/tabs/tab-navigation.hbs' },
|
tabs: { template: 'systems/daggerheart/templates/sheets/global/tabs/tab-navigation.hbs' },
|
||||||
details: {
|
details: {
|
||||||
id: 'details',
|
id: 'details',
|
||||||
template: 'systems/daggerheart/templates/sheets/applications/companion-settings/details.hbs'
|
template: 'systems/daggerheart/templates/sheets-settings/companion-settings/details.hbs'
|
||||||
},
|
},
|
||||||
experiences: {
|
experiences: {
|
||||||
id: 'experiences',
|
id: 'experiences',
|
||||||
template: 'systems/daggerheart/templates/sheets/applications/companion-settings/experiences.hbs'
|
template: 'systems/daggerheart/templates/sheets-settings/companion-settings/experiences.hbs'
|
||||||
},
|
},
|
||||||
attack: {
|
attack: {
|
||||||
id: 'attack',
|
id: 'attack',
|
||||||
template: 'systems/daggerheart/templates/sheets/applications/companion-settings/attack.hbs'
|
template: 'systems/daggerheart/templates/sheets-settings/companion-settings/attack.hbs'
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -120,7 +120,7 @@ export default class DHCompanionSettings extends HandlebarsApplicationMixin(Appl
|
||||||
const partnerUpdate = { 'system.companion': event.target.value ? this.actor.uuid : null };
|
const partnerUpdate = { 'system.companion': event.target.value ? this.actor.uuid : null };
|
||||||
|
|
||||||
if (!partnerDocument.testUserPermission(game.user, CONST.DOCUMENT_OWNERSHIP_LEVELS.OWNER)) {
|
if (!partnerDocument.testUserPermission(game.user, CONST.DOCUMENT_OWNERSHIP_LEVELS.OWNER)) {
|
||||||
await game.socket.emit(`system.${SYSTEM.id}`, {
|
await game.socket.emit(`system.${CONFIG.DH.id}`, {
|
||||||
action: socketEvent.GMUpdate,
|
action: socketEvent.GMUpdate,
|
||||||
data: {
|
data: {
|
||||||
action: GMUpdateEvent.UpdateDocument,
|
action: GMUpdateEvent.UpdateDocument,
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import DHActionConfig from '../../config/Action.mjs';
|
import DHActionConfig from './action-config.mjs';
|
||||||
import DHBaseItemSheet from '../api/base-item.mjs';
|
import DHBaseItemSheet from '../sheets/api/base-item.mjs';
|
||||||
import { actionsTypes } from '../../../data/_module.mjs';
|
import { actionsTypes } from '../../data/action/_module.mjs';
|
||||||
|
|
||||||
const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api;
|
const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api;
|
||||||
|
|
||||||
|
|
@ -44,20 +44,20 @@ export default class DHEnvironmentSettings extends HandlebarsApplicationMixin(Ap
|
||||||
static PARTS = {
|
static PARTS = {
|
||||||
header: {
|
header: {
|
||||||
id: 'header',
|
id: 'header',
|
||||||
template: 'systems/daggerheart/templates/sheets/applications/environment-settings/header.hbs'
|
template: 'systems/daggerheart/templates/sheets-settings/environment-settings/header.hbs'
|
||||||
},
|
},
|
||||||
tabs: { template: 'systems/daggerheart/templates/sheets/global/tabs/tab-navigation.hbs' },
|
tabs: { template: 'systems/daggerheart/templates/sheets/global/tabs/tab-navigation.hbs' },
|
||||||
details: {
|
details: {
|
||||||
id: 'details',
|
id: 'details',
|
||||||
template: 'systems/daggerheart/templates/sheets/applications/environment-settings/details.hbs'
|
template: 'systems/daggerheart/templates/sheets-settings/environment-settings/details.hbs'
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
id: 'actions',
|
id: 'actions',
|
||||||
template: 'systems/daggerheart/templates/sheets/applications/environment-settings/actions.hbs'
|
template: 'systems/daggerheart/templates/sheets-settings/environment-settings/actions.hbs'
|
||||||
},
|
},
|
||||||
adversaries: {
|
adversaries: {
|
||||||
id: 'adversaries',
|
id: 'adversaries',
|
||||||
template: 'systems/daggerheart/templates/sheets/applications/environment-settings/adversaries.hbs'
|
template: 'systems/daggerheart/templates/sheets-settings/environment-settings/adversaries.hbs'
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -131,7 +131,7 @@ export default class DHEnvironmentSettings extends HandlebarsApplicationMixin(Ap
|
||||||
{
|
{
|
||||||
_id: foundry.utils.randomID(),
|
_id: foundry.utils.randomID(),
|
||||||
type: actionType,
|
type: actionType,
|
||||||
name: game.i18n.localize(SYSTEM.ACTIONS.actionTypes[actionType].name),
|
name: game.i18n.localize(CONFIG.DH.ACTIONS.actionTypes[actionType].name),
|
||||||
...cls.getSourceConfig(this.actor)
|
...cls.getSourceConfig(this.actor)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -200,7 +200,7 @@ export default class DHEnvironmentSettings extends HandlebarsApplicationMixin(Ap
|
||||||
}
|
}
|
||||||
|
|
||||||
async _onDrop(event) {
|
async _onDrop(event) {
|
||||||
const data = TextEditor.getDragEventData(event);
|
const data = foundry.applications.ux.TextEditor.implementation.getDragEventData(event);
|
||||||
const item = await fromUuid(data.uuid);
|
const item = await fromUuid(data.uuid);
|
||||||
if (item.type === 'adversary') {
|
if (item.type === 'adversary') {
|
||||||
const target = event.target.closest('.category-container');
|
const target = event.target.closest('.category-container');
|
||||||
3
module/applications/sheets/_module.mjs
Normal file
3
module/applications/sheets/_module.mjs
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
export * as actors from './actors/_module.mjs';
|
||||||
|
export * as api from './api/_modules.mjs';
|
||||||
|
export * as items from './items/_module.mjs';
|
||||||
4
module/applications/sheets/actors/_module.mjs
Normal file
4
module/applications/sheets/actors/_module.mjs
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
export { default as Adversary } from './adversary.mjs';
|
||||||
|
export { default as Character } from './character.mjs';
|
||||||
|
export { default as Companion } from './companion.mjs';
|
||||||
|
export { default as Environment } from './environment.mjs';
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import DHActionConfig from '../../config/Action.mjs';
|
import DHActionConfig from '../../sheets-configs/action-config.mjs';
|
||||||
import DaggerheartSheet from '../daggerheart-sheet.mjs';
|
import DaggerheartSheet from '../daggerheart-sheet.mjs';
|
||||||
import DHAdversarySettings from '../applications/adversary-settings.mjs';
|
import DHAdversarySettings from '../../sheets-configs/adversary-settings.mjs';
|
||||||
|
|
||||||
const { ActorSheetV2 } = foundry.applications.sheets;
|
const { ActorSheetV2 } = foundry.applications.sheets;
|
||||||
export default class AdversarySheet extends DaggerheartSheet(ActorSheetV2) {
|
export default class AdversarySheet extends DaggerheartSheet(ActorSheetV2) {
|
||||||
|
|
@ -92,7 +92,7 @@ export default class AdversarySheet extends DaggerheartSheet(ActorSheetV2) {
|
||||||
},
|
},
|
||||||
chatMessage: {
|
chatMessage: {
|
||||||
type: 'adversaryRoll',
|
type: 'adversaryRoll',
|
||||||
template: 'systems/daggerheart/templates/chat/adversary-roll.hbs',
|
template: 'systems/daggerheart/templates/ui/chat/adversary-roll.hbs',
|
||||||
mute: true
|
mute: true
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -127,7 +127,7 @@ export default class AdversarySheet extends DaggerheartSheet(ActorSheetV2) {
|
||||||
user: game.user.id,
|
user: game.user.id,
|
||||||
system: systemData,
|
system: systemData,
|
||||||
content: await foundry.applications.handlebars.renderTemplate(
|
content: await foundry.applications.handlebars.renderTemplate(
|
||||||
'systems/daggerheart/templates/chat/ability-use.hbs',
|
'systems/daggerheart/templates/ui/chat/ability-use.hbs',
|
||||||
systemData
|
systemData
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,12 @@
|
||||||
import { capitalize } from '../../../helpers/utils.mjs';
|
import { capitalize } from '../../../helpers/utils.mjs';
|
||||||
import DhpDeathMove from '../../deathMove.mjs';
|
import DhpDeathMove from '../../dialogs/deathMove.mjs';
|
||||||
import DhpDowntime from '../../downtime.mjs';
|
import DhpDowntime from '../../dialogs/downtime.mjs';
|
||||||
import AncestrySelectionDialog from '../../ancestrySelectionDialog.mjs';
|
|
||||||
import DaggerheartSheet from '.././daggerheart-sheet.mjs';
|
import DaggerheartSheet from '.././daggerheart-sheet.mjs';
|
||||||
import { abilities } from '../../../config/actorConfig.mjs';
|
import { abilities } from '../../../config/actorConfig.mjs';
|
||||||
import DhCharacterlevelUp from '../../levelup/characterLevelup.mjs';
|
import DhCharacterlevelUp from '../../levelup/characterLevelup.mjs';
|
||||||
import DhCharacterCreation from '../../characterCreation.mjs';
|
import DhCharacterCreation from '../../characterCreation/characterCreation.mjs';
|
||||||
import FilterMenu from '../../ux/filter-menu.mjs';
|
import FilterMenu from '../../ux/filter-menu.mjs';
|
||||||
import { DhBeastformAction } from '../../../data/action/action.mjs';
|
import DHActionConfig from '../../sheets-configs/action-config.mjs';
|
||||||
import DHActionConfig from '../../config/Action.mjs';
|
|
||||||
|
|
||||||
const { ActorSheetV2 } = foundry.applications.sheets;
|
const { ActorSheetV2 } = foundry.applications.sheets;
|
||||||
const { TextEditor } = foundry.applications.ux;
|
const { TextEditor } = foundry.applications.ux;
|
||||||
|
|
@ -33,7 +31,6 @@ export default class CharacterSheet extends DaggerheartSheet(ActorSheetV2) {
|
||||||
useDomainCard: this.useDomainCard,
|
useDomainCard: this.useDomainCard,
|
||||||
selectClass: this.selectClass,
|
selectClass: this.selectClass,
|
||||||
selectSubclass: this.selectSubclass,
|
selectSubclass: this.selectSubclass,
|
||||||
selectAncestry: this.selectAncestry,
|
|
||||||
selectCommunity: this.selectCommunity,
|
selectCommunity: this.selectCommunity,
|
||||||
viewObject: this.viewObject,
|
viewObject: this.viewObject,
|
||||||
useItem: this.useItem,
|
useItem: this.useItem,
|
||||||
|
|
@ -338,13 +335,13 @@ export default class CharacterSheet extends DaggerheartSheet(ActorSheetV2) {
|
||||||
const context = await super._prepareContext(_options);
|
const context = await super._prepareContext(_options);
|
||||||
context.document = this.document;
|
context.document = this.document;
|
||||||
context.tabs = super._getTabs(this.constructor.TABS);
|
context.tabs = super._getTabs(this.constructor.TABS);
|
||||||
context.config = SYSTEM;
|
context.config = CONFIG.DH;
|
||||||
|
|
||||||
context.attributes = Object.keys(this.document.system.traits).reduce((acc, key) => {
|
context.attributes = Object.keys(this.document.system.traits).reduce((acc, key) => {
|
||||||
acc[key] = {
|
acc[key] = {
|
||||||
...this.document.system.traits[key],
|
...this.document.system.traits[key],
|
||||||
name: game.i18n.localize(SYSTEM.ACTOR.abilities[key].name),
|
name: game.i18n.localize(CONFIG.DH.ACTOR.abilities[key].name),
|
||||||
verbs: SYSTEM.ACTOR.abilities[key].verbs.map(x => game.i18n.localize(x))
|
verbs: CONFIG.DH.ACTOR.abilities[key].verbs.map(x => game.i18n.localize(x))
|
||||||
};
|
};
|
||||||
|
|
||||||
return acc;
|
return acc;
|
||||||
|
|
@ -360,7 +357,7 @@ export default class CharacterSheet extends DaggerheartSheet(ActorSheetV2) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const homebrewCurrency = game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Homebrew).currency;
|
const homebrewCurrency = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Homebrew).currency;
|
||||||
if (homebrewCurrency.enabled) {
|
if (homebrewCurrency.enabled) {
|
||||||
context.inventory.currency = homebrewCurrency;
|
context.inventory.currency = homebrewCurrency;
|
||||||
}
|
}
|
||||||
|
|
@ -631,13 +628,13 @@ export default class CharacterSheet extends DaggerheartSheet(ActorSheetV2) {
|
||||||
|
|
||||||
static async toggleLoadoutView(_, button) {
|
static async toggleLoadoutView(_, button) {
|
||||||
const newAbilityView = !(button.dataset.value === 'true');
|
const newAbilityView = !(button.dataset.value === 'true');
|
||||||
await game.user.setFlag(SYSTEM.id, SYSTEM.FLAGS.displayDomainCardsAsList, newAbilityView);
|
await game.user.setFlag(CONFIG.DH.id, CONFIG.DH.FLAGS.displayDomainCardsAsList, newAbilityView);
|
||||||
this.render();
|
this.render();
|
||||||
}
|
}
|
||||||
|
|
||||||
static async toggleLoadoutView(_, button) {
|
static async toggleLoadoutView(_, button) {
|
||||||
const newAbilityView = !(button.dataset.value === 'true');
|
const newAbilityView = !(button.dataset.value === 'true');
|
||||||
await game.user.setFlag(SYSTEM.id, SYSTEM.FLAGS.displayDomainCardsAsList, newAbilityView);
|
await game.user.setFlag(CONFIG.DH.id, CONFIG.DH.FLAGS.displayDomainCardsAsList, newAbilityView);
|
||||||
this.render();
|
this.render();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -647,7 +644,7 @@ export default class CharacterSheet extends DaggerheartSheet(ActorSheetV2) {
|
||||||
|
|
||||||
const wasUsed = await weapon.use(event);
|
const wasUsed = await weapon.use(event);
|
||||||
if (wasUsed) {
|
if (wasUsed) {
|
||||||
Hooks.callAll(SYSTEM.HOOKS.characterAttack, {});
|
Hooks.callAll(CONFIG.DH.HOOKS.characterAttack, {});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -689,7 +686,7 @@ export default class CharacterSheet extends DaggerheartSheet(ActorSheetV2) {
|
||||||
type: 'abilityUse',
|
type: 'abilityUse',
|
||||||
user: game.user.id,
|
user: game.user.id,
|
||||||
content: await foundry.applications.handlebars.renderTemplate(
|
content: await foundry.applications.handlebars.renderTemplate(
|
||||||
'systems/daggerheart/templates/chat/ability-use.hbs',
|
'systems/daggerheart/templates/ui/chat/ability-use.hbs',
|
||||||
systemData
|
systemData
|
||||||
),
|
),
|
||||||
system: systemData
|
system: systemData
|
||||||
|
|
@ -706,28 +703,6 @@ export default class CharacterSheet extends DaggerheartSheet(ActorSheetV2) {
|
||||||
(await game.packs.get('daggerheart.subclasses'))?.render(true);
|
(await game.packs.get('daggerheart.subclasses'))?.render(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
static async selectAncestry() {
|
|
||||||
const dialogClosed = new Promise((resolve, _) => {
|
|
||||||
new AncestrySelectionDialog(resolve).render(true);
|
|
||||||
});
|
|
||||||
const result = await dialogClosed;
|
|
||||||
|
|
||||||
for (var ancestry of this.document.items.filter(x => x => x.type === 'ancestry')) {
|
|
||||||
await ancestry.delete();
|
|
||||||
}
|
|
||||||
|
|
||||||
const createdItems = [];
|
|
||||||
for (var feature of this.document.items.filter(
|
|
||||||
x => x.type === 'feature' && x.system.type === SYSTEM.ITEM.featureTypes.ancestry.id
|
|
||||||
)) {
|
|
||||||
await feature.delete();
|
|
||||||
}
|
|
||||||
|
|
||||||
createdItems.push(result.data);
|
|
||||||
|
|
||||||
await this.document.createEmbeddedDocuments('Item', createdItems);
|
|
||||||
}
|
|
||||||
|
|
||||||
static async selectCommunity() {
|
static async selectCommunity() {
|
||||||
(await game.packs.get('daggerheart.communities'))?.render(true);
|
(await game.packs.get('daggerheart.communities'))?.render(true);
|
||||||
}
|
}
|
||||||
|
|
@ -744,7 +719,7 @@ export default class CharacterSheet extends DaggerheartSheet(ActorSheetV2) {
|
||||||
} else {
|
} else {
|
||||||
const wasUsed = await item.use(event);
|
const wasUsed = await item.use(event);
|
||||||
if (wasUsed && item.type === 'weapon') {
|
if (wasUsed && item.type === 'weapon') {
|
||||||
Hooks.callAll(SYSTEM.HOOKS.characterAttack, {});
|
Hooks.callAll(CONFIG.DH.HOOKS.characterAttack, {});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -840,7 +815,7 @@ export default class CharacterSheet extends DaggerheartSheet(ActorSheetV2) {
|
||||||
type: 'abilityUse',
|
type: 'abilityUse',
|
||||||
user: game.user.id,
|
user: game.user.id,
|
||||||
content: await foundry.applications.handlebars.renderTemplate(
|
content: await foundry.applications.handlebars.renderTemplate(
|
||||||
'systems/daggerheart/templates/chat/ability-use.hbs',
|
'systems/daggerheart/templates/ui/chat/ability-use.hbs',
|
||||||
systemData
|
systemData
|
||||||
),
|
),
|
||||||
system: systemData
|
system: systemData
|
||||||
|
|
@ -862,7 +837,7 @@ export default class CharacterSheet extends DaggerheartSheet(ActorSheetV2) {
|
||||||
user: game.user.id,
|
user: game.user.id,
|
||||||
system: systemData,
|
system: systemData,
|
||||||
content: await foundry.applications.handlebars.renderTemplate(
|
content: await foundry.applications.handlebars.renderTemplate(
|
||||||
'systems/daggerheart/templates/chat/ability-use.hbs',
|
'systems/daggerheart/templates/ui/chat/ability-use.hbs',
|
||||||
systemData
|
systemData
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
|
@ -898,7 +873,7 @@ export default class CharacterSheet extends DaggerheartSheet(ActorSheetV2) {
|
||||||
user: game.user.id,
|
user: game.user.id,
|
||||||
system: systemData,
|
system: systemData,
|
||||||
content: await foundry.applications.handlebars.renderTemplate(
|
content: await foundry.applications.handlebars.renderTemplate(
|
||||||
'systems/daggerheart/templates/chat/ability-use.hbs',
|
'systems/daggerheart/templates/ui/chat/ability-use.hbs',
|
||||||
systemData
|
systemData
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
|
@ -921,7 +896,7 @@ export default class CharacterSheet extends DaggerheartSheet(ActorSheetV2) {
|
||||||
user: game.user.id,
|
user: game.user.id,
|
||||||
system: systemData,
|
system: systemData,
|
||||||
content: await foundry.applications.handlebars.renderTemplate(
|
content: await foundry.applications.handlebars.renderTemplate(
|
||||||
'systems/daggerheart/templates/chat/ability-use.hbs',
|
'systems/daggerheart/templates/ui/chat/ability-use.hbs',
|
||||||
systemData
|
systemData
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import DaggerheartSheet from '../daggerheart-sheet.mjs';
|
import DaggerheartSheet from '../daggerheart-sheet.mjs';
|
||||||
import DHCompanionSettings from '../applications/companion-settings.mjs';
|
import DHCompanionSettings from '../../sheets-configs/companion-settings.mjs';
|
||||||
|
|
||||||
const { ActorSheetV2 } = foundry.applications.sheets;
|
const { ActorSheetV2 } = foundry.applications.sheets;
|
||||||
export default class DhCompanionSheet extends DaggerheartSheet(ActorSheetV2) {
|
export default class DhCompanionSheet extends DaggerheartSheet(ActorSheetV2) {
|
||||||
|
|
@ -90,7 +90,7 @@ export default class DhCompanionSheet extends DaggerheartSheet(ActorSheetV2) {
|
||||||
user: game.user.id,
|
user: game.user.id,
|
||||||
system: systemData,
|
system: systemData,
|
||||||
content: await foundry.applications.handlebars.renderTemplate(
|
content: await foundry.applications.handlebars.renderTemplate(
|
||||||
'systems/daggerheart/templates/chat/ability-use.hbs',
|
'systems/daggerheart/templates/ui/chat/ability-use.hbs',
|
||||||
systemData
|
systemData
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import DaggerheartSheet from '../daggerheart-sheet.mjs';
|
import DaggerheartSheet from '../daggerheart-sheet.mjs';
|
||||||
import DHEnvironmentSettings from '../applications/environment-settings.mjs';
|
import DHEnvironmentSettings from '../../sheets-configs/environment-settings.mjs';
|
||||||
|
|
||||||
const { ActorSheetV2 } = foundry.applications.sheets;
|
const { ActorSheetV2 } = foundry.applications.sheets;
|
||||||
export default class DhpEnvironment extends DaggerheartSheet(ActorSheetV2) {
|
export default class DhpEnvironment extends DaggerheartSheet(ActorSheetV2) {
|
||||||
|
|
|
||||||
|
|
@ -139,7 +139,7 @@ export default function DHApplicationMixin(Base) {
|
||||||
* @param {DragEvent} event
|
* @param {DragEvent} event
|
||||||
* @protected
|
* @protected
|
||||||
*/
|
*/
|
||||||
_onDrop(event) { }
|
_onDrop(event) {}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
/* Prepare Context */
|
/* Prepare Context */
|
||||||
|
|
@ -154,7 +154,7 @@ export default function DHApplicationMixin(Base) {
|
||||||
*/
|
*/
|
||||||
async _prepareContext(options, objectPath = 'document') {
|
async _prepareContext(options, objectPath = 'document') {
|
||||||
const context = await super._prepareContext(options);
|
const context = await super._prepareContext(options);
|
||||||
context.config = CONFIG.daggerheart;
|
context.config = CONFIG.DH;
|
||||||
context.source = this[objectPath];
|
context.source = this[objectPath];
|
||||||
context.fields = this[objectPath].schema.fields;
|
context.fields = this[objectPath].schema.fields;
|
||||||
context.systemFields = this[objectPath].system ? this[objectPath].system.schema.fields : {};
|
context.systemFields = this[objectPath].system ? this[objectPath].system.schema.fields : {};
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import DHApplicationMixin from './application-mixin.mjs';
|
import DHApplicationMixin from './application-mixin.mjs';
|
||||||
import { actionsTypes } from '../../../data/_module.mjs';
|
import DHActionConfig from '../../sheets-configs/action-config.mjs';
|
||||||
import DHActionConfig from '../../config/Action.mjs';
|
import { actionsTypes } from '../../../data/action/_module.mjs';
|
||||||
|
|
||||||
const { ItemSheetV2 } = foundry.applications.sheets;
|
const { ItemSheetV2 } = foundry.applications.sheets;
|
||||||
|
|
||||||
|
|
@ -69,8 +69,8 @@ export default class DHBaseItemSheet extends DHApplicationMixin(ItemSheetV2) {
|
||||||
*/
|
*/
|
||||||
static async selectActionType() {
|
static async selectActionType() {
|
||||||
const content = await foundry.applications.handlebars.renderTemplate(
|
const content = await foundry.applications.handlebars.renderTemplate(
|
||||||
'systems/daggerheart/templates/views/actionType.hbs',
|
'systems/daggerheart/templates/actionTypes/actionType.hbs',
|
||||||
{ types: SYSTEM.ACTIONS.actionTypes }
|
{ types: CONFIG.DH.ACTIONS.actionTypes }
|
||||||
),
|
),
|
||||||
title = 'Select Action Type';
|
title = 'Select Action Type';
|
||||||
|
|
||||||
|
|
@ -98,7 +98,7 @@ export default class DHBaseItemSheet extends DHApplicationMixin(ItemSheetV2) {
|
||||||
{
|
{
|
||||||
_id: foundry.utils.randomID(),
|
_id: foundry.utils.randomID(),
|
||||||
type: actionType,
|
type: actionType,
|
||||||
name: game.i18n.localize(SYSTEM.ACTIONS.actionTypes[actionType].name),
|
name: game.i18n.localize(CONFIG.DH.ACTIONS.actionTypes[actionType].name),
|
||||||
...cls.getSourceConfig(this.document)
|
...cls.getSourceConfig(this.document)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
||||||
11
module/applications/sheets/items/_module.mjs
Normal file
11
module/applications/sheets/items/_module.mjs
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
export { default as Ancestry } from './ancestry.mjs';
|
||||||
|
export { default as Armor } from './armor.mjs';
|
||||||
|
export { default as Beastform } from './beastform.mjs';
|
||||||
|
export { default as Class } from './class.mjs';
|
||||||
|
export { default as Community } from './community.mjs';
|
||||||
|
export { default as Consumable } from './consumable.mjs';
|
||||||
|
export { default as DomainCard } from './domainCard.mjs';
|
||||||
|
export { default as Feature } from './feature.mjs';
|
||||||
|
export { default as Miscellaneous } from './miscellaneous.mjs';
|
||||||
|
export { default as Subclass } from './subclass.mjs';
|
||||||
|
export { default as Weapon } from './weapon.mjs';
|
||||||
|
|
@ -8,7 +8,7 @@ export default class ArmorSheet extends DHBaseItemSheet {
|
||||||
tagifyConfigs: [
|
tagifyConfigs: [
|
||||||
{
|
{
|
||||||
selector: '.features-input',
|
selector: '.features-input',
|
||||||
options: () => CONFIG.daggerheart.ITEM.armorFeatures,
|
options: () => CONFIG.DH.ITEM.armorFeatures,
|
||||||
callback: ArmorSheet.#onFeatureSelect
|
callback: ArmorSheet.#onFeatureSelect
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,7 @@ export default class BeastformSheet extends DHBaseItemSheet {
|
||||||
}
|
}
|
||||||
|
|
||||||
async _onDrop(event) {
|
async _onDrop(event) {
|
||||||
const data = TextEditor.getDragEventData(event);
|
const data = foundry.applications.ux.TextEditor.implementation.getDragEventData(event);
|
||||||
const item = await fromUuid(data.uuid);
|
const item = await fromUuid(data.uuid);
|
||||||
if (item.type === 'feature') {
|
if (item.type === 'feature') {
|
||||||
const current = this.document.system.features.map(x => x.uuid);
|
const current = this.document.system.features.map(x => x.uuid);
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import DHBaseItemSheet from '../api/base-item.mjs';
|
import DHBaseItemSheet from '../api/base-item.mjs';
|
||||||
import { actionsTypes } from '../../../data/_module.mjs';
|
import DHActionConfig from '../../sheets-configs/action-config.mjs';
|
||||||
import DHActionConfig from '../../config/Action.mjs';
|
import { actionsTypes } from '../../../data/action/_module.mjs';
|
||||||
|
|
||||||
const { TextEditor } = foundry.applications.ux;
|
const { TextEditor } = foundry.applications.ux;
|
||||||
|
|
||||||
|
|
@ -20,7 +20,7 @@ export default class ClassSheet extends DHBaseItemSheet {
|
||||||
tagifyConfigs: [
|
tagifyConfigs: [
|
||||||
{
|
{
|
||||||
selector: '.domain-input',
|
selector: '.domain-input',
|
||||||
options: () => CONFIG.daggerheart.DOMAIN.domains,
|
options: () => CONFIG.DH.DOMAIN.domains,
|
||||||
callback: ClassSheet.#onDomainSelect
|
callback: ClassSheet.#onDomainSelect
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|
@ -172,8 +172,8 @@ export default class ClassSheet extends DHBaseItemSheet {
|
||||||
//TODO: redo this
|
//TODO: redo this
|
||||||
async selectActionType() {
|
async selectActionType() {
|
||||||
const content = await foundry.applications.handlebars.renderTemplate(
|
const content = await foundry.applications.handlebars.renderTemplate(
|
||||||
'systems/daggerheart/templates/views/actionType.hbs',
|
'systems/daggerheart/templates/actionTypes/actionType.hbs',
|
||||||
{ types: SYSTEM.ACTIONS.actionTypes }
|
{ types: CONFIG.DH.ACTIONS.actionTypes }
|
||||||
),
|
),
|
||||||
title = 'Select Action Type',
|
title = 'Select Action Type',
|
||||||
type = 'form',
|
type = 'form',
|
||||||
|
|
@ -209,7 +209,7 @@ export default class ClassSheet extends DHBaseItemSheet {
|
||||||
_id: foundry.utils.randomID(),
|
_id: foundry.utils.randomID(),
|
||||||
systemPath: actionPath,
|
systemPath: actionPath,
|
||||||
type: actionType.type,
|
type: actionType.type,
|
||||||
name: game.i18n.localize(SYSTEM.ACTIONS.actionTypes[actionType.type].name),
|
name: game.i18n.localize(CONFIG.DH.ACTIONS.actionTypes[actionType.type].name),
|
||||||
...cls.getSourceConfig(this.document)
|
...cls.getSourceConfig(this.document)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import DHBaseItemSheet from '../api/base-item.mjs';
|
import DHBaseItemSheet from '../api/base-item.mjs';
|
||||||
import { actionsTypes } from '../../../data/_module.mjs';
|
import DHActionConfig from '../../sheets-configs/action-config.mjs';
|
||||||
import DHActionConfig from '../../config/Action.mjs';
|
import { actionsTypes } from '../../../data/action/_module.mjs';
|
||||||
|
|
||||||
export default class SubclassSheet extends DHBaseItemSheet {
|
export default class SubclassSheet extends DHBaseItemSheet {
|
||||||
/**@inheritdoc */
|
/**@inheritdoc */
|
||||||
|
|
@ -58,8 +58,8 @@ export default class SubclassSheet extends DHBaseItemSheet {
|
||||||
|
|
||||||
async #selectActionType() {
|
async #selectActionType() {
|
||||||
const content = await foundry.applications.handlebars.renderTemplate(
|
const content = await foundry.applications.handlebars.renderTemplate(
|
||||||
'systems/daggerheart/templates/views/actionType.hbs',
|
'systems/daggerheart/templates/actionTypes/actionType.hbs',
|
||||||
{ types: SYSTEM.ACTIONS.actionTypes }
|
{ types: CONFIG.DH.ACTIONS.actionTypes }
|
||||||
),
|
),
|
||||||
title = 'Select Action Type',
|
title = 'Select Action Type',
|
||||||
type = 'form',
|
type = 'form',
|
||||||
|
|
@ -87,7 +87,7 @@ export default class SubclassSheet extends DHBaseItemSheet {
|
||||||
_id: foundry.utils.randomID(),
|
_id: foundry.utils.randomID(),
|
||||||
systemPath: `${level}.actions`,
|
systemPath: `${level}.actions`,
|
||||||
type: actionType.type,
|
type: actionType.type,
|
||||||
name: game.i18n.localize(SYSTEM.ACTIONS.actionTypes[actionType.type].name),
|
name: game.i18n.localize(CONFIG.DH.ACTIONS.actionTypes[actionType.type].name),
|
||||||
...cls.getSourceConfig(this.document)
|
...cls.getSourceConfig(this.document)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ export default class WeaponSheet extends DHBaseItemSheet {
|
||||||
tagifyConfigs: [
|
tagifyConfigs: [
|
||||||
{
|
{
|
||||||
selector: '.features-input',
|
selector: '.features-input',
|
||||||
options: () => CONFIG.daggerheart.ITEM.weaponFeatures,
|
options: () => CONFIG.DH.ITEM.weaponFeatures,
|
||||||
callback: WeaponSheet.#onFeatureSelect
|
callback: WeaponSheet.#onFeatureSelect
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
|
||||||
4
module/applications/ui/_module.mjs
Normal file
4
module/applications/ui/_module.mjs
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
export { default as DhChatLog } from './chatLog.mjs';
|
||||||
|
export { default as DhCombatTracker } from './combatTracker.mjs';
|
||||||
|
export * as DhCountdowns from './countdowns.mjs';
|
||||||
|
export { default as DhFearTracker } from './fearTracker.mjs';
|
||||||
|
|
@ -1,5 +1,3 @@
|
||||||
import { actionsTypes } from '../data/_module.mjs';
|
|
||||||
|
|
||||||
export default class DhpChatLog extends foundry.applications.sidebar.tabs.ChatLog {
|
export default class DhpChatLog extends foundry.applications.sidebar.tabs.ChatLog {
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
|
|
@ -213,7 +211,7 @@ export default class DhpChatLog extends foundry.applications.sidebar.tabs.ChatLo
|
||||||
for (let target of targets) {
|
for (let target of targets) {
|
||||||
let damage = message.system.roll.total;
|
let damage = message.system.roll.total;
|
||||||
if (message.system.onSave && message.system.targets.find(t => t.id === target.id)?.saved?.success === true)
|
if (message.system.onSave && message.system.targets.find(t => t.id === target.id)?.saved?.success === true)
|
||||||
damage = Math.ceil(damage * (SYSTEM.ACTIONS.damageOnSave[message.system.onSave]?.mod ?? 1));
|
damage = Math.ceil(damage * (CONFIG.DH.ACTIONS.damageOnSave[message.system.onSave]?.mod ?? 1));
|
||||||
|
|
||||||
await target.actor.takeDamage(damage, message.system.roll.type);
|
await target.actor.takeDamage(damage, message.system.roll.type);
|
||||||
}
|
}
|
||||||
|
|
@ -260,10 +258,10 @@ export default class DhpChatLog extends foundry.applications.sidebar.tabs.ChatLo
|
||||||
|
|
||||||
actionUseButton = async (_, message) => {
|
actionUseButton = async (_, message) => {
|
||||||
const parent = await foundry.utils.fromUuid(message.system.actor);
|
const parent = await foundry.utils.fromUuid(message.system.actor);
|
||||||
const testAction = Object.values(message.system.moves)[0].actions[0];
|
const actionType = Object.values(message.system.moves)[0].actions[0];
|
||||||
const cls = actionsTypes[testAction.type];
|
const cls = CONFIG.DH.ACTIONS.actionTypes[actionType.type];
|
||||||
const action = new cls(
|
const action = new cls(
|
||||||
{ ...testAction, _id: foundry.utils.randomID(), name: game.i18n.localize(testAction.name) },
|
{ ...actionType, _id: foundry.utils.randomID(), name: game.i18n.localize(actionType.name) },
|
||||||
{ parent: parent }
|
{ parent: parent }
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { EncounterCountdowns } from '../applications/countdowns.mjs';
|
import { EncounterCountdowns } from '../ui/countdowns.mjs';
|
||||||
|
|
||||||
export default class DhCombatTracker extends foundry.applications.sidebar.tabs.CombatTracker {
|
export default class DhCombatTracker extends foundry.applications.sidebar.tabs.CombatTracker {
|
||||||
static DEFAULT_OPTIONS = {
|
static DEFAULT_OPTIONS = {
|
||||||
|
|
@ -12,13 +12,13 @@ export default class DhCombatTracker extends foundry.applications.sidebar.tabs.C
|
||||||
|
|
||||||
static PARTS = {
|
static PARTS = {
|
||||||
header: {
|
header: {
|
||||||
template: 'systems/daggerheart/templates/ui/combat/combatTrackerHeader.hbs'
|
template: 'systems/daggerheart/templates/ui/combatTracker/combatTrackerHeader.hbs'
|
||||||
},
|
},
|
||||||
tracker: {
|
tracker: {
|
||||||
template: 'systems/daggerheart/templates/ui/combat/combatTracker.hbs'
|
template: 'systems/daggerheart/templates/ui/combatTracker/combatTracker.hbs'
|
||||||
},
|
},
|
||||||
footer: {
|
footer: {
|
||||||
template: 'systems/daggerheart/templates/ui/combat/combatTrackerFooter.hbs'
|
template: 'systems/daggerheart/templates/ui/combatTracker/combatTrackerFooter.hbs'
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -26,7 +26,7 @@ export default class DhCombatTracker extends foundry.applications.sidebar.tabs.C
|
||||||
await super._prepareCombatContext(context, options);
|
await super._prepareCombatContext(context, options);
|
||||||
|
|
||||||
Object.assign(context, {
|
Object.assign(context, {
|
||||||
fear: game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Resources.Fear)
|
fear: game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Resources.Fear)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -37,7 +37,7 @@ export default class DhCombatTracker extends foundry.applications.sidebar.tabs.C
|
||||||
const characters = context.turns?.filter(x => !x.isNPC) ?? [];
|
const characters = context.turns?.filter(x => !x.isNPC) ?? [];
|
||||||
|
|
||||||
Object.assign(context, {
|
Object.assign(context, {
|
||||||
actionTokens: game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.variantRules).actionTokens,
|
actionTokens: game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.variantRules).actionTokens,
|
||||||
adversaries,
|
adversaries,
|
||||||
characters
|
characters
|
||||||
});
|
});
|
||||||
|
|
@ -86,7 +86,7 @@ export default class DhCombatTracker extends foundry.applications.sidebar.tabs.C
|
||||||
.map(x => x.id)
|
.map(x => x.id)
|
||||||
.indexOf(combatantId);
|
.indexOf(combatantId);
|
||||||
|
|
||||||
if (this.viewed.turn !== toggleTurn) Hooks.callAll(SYSTEM.HOOKS.spotlight, {});
|
if (this.viewed.turn !== toggleTurn) Hooks.callAll(CONFIG.DH.HOOKS.spotlight, {});
|
||||||
|
|
||||||
await this.viewed.update({ turn: this.viewed.turn === toggleTurn ? null : toggleTurn });
|
await this.viewed.update({ turn: this.viewed.turn === toggleTurn ? null : toggleTurn });
|
||||||
await combatant.update({ 'system.spotlight.requesting': false });
|
await combatant.update({ 'system.spotlight.requesting': false });
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import { countdownTypes } from '../config/generalConfig.mjs';
|
import { countdownTypes } from '../../config/generalConfig.mjs';
|
||||||
import { GMUpdateEvent, RefreshType, socketEvent } from '../helpers/socket.mjs';
|
import { GMUpdateEvent, RefreshType, socketEvent } from '../../systemRegistration/socket.mjs';
|
||||||
import constructHTMLButton from '../helpers/utils.mjs';
|
import constructHTMLButton from '../../helpers/utils.mjs';
|
||||||
import OwnershipSelection from './ownershipSelection.mjs';
|
import OwnershipSelection from '../dialogs/ownershipSelection.mjs';
|
||||||
|
|
||||||
const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api;
|
const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api;
|
||||||
|
|
||||||
|
|
@ -41,7 +41,7 @@ class Countdowns extends HandlebarsApplicationMixin(ApplicationV2) {
|
||||||
|
|
||||||
static PARTS = {
|
static PARTS = {
|
||||||
countdowns: {
|
countdowns: {
|
||||||
template: 'systems/daggerheart/templates/views/countdowns.hbs',
|
template: 'systems/daggerheart/templates/ui/countdowns.hbs',
|
||||||
scrollable: ['.expanded-view']
|
scrollable: ['.expanded-view']
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -57,18 +57,18 @@ class Countdowns extends HandlebarsApplicationMixin(ApplicationV2) {
|
||||||
|
|
||||||
async _preFirstRender(context, options) {
|
async _preFirstRender(context, options) {
|
||||||
options.position =
|
options.position =
|
||||||
game.user.getFlag(SYSTEM.id, SYSTEM.FLAGS[`${this.basePath}Countdown`].position) ??
|
game.user.getFlag(CONFIG.DH.id, CONFIG.DH.FLAGS[`${this.basePath}Countdown`].position) ??
|
||||||
Countdowns.DEFAULT_OPTIONS.position;
|
Countdowns.DEFAULT_OPTIONS.position;
|
||||||
|
|
||||||
const viewSetting =
|
const viewSetting =
|
||||||
game.user.getFlag(SYSTEM.id, SYSTEM.FLAGS[`${this.basePath}Countdown`].simple) ?? !game.user.isGM;
|
game.user.getFlag(CONFIG.DH.id, CONFIG.DH.FLAGS[`${this.basePath}Countdown`].simple) ?? !game.user.isGM;
|
||||||
this.simpleView =
|
this.simpleView =
|
||||||
game.user.isGM || !this.testUserPermission(CONST.DOCUMENT_OWNERSHIP_LEVELS.OBSERVER) ? viewSetting : true;
|
game.user.isGM || !this.testUserPermission(CONST.DOCUMENT_OWNERSHIP_LEVELS.OBSERVER) ? viewSetting : true;
|
||||||
context.simple = this.simpleView;
|
context.simple = this.simpleView;
|
||||||
}
|
}
|
||||||
|
|
||||||
_onPosition(position) {
|
_onPosition(position) {
|
||||||
game.user.setFlag(SYSTEM.id, SYSTEM.FLAGS[`${this.basePath}Countdown`].position, position);
|
game.user.setFlag(CONFIG.DH.id, CONFIG.DH.FLAGS[`${this.basePath}Countdown`].position, position);
|
||||||
}
|
}
|
||||||
|
|
||||||
async _renderFrame(options) {
|
async _renderFrame(options) {
|
||||||
|
|
@ -90,7 +90,7 @@ class Countdowns extends HandlebarsApplicationMixin(ApplicationV2) {
|
||||||
if (game.user.isGM) return true;
|
if (game.user.isGM) return true;
|
||||||
|
|
||||||
const settings =
|
const settings =
|
||||||
altSettings ?? game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Countdowns)[this.basePath];
|
altSettings ?? game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Countdowns)[this.basePath];
|
||||||
const defaultAllowed = exact ? settings.ownership.default === level : settings.ownership.default >= level;
|
const defaultAllowed = exact ? settings.ownership.default === level : settings.ownership.default >= level;
|
||||||
const userAllowed = exact
|
const userAllowed = exact
|
||||||
? settings.playerOwnership[game.user.id]?.value === level
|
? settings.playerOwnership[game.user.id]?.value === level
|
||||||
|
|
@ -100,7 +100,9 @@ class Countdowns extends HandlebarsApplicationMixin(ApplicationV2) {
|
||||||
|
|
||||||
async _prepareContext(_options) {
|
async _prepareContext(_options) {
|
||||||
const context = await super._prepareContext(_options);
|
const context = await super._prepareContext(_options);
|
||||||
const countdownData = game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Countdowns)[this.basePath];
|
const countdownData = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Countdowns)[
|
||||||
|
this.basePath
|
||||||
|
];
|
||||||
|
|
||||||
context.isGM = game.user.isGM;
|
context.isGM = game.user.isGM;
|
||||||
context.base = this.basePath;
|
context.base = this.basePath;
|
||||||
|
|
@ -131,19 +133,19 @@ class Countdowns extends HandlebarsApplicationMixin(ApplicationV2) {
|
||||||
static async updateData(event, _, formData) {
|
static async updateData(event, _, formData) {
|
||||||
const data = foundry.utils.expandObject(formData.object);
|
const data = foundry.utils.expandObject(formData.object);
|
||||||
const newSetting = foundry.utils.mergeObject(
|
const newSetting = foundry.utils.mergeObject(
|
||||||
game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Countdowns).toObject(),
|
game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Countdowns).toObject(),
|
||||||
data
|
data
|
||||||
);
|
);
|
||||||
|
|
||||||
if (game.user.isGM) {
|
if (game.user.isGM) {
|
||||||
await game.settings.set(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Countdowns, newSetting);
|
await game.settings.set(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Countdowns, newSetting);
|
||||||
this.render();
|
this.render();
|
||||||
} else {
|
} else {
|
||||||
await game.socket.emit(`system.${SYSTEM.id}`, {
|
await game.socket.emit(`system.${CONFIG.DH.id}`, {
|
||||||
action: socketEvent.GMUpdate,
|
action: socketEvent.GMUpdate,
|
||||||
data: {
|
data: {
|
||||||
action: GMUpdateEvent.UpdateSetting,
|
action: GMUpdateEvent.UpdateSetting,
|
||||||
uuid: SYSTEM.SETTINGS.gameSettings.Countdowns,
|
uuid: CONFIG.DH.SETTINGS.gameSettings.Countdowns,
|
||||||
update: newSetting
|
update: newSetting
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
@ -152,8 +154,8 @@ class Countdowns extends HandlebarsApplicationMixin(ApplicationV2) {
|
||||||
|
|
||||||
async updateSetting(update) {
|
async updateSetting(update) {
|
||||||
if (game.user.isGM) {
|
if (game.user.isGM) {
|
||||||
await game.settings.set(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Countdowns, update);
|
await game.settings.set(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Countdowns, update);
|
||||||
await game.socket.emit(`system.${SYSTEM.id}`, {
|
await game.socket.emit(`system.${CONFIG.DH.id}`, {
|
||||||
action: socketEvent.Refresh,
|
action: socketEvent.Refresh,
|
||||||
data: {
|
data: {
|
||||||
refreshType: RefreshType.Countdown,
|
refreshType: RefreshType.Countdown,
|
||||||
|
|
@ -163,11 +165,11 @@ class Countdowns extends HandlebarsApplicationMixin(ApplicationV2) {
|
||||||
|
|
||||||
this.render();
|
this.render();
|
||||||
} else {
|
} else {
|
||||||
await game.socket.emit(`system.${SYSTEM.id}`, {
|
await game.socket.emit(`system.${CONFIG.DH.id}`, {
|
||||||
action: socketEvent.GMUpdate,
|
action: socketEvent.GMUpdate,
|
||||||
data: {
|
data: {
|
||||||
action: GMUpdateEvent.UpdateSetting,
|
action: GMUpdateEvent.UpdateSetting,
|
||||||
uuid: SYSTEM.SETTINGS.gameSettings.Countdowns,
|
uuid: CONFIG.DH.SETTINGS.gameSettings.Countdowns,
|
||||||
update: update,
|
update: update,
|
||||||
refresh: { refreshType: RefreshType.Countdown, application: `${this.basePath}-countdowns` }
|
refresh: { refreshType: RefreshType.Countdown, application: `${this.basePath}-countdowns` }
|
||||||
}
|
}
|
||||||
|
|
@ -176,7 +178,7 @@ class Countdowns extends HandlebarsApplicationMixin(ApplicationV2) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static onEditImage(_, target) {
|
static onEditImage(_, target) {
|
||||||
const setting = game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Countdowns)[this.basePath];
|
const setting = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Countdowns)[this.basePath];
|
||||||
const current = setting.countdowns[target.dataset.countdown].img;
|
const current = setting.countdowns[target.dataset.countdown].img;
|
||||||
const fp = new foundry.applications.apps.FilePicker.implementation({
|
const fp = new foundry.applications.apps.FilePicker.implementation({
|
||||||
current,
|
current,
|
||||||
|
|
@ -189,7 +191,7 @@ class Countdowns extends HandlebarsApplicationMixin(ApplicationV2) {
|
||||||
}
|
}
|
||||||
|
|
||||||
async updateImage(path, countdown) {
|
async updateImage(path, countdown) {
|
||||||
const setting = game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Countdowns);
|
const setting = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Countdowns);
|
||||||
await setting.updateSource({
|
await setting.updateSource({
|
||||||
[`${this.basePath}.countdowns.${countdown}.img`]: path
|
[`${this.basePath}.countdowns.${countdown}.img`]: path
|
||||||
});
|
});
|
||||||
|
|
@ -199,16 +201,16 @@ class Countdowns extends HandlebarsApplicationMixin(ApplicationV2) {
|
||||||
|
|
||||||
static openOwnership(_, target) {
|
static openOwnership(_, target) {
|
||||||
new Promise((resolve, reject) => {
|
new Promise((resolve, reject) => {
|
||||||
const setting = game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Countdowns)[this.basePath];
|
const setting = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Countdowns)[this.basePath];
|
||||||
const ownership = { default: setting.ownership.default, players: setting.playerOwnership };
|
const ownership = { default: setting.ownership.default, players: setting.playerOwnership };
|
||||||
new OwnershipSelection(resolve, reject, this.title, ownership).render(true);
|
new OwnershipSelection(resolve, reject, this.title, ownership).render(true);
|
||||||
}).then(async ownership => {
|
}).then(async ownership => {
|
||||||
const setting = game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Countdowns);
|
const setting = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Countdowns);
|
||||||
await setting.updateSource({
|
await setting.updateSource({
|
||||||
[`${this.basePath}.ownership`]: ownership
|
[`${this.basePath}.ownership`]: ownership
|
||||||
});
|
});
|
||||||
|
|
||||||
await game.settings.set(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Countdowns, setting.toObject());
|
await game.settings.set(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Countdowns, setting.toObject());
|
||||||
this.render();
|
this.render();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -216,29 +218,29 @@ class Countdowns extends HandlebarsApplicationMixin(ApplicationV2) {
|
||||||
static openCountdownOwnership(_, target) {
|
static openCountdownOwnership(_, target) {
|
||||||
const countdownId = target.dataset.countdown;
|
const countdownId = target.dataset.countdown;
|
||||||
new Promise((resolve, reject) => {
|
new Promise((resolve, reject) => {
|
||||||
const countdown = game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Countdowns)[this.basePath]
|
const countdown = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Countdowns)[this.basePath]
|
||||||
.countdowns[countdownId];
|
.countdowns[countdownId];
|
||||||
const ownership = { default: countdown.ownership.default, players: countdown.playerOwnership };
|
const ownership = { default: countdown.ownership.default, players: countdown.playerOwnership };
|
||||||
new OwnershipSelection(resolve, reject, countdown.name, ownership).render(true);
|
new OwnershipSelection(resolve, reject, countdown.name, ownership).render(true);
|
||||||
}).then(async ownership => {
|
}).then(async ownership => {
|
||||||
const setting = game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Countdowns);
|
const setting = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Countdowns);
|
||||||
await setting.updateSource({
|
await setting.updateSource({
|
||||||
[`${this.basePath}.countdowns.${countdownId}.ownership`]: ownership
|
[`${this.basePath}.countdowns.${countdownId}.ownership`]: ownership
|
||||||
});
|
});
|
||||||
|
|
||||||
await game.settings.set(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Countdowns, setting);
|
await game.settings.set(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Countdowns, setting);
|
||||||
this.render();
|
this.render();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
static async toggleSimpleView() {
|
static async toggleSimpleView() {
|
||||||
this.simpleView = !this.simpleView;
|
this.simpleView = !this.simpleView;
|
||||||
await game.user.setFlag(SYSTEM.id, SYSTEM.FLAGS[`${this.basePath}Countdown`].simple, this.simpleView);
|
await game.user.setFlag(CONFIG.DH.id, CONFIG.DH.FLAGS[`${this.basePath}Countdown`].simple, this.simpleView);
|
||||||
this.render();
|
this.render();
|
||||||
}
|
}
|
||||||
|
|
||||||
async updateCountdownValue(event, increase) {
|
async updateCountdownValue(event, increase) {
|
||||||
const countdownSetting = game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Countdowns);
|
const countdownSetting = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Countdowns);
|
||||||
const countdown = countdownSetting[this.basePath].countdowns[event.currentTarget.dataset.countdown];
|
const countdown = countdownSetting[this.basePath].countdowns[event.currentTarget.dataset.countdown];
|
||||||
|
|
||||||
if (!this.testUserPermission(CONST.DOCUMENT_OWNERSHIP_LEVELS.OWNER)) {
|
if (!this.testUserPermission(CONST.DOCUMENT_OWNERSHIP_LEVELS.OWNER)) {
|
||||||
|
|
@ -260,7 +262,7 @@ class Countdowns extends HandlebarsApplicationMixin(ApplicationV2) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static async addCountdown() {
|
static async addCountdown() {
|
||||||
const countdownSetting = game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Countdowns);
|
const countdownSetting = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Countdowns);
|
||||||
await countdownSetting.updateSource({
|
await countdownSetting.updateSource({
|
||||||
[`${this.basePath}.countdowns.${foundry.utils.randomID()}`]: {
|
[`${this.basePath}.countdowns.${foundry.utils.randomID()}`]: {
|
||||||
name: game.i18n.localize('DAGGERHEART.Countdown.NewCountdown'),
|
name: game.i18n.localize('DAGGERHEART.Countdown.NewCountdown'),
|
||||||
|
|
@ -278,7 +280,7 @@ class Countdowns extends HandlebarsApplicationMixin(ApplicationV2) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static async removeCountdown(_, target) {
|
static async removeCountdown(_, target) {
|
||||||
const countdownSetting = game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Countdowns);
|
const countdownSetting = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Countdowns);
|
||||||
const countdownName = countdownSetting[this.basePath].countdowns[target.dataset.countdown].name;
|
const countdownName = countdownSetting[this.basePath].countdowns[target.dataset.countdown].name;
|
||||||
|
|
||||||
const confirmed = await foundry.applications.api.DialogV2.confirm({
|
const confirmed = await foundry.applications.api.DialogV2.confirm({
|
||||||
|
|
@ -297,8 +299,9 @@ class Countdowns extends HandlebarsApplicationMixin(ApplicationV2) {
|
||||||
async open() {
|
async open() {
|
||||||
await this.render(true);
|
await this.render(true);
|
||||||
if (
|
if (
|
||||||
Object.keys(game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Countdowns)[this.basePath].countdowns)
|
Object.keys(
|
||||||
.length > 0
|
game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Countdowns)[this.basePath].countdowns
|
||||||
|
).length > 0
|
||||||
) {
|
) {
|
||||||
this.minimize();
|
this.minimize();
|
||||||
}
|
}
|
||||||
|
|
@ -327,8 +330,8 @@ export class EncounterCountdowns extends Countdowns {
|
||||||
|
|
||||||
export const registerCountdownApplicationHooks = () => {
|
export const registerCountdownApplicationHooks = () => {
|
||||||
const updateCountdowns = async shouldProgress => {
|
const updateCountdowns = async shouldProgress => {
|
||||||
if (game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Automation).countdowns) {
|
if (game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation).countdowns) {
|
||||||
const countdownSetting = game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Countdowns);
|
const countdownSetting = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Countdowns);
|
||||||
for (let countdownCategoryKey in countdownSetting) {
|
for (let countdownCategoryKey in countdownSetting) {
|
||||||
const countdownCategory = countdownSetting[countdownCategoryKey];
|
const countdownCategory = countdownSetting[countdownCategoryKey];
|
||||||
for (let countdownKey in countdownCategory.countdowns) {
|
for (let countdownKey in countdownCategory.countdowns) {
|
||||||
|
|
@ -339,7 +342,11 @@ export const registerCountdownApplicationHooks = () => {
|
||||||
[`${countdownCategoryKey}.countdowns.${countdownKey}.progress.current`]:
|
[`${countdownCategoryKey}.countdowns.${countdownKey}.progress.current`]:
|
||||||
countdown.progress.current - 1
|
countdown.progress.current - 1
|
||||||
});
|
});
|
||||||
await game.settings.set(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Countdowns, countdownSetting);
|
await game.settings.set(
|
||||||
|
CONFIG.DH.id,
|
||||||
|
CONFIG.DH.SETTINGS.gameSettings.Countdowns,
|
||||||
|
countdownSetting
|
||||||
|
);
|
||||||
foundry.applications.instances.get(`${countdownCategoryKey}-countdowns`)?.render();
|
foundry.applications.instances.get(`${countdownCategoryKey}-countdowns`)?.render();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -347,7 +354,7 @@ export const registerCountdownApplicationHooks = () => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Hooks.on(SYSTEM.HOOKS.characterAttack, async () => {
|
Hooks.on(CONFIG.DH.HOOKS.characterAttack, async () => {
|
||||||
updateCountdowns(countdown => {
|
updateCountdowns(countdown => {
|
||||||
return (
|
return (
|
||||||
countdown.progress.type.value === countdownTypes.characterAttack.id && countdown.progress.current > 0
|
countdown.progress.type.value === countdownTypes.characterAttack.id && countdown.progress.current > 0
|
||||||
|
|
@ -355,7 +362,7 @@ export const registerCountdownApplicationHooks = () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
Hooks.on(SYSTEM.HOOKS.spotlight, async () => {
|
Hooks.on(CONFIG.DH.HOOKS.spotlight, async () => {
|
||||||
updateCountdowns(countdown => {
|
updateCountdowns(countdown => {
|
||||||
return countdown.progress.type.value === countdownTypes.spotlight.id && countdown.progress.current > 0;
|
return countdown.progress.type.value === countdownTypes.spotlight.id && countdown.progress.current > 0;
|
||||||
});
|
});
|
||||||
|
|
@ -8,7 +8,7 @@ const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api;
|
||||||
* @mixes HandlebarsApplication
|
* @mixes HandlebarsApplication
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export default class Resources extends HandlebarsApplicationMixin(ApplicationV2) {
|
export default class FearTracker extends HandlebarsApplicationMixin(ApplicationV2) {
|
||||||
constructor(options = {}) {
|
constructor(options = {}) {
|
||||||
super(options);
|
super(options);
|
||||||
}
|
}
|
||||||
|
|
@ -26,8 +26,8 @@ export default class Resources extends HandlebarsApplicationMixin(ApplicationV2)
|
||||||
minimizable: false
|
minimizable: false
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
setFear: Resources.setFear,
|
setFear: FearTracker.setFear,
|
||||||
increaseFear: Resources.increaseFear
|
increaseFear: FearTracker.increaseFear
|
||||||
},
|
},
|
||||||
position: {
|
position: {
|
||||||
width: 222,
|
width: 222,
|
||||||
|
|
@ -41,16 +41,16 @@ export default class Resources extends HandlebarsApplicationMixin(ApplicationV2)
|
||||||
static PARTS = {
|
static PARTS = {
|
||||||
resources: {
|
resources: {
|
||||||
root: true,
|
root: true,
|
||||||
template: 'systems/daggerheart/templates/views/resources.hbs'
|
template: 'systems/daggerheart/templates/ui/fearTracker.hbs'
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
get currentFear() {
|
get currentFear() {
|
||||||
return game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Resources.Fear);
|
return game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Resources.Fear);
|
||||||
}
|
}
|
||||||
|
|
||||||
get maxFear() {
|
get maxFear() {
|
||||||
return game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Homebrew).maxFear;
|
return game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Homebrew).maxFear;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
|
|
@ -59,7 +59,7 @@ export default class Resources extends HandlebarsApplicationMixin(ApplicationV2)
|
||||||
|
|
||||||
/** @override */
|
/** @override */
|
||||||
async _prepareContext(_options) {
|
async _prepareContext(_options) {
|
||||||
const display = game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.appearance).displayFear,
|
const display = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.appearance).displayFear,
|
||||||
current = this.currentFear,
|
current = this.currentFear,
|
||||||
max = this.maxFear,
|
max = this.maxFear,
|
||||||
percent = (current / max) * 100,
|
percent = (current / max) * 100,
|
||||||
|
|
@ -70,17 +70,18 @@ export default class Resources extends HandlebarsApplicationMixin(ApplicationV2)
|
||||||
|
|
||||||
/** @override */
|
/** @override */
|
||||||
async _preFirstRender(context, options) {
|
async _preFirstRender(context, options) {
|
||||||
options.position = game.user.getFlag(SYSTEM.id, 'app.resources.position') ?? Resources.DEFAULT_OPTIONS.position;
|
options.position =
|
||||||
|
game.user.getFlag(CONFIG.DH.id, 'app.resources.position') ?? FearTracker.DEFAULT_OPTIONS.position;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @override */
|
/** @override */
|
||||||
async _preRender(context, options) {
|
async _preRender(context, options) {
|
||||||
if (this.currentFear > this.maxFear)
|
if (this.currentFear > this.maxFear)
|
||||||
await game.settings.set(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Resources.Fear, this.maxFear);
|
await game.settings.set(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Resources.Fear, this.maxFear);
|
||||||
}
|
}
|
||||||
|
|
||||||
_onPosition(position) {
|
_onPosition(position) {
|
||||||
game.user.setFlag(SYSTEM.id, 'app.resources.position', position);
|
game.user.setFlag(CONFIG.DH.id, 'app.resources.position', position);
|
||||||
}
|
}
|
||||||
|
|
||||||
async close(options = {}) {
|
async close(options = {}) {
|
||||||
|
|
@ -104,6 +105,6 @@ export default class Resources extends HandlebarsApplicationMixin(ApplicationV2)
|
||||||
async updateFear(value) {
|
async updateFear(value) {
|
||||||
if (!game.user.isGM) return;
|
if (!game.user.isGM) return;
|
||||||
value = Math.max(0, Math.min(this.maxFear, value));
|
value = Math.max(0, Math.min(this.maxFear, value));
|
||||||
await game.settings.set(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Resources.Fear, value);
|
await game.settings.set(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Resources.Fear, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1 +1,2 @@
|
||||||
export { default as FilterMenu } from './filter-menu.mjs';
|
export { default as FilterMenu } from './filter-menu.mjs';
|
||||||
|
export { default as ContextMenu } from './contextMenu.mjs';
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,8 @@ export default class FilterMenu extends foundry.applications.ux.ContextMenu {
|
||||||
const mergedOptions = {
|
const mergedOptions = {
|
||||||
eventName: 'click',
|
eventName: 'click',
|
||||||
fixed: true,
|
fixed: true,
|
||||||
...options
|
...options,
|
||||||
|
jQuery: false
|
||||||
};
|
};
|
||||||
|
|
||||||
super(container, selector, menuItems, mergedOptions);
|
super(container, selector, menuItems, mergedOptions);
|
||||||
|
|
@ -176,7 +177,7 @@ export default class FilterMenu extends foundry.applications.ux.ContextMenu {
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const burdenFilter = Object.values(CONFIG.daggerheart.GENERAL.burden).map(({ value, label }) => ({
|
const burdenFilter = Object.values(CONFIG.DH.GENERAL.burden).map(({ value, label }) => ({
|
||||||
group: game.i18n.localize('DAGGERHEART.Sheets.Weapon.Burden'),
|
group: game.i18n.localize('DAGGERHEART.Sheets.Weapon.Burden'),
|
||||||
name: game.i18n.localize(label),
|
name: game.i18n.localize(label),
|
||||||
filter: {
|
filter: {
|
||||||
|
|
@ -186,7 +187,7 @@ export default class FilterMenu extends foundry.applications.ux.ContextMenu {
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const damageTypeFilter = Object.values(CONFIG.daggerheart.GENERAL.damageTypes).map(({ id, abbreviation }) => ({
|
const damageTypeFilter = Object.values(CONFIG.DH.GENERAL.damageTypes).map(({ id, abbreviation }) => ({
|
||||||
group: 'Damage Type', //TODO localize
|
group: 'Damage Type', //TODO localize
|
||||||
name: game.i18n.localize(abbreviation),
|
name: game.i18n.localize(abbreviation),
|
||||||
filter: {
|
filter: {
|
||||||
|
|
@ -210,7 +211,7 @@ export default class FilterMenu extends foundry.applications.ux.ContextMenu {
|
||||||
static get cardsFilters() {
|
static get cardsFilters() {
|
||||||
const { OPERATORS } = foundry.applications.ux.SearchFilter;
|
const { OPERATORS } = foundry.applications.ux.SearchFilter;
|
||||||
|
|
||||||
const typesFilters = Object.values(CONFIG.daggerheart.DOMAIN.cardTypes).map(({ id, label }) => ({
|
const typesFilters = Object.values(CONFIG.DH.DOMAIN.cardTypes).map(({ id, label }) => ({
|
||||||
group: game.i18n.localize('Type'),
|
group: game.i18n.localize('Type'),
|
||||||
name: game.i18n.localize(label),
|
name: game.i18n.localize(label),
|
||||||
filter: {
|
filter: {
|
||||||
|
|
@ -220,7 +221,7 @@ export default class FilterMenu extends foundry.applications.ux.ContextMenu {
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const domainFilter = Object.values(CONFIG.daggerheart.DOMAIN.domains).map(({ id, label }) => ({
|
const domainFilter = Object.values(CONFIG.DH.DOMAIN.domains).map(({ id, label }) => ({
|
||||||
group: game.i18n.localize('DAGGERHEART.Sheets.DomainCard.Domain'),
|
group: game.i18n.localize('DAGGERHEART.Sheets.DomainCard.Domain'),
|
||||||
name: game.i18n.localize(label),
|
name: game.i18n.localize(label),
|
||||||
filter: {
|
filter: {
|
||||||
|
|
|
||||||
1
module/canvas/_module.mjs
Normal file
1
module/canvas/_module.mjs
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
export * as placeables from './placeables/_module.mjs';
|
||||||
3
module/canvas/placeables/_module.mjs
Normal file
3
module/canvas/placeables/_module.mjs
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
export { default as DhMeasuredTemplate } from './measuredTemplate.mjs';
|
||||||
|
export { default as DhRuler } from './ruler.mjs';
|
||||||
|
export { default as DhTokenRuler } from './tokenRuler.mjs';
|
||||||
|
|
@ -2,7 +2,10 @@ export default class DhMeasuredTemplate extends foundry.canvas.placeables.Measur
|
||||||
_refreshRulerText() {
|
_refreshRulerText() {
|
||||||
super._refreshRulerText();
|
super._refreshRulerText();
|
||||||
|
|
||||||
const rangeMeasurementSettings = game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.RangeMeasurement);
|
const rangeMeasurementSettings = game.settings.get(
|
||||||
|
CONFIG.DH.id,
|
||||||
|
CONFIG.DH.SETTINGS.gameSettings.RangeMeasurement
|
||||||
|
);
|
||||||
if (rangeMeasurementSettings.enabled) {
|
if (rangeMeasurementSettings.enabled) {
|
||||||
const splitRulerText = this.ruler.text.split(' ');
|
const splitRulerText = this.ruler.text.split(' ');
|
||||||
if (splitRulerText.length > 0) {
|
if (splitRulerText.length > 0) {
|
||||||
|
|
@ -5,7 +5,7 @@ export default class DhpRuler extends foundry.canvas.interaction.Ruler {
|
||||||
const context = super._getWaypointLabelContext(waypoint, state);
|
const context = super._getWaypointLabelContext(waypoint, state);
|
||||||
if (!context) return;
|
if (!context) return;
|
||||||
|
|
||||||
const range = game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.RangeMeasurement);
|
const range = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.RangeMeasurement);
|
||||||
|
|
||||||
if (range.enabled) {
|
if (range.enabled) {
|
||||||
const distance = DhMeasuredTemplate.getDistanceLabel(waypoint.measurement.distance.toNearest(0.01), range);
|
const distance = DhMeasuredTemplate.getDistanceLabel(waypoint.measurement.distance.toNearest(0.01), range);
|
||||||
|
|
@ -5,7 +5,7 @@ export default class DhpTokenRuler extends foundry.canvas.placeables.tokens.Toke
|
||||||
const context = super._getWaypointLabelContext(waypoint, state);
|
const context = super._getWaypointLabelContext(waypoint, state);
|
||||||
if (!context) return;
|
if (!context) return;
|
||||||
|
|
||||||
const range = game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.RangeMeasurement);
|
const range = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.RangeMeasurement);
|
||||||
|
|
||||||
if (range.enabled) {
|
if (range.enabled) {
|
||||||
const distance = DhMeasuredTemplate.getDistanceLabel(waypoint.measurement.distance.toNearest(0.01), range);
|
const distance = DhMeasuredTemplate.getDistanceLabel(waypoint.measurement.distance.toNearest(0.01), range);
|
||||||
10
module/config/_module.mjs
Normal file
10
module/config/_module.mjs
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
export * as actionConfig from './actionConfig.mjs';
|
||||||
|
export * as actorConfig from './actorConfig.mjs';
|
||||||
|
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';
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { range } from './generalConfig.mjs';
|
import { range } from '../config/generalConfig.mjs';
|
||||||
|
|
||||||
export const valueTypes = {
|
export const valueTypes = {
|
||||||
numberString: {
|
numberString: {
|
||||||
|
|
|
||||||
|
|
@ -290,7 +290,7 @@ export const diceSetNumbers = {
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getDiceSoNicePresets = () => {
|
export const getDiceSoNicePresets = () => {
|
||||||
const { diceSoNice } = game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.appearance);
|
const { diceSoNice } = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.appearance);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
hope: {
|
hope: {
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
export { default as DhCombat } from './combat.mjs';
|
export { default as DhCombat } from './combat.mjs';
|
||||||
export { default as DhCombatant } from './combatant.mjs';
|
export { default as DhCombatant } from './combatant.mjs';
|
||||||
|
|
||||||
export * as actors from './actor/_module.mjs';
|
export * as actions from './action/_module.mjs';
|
||||||
export * as items from './item/_module.mjs';
|
|
||||||
export { actionsTypes } from './action/_module.mjs';
|
|
||||||
export * as messages from './chat-message/_modules.mjs';
|
|
||||||
export * as fields from './fields/_module.mjs';
|
|
||||||
export * as activeEffects from './activeEffect/_module.mjs';
|
export * as activeEffects from './activeEffect/_module.mjs';
|
||||||
|
export * as actors from './actor/_module.mjs';
|
||||||
|
export * as chatMessages from './chat-message/_modules.mjs';
|
||||||
|
export * as fields from './fields/_module.mjs';
|
||||||
|
export * as items from './item/_module.mjs';
|
||||||
|
|
|
||||||
|
|
@ -1,25 +1,20 @@
|
||||||
import {
|
export * as ActionDice from './actionDice.mjs';
|
||||||
DHAttackAction,
|
import AttackAction from './attackAction.mjs';
|
||||||
DHBaseAction,
|
import BaseAction from './baseAction.mjs';
|
||||||
DhBeastformAction,
|
import BeastformAction from './beastformAction.mjs';
|
||||||
DHDamageAction,
|
import DamageAction from './damageAction.mjs';
|
||||||
DHEffectAction,
|
import EffectAction from './effectAction.mjs';
|
||||||
DHHealingAction,
|
import HealingAction from './healingAction.mjs';
|
||||||
DHMacroAction,
|
import MacroAction from './macroAction.mjs';
|
||||||
// DHResourceAction,
|
import SummonAction from './summonAction.mjs';
|
||||||
// DHSpellCastAction,
|
|
||||||
DHSummonAction
|
|
||||||
} from './action.mjs';
|
|
||||||
|
|
||||||
export const actionsTypes = {
|
export const actionsTypes = {
|
||||||
base: DHBaseAction,
|
base: BaseAction,
|
||||||
attack: DHAttackAction,
|
attack: AttackAction,
|
||||||
// spellcast: DHSpellCastAction,
|
damage: DamageAction,
|
||||||
// resource: DHResourceAction,
|
healing: HealingAction,
|
||||||
damage: DHDamageAction,
|
summon: SummonAction,
|
||||||
healing: DHHealingAction,
|
effect: EffectAction,
|
||||||
summon: DHSummonAction,
|
macro: MacroAction,
|
||||||
effect: DHEffectAction,
|
beastform: BeastformAction
|
||||||
macro: DHMacroAction,
|
|
||||||
beastform: DhBeastformAction
|
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -8,21 +8,25 @@ export class DHActionRollData extends foundry.abstract.DataModel {
|
||||||
/** @override */
|
/** @override */
|
||||||
static defineSchema() {
|
static defineSchema() {
|
||||||
return {
|
return {
|
||||||
type: new fields.StringField({ nullable: true, initial: null, choices: SYSTEM.GENERAL.rollTypes }),
|
type: new fields.StringField({ nullable: true, initial: null, choices: CONFIG.DH.GENERAL.rollTypes }),
|
||||||
trait: new fields.StringField({ nullable: true, initial: null, choices: SYSTEM.ACTOR.abilities }),
|
trait: new fields.StringField({ nullable: true, initial: null, choices: CONFIG.DH.ACTOR.abilities }),
|
||||||
difficulty: new fields.NumberField({ nullable: true, initial: null, integer: true, min: 0 }),
|
difficulty: new fields.NumberField({ nullable: true, initial: null, integer: true, min: 0 }),
|
||||||
bonus: new fields.NumberField({ nullable: true, initial: null, integer: true }),
|
bonus: new fields.NumberField({ nullable: true, initial: null, integer: true }),
|
||||||
advState: new fields.StringField({ choices: SYSTEM.ACTIONS.advandtageState, initial: 'neutral' }),
|
advState: new fields.StringField({ choices: CONFIG.DH.ACTIONS.advandtageState, initial: 'neutral' }),
|
||||||
diceRolling: new fields.SchemaField({
|
diceRolling: new fields.SchemaField({
|
||||||
multiplier: new fields.StringField({
|
multiplier: new fields.StringField({
|
||||||
choices: SYSTEM.GENERAL.diceSetNumbers,
|
choices: CONFIG.DH.GENERAL.diceSetNumbers,
|
||||||
initial: 'prof',
|
initial: 'prof',
|
||||||
label: 'Dice Number'
|
label: 'Dice Number'
|
||||||
}),
|
}),
|
||||||
flatMultiplier: new fields.NumberField({ nullable: true, initial: 1, label: 'Flat Multiplier' }),
|
flatMultiplier: new fields.NumberField({ nullable: true, initial: 1, label: 'Flat Multiplier' }),
|
||||||
dice: new fields.StringField({ choices: SYSTEM.GENERAL.diceTypes, initial: 'd6', label: 'Dice Type' }),
|
dice: new fields.StringField({
|
||||||
|
choices: CONFIG.DH.GENERAL.diceTypes,
|
||||||
|
initial: 'd6',
|
||||||
|
label: 'Dice Type'
|
||||||
|
}),
|
||||||
compare: new fields.StringField({
|
compare: new fields.StringField({
|
||||||
choices: SYSTEM.ACTIONS.diceCompare,
|
choices: CONFIG.DH.ACTIONS.diceCompare,
|
||||||
initial: 'above',
|
initial: 'above',
|
||||||
label: 'Should be'
|
label: 'Should be'
|
||||||
}),
|
}),
|
||||||
|
|
@ -40,7 +44,7 @@ export class DHActionRollData extends foundry.abstract.DataModel {
|
||||||
this.diceRolling.multiplier === 'flat'
|
this.diceRolling.multiplier === 'flat'
|
||||||
? this.diceRolling.flatMultiplier
|
? this.diceRolling.flatMultiplier
|
||||||
: `@${this.diceRolling.multiplier}`;
|
: `@${this.diceRolling.multiplier}`;
|
||||||
formula = `${multiplier}${this.diceRolling.dice}cs${SYSTEM.ACTIONS.diceCompare[this.diceRolling.compare].operator}${this.diceRolling.treshold}`;
|
formula = `${multiplier}${this.diceRolling.dice}cs${CONFIG.DH.ACTIONS.diceCompare[this.diceRolling.compare].operator}${this.diceRolling.treshold}`;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
// formula = `${(!!this.parent?.actor?.system?.attack ? `@attackBonus` : `@traits.${this.trait}.total`)}`;
|
// formula = `${(!!this.parent?.actor?.system?.attack ? `@attackBonus` : `@traits.${this.trait}.total`)}`;
|
||||||
|
|
@ -58,12 +62,12 @@ export class DHActionDiceData extends foundry.abstract.DataModel {
|
||||||
static defineSchema() {
|
static defineSchema() {
|
||||||
return {
|
return {
|
||||||
multiplier: new fields.StringField({
|
multiplier: new fields.StringField({
|
||||||
choices: SYSTEM.GENERAL.multiplierTypes,
|
choices: CONFIG.DH.GENERAL.multiplierTypes,
|
||||||
initial: 'prof',
|
initial: 'prof',
|
||||||
label: 'Multiplier'
|
label: 'Multiplier'
|
||||||
}),
|
}),
|
||||||
flatMultiplier: new fields.NumberField({ nullable: true, initial: 1, label: 'Flat Multiplier' }),
|
flatMultiplier: new fields.NumberField({ nullable: true, initial: 1, label: 'Flat Multiplier' }),
|
||||||
dice: new fields.StringField({ choices: SYSTEM.GENERAL.diceTypes, initial: 'd6', label: 'Dice' }),
|
dice: new fields.StringField({ choices: CONFIG.DH.GENERAL.diceTypes, initial: 'd6', label: 'Dice' }),
|
||||||
bonus: new fields.NumberField({ nullable: true, initial: null, label: 'Bonus' }),
|
bonus: new fields.NumberField({ nullable: true, initial: null, label: 'Bonus' }),
|
||||||
custom: new fields.SchemaField({
|
custom: new fields.SchemaField({
|
||||||
enabled: new fields.BooleanField({ label: 'Custom Formula' }),
|
enabled: new fields.BooleanField({ label: 'Custom Formula' }),
|
||||||
|
|
@ -101,7 +105,7 @@ export class DHDamageData extends foundry.abstract.DataModel {
|
||||||
// ...super.defineSchema(),
|
// ...super.defineSchema(),
|
||||||
base: new fields.BooleanField({ initial: false, readonly: true, label: 'Base' }),
|
base: new fields.BooleanField({ initial: false, readonly: true, label: 'Base' }),
|
||||||
type: new fields.StringField({
|
type: new fields.StringField({
|
||||||
choices: SYSTEM.GENERAL.damageTypes,
|
choices: CONFIG.DH.GENERAL.damageTypes,
|
||||||
initial: 'physical',
|
initial: 'physical',
|
||||||
label: 'Type',
|
label: 'Type',
|
||||||
nullable: false,
|
nullable: false,
|
||||||
|
|
|
||||||
34
module/data/action/attackAction.mjs
Normal file
34
module/data/action/attackAction.mjs
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
import { DHDamageData } from './actionDice.mjs';
|
||||||
|
import DHDamageAction from './damageAction.mjs';
|
||||||
|
|
||||||
|
export default class DHAttackAction extends DHDamageAction {
|
||||||
|
static extraSchemas = [...super.extraSchemas, ...['roll', 'save']];
|
||||||
|
|
||||||
|
static getRollType(parent) {
|
||||||
|
return parent.type === 'weapon' ? 'weapon' : 'spellcast';
|
||||||
|
}
|
||||||
|
|
||||||
|
get chatTemplate() {
|
||||||
|
return 'systems/daggerheart/templates/ui/chat/duality-roll.hbs';
|
||||||
|
}
|
||||||
|
|
||||||
|
prepareData() {
|
||||||
|
super.prepareData();
|
||||||
|
if (this.damage.includeBase && !!this.item?.system?.damage) {
|
||||||
|
const baseDamage = this.getParentDamage();
|
||||||
|
this.damage.parts.unshift(new DHDamageData(baseDamage));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getParentDamage() {
|
||||||
|
return {
|
||||||
|
value: {
|
||||||
|
multiplier: 'prof',
|
||||||
|
dice: this.item?.system?.damage.dice,
|
||||||
|
bonus: this.item?.system?.damage.bonus ?? 0
|
||||||
|
},
|
||||||
|
type: this.item?.system?.damage.type,
|
||||||
|
base: true
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
import { DHActionDiceData, DHActionRollData, DHDamageData, DHDamageField } from './actionDice.mjs';
|
import { DHActionDiceData, DHActionRollData, DHDamageData, DHDamageField } from './actionDice.mjs';
|
||||||
import DhpActor from '../../documents/actor.mjs';
|
import DhpActor from '../../documents/actor.mjs';
|
||||||
import D20RollDialog from '../../dialogs/d20RollDialog.mjs';
|
import D20RollDialog from '../../applications/dialogs/d20RollDialog.mjs';
|
||||||
import BeastformDialog from '../../dialogs/beastformDialog.mjs';
|
|
||||||
|
|
||||||
const fields = foundry.data.fields;
|
const fields = foundry.data.fields;
|
||||||
|
|
||||||
|
|
@ -21,7 +20,7 @@ const fields = foundry.data.fields;
|
||||||
- Auto use action <= Into Roll
|
- Auto use action <= Into Roll
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export class DHBaseAction extends foundry.abstract.DataModel {
|
export default class DHBaseAction extends foundry.abstract.DataModel {
|
||||||
static extraSchemas = [];
|
static extraSchemas = [];
|
||||||
|
|
||||||
static defineSchema() {
|
static defineSchema() {
|
||||||
|
|
@ -33,11 +32,15 @@ export class DHBaseAction extends foundry.abstract.DataModel {
|
||||||
description: new fields.HTMLField(),
|
description: new fields.HTMLField(),
|
||||||
img: new fields.FilePathField({ initial: undefined, categories: ['IMAGE'], base64: false }),
|
img: new fields.FilePathField({ initial: undefined, categories: ['IMAGE'], base64: false }),
|
||||||
chatDisplay: new fields.BooleanField({ initial: true, label: 'Display in chat' }),
|
chatDisplay: new fields.BooleanField({ initial: true, label: 'Display in chat' }),
|
||||||
actionType: new fields.StringField({ choices: SYSTEM.ITEM.actionTypes, initial: 'action', nullable: true }),
|
actionType: new fields.StringField({
|
||||||
|
choices: CONFIG.DH.ITEM.actionTypes,
|
||||||
|
initial: 'action',
|
||||||
|
nullable: true
|
||||||
|
}),
|
||||||
cost: new fields.ArrayField(
|
cost: new fields.ArrayField(
|
||||||
new fields.SchemaField({
|
new fields.SchemaField({
|
||||||
type: new fields.StringField({
|
type: new fields.StringField({
|
||||||
choices: SYSTEM.GENERAL.abilityCosts,
|
choices: CONFIG.DH.GENERAL.abilityCosts,
|
||||||
nullable: false,
|
nullable: false,
|
||||||
required: true,
|
required: true,
|
||||||
initial: 'hope'
|
initial: 'hope'
|
||||||
|
|
@ -51,13 +54,13 @@ export class DHBaseAction extends foundry.abstract.DataModel {
|
||||||
value: new fields.NumberField({ nullable: true, initial: null }),
|
value: new fields.NumberField({ nullable: true, initial: null }),
|
||||||
max: new fields.NumberField({ nullable: true, initial: null }),
|
max: new fields.NumberField({ nullable: true, initial: null }),
|
||||||
recovery: new fields.StringField({
|
recovery: new fields.StringField({
|
||||||
choices: SYSTEM.GENERAL.refreshTypes,
|
choices: CONFIG.DH.GENERAL.refreshTypes,
|
||||||
initial: null,
|
initial: null,
|
||||||
nullable: true
|
nullable: true
|
||||||
})
|
})
|
||||||
}),
|
}),
|
||||||
range: new fields.StringField({
|
range: new fields.StringField({
|
||||||
choices: SYSTEM.GENERAL.range,
|
choices: CONFIG.DH.GENERAL.range,
|
||||||
required: false,
|
required: false,
|
||||||
blank: true
|
blank: true
|
||||||
// initial: null
|
// initial: null
|
||||||
|
|
@ -71,17 +74,21 @@ export class DHBaseAction extends foundry.abstract.DataModel {
|
||||||
damage: new DHDamageField(),
|
damage: new DHDamageField(),
|
||||||
roll: new fields.EmbeddedDataField(DHActionRollData),
|
roll: new fields.EmbeddedDataField(DHActionRollData),
|
||||||
save: new fields.SchemaField({
|
save: new fields.SchemaField({
|
||||||
trait: new fields.StringField({ nullable: true, initial: null, choices: SYSTEM.ACTOR.abilities }),
|
trait: new fields.StringField({
|
||||||
|
nullable: true,
|
||||||
|
initial: null,
|
||||||
|
choices: CONFIG.DH.ACTOR.abilities
|
||||||
|
}),
|
||||||
difficulty: new fields.NumberField({ nullable: true, initial: 10, integer: true, min: 0 }),
|
difficulty: new fields.NumberField({ nullable: true, initial: 10, integer: true, min: 0 }),
|
||||||
damageMod: new fields.StringField({
|
damageMod: new fields.StringField({
|
||||||
initial: SYSTEM.ACTIONS.damageOnSave.none.id,
|
initial: CONFIG.DH.ACTIONS.damageOnSave.none.id,
|
||||||
choices: SYSTEM.ACTIONS.damageOnSave
|
choices: CONFIG.DH.ACTIONS.damageOnSave
|
||||||
})
|
})
|
||||||
}),
|
}),
|
||||||
target: new fields.SchemaField({
|
target: new fields.SchemaField({
|
||||||
type: new fields.StringField({
|
type: new fields.StringField({
|
||||||
choices: SYSTEM.ACTIONS.targetTypes,
|
choices: CONFIG.DH.ACTIONS.targetTypes,
|
||||||
initial: SYSTEM.ACTIONS.targetTypes.any.id,
|
initial: CONFIG.DH.ACTIONS.targetTypes.any.id,
|
||||||
nullable: true,
|
nullable: true,
|
||||||
initial: null
|
initial: null
|
||||||
}),
|
}),
|
||||||
|
|
@ -95,10 +102,10 @@ export class DHBaseAction extends foundry.abstract.DataModel {
|
||||||
),
|
),
|
||||||
healing: new fields.SchemaField({
|
healing: new fields.SchemaField({
|
||||||
type: new fields.StringField({
|
type: new fields.StringField({
|
||||||
choices: SYSTEM.GENERAL.healingTypes,
|
choices: CONFIG.DH.GENERAL.healingTypes,
|
||||||
required: true,
|
required: true,
|
||||||
blank: false,
|
blank: false,
|
||||||
initial: SYSTEM.GENERAL.healingTypes.hitPoints.id,
|
initial: CONFIG.DH.GENERAL.healingTypes.hitPoints.id,
|
||||||
label: 'Healing'
|
label: 'Healing'
|
||||||
}),
|
}),
|
||||||
resultBased: new fields.BooleanField({
|
resultBased: new fields.BooleanField({
|
||||||
|
|
@ -143,7 +150,7 @@ export class DHBaseAction extends foundry.abstract.DataModel {
|
||||||
}
|
}
|
||||||
|
|
||||||
get chatTemplate() {
|
get chatTemplate() {
|
||||||
return 'systems/daggerheart/templates/chat/duality-roll.hbs';
|
return 'systems/daggerheart/templates/ui/chat/duality-roll.hbs';
|
||||||
}
|
}
|
||||||
|
|
||||||
static getRollType(parent) {
|
static getRollType(parent) {
|
||||||
|
|
@ -228,7 +235,7 @@ export class DHBaseAction extends foundry.abstract.DataModel {
|
||||||
data: actorData
|
data: actorData
|
||||||
};
|
};
|
||||||
|
|
||||||
if (Hooks.call(`${SYSTEM.id}.preUseAction`, this, config) === false) return;
|
if (Hooks.call(`${CONFIG.DH.id}.preUseAction`, this, config) === false) return;
|
||||||
|
|
||||||
// Display configuration window if necessary
|
// Display configuration window if necessary
|
||||||
if (config.dialog?.configure && this.requireConfigurationDialog(config)) {
|
if (config.dialog?.configure && this.requireConfigurationDialog(config)) {
|
||||||
|
|
@ -284,7 +291,7 @@ export class DHBaseAction extends foundry.abstract.DataModel {
|
||||||
// Consume resources
|
// Consume resources
|
||||||
await this.consume(config);
|
await this.consume(config);
|
||||||
|
|
||||||
if (Hooks.call(`${SYSTEM.id}.postUseAction`, this, config) === false) return;
|
if (Hooks.call(`${CONFIG.DH.id}.postUseAction`, this, config) === false) return;
|
||||||
|
|
||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
|
|
@ -324,11 +331,11 @@ export class DHBaseAction extends foundry.abstract.DataModel {
|
||||||
|
|
||||||
prepareTarget() {
|
prepareTarget() {
|
||||||
let targets;
|
let targets;
|
||||||
if (this.target?.type === SYSTEM.ACTIONS.targetTypes.self.id)
|
if (this.target?.type === CONFIG.DH.ACTIONS.targetTypes.self.id)
|
||||||
targets = this.constructor.formatTarget(this.actor.token ?? this.actor.prototypeToken);
|
targets = this.constructor.formatTarget(this.actor.token ?? this.actor.prototypeToken);
|
||||||
targets = Array.from(game.user.targets);
|
targets = Array.from(game.user.targets);
|
||||||
// foundry.CONST.TOKEN_DISPOSITIONS.FRIENDLY
|
// foundry.CONST.TOKEN_DISPOSITIONS.FRIENDLY
|
||||||
if (this.target?.type && this.target.type !== SYSTEM.ACTIONS.targetTypes.any.id) {
|
if (this.target?.type && this.target.type !== CONFIG.DH.ACTIONS.targetTypes.any.id) {
|
||||||
targets = targets.filter(t => this.isTargetFriendly(t));
|
targets = targets.filter(t => this.isTargetFriendly(t));
|
||||||
if (this.target.amount && targets.length > this.target.amount) targets = [];
|
if (this.target.amount && targets.length > this.target.amount) targets = [];
|
||||||
}
|
}
|
||||||
|
|
@ -350,7 +357,7 @@ export class DHBaseAction extends foundry.abstract.DataModel {
|
||||||
difficulty: this.roll?.difficulty,
|
difficulty: this.roll?.difficulty,
|
||||||
formula: this.roll.getFormula(),
|
formula: this.roll.getFormula(),
|
||||||
bonus: this.roll.bonus,
|
bonus: this.roll.bonus,
|
||||||
advantage: SYSTEM.ACTIONS.advandtageState[this.roll.advState].value
|
advantage: CONFIG.DH.ACTIONS.advandtageState[this.roll.advState].value
|
||||||
};
|
};
|
||||||
if (this.roll?.type === 'diceSet') roll.lite = true;
|
if (this.roll?.type === 'diceSet') roll.lite = true;
|
||||||
|
|
||||||
|
|
@ -413,7 +420,7 @@ export class DHBaseAction extends foundry.abstract.DataModel {
|
||||||
const fearCost = realCosts.splice(hasFearCost, 1);
|
const fearCost = realCosts.splice(hasFearCost, 1);
|
||||||
if (
|
if (
|
||||||
!game.user.isGM ||
|
!game.user.isGM ||
|
||||||
fearCost[0].total > game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Resources.Fear)
|
fearCost[0].total > game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Resources.Fear)
|
||||||
)
|
)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -446,8 +453,10 @@ export class DHBaseAction extends foundry.abstract.DataModel {
|
||||||
: this.actor.prototypeToken.disposition,
|
: this.actor.prototypeToken.disposition,
|
||||||
targetDisposition = target.document.disposition;
|
targetDisposition = target.document.disposition;
|
||||||
return (
|
return (
|
||||||
(this.target.type === SYSTEM.ACTIONS.targetTypes.friendly.id && actorDisposition === targetDisposition) ||
|
(this.target.type === CONFIG.DH.ACTIONS.targetTypes.friendly.id &&
|
||||||
(this.target.type === SYSTEM.ACTIONS.targetTypes.hostile.id && actorDisposition + targetDisposition === 0)
|
actorDisposition === targetDisposition) ||
|
||||||
|
(this.target.type === CONFIG.DH.ACTIONS.targetTypes.hostile.id &&
|
||||||
|
actorDisposition + targetDisposition === 0)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -567,7 +576,7 @@ export class DHBaseAction extends foundry.abstract.DataModel {
|
||||||
user: game.user.id,
|
user: game.user.id,
|
||||||
system: systemData,
|
system: systemData,
|
||||||
content: await foundry.applications.handlebars.renderTemplate(
|
content: await foundry.applications.handlebars.renderTemplate(
|
||||||
'systems/daggerheart/templates/chat/ability-use.hbs',
|
'systems/daggerheart/templates/ui/chat/ability-use.hbs',
|
||||||
systemData
|
systemData
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
|
@ -575,239 +584,3 @@ export class DHBaseAction extends foundry.abstract.DataModel {
|
||||||
cls.create(msg.toObject());
|
cls.create(msg.toObject());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class DHDamageAction extends DHBaseAction {
|
|
||||||
static extraSchemas = ['damage', 'target', 'effects'];
|
|
||||||
|
|
||||||
getFormulaValue(part, data) {
|
|
||||||
let formulaValue = part.value;
|
|
||||||
if (this.hasRoll && part.resultBased && data.system.roll.result.duality === -1) return part.valueAlt;
|
|
||||||
return formulaValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
async rollDamage(event, data) {
|
|
||||||
let formula = this.damage.parts.map(p => this.getFormulaValue(p, data).getFormula(this.actor)).join(' + ');
|
|
||||||
|
|
||||||
if (!formula || formula == '') return;
|
|
||||||
let roll = { formula: formula, total: formula },
|
|
||||||
bonusDamage = [];
|
|
||||||
|
|
||||||
if (isNaN(formula)) formula = Roll.replaceFormulaData(formula, this.getRollData(data.system ?? data));
|
|
||||||
|
|
||||||
const config = {
|
|
||||||
title: game.i18n.format('DAGGERHEART.Chat.DamageRoll.Title', { damage: this.name }),
|
|
||||||
roll: { formula },
|
|
||||||
targets: data.system?.targets.filter(t => t.hit) ?? data.targets,
|
|
||||||
hasSave: this.hasSave,
|
|
||||||
isCritical: data.system?.roll?.isCritical ?? false,
|
|
||||||
source: data.system?.source,
|
|
||||||
event
|
|
||||||
};
|
|
||||||
if (this.hasSave) config.onSave = this.save.damageMod;
|
|
||||||
if (data.system) {
|
|
||||||
config.source.message = data._id;
|
|
||||||
config.directDamage = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
roll = CONFIG.Dice.daggerheart.DamageRoll.build(config);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class DHAttackAction extends DHDamageAction {
|
|
||||||
static extraSchemas = [...super.extraSchemas, ...['roll', 'save']];
|
|
||||||
|
|
||||||
static getRollType(parent) {
|
|
||||||
return parent.type === 'weapon' ? 'weapon' : 'spellcast';
|
|
||||||
}
|
|
||||||
|
|
||||||
get chatTemplate() {
|
|
||||||
return 'systems/daggerheart/templates/chat/duality-roll.hbs';
|
|
||||||
}
|
|
||||||
|
|
||||||
prepareData() {
|
|
||||||
super.prepareData();
|
|
||||||
if (this.damage.includeBase && !!this.item?.system?.damage) {
|
|
||||||
const baseDamage = this.getParentDamage();
|
|
||||||
this.damage.parts.unshift(new DHDamageData(baseDamage));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
getParentDamage() {
|
|
||||||
return {
|
|
||||||
value: {
|
|
||||||
multiplier: 'prof',
|
|
||||||
dice: this.item?.system?.damage.dice,
|
|
||||||
bonus: this.item?.system?.damage.bonus ?? 0
|
|
||||||
},
|
|
||||||
type: this.item?.system?.damage.type,
|
|
||||||
base: true
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class DHHealingAction extends DHBaseAction {
|
|
||||||
static extraSchemas = ['target', 'effects', 'healing', 'roll'];
|
|
||||||
|
|
||||||
static getRollType(parent) {
|
|
||||||
return 'spellcast';
|
|
||||||
}
|
|
||||||
|
|
||||||
getFormulaValue(data) {
|
|
||||||
let formulaValue = this.healing.value;
|
|
||||||
if (this.hasRoll && this.healing.resultBased && data.system.roll.result.duality === -1)
|
|
||||||
return this.healing.valueAlt;
|
|
||||||
return formulaValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
async rollHealing(event, data) {
|
|
||||||
let formulaValue = this.getFormulaValue(data),
|
|
||||||
formula = formulaValue.getFormula(this.actor);
|
|
||||||
|
|
||||||
if (!formula || formula == '') return;
|
|
||||||
let roll = { formula: formula, total: formula },
|
|
||||||
bonusDamage = [];
|
|
||||||
|
|
||||||
const config = {
|
|
||||||
title: game.i18n.format('DAGGERHEART.Chat.HealingRoll.Title', {
|
|
||||||
healing: game.i18n.localize(SYSTEM.GENERAL.healingTypes[this.healing.type].label)
|
|
||||||
}),
|
|
||||||
roll: { formula },
|
|
||||||
targets: (data.system?.targets ?? data.targets).filter(t => t.hit),
|
|
||||||
messageType: 'healing',
|
|
||||||
type: this.healing.type,
|
|
||||||
event
|
|
||||||
};
|
|
||||||
|
|
||||||
roll = CONFIG.Dice.daggerheart.DamageRoll.build(config);
|
|
||||||
}
|
|
||||||
|
|
||||||
get chatTemplate() {
|
|
||||||
return 'systems/daggerheart/templates/chat/healing-roll.hbs';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class DHSummonAction extends DHBaseAction {
|
|
||||||
static defineSchema() {
|
|
||||||
return {
|
|
||||||
...super.defineSchema(),
|
|
||||||
documentUUID: new fields.DocumentUUIDField({ type: 'Actor' })
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
async trigger(event, ...args) {
|
|
||||||
if (!this.canSummon || !canvas.scene) return;
|
|
||||||
// const config = await super.use(event, args);
|
|
||||||
}
|
|
||||||
|
|
||||||
get canSummon() {
|
|
||||||
return game.user.can('TOKEN_CREATE');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class DHEffectAction extends DHBaseAction {
|
|
||||||
static extraSchemas = ['effects', 'target'];
|
|
||||||
|
|
||||||
async use(event, ...args) {
|
|
||||||
const config = await super.use(event, args);
|
|
||||||
if (['error', 'warning'].includes(config.type)) return;
|
|
||||||
return await this.chatApplyEffects(event, config);
|
|
||||||
}
|
|
||||||
|
|
||||||
async chatApplyEffects(event, data) {
|
|
||||||
const cls = getDocumentClass('ChatMessage'),
|
|
||||||
systemData = {
|
|
||||||
title: game.i18n.format('DAGGERHEART.Chat.ApplyEffect.Title', { name: this.name }),
|
|
||||||
origin: this.actor._id,
|
|
||||||
description: '',
|
|
||||||
targets: data.targets.map(x => ({ id: x.id, name: x.name, img: x.img, hit: true })),
|
|
||||||
action: {
|
|
||||||
itemId: this.item._id,
|
|
||||||
actionId: this._id
|
|
||||||
}
|
|
||||||
},
|
|
||||||
msg = new cls({
|
|
||||||
type: 'applyEffect',
|
|
||||||
user: game.user.id,
|
|
||||||
system: systemData,
|
|
||||||
content: await foundry.applications.handlebars.renderTemplate(
|
|
||||||
'systems/daggerheart/templates/chat/apply-effects.hbs',
|
|
||||||
systemData
|
|
||||||
)
|
|
||||||
});
|
|
||||||
|
|
||||||
cls.create(msg.toObject());
|
|
||||||
}
|
|
||||||
|
|
||||||
get chatTemplate() {
|
|
||||||
return 'systems/daggerheart/templates/chat/apply-effects.hbs';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class DHMacroAction extends DHBaseAction {
|
|
||||||
static defineSchema() {
|
|
||||||
return {
|
|
||||||
...super.defineSchema(),
|
|
||||||
documentUUID: new fields.DocumentUUIDField({ type: 'Macro' })
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
async trigger(event, ...args) {
|
|
||||||
// const config = await super.use(event, args);
|
|
||||||
// if (['error', 'warning'].includes(config.type)) return;
|
|
||||||
const fixUUID = !this.documentUUID.includes('Macro.') ? `Macro.${this.documentUUID}` : this.documentUUID,
|
|
||||||
macro = await fromUuid(fixUUID);
|
|
||||||
try {
|
|
||||||
if (!macro) throw new Error(`No macro found for the UUID: ${this.documentUUID}.`);
|
|
||||||
macro.execute();
|
|
||||||
} catch (error) {
|
|
||||||
ui.notifications.error(error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class DhBeastformAction extends DHBaseAction {
|
|
||||||
static extraSchemas = ['beastform'];
|
|
||||||
|
|
||||||
async use(event, ...args) {
|
|
||||||
const beastformConfig = this.prepareBeastformConfig();
|
|
||||||
|
|
||||||
const abort = await this.handleActiveTransformations();
|
|
||||||
if (abort) return;
|
|
||||||
|
|
||||||
const beastformUuid = await BeastformDialog.configure(beastformConfig);
|
|
||||||
if (!beastformUuid) return;
|
|
||||||
|
|
||||||
await this.transform(beastformUuid);
|
|
||||||
}
|
|
||||||
|
|
||||||
prepareBeastformConfig(config) {
|
|
||||||
const settingsTiers = game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.LevelTiers).tiers;
|
|
||||||
const actorLevel = this.actor.system.levelData.level.current;
|
|
||||||
const actorTier =
|
|
||||||
Object.values(settingsTiers).find(
|
|
||||||
tier => actorLevel >= tier.levels.start && actorLevel <= tier.levels.end
|
|
||||||
) ?? 1;
|
|
||||||
|
|
||||||
return {
|
|
||||||
tierLimit: this.beastform.tierAccess.exact ?? actorTier
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
async transform(beastformUuid) {
|
|
||||||
const beastform = await foundry.utils.fromUuid(beastformUuid);
|
|
||||||
this.actor.createEmbeddedDocuments('Item', [beastform.toObject()]);
|
|
||||||
}
|
|
||||||
|
|
||||||
async handleActiveTransformations() {
|
|
||||||
const beastformEffects = this.actor.effects.filter(x => x.type === 'beastform');
|
|
||||||
if (beastformEffects.length > 0) {
|
|
||||||
for (let effect of beastformEffects) {
|
|
||||||
await effect.delete();
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
49
module/data/action/beastformAction.mjs
Normal file
49
module/data/action/beastformAction.mjs
Normal file
|
|
@ -0,0 +1,49 @@
|
||||||
|
import BeastformDialog from '../../applications/dialogs/beastformDialog.mjs';
|
||||||
|
import DHBaseAction from './baseAction.mjs';
|
||||||
|
|
||||||
|
export default class DhBeastformAction extends DHBaseAction {
|
||||||
|
static extraSchemas = ['beastform'];
|
||||||
|
|
||||||
|
async use(event, ...args) {
|
||||||
|
const beastformConfig = this.prepareBeastformConfig();
|
||||||
|
|
||||||
|
const abort = await this.handleActiveTransformations();
|
||||||
|
if (abort) return;
|
||||||
|
|
||||||
|
const beastformUuid = await BeastformDialog.configure(beastformConfig);
|
||||||
|
if (!beastformUuid) return;
|
||||||
|
|
||||||
|
await this.transform(beastformUuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
prepareBeastformConfig(config) {
|
||||||
|
const settingsTiers = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.LevelTiers).tiers;
|
||||||
|
const actorLevel = this.actor.system.levelData.level.current;
|
||||||
|
const actorTier =
|
||||||
|
Object.values(settingsTiers).find(
|
||||||
|
tier => actorLevel >= tier.levels.start && actorLevel <= tier.levels.end
|
||||||
|
) ?? 1;
|
||||||
|
|
||||||
|
return {
|
||||||
|
tierLimit: this.beastform.tierAccess.exact ?? actorTier
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
async transform(beastformUuid) {
|
||||||
|
const beastform = await foundry.utils.fromUuid(beastformUuid);
|
||||||
|
this.actor.createEmbeddedDocuments('Item', [beastform.toObject()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
async handleActiveTransformations() {
|
||||||
|
const beastformEffects = this.actor.effects.filter(x => x.type === 'beastform');
|
||||||
|
if (beastformEffects.length > 0) {
|
||||||
|
for (let effect of beastformEffects) {
|
||||||
|
await effect.delete();
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
38
module/data/action/damageAction.mjs
Normal file
38
module/data/action/damageAction.mjs
Normal file
|
|
@ -0,0 +1,38 @@
|
||||||
|
import DHBaseAction from './baseAction.mjs';
|
||||||
|
|
||||||
|
export default class DHDamageAction extends DHBaseAction {
|
||||||
|
static extraSchemas = ['damage', 'target', 'effects'];
|
||||||
|
|
||||||
|
getFormulaValue(part, data) {
|
||||||
|
let formulaValue = part.value;
|
||||||
|
if (this.hasRoll && part.resultBased && data.system.roll.result.duality === -1) return part.valueAlt;
|
||||||
|
return formulaValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
async rollDamage(event, data) {
|
||||||
|
let formula = this.damage.parts.map(p => this.getFormulaValue(p, data).getFormula(this.actor)).join(' + ');
|
||||||
|
|
||||||
|
if (!formula || formula == '') return;
|
||||||
|
let roll = { formula: formula, total: formula },
|
||||||
|
bonusDamage = [];
|
||||||
|
|
||||||
|
if (isNaN(formula)) formula = Roll.replaceFormulaData(formula, this.getRollData(data.system ?? data));
|
||||||
|
|
||||||
|
const config = {
|
||||||
|
title: game.i18n.format('DAGGERHEART.Chat.DamageRoll.Title', { damage: this.name }),
|
||||||
|
roll: { formula },
|
||||||
|
targets: data.system?.targets.filter(t => t.hit) ?? data.targets,
|
||||||
|
hasSave: this.hasSave,
|
||||||
|
isCritical: data.system?.roll?.isCritical ?? false,
|
||||||
|
source: data.system?.source,
|
||||||
|
event
|
||||||
|
};
|
||||||
|
if (this.hasSave) config.onSave = this.save.damageMod;
|
||||||
|
if (data.system) {
|
||||||
|
config.source.message = data._id;
|
||||||
|
config.directDamage = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
roll = CONFIG.Dice.daggerheart.DamageRoll.build(config);
|
||||||
|
}
|
||||||
|
}
|
||||||
40
module/data/action/effectAction.mjs
Normal file
40
module/data/action/effectAction.mjs
Normal file
|
|
@ -0,0 +1,40 @@
|
||||||
|
import DHBaseAction from './baseAction.mjs';
|
||||||
|
|
||||||
|
export default class DHEffectAction extends DHBaseAction {
|
||||||
|
static extraSchemas = ['effects', 'target'];
|
||||||
|
|
||||||
|
async use(event, ...args) {
|
||||||
|
const config = await super.use(event, args);
|
||||||
|
if (['error', 'warning'].includes(config.type)) return;
|
||||||
|
return await this.chatApplyEffects(event, config);
|
||||||
|
}
|
||||||
|
|
||||||
|
async chatApplyEffects(event, data) {
|
||||||
|
const cls = getDocumentClass('ChatMessage'),
|
||||||
|
systemData = {
|
||||||
|
title: game.i18n.format('DAGGERHEART.Chat.ApplyEffect.Title', { name: this.name }),
|
||||||
|
origin: this.actor._id,
|
||||||
|
description: '',
|
||||||
|
targets: data.targets.map(x => ({ id: x.id, name: x.name, img: x.img, hit: true })),
|
||||||
|
action: {
|
||||||
|
itemId: this.item._id,
|
||||||
|
actionId: this._id
|
||||||
|
}
|
||||||
|
},
|
||||||
|
msg = new cls({
|
||||||
|
type: 'applyEffect',
|
||||||
|
user: game.user.id,
|
||||||
|
system: systemData,
|
||||||
|
content: await foundry.applications.handlebars.renderTemplate(
|
||||||
|
'systems/daggerheart/templates/ui/chat/apply-effects.hbs',
|
||||||
|
systemData
|
||||||
|
)
|
||||||
|
});
|
||||||
|
|
||||||
|
cls.create(msg.toObject());
|
||||||
|
}
|
||||||
|
|
||||||
|
get chatTemplate() {
|
||||||
|
return 'systems/daggerheart/templates/ui/chat/apply-effects.hbs';
|
||||||
|
}
|
||||||
|
}
|
||||||
42
module/data/action/healingAction.mjs
Normal file
42
module/data/action/healingAction.mjs
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
import DHBaseAction from './baseAction.mjs';
|
||||||
|
|
||||||
|
export default class DHHealingAction extends DHBaseAction {
|
||||||
|
static extraSchemas = ['target', 'effects', 'healing', 'roll'];
|
||||||
|
|
||||||
|
static getRollType(parent) {
|
||||||
|
return 'spellcast';
|
||||||
|
}
|
||||||
|
|
||||||
|
getFormulaValue(data) {
|
||||||
|
let formulaValue = this.healing.value;
|
||||||
|
if (this.hasRoll && this.healing.resultBased && data.system.roll.result.duality === -1)
|
||||||
|
return this.healing.valueAlt;
|
||||||
|
return formulaValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
async rollHealing(event, data) {
|
||||||
|
let formulaValue = this.getFormulaValue(data),
|
||||||
|
formula = formulaValue.getFormula(this.actor);
|
||||||
|
|
||||||
|
if (!formula || formula == '') return;
|
||||||
|
let roll = { formula: formula, total: formula },
|
||||||
|
bonusDamage = [];
|
||||||
|
|
||||||
|
const config = {
|
||||||
|
title: game.i18n.format('DAGGERHEART.Chat.HealingRoll.Title', {
|
||||||
|
healing: game.i18n.localize(CONFIG.DH.GENERAL.healingTypes[this.healing.type].label)
|
||||||
|
}),
|
||||||
|
roll: { formula },
|
||||||
|
targets: (data.system?.targets ?? data.targets).filter(t => t.hit),
|
||||||
|
messageType: 'healing',
|
||||||
|
type: this.healing.type,
|
||||||
|
event
|
||||||
|
};
|
||||||
|
|
||||||
|
roll = CONFIG.Dice.daggerheart.DamageRoll.build(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
get chatTemplate() {
|
||||||
|
return 'systems/daggerheart/templates/ui/chat/healing-roll.hbs';
|
||||||
|
}
|
||||||
|
}
|
||||||
24
module/data/action/macroAction.mjs
Normal file
24
module/data/action/macroAction.mjs
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
import DHBaseAction from './baseAction.mjs';
|
||||||
|
|
||||||
|
export default class DHMacroAction extends DHBaseAction {
|
||||||
|
static defineSchema() {
|
||||||
|
const fields = foundry.data.fields;
|
||||||
|
return {
|
||||||
|
...super.defineSchema(),
|
||||||
|
documentUUID: new fields.DocumentUUIDField({ type: 'Macro' })
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
async trigger(event, ...args) {
|
||||||
|
// const config = await super.use(event, args);
|
||||||
|
// if (['error', 'warning'].includes(config.type)) return;
|
||||||
|
const fixUUID = !this.documentUUID.includes('Macro.') ? `Macro.${this.documentUUID}` : this.documentUUID,
|
||||||
|
macro = await fromUuid(fixUUID);
|
||||||
|
try {
|
||||||
|
if (!macro) throw new Error(`No macro found for the UUID: ${this.documentUUID}.`);
|
||||||
|
macro.execute();
|
||||||
|
} catch (error) {
|
||||||
|
ui.notifications.error(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
20
module/data/action/summonAction.mjs
Normal file
20
module/data/action/summonAction.mjs
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
import DHBaseAction from './baseAction.mjs';
|
||||||
|
|
||||||
|
export default class DHSummonAction extends DHBaseAction {
|
||||||
|
static defineSchema() {
|
||||||
|
const fields = foundry.data.fields;
|
||||||
|
return {
|
||||||
|
...super.defineSchema(),
|
||||||
|
documentUUID: new fields.DocumentUUIDField({ type: 'Actor' })
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
async trigger(event, ...args) {
|
||||||
|
if (!this.canSummon || !canvas.scene) return;
|
||||||
|
// const config = await super.use(event, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
get canSummon() {
|
||||||
|
return game.user.can('TOKEN_CREATE');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import beastformEffect from './beastformEffect.mjs';
|
import BeastformEffect from './beastformEffect.mjs';
|
||||||
|
|
||||||
export { beastformEffect };
|
export { BeastformEffect };
|
||||||
|
|
||||||
export const config = {
|
export const config = {
|
||||||
beastform: beastformEffect
|
beastform: BeastformEffect
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -22,13 +22,13 @@ export default class DhpAdversary extends BaseDataActor {
|
||||||
return {
|
return {
|
||||||
tier: new fields.StringField({
|
tier: new fields.StringField({
|
||||||
required: true,
|
required: true,
|
||||||
choices: SYSTEM.GENERAL.tiers,
|
choices: CONFIG.DH.GENERAL.tiers,
|
||||||
initial: SYSTEM.GENERAL.tiers.tier1.id
|
initial: CONFIG.DH.GENERAL.tiers.tier1.id
|
||||||
}),
|
}),
|
||||||
type: new fields.StringField({
|
type: new fields.StringField({
|
||||||
required: true,
|
required: true,
|
||||||
choices: SYSTEM.ACTOR.adversaryTypes,
|
choices: CONFIG.DH.ACTOR.adversaryTypes,
|
||||||
initial: SYSTEM.ACTOR.adversaryTypes.standard.id
|
initial: CONFIG.DH.ACTOR.adversaryTypes.standard.id
|
||||||
}),
|
}),
|
||||||
description: new fields.StringField(),
|
description: new fields.StringField(),
|
||||||
motivesAndTactics: new fields.StringField(),
|
motivesAndTactics: new fields.StringField(),
|
||||||
|
|
@ -47,6 +47,7 @@ export default class DhpAdversary extends BaseDataActor {
|
||||||
attack: new ActionField({
|
attack: new ActionField({
|
||||||
initial: {
|
initial: {
|
||||||
name: 'Attack',
|
name: 'Attack',
|
||||||
|
img: 'icons/skills/melee/blood-slash-foam-red.webp',
|
||||||
_id: foundry.utils.randomID(),
|
_id: foundry.utils.randomID(),
|
||||||
systemPath: 'attack',
|
systemPath: 'attack',
|
||||||
type: 'attack',
|
type: 'attack',
|
||||||
|
|
|
||||||
|
|
@ -144,7 +144,7 @@ export default class DhCharacter extends BaseDataActor {
|
||||||
get tier() {
|
get tier() {
|
||||||
return this.levelData.level.current === 1
|
return this.levelData.level.current === 1
|
||||||
? 1
|
? 1
|
||||||
: Object.values(game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.LevelTiers).tiers).find(
|
: Object.values(game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.LevelTiers).tiers).find(
|
||||||
tier => currentLevel >= tier.levels.start && currentLevel <= tier.levels.end
|
tier => currentLevel >= tier.levels.start && currentLevel <= tier.levels.end
|
||||||
).tier;
|
).tier;
|
||||||
}
|
}
|
||||||
|
|
@ -225,7 +225,7 @@ export default class DhCharacter extends BaseDataActor {
|
||||||
const primary = this.primaryWeapon,
|
const primary = this.primaryWeapon,
|
||||||
secondary = this.secondaryWeapon;
|
secondary = this.secondaryWeapon;
|
||||||
if (itemToEquip.system.secondary) {
|
if (itemToEquip.system.secondary) {
|
||||||
if (primary && primary.burden === SYSTEM.GENERAL.burden.twoHanded.value) {
|
if (primary && primary.burden === CONFIG.DH.GENERAL.burden.twoHanded.value) {
|
||||||
await primary.update({ 'system.equipped': false });
|
await primary.update({ 'system.equipped': false });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -233,7 +233,7 @@ export default class DhCharacter extends BaseDataActor {
|
||||||
await secondary.update({ 'system.equipped': false });
|
await secondary.update({ 'system.equipped': false });
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (secondary && itemToEquip.system.burden === SYSTEM.GENERAL.burden.twoHanded.value) {
|
if (secondary && itemToEquip.system.burden === CONFIG.DH.GENERAL.burden.twoHanded.value) {
|
||||||
await secondary.update({ 'system.equipped': false });
|
await secondary.update({ 'system.equipped': false });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -248,7 +248,7 @@ export default class DhCharacter extends BaseDataActor {
|
||||||
const currentTier =
|
const currentTier =
|
||||||
currentLevel === 1
|
currentLevel === 1
|
||||||
? null
|
? null
|
||||||
: Object.values(game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.LevelTiers).tiers).find(
|
: Object.values(game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.LevelTiers).tiers).find(
|
||||||
tier => currentLevel >= tier.levels.start && currentLevel <= tier.levels.end
|
tier => currentLevel >= tier.levels.start && currentLevel <= tier.levels.end
|
||||||
).tier;
|
).tier;
|
||||||
for (let levelKey in this.levelData.levelups) {
|
for (let levelKey in this.levelData.levelups) {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,4 @@
|
||||||
import { environmentTypes } from '../../config/actorConfig.mjs';
|
|
||||||
import BaseDataActor from './base.mjs';
|
import BaseDataActor from './base.mjs';
|
||||||
import ForeignDocumentUUIDField from '../fields/foreignDocumentUUIDField.mjs';
|
|
||||||
import ActionField from '../fields/actionField.mjs';
|
import ActionField from '../fields/actionField.mjs';
|
||||||
import ForeignDocumentUUIDArrayField from '../fields/foreignDocumentUUIDArrayField.mjs';
|
import ForeignDocumentUUIDArrayField from '../fields/foreignDocumentUUIDArrayField.mjs';
|
||||||
|
|
||||||
|
|
@ -19,10 +17,10 @@ export default class DhEnvironment extends BaseDataActor {
|
||||||
return {
|
return {
|
||||||
tier: new fields.StringField({
|
tier: new fields.StringField({
|
||||||
required: true,
|
required: true,
|
||||||
choices: SYSTEM.GENERAL.tiers,
|
choices: CONFIG.DH.GENERAL.tiers,
|
||||||
initial: SYSTEM.GENERAL.tiers.tier1.id
|
initial: CONFIG.DH.GENERAL.tiers.tier1.id
|
||||||
}),
|
}),
|
||||||
type: new fields.StringField({ choices: environmentTypes }),
|
type: new fields.StringField({ choices: CONFIG.DH.ACTOR.environmentTypes }),
|
||||||
description: new fields.StringField(),
|
description: new fields.StringField(),
|
||||||
impulses: new fields.StringField(),
|
impulses: new fields.StringField(),
|
||||||
difficulty: new fields.NumberField({ required: true, initial: 11, integer: true }),
|
difficulty: new fields.NumberField({ required: true, initial: 11, integer: true }),
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { DHBaseAction } from '../action/action.mjs';
|
import DHBaseAction from '../../data/action/baseAction.mjs';
|
||||||
|
|
||||||
const fields = foundry.data.fields;
|
const fields = foundry.data.fields;
|
||||||
|
|
||||||
|
|
@ -37,7 +37,7 @@ export default class DHAdversaryRoll extends foundry.abstract.TypeDataModel {
|
||||||
}
|
}
|
||||||
|
|
||||||
get messageTemplate() {
|
get messageTemplate() {
|
||||||
return 'systems/daggerheart/templates/chat/adversary-roll.hbs';
|
return 'systems/daggerheart/templates/ui/chat/adversary-roll.hbs';
|
||||||
}
|
}
|
||||||
|
|
||||||
prepareDerivedData() {
|
prepareDerivedData() {
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ export default class DHDamageRoll extends foundry.abstract.TypeDataModel {
|
||||||
}
|
}
|
||||||
|
|
||||||
get messageTemplate() {
|
get messageTemplate() {
|
||||||
return `systems/daggerheart/templates/chat/${this.messageType}-roll.hbs`;
|
return `systems/daggerheart/templates/ui/chat/${this.messageType}-roll.hbs`;
|
||||||
}
|
}
|
||||||
|
|
||||||
prepareDerivedData() {
|
prepareDerivedData() {
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,6 @@ import DHAdversaryRoll from './adversaryRoll.mjs';
|
||||||
|
|
||||||
export default class DHDualityRoll extends DHAdversaryRoll {
|
export default class DHDualityRoll extends DHAdversaryRoll {
|
||||||
get messageTemplate() {
|
get messageTemplate() {
|
||||||
return 'systems/daggerheart/templates/chat/duality-roll.hbs';
|
return 'systems/daggerheart/templates/ui/chat/duality-roll.hbs';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
import { countdownTypes } from '../config/generalConfig.mjs';
|
import { RefreshType, socketEvent } from '../systemRegistration/socket.mjs';
|
||||||
import { RefreshType, socketEvent } from '../helpers/socket.mjs';
|
|
||||||
|
|
||||||
export default class DhCountdowns extends foundry.abstract.DataModel {
|
export default class DhCountdowns extends foundry.abstract.DataModel {
|
||||||
static defineSchema() {
|
static defineSchema() {
|
||||||
|
|
@ -102,8 +101,8 @@ class DhCountdown extends foundry.abstract.DataModel {
|
||||||
type: new fields.SchemaField({
|
type: new fields.SchemaField({
|
||||||
value: new fields.StringField({
|
value: new fields.StringField({
|
||||||
required: true,
|
required: true,
|
||||||
choices: countdownTypes,
|
choices: CONFIG.DH.GENERAL.countdownTypes,
|
||||||
initial: countdownTypes.spotlight.id,
|
initial: CONFIG.DH.GENERAL.countdownTypes.spotlight.id,
|
||||||
label: 'DAGGERHEART.Countdown.FIELDS.countdowns.element.progress.type.value.label'
|
label: 'DAGGERHEART.Countdown.FIELDS.countdowns.element.progress.type.value.label'
|
||||||
}),
|
}),
|
||||||
label: new fields.StringField({
|
label: new fields.StringField({
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
// import { actionsTypes } from '../action/_module.mjs';
|
import { actionsTypes } from '../action/_module.mjs';
|
||||||
|
|
||||||
// Temporary Solution
|
// Temporary Solution
|
||||||
export default class ActionField extends foundry.data.fields.ObjectField {
|
export default class ActionField extends foundry.data.fields.ObjectField {
|
||||||
getModel(value) {
|
getModel(value) {
|
||||||
return game.system.api.models.actionsTypes[value.type] ?? game.system.api.models.actionsTypes.attack;
|
return actionsTypes[value.type] ?? actionsTypes.attack;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,11 @@ export default class DHArmor extends BaseDataItem {
|
||||||
baseScore: new fields.NumberField({ integer: true, initial: 0 }),
|
baseScore: new fields.NumberField({ integer: true, initial: 0 }),
|
||||||
features: new fields.ArrayField(
|
features: new fields.ArrayField(
|
||||||
new fields.SchemaField({
|
new fields.SchemaField({
|
||||||
value: new fields.StringField({ required: true, choices: SYSTEM.ITEM.armorFeatures, blank: true }),
|
value: new fields.StringField({
|
||||||
|
required: true,
|
||||||
|
choices: CONFIG.DH.ITEM.armorFeatures,
|
||||||
|
blank: true
|
||||||
|
}),
|
||||||
effectIds: new fields.ArrayField(new fields.StringField({ required: true })),
|
effectIds: new fields.ArrayField(new fields.StringField({ required: true })),
|
||||||
actionIds: new fields.ArrayField(new fields.StringField({ required: true }))
|
actionIds: new fields.ArrayField(new fields.StringField({ required: true }))
|
||||||
})
|
})
|
||||||
|
|
@ -41,7 +45,7 @@ export default class DHArmor extends BaseDataItem {
|
||||||
}
|
}
|
||||||
|
|
||||||
get featureInfo() {
|
get featureInfo() {
|
||||||
return this.feature ? CONFIG.daggerheart.ITEM.armorFeatures[this.feature] : null;
|
return this.feature ? CONFIG.DH.ITEM.armorFeatures[this.feature] : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
async _preUpdate(changes, options, user) {
|
async _preUpdate(changes, options, user) {
|
||||||
|
|
|
||||||
|
|
@ -66,7 +66,7 @@ export default class BaseDataItem extends foundry.abstract.TypeDataModel {
|
||||||
{
|
{
|
||||||
_id: foundry.utils.randomID(),
|
_id: foundry.utils.randomID(),
|
||||||
type: actionType,
|
type: actionType,
|
||||||
name: game.i18n.localize(SYSTEM.ACTIONS.actionTypes[actionType].name),
|
name: game.i18n.localize(CONFIG.DH.ACTIONS.actionTypes[actionType].name),
|
||||||
...cls.getSourceConfig(this.parent)
|
...cls.getSourceConfig(this.parent)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -21,8 +21,8 @@ export default class DHBeastform extends BaseDataItem {
|
||||||
...super.defineSchema(),
|
...super.defineSchema(),
|
||||||
tier: new fields.StringField({
|
tier: new fields.StringField({
|
||||||
required: true,
|
required: true,
|
||||||
choices: SYSTEM.GENERAL.tiers,
|
choices: CONFIG.DH.GENERAL.tiers,
|
||||||
initial: SYSTEM.GENERAL.tiers.tier1.id
|
initial: CONFIG.DH.GENERAL.tiers.tier1.id
|
||||||
}),
|
}),
|
||||||
tokenImg: new fields.FilePathField({
|
tokenImg: new fields.FilePathField({
|
||||||
initial: 'icons/svg/mystery-man.svg',
|
initial: 'icons/svg/mystery-man.svg',
|
||||||
|
|
|
||||||
|
|
@ -17,16 +17,16 @@ export default class DHDomainCard extends BaseDataItem {
|
||||||
return {
|
return {
|
||||||
...super.defineSchema(),
|
...super.defineSchema(),
|
||||||
domain: new fields.StringField({
|
domain: new fields.StringField({
|
||||||
choices: SYSTEM.DOMAIN.domains,
|
choices: CONFIG.DH.DOMAIN.domains,
|
||||||
required: true,
|
required: true,
|
||||||
initial: SYSTEM.DOMAIN.domains.arcana.id
|
initial: CONFIG.DH.DOMAIN.domains.arcana.id
|
||||||
}),
|
}),
|
||||||
level: new fields.NumberField({ initial: 1, integer: true }),
|
level: new fields.NumberField({ initial: 1, integer: true }),
|
||||||
recallCost: new fields.NumberField({ initial: 0, integer: true }),
|
recallCost: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
type: new fields.StringField({
|
type: new fields.StringField({
|
||||||
choices: SYSTEM.DOMAIN.cardTypes,
|
choices: CONFIG.DH.DOMAIN.cardTypes,
|
||||||
required: true,
|
required: true,
|
||||||
initial: SYSTEM.DOMAIN.cardTypes.ability.id
|
initial: CONFIG.DH.DOMAIN.cardTypes.ability.id
|
||||||
}),
|
}),
|
||||||
foundation: new fields.BooleanField({ initial: false }),
|
foundation: new fields.BooleanField({ initial: false }),
|
||||||
inVault: new fields.BooleanField({ initial: false }),
|
inVault: new fields.BooleanField({ initial: false }),
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ export default class DHSubclass extends BaseDataItem {
|
||||||
return {
|
return {
|
||||||
...super.defineSchema(),
|
...super.defineSchema(),
|
||||||
spellcastingTrait: new fields.StringField({
|
spellcastingTrait: new fields.StringField({
|
||||||
choices: SYSTEM.ACTOR.abilities,
|
choices: CONFIG.DH.ACTOR.abilities,
|
||||||
integer: false,
|
integer: false,
|
||||||
nullable: true,
|
nullable: true,
|
||||||
initial: null
|
initial: null
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,5 @@
|
||||||
import BaseDataItem from './base.mjs';
|
import BaseDataItem from './base.mjs';
|
||||||
import FormulaField from '../fields/formulaField.mjs';
|
|
||||||
import ActionField from '../fields/actionField.mjs';
|
import ActionField from '../fields/actionField.mjs';
|
||||||
import { weaponFeatures } from '../../config/itemConfig.mjs';
|
|
||||||
import { actionsTypes } from '../action/_module.mjs';
|
|
||||||
|
|
||||||
export default class DHWeapon extends BaseDataItem {
|
export default class DHWeapon extends BaseDataItem {
|
||||||
/** @inheritDoc */
|
/** @inheritDoc */
|
||||||
|
|
@ -27,22 +24,26 @@ export default class DHWeapon extends BaseDataItem {
|
||||||
|
|
||||||
//SETTINGS
|
//SETTINGS
|
||||||
secondary: new fields.BooleanField({ initial: false }),
|
secondary: new fields.BooleanField({ initial: false }),
|
||||||
trait: new fields.StringField({ required: true, choices: SYSTEM.ACTOR.abilities, initial: 'agility' }),
|
trait: new fields.StringField({ required: true, choices: CONFIG.DH.ACTOR.abilities, initial: 'agility' }),
|
||||||
range: new fields.StringField({ required: true, choices: SYSTEM.GENERAL.range, initial: 'melee' }),
|
range: new fields.StringField({ required: true, choices: CONFIG.DH.GENERAL.range, initial: 'melee' }),
|
||||||
burden: new fields.StringField({ required: true, choices: SYSTEM.GENERAL.burden, initial: 'oneHanded' }),
|
burden: new fields.StringField({ required: true, choices: CONFIG.DH.GENERAL.burden, initial: 'oneHanded' }),
|
||||||
//DAMAGE
|
//DAMAGE
|
||||||
damage: new fields.SchemaField({
|
damage: new fields.SchemaField({
|
||||||
dice: new fields.StringField({ choices: SYSTEM.GENERAL.diceTypes, initial: 'd6' }),
|
dice: new fields.StringField({ choices: CONFIG.DH.GENERAL.diceTypes, initial: 'd6' }),
|
||||||
bonus: new fields.NumberField({ nullable: true, initial: null }),
|
bonus: new fields.NumberField({ nullable: true, initial: null }),
|
||||||
type: new fields.StringField({
|
type: new fields.StringField({
|
||||||
required: true,
|
required: true,
|
||||||
choices: SYSTEM.GENERAL.damageTypes,
|
choices: CONFIG.DH.GENERAL.damageTypes,
|
||||||
initial: 'physical'
|
initial: 'physical'
|
||||||
})
|
})
|
||||||
}),
|
}),
|
||||||
features: new fields.ArrayField(
|
features: new fields.ArrayField(
|
||||||
new fields.SchemaField({
|
new fields.SchemaField({
|
||||||
value: new fields.StringField({ required: true, choices: SYSTEM.ITEM.weaponFeatures, blank: true }),
|
value: new fields.StringField({
|
||||||
|
required: true,
|
||||||
|
choices: CONFIG.DH.ITEM.weaponFeatures,
|
||||||
|
blank: true
|
||||||
|
}),
|
||||||
effectIds: new fields.ArrayField(new fields.StringField({ required: true })),
|
effectIds: new fields.ArrayField(new fields.StringField({ required: true })),
|
||||||
actionIds: new fields.ArrayField(new fields.StringField({ required: true }))
|
actionIds: new fields.ArrayField(new fields.StringField({ required: true }))
|
||||||
})
|
})
|
||||||
|
|
@ -68,7 +69,7 @@ export default class DHWeapon extends BaseDataItem {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var feature of added) {
|
for (var feature of added) {
|
||||||
const featureData = weaponFeatures[feature.value];
|
const featureData = CONFIG.DH.ITEM.weaponFeatures[feature.value];
|
||||||
if (featureData.effects?.length > 0) {
|
if (featureData.effects?.length > 0) {
|
||||||
const embeddedItems = await this.parent.createEmbeddedDocuments('ActiveEffect', [
|
const embeddedItems = await this.parent.createEmbeddedDocuments('ActiveEffect', [
|
||||||
{
|
{
|
||||||
|
|
@ -81,7 +82,7 @@ export default class DHWeapon extends BaseDataItem {
|
||||||
}
|
}
|
||||||
if (featureData.actions?.length > 0) {
|
if (featureData.actions?.length > 0) {
|
||||||
const newActions = featureData.actions.map(action => {
|
const newActions = featureData.actions.map(action => {
|
||||||
const cls = actionsTypes[action.type];
|
const cls = CONFIG.DH.ACTIONS.actionsTypes[action.type];
|
||||||
return new cls(
|
return new cls(
|
||||||
{ ...action, _id: foundry.utils.randomID(), name: game.i18n.localize(action.name) },
|
{ ...action, _id: foundry.utils.randomID(), name: game.i18n.localize(action.name) },
|
||||||
{ parent: this }
|
{ parent: this }
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,5 @@
|
||||||
import DhAppearance from './Appearance.mjs';
|
export { default as DhAppearance } from './Appearance.mjs';
|
||||||
import DhAutomation from './Automation.mjs';
|
export { default as DhAutomation } from './Automation.mjs';
|
||||||
import DhHomebrew from './Homebrew.mjs';
|
export { default as DhHomebrew } from './Homebrew.mjs';
|
||||||
import DhRangeMeasurement from './RangeMeasurement.mjs';
|
export { default as DhRangeMeasurement } from './RangeMeasurement.mjs';
|
||||||
import DhVariantRules from './VariantRules.mjs';
|
export { default as DhVariantRules } from './VariantRules.mjs';
|
||||||
|
|
||||||
export { DhAppearance, DhAutomation, DhHomebrew, DhRangeMeasurement, DhVariantRules };
|
|
||||||
|
|
|
||||||
5
module/dice/_module.mjs
Normal file
5
module/dice/_module.mjs
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
export { default as D20Roll } from './d20Roll.mjs';
|
||||||
|
export { default as DamageRoll } from './damageRoll.mjs';
|
||||||
|
export { default as DHRoll } from './dhRoll.mjs';
|
||||||
|
export { default as DualityDie } from './dualityDie.mjs';
|
||||||
|
export { default as DualityRoll } from './dualityRoll.mjs';
|
||||||
179
module/dice/d20Roll.mjs
Normal file
179
module/dice/d20Roll.mjs
Normal file
|
|
@ -0,0 +1,179 @@
|
||||||
|
import D20RollDialog from '../applications/dialogs/d20RollDialog.mjs';
|
||||||
|
import { setDiceSoNiceForDualityRoll } from '../helpers/utils.mjs';
|
||||||
|
import DHRoll from './dhRoll.mjs';
|
||||||
|
|
||||||
|
export default class D20Roll extends DHRoll {
|
||||||
|
constructor(formula, data = {}, options = {}) {
|
||||||
|
super(formula, data, options);
|
||||||
|
this.constructFormula();
|
||||||
|
}
|
||||||
|
|
||||||
|
static ADV_MODE = {
|
||||||
|
NORMAL: 0,
|
||||||
|
ADVANTAGE: 1,
|
||||||
|
DISADVANTAGE: -1
|
||||||
|
};
|
||||||
|
|
||||||
|
static messageType = 'adversaryRoll';
|
||||||
|
|
||||||
|
static CRITICAL_TRESHOLD = 20;
|
||||||
|
|
||||||
|
static DefaultDialog = D20RollDialog;
|
||||||
|
|
||||||
|
get d20() {
|
||||||
|
if (!(this.terms[0] instanceof foundry.dice.terms.Die)) this.createBaseDice();
|
||||||
|
return this.terms[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
set d20(faces) {
|
||||||
|
if (!(this.terms[0] instanceof foundry.dice.terms.Die)) this.createBaseDice();
|
||||||
|
this.terms[0].faces = this.getFaces(faces);
|
||||||
|
}
|
||||||
|
|
||||||
|
get dAdvantage() {
|
||||||
|
return this.dice[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
get isCritical() {
|
||||||
|
if (!this.d20._evaluated) return;
|
||||||
|
return this.d20.total >= this.constructor.CRITICAL_TRESHOLD;
|
||||||
|
}
|
||||||
|
|
||||||
|
get hasAdvantage() {
|
||||||
|
return this.options.roll.advantage === this.constructor.ADV_MODE.ADVANTAGE;
|
||||||
|
}
|
||||||
|
|
||||||
|
get hasDisadvantage() {
|
||||||
|
return this.options.roll.advantage === this.constructor.ADV_MODE.DISADVANTAGE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static applyKeybindings(config) {
|
||||||
|
let keys = {
|
||||||
|
normal: true,
|
||||||
|
advantage: false,
|
||||||
|
disadvantage: false
|
||||||
|
};
|
||||||
|
|
||||||
|
if (config.event) {
|
||||||
|
keys = {
|
||||||
|
normal: config.event.shiftKey || config.event.altKey || config.event.ctrlKey,
|
||||||
|
advantage: config.event.altKey,
|
||||||
|
disadvantage: config.event.ctrlKey
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Should the roll configuration dialog be displayed?
|
||||||
|
config.dialog.configure ??= !Object.values(keys).some(k => k);
|
||||||
|
|
||||||
|
// Determine advantage mode
|
||||||
|
const advantage = config.roll.advantage === this.ADV_MODE.ADVANTAGE || keys.advantage || config.advantage;
|
||||||
|
const disadvantage =
|
||||||
|
config.roll.advantage === this.ADV_MODE.DISADVANTAGE || keys.disadvantage || config.disadvantage;
|
||||||
|
if (advantage && !disadvantage) config.roll.advantage = this.ADV_MODE.ADVANTAGE;
|
||||||
|
else if (!advantage && disadvantage) config.roll.advantage = this.ADV_MODE.DISADVANTAGE;
|
||||||
|
else config.roll.advantage = this.ADV_MODE.NORMAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
constructFormula(config) {
|
||||||
|
// this.terms = [];
|
||||||
|
this.createBaseDice();
|
||||||
|
this.configureModifiers();
|
||||||
|
this.resetFormula();
|
||||||
|
return this._formula;
|
||||||
|
}
|
||||||
|
|
||||||
|
createBaseDice() {
|
||||||
|
if (this.terms[0] instanceof foundry.dice.terms.Die) {
|
||||||
|
this.terms = [this.terms[0]];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.terms[0] = new foundry.dice.terms.Die({ faces: 20 });
|
||||||
|
}
|
||||||
|
|
||||||
|
configureModifiers() {
|
||||||
|
this.applyAdvantage();
|
||||||
|
this.applyBaseBonus();
|
||||||
|
|
||||||
|
this.options.experiences?.forEach(m => {
|
||||||
|
if (this.options.data.experiences?.[m])
|
||||||
|
this.options.roll.modifiers.push({
|
||||||
|
label: this.options.data.experiences[m].name,
|
||||||
|
value: this.options.data.experiences[m].total ?? this.options.data.experiences[m].value
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
this.options.roll.modifiers?.forEach(m => {
|
||||||
|
this.terms.push(...this.formatModifier(m.value));
|
||||||
|
});
|
||||||
|
|
||||||
|
this.baseTerms = foundry.utils.deepClone(this.terms);
|
||||||
|
|
||||||
|
if (this.options.extraFormula) {
|
||||||
|
this.terms.push(
|
||||||
|
new foundry.dice.terms.OperatorTerm({ operator: '+' }),
|
||||||
|
...this.constructor.parse(this.options.extraFormula, this.options.data)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
applyAdvantage() {
|
||||||
|
this.d20.modifiers.findSplice(m => ['kh', 'kl'].includes(m));
|
||||||
|
if (!this.hasAdvantage && !this.hasDisadvantage) this.number = 1;
|
||||||
|
else {
|
||||||
|
this.d20.number = 2;
|
||||||
|
this.d20.modifiers.push(this.hasAdvantage ? 'kh' : 'kl');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
applyBaseBonus() {
|
||||||
|
this.options.roll.modifiers = [];
|
||||||
|
if (!this.options.roll.bonus) return;
|
||||||
|
this.options.roll.modifiers.push({
|
||||||
|
label: 'Bonus to Hit',
|
||||||
|
value: this.options.roll.bonus
|
||||||
|
// value: Roll.replaceFormulaData('@attackBonus', this.data)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
static async buildEvaluate(roll, config = {}, message = {}) {
|
||||||
|
if (config.evaluate !== false) await roll.evaluate();
|
||||||
|
const advantageState =
|
||||||
|
config.roll.advantage == this.ADV_MODE.ADVANTAGE
|
||||||
|
? true
|
||||||
|
: config.roll.advantage == this.ADV_MODE.DISADVANTAGE
|
||||||
|
? false
|
||||||
|
: null;
|
||||||
|
setDiceSoNiceForDualityRoll(roll, advantageState);
|
||||||
|
this.postEvaluate(roll, config);
|
||||||
|
}
|
||||||
|
|
||||||
|
static postEvaluate(roll, config = {}) {
|
||||||
|
super.postEvaluate(roll, config);
|
||||||
|
if (config.targets?.length) {
|
||||||
|
config.targets.forEach(target => {
|
||||||
|
const difficulty = config.roll.difficulty ?? target.difficulty ?? target.evasion;
|
||||||
|
target.hit = this.isCritical || roll.total >= difficulty;
|
||||||
|
});
|
||||||
|
} else if (config.roll.difficulty)
|
||||||
|
config.roll.success = roll.isCritical || roll.total >= config.roll.difficulty;
|
||||||
|
config.roll.advantage = {
|
||||||
|
type: config.roll.advantage,
|
||||||
|
dice: roll.dAdvantage?.denomination,
|
||||||
|
value: roll.dAdvantage?.total
|
||||||
|
};
|
||||||
|
config.roll.isCritical = roll.isCritical;
|
||||||
|
config.roll.extra = roll.dice
|
||||||
|
.filter(d => !roll.baseTerms.includes(d))
|
||||||
|
.map(d => {
|
||||||
|
return {
|
||||||
|
dice: d.denomination,
|
||||||
|
value: d.total
|
||||||
|
};
|
||||||
|
});
|
||||||
|
config.roll.modifierTotal = this.calculateTotalModifiers(roll);
|
||||||
|
}
|
||||||
|
|
||||||
|
resetFormula() {
|
||||||
|
return (this._formula = this.constructor.getFormula(this.terms));
|
||||||
|
}
|
||||||
|
}
|
||||||
32
module/dice/damageRoll.mjs
Normal file
32
module/dice/damageRoll.mjs
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
import DamageDialog from '../applications/dialogs/damageDialog.mjs';
|
||||||
|
import DHRoll from './dhRoll.mjs';
|
||||||
|
|
||||||
|
export default class DamageRoll extends DHRoll {
|
||||||
|
constructor(formula, data = {}, options = {}) {
|
||||||
|
super(formula, data, options);
|
||||||
|
}
|
||||||
|
|
||||||
|
static messageType = 'damageRoll';
|
||||||
|
|
||||||
|
static DefaultDialog = DamageDialog;
|
||||||
|
|
||||||
|
static async postEvaluate(roll, config = {}) {
|
||||||
|
super.postEvaluate(roll, config);
|
||||||
|
config.roll.type = config.type;
|
||||||
|
config.roll.modifierTotal = this.calculateTotalModifiers(roll);
|
||||||
|
if (config.source?.message) {
|
||||||
|
const chatMessage = ui.chat.collection.get(config.source.message);
|
||||||
|
chatMessage.update({ 'system.damage': config });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
constructFormula(config) {
|
||||||
|
super.constructFormula(config);
|
||||||
|
if (config.isCritical) {
|
||||||
|
const tmpRoll = new Roll(this._formula)._evaluateSync({ maximize: true }),
|
||||||
|
criticalBonus = tmpRoll.total - this.constructor.calculateTotalModifiers(tmpRoll);
|
||||||
|
this.terms.push(...this.formatModifier(criticalBonus));
|
||||||
|
}
|
||||||
|
return (this._formula = this.constructor.getFormula(this.terms));
|
||||||
|
}
|
||||||
|
}
|
||||||
133
module/dice/dhRoll.mjs
Normal file
133
module/dice/dhRoll.mjs
Normal file
|
|
@ -0,0 +1,133 @@
|
||||||
|
import D20RollDialog from '../applications/dialogs/d20RollDialog.mjs';
|
||||||
|
|
||||||
|
export default class DHRoll extends Roll {
|
||||||
|
baseTerms = [];
|
||||||
|
constructor(formula, data, options) {
|
||||||
|
super(formula, data, options);
|
||||||
|
}
|
||||||
|
|
||||||
|
static messageType = 'adversaryRoll';
|
||||||
|
|
||||||
|
static DefaultDialog = D20RollDialog;
|
||||||
|
|
||||||
|
static async build(config = {}, message = {}) {
|
||||||
|
const roll = await this.buildConfigure(config, message);
|
||||||
|
if (!roll) return;
|
||||||
|
await this.buildEvaluate(roll, config, (message = {}));
|
||||||
|
await this.buildPost(roll, config, (message = {}));
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
|
||||||
|
static async buildConfigure(config = {}, message = {}) {
|
||||||
|
config.hooks = [...(config.hooks ?? []), ''];
|
||||||
|
config.dialog ??= {};
|
||||||
|
for (const hook of config.hooks) {
|
||||||
|
if (Hooks.call(`${CONFIG.DH.id}.preRoll${hook.capitalize()}`, config, message) === false) return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.applyKeybindings(config);
|
||||||
|
|
||||||
|
let roll = new this(config.roll.formula, config.data, config);
|
||||||
|
if (config.dialog.configure !== false) {
|
||||||
|
// Open Roll Dialog
|
||||||
|
const DialogClass = config.dialog?.class ?? this.DefaultDialog;
|
||||||
|
const configDialog = await DialogClass.configure(roll, config, message);
|
||||||
|
if (!configDialog) return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const hook of config.hooks) {
|
||||||
|
if (
|
||||||
|
Hooks.call(`${CONFIG.DH.id}.post${hook.capitalize()}RollConfiguration`, roll, config, message) === false
|
||||||
|
)
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
return roll;
|
||||||
|
}
|
||||||
|
|
||||||
|
static async buildEvaluate(roll, config = {}, message = {}) {
|
||||||
|
if (config.evaluate !== false) await roll.evaluate();
|
||||||
|
this.postEvaluate(roll, config);
|
||||||
|
}
|
||||||
|
|
||||||
|
static async buildPost(roll, config, message) {
|
||||||
|
for (const hook of config.hooks) {
|
||||||
|
if (Hooks.call(`${CONFIG.DH.id}.postRoll${hook.capitalize()}`, config, message) === false) return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create Chat Message
|
||||||
|
if (config.source?.message) {
|
||||||
|
} else {
|
||||||
|
const messageData = {};
|
||||||
|
config.message = await this.toMessage(roll, config);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static postEvaluate(roll, config = {}) {
|
||||||
|
if (!config.roll) config.roll = {};
|
||||||
|
config.roll.total = roll.total;
|
||||||
|
config.roll.formula = roll.formula;
|
||||||
|
config.roll.dice = [];
|
||||||
|
roll.dice.forEach(d => {
|
||||||
|
config.roll.dice.push({
|
||||||
|
dice: d.denomination,
|
||||||
|
total: d.total,
|
||||||
|
formula: d.formula,
|
||||||
|
results: d.results
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
static async toMessage(roll, config) {
|
||||||
|
const cls = getDocumentClass('ChatMessage'),
|
||||||
|
msg = {
|
||||||
|
type: this.messageType,
|
||||||
|
user: game.user.id,
|
||||||
|
sound: config.mute ? null : CONFIG.sounds.dice,
|
||||||
|
system: config,
|
||||||
|
rolls: [roll]
|
||||||
|
};
|
||||||
|
return await cls.create(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
static applyKeybindings(config) {
|
||||||
|
if (config.event)
|
||||||
|
config.dialog.configure ??= !(config.event.shiftKey || config.event.altKey || config.event.ctrlKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
formatModifier(modifier) {
|
||||||
|
const numTerm = modifier < 0 ? '-' : '+';
|
||||||
|
return [
|
||||||
|
new foundry.dice.terms.OperatorTerm({ operator: numTerm }),
|
||||||
|
new foundry.dice.terms.NumericTerm({ number: Math.abs(modifier) })
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
getFaces(faces) {
|
||||||
|
return Number(faces.startsWith('d') ? faces.replace('d', '') : faces);
|
||||||
|
}
|
||||||
|
|
||||||
|
constructFormula(config) {
|
||||||
|
this.terms = Roll.parse(this.options.roll.formula, config.data);
|
||||||
|
|
||||||
|
if (this.options.extraFormula) {
|
||||||
|
this.terms.push(
|
||||||
|
new foundry.dice.terms.OperatorTerm({ operator: '+' }),
|
||||||
|
...this.constructor.parse(this.options.extraFormula, this.options.data)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return (this._formula = this.constructor.getFormula(this.terms));
|
||||||
|
}
|
||||||
|
|
||||||
|
static calculateTotalModifiers(roll) {
|
||||||
|
let modifierTotal = 0;
|
||||||
|
for (let i = 0; i < roll.terms.length; i++) {
|
||||||
|
if (
|
||||||
|
roll.terms[i] instanceof foundry.dice.terms.NumericTerm &&
|
||||||
|
!!roll.terms[i - 1] &&
|
||||||
|
roll.terms[i - 1] instanceof foundry.dice.terms.OperatorTerm
|
||||||
|
)
|
||||||
|
modifierTotal += Number(`${roll.terms[i - 1].operator}${roll.terms[i].total}`);
|
||||||
|
}
|
||||||
|
return modifierTotal;
|
||||||
|
}
|
||||||
|
}
|
||||||
5
module/dice/dualityDie.mjs
Normal file
5
module/dice/dualityDie.mjs
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
export default class DualityDie extends foundry.dice.terms.Die {
|
||||||
|
constructor({ number = 1, faces = 12, ...args } = {}) {
|
||||||
|
super({ number, faces, ...args });
|
||||||
|
}
|
||||||
|
}
|
||||||
143
module/dice/dualityRoll.mjs
Normal file
143
module/dice/dualityRoll.mjs
Normal file
|
|
@ -0,0 +1,143 @@
|
||||||
|
import D20RollDialog from '../applications/dialogs/d20RollDialog.mjs';
|
||||||
|
import D20Roll from './d20Roll.mjs';
|
||||||
|
|
||||||
|
export default class DualityRoll extends D20Roll {
|
||||||
|
_advantageFaces = 6;
|
||||||
|
|
||||||
|
constructor(formula, data = {}, options = {}) {
|
||||||
|
super(formula, data, options);
|
||||||
|
}
|
||||||
|
|
||||||
|
static messageType = 'dualityRoll';
|
||||||
|
|
||||||
|
static DefaultDialog = D20RollDialog;
|
||||||
|
|
||||||
|
get dHope() {
|
||||||
|
// if ( !(this.terms[0] instanceof foundry.dice.terms.Die) ) return;
|
||||||
|
if (!(this.dice[0] instanceof CONFIG.Dice.daggerheart.DualityDie)) this.createBaseDice();
|
||||||
|
return this.dice[0];
|
||||||
|
// return this.#hopeDice;
|
||||||
|
}
|
||||||
|
|
||||||
|
set dHope(faces) {
|
||||||
|
if (!(this.dice[0] instanceof CONFIG.Dice.daggerheart.DualityDie)) this.createBaseDice();
|
||||||
|
this.terms[0].faces = this.getFaces(faces);
|
||||||
|
// this.#hopeDice = `d${face}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
get dFear() {
|
||||||
|
// if ( !(this.terms[1] instanceof foundry.dice.terms.Die) ) return;
|
||||||
|
if (!(this.dice[1] instanceof CONFIG.Dice.daggerheart.DualityDie)) this.createBaseDice();
|
||||||
|
return this.dice[1];
|
||||||
|
// return this.#fearDice;
|
||||||
|
}
|
||||||
|
|
||||||
|
set dFear(faces) {
|
||||||
|
if (!(this.dice[1] instanceof CONFIG.Dice.daggerheart.DualityDie)) this.createBaseDice();
|
||||||
|
this.dice[1].faces = this.getFaces(faces);
|
||||||
|
// this.#fearDice = `d${face}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
get dAdvantage() {
|
||||||
|
return this.dice[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
get advantageFaces() {
|
||||||
|
return this._advantageFaces;
|
||||||
|
}
|
||||||
|
|
||||||
|
set advantageFaces(faces) {
|
||||||
|
this._advantageFaces = this.getFaces(faces);
|
||||||
|
}
|
||||||
|
|
||||||
|
get isCritical() {
|
||||||
|
if (!this.dHope._evaluated || !this.dFear._evaluated) return;
|
||||||
|
return this.dHope.total === this.dFear.total;
|
||||||
|
}
|
||||||
|
|
||||||
|
get withHope() {
|
||||||
|
if (!this._evaluated) return;
|
||||||
|
return this.dHope.total > this.dFear.total;
|
||||||
|
}
|
||||||
|
|
||||||
|
get withFear() {
|
||||||
|
if (!this._evaluated) return;
|
||||||
|
return this.dHope.total < this.dFear.total;
|
||||||
|
}
|
||||||
|
|
||||||
|
get hasBarRally() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
get totalLabel() {
|
||||||
|
const label = this.withHope
|
||||||
|
? 'DAGGERHEART.General.Hope'
|
||||||
|
: this.withFear
|
||||||
|
? 'DAGGERHEART.General.Fear'
|
||||||
|
: 'DAGGERHEART.General.CriticalSuccess';
|
||||||
|
|
||||||
|
return game.i18n.localize(label);
|
||||||
|
}
|
||||||
|
|
||||||
|
updateFormula() {}
|
||||||
|
|
||||||
|
createBaseDice() {
|
||||||
|
if (
|
||||||
|
this.dice[0] instanceof CONFIG.Dice.daggerheart.DualityDie &&
|
||||||
|
this.dice[1] instanceof CONFIG.Dice.daggerheart.DualityDie
|
||||||
|
) {
|
||||||
|
this.terms = [this.terms[0], this.terms[1], this.terms[2]];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.terms[0] = new CONFIG.Dice.daggerheart.DualityDie();
|
||||||
|
this.terms[1] = new foundry.dice.terms.OperatorTerm({ operator: '+' });
|
||||||
|
this.terms[2] = new CONFIG.Dice.daggerheart.DualityDie();
|
||||||
|
}
|
||||||
|
|
||||||
|
applyAdvantage() {
|
||||||
|
const dieFaces = this.advantageFaces,
|
||||||
|
bardRallyFaces = this.hasBarRally,
|
||||||
|
advDie = new foundry.dice.terms.Die({ faces: dieFaces });
|
||||||
|
if (this.hasAdvantage || this.hasDisadvantage || bardRallyFaces)
|
||||||
|
this.terms.push(new foundry.dice.terms.OperatorTerm({ operator: this.hasDisadvantage ? '-' : '+' }));
|
||||||
|
if (bardRallyFaces) {
|
||||||
|
const rallyDie = new foundry.dice.terms.Die({ faces: bardRallyFaces });
|
||||||
|
if (this.hasAdvantage) {
|
||||||
|
this.terms.push(
|
||||||
|
new foundry.dice.terms.PoolTerm({
|
||||||
|
terms: [advDie.formula, rallyDie.formula],
|
||||||
|
modifiers: ['kh']
|
||||||
|
})
|
||||||
|
);
|
||||||
|
} else if (this.hasDisadvantage) {
|
||||||
|
this.terms.push(advDie, new foundry.dice.terms.OperatorTerm({ operator: '+' }), rallyDie);
|
||||||
|
}
|
||||||
|
} else if (this.hasAdvantage || this.hasDisadvantage) this.terms.push(advDie);
|
||||||
|
}
|
||||||
|
|
||||||
|
applyBaseBonus() {
|
||||||
|
this.options.roll.modifiers = [];
|
||||||
|
if (!this.options.roll.trait) return;
|
||||||
|
this.options.roll.modifiers.push({
|
||||||
|
label: `DAGGERHEART.Abilities.${this.options.roll.trait}.name`,
|
||||||
|
value: Roll.replaceFormulaData(`@traits.${this.options.roll.trait}.total`, this.data)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
static postEvaluate(roll, config = {}) {
|
||||||
|
super.postEvaluate(roll, config);
|
||||||
|
config.roll.hope = {
|
||||||
|
dice: roll.dHope.denomination,
|
||||||
|
value: roll.dHope.total
|
||||||
|
};
|
||||||
|
config.roll.fear = {
|
||||||
|
dice: roll.dFear.denomination,
|
||||||
|
value: roll.dFear.total
|
||||||
|
};
|
||||||
|
config.roll.result = {
|
||||||
|
duality: roll.withHope ? 1 : roll.withFear ? -1 : 0,
|
||||||
|
total: roll.dHope.total + roll.dFear.total,
|
||||||
|
label: roll.totalLabel
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue