diff --git a/daggerheart.mjs b/daggerheart.mjs index 61e74f9b..76205475 100644 --- a/daggerheart.mjs +++ b/daggerheart.mjs @@ -60,9 +60,6 @@ CONFIG.Canvas.layers.tokens.layerClass = DhTokenLayer; CONFIG.MeasuredTemplate.objectClass = placeables.DhMeasuredTemplate; -CONFIG.RollTable.documentClass = documents.DhRollTable; -CONFIG.RollTable.resultTemplate = 'systems/daggerheart/templates/ui/chat/table-result.hbs'; - CONFIG.Scene.documentClass = documents.DhScene; CONFIG.Token.documentClass = documents.DhToken; @@ -110,7 +107,7 @@ Hooks.once('init', () => { type: game.i18n.localize(typePath) }); - const { Items, Actors, RollTables } = foundry.documents.collections; + const { Items, Actors } = foundry.documents.collections; Items.unregisterSheet('core', foundry.applications.sheets.ItemSheetV2); Items.registerSheet(SYSTEM.id, applications.sheets.items.Ancestry, { types: ['ancestry'], @@ -195,12 +192,6 @@ Hooks.once('init', () => { label: sheetLabel('TYPES.Actor.party') }); - RollTables.unregisterSheet('core', foundry.applications.sheets.RollTableSheet); - RollTables.registerSheet(SYSTEM.id, applications.sheets.rollTables.RollTableSheet, { - types: ['base'], - makeDefault: true - }); - DocumentSheetConfig.unregisterSheet( CONFIG.ActiveEffect.documentClass, 'core', @@ -309,7 +300,6 @@ Hooks.on('chatMessage', (_, message) => { ? CONFIG.DH.ACTIONS.advantageState.disadvantage.value : undefined; const difficulty = rollCommand.difficulty; - const grantResources = Boolean(rollCommand.grantResources); const target = getCommandTarget({ allowNull: true }); const title = @@ -327,8 +317,7 @@ Hooks.on('chatMessage', (_, message) => { title, label: game.i18n.localize('DAGGERHEART.GENERAL.dualityRoll'), actionType: null, - advantage, - grantResources + advantage }); return false; } diff --git a/lang/en.json b/lang/en.json index 4d6815c3..69965b9e 100755 --- a/lang/en.json +++ b/lang/en.json @@ -330,12 +330,6 @@ "title": "{actor} - Character Setup", "traitIncreases": "Trait Increases" }, - "CharacterReset": { - "title": "Reset Character", - "alwaysDeleteSection": "Deleted Data", - "optionalDeleteSection": "Optional Data", - "headerTitle": "Select which data you'd like to keep" - }, "CombatTracker": { "combatStarted": "Active", "giveSpotlight": "Give The Spotlight", @@ -488,9 +482,7 @@ "tokenHUD": { "genericEffects": "Foundry Effects", "depositPartyTokens": "Deposit Party Tokens", - "retrievePartyTokens": "Retrieve Party Tokens", - "depositCompanionTokens": "Deposit Companion Token", - "retrieveCompanionTokens": "Retrieve Companion Token" + "retrievePartyTokens": "Retrieve Party Tokens" } }, "ImageSelect": { @@ -620,7 +612,6 @@ }, "RerollDialog": { "title": "Reroll", - "damageTitle": "Reroll Damage", "deselectDiceNotification": "Deselect one of the selected dice first", "acceptCurrentRolls": "Accept Current Rolls" }, @@ -982,10 +973,6 @@ "outsideRange": "Outside Range" }, "Condition": { - "deathMove": { - "name": "Death Move", - "description": "The character is about to make a Death Move" - }, "dead": { "name": "Dead", "description": "The character is dead" @@ -2223,7 +2210,6 @@ "single": "Player", "plurial": "Players" }, - "portrait": "Portrait", "proficiency": "Proficiency", "quantity": "Quantity", "range": "Range", @@ -2383,12 +2369,6 @@ "secondaryWeapon": "Secondary Weapon" } }, - "ROLLTABLES": { - "FIELDS": { - "formulaName": { "label": "Formula Name" } - }, - "formula": "Formula" - }, "SETTINGS": { "Appearance": { "FIELDS": { @@ -2455,11 +2435,7 @@ "overlay": { "label": "Overlay Effect" }, "characterDefault": { "label": "Character Default Defeated Status" }, "adversaryDefault": { "label": "Adversary Default Defeated Status" }, - "companionDefault": { "label": "Companion Default Defeated Status" }, - "deathMove": { "label": "Death Move" }, - "dead": { "label": "Dead" }, - "defeated": { "label": "Defeated" }, - "unconscious": { "label": "Unconscious" } + "companionDefault": { "label": "Companion Default Defeated Status" } }, "hopeFear": { "label": "Hope & Fear", @@ -2544,7 +2520,6 @@ "itemFeatures": "Item Features", "nrChoices": "# Moves Per Rest", "resetMovesTitle": "Reset {type} Downtime Moves", - "resetItemFeaturesTitle": "Reset {type}", "resetMovesText": "Are you sure you want to reset?", "FIELDS": { "maxFear": { "label": "Max Fear" }, @@ -2893,8 +2868,7 @@ "documentIsMissing": "The {documentType} is missing from the world.", "tokenActorMissing": "{name} is missing an Actor", "tokenActorsMissing": "[{names}] missing Actors", - "domainTouchRequirement": "This domain card requires {nr} {domain} cards in the loadout to be used", - "knowTheTide": "Know The Tide gained a token" + "domainTouchRequirement": "This domain card requires {nr} {domain} cards in the loadout to be used" }, "Sidebar": { "actorDirectory": { diff --git a/module/applications/dialogs/_module.mjs b/module/applications/dialogs/_module.mjs index 4eda8579..d43045e6 100644 --- a/module/applications/dialogs/_module.mjs +++ b/module/applications/dialogs/_module.mjs @@ -1,6 +1,5 @@ export { default as AttributionDialog } from './attributionDialog.mjs'; export { default as BeastformDialog } from './beastformDialog.mjs'; -export { default as CharacterResetDialog } from './characterResetDialog.mjs'; export { default as d20RollDialog } from './d20RollDialog.mjs'; export { default as DamageDialog } from './damageDialog.mjs'; export { default as DamageReductionDialog } from './damageReductionDialog.mjs'; diff --git a/module/applications/dialogs/characterResetDialog.mjs b/module/applications/dialogs/characterResetDialog.mjs deleted file mode 100644 index 0836af9c..00000000 --- a/module/applications/dialogs/characterResetDialog.mjs +++ /dev/null @@ -1,105 +0,0 @@ -const { ApplicationV2, HandlebarsApplicationMixin } = foundry.applications.api; - -export default class CharacterResetDialog extends HandlebarsApplicationMixin(ApplicationV2) { - constructor(actor, options = {}) { - super(options); - - this.actor = actor; - this.data = { - delete: { - class: { keep: false, label: 'TYPES.Item.class' }, - subclass: { keep: false, label: 'TYPES.Item.subclass' }, - ancestry: { keep: false, label: 'TYPES.Item.ancestry' }, - community: { keep: false, label: 'TYPES.Item.community' } - }, - optional: { - portrait: { keep: true, label: 'DAGGERHEART.GENERAL.portrait' }, - name: { keep: true, label: 'Name' }, - biography: { keep: true, label: 'DAGGERHEART.GENERAL.Tabs.biography' }, - inventory: { keep: true, label: 'DAGGERHEART.GENERAL.inventory' } - } - }; - } - - static DEFAULT_OPTIONS = { - tag: 'form', - classes: ['daggerheart', 'dialog', 'dh-style', 'views', 'character-reset'], - window: { - icon: 'fa-solid fa-arrow-rotate-left', - title: 'DAGGERHEART.APPLICATIONS.CharacterReset.title' - }, - actions: { - finishSelection: this.#finishSelection - }, - form: { - handler: this.updateData, - submitOnChange: true, - submitOnClose: false - } - }; - - /** @override */ - static PARTS = { - resourceDice: { - id: 'resourceDice', - template: 'systems/daggerheart/templates/dialogs/characterReset.hbs' - } - }; - - async _prepareContext(_options) { - const context = await super._prepareContext(_options); - context.data = this.data; - - return context; - } - - static async updateData(event, _, formData) { - const { data } = foundry.utils.expandObject(formData.object); - - this.data = foundry.utils.mergeObject(this.data, data); - this.render(); - } - - static getUpdateData() { - const update = {}; - if (!this.data.optional.portrait) update.if(!this.data.optional.biography); - - if (!this.data.optional.inventory) return update; - } - - static async #finishSelection() { - const update = {}; - if (!this.data.optional.name.keep) { - const defaultName = game.system.api.documents.DhpActor.defaultName({ type: 'character' }); - foundry.utils.setProperty(update, 'name', defaultName); - foundry.utils.setProperty(update, 'prototypeToken.name', defaultName); - } - - if (!this.data.optional.portrait.keep) { - foundry.utils.setProperty(update, 'img', this.actor.schema.fields.img.initial(this.actor)); - foundry.utils.setProperty(update, 'prototypeToken.==texture', {}); - foundry.utils.setProperty(update, 'prototypeToken.==ring', {}); - } - - if (this.data.optional.biography.keep) - foundry.utils.setProperty(update, 'system.biography', this.actor.system.biography); - - if (this.data.optional.inventory.keep) foundry.utils.setProperty(update, 'system.gold', this.actor.system.gold); - - const { system, ...rest } = update; - await this.actor.update({ - ...rest, - '==system': system ?? {} - }); - - const inventoryItemTypes = ['weapon', 'armor', 'consumable', 'loot']; - await this.actor.deleteEmbeddedDocuments( - 'Item', - this.actor.items - .filter(x => !inventoryItemTypes.includes(x.type) || !this.data.optional.inventory.keep) - .map(x => x.id) - ); - - this.close(); - } -} diff --git a/module/applications/dialogs/d20RollDialog.mjs b/module/applications/dialogs/d20RollDialog.mjs index 4a4b1556..6f320152 100644 --- a/module/applications/dialogs/d20RollDialog.mjs +++ b/module/applications/dialogs/d20RollDialog.mjs @@ -109,17 +109,11 @@ export default class D20RollDialog extends HandlebarsApplicationMixin(Applicatio context.roll = this.roll; context.rollType = this.roll?.constructor.name; context.rallyDie = this.roll.rallyChoices; - - const actorExperiences = this.config.data?.system?.experiences || {}; - const companionExperiences = this.config.roll.companionRoll - ? (this.config.data?.companion?.system.experiences ?? {}) - : null; - const experiences = companionExperiences ?? actorExperiences; + const experiences = this.config.data?.system?.experiences || {}; context.experiences = Object.keys(experiences).map(id => ({ id, ...experiences[id] })); - context.selectedExperiences = this.config.experiences; context.advantage = this.config.roll?.advantage; context.disadvantage = this.config.roll?.disadvantage; diff --git a/module/applications/dialogs/deathMove.mjs b/module/applications/dialogs/deathMove.mjs index 3eadede6..01df6057 100644 --- a/module/applications/dialogs/deathMove.mjs +++ b/module/applications/dialogs/deathMove.mjs @@ -54,9 +54,10 @@ export default class DhDeathMove extends HandlebarsApplicationMixin(ApplicationV if (!config.roll.fate) return; - let returnMessage = game.i18n.localize('DAGGERHEART.UI.Chat.deathMove.avoidScar'); if (config.roll.fate.value <= this.actor.system.levelData.level.current) { + // apply scarring - for now directly apply - later add a button. const newScarAmount = this.actor.system.scars + 1; + await this.actor.update({ system: { scars: newScarAmount @@ -64,15 +65,13 @@ export default class DhDeathMove extends HandlebarsApplicationMixin(ApplicationV }); if (newScarAmount >= this.actor.system.resources.hope.max) { - await this.actor.setDeathMoveDefeated(CONFIG.DH.GENERAL.defeatedConditionChoices.dead.id); return game.i18n.format('DAGGERHEART.UI.Chat.deathMove.journeysEnd', { scars: newScarAmount }); } - returnMessage = game.i18n.localize('DAGGERHEART.UI.Chat.deathMove.gainScar'); + return game.i18n.localize('DAGGERHEART.UI.Chat.deathMove.gainScar'); } - await this.actor.setDeathMoveDefeated(CONFIG.DH.GENERAL.defeatedConditionChoices.unconscious.id); - return returnMessage; + return game.i18n.localize('DAGGERHEART.UI.Chat.deathMove.avoidScar'); } async handleRiskItAll() { @@ -85,7 +84,6 @@ export default class DhDeathMove extends HandlebarsApplicationMixin(ApplicationV label: game.i18n.localize('DAGGERHEART.GENERAL.dualityDice'), actionType: null, advantage: null, - grantResources: false, customConfig: { skips: { resources: true, reaction: true } } }); @@ -120,7 +118,6 @@ export default class DhDeathMove extends HandlebarsApplicationMixin(ApplicationV } if (config.roll.result.duality == -1) { - await this.actor.setDeathMoveDefeated(CONFIG.DH.GENERAL.defeatedConditionChoices.dead.id); chatMessage = game.i18n.localize('DAGGERHEART.UI.Chat.deathMove.riskItAllFailure'); } @@ -144,7 +141,6 @@ export default class DhDeathMove extends HandlebarsApplicationMixin(ApplicationV } ]); - await this.actor.setDeathMoveDefeated(CONFIG.DH.GENERAL.defeatedConditionChoices.dead.id); return game.i18n.localize('DAGGERHEART.UI.Chat.deathMove.blazeOfGlory'); } diff --git a/module/applications/hud/tokenHUD.mjs b/module/applications/hud/tokenHUD.mjs index 77caaaff..87c3e88e 100644 --- a/module/applications/hud/tokenHUD.mjs +++ b/module/applications/hud/tokenHUD.mjs @@ -5,8 +5,7 @@ export default class DHTokenHUD extends foundry.applications.hud.TokenHUD { classes: ['daggerheart'], actions: { combat: DHTokenHUD.#onToggleCombat, - togglePartyTokens: DHTokenHUD.#togglePartyTokens, - toggleCompanions: DHTokenHUD.#toggleCompanions + togglePartyTokens: DHTokenHUD.#togglePartyTokens } }; @@ -27,7 +26,7 @@ export default class DHTokenHUD extends foundry.applications.hud.TokenHUD { context.partyOnCanvas = this.actor.type === 'party' && this.actor.system.partyMembers.some(member => member.getActiveTokens().length > 0); - context.icons.toggleClowncar = 'systems/daggerheart/assets/icons/arrow-dunk.png'; + context.icons.toggleParty = 'systems/daggerheart/assets/icons/arrow-dunk.png'; context.actorType = this.actor.type; context.usesEffects = this.actor.type !== 'party'; context.canToggleCombat = DHTokenHUD.#nonCombatTypes.includes(this.actor.type) @@ -57,9 +56,6 @@ export default class DHTokenHUD extends foundry.applications.hud.TokenHUD { }, {}) : null; - context.hasCompanion = this.actor.system.companion; - context.companionOnCanvas = context.hasCompanion && this.actor.system.companion.getActiveTokens().length > 0; - return context; } @@ -105,24 +101,8 @@ export default class DHTokenHUD extends foundry.applications.hud.TokenHUD { : 'DAGGERHEART.APPLICATIONS.HUD.tokenHUD.depositPartyTokens' ); - await this.toggleClowncar(this.actor.system.partyMembers); - } - - static async #toggleCompanions(_, button) { - const icon = button.querySelector('img'); - icon.classList.toggle('flipped'); - button.dataset.tooltip = game.i18n.localize( - icon.classList.contains('flipped') - ? 'DAGGERHEART.APPLICATIONS.HUD.tokenHUD.retrieveCompanionTokens' - : 'DAGGERHEART.APPLICATIONS.HUD.tokenHUD.depositCompanionTokens' - ); - - await this.toggleClowncar([this.actor.system.companion]); - } - - async toggleClowncar(actors) { const animationDuration = 500; - const activeTokens = actors.flatMap(member => member.getActiveTokens()); + const activeTokens = this.actor.system.partyMembers.flatMap(member => member.getActiveTokens()); const { x: actorX, y: actorY } = this.document; if (activeTokens.length > 0) { for (let token of activeTokens) { @@ -134,15 +114,14 @@ export default class DHTokenHUD extends foundry.applications.hud.TokenHUD { } } else { const activeScene = game.scenes.find(x => x.id === game.user.viewedScene); - const tokenData = []; - for (let member of actors) { + const partyTokenData = []; + for (let member of this.actor.system.partyMembers) { const data = await member.getTokenDocument(); - tokenData.push(data.toObject()); + partyTokenData.push(data.toObject()); } - const newTokens = await activeScene.createEmbeddedDocuments( 'Token', - tokenData.map(tokenData => ({ + partyTokenData.map(tokenData => ({ ...tokenData, alpha: 0, x: actorX, diff --git a/module/applications/scene/sceneConfigSettings.mjs b/module/applications/scene/sceneConfigSettings.mjs index 98e18f09..8a58db5c 100644 --- a/module/applications/scene/sceneConfigSettings.mjs +++ b/module/applications/scene/sceneConfigSettings.mjs @@ -65,15 +65,8 @@ export default class DhSceneConfigSettings extends foundry.applications.sheets.S const data = foundry.applications.ux.TextEditor.implementation.getDragEventData(event); const item = await foundry.utils.fromUuid(data.uuid); if (item instanceof game.system.api.documents.DhpActor && item.type === 'environment') { - let sceneUuid = data.uuid; - if (item.pack) { - const inWorldActor = await game.system.api.documents.DhpActor.create([item.toObject()]); - if (!inWorldActor.length) return; - sceneUuid = inWorldActor[0].uuid; - } - await this.daggerheartFlag.updateSource({ - sceneEnvironments: [...this.daggerheartFlag.sceneEnvironments, sceneUuid] + sceneEnvironments: [...this.daggerheartFlag.sceneEnvironments, data.uuid] }); this.render({ internalRefresh: true }); } @@ -104,10 +97,6 @@ export default class DhSceneConfigSettings extends foundry.applications.sheets.S /** @override */ async _processSubmitData(event, form, submitData, options) { submitData.flags.daggerheart = this.daggerheartFlag.toObject(); - submitData.flags.daggerheart.sceneEnvironments = submitData.flags.daggerheart.sceneEnvironments.filter(x => - foundry.utils.fromUuidSync(x) - ); - for (const key of Object.keys(this.document._source.flags.daggerheart?.sceneEnvironments ?? {})) { if (!submitData.flags.daggerheart.sceneEnvironments[key]) { submitData.flags.daggerheart.sceneEnvironments[`-=${key}`] = null; diff --git a/module/applications/settings/homebrewSettings.mjs b/module/applications/settings/homebrewSettings.mjs index 6e2e665d..3c4486c1 100644 --- a/module/applications/settings/homebrewSettings.mjs +++ b/module/applications/settings/homebrewSettings.mjs @@ -36,8 +36,7 @@ export default class DhHomebrewSettings extends HandlebarsApplicationMixin(Appli addItem: this.addItem, editItem: this.editItem, removeItem: this.removeItem, - resetDowntimeMoves: this.resetDowntimeMoves, - resetItemFeatures: this.resetItemFeatures, + resetMoves: this.resetMoves, addDomain: this.addDomain, toggleSelectedDomain: this.toggleSelectedDomain, deleteDomain: this.deleteDomain, @@ -233,7 +232,7 @@ export default class DhHomebrewSettings extends HandlebarsApplicationMixin(Appli this.render(); } - static async resetDowntimeMoves(_, target) { + static async resetMoves(_, target) { const confirmed = await foundry.applications.api.DialogV2.confirm({ window: { title: game.i18n.format('DAGGERHEART.SETTINGS.Homebrew.resetMovesTitle', { @@ -267,7 +266,7 @@ export default class DhHomebrewSettings extends HandlebarsApplicationMixin(Appli ...move, name: game.i18n.localize(move.name), description: game.i18n.localize(move.description), - actions: Object.keys(move.actions).reduce((acc, key) => { + actions: move.actions.reduce((acc, key) => { const action = move.actions[key]; acc[key] = { ...action, @@ -294,31 +293,6 @@ export default class DhHomebrewSettings extends HandlebarsApplicationMixin(Appli this.render(); } - static async resetItemFeatures(_, target) { - const confirmed = await foundry.applications.api.DialogV2.confirm({ - window: { - title: game.i18n.format('DAGGERHEART.SETTINGS.Homebrew.resetItemFeaturesTitle', { - type: game.i18n.localize(`DAGGERHEART.GENERAL.${target.dataset.type}`) - }) - }, - content: game.i18n.localize('DAGGERHEART.SETTINGS.Homebrew.resetMovesText') - }); - - if (!confirmed) return; - - await this.settings.updateSource({ - [`itemFeatures.${target.dataset.type}`]: Object.keys( - this.settings.itemFeatures[target.dataset.type] - ).reduce((acc, key) => { - acc[`-=${key}`] = null; - - return acc; - }, {}) - }); - - this.render(); - } - static async addDomain(event) { event.preventDefault(); const content = new foundry.data.fields.StringField({ diff --git a/module/applications/sheets-configs/action-base-config.mjs b/module/applications/sheets-configs/action-base-config.mjs index 42252362..7051ad2b 100644 --- a/module/applications/sheets-configs/action-base-config.mjs +++ b/module/applications/sheets-configs/action-base-config.mjs @@ -125,7 +125,6 @@ export default class DHActionBaseConfig extends DaggerheartSheet(ApplicationV2) async _prepareContext(_options) { const context = await super._prepareContext(_options, 'action'); context.source = this.action.toObject(true); - context.action = this.action; context.summons = []; for (const summon of context.source.summon ?? []) { diff --git a/module/applications/sheets/_module.mjs b/module/applications/sheets/_module.mjs index 390267d5..c503e054 100644 --- a/module/applications/sheets/_module.mjs +++ b/module/applications/sheets/_module.mjs @@ -1,4 +1,3 @@ export * as actors from './actors/_module.mjs'; export * as api from './api/_modules.mjs'; export * as items from './items/_module.mjs'; -export * as rollTables from './rollTables/_module.mjs'; diff --git a/module/applications/sheets/actors/character.mjs b/module/applications/sheets/actors/character.mjs index 4ecaeb06..5c6bac3a 100644 --- a/module/applications/sheets/actors/character.mjs +++ b/module/applications/sheets/actors/character.mjs @@ -669,7 +669,26 @@ export default class CharacterSheet extends DHBaseActorSheet { * Resets the character data and removes all embedded documents. */ static async #resetCharacter() { - new game.system.api.applications.dialogs.CharacterResetDialog(this.document).render({ force: true }); + const confirmed = await foundry.applications.api.DialogV2.confirm({ + window: { + title: game.i18n.localize('DAGGERHEART.ACTORS.Character.resetCharacterConfirmationTitle') + }, + content: game.i18n.localize('DAGGERHEART.ACTORS.Character.resetCharacterConfirmationContent') + }); + + if (!confirmed) return; + + await this.document.update({ + '==system': {} + }); + await this.document.deleteEmbeddedDocuments( + 'Item', + this.document.items.map(x => x.id) + ); + await this.document.deleteEmbeddedDocuments( + 'ActiveEffect', + this.document.effects.map(x => x.id) + ); } /** @@ -734,9 +753,8 @@ export default class CharacterSheet extends DHBaseActorSheet { if (!result) return; /* This could be avoided by baking config.costs into config.resourceUpdates. Didn't feel like messing with it at the time */ - const costResources = - result.costs?.filter(x => x.enabled).map(cost => ({ ...cost, value: -cost.value, total: -cost.total })) || - {}; + const costResources = result.costs?.filter(x => x.enabled) + .map(cost => ({ ...cost, value: -cost.value, total: -cost.total })) || {}; config.resourceUpdates.addResources(costResources); await config.resourceUpdates.updateResources(); } diff --git a/module/applications/sheets/actors/companion.mjs b/module/applications/sheets/actors/companion.mjs index b30b9c07..6f3bbf16 100644 --- a/module/applications/sheets/actors/companion.mjs +++ b/module/applications/sheets/actors/companion.mjs @@ -62,10 +62,10 @@ export default class DhCompanionSheet extends DHBaseActorSheet { title: `${game.i18n.localize('DAGGERHEART.GENERAL.Roll.action')}: ${this.actor.name}`, headerTitle: `Companion ${game.i18n.localize('DAGGERHEART.GENERAL.Roll.action')}`, roll: { - trait: partner.system.spellcastModifierTrait?.key, - companionRoll: true + trait: partner.system.spellcastModifierTrait?.key }, - hasRoll: true + hasRoll: true, + data: partner.getRollData() }; const result = await partner.diceRoll(config); diff --git a/module/applications/sheets/api/application-mixin.mjs b/module/applications/sheets/api/application-mixin.mjs index 3c0444eb..b590de86 100644 --- a/module/applications/sheets/api/application-mixin.mjs +++ b/module/applications/sheets/api/application-mixin.mjs @@ -600,7 +600,7 @@ export default function DHApplicationMixin(Base) { { relativeTo: isAction ? doc.parent : doc, rollData: doc.getRollData?.(), - secrets: isAction ? doc.parent.parent.isOwner : doc.isOwner + secrets: isAction ? doc.parent.isOwner : doc.isOwner } ); } diff --git a/module/applications/sheets/rollTables/_module.mjs b/module/applications/sheets/rollTables/_module.mjs deleted file mode 100644 index 73067b64..00000000 --- a/module/applications/sheets/rollTables/_module.mjs +++ /dev/null @@ -1 +0,0 @@ -export { default as RollTableSheet } from './rollTable.mjs'; diff --git a/module/applications/sheets/rollTables/rollTable.mjs b/module/applications/sheets/rollTables/rollTable.mjs deleted file mode 100644 index 9ead6814..00000000 --- a/module/applications/sheets/rollTables/rollTable.mjs +++ /dev/null @@ -1,191 +0,0 @@ -export default class DhRollTableSheet extends foundry.applications.sheets.RollTableSheet { - static DEFAULT_OPTIONS = { - ...super.DEFAULT_OPTIONS, - actions: { - changeMode: DhRollTableSheet.#onChangeMode, - drawResult: DhRollTableSheet.#onDrawResult, - resetResults: DhRollTableSheet.#onResetResults, - addFormula: DhRollTableSheet.#addFormula, - removeFormula: DhRollTableSheet.#removeFormula - } - }; - - static buildParts() { - const { footer, header, sheet, results, ...parts } = super.PARTS; - return { - sheet: { - ...sheet, - template: 'systems/daggerheart/templates/sheets/rollTable/sheet.hbs' - }, - header: { template: 'systems/daggerheart/templates/sheets/rollTable/header.hbs' }, - ...parts, - results: { - template: 'systems/daggerheart/templates/sheets/rollTable/results.hbs', - templates: ['templates/sheets/roll-table/result-details.hbs'], - scrollable: ['table[data-results] tbody'] - }, - summary: { template: 'systems/daggerheart/templates/sheets/rollTable/summary.hbs' }, - footer - }; - } - - static PARTS = DhRollTableSheet.buildParts(); - - async _preRender(context, options) { - await super._preRender(context, options); - - if (!options.internalRefresh) - this.daggerheartFlag = new game.system.api.data.DhRollTable(this.document.flags.daggerheart); - } - - /* root PART has a blank element on _attachPartListeners, so it cannot be used to set the eventListeners for the view mode */ - async _onRender(context, options) { - super._onRender(context, options); - - for (const element of this.element.querySelectorAll('.system-update-field')) - element.addEventListener('change', this.updateSystemField.bind(this)); - } - - async _preparePartContext(partId, context, options) { - context = await super._preparePartContext(partId, context, options); - - switch (partId) { - case 'sheet': - context.altFormula = this.daggerheartFlag.altFormula; - context.usesAltFormula = Object.keys(this.daggerheartFlag.altFormula).length > 0; - context.altFormulaOptions = { - '': { name: this.daggerheartFlag.formulaName }, - ...this.daggerheartFlag.altFormula - }; - context.activeAltFormula = this.daggerheartFlag.activeAltFormula; - context.selectedFormula = this.daggerheartFlag.getActiveFormula(this.document.formula); - context.results = this.getExtendedResults(context.results); - break; - case 'header': - context.altFormula = this.daggerheartFlag.altFormula; - context.usesAltFormula = Object.keys(this.daggerheartFlag.altFormula).length > 0; - context.altFormulaOptions = { - '': { name: this.daggerheartFlag.formulaName }, - ...this.daggerheartFlag.altFormula - }; - context.activeAltFormula = this.daggerheartFlag.activeAltFormula; - break; - case 'summary': - context.systemFields = this.daggerheartFlag.schema.fields; - context.altFormula = this.daggerheartFlag.altFormula; - context.formulaName = this.daggerheartFlag.formulaName; - break; - case 'results': - context.results = this.getExtendedResults(context.results); - break; - } - - return context; - } - - getExtendedResults(results) { - const bodyDarkMode = document.body.classList.contains('theme-dark'); - const elementLightMode = this.element.classList.contains('theme-light'); - const elementDarkMode = this.element.classList.contains('theme-dark'); - const isDarkMode = elementDarkMode || (!elementLightMode && bodyDarkMode); - - return results.map(x => ({ - ...x, - displayImg: isDarkMode && x.img === 'icons/svg/d20-black.svg' ? 'icons/svg/d20.svg' : x.img - })); - } - - /* -------------------------------------------- */ - /* Flag SystemData update methods */ - /* -------------------------------------------- */ - - async updateSystemField(event) { - const { dataset, value } = event.target; - await this.daggerheartFlag.updateSource({ [dataset.path]: value }); - this.render({ internalRefresh: true }); - } - - getSystemFlagUpdate() { - const deleteUpdate = Object.keys(this.document._source.flags.daggerheart?.altFormula ?? {}).reduce( - (acc, formulaKey) => { - if (!this.daggerheartFlag.altFormula[formulaKey]) acc.altFormula[`-=${formulaKey}`] = null; - - return acc; - }, - { altFormula: {} } - ); - - return { ['flags.daggerheart']: foundry.utils.mergeObject(this.daggerheartFlag.toObject(), deleteUpdate) }; - } - - static async #addFormula() { - await this.daggerheartFlag.updateSource({ - [`altFormula.${foundry.utils.randomID()}`]: game.system.api.data.DhRollTable.getDefaultFormula() - }); - this.render({ internalRefresh: true }); - } - - static async #removeFormula(_event, target) { - await this.daggerheartFlag.updateSource({ - [`altFormula.-=${target.dataset.key}`]: null - }); - this.render({ internalRefresh: true }); - } - - /* -------------------------------------------- */ - /* Extended RollTable methods */ - /* -------------------------------------------- */ - - /** - * Alternate between view and edit modes. - * @this {RollTableSheet} - * @type {ApplicationClickAction} - */ - static async #onChangeMode() { - this.mode = this.isEditMode ? 'view' : 'edit'; - await this.document.update(this.getSystemFlagUpdate()); - await this.render({ internalRefresh: true }); - } - - /** @inheritdoc */ - async _processSubmitData(event, form, submitData, options) { - /* RollTable sends an empty dummy event when swapping from view/edit first time */ - if (Object.keys(submitData).length) { - if (!submitData.flags) submitData.flags = { daggerheart: {} }; - submitData.flags.daggerheart = this.getSystemFlagUpdate(); - } - - super._processSubmitData(event, form, submitData, options); - } - - /** @inheritdoc */ - static async #onResetResults() { - await this.document.update(this.getSystemFlagUpdate()); - await this.document.resetResults(); - } - - /** - * Roll and draw a TableResult. - * @this {RollTableSheet} - * @type {ApplicationClickAction} - */ - static async #onDrawResult(_event, button) { - if (this.form) await this.submit({ operation: { render: false } }); - button.disabled = true; - const table = this.document; - - await this.document.update(this.getSystemFlagUpdate()); - - /* Sending in the currently selectd activeFormula to table.roll to use as the formula */ - const selectedFormula = this.daggerheartFlag.getActiveFormula(this.document.formula); - const tableRoll = await table.roll({ selectedFormula }); - const draws = table.getResultsForRoll(tableRoll.roll.total); - if (draws.length > 0) { - if (game.settings.get('core', 'animateRollTable')) await this._animateRoll(draws); - await table.draw(tableRoll); - } - - // Reenable the button if drawing with replacement since the draw won't trigger a sheet re-render - if (table.replacement) button.disabled = false; - } -} diff --git a/module/applications/ui/combatTracker.mjs b/module/applications/ui/combatTracker.mjs index fc47f085..288ba8ad 100644 --- a/module/applications/ui/combatTracker.mjs +++ b/module/applications/ui/combatTracker.mjs @@ -42,8 +42,8 @@ export default class DhCombatTracker extends foundry.applications.sidebar.tabs.C this.combats .find(x => x.active) ?.system?.extendedBattleToggles?.reduce((acc, toggle) => (acc ?? 0) + toggle.category, null) ?? null; - const maxBP = CONFIG.DH.ENCOUNTER.BaseBPPerEncounter(context.allCharacters.length) + modifierBP; - const currentBP = AdversaryBPPerEncounter(context.adversaries, context.allCharacters); + const maxBP = CONFIG.DH.ENCOUNTER.BaseBPPerEncounter(context.characters.length) + modifierBP; + const currentBP = AdversaryBPPerEncounter(context.adversaries, context.characters); Object.assign(context, { fear: game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Resources.Fear), @@ -73,8 +73,9 @@ export default class DhCombatTracker extends foundry.applications.sidebar.tabs.C Object.assign(context, { actionTokens: game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.variantRules).actionTokens, adversaries, - allCharacters: characters, - characters: characters.filter(x => !spotlightQueueEnabled || x.system.spotlight.requestOrderIndex == 0), + characters: characters + ?.filter(x => !x.isNPC) + .filter(x => !spotlightQueueEnabled || x.system.spotlight.requestOrderIndex == 0), spotlightRequests }); } diff --git a/module/applications/ui/effectsDisplay.mjs b/module/applications/ui/effectsDisplay.mjs index 8c0c939c..0875e783 100644 --- a/module/applications/ui/effectsDisplay.mjs +++ b/module/applications/ui/effectsDisplay.mjs @@ -76,8 +76,6 @@ export default class DhEffectsDisplay extends HandlebarsApplicationMixin(Applica }; toggleHidden(token, focused) { - if (!this.element) return; - const effects = DhEffectsDisplay.getTokenEffects(focused ? token : null); this.element.hidden = effects.length === 0; diff --git a/module/config/generalConfig.mjs b/module/config/generalConfig.mjs index be1dfce1..37894644 100644 --- a/module/config/generalConfig.mjs +++ b/module/config/generalConfig.mjs @@ -171,7 +171,7 @@ export const defeatedConditions = () => { acc[key] = { ...choice, img: defeated[`${choice.id}Icon`], - description: game.i18n.localize(`DAGGERHEART.CONFIG.Condition.${choice.id}.description`) + description: `DAGGERHEART.CONFIG.Condition.${choice.id}.description` }; return acc; @@ -179,10 +179,6 @@ export const defeatedConditions = () => { }; export const defeatedConditionChoices = { - deathMove: { - id: 'deathMove', - name: 'DAGGERHEART.CONFIG.Condition.deathMove.name' - }, defeated: { id: 'defeated', name: 'DAGGERHEART.CONFIG.Condition.defeated.name' diff --git a/module/data/_module.mjs b/module/data/_module.mjs index f7e25a4e..7ad20808 100644 --- a/module/data/_module.mjs +++ b/module/data/_module.mjs @@ -1,7 +1,6 @@ export { default as DhCombat } from './combat.mjs'; export { default as DhCombatant } from './combatant.mjs'; export { default as DhTagTeamRoll } from './tagTeamRoll.mjs'; -export { default as DhRollTable } from './rollTable.mjs'; export { default as RegisteredTriggers } from './registeredTriggers.mjs'; export * as countdowns from './countdowns.mjs'; diff --git a/module/data/action/baseAction.mjs b/module/data/action/baseAction.mjs index 115e6463..4e699f79 100644 --- a/module/data/action/baseAction.mjs +++ b/module/data/action/baseAction.mjs @@ -241,7 +241,6 @@ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel hasHealing: this.hasHealing, hasEffect: this.hasEffect, hasSave: this.hasSave, - onSave: this.save?.damageMod, isDirect: !!this.damage?.direct, selectedRollMode: game.settings.get('core', 'rollMode'), data: this.getRollData(), diff --git a/module/data/actor/base.mjs b/module/data/actor/base.mjs index 08308eab..b90361e2 100644 --- a/module/data/actor/base.mjs +++ b/module/data/actor/base.mjs @@ -27,7 +27,7 @@ const resistanceField = (resistanceLabel, immunityLabel, reductionLabel) => }); /* Common rules applying to Characters and Adversaries */ -export const commonActorRules = (extendedData = { damageReduction: {}, attack: { damage: {} } }) => ({ +export const commonActorRules = (extendedData = { damageReduction: {} }) => ({ conditionImmunities: new fields.SchemaField({ hidden: new fields.BooleanField({ initial: false }), restrained: new fields.BooleanField({ initial: false }), @@ -41,23 +41,7 @@ export const commonActorRules = (extendedData = { damageReduction: {}, attack: { magical: new fields.NumberField({ initial: 0, min: 0 }), physical: new fields.NumberField({ initial: 0, min: 0 }) }), - ...(extendedData.damageReduction ?? {}) - }), - attack: new fields.SchemaField({ - ...extendedData.attack, - damage: new fields.SchemaField({ - hpDamageMultiplier: new fields.NumberField({ - required: true, - nullable: false, - initial: 1 - }), - hpDamageTakenMultiplier: new fields.NumberField({ - required: true, - nullable: false, - initial: 1 - }), - ...(extendedData.attack?.damage ?? {}) - }) + ...extendedData.damageReduction }) }); diff --git a/module/data/actor/character.mjs b/module/data/actor/character.mjs index e8da2e10..897c4790 100644 --- a/module/data/actor/character.mjs +++ b/module/data/actor/character.mjs @@ -253,35 +253,35 @@ export default class DhCharacter extends BaseDataActor { hint: 'DAGGERHEART.GENERAL.Rules.damageReduction.increasePerArmorMark.hint' }), disabledArmor: new fields.BooleanField({ intial: false }) - }, - attack: { - damage: { - diceIndex: new fields.NumberField({ - integer: true, - min: 0, - max: 5, - initial: 0, - label: 'DAGGERHEART.GENERAL.Rules.attack.damage.dice.label', - hint: 'DAGGERHEART.GENERAL.Rules.attack.damage.dice.hint' - }), - bonus: new fields.NumberField({ - required: true, - initial: 0, - min: 0, - label: 'DAGGERHEART.GENERAL.Rules.attack.damage.bonus.label' - }) - }, - roll: new fields.SchemaField({ - trait: new fields.StringField({ - required: true, - choices: CONFIG.DH.ACTOR.abilities, - nullable: true, - initial: null, - label: 'DAGGERHEART.GENERAL.Rules.attack.roll.trait.label' - }) - }) } }), + attack: new fields.SchemaField({ + damage: new fields.SchemaField({ + diceIndex: new fields.NumberField({ + integer: true, + min: 0, + max: 5, + initial: 0, + label: 'DAGGERHEART.GENERAL.Rules.attack.damage.dice.label', + hint: 'DAGGERHEART.GENERAL.Rules.attack.damage.dice.hint' + }), + bonus: new fields.NumberField({ + required: true, + initial: 0, + min: 0, + label: 'DAGGERHEART.GENERAL.Rules.attack.damage.bonus.label' + }) + }), + roll: new fields.SchemaField({ + trait: new fields.StringField({ + required: true, + choices: CONFIG.DH.ACTOR.abilities, + nullable: true, + initial: null, + label: 'DAGGERHEART.GENERAL.Rules.attack.roll.trait.label' + }) + }) + }), dualityRoll: new fields.SchemaField({ defaultHopeDice: new fields.NumberField({ nullable: false, @@ -368,7 +368,7 @@ export default class DhCharacter extends BaseDataActor { const modifiers = subClasses ?.map(sc => ({ ...this.traits[sc.system.spellcastingTrait], key: sc.system.spellcastingTrait })) .filter(x => x); - return modifiers.sort((a, b) => (b.value ?? 0) - (a.value ?? 0))[0]; + return modifiers.sort((a, b) => a.value - b.value)[0]; } get spellcastModifier() { @@ -549,18 +549,7 @@ export default class DhCharacter extends BaseDataActor { } get deathMoveViable() { - const { characterDefault } = game.settings.get( - CONFIG.DH.id, - CONFIG.DH.SETTINGS.gameSettings.Automation - ).defeated; - const deathMoveOutcomeStatuses = Object.keys(CONFIG.DH.GENERAL.defeatedConditionChoices).filter( - key => key !== characterDefault - ); - const deathMoveNotResolved = this.parent.statuses.every(status => !deathMoveOutcomeStatuses.includes(status)); - - const allHitPointsMarked = - this.resources.hitPoints.max > 0 && this.resources.hitPoints.value >= this.resources.hitPoints.max; - return deathMoveNotResolved && allHitPointsMarked; + return this.resources.hitPoints.max > 0 && this.resources.hitPoints.value >= this.resources.hitPoints.max; } get armorApplicableDamageTypes() { @@ -682,8 +671,6 @@ export default class DhCharacter extends BaseDataActor { } } } - - this.companion.system.attack.roll.bonus = this.traits.instinct.value; } this.resources.hope.value = Math.min(baseHope, this.resources.hope.max); diff --git a/module/data/fields/action/damageField.mjs b/module/data/fields/action/damageField.mjs index ef91c64e..bb81c702 100644 --- a/module/data/fields/action/damageField.mjs +++ b/module/data/fields/action/damageField.mjs @@ -105,22 +105,12 @@ export default class DamageField extends fields.SchemaField { damagePromises.push( actor.takeHealing(config.damage).then(updates => targetDamage.push({ token, updates })) ); - else { - const configDamage = foundry.utils.deepClone(config.damage); - const hpDamageMultiplier = config.actionActor?.system.rules.attack.damage.hpDamageMultiplier ?? 1; - const hpDamageTakenMultiplier = actor.system.rules.attack.damage.hpDamageTakenMultiplier; - if (configDamage.hitPoints) { - for (const part of configDamage.hitPoints.parts) { - part.total = Math.ceil(part.total * hpDamageMultiplier * hpDamageTakenMultiplier); - } - } - + else damagePromises.push( actor - .takeDamage(configDamage, config.isDirect) + .takeDamage(config.damage, config.isDirect) .then(updates => targetDamage.push({ token, updates })) ); - } } Promise.all(damagePromises).then(async _ => { diff --git a/module/data/item/base.mjs b/module/data/item/base.mjs index 84f39103..2399b7db 100644 --- a/module/data/item/base.mjs +++ b/module/data/item/base.mjs @@ -147,7 +147,7 @@ export default class BaseDataItem extends foundry.abstract.TypeDataModel { return await foundry.applications.ux.TextEditor.implementation.enrichHTML(fullDescription, { relativeTo: this, rollData: this.getRollData(), - secrets: this.parent.isOwner + secrets: this.isOwner }); } diff --git a/module/data/registeredTriggers.mjs b/module/data/registeredTriggers.mjs index ee4f3b49..8a100585 100644 --- a/module/data/registeredTriggers.mjs +++ b/module/data/registeredTriggers.mjs @@ -20,7 +20,6 @@ export default class RegisteredTriggers extends Map { } registerItemTriggers(item, registerOverride) { - if (!item.actor || !item._stats.createdTime) return; for (const action of item.system.actions ?? []) { if (!action.actor) continue; @@ -72,21 +71,10 @@ export default class RegisteredTriggers extends Map { } } - unregisterSceneEnvironmentTriggers(flagSystemData) { - const sceneData = new game.system.api.data.scenes.DHScene(flagSystemData); - for (const environment of sceneData.sceneEnvironments) { - if (environment.pack) continue; - this.unregisterItemTriggers(environment.system.features); - } - } - unregisterSceneTriggers(scene) { - this.unregisterSceneEnvironmentTriggers(scene.flags.daggerheart); - for (const triggerKey of Object.keys(CONFIG.DH.TRIGGER.triggers)) { const existingTrigger = this.get(triggerKey); if (!existingTrigger) continue; - const filtered = new Map(); for (const [uuid, data] of existingTrigger.entries()) { if (!uuid.startsWith(scene.uuid)) filtered.set(uuid, data); @@ -95,17 +83,14 @@ export default class RegisteredTriggers extends Map { } } - registerSceneEnvironmentTriggers(flagSystemData) { - const sceneData = new game.system.api.data.scenes.DHScene(flagSystemData); - for (const environment of sceneData.sceneEnvironments) { - for (const feature of environment.system.features) { - if (feature) this.registerItemTriggers(feature, true); - } - } - } - registerSceneTriggers(scene) { - this.registerSceneEnvironmentTriggers(scene.flags.daggerheart); + /* TODO: Finish sceneEnvironment registration and unreg */ + // const systemData = new game.system.api.data.scenes.DHScene(scene.flags.daggerheart); + // for (const environment of systemData.sceneEnvironments) { + // for (const feature of environment.system.features) { + // if(feature) this.registerItemTriggers(feature, true); + // } + // } for (const actor of scene.tokens.filter(x => x.actor).map(x => x.actor)) { if (actor.prototypeToken.actorLink) continue; @@ -122,11 +107,13 @@ export default class RegisteredTriggers extends Map { if (!triggerSettings.enabled) return updates; const dualityTrigger = this.get(trigger); - if (dualityTrigger?.size) { - const triggerActors = ['character', 'adversary', 'environment']; + if (dualityTrigger) { + const tokenBoundActors = ['adversary', 'environment']; + const triggerActors = ['character', ...tokenBoundActors]; for (let [itemUuid, { actor: actorUuid, triggeringActorType, commands }] of dualityTrigger.entries()) { const actor = await foundry.utils.fromUuid(actorUuid); if (!actor || !triggerActors.includes(actor.type)) continue; + if (tokenBoundActors.includes(actor.type) && !actor.getActiveTokens().length) continue; const triggerData = CONFIG.DH.TRIGGER.triggers[trigger]; if (triggerData.usesActor && triggeringActorType !== 'any') { diff --git a/module/data/rollTable.mjs b/module/data/rollTable.mjs deleted file mode 100644 index 78f7e6dd..00000000 --- a/module/data/rollTable.mjs +++ /dev/null @@ -1,38 +0,0 @@ -import FormulaField from './fields/formulaField.mjs'; - -//Extra definitions for RollTable -export default class DhRollTable extends foundry.abstract.TypeDataModel { - static defineSchema() { - const fields = foundry.data.fields; - - return { - formulaName: new fields.StringField({ - required: true, - nullable: false, - initial: 'Roll Formula', - label: 'DAGGERHEART.ROLLTABLES.FIELDS.formulaName.label' - }), - altFormula: new fields.TypedObjectField( - new fields.SchemaField({ - name: new fields.StringField({ - required: true, - nullable: false, - initial: 'Roll Formula', - label: 'DAGGERHEART.ROLLTABLES.FIELDS.formulaName.label' - }), - formula: new FormulaField({ label: 'Formula Roll', initial: '1d20' }) - }) - ), - activeAltFormula: new fields.StringField({ nullable: true, initial: null }) - }; - } - - getActiveFormula(baseFormula) { - return this.activeAltFormula ? (this.altFormula[this.activeAltFormula]?.formula ?? baseFormula) : baseFormula; - } - - static getDefaultFormula = () => ({ - name: game.i18n.localize('Roll Formula'), - formula: '1d20' - }); -} diff --git a/module/data/settings/Automation.mjs b/module/data/settings/Automation.mjs index 436f0eb7..bff0bae9 100644 --- a/module/data/settings/Automation.mjs +++ b/module/data/settings/Automation.mjs @@ -58,7 +58,7 @@ export default class DhAutomation extends foundry.abstract.DataModel { defeated: new fields.SchemaField({ enabled: new fields.BooleanField({ required: true, - initial: true, + initial: false, label: 'DAGGERHEART.SETTINGS.Automation.FIELDS.defeated.enabled.label' }), overlay: new fields.BooleanField({ @@ -69,7 +69,7 @@ export default class DhAutomation extends foundry.abstract.DataModel { characterDefault: new fields.StringField({ required: true, choices: CONFIG.DH.GENERAL.defeatedConditionChoices, - initial: CONFIG.DH.GENERAL.defeatedConditionChoices.deathMove.id, + initial: CONFIG.DH.GENERAL.defeatedConditionChoices.unconscious.id, label: 'DAGGERHEART.SETTINGS.Automation.FIELDS.defeated.characterDefault.label' }), adversaryDefault: new fields.StringField({ @@ -84,29 +84,23 @@ export default class DhAutomation extends foundry.abstract.DataModel { initial: CONFIG.DH.GENERAL.defeatedConditionChoices.defeated.id, label: 'DAGGERHEART.SETTINGS.Automation.FIELDS.defeated.companionDefault.label' }), - deathMoveIcon: new fields.FilePathField({ - initial: 'icons/magic/life/heart-cross-purple-orange.webp', - categories: ['IMAGE'], - base64: false, - label: 'DAGGERHEART.SETTINGS.Automation.FIELDS.defeated.deathMove.label' - }), deadIcon: new fields.FilePathField({ initial: 'icons/magic/death/grave-tombstone-glow-teal.webp', categories: ['IMAGE'], base64: false, - label: 'DAGGERHEART.SETTINGS.Automation.FIELDS.defeated.dead.label' + label: 'Dead' }), defeatedIcon: new fields.FilePathField({ initial: 'icons/magic/control/fear-fright-mask-orange.webp', categories: ['IMAGE'], base64: false, - label: 'DAGGERHEART.SETTINGS.Automation.FIELDS.defeated.defeated.label' + label: 'Defeated' }), unconsciousIcon: new fields.FilePathField({ initial: 'icons/magic/control/sleep-bubble-purple.webp', categories: ['IMAGE'], base64: false, - label: 'DAGGERHEART.SETTINGS.Automation.FIELDS.defeated.unconscious.label' + label: 'Unconcious' }) }), roll: new fields.SchemaField({ diff --git a/module/dice/d20Roll.mjs b/module/dice/d20Roll.mjs index f117ff65..3ddd8027 100644 --- a/module/dice/d20Roll.mjs +++ b/module/dice/d20Roll.mjs @@ -99,14 +99,11 @@ export default class D20Roll extends DHRoll { this.options.roll.modifiers = this.applyBaseBonus(); - const actorExperiences = this.options.roll.companionRoll - ? (this.options.data?.companion?.system.experiences ?? {}) - : (this.options.data.system?.experiences ?? {}); this.options.experiences?.forEach(m => { - if (actorExperiences[m]) + if (this.options.data.system?.experiences?.[m]) this.options.roll.modifiers.push({ - label: actorExperiences[m].name, - value: actorExperiences[m].value + label: this.options.data.system.experiences[m].name, + value: this.options.data.system.experiences[m].value }); }); diff --git a/module/dice/dhRoll.mjs b/module/dice/dhRoll.mjs index 1977c7ea..a5ac5091 100644 --- a/module/dice/dhRoll.mjs +++ b/module/dice/dhRoll.mjs @@ -3,7 +3,7 @@ import D20RollDialog from '../applications/dialogs/d20RollDialog.mjs'; export default class DHRoll extends Roll { baseTerms = []; constructor(formula, data = {}, options = {}) { - super(formula, data, foundry.utils.mergeObject(options, { roll: [] }, { overwrite: false })); + super(formula, data, options); options.bonusEffects = this.bonusEffectBuilder(); if (!this.data || !Object.keys(this.data).length) this.data = options.data; } diff --git a/module/dice/dualityRoll.mjs b/module/dice/dualityRoll.mjs index e65d0ff5..0edbe5ad 100644 --- a/module/dice/dualityRoll.mjs +++ b/module/dice/dualityRoll.mjs @@ -274,7 +274,7 @@ export default class DualityRoll extends D20Roll { } static async handleTriggers(roll, config) { - if (!config.source?.actor || config.skips?.triggers) return; + if (!config.source?.actor) return; const updates = []; const dualityUpdates = await game.system.registeredTriggers.runTrigger( diff --git a/module/documents/_module.mjs b/module/documents/_module.mjs index b9cfd3f2..8073cfe1 100644 --- a/module/documents/_module.mjs +++ b/module/documents/_module.mjs @@ -4,7 +4,6 @@ export { default as DhpCombat } from './combat.mjs'; export { default as DHCombatant } from './combatant.mjs'; export { default as DhActiveEffect } from './activeEffect.mjs'; export { default as DhChatMessage } from './chatMessage.mjs'; -export { default as DhRollTable } from './rollTable.mjs'; export { default as DhScene } from './scene.mjs'; export { default as DhToken } from './token.mjs'; export { default as DhTooltipManager } from './tooltipManager.mjs'; diff --git a/module/documents/actor.mjs b/module/documents/actor.mjs index e8bea0bf..1616c496 100644 --- a/module/documents/actor.mjs +++ b/module/documents/actor.mjs @@ -612,7 +612,7 @@ export default class DhpActor extends Actor { if (!updates.length) return; const hpDamage = updates.find(u => u.key === CONFIG.DH.GENERAL.healingTypes.hitPoints.id); - if (hpDamage?.value) { + if (hpDamage) { hpDamage.value = this.convertDamageToThreshold(hpDamage.value); if ( this.type === 'character' && @@ -854,8 +854,8 @@ export default class DhpActor extends Actor { async toggleDefeated(defeatedState) { const settings = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation).defeated; - const { deathMove, unconscious, defeated, dead } = CONFIG.DH.GENERAL.conditions(); - const defeatedConditions = new Set([deathMove.id, unconscious.id, defeated.id, dead.id]); + const { unconscious, defeated, dead } = CONFIG.DH.GENERAL.conditions(); + const defeatedConditions = new Set([unconscious.id, defeated.id, dead.id]); if (!defeatedState) { for (let defeatedId of defeatedConditions) { await this.toggleStatusEffect(defeatedId, { overlay: settings.overlay, active: defeatedState }); @@ -869,18 +869,6 @@ export default class DhpActor extends Actor { } } - async setDeathMoveDefeated(defeatedIconId) { - const settings = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation).defeated; - const actorDefault = settings[`${this.type}Default`]; - if (!settings.enabled || !settings.enabled || !actorDefault || actorDefault === defeatedIconId) return; - - for (let defeatedId of Object.keys(CONFIG.DH.GENERAL.defeatedConditionChoices)) { - await this.toggleStatusEffect(defeatedId, { overlay: settings.overlay, active: false }); - } - - if (defeatedIconId) await this.toggleStatusEffect(defeatedIconId, { overlay: settings.overlay, active: true }); - } - queueScrollText(scrollingTextData) { this.#scrollTextQueue.push(...scrollingTextData.map(data => () => createScrollText(this, data))); if (!this.#scrollTextInterval) { diff --git a/module/documents/chatMessage.mjs b/module/documents/chatMessage.mjs index 1d2c6c41..e03c3cf0 100644 --- a/module/documents/chatMessage.mjs +++ b/module/documents/chatMessage.mjs @@ -188,7 +188,7 @@ export default class DhpChatMessage extends foundry.documents.ChatMessage { config = foundry.utils.deepClone(this.system); config.event = event; - if (config.hasSave) { + if (this.system.onSave) { const pendingingSaves = targets.filter(t => t.saved.success === null); if (pendingingSaves.length) { const confirm = await foundry.applications.api.DialogV2.confirm({ diff --git a/module/documents/rollTable.mjs b/module/documents/rollTable.mjs deleted file mode 100644 index 50b8fe63..00000000 --- a/module/documents/rollTable.mjs +++ /dev/null @@ -1,122 +0,0 @@ -export default class DhRollTable extends foundry.documents.RollTable { - async roll({ selectedFormula, roll, recursive = true, _depth = 0 } = {}) { - // Prevent excessive recursion - if (_depth > 5) { - throw new Error(`Maximum recursion depth exceeded when attempting to draw from RollTable ${this.id}`); - } - - const formula = selectedFormula ?? this.formula; - - // If there is no formula, automatically calculate an even distribution - if (!this.formula) { - await this.normalize(); - } - - // Reference the provided roll formula - roll = roll instanceof Roll ? roll : Roll.create(formula); - let results = []; - - // Ensure that at least one non-drawn result remains - const available = this.results.filter(r => !r.drawn); - if (!available.length) { - ui.notifications.warn(game.i18n.localize('TABLE.NoAvailableResults')); - return { roll, results }; - } - - // Ensure that results are available within the minimum/maximum range - const minRoll = (await roll.reroll({ minimize: true })).total; - const maxRoll = (await roll.reroll({ maximize: true })).total; - const availableRange = available.reduce( - (range, result) => { - const r = result.range; - if (!range[0] || r[0] < range[0]) range[0] = r[0]; - if (!range[1] || r[1] > range[1]) range[1] = r[1]; - return range; - }, - [null, null] - ); - if (availableRange[0] > maxRoll || availableRange[1] < minRoll) { - ui.notifications.warn('No results can possibly be drawn from this table and formula.'); - return { roll, results }; - } - - // Continue rolling until one or more results are recovered - let iter = 0; - while (!results.length) { - if (iter >= 10000) { - ui.notifications.error( - `Failed to draw an available entry from Table ${this.name}, maximum iteration reached` - ); - break; - } - roll = await roll.reroll(); - results = this.getResultsForRoll(roll.total); - iter++; - } - - // Draw results recursively from any inner Roll Tables - if (recursive) { - const inner = []; - for (const result of results) { - const { type, documentUuid } = result; - const documentName = foundry.utils.parseUuid(documentUuid)?.type; - if (type === 'document' && documentName === 'RollTable') { - const innerTable = await fromUuid(documentUuid); - if (innerTable) { - const innerRoll = await innerTable.roll({ _depth: _depth + 1 }); - inner.push(...innerRoll.results); - } - } else inner.push(result); - } - results = inner; - } - - // Return the Roll and the results - return { roll, results }; - } - - async toMessage(results, { roll, messageData = {}, messageOptions = {} } = {}) { - messageOptions.rollMode ??= game.settings.get('core', 'rollMode'); - - // Construct chat data - messageData = foundry.utils.mergeObject( - { - author: game.user.id, - speaker: foundry.documents.ChatMessage.implementation.getSpeaker(), - rolls: [], - sound: roll ? CONFIG.sounds.dice : null, - flags: { 'core.RollTable': this.id } - }, - messageData - ); - if (roll) messageData.rolls.push(roll); - - // Render the chat card which combines the dice roll with the drawn results - const detailsPromises = await Promise.allSettled(results.map(r => r.getHTML())); - const flavorKey = `TABLE.DrawFlavor${results.length > 1 ? 'Plural' : ''}`; - const flavor = game.i18n.format(flavorKey, { - number: results.length, - name: foundry.utils.escapeHTML(this.name) - }); - messageData.content = await foundry.applications.handlebars.renderTemplate(CONFIG.RollTable.resultTemplate, { - description: await TextEditor.implementation.enrichHTML(this.description, { - documents: true, - secrets: this.isOwner - }), - flavor: flavor, - results: results.map((result, i) => { - const r = result.toObject(false); - r.details = detailsPromises[i].value ?? ''; - const useTableIcon = - result.icon === CONFIG.RollTable.resultIcon && this.img !== this.constructor.DEFAULT_ICON; - r.icon = useTableIcon ? this.img : result.icon; - return r; - }), - rollHTML: this.displayRoll && roll ? await roll.render() : null, - table: this - }); - - // Create the chat message - return foundry.documents.ChatMessage.implementation.create(messageData, messageOptions); - } -} diff --git a/module/documents/scene.mjs b/module/documents/scene.mjs index 9e2a3f5b..7f880b1d 100644 --- a/module/documents/scene.mjs +++ b/module/documents/scene.mjs @@ -51,27 +51,6 @@ export default class DhScene extends Scene { } } - async _preUpdate(changes, options, user) { - const allowed = await super._preUpdate(changes, options, user); - if (allowed === false) return false; - - if (changes.flags?.daggerheart) { - if (this._source.flags.daggerheart) { - const unregisterTriggerData = this._source.flags.daggerheart.sceneEnvironments.reduce( - (acc, env) => { - if (!changes.flags.daggerheart.sceneEnvironments.includes(env)) acc.sceneEnvironments.push(env); - - return acc; - }, - { ...this._source.flags.daggerheart, sceneEnvironments: [] } - ); - game.system.registeredTriggers.unregisterSceneEnvironmentTriggers(unregisterTriggerData); - } - - game.system.registeredTriggers.registerSceneEnvironmentTriggers(changes.flags.daggerheart); - } - } - _onDelete(options, userId) { super._onDelete(options, userId); diff --git a/module/enrichers/DualityRollEnricher.mjs b/module/enrichers/DualityRollEnricher.mjs index 91149fd8..f6f022f9 100644 --- a/module/enrichers/DualityRollEnricher.mjs +++ b/module/enrichers/DualityRollEnricher.mjs @@ -47,7 +47,6 @@ function getDualityMessage(roll, flavor) { ${roll?.trait && abilities[roll.trait] ? `data-trait="${roll.trait}"` : ''} ${roll?.advantage ? 'data-advantage="true"' : ''} ${roll?.disadvantage ? 'data-disadvantage="true"' : ''} - ${roll?.grantResources ? 'data-grant-resources="true"' : ''} > ${roll?.reaction ? '' : ''} ${label} @@ -64,8 +63,7 @@ export const renderDualityButton = async event => { traitValue = button.dataset.trait?.toLowerCase(), target = getCommandTarget({ allowNull: true }), difficulty = button.dataset.difficulty, - advantage = button.dataset.advantage ? Number(button.dataset.advantage) : undefined, - grantResources = Boolean(button.dataset?.grantResources); + advantage = button.dataset.advantage ? Number(button.dataset.advantage) : undefined; await enrichedDualityRoll( { @@ -75,15 +73,14 @@ export const renderDualityButton = async event => { difficulty, title: button.dataset.title, label: button.dataset.label, - advantage, - grantResources + advantage }, event ); }; export const enrichedDualityRoll = async ( - { reaction, traitValue, target, difficulty, title, label, advantage, grantResources, customConfig }, + { reaction, traitValue, target, difficulty, title, label, advantage, customConfig }, event ) => { const config = { @@ -96,18 +93,13 @@ export const enrichedDualityRoll = async ( advantage, type: reaction ? 'reaction' : null }, - skips: { - resources: !grantResources, - triggers: !grantResources - }, type: 'trait', hasRoll: true, ...(customConfig ?? {}) }; if (target) { - const result = await target.diceRoll(config); - result.resourceUpdates.updateResources(); + await target.diceRoll(config); } else { // For no target, call DualityRoll directly with basic data config.data = { experiences: {}, traits: {}, rules: {} }; diff --git a/module/systemRegistration/migrations.mjs b/module/systemRegistration/migrations.mjs index 743d42a4..b3116459 100644 --- a/module/systemRegistration/migrations.mjs +++ b/module/systemRegistration/migrations.mjs @@ -210,42 +210,6 @@ export async function runMigrations() { lastMigrationVersion = '1.2.7'; } - - if (foundry.utils.isNewerVersion('1.5.5', lastMigrationVersion)) { - /* Clear out Environments that were added directly from compendium */ - for (const scene of game.scenes) { - if (!scene.flags.daggerheart) continue; - const systemData = new game.system.api.data.scenes.DHScene(scene.flags.daggerheart); - const sceneEnvironments = systemData.sceneEnvironments; - - const newEnvironments = sceneEnvironments.filter(x => !x?.pack); - if (newEnvironments.length !== sceneEnvironments.length) - await scene.update({ 'flags.daggerheart.sceneEnvironments': newEnvironments }); - } - - ui.nav.render(true); - - lastMigrationVersion = '1.5.5'; - } - - if (foundry.utils.isNewerVersion('1.6.0', lastMigrationVersion)) { - /* Delevel any companions that are higher level than their partner character */ - for (const companion of game.actors.filter(x => x.type === 'companion')) { - if (companion.system.levelData.level.current <= 1) continue; - - if (!companion.system.partner) { - await companion.updateLevel(1); - } else { - const endLevel = companion.system.partner.system.levelData.level.current; - if (endLevel < companion.system.levelData.level.current) { - companion.system.levelData.level.changed = companion.system.levelData.level.current; - await companion.updateLevel(endLevel); - } - } - } - - lastMigrationVersion = '1.6.0'; - } //#endregion await game.settings.set(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.LastMigrationVersion, lastMigrationVersion); diff --git a/src/packs/adversaries/adversary_Demon_of_Despair_kE4dfhqmIQpNd44e.json b/src/packs/adversaries/adversary_Demon_of_Despair_kE4dfhqmIQpNd44e.json index 830848c3..188b2687 100644 --- a/src/packs/adversaries/adversary_Demon_of_Despair_kE4dfhqmIQpNd44e.json +++ b/src/packs/adversaries/adversary_Demon_of_Despair_kE4dfhqmIQpNd44e.json @@ -235,51 +235,7 @@ }, "_id": "2ESeh4tPhr6DI5ty", "img": "icons/magic/death/skull-horned-worn-fire-blue.webp", - "effects": [ - { - "name": "Depths Of Despair", - "type": "base", - "system": { - "rangeDependence": { - "enabled": false, - "type": "withinRange", - "target": "hostile", - "range": "melee" - } - }, - "_id": "nofxm1vGZ2TmceA2", - "img": "icons/magic/death/skull-horned-worn-fire-blue.webp", - "changes": [ - { - "key": "system.rules.attack.damage.hpDamageMultiplier", - "mode": 5, - "value": "2", - "priority": null - } - ], - "disabled": true, - "duration": { - "startTime": null, - "combat": null, - "seconds": null, - "rounds": null, - "turns": null, - "startRound": null, - "startTurn": null - }, - "description": "

The Demon of Despair deals double damage to PCs with 0 Hope.

", - "origin": null, - "tint": "#ffffff", - "transfer": true, - "statuses": [], - "sort": 0, - "flags": {}, - "_stats": { - "compendiumSource": null - }, - "_key": "!actors.items.effects!kE4dfhqmIQpNd44e.2ESeh4tPhr6DI5ty.nofxm1vGZ2TmceA2" - } - ], + "effects": [], "folder": null, "sort": 0, "ownership": { diff --git a/src/packs/adversaries/adversary_Failed_Experiment_ChwwVqowFw8hJQwT.json b/src/packs/adversaries/adversary_Failed_Experiment_ChwwVqowFw8hJQwT.json index 408d5102..39800002 100644 --- a/src/packs/adversaries/adversary_Failed_Experiment_ChwwVqowFw8hJQwT.json +++ b/src/packs/adversaries/adversary_Failed_Experiment_ChwwVqowFw8hJQwT.json @@ -304,51 +304,7 @@ }, "_id": "1fE6xo8yIOmZkGNE", "img": "icons/skills/melee/strike-slashes-orange.webp", - "effects": [ - { - "name": "Overwhelm", - "type": "base", - "system": { - "rangeDependence": { - "enabled": false, - "type": "withinRange", - "target": "hostile", - "range": "melee" - } - }, - "_id": "eGB9G0ljYCcdGbOx", - "img": "icons/skills/melee/strike-slashes-orange.webp", - "changes": [ - { - "key": "system.rules.attack.damage.hpDamageMultiplier", - "mode": 5, - "value": "2", - "priority": null - } - ], - "disabled": true, - "duration": { - "startTime": null, - "combat": null, - "seconds": null, - "rounds": null, - "turns": null, - "startRound": null, - "startTurn": null - }, - "description": "

When a target the Failed Experiment attacks has other adversaries within Very Close range, the Failed Experiment deals double damage.

", - "origin": null, - "tint": "#ffffff", - "transfer": true, - "statuses": [], - "sort": 0, - "flags": {}, - "_stats": { - "compendiumSource": null - }, - "_key": "!actors.items.effects!ChwwVqowFw8hJQwT.1fE6xo8yIOmZkGNE.eGB9G0ljYCcdGbOx" - } - ], + "effects": [], "folder": null, "sort": 0, "ownership": { diff --git a/src/packs/adversaries/adversary_Hallowed_Archer_kabueAo6BALApWqp.json b/src/packs/adversaries/adversary_Hallowed_Archer_kabueAo6BALApWqp.json index 8cce1b94..0abf1661 100644 --- a/src/packs/adversaries/adversary_Hallowed_Archer_kabueAo6BALApWqp.json +++ b/src/packs/adversaries/adversary_Hallowed_Archer_kabueAo6BALApWqp.json @@ -229,51 +229,7 @@ }, "_id": "FGJTAeL38zTVd4fA", "img": "icons/magic/control/buff-flight-wings-runes-red-yellow.webp", - "effects": [ - { - "name": "Punish the Guilty", - "type": "base", - "system": { - "rangeDependence": { - "enabled": false, - "type": "withinRange", - "target": "hostile", - "range": "melee" - } - }, - "_id": "ID85zoIa5GfhNMti", - "img": "icons/magic/control/buff-flight-wings-runes-red-yellow.webp", - "changes": [ - { - "key": "system.rules.attack.damage.hpDamageMultiplier", - "mode": 5, - "value": "2", - "priority": null - } - ], - "disabled": true, - "duration": { - "startTime": null, - "combat": null, - "seconds": null, - "rounds": null, - "turns": null, - "startRound": null, - "startTurn": null - }, - "description": "

The Hallowed Archer deals double damage to targets marked Guilty by a High Seraph.

", - "origin": null, - "tint": "#ffffff", - "transfer": true, - "statuses": [], - "sort": 0, - "flags": {}, - "_stats": { - "compendiumSource": null - }, - "_key": "!actors.items.effects!kabueAo6BALApWqp.FGJTAeL38zTVd4fA.ID85zoIa5GfhNMti" - } - ], + "effects": [], "folder": null, "sort": 0, "ownership": { diff --git a/src/packs/adversaries/adversary_Jagged_Knife_Kneebreaker_CBKixLH3yhivZZuL.json b/src/packs/adversaries/adversary_Jagged_Knife_Kneebreaker_CBKixLH3yhivZZuL.json index c38260e9..fc644604 100644 --- a/src/packs/adversaries/adversary_Jagged_Knife_Kneebreaker_CBKixLH3yhivZZuL.json +++ b/src/packs/adversaries/adversary_Jagged_Knife_Kneebreaker_CBKixLH3yhivZZuL.json @@ -336,14 +336,7 @@ "range": "melee" } }, - "changes": [ - { - "key": "system.rules.attack.damage.hpDamageTakenMultiplier", - "mode": 5, - "value": "2", - "priority": null - } - ], + "changes": [], "disabled": false, "duration": { "startTime": null, @@ -357,8 +350,8 @@ "description": "", "tint": "#ffffff", "statuses": [ - "vulnerable", - "restrained" + "restrained", + "vulnerable" ], "sort": 0, "flags": {}, diff --git a/src/packs/adversaries/adversary_Skeleton_Archer_7X5q7a6ueeHs5oA9.json b/src/packs/adversaries/adversary_Skeleton_Archer_7X5q7a6ueeHs5oA9.json index 9d837ac0..e5381f6f 100644 --- a/src/packs/adversaries/adversary_Skeleton_Archer_7X5q7a6ueeHs5oA9.json +++ b/src/packs/adversaries/adversary_Skeleton_Archer_7X5q7a6ueeHs5oA9.json @@ -230,51 +230,7 @@ "subType": null, "originId": null }, - "effects": [ - { - "name": "Opportunist", - "type": "base", - "system": { - "rangeDependence": { - "enabled": false, - "type": "withinRange", - "target": "hostile", - "range": "melee" - } - }, - "_id": "O03vYbyNLO3YPZGo", - "img": "icons/skills/targeting/crosshair-triple-strike-orange.webp", - "changes": [ - { - "key": "system.rules.attack.damage.hpDamageMultiplier", - "mode": 5, - "value": "2", - "priority": null - } - ], - "disabled": true, - "duration": { - "startTime": null, - "combat": null, - "seconds": null, - "rounds": null, - "turns": null, - "startRound": null, - "startTurn": null - }, - "description": "

When two or more adversaries are within Very Close range of a creature, all damage the Skeleton Archer deals to that creature is doubled.

", - "origin": null, - "tint": "#ffffff", - "transfer": true, - "statuses": [], - "sort": 0, - "flags": {}, - "_stats": { - "compendiumSource": null - }, - "_key": "!actors.items.effects!7X5q7a6ueeHs5oA9.6mL2FQ9pQdfoDNzG.O03vYbyNLO3YPZGo" - } - ], + "effects": [], "folder": null, "sort": 0, "ownership": { diff --git a/src/packs/communities/feature_Know_the_Tide_07x6Qe6qMzDw2xN4.json b/src/packs/communities/feature_Know_the_Tide_07x6Qe6qMzDw2xN4.json index 41f11a74..069fe6ba 100644 --- a/src/packs/communities/feature_Know_the_Tide_07x6Qe6qMzDw2xN4.json +++ b/src/packs/communities/feature_Know_the_Tide_07x6Qe6qMzDw2xN4.json @@ -9,47 +9,13 @@ "resource": { "type": "simple", "value": 0, - "max": "@system.levelData.level.current", - "icon": "fa-solid fa-water", - "recovery": "session", + "max": "", + "icon": "", + "recovery": null, "diceStates": {}, "dieFaces": "d4" }, - "actions": { - "tFlus34KotJjHfTe": { - "type": "effect", - "_id": "tFlus34KotJjHfTe", - "systemPath": "actions", - "baseAction": false, - "description": "", - "chatDisplay": true, - "originItem": { - "type": "itemCollection" - }, - "actionType": "action", - "triggers": [ - { - "trigger": "fearRoll", - "triggeringActorType": "self", - "command": "const { max, value } = this.item.system.resource;\nconst maxValue = actor.system.levelData.level.current;\nconst afterUpdate = value+1;\nif (afterUpdate > maxValue) return;\n\nui.notifications.info(game.i18n.localize('DAGGERHEART.UI.Notifications.knowTheTide'));\nreturn { updates: [{\n key: 'resource',\n itemId: this.item.id,\n target: this.item,\n value: 1,\n}]};" - } - ], - "cost": [], - "uses": { - "value": null, - "max": "", - "recovery": null, - "consumeOnSuccess": false - }, - "effects": [], - "target": { - "type": "any", - "amount": null - }, - "name": "Know The Tide", - "range": "" - } - }, + "actions": {}, "originItemType": null, "subType": null, "originId": null, diff --git a/src/packs/rolltables/tables_Consumables_tF04P02yVN1YDVel.json b/src/packs/rolltables/tables_Consumables_tF04P02yVN1YDVel.json index c3f5ffdc..c2413ec3 100644 --- a/src/packs/rolltables/tables_Consumables_tF04P02yVN1YDVel.json +++ b/src/packs/rolltables/tables_Consumables_tF04P02yVN1YDVel.json @@ -1,7 +1,7 @@ { "name": "Consumables", "img": "icons/consumables/potions/bottle-corked-red.webp", - "description": "", + "description": "

To generate a random consumable, choose a rarity, roll the designated dice, and match the total to the item in the table:

", "results": [ { "type": "document", @@ -1511,27 +1511,8 @@ "default": 0, "Bgvu4A6AMkRFOTGR": 3 }, - "flags": { - "daggerheart": { - "activeAltFormula": "", - "formulaName": "Common", - "altFormula": { - "uoUn5fRTUkyg6U2G": { - "name": "Uncommon", - "formula": "3d12" - }, - "FGxM2yoxUUUd9Eov": { - "name": "Rare", - "formula": "4d12" - }, - "HZ2hRBxu0k8IW0jC": { - "name": "Legendary", - "formula": "5d12" - } - } - } - }, - "formula": "2d12", + "flags": {}, + "formula": "1d60", "_id": "tF04P02yVN1YDVel", "sort": 300000, "_key": "!tables!tF04P02yVN1YDVel" diff --git a/src/packs/rolltables/tables_Loot_S61Shlt2I5CbLRjz.json b/src/packs/rolltables/tables_Loot_S61Shlt2I5CbLRjz.json index 2151ae81..9517eadd 100644 --- a/src/packs/rolltables/tables_Loot_S61Shlt2I5CbLRjz.json +++ b/src/packs/rolltables/tables_Loot_S61Shlt2I5CbLRjz.json @@ -1,7 +1,7 @@ { "name": "Loot", "img": "icons/commodities/treasure/brooch-gold-ruby.webp", - "description": "", + "description": "

To generate a random item, choose a rarity, roll the designated dice, and match the total to the item in the table:

", "results": [ { "type": "document", @@ -1511,27 +1511,8 @@ "default": 0, "Bgvu4A6AMkRFOTGR": 3 }, - "flags": { - "daggerheart": { - "activeAltFormula": "", - "formulaName": "Common", - "altFormula": { - "hJJtajaMk14bYM4X": { - "name": "Uncommon", - "formula": "3d12" - }, - "yDVeXdKpG7LzjHWa": { - "name": "Rare", - "formula": "4d12" - }, - "qPHNIuUgWAHauI6V": { - "name": "Legendary", - "formula": "5d12" - } - } - } - }, - "formula": "2d12", + "flags": {}, + "formula": "1d60", "_id": "S61Shlt2I5CbLRjz", "sort": 200000, "_key": "!tables!S61Shlt2I5CbLRjz" diff --git a/src/packs/rolltables/tables_Random_Objectives_I5L1dlgxXTNrCCkL.json b/src/packs/rolltables/tables_Table_of_Random_Objectives_I5L1dlgxXTNrCCkL.json similarity index 95% rename from src/packs/rolltables/tables_Random_Objectives_I5L1dlgxXTNrCCkL.json rename to src/packs/rolltables/tables_Table_of_Random_Objectives_I5L1dlgxXTNrCCkL.json index 9165f9d7..b10127e7 100644 --- a/src/packs/rolltables/tables_Random_Objectives_I5L1dlgxXTNrCCkL.json +++ b/src/packs/rolltables/tables_Table_of_Random_Objectives_I5L1dlgxXTNrCCkL.json @@ -1,7 +1,7 @@ { - "name": "Random Objectives", + "name": "Table of Random Objectives", "img": "icons/sundries/documents/document-torn-diagram-tan.webp", - "description": "", + "description": "

Layering Goals Other than Attrition into Combat

", "results": [ { "type": "text", @@ -311,20 +311,7 @@ "default": 0, "Bgvu4A6AMkRFOTGR": 3 }, - "flags": { - "daggerheart": { - "formulaName": "Roll Formula", - "altFormula": {}, - "activeAltFormula": null, - "flags": { - "daggerheart": { - "formulaName": "Roll Formula", - "altFormula": {}, - "activeAltFormula": null - } - } - } - }, + "flags": {}, "formula": "1d12", "_id": "I5L1dlgxXTNrCCkL", "sort": 400000, diff --git a/styles/less/dialog/character-reset/sheet.less b/styles/less/dialog/character-reset/sheet.less deleted file mode 100644 index 44312a3e..00000000 --- a/styles/less/dialog/character-reset/sheet.less +++ /dev/null @@ -1,27 +0,0 @@ -.daggerheart.dh-style.dialog.views.character-reset { - .character-reset-container { - display: flex; - flex-direction: column; - gap: 8px; - - legend { - padding: 0 4px; - } - - .character-reset-header { - font-size: var(--font-size-18); - text-align: center; - } - - .reset-data-container { - display: grid; - grid-template-columns: 3fr 2fr; - align-items: center; - gap: 4px; - - label { - font-weight: bold; - } - } - } -} diff --git a/styles/less/dialog/index.less b/styles/less/dialog/index.less index 733cdd1c..01a3f954 100644 --- a/styles/less/dialog/index.less +++ b/styles/less/dialog/index.less @@ -41,5 +41,3 @@ @import './settings/change-currency-icon.less'; @import './risk-it-all/sheet.less'; - -@import './character-reset/sheet.less'; diff --git a/styles/less/global/chat.less b/styles/less/global/chat.less index b9478ea4..dc671e44 100644 --- a/styles/less/global/chat.less +++ b/styles/less/global/chat.less @@ -15,14 +15,6 @@ .message-header .message-header-main .message-sub-header-container h4 { color: @dark-blue; } - - .message-content { - .table-draw { - .table-description { - color: @dark; - } - } - } } } @@ -91,7 +83,6 @@ .message-content { padding-bottom: 8px; - .flavor-text { font-size: var(--font-size-12); line-height: 20px; @@ -99,33 +90,6 @@ text-align: center; display: block; } - - .table-draw { - .table-flavor { - padding-top: 5px; - padding-bottom: 0.5rem; - font-size: var(--font-size-12); - } - - .table-description { - color: @beige; - font-style: italic; - - &.flavor-spaced { - padding-top: 0; - } - } - - .table-results { - .description { - flex-basis: min-content; - - > p:first-of-type { - margin-top: 0; - } - } - } - } } } } diff --git a/styles/less/hud/token-hud/token-hud.less b/styles/less/hud/token-hud/token-hud.less index ea58f673..46003975 100644 --- a/styles/less/hud/token-hud/token-hud.less +++ b/styles/less/hud/token-hud/token-hud.less @@ -24,13 +24,13 @@ font-weight: bold; } } - } - .clown-car img { - transition: 0.5s; + .clown-car img { + transition: 0.5s; - &.flipped { - transform: scaleX(-1); + &.flipped { + transform: scaleX(-1); + } } } diff --git a/styles/less/sheets/index.less b/styles/less/sheets/index.less index 1bdb451a..216cda33 100644 --- a/styles/less/sheets/index.less +++ b/styles/less/sheets/index.less @@ -40,5 +40,4 @@ @import './items/heritage.less'; @import './items/item-sheet-shared.less'; -@import './rollTables/sheet.less'; @import './actions/actions.less'; diff --git a/styles/less/sheets/rollTables/sheet.less b/styles/less/sheets/rollTables/sheet.less deleted file mode 100644 index a7c05455..00000000 --- a/styles/less/sheets/rollTables/sheet.less +++ /dev/null @@ -1,29 +0,0 @@ -.application.sheet.roll-table-sheet { - .formulas-section { - legend { - margin-left: auto; - margin-right: auto; - } - - .formulas-container { - display: grid; - grid-template-columns: 1fr 1fr 40px; - gap: 10px; - text-align: center; - - .formula-button { - width: 100%; - display: flex; - align-items: center; - justify-content: center; - } - } - } - - .roll-table-view-formula-container { - width: fit-content; - display: flex; - align-items: center; - gap: 4px; - } -} diff --git a/system.json b/system.json index 8624bab7..8e4d19d9 100644 --- a/system.json +++ b/system.json @@ -2,7 +2,7 @@ "id": "daggerheart", "title": "Daggerheart", "description": "An unofficial implementation of the Daggerheart system", - "version": "1.6.0", + "version": "1.5.4", "compatibility": { "minimum": "13.346", "verified": "13.351", diff --git a/templates/dialogs/characterReset.hbs b/templates/dialogs/characterReset.hbs deleted file mode 100644 index 298826e5..00000000 --- a/templates/dialogs/characterReset.hbs +++ /dev/null @@ -1,33 +0,0 @@ -
-
-
{{localize "DAGGERHEART.APPLICATIONS.CharacterReset.headerTitle"}}
- -
- {{localize "DAGGERHEART.APPLICATIONS.CharacterReset.alwaysDeleteSection"}} - -
- {{#each this.data.delete as | data key|}} -
- - -
- {{/each}} -
-
- -
- {{localize "DAGGERHEART.APPLICATIONS.CharacterReset.optionalDeleteSection"}} - -
- {{#each this.data.optional as | data key|}} -
- - -
- {{/each}} -
-
- - -
-
\ No newline at end of file diff --git a/templates/hud/tokenHUD.hbs b/templates/hud/tokenHUD.hbs index 1ba29621..f079e5d9 100644 --- a/templates/hud/tokenHUD.hbs +++ b/templates/hud/tokenHUD.hbs @@ -11,11 +11,6 @@ - {{#if hasCompanion}} - - {{/if}} {{#if canConfigure}} {{/if}} diff --git a/templates/settings/automation-settings/rules.hbs b/templates/settings/automation-settings/rules.hbs index 24f0b262..a12c2999 100644 --- a/templates/settings/automation-settings/rules.hbs +++ b/templates/settings/automation-settings/rules.hbs @@ -9,12 +9,11 @@ {{formGroup settingFields.schema.fields.defeated.fields.enabled value=settingFields._source.defeated.enabled localize=true}} - {{formGroup settingFields.schema.fields.defeated.fields.overlay value=settingFields._source.defeated.overlay localize=true}} + {{formGroup settingFields.schema.fields.defeated.fields.overlay value=settingFields._source.defeated.overlay localize=true}} {{formGroup settingFields.schema.fields.defeated.fields.characterDefault value=settingFields._source.defeated.characterDefault labelAttr="name" localize=true}} {{formGroup settingFields.schema.fields.defeated.fields.adversaryDefault value=settingFields._source.defeated.adversaryDefault labelAttr="name" localize=true}} {{formGroup settingFields.schema.fields.defeated.fields.companionDefault value=settingFields._source.defeated.companionDefault labelAttr="name" localize=true}} - {{formGroup settingFields.schema.fields.defeated.fields.deathMoveIcon value=settingFields._source.defeated.deathMoveIcon localize=true}} {{formGroup settingFields.schema.fields.defeated.fields.deadIcon value=settingFields._source.defeated.deadIcon localize=true}} {{formGroup settingFields.schema.fields.defeated.fields.defeatedIcon value=settingFields._source.defeated.defeatedIcon localize=true}} {{formGroup settingFields.schema.fields.defeated.fields.unconsciousIcon value=settingFields._source.defeated.unconsciousIcon localize=true}} diff --git a/templates/settings/homebrew-settings/downtime.hbs b/templates/settings/homebrew-settings/downtime.hbs index 25f4c95d..8612f3d5 100644 --- a/templates/settings/homebrew-settings/downtime.hbs +++ b/templates/settings/homebrew-settings/downtime.hbs @@ -10,7 +10,7 @@ {{localize "DAGGERHEART.APPLICATIONS.Downtime.longRest.title"}} - +
@@ -31,7 +31,7 @@ {{localize "DAGGERHEART.APPLICATIONS.Downtime.shortRest.title"}} - +
diff --git a/templates/settings/homebrew-settings/itemFeatures.hbs b/templates/settings/homebrew-settings/itemFeatures.hbs index df3419fa..22c23af6 100644 --- a/templates/settings/homebrew-settings/itemFeatures.hbs +++ b/templates/settings/homebrew-settings/itemFeatures.hbs @@ -8,7 +8,7 @@ {{localize "DAGGERHEART.GENERAL.weaponFeatures"}} - +
@@ -22,7 +22,7 @@ {{localize "DAGGERHEART.GENERAL.armorFeatures"}} - +
diff --git a/templates/sheets-settings/action-settings/base.hbs b/templates/sheets-settings/action-settings/base.hbs index 95c3cc50..65010903 100644 --- a/templates/sheets-settings/action-settings/base.hbs +++ b/templates/sheets-settings/action-settings/base.hbs @@ -11,6 +11,6 @@
{{localize "DAGGERHEART.GENERAL.description"}} - {{formInput fields.description value=source.description enriched=action.description name="description" toggled=true }} + {{formInput fields.description value=source.description enriched=source.description name="description" toggled=true }}
\ No newline at end of file diff --git a/templates/sheets/actors/character/sidebar.hbs b/templates/sheets/actors/character/sidebar.hbs index 24e68e02..0db2bf42 100644 --- a/templates/sheets/actors/character/sidebar.hbs +++ b/templates/sheets/actors/character/sidebar.hbs @@ -1,12 +1,12 @@