mirror of
https://github.com/Foundryborne/daggerheart.git
synced 2026-07-22 02:19:54 +02:00
Merge branch 'main' into weapon-tokens
This commit is contained in:
commit
7bbd250aec
454 changed files with 3347 additions and 4751 deletions
|
|
@ -315,15 +315,15 @@ export default class BeastformDialog extends HandlebarsApplicationMixin(Applicat
|
|||
|
||||
const beastformEffect = selected.effects.find(x => x.type === 'beastform');
|
||||
for (const traitBonus of app.modifications.traitBonuses) {
|
||||
const existingChange = beastformEffect.changes.find(
|
||||
const existingChange = beastformEffect.system.changes.find(
|
||||
x => x.key === `system.traits.${traitBonus.trait}.value`
|
||||
);
|
||||
if (existingChange) {
|
||||
existingChange.value = Number.parseInt(existingChange.value) + traitBonus.bonus;
|
||||
} else {
|
||||
beastformEffect.changes.push({
|
||||
beastformEffect.system.changes.push({
|
||||
key: `system.traits.${traitBonus.trait}.value`,
|
||||
mode: 2,
|
||||
type: 'add',
|
||||
priority: null,
|
||||
value: traitBonus.bonus
|
||||
});
|
||||
|
|
|
|||
|
|
@ -139,13 +139,15 @@ export default class DhDeathMove extends HandlebarsApplicationMixin(ApplicationV
|
|||
name: game.i18n.localize('DAGGERHEART.CONFIG.DeathMoves.blazeOfGlory.name'),
|
||||
description: game.i18n.localize('DAGGERHEART.CONFIG.DeathMoves.blazeOfGlory.description'),
|
||||
img: CONFIG.DH.GENERAL.deathMoves.blazeOfGlory.img,
|
||||
changes: [
|
||||
{
|
||||
key: 'system.rules.roll.guaranteedCritical',
|
||||
mode: 2,
|
||||
value: 'true'
|
||||
}
|
||||
]
|
||||
system: {
|
||||
changes: [
|
||||
{
|
||||
key: 'system.rules.roll.guaranteedCritical',
|
||||
type: 'add',
|
||||
value: 'true'
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]);
|
||||
|
||||
|
|
@ -183,8 +185,6 @@ export default class DhDeathMove extends HandlebarsApplicationMixin(ApplicationV
|
|||
|
||||
if (result === undefined) return;
|
||||
|
||||
const autoExpandDescription = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.appearance)
|
||||
.expandRollMessage?.desc;
|
||||
const cls = getDocumentClass('ChatMessage');
|
||||
|
||||
const msg = {
|
||||
|
|
@ -200,7 +200,6 @@ export default class DhDeathMove extends HandlebarsApplicationMixin(ApplicationV
|
|||
img: this.selectedMove.img,
|
||||
description: game.i18n.localize(this.selectedMove.description),
|
||||
result: result,
|
||||
open: autoExpandDescription ? 'open' : '',
|
||||
showRiskItAllButton: this.showRiskItAllButton,
|
||||
riskItAllButtonLabel: this.riskItAllButtonLabel,
|
||||
riskItAllHope: this.riskItAllHope
|
||||
|
|
|
|||
|
|
@ -196,9 +196,6 @@ export default class DhpDowntime extends HandlebarsApplicationMixin(ApplicationV
|
|||
.filter(x => x.testUserPermission(game.user, 'LIMITED'))
|
||||
.filter(x => x.uuid !== this.actor.uuid);
|
||||
|
||||
const autoExpandDescription = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.appearance)
|
||||
.expandRollMessage?.desc;
|
||||
|
||||
const cls = getDocumentClass('ChatMessage');
|
||||
const msg = {
|
||||
user: game.user.id,
|
||||
|
|
@ -219,8 +216,7 @@ export default class DhpDowntime extends HandlebarsApplicationMixin(ApplicationV
|
|||
actor: { name: this.actor.name, img: this.actor.img },
|
||||
moves: moves,
|
||||
characters: characters,
|
||||
selfId: this.actor.uuid,
|
||||
open: autoExpandDescription ? 'open' : ''
|
||||
selfId: this.actor.uuid
|
||||
}
|
||||
),
|
||||
flags: {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { ResourceUpdateMap } from '../../data/action/baseAction.mjs';
|
||||
import { shouldUseHopeFearAutomation } from '../../helpers/utils.mjs';
|
||||
import { emitGMUpdate, GMUpdateEvent, RefreshType, socketEvent } from '../../systemRegistration/socket.mjs';
|
||||
import Party from '../sheets/actors/party.mjs';
|
||||
import PartySheet from '../sheets/actors/party.mjs';
|
||||
|
||||
const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api;
|
||||
|
||||
|
|
@ -11,7 +11,7 @@ export default class GroupRollDialog extends HandlebarsApplicationMixin(Applicat
|
|||
|
||||
this.party = party;
|
||||
this.partyMembers = party.system.partyMembers
|
||||
.filter(x => Party.DICE_ROLL_ACTOR_TYPES.includes(x.type))
|
||||
.filter(x => PartySheet.DICE_ROLL_ACTOR_TYPES.includes(x.type))
|
||||
.map(member => ({
|
||||
...member.toObject(),
|
||||
uuid: member.uuid,
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import { ResourceUpdateMap } from '../../data/action/baseAction.mjs';
|
|||
import { MemberData } from '../../data/tagTeamData.mjs';
|
||||
import { getCritDamageBonus, shouldUseHopeFearAutomation } from '../../helpers/utils.mjs';
|
||||
import { emitGMUpdate, GMUpdateEvent, RefreshType, socketEvent } from '../../systemRegistration/socket.mjs';
|
||||
import Party from '../sheets/actors/party.mjs';
|
||||
import PartySheet from '../sheets/actors/party.mjs';
|
||||
|
||||
const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api;
|
||||
|
||||
|
|
@ -13,7 +13,7 @@ export default class TagTeamDialog extends HandlebarsApplicationMixin(Applicatio
|
|||
this.usesTagTeamHopeCost = true;
|
||||
this.party = party;
|
||||
this.partyMembers = party.system.partyMembers
|
||||
.filter(x => Party.DICE_ROLL_ACTOR_TYPES.includes(x.type))
|
||||
.filter(x => PartySheet.DICE_ROLL_ACTOR_TYPES.includes(x.type))
|
||||
.map(member => ({
|
||||
...member.toObject(),
|
||||
uuid: member.uuid,
|
||||
|
|
@ -208,6 +208,16 @@ export default class TagTeamDialog extends HandlebarsApplicationMixin(Applicatio
|
|||
|
||||
const rollOptions = [];
|
||||
const damageRollOptions = [];
|
||||
|
||||
if (actor?.system.usedUnarmed) {
|
||||
damageRollOptions.push({
|
||||
value: actor.system.attack.uuid,
|
||||
label: actor.system.usedUnarmed.name,
|
||||
group: actor.name,
|
||||
baseAction: actor.system.attack
|
||||
});
|
||||
}
|
||||
|
||||
for (const item of actor?.items ?? []) {
|
||||
if (!item.system.metadata.hasActions) continue;
|
||||
const actions = [...item.system.actions, ...(item.system.attack ? [item.system.attack] : [])];
|
||||
|
|
|
|||
|
|
@ -155,6 +155,10 @@ export default class DhActiveEffectConfig extends foundry.applications.sheets.Ac
|
|||
.querySelector('.stacking-change-checkbox')
|
||||
?.addEventListener('change', this.stackingChangeToggle.bind(this));
|
||||
|
||||
htmlElement
|
||||
.querySelector('.range-dependence-change-checkbox')
|
||||
?.addEventListener('change', this.rangeDependenceChangeToggle.bind(this));
|
||||
|
||||
htmlElement
|
||||
.querySelector('.armor-change-checkbox')
|
||||
?.addEventListener('change', this.armorChangeToggle.bind(this));
|
||||
|
|
@ -224,6 +228,20 @@ export default class DhActiveEffectConfig extends foundry.applications.sheets.Ac
|
|||
return this.submit({ updateData: { system: systemData } });
|
||||
}
|
||||
|
||||
rangeDependenceChangeToggle(event) {
|
||||
const rangeFields = this.document.system.schema.fields.rangeDependence.fields;
|
||||
const systemData = {
|
||||
rangeDependence: event.target.checked
|
||||
? _replace({
|
||||
type: rangeFields.type.initial,
|
||||
target: rangeFields.target.initial,
|
||||
range: rangeFields.range.initial
|
||||
})
|
||||
: null
|
||||
};
|
||||
return this.submit({ updateData: { system: systemData } });
|
||||
}
|
||||
|
||||
armorChangeToggle(event) {
|
||||
if (event.target.checked) {
|
||||
this.addArmorChange();
|
||||
|
|
|
|||
10
module/applications/sheets/actors/_types.d.ts
vendored
10
module/applications/sheets/actors/_types.d.ts
vendored
|
|
@ -1,8 +1,18 @@
|
|||
import DhCompanion from '../../../data/actor/companion.mjs';
|
||||
import DhParty from '../../../data/actor/party.mjs';
|
||||
import DhpActor from '../../../documents/actor.mjs';
|
||||
|
||||
declare module './companion.mjs' {
|
||||
export default interface DhCompanionSheet {
|
||||
actor: DhpActor<DhCompanion>;
|
||||
document: DhpActor<DhCompanion>;
|
||||
}
|
||||
}
|
||||
|
||||
declare module './party.mjs' {
|
||||
export default interface PartySheet {
|
||||
actor: DhpActor<DhParty>;
|
||||
document: DhpActor<DhParty>;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -914,7 +914,7 @@ export default class CharacterSheet extends DHBaseActorSheet {
|
|||
const doc = await getDocFromElement(button);
|
||||
const { available } = this.document.system.loadoutSlot;
|
||||
if (doc.system.inVault && !available && !doc.system.loadoutIgnore) {
|
||||
return ui.notifications.warn(game.i18n.localize('DAGGERHEART.UI.Notifications.loadoutMaxReached'));
|
||||
return ui.notifications.warn('DAGGERHEART.UI.Notifications.loadoutMaxReached', { localize: true });
|
||||
}
|
||||
|
||||
await doc?.update({ 'system.inVault': !doc.system.inVault });
|
||||
|
|
@ -1206,10 +1206,22 @@ export default class CharacterSheet extends DHBaseActorSheet {
|
|||
if (!confirmed) return;
|
||||
}
|
||||
|
||||
if (this.document.uuid === item.parent?.uuid) {
|
||||
// Check for same actor drag/drop attempts
|
||||
const isSameActor = this.document.uuid === item.parent?.uuid;
|
||||
const loadoutFieldset = event.target.closest('[data-in-vault]');
|
||||
const vaulting = loadoutFieldset?.dataset.inVault === 'true';
|
||||
if (isSameActor && loadoutFieldset && item.type === 'domainCard' && vaulting !== item.system.inVault) {
|
||||
// This is likely an attempt to vault or unvault an item
|
||||
const { available } = this.document.system.loadoutSlot;
|
||||
if (!vaulting && !available && !item.system.loadoutIgnore) {
|
||||
return ui.notifications.warn('DAGGERHEART.UI.Notifications.loadoutMaxReached', { localize: true });
|
||||
}
|
||||
return item.update({ 'system.inVault': vaulting });
|
||||
} else if (isSameActor) {
|
||||
return super._onDropItem(event, item);
|
||||
}
|
||||
|
||||
// Handle beastforms
|
||||
if (item.type === 'beastform') {
|
||||
if (this.document.effects.find(x => x.type === 'beastform')) {
|
||||
return ui.notifications.warn(
|
||||
|
|
|
|||
|
|
@ -6,7 +6,9 @@ import DaggerheartMenu from '../../sidebar/tabs/daggerheartMenu.mjs';
|
|||
import { socketEvent } from '../../../systemRegistration/socket.mjs';
|
||||
import DhpActor from '../../../documents/actor.mjs';
|
||||
|
||||
export default class Party extends DHBaseActorSheet {
|
||||
/**@typedef {import('@client/applications/_types.mjs').ApplicationClickAction} ApplicationClickAction */
|
||||
|
||||
export default class PartySheet extends DHBaseActorSheet {
|
||||
constructor(options) {
|
||||
super(options);
|
||||
|
||||
|
|
@ -24,17 +26,17 @@ export default class Party extends DHBaseActorSheet {
|
|||
resizable: true
|
||||
},
|
||||
actions: {
|
||||
openDocument: Party.#openDocument,
|
||||
deletePartyMember: Party.#deletePartyMember,
|
||||
toggleHope: Party.#toggleHope,
|
||||
toggleHitPoints: Party.#toggleHitPoints,
|
||||
toggleStress: Party.#toggleStress,
|
||||
toggleArmorSlot: Party.#toggleArmorSlot,
|
||||
tempBrowser: Party.#tempBrowser,
|
||||
refeshActions: Party.#refeshActions,
|
||||
triggerRest: Party.#triggerRest,
|
||||
tagTeamRoll: Party.#tagTeamRoll,
|
||||
groupRoll: Party.#groupRoll
|
||||
openDocument: PartySheet.#onOpenDocument,
|
||||
deletePartyMember: PartySheet.#onDeletePartyMember,
|
||||
toggleHope: PartySheet.#onToggleHope,
|
||||
toggleHitPoints: PartySheet.#onToggleHitPoints,
|
||||
toggleStress: PartySheet.#onToggleStress,
|
||||
toggleArmorSlot: PartySheet.#onToggleArmorSlot,
|
||||
tempBrowser: PartySheet.#onTempBrowser,
|
||||
refreshActions: PartySheet.#onRefreshActions,
|
||||
triggerRest: PartySheet.#onTriggerRest,
|
||||
tagTeamRoll: PartySheet.#onTagTeamRoll,
|
||||
groupRoll: PartySheet.#onGroupRoll
|
||||
},
|
||||
dragDrop: [{ dragSelector: '[data-item-id]', dropSelector: null }]
|
||||
};
|
||||
|
|
@ -72,6 +74,23 @@ export default class Party extends DHBaseActorSheet {
|
|||
this._createSearchFilter();
|
||||
}
|
||||
|
||||
/** @inheritdoc */
|
||||
_toggleDisabled(disabled) {
|
||||
// Overriden to only disable text inputs by default if the user is a member
|
||||
const isMember = this.actor.system.partyMembers.some(
|
||||
m => m.testUserPermission(game.user, CONST.DOCUMENT_OWNERSHIP_LEVELS.OWNER)
|
||||
);
|
||||
if (!isMember) return super._toggleDisabled(disabled);
|
||||
|
||||
const form = this.form;
|
||||
for (const input of form.querySelectorAll('input:not([type=search]), .editor.prosemirror')) {
|
||||
input.disabled = disabled;
|
||||
}
|
||||
for (const element of form.querySelectorAll('.input[contenteditable]')) {
|
||||
element.classList.toggle('disabled', disabled);
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
/* Prepare Context */
|
||||
/* -------------------------------------------- */
|
||||
|
|
@ -198,8 +217,16 @@ export default class Party extends DHBaseActorSheet {
|
|||
};
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
/* Event handlers */
|
||||
/* -------------------------------------------- */
|
||||
|
||||
static async #openDocument(_, target) {
|
||||
/**
|
||||
* @this PartySheet
|
||||
* @type {ApplicationClickAction}
|
||||
*/
|
||||
static async #onOpenDocument(_, target) {
|
||||
const uuid = target.dataset.uuid;
|
||||
const document = await foundry.utils.fromUuid(uuid);
|
||||
document?.sheet?.render(true);
|
||||
|
|
@ -207,9 +234,10 @@ export default class Party extends DHBaseActorSheet {
|
|||
|
||||
/**
|
||||
* Toggles a hope resource value.
|
||||
* @this PartySheet
|
||||
* @type {ApplicationClickAction}
|
||||
*/
|
||||
static async #toggleHope(_, target) {
|
||||
static async #onToggleHope(_, target) {
|
||||
const hopeValue = Number.parseInt(target.dataset.value);
|
||||
const actor = await foundry.utils.fromUuid(target.dataset.actorId);
|
||||
const newValue = actor.system.resources.hope.value >= hopeValue ? hopeValue - 1 : hopeValue;
|
||||
|
|
@ -219,9 +247,10 @@ export default class Party extends DHBaseActorSheet {
|
|||
|
||||
/**
|
||||
* Toggles a hp resource value.
|
||||
* @this PartySheet
|
||||
* @type {ApplicationClickAction}
|
||||
*/
|
||||
static async #toggleHitPoints(_, target) {
|
||||
static async #onToggleHitPoints(_, target) {
|
||||
const hitPointsValue = Number.parseInt(target.dataset.value);
|
||||
const actor = await foundry.utils.fromUuid(target.dataset.actorId);
|
||||
const newValue = actor.system.resources.hitPoints.value >= hitPointsValue ? hitPointsValue - 1 : hitPointsValue;
|
||||
|
|
@ -231,9 +260,10 @@ export default class Party extends DHBaseActorSheet {
|
|||
|
||||
/**
|
||||
* Toggles a stress resource value.
|
||||
* @this PartySheet
|
||||
* @type {ApplicationClickAction}
|
||||
*/
|
||||
static async #toggleStress(_, target) {
|
||||
static async #onToggleStress(_, target) {
|
||||
const stressValue = Number.parseInt(target.dataset.value);
|
||||
const actor = await foundry.utils.fromUuid(target.dataset.actorId);
|
||||
const newValue = actor.system.resources.stress.value >= stressValue ? stressValue - 1 : stressValue;
|
||||
|
|
@ -243,9 +273,10 @@ export default class Party extends DHBaseActorSheet {
|
|||
|
||||
/**
|
||||
* Toggles a armor slot resource value.
|
||||
* @this PartySheet
|
||||
* @type {ApplicationClickAction}
|
||||
*/
|
||||
static async #toggleArmorSlot(_, target) {
|
||||
static async #onToggleArmorSlot(_, target) {
|
||||
const actor = await foundry.utils.fromUuid(target.dataset.actorId);
|
||||
const { value, max } = actor.system.armorScore;
|
||||
const inputValue = Number.parseInt(target.dataset.value);
|
||||
|
|
@ -258,12 +289,19 @@ export default class Party extends DHBaseActorSheet {
|
|||
|
||||
/**
|
||||
* Opens Compedium Browser
|
||||
* @this PartySheet
|
||||
* @type {ApplicationClickAction}
|
||||
*/
|
||||
static async #tempBrowser(_, target) {
|
||||
static async #onTempBrowser(_, target) {
|
||||
new ItemBrowser().render({ force: true });
|
||||
}
|
||||
|
||||
static async #refeshActions() {
|
||||
/**
|
||||
* @todo Is this unused?
|
||||
* @this PartySheet
|
||||
* @type {ApplicationClickAction}
|
||||
*/
|
||||
static async #onRefreshActions() {
|
||||
const confirmed = await foundry.applications.api.DialogV2.confirm({
|
||||
window: {
|
||||
title: 'New Section',
|
||||
|
|
@ -281,7 +319,11 @@ export default class Party extends DHBaseActorSheet {
|
|||
if (!confirmed) return;
|
||||
}
|
||||
|
||||
static async #triggerRest(_, button) {
|
||||
/**
|
||||
* @this PartySheet
|
||||
* @type {ApplicationClickAction}
|
||||
*/
|
||||
static async #onTriggerRest(_, button) {
|
||||
const confirmed = await foundry.applications.api.DialogV2.confirm({
|
||||
window: {
|
||||
title: game.i18n.localize(`DAGGERHEART.APPLICATIONS.Downtime.${button.dataset.type}.title`),
|
||||
|
|
@ -304,6 +346,30 @@ export default class Party extends DHBaseActorSheet {
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @this PartySheet
|
||||
* @type {ApplicationClickAction}
|
||||
*/
|
||||
static async #onDeletePartyMember(event, target) {
|
||||
const doc = await foundry.utils.fromUuid(target.closest('[data-uuid]')?.dataset.uuid);
|
||||
if (!event.shiftKey) {
|
||||
const confirmed = await foundry.applications.api.DialogV2.confirm({
|
||||
window: {
|
||||
title: game.i18n.format('DAGGERHEART.ACTORS.Party.RemoveConfirmation.title', {
|
||||
name: doc.name
|
||||
})
|
||||
},
|
||||
content: game.i18n.format('DAGGERHEART.ACTORS.Party.RemoveConfirmation.text', { name: doc.name })
|
||||
});
|
||||
|
||||
if (!confirmed) return;
|
||||
}
|
||||
|
||||
const currentMembers = this.document.system.partyMembers.map(x => x.uuid);
|
||||
const newMembersList = currentMembers.filter(uuid => uuid !== doc.uuid);
|
||||
await this.document.update({ 'system.partyMembers': newMembersList });
|
||||
}
|
||||
|
||||
static async downtimeMoveQuery({ actorId, downtimeType }) {
|
||||
const actor = await foundry.utils.fromUuid(actorId);
|
||||
if (!actor || !actor?.isOwner) return;
|
||||
|
|
@ -312,11 +378,19 @@ export default class Party extends DHBaseActorSheet {
|
|||
});
|
||||
}
|
||||
|
||||
static async #tagTeamRoll() {
|
||||
/**
|
||||
* @this PartySheet
|
||||
* @type {ApplicationClickAction}
|
||||
*/
|
||||
static async #onTagTeamRoll() {
|
||||
new game.system.api.applications.dialogs.TagTeamDialog(this.document).render({ force: true });
|
||||
}
|
||||
|
||||
static async #groupRoll(_params) {
|
||||
/**
|
||||
* @this PartySheet
|
||||
* @type {ApplicationClickAction}
|
||||
*/
|
||||
static async #onGroupRoll(_params) {
|
||||
new game.system.api.applications.dialogs.GroupRollDialog(this.document).render({ force: true });
|
||||
}
|
||||
|
||||
|
|
@ -460,11 +534,10 @@ export default class Party extends DHBaseActorSheet {
|
|||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
|
||||
/** @inheritdoc */
|
||||
async _onDropActor(event, document) {
|
||||
const data = foundry.applications.ux.TextEditor.implementation.getDragEventData(event);
|
||||
if (document instanceof DhpActor && Party.ALLOWED_ACTOR_TYPES.includes(document.type)) {
|
||||
if (document instanceof DhpActor && PartySheet.ALLOWED_ACTOR_TYPES.includes(document.type)) {
|
||||
const currentMembers = this.document.system.partyMembers.map(x => x.uuid);
|
||||
if (currentMembers.includes(data.uuid)) {
|
||||
return ui.notifications.warn(game.i18n.localize('DAGGERHEART.UI.Notifications.duplicateCharacter'));
|
||||
|
|
@ -477,24 +550,4 @@ export default class Party extends DHBaseActorSheet {
|
|||
|
||||
return null;
|
||||
}
|
||||
|
||||
static async #deletePartyMember(event, target) {
|
||||
const doc = await foundry.utils.fromUuid(target.closest('[data-uuid]')?.dataset.uuid);
|
||||
if (!event.shiftKey) {
|
||||
const confirmed = await foundry.applications.api.DialogV2.confirm({
|
||||
window: {
|
||||
title: game.i18n.format('DAGGERHEART.ACTORS.Party.RemoveConfirmation.title', {
|
||||
name: doc.name
|
||||
})
|
||||
},
|
||||
content: game.i18n.format('DAGGERHEART.ACTORS.Party.RemoveConfirmation.text', { name: doc.name })
|
||||
});
|
||||
|
||||
if (!confirmed) return;
|
||||
}
|
||||
|
||||
const currentMembers = this.document.system.partyMembers.map(x => x.uuid);
|
||||
const newMembersList = currentMembers.filter(uuid => uuid !== doc.uuid);
|
||||
await this.document.update({ 'system.partyMembers': newMembersList });
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,7 +30,8 @@ export default class DHBaseItemSheet extends DHApplicationMixin(ItemSheetV2) {
|
|||
addFeature: DHBaseItemSheet.#addFeature,
|
||||
deleteFeature: DHBaseItemSheet.#deleteFeature,
|
||||
addResource: DHBaseItemSheet.#addResource,
|
||||
removeResource: DHBaseItemSheet.#removeResource
|
||||
removeResource: DHBaseItemSheet.#removeResource,
|
||||
editGMNote: DHBaseItemSheet.#onEditGMNote
|
||||
},
|
||||
dragDrop: [
|
||||
{ dragSelector: null, dropSelector: '.drop-section' },
|
||||
|
|
@ -76,10 +77,16 @@ export default class DHBaseItemSheet extends DHApplicationMixin(ItemSheetV2) {
|
|||
/**@inheritdoc */
|
||||
async _preparePartContext(partId, context, options) {
|
||||
await super._preparePartContext(partId, context, options);
|
||||
const TextEditor = foundry.applications.ux.TextEditor.implementation;
|
||||
|
||||
switch (partId) {
|
||||
case 'description':
|
||||
context.enrichedDescription = await this.document.system.getEnrichedDescription();
|
||||
context.enrichedDescription = await this.document.system.getEnrichedDescription({ gmNotes: false });
|
||||
context.enrichedGMNotes = await TextEditor.implementation.enrichHTML(this.item.system.gmNotes, {
|
||||
relativeTo: this.item,
|
||||
rollData: this.item.getRollData(),
|
||||
secrets: this.item.isOwner
|
||||
})
|
||||
break;
|
||||
case 'effects':
|
||||
await this._prepareEffectsContext(context, options);
|
||||
|
|
@ -331,4 +338,45 @@ export default class DHBaseItemSheet extends DHApplicationMixin(ItemSheetV2) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the Add GM Note button being pressed. This is only used when an item has no GM notes.
|
||||
* Later edits to a GM note instead go through the normal editor toggle workflow.
|
||||
* @this DHBaseItemSheet
|
||||
*/
|
||||
static #onEditGMNote() {
|
||||
// Open the editor, which might be hidden. We remove the css class to hide temporarily
|
||||
// so that menu auto resizing functions properly.
|
||||
const editor = this.element.querySelector('prose-mirror[name="system.gmNotes"]');
|
||||
const wasHidden = editor.classList.contains('hide-if-inactive');
|
||||
editor.classList.remove('hide-if-inactive');
|
||||
editor.open = true;
|
||||
window.setTimeout(() => {
|
||||
if (wasHidden) editor.classList.add('hide-if-inactive');
|
||||
}, 0);
|
||||
}
|
||||
|
||||
/** @inheritdoc */
|
||||
async _onRender(context, options) {
|
||||
await super._onRender(context, options);
|
||||
|
||||
// Render an add gmnotes button if there are no set GM notes.
|
||||
// We need to re-render on close since its possible to prosemirror to close *without* triggering a full re-render
|
||||
if (game.user.isGM && !this.item.system.gmNotes) {
|
||||
const description = this.element.querySelector('[name="system.description"]');
|
||||
const addButton = () => {
|
||||
if (description.querySelector('[data-action=editGMNote]')) return;
|
||||
|
||||
const button = document.createElement('button');
|
||||
button.type = 'button';
|
||||
button.classList.add('icon', 'toggle', 'fa-regular', 'fa-note-medical');
|
||||
button.dataset.action = 'editGMNote';
|
||||
button.dataset.tooltip = 'DAGGERHEART.ITEMS.Base.addGMNote';
|
||||
description.appendChild(button);
|
||||
}
|
||||
|
||||
addButton();
|
||||
description.addEventListener('close', () => addButton());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue