mirror of
https://github.com/Foundryborne/daggerheart.git
synced 2026-06-07 21:34:16 +02:00
Merge branch 'main' into feature/granular-action-outcomes
This commit is contained in:
commit
482f712086
31 changed files with 221 additions and 195 deletions
|
|
@ -64,7 +64,7 @@ You can find the documentation here: https://github.com/Foundryborne/daggerheart
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|
||||||
Looking to contribute to the project? Look no further, check out our [contributing guide](contributing.md), and keep the [Code of Conduct](coc.md) in mind when working on things.
|
Looking to contribute to the project? Look no further, check out our [contributing guide](CONTRIBUTING.md), and keep the [Code of Conduct](coc.md) in mind when working on things.
|
||||||
|
|
||||||
## Disclaimer:
|
## Disclaimer:
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -342,7 +342,8 @@ Hooks.on(CONFIG.DH.HOOKS.hooksConfig.tagTeamStart, async data => {
|
||||||
const party = game.actors.get(data.partyId);
|
const party = game.actors.get(data.partyId);
|
||||||
if (!party) return;
|
if (!party) return;
|
||||||
|
|
||||||
const dialog = new game.system.api.applications.dialogs.TagTeamDialog(party);
|
const TagTeamDialog = game.system.api.applications.dialogs.TagTeamDialog;
|
||||||
|
const dialog = foundry.applications.instances.get(`TagTeamDialog-${party.id}`) ?? new TagTeamDialog(party);
|
||||||
dialog.tabGroups.application = 'tagTeamRoll';
|
dialog.tabGroups.application = 'tagTeamRoll';
|
||||||
await dialog.render({ force: true });
|
await dialog.render({ force: true });
|
||||||
}
|
}
|
||||||
|
|
@ -353,7 +354,8 @@ Hooks.on(CONFIG.DH.HOOKS.hooksConfig.groupRollStart, async data => {
|
||||||
const party = game.actors.get(data.partyId);
|
const party = game.actors.get(data.partyId);
|
||||||
if (!party) return;
|
if (!party) return;
|
||||||
|
|
||||||
const dialog = new game.system.api.applications.dialogs.GroupRollDialog(party);
|
const GroupRollDialog = game.system.api.applications.dialogs.GroupRollDialog;
|
||||||
|
const dialog = foundry.applications.instances.get(`GroupRollDialog-${party.id}`) ?? new GroupRollDialog(party);
|
||||||
dialog.tabGroups.application = 'groupRoll';
|
dialog.tabGroups.application = 'groupRoll';
|
||||||
await dialog.render({ force: true });
|
await dialog.render({ force: true });
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3221,7 +3221,8 @@
|
||||||
"domainTouchRequirement": "This domain card requires {nr} {domain} cards in the loadout to be used",
|
"domainTouchRequirement": "This domain card requires {nr} {domain} cards in the loadout to be used",
|
||||||
"knowTheTide": "Know The Tide gained a token",
|
"knowTheTide": "Know The Tide gained a token",
|
||||||
"lackingItemTransferPermission": "User {user} lacks owner permission needed to transfer items to {target}",
|
"lackingItemTransferPermission": "User {user} lacks owner permission needed to transfer items to {target}",
|
||||||
"noTokenTargeted": "No token is targeted"
|
"noTokenTargeted": "No token is targeted",
|
||||||
|
"behaviorRegionRequiresGM": "Creating a Region with an attached Behavior requires an online GM"
|
||||||
},
|
},
|
||||||
"Progress": {
|
"Progress": {
|
||||||
"migrationLabel": "Performing system migration. Please wait and do not close Foundry."
|
"migrationLabel": "Performing system migration. Please wait and do not close Foundry."
|
||||||
|
|
|
||||||
|
|
@ -22,9 +22,10 @@ export default class DamageReductionDialog extends HandlebarsApplicationMixin(Ap
|
||||||
);
|
);
|
||||||
|
|
||||||
const orderedArmorSources = getArmorSources(actor).filter(s => !s.disabled);
|
const orderedArmorSources = getArmorSources(actor).filter(s => !s.disabled);
|
||||||
const armor = orderedArmorSources.reduce((acc, { document }) => {
|
const armor = orderedArmorSources.reduce((acc, { name, document }) => {
|
||||||
const { current, max } = document.type === 'armor' ? document.system.armor : document.system.armorData;
|
const { current, max } = document.type === 'armor' ? document.system.armor : document.system.armorData;
|
||||||
acc.push({
|
acc.push({
|
||||||
|
name,
|
||||||
effect: document,
|
effect: document,
|
||||||
marks: [...Array(max).keys()].reduce((acc, _, index) => {
|
marks: [...Array(max).keys()].reduce((acc, _, index) => {
|
||||||
const spent = index < current;
|
const spent = index < current;
|
||||||
|
|
@ -152,14 +153,8 @@ export default class DamageReductionDialog extends HandlebarsApplicationMixin(Ap
|
||||||
|
|
||||||
const armorSources = [];
|
const armorSources = [];
|
||||||
for (const source of this.marks.armor) {
|
for (const source of this.marks.armor) {
|
||||||
const parent = source.effect.origin
|
|
||||||
? await foundry.utils.fromUuid(source.effect.origin)
|
|
||||||
: source.effect.parent;
|
|
||||||
|
|
||||||
const useEffectName = parent.type === 'armor' || parent instanceof Actor;
|
|
||||||
const label = useEffectName ? source.effect.name : parent.name;
|
|
||||||
armorSources.push({
|
armorSources.push({
|
||||||
label: label,
|
label: source.name,
|
||||||
uuid: source.effect.uuid,
|
uuid: source.effect.uuid,
|
||||||
marks: source.marks
|
marks: source.marks
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -259,7 +259,9 @@ export default class DhpDowntime extends HandlebarsApplicationMixin(ApplicationV
|
||||||
const resetValue = increasing
|
const resetValue = increasing
|
||||||
? 0
|
? 0
|
||||||
: feature.system.resource.max
|
: feature.system.resource.max
|
||||||
? new Roll(Roll.replaceFormulaData(feature.system.resource.max, this.actor)).evaluateSync().total
|
? new Roll(
|
||||||
|
Roll.replaceFormulaData(feature.system.resource.max, this.actor.getRollData())
|
||||||
|
).evaluateSync().total
|
||||||
: 0;
|
: 0;
|
||||||
|
|
||||||
await feature.update({ 'system.resource.value': resetValue });
|
await feature.update({ 'system.resource.value': resetValue });
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,12 @@
|
||||||
import { ResourceUpdateMap } from '../../data/action/baseAction.mjs';
|
import { ResourceUpdateMap } from '../../data/action/baseAction.mjs';
|
||||||
import { emitAsGM, GMUpdateEvent, RefreshType, socketEvent } from '../../systemRegistration/socket.mjs';
|
import { emitGMUpdate, GMUpdateEvent, RefreshType, socketEvent } from '../../systemRegistration/socket.mjs';
|
||||||
import Party from '../sheets/actors/party.mjs';
|
import Party from '../sheets/actors/party.mjs';
|
||||||
|
|
||||||
const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api;
|
const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api;
|
||||||
|
|
||||||
export default class GroupRollDialog extends HandlebarsApplicationMixin(ApplicationV2) {
|
export default class GroupRollDialog extends HandlebarsApplicationMixin(ApplicationV2) {
|
||||||
constructor(party) {
|
constructor(party) {
|
||||||
super();
|
super({ id: `GroupRollDialog-${party.id}` });
|
||||||
|
|
||||||
this.party = party;
|
this.party = party;
|
||||||
this.partyMembers = party.system.partyMembers
|
this.partyMembers = party.system.partyMembers
|
||||||
|
|
@ -35,7 +35,6 @@ export default class GroupRollDialog extends HandlebarsApplicationMixin(Applicat
|
||||||
|
|
||||||
static DEFAULT_OPTIONS = {
|
static DEFAULT_OPTIONS = {
|
||||||
tag: 'form',
|
tag: 'form',
|
||||||
id: 'GroupRollDialog',
|
|
||||||
classes: ['daggerheart', 'views', 'dh-style', 'dialog', 'group-roll-dialog'],
|
classes: ['daggerheart', 'views', 'dh-style', 'dialog', 'group-roll-dialog'],
|
||||||
position: { width: 390, height: 'auto' },
|
position: { width: 390, height: 'auto' },
|
||||||
window: {
|
window: {
|
||||||
|
|
@ -243,7 +242,7 @@ export default class GroupRollDialog extends HandlebarsApplicationMixin(Applicat
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
await emitAsGM(
|
await emitGMUpdate(
|
||||||
GMUpdateEvent.UpdateDocument,
|
GMUpdateEvent.UpdateDocument,
|
||||||
gmUpdate,
|
gmUpdate,
|
||||||
update,
|
update,
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,13 @@
|
||||||
import { MemberData } from '../../data/tagTeamData.mjs';
|
import { MemberData } from '../../data/tagTeamData.mjs';
|
||||||
import { getCritDamageBonus } from '../../helpers/utils.mjs';
|
import { getCritDamageBonus } from '../../helpers/utils.mjs';
|
||||||
import { emitAsGM, GMUpdateEvent, RefreshType, socketEvent } from '../../systemRegistration/socket.mjs';
|
import { emitGMUpdate, GMUpdateEvent, RefreshType, socketEvent } from '../../systemRegistration/socket.mjs';
|
||||||
import Party from '../sheets/actors/party.mjs';
|
import Party from '../sheets/actors/party.mjs';
|
||||||
|
|
||||||
const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api;
|
const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api;
|
||||||
|
|
||||||
export default class TagTeamDialog extends HandlebarsApplicationMixin(ApplicationV2) {
|
export default class TagTeamDialog extends HandlebarsApplicationMixin(ApplicationV2) {
|
||||||
constructor(party) {
|
constructor(party) {
|
||||||
super();
|
super({ id: `TagTeamDialog-${party.id}` });
|
||||||
|
|
||||||
this.party = party;
|
this.party = party;
|
||||||
this.partyMembers = party.system.partyMembers
|
this.partyMembers = party.system.partyMembers
|
||||||
|
|
@ -36,7 +36,6 @@ export default class TagTeamDialog extends HandlebarsApplicationMixin(Applicatio
|
||||||
|
|
||||||
static DEFAULT_OPTIONS = {
|
static DEFAULT_OPTIONS = {
|
||||||
tag: 'form',
|
tag: 'form',
|
||||||
id: 'TagTeamDialog',
|
|
||||||
classes: ['daggerheart', 'views', 'dh-style', 'dialog', 'tag-team-dialog'],
|
classes: ['daggerheart', 'views', 'dh-style', 'dialog', 'tag-team-dialog'],
|
||||||
position: { width: 550, height: 'auto' },
|
position: { width: 550, height: 'auto' },
|
||||||
actions: {
|
actions: {
|
||||||
|
|
@ -60,13 +59,17 @@ export default class TagTeamDialog extends HandlebarsApplicationMixin(Applicatio
|
||||||
id: 'initialization',
|
id: 'initialization',
|
||||||
template: 'systems/daggerheart/templates/dialogs/tagTeamDialog/initialization.hbs'
|
template: 'systems/daggerheart/templates/dialogs/tagTeamDialog/initialization.hbs'
|
||||||
},
|
},
|
||||||
|
tagTeamRoll: {
|
||||||
|
id: 'tagTeamRoll',
|
||||||
|
template: 'systems/daggerheart/templates/dialogs/tagTeamDialog/tagTeamRoll.hbs'
|
||||||
|
},
|
||||||
rollSelection: {
|
rollSelection: {
|
||||||
id: 'rollSelection',
|
id: 'rollSelection',
|
||||||
template: 'systems/daggerheart/templates/dialogs/tagTeamDialog/rollSelection.hbs'
|
template: 'systems/daggerheart/templates/dialogs/tagTeamDialog/rollSelection.hbs'
|
||||||
},
|
},
|
||||||
tagTeamRoll: {
|
result: {
|
||||||
id: 'tagTeamRoll',
|
id: 'result',
|
||||||
template: 'systems/daggerheart/templates/dialogs/tagTeamDialog/tagTeamRoll.hbs'
|
template: 'systems/daggerheart/templates/dialogs/tagTeamDialog/result.hbs'
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -97,36 +100,15 @@ export default class TagTeamDialog extends HandlebarsApplicationMixin(Applicatio
|
||||||
}
|
}
|
||||||
|
|
||||||
_configureRenderParts(options) {
|
_configureRenderParts(options) {
|
||||||
const { initialization, rollSelection, tagTeamRoll } = super._configureRenderParts(options);
|
const parts = super._configureRenderParts(options);
|
||||||
const augmentedParts = { initialization };
|
|
||||||
for (const memberKey of Object.keys(this.party.system.tagTeam.members)) {
|
for (const memberKey of Object.keys(this.party.system.tagTeam.members)) {
|
||||||
augmentedParts[memberKey] = {
|
parts[memberKey] = {
|
||||||
id: memberKey,
|
id: memberKey,
|
||||||
template: 'systems/daggerheart/templates/dialogs/tagTeamDialog/tagTeamMember.hbs'
|
template: 'systems/daggerheart/templates/dialogs/tagTeamDialog/tagTeamMember.hbs'
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
augmentedParts.rollSelection = rollSelection;
|
|
||||||
augmentedParts.tagTeamRoll = tagTeamRoll;
|
|
||||||
|
|
||||||
return augmentedParts;
|
return parts;
|
||||||
}
|
|
||||||
|
|
||||||
/**@inheritdoc */
|
|
||||||
async _onRender(context, options) {
|
|
||||||
await super._onRender(context, options);
|
|
||||||
|
|
||||||
// if (this.element.querySelector('.roll-selection')) {
|
|
||||||
// for (const element of this.element.querySelectorAll('.team-member-container')) {
|
|
||||||
// element.classList.add('select-padding');
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
if (this.element.querySelector('.team-container')) return;
|
|
||||||
const initializationPart = this.element.querySelector('.initialization-container');
|
|
||||||
initializationPart.insertAdjacentHTML('afterend', '<div class="team-container"></div>');
|
|
||||||
const teamContainer = this.element.querySelector('.team-container');
|
|
||||||
for (const memberContainer of this.element.querySelectorAll('.team-member-container'))
|
|
||||||
teamContainer.appendChild(memberContainer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async _prepareContext(_options) {
|
async _prepareContext(_options) {
|
||||||
|
|
@ -167,6 +149,9 @@ export default class TagTeamDialog extends HandlebarsApplicationMixin(Applicatio
|
||||||
partContext.initiatorDisabled = !selectedMembers.length;
|
partContext.initiatorDisabled = !selectedMembers.length;
|
||||||
partContext.openForAllPlayers = this.openForAllPlayers;
|
partContext.openForAllPlayers = this.openForAllPlayers;
|
||||||
|
|
||||||
|
break;
|
||||||
|
case 'tagTeamRoll':
|
||||||
|
partContext.memberKeys = Object.keys(this.party.system.tagTeam.members);
|
||||||
break;
|
break;
|
||||||
case 'rollSelection':
|
case 'rollSelection':
|
||||||
partContext.members = Object.keys(this.party.system.tagTeam.members).reduce((acc, key) => {
|
partContext.members = Object.keys(this.party.system.tagTeam.members).reduce((acc, key) => {
|
||||||
|
|
@ -175,7 +160,7 @@ export default class TagTeamDialog extends HandlebarsApplicationMixin(Applicatio
|
||||||
return acc;
|
return acc;
|
||||||
}, {});
|
}, {});
|
||||||
break;
|
break;
|
||||||
case 'tagTeamRoll':
|
case 'result':
|
||||||
const selectedRoll = Object.values(this.party.system.tagTeam.members).find(member => member.selected);
|
const selectedRoll = Object.values(this.party.system.tagTeam.members).find(member => member.selected);
|
||||||
const critSelected = !selectedRoll
|
const critSelected = !selectedRoll
|
||||||
? undefined
|
? undefined
|
||||||
|
|
@ -243,7 +228,7 @@ export default class TagTeamDialog extends HandlebarsApplicationMixin(Applicatio
|
||||||
}
|
}
|
||||||
|
|
||||||
getUpdatingParts(target) {
|
getUpdatingParts(target) {
|
||||||
const { initialization, rollSelection, tagTeamRoll } = this.constructor.PARTS;
|
const { initialization, rollSelection, result } = this.constructor.PARTS;
|
||||||
const isInitialization = this.tabGroups.application === initialization.id;
|
const isInitialization = this.tabGroups.application === initialization.id;
|
||||||
const updatingMember = target.closest('.team-member-container')?.dataset?.memberKey;
|
const updatingMember = target.closest('.team-member-container')?.dataset?.memberKey;
|
||||||
|
|
||||||
|
|
@ -251,7 +236,7 @@ export default class TagTeamDialog extends HandlebarsApplicationMixin(Applicatio
|
||||||
...(isInitialization ? [initialization.id] : []),
|
...(isInitialization ? [initialization.id] : []),
|
||||||
...(updatingMember ? [updatingMember] : []),
|
...(updatingMember ? [updatingMember] : []),
|
||||||
...(!isInitialization ? [rollSelection.id] : []),
|
...(!isInitialization ? [rollSelection.id] : []),
|
||||||
...(!isInitialization ? [tagTeamRoll.id] : [])
|
...(!isInitialization ? [result.id] : [])
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -274,7 +259,7 @@ export default class TagTeamDialog extends HandlebarsApplicationMixin(Applicatio
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
await emitAsGM(
|
await emitGMUpdate(
|
||||||
GMUpdateEvent.UpdateDocument,
|
GMUpdateEvent.UpdateDocument,
|
||||||
gmUpdate,
|
gmUpdate,
|
||||||
update,
|
update,
|
||||||
|
|
|
||||||
|
|
@ -120,12 +120,6 @@ export default class DhSceneConfigSettings extends foundry.applications.sheets.S
|
||||||
foundry.utils.fromUuidSync(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] = _del;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
super._processSubmitData(event, form, submitData, options);
|
super._processSubmitData(event, form, submitData, options);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -110,6 +110,7 @@ export default class DHAdversarySettings extends DHBaseActorSettings {
|
||||||
}
|
}
|
||||||
|
|
||||||
async _onDrop(event) {
|
async _onDrop(event) {
|
||||||
|
event.stopPropagation();
|
||||||
const data = foundry.applications.ux.TextEditor.implementation.getDragEventData(event);
|
const data = foundry.applications.ux.TextEditor.implementation.getDragEventData(event);
|
||||||
|
|
||||||
const item = await fromUuid(data.uuid);
|
const item = await fromUuid(data.uuid);
|
||||||
|
|
|
||||||
|
|
@ -121,6 +121,7 @@ export default class DHEnvironmentSettings extends DHBaseActorSettings {
|
||||||
}
|
}
|
||||||
|
|
||||||
async _onDrop(event) {
|
async _onDrop(event) {
|
||||||
|
event.stopPropagation();
|
||||||
const data = foundry.applications.ux.TextEditor.implementation.getDragEventData(event);
|
const data = foundry.applications.ux.TextEditor.implementation.getDragEventData(event);
|
||||||
const item = await fromUuid(data.uuid);
|
const item = await fromUuid(data.uuid);
|
||||||
if (data.fromInternal && item?.parent?.uuid === this.actor.uuid) return;
|
if (data.fromInternal && item?.parent?.uuid === this.actor.uuid) return;
|
||||||
|
|
@ -138,8 +139,4 @@ export default class DHEnvironmentSettings extends DHBaseActorSettings {
|
||||||
this.render();
|
this.render();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async _onDropItem(event, item) {
|
|
||||||
console.log(item);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -531,7 +531,7 @@ export default function DHApplicationMixin(Base) {
|
||||||
visible: element => {
|
visible: element => {
|
||||||
const target = element.closest('[data-item-uuid]');
|
const target = element.closest('[data-item-uuid]');
|
||||||
const doc = getDocFromElementSync(target);
|
const doc = getDocFromElementSync(target);
|
||||||
return doc?.isOwner && target.dataset.itemType !== 'beastform';
|
return doc?.isOwner !== false && target.dataset.itemType !== 'beastform';
|
||||||
},
|
},
|
||||||
callback: async (target, event) => {
|
callback: async (target, event) => {
|
||||||
const doc = await getDocFromElement(target);
|
const doc = await getDocFromElement(target);
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import { DhCountdown } from '../../data/countdowns.mjs';
|
import { DhCountdown } from '../../data/countdowns.mjs';
|
||||||
import { waitForDiceSoNice } from '../../helpers/utils.mjs';
|
import { waitForDiceSoNice } from '../../helpers/utils.mjs';
|
||||||
import { emitAsGM, GMUpdateEvent, RefreshType, socketEvent } from '../../systemRegistration/socket.mjs';
|
import { emitGMUpdate, GMUpdateEvent, RefreshType, socketEvent } from '../../systemRegistration/socket.mjs';
|
||||||
|
|
||||||
const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api;
|
const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api;
|
||||||
|
|
||||||
|
|
@ -114,7 +114,7 @@ export default class CountdownEdit extends HandlebarsApplicationMixin(Applicatio
|
||||||
}
|
}
|
||||||
|
|
||||||
await this.data.updateSource(update);
|
await this.data.updateSource(update);
|
||||||
await emitAsGM(GMUpdateEvent.UpdateCountdowns, this.gmSetSetting.bind(this.data), this.data, null, {
|
await emitGMUpdate(GMUpdateEvent.UpdateCountdowns, this.gmSetSetting.bind(this.data), this.data, null, {
|
||||||
refreshType: RefreshType.Countdown
|
refreshType: RefreshType.Countdown
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import { waitForDiceSoNice } from '../../helpers/utils.mjs';
|
import { waitForDiceSoNice } from '../../helpers/utils.mjs';
|
||||||
import { emitAsGM, GMUpdateEvent, RefreshType, socketEvent } from '../../systemRegistration/socket.mjs';
|
import { emitGMUpdate, GMUpdateEvent, RefreshType, socketEvent } from '../../systemRegistration/socket.mjs';
|
||||||
|
|
||||||
const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api;
|
const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api;
|
||||||
|
|
||||||
|
|
@ -204,7 +204,7 @@ export default class DhCountdowns extends HandlebarsApplicationMixin(Application
|
||||||
start: newMax
|
start: newMax
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
await emitAsGM(GMUpdateEvent.UpdateCountdowns, DhCountdowns.gmSetSetting.bind(settings), settings, null, {
|
await emitGMUpdate(GMUpdateEvent.UpdateCountdowns, DhCountdowns.gmSetSetting.bind(settings), settings, null, {
|
||||||
refreshType: RefreshType.Countdown
|
refreshType: RefreshType.Countdown
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -218,7 +218,7 @@ export default class DhCountdowns extends HandlebarsApplicationMixin(Application
|
||||||
? Math.min(countdown.progress.current + 1, countdown.progress.start)
|
? Math.min(countdown.progress.current + 1, countdown.progress.start)
|
||||||
: Math.max(countdown.progress.current - 1, 0);
|
: Math.max(countdown.progress.current - 1, 0);
|
||||||
await settings.updateSource({ [`countdowns.${target.id}.progress.current`]: newCurrent });
|
await settings.updateSource({ [`countdowns.${target.id}.progress.current`]: newCurrent });
|
||||||
await emitAsGM(GMUpdateEvent.UpdateCountdowns, DhCountdowns.gmSetSetting.bind(settings), settings, null, {
|
await emitGMUpdate(GMUpdateEvent.UpdateCountdowns, DhCountdowns.gmSetSetting.bind(settings), settings, null, {
|
||||||
refreshType: RefreshType.Countdown
|
refreshType: RefreshType.Countdown
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -277,7 +277,7 @@ export default class DhCountdowns extends HandlebarsApplicationMixin(Application
|
||||||
return acc;
|
return acc;
|
||||||
}, {})
|
}, {})
|
||||||
};
|
};
|
||||||
await emitAsGM(GMUpdateEvent.UpdateCountdowns, DhCountdowns.gmSetSetting.bind(settings), settings, null, {
|
await emitGMUpdate(GMUpdateEvent.UpdateCountdowns, DhCountdowns.gmSetSetting.bind(settings), settings, null, {
|
||||||
refreshType: RefreshType.Countdown
|
refreshType: RefreshType.Countdown
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { emitAsGM, GMUpdateEvent } from '../../systemRegistration/socket.mjs';
|
import { emitGMUpdate, GMUpdateEvent } from '../../systemRegistration/socket.mjs';
|
||||||
|
|
||||||
const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api;
|
const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api;
|
||||||
|
|
||||||
|
|
@ -104,7 +104,7 @@ export default class FearTracker extends HandlebarsApplicationMixin(ApplicationV
|
||||||
}
|
}
|
||||||
|
|
||||||
async updateFear(value) {
|
async updateFear(value) {
|
||||||
return emitAsGM(
|
return emitGMUpdate(
|
||||||
GMUpdateEvent.UpdateFear,
|
GMUpdateEvent.UpdateFear,
|
||||||
game.settings.set.bind(game.settings, CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Resources.Fear),
|
game.settings.set.bind(game.settings, CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Resources.Fear),
|
||||||
value
|
value
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { emitAsGM, GMUpdateEvent } from '../../systemRegistration/socket.mjs';
|
import { emitGMUpdate, GMUpdateEvent } from '../../systemRegistration/socket.mjs';
|
||||||
|
|
||||||
export default class DhSceneNavigation extends foundry.applications.ui.SceneNavigation {
|
export default class DhSceneNavigation extends foundry.applications.ui.SceneNavigation {
|
||||||
/** @inheritdoc */
|
/** @inheritdoc */
|
||||||
|
|
@ -68,7 +68,7 @@ export default class DhSceneNavigation extends foundry.applications.ui.SceneNavi
|
||||||
1
|
1
|
||||||
)[0];
|
)[0];
|
||||||
newEnvironments.unshift(newFirst);
|
newEnvironments.unshift(newFirst);
|
||||||
emitAsGM(
|
emitGMUpdate(
|
||||||
GMUpdateEvent.UpdateDocument,
|
GMUpdateEvent.UpdateDocument,
|
||||||
scene.update.bind(scene),
|
scene.update.bind(scene),
|
||||||
{ 'flags.daggerheart.sceneEnvironments': newEnvironments },
|
{ 'flags.daggerheart.sceneEnvironments': newEnvironments },
|
||||||
|
|
|
||||||
|
|
@ -57,14 +57,14 @@ export default class DhRegionLayer extends foundry.canvas.layers.RegionLayer {
|
||||||
}
|
}
|
||||||
|
|
||||||
async placeRegion(data, options = {}) {
|
async placeRegion(data, options = {}) {
|
||||||
const preConfirm = ({ _event, document, _create, _options }) => {
|
const preConfirm = data => {
|
||||||
const shape = document.shapes[0];
|
const shape = data.document.shapes[0];
|
||||||
const isEmanation = shape.type === 'emanation';
|
const isEmanation = shape.type === 'emanation';
|
||||||
if (isEmanation) {
|
if (isEmanation) {
|
||||||
const token = this.#findTokenInBounds(shape.base.origin);
|
const token = this.#findTokenInBounds(shape.base.origin);
|
||||||
if (!token) return options.preConfirm?.() ?? true;
|
if (!token) return options.preConfirm?.(data) ?? true;
|
||||||
const shapeData = shape.toObject();
|
const shapeData = shape.toObject();
|
||||||
document.updateSource({
|
data.document.updateSource({
|
||||||
shapes: [
|
shapes: [
|
||||||
{
|
{
|
||||||
...shapeData,
|
...shapeData,
|
||||||
|
|
@ -80,10 +80,10 @@ export default class DhRegionLayer extends foundry.canvas.layers.RegionLayer {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return options?.preConfirm?.() ?? true;
|
return options?.preConfirm?.(data) ?? true;
|
||||||
};
|
};
|
||||||
|
|
||||||
super.placeRegion(data, { ...options, preConfirm });
|
return await super.placeRegion(data, { ...options, preConfirm });
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Searches for token at origin point, returning null if there are no tokens or multiple overlapping tokens */
|
/** Searches for token at origin point, returning null if there are no tokens or multiple overlapping tokens */
|
||||||
|
|
|
||||||
|
|
@ -836,10 +836,10 @@ export default class DhCharacter extends DhCreature {
|
||||||
|
|
||||||
/* Scars can alter the amount of current hope */
|
/* Scars can alter the amount of current hope */
|
||||||
if (changes.system?.scars) {
|
if (changes.system?.scars) {
|
||||||
const diff = this.system.scars - changes.system.scars;
|
const diff = this.scars - changes.system.scars;
|
||||||
const newHopeMax = this.system.resources.hope.max + diff;
|
const newHopeMax = this.resources.hope.max + diff;
|
||||||
const newHopeValue = Math.min(newHopeMax, this.system.resources.hope.value);
|
const newHopeValue = Math.min(newHopeMax, this.resources.hope.value);
|
||||||
if (newHopeValue != this.system.resources.hope.value) {
|
if (newHopeValue != this.resources.hope.value) {
|
||||||
if (!changes.system.resources.hope) changes.system.resources.hope = { value: 0 };
|
if (!changes.system.resources.hope) changes.system.resources.hope = { value: 0 };
|
||||||
|
|
||||||
changes.system.resources.hope = {
|
changes.system.resources.hope = {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { emitAsGM, GMUpdateEvent, RefreshType, socketEvent } from '../../../systemRegistration/socket.mjs';
|
import { emitGMUpdate, GMUpdateEvent, RefreshType, socketEvent } from '../../../systemRegistration/socket.mjs';
|
||||||
|
|
||||||
const fields = foundry.data.fields;
|
const fields = foundry.data.fields;
|
||||||
|
|
||||||
|
|
@ -78,7 +78,7 @@ export default class CountdownField extends fields.ArrayField {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
await emitAsGM(
|
await emitGMUpdate(
|
||||||
GMUpdateEvent.UpdateCountdowns,
|
GMUpdateEvent.UpdateCountdowns,
|
||||||
async () => {
|
async () => {
|
||||||
const countdownSetting = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Countdowns);
|
const countdownSetting = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Countdowns);
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { emitAsGM, GMUpdateEvent } from '../../../systemRegistration/socket.mjs';
|
import { emitGMUpdate, GMUpdateEvent } from '../../../systemRegistration/socket.mjs';
|
||||||
|
|
||||||
const fields = foundry.data.fields;
|
const fields = foundry.data.fields;
|
||||||
|
|
||||||
|
|
@ -34,7 +34,7 @@ export default class EffectsField extends fields.ArrayField {
|
||||||
}
|
}
|
||||||
if (EffectsField.getAutomation() || force) {
|
if (EffectsField.getAutomation() || force) {
|
||||||
targets ??= (message.system?.targets ?? config.targets).filter(t => !config.hasRoll || t.hit);
|
targets ??= (message.system?.targets ?? config.targets).filter(t => !config.hasRoll || t.hit);
|
||||||
await emitAsGM(GMUpdateEvent.UpdateEffect, EffectsField.applyEffects.bind(this), targets, this.uuid);
|
await emitGMUpdate(GMUpdateEvent.UpdateEffect, EffectsField.applyEffects.bind(this), targets, this.uuid);
|
||||||
// EffectsField.applyEffects.call(this, config.targets.filter(t => !config.hasRoll || t.hit));
|
// EffectsField.applyEffects.call(this, config.targets.filter(t => !config.hasRoll || t.hit));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -171,6 +171,7 @@ export default class DhActiveEffect extends foundry.documents.ActiveEffect {
|
||||||
|
|
||||||
/** Recursively finds the first parent document of the given object */
|
/** Recursively finds the first parent document of the given object */
|
||||||
static #resolveParentDocument(model, documentClass) {
|
static #resolveParentDocument(model, documentClass) {
|
||||||
|
if (!model) return null;
|
||||||
return model instanceof documentClass
|
return model instanceof documentClass
|
||||||
? model
|
? model
|
||||||
: model.parent
|
: model.parent
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { emitAsGM, GMUpdateEvent } from '../systemRegistration/socket.mjs';
|
import { emitGMUpdate, GMUpdateEvent } from '../systemRegistration/socket.mjs';
|
||||||
import { LevelOptionType } from '../data/levelTier.mjs';
|
import { LevelOptionType } from '../data/levelTier.mjs';
|
||||||
import DHFeature from '../data/item/feature.mjs';
|
import DHFeature from '../data/item/feature.mjs';
|
||||||
import { createScrollText, damageKeyToNumber, getDamageKey, createShallowProxy } from '../helpers/utils.mjs';
|
import { createScrollText, damageKeyToNumber, getDamageKey, createShallowProxy } from '../helpers/utils.mjs';
|
||||||
|
|
@ -827,7 +827,7 @@ export default class DhpActor extends Actor {
|
||||||
const u = updates[key];
|
const u = updates[key];
|
||||||
if (key === 'items') {
|
if (key === 'items') {
|
||||||
Object.values(u).forEach(async item => {
|
Object.values(u).forEach(async item => {
|
||||||
await emitAsGM(
|
await emitGMUpdate(
|
||||||
GMUpdateEvent.UpdateDocument,
|
GMUpdateEvent.UpdateDocument,
|
||||||
item.target.update.bind(item.target),
|
item.target.update.bind(item.target),
|
||||||
item.resources,
|
item.resources,
|
||||||
|
|
@ -836,7 +836,7 @@ export default class DhpActor extends Actor {
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
if (Object.keys(u.resources).length > 0) {
|
if (Object.keys(u.resources).length > 0) {
|
||||||
await emitAsGM(
|
await emitGMUpdate(
|
||||||
GMUpdateEvent.UpdateDocument,
|
GMUpdateEvent.UpdateDocument,
|
||||||
u.target.update.bind(u.target),
|
u.target.update.bind(u.target),
|
||||||
u.resources,
|
u.resources,
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { emitAsGM, GMUpdateEvent } from '../systemRegistration/socket.mjs';
|
import { emitGMUpdate, emitGMCreate, GMUpdateEvent } from '../systemRegistration/socket.mjs';
|
||||||
|
|
||||||
export default class DhpChatMessage extends foundry.documents.ChatMessage {
|
export default class DhpChatMessage extends foundry.documents.ChatMessage {
|
||||||
targetHook = null;
|
targetHook = null;
|
||||||
|
|
@ -214,7 +214,7 @@ export default class DhpChatMessage extends foundry.documents.ChatMessage {
|
||||||
const action = this.system.action;
|
const action = this.system.action;
|
||||||
if (!action || !action?.hasSave) return;
|
if (!action || !action?.hasSave) return;
|
||||||
game.system.api.fields.ActionFields.SaveField.rollSave.call(action, token.actor, event).then(result =>
|
game.system.api.fields.ActionFields.SaveField.rollSave.call(action, token.actor, event).then(result =>
|
||||||
emitAsGM(
|
emitGMUpdate(
|
||||||
GMUpdateEvent.UpdateSaveMessage,
|
GMUpdateEvent.UpdateSaveMessage,
|
||||||
game.system.api.fields.ActionFields.SaveField.updateSaveMessage.bind(
|
game.system.api.fields.ActionFields.SaveField.updateSaveMessage.bind(
|
||||||
action,
|
action,
|
||||||
|
|
@ -259,12 +259,17 @@ export default class DhpChatMessage extends foundry.documents.ChatMessage {
|
||||||
const { shape: type, size: range } = selectedArea;
|
const { shape: type, size: range } = selectedArea;
|
||||||
const shapeData = CONFIG.Canvas.layers.regions.layerClass.getTemplateShape({ type, range });
|
const shapeData = CONFIG.Canvas.layers.regions.layerClass.getTemplateShape({ type, range });
|
||||||
|
|
||||||
await canvas.regions.placeRegion(
|
const scene = game.scenes.get(game.user.viewedScene);
|
||||||
{
|
const level = scene.levels.find(x => x.isView);
|
||||||
|
|
||||||
|
const regionData = {
|
||||||
name: selectedArea.name,
|
name: selectedArea.name,
|
||||||
|
levels: level ? [level.id] : [],
|
||||||
shapes: [shapeData],
|
shapes: [shapeData],
|
||||||
restriction: { enabled: false, type: 'move', priority: 0 },
|
restriction: { enabled: false, type: 'move', priority: 0 },
|
||||||
behaviors: [
|
behaviors:
|
||||||
|
effects.length > 0
|
||||||
|
? [
|
||||||
{
|
{
|
||||||
name: game.i18n.localize('TYPES.RegionBehavior.applyActiveEffect'),
|
name: game.i18n.localize('TYPES.RegionBehavior.applyActiveEffect'),
|
||||||
type: 'applyActiveEffect',
|
type: 'applyActiveEffect',
|
||||||
|
|
@ -272,14 +277,29 @@ export default class DhpChatMessage extends foundry.documents.ChatMessage {
|
||||||
effects: effects
|
effects: effects
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
]
|
||||||
|
: [],
|
||||||
displayMeasurements: true,
|
displayMeasurements: true,
|
||||||
locked: false,
|
locked: false,
|
||||||
ownership: { default: CONST.DOCUMENT_OWNERSHIP_LEVELS.NONE },
|
ownership: { default: CONST.DOCUMENT_OWNERSHIP_LEVELS.NONE },
|
||||||
visibility: CONST.REGION_VISIBILITY.ALWAYS
|
visibility: CONST.REGION_VISIBILITY.ALWAYS
|
||||||
},
|
};
|
||||||
{ create: true }
|
const placeRegion = data => {
|
||||||
|
canvas.regions.placeRegion(data, { create: true });
|
||||||
|
};
|
||||||
|
|
||||||
|
// Regions with effects must be placed by the GM
|
||||||
|
if (effects.length > 0 && !game.user.isGM) {
|
||||||
|
if (!game.users.activeGM)
|
||||||
|
return ui.notifications.error(
|
||||||
|
game.i18n.localize('DAGGERHEART.UI.Notifications.behaviorRegionRequiresGM')
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const region = await canvas.regions.placeRegion(regionData, { create: false });
|
||||||
|
emitGMCreate('Region', placeRegion, region, scene.id);
|
||||||
|
} else {
|
||||||
|
placeRegion(regionData);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if (this.system.action.areas.length === 1) createArea(this.system.action.areas[0]);
|
if (this.system.action.areas.length === 1) createArea(this.system.action.areas[0]);
|
||||||
|
|
|
||||||
|
|
@ -757,9 +757,12 @@ export function getArmorSources(actor) {
|
||||||
// Get the origin item. Since the actor is already loaded, it should already be cached
|
// Get the origin item. Since the actor is already loaded, it should already be cached
|
||||||
// Consider the relative function versions if this causes an issue
|
// Consider the relative function versions if this causes an issue
|
||||||
const origin = doc.origin ? foundry.utils.fromUuidSync(doc.origin) : doc;
|
const origin = doc.origin ? foundry.utils.fromUuidSync(doc.origin) : doc;
|
||||||
|
const useParentName = doc.parent && !(doc.parent instanceof Actor);
|
||||||
|
const name = doc.origin || !useParentName ? doc.name : doc.parent.name;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
origin,
|
origin,
|
||||||
name: origin.name,
|
name,
|
||||||
document: doc,
|
document: doc,
|
||||||
data: doc.system.armor ?? doc.system.armorData,
|
data: doc.system.armor ?? doc.system.armorData,
|
||||||
disabled: !!doc.disabled || !!doc.isSuppressed
|
disabled: !!doc.disabled || !!doc.isSuppressed
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,9 @@ export function handleSocketEvent({ action = null, data = {} } = {}) {
|
||||||
case socketEvent.GMUpdate:
|
case socketEvent.GMUpdate:
|
||||||
Hooks.callAll(socketEvent.GMUpdate, data);
|
Hooks.callAll(socketEvent.GMUpdate, data);
|
||||||
break;
|
break;
|
||||||
|
case socketEvent.GMCreate:
|
||||||
|
Hooks.callAll(socketEvent.GMCreate, data);
|
||||||
|
break;
|
||||||
case socketEvent.DhpFearUpdate:
|
case socketEvent.DhpFearUpdate:
|
||||||
Hooks.callAll(socketEvent.DhpFearUpdate);
|
Hooks.callAll(socketEvent.DhpFearUpdate);
|
||||||
break;
|
break;
|
||||||
|
|
@ -25,6 +28,7 @@ export function handleSocketEvent({ action = null, data = {} } = {}) {
|
||||||
|
|
||||||
export const socketEvent = {
|
export const socketEvent = {
|
||||||
GMUpdate: 'DhGMUpdate',
|
GMUpdate: 'DhGMUpdate',
|
||||||
|
GMCreate: 'DhGMCreate',
|
||||||
Refresh: 'DhRefresh',
|
Refresh: 'DhRefresh',
|
||||||
DhpFearUpdate: 'DhFearUpdate',
|
DhpFearUpdate: 'DhFearUpdate',
|
||||||
DowntimeTrigger: 'DowntimeTrigger',
|
DowntimeTrigger: 'DowntimeTrigger',
|
||||||
|
|
@ -56,14 +60,14 @@ export const registerSocketHooks = () => {
|
||||||
const document = data.uuid ? await fromUuid(data.uuid) : null;
|
const document = data.uuid ? await fromUuid(data.uuid) : null;
|
||||||
switch (data.action) {
|
switch (data.action) {
|
||||||
case GMUpdateEvent.UpdateDocument:
|
case GMUpdateEvent.UpdateDocument:
|
||||||
if (document && data.update) await document.update(data.update);
|
if (document && data.data) await document.update(data.data);
|
||||||
break;
|
break;
|
||||||
case GMUpdateEvent.UpdateEffect:
|
case GMUpdateEvent.UpdateEffect:
|
||||||
if (document && data.update)
|
if (document && data.data)
|
||||||
await game.system.api.fields.ActionFields.EffectsField.applyEffects.call(document, data.update);
|
await game.system.api.fields.ActionFields.EffectsField.applyEffects.call(document, data.data);
|
||||||
break;
|
break;
|
||||||
case GMUpdateEvent.UpdateSetting:
|
case GMUpdateEvent.UpdateSetting:
|
||||||
await game.settings.set(CONFIG.DH.id, data.uuid, data.update);
|
await game.settings.set(CONFIG.DH.id, data.uuid, data.data);
|
||||||
break;
|
break;
|
||||||
case GMUpdateEvent.UpdateFear:
|
case GMUpdateEvent.UpdateFear:
|
||||||
await game.settings.set(
|
await game.settings.set(
|
||||||
|
|
@ -73,22 +77,22 @@ export const registerSocketHooks = () => {
|
||||||
0,
|
0,
|
||||||
Math.min(
|
Math.min(
|
||||||
game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Homebrew).maxFear,
|
game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Homebrew).maxFear,
|
||||||
data.update
|
data.data
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
case GMUpdateEvent.UpdateCountdowns:
|
case GMUpdateEvent.UpdateCountdowns:
|
||||||
await game.settings.set(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Countdowns, data.update);
|
await game.settings.set(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Countdowns, data.data);
|
||||||
Hooks.callAll(socketEvent.Refresh, { refreshType: RefreshType.Countdown });
|
Hooks.callAll(socketEvent.Refresh, { refreshType: RefreshType.Countdown });
|
||||||
break;
|
break;
|
||||||
case GMUpdateEvent.UpdateSaveMessage:
|
case GMUpdateEvent.UpdateSaveMessage:
|
||||||
const message = game.messages.get(data.update.message);
|
const message = game.messages.get(data.data.message);
|
||||||
if (!message) return;
|
if (!message) return;
|
||||||
game.system.api.fields.ActionFields.SaveField.updateSaveMessage(
|
game.system.api.fields.ActionFields.SaveField.updateSaveMessage(
|
||||||
data.update.result,
|
data.data.result,
|
||||||
message,
|
message,
|
||||||
data.update.token
|
data.data.token
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -102,6 +106,17 @@ export const registerSocketHooks = () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Hooks.on(socketEvent.GMCreate, async ({ data, documentType, scene }) => {
|
||||||
|
if (!game.user.isGM) return;
|
||||||
|
|
||||||
|
switch (documentType) {
|
||||||
|
default:
|
||||||
|
const cls = getDocumentClass(documentType);
|
||||||
|
cls.create(data, { parent: game.scenes.get(scene) });
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const registerUserQueries = () => {
|
export const registerUserQueries = () => {
|
||||||
|
|
@ -109,18 +124,21 @@ export const registerUserQueries = () => {
|
||||||
CONFIG.queries.reactionRoll = game.system.api.fields.ActionFields.SaveField.rollSaveQuery;
|
CONFIG.queries.reactionRoll = game.system.api.fields.ActionFields.SaveField.rollSaveQuery;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const emitAsGM = async (eventName, callback, update, uuid = null, refresh = null) => {
|
export const emitGMUpdate = async (eventName, callback, update, uuid = null, refresh = null) => {
|
||||||
|
return await emitAsGM(socketEvent.GMUpdate, { action: eventName, callback, data: update, uuid, refresh });
|
||||||
|
};
|
||||||
|
|
||||||
|
export const emitGMCreate = async (documentType, callback, data, scene) => {
|
||||||
|
return await emitAsGM(socketEvent.GMCreate, { documentType, callback, data, scene });
|
||||||
|
};
|
||||||
|
|
||||||
|
export const emitAsGM = async (event, data = { callback: () => {}, data: {} }) => {
|
||||||
if (!game.user.isGM) {
|
if (!game.user.isGM) {
|
||||||
return await game.socket.emit(`system.${CONFIG.DH.id}`, {
|
return await game.socket.emit(`system.${CONFIG.DH.id}`, {
|
||||||
action: socketEvent.GMUpdate,
|
action: event,
|
||||||
data: {
|
data: data
|
||||||
action: eventName,
|
|
||||||
uuid,
|
|
||||||
update,
|
|
||||||
refresh
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
} else return callback(update);
|
} else return data.callback(data.data);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const emitAsOwner = (eventName, userId, args) => {
|
export const emitAsOwner = (eventName, userId, args) => {
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,8 @@
|
||||||
"experiences": {
|
"experiences": {
|
||||||
"ti3Z1mq2M92KK4GJ": {
|
"ti3Z1mq2M92KK4GJ": {
|
||||||
"name": "Bloodthirsty",
|
"name": "Bloodthirsty",
|
||||||
"description": ""
|
"description": "",
|
||||||
|
"value": 3
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"bonuses": {
|
"bonuses": {
|
||||||
|
|
@ -242,27 +243,24 @@
|
||||||
"type": "withinRange",
|
"type": "withinRange",
|
||||||
"target": "hostile",
|
"target": "hostile",
|
||||||
"range": "melee"
|
"range": "melee"
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"_id": "qZfNiqw1iAIxeuYg",
|
|
||||||
"img": "icons/commodities/biological/wing-lizard-brown.webp",
|
|
||||||
"changes": [
|
"changes": [
|
||||||
{
|
{
|
||||||
"key": "system.difficulty",
|
"key": "system.difficulty",
|
||||||
"mode": 2,
|
"value": 3,
|
||||||
"value": "3",
|
"priority": null,
|
||||||
"priority": null
|
"type": "add"
|
||||||
}
|
}
|
||||||
],
|
]
|
||||||
|
},
|
||||||
|
"_id": "qZfNiqw1iAIxeuYg",
|
||||||
|
"img": "icons/commodities/biological/wing-lizard-brown.webp",
|
||||||
"disabled": false,
|
"disabled": false,
|
||||||
"duration": {
|
"duration": {
|
||||||
"startTime": null,
|
"value": null,
|
||||||
"combat": null,
|
"units": "seconds",
|
||||||
"seconds": null,
|
"expiry": null,
|
||||||
"rounds": null,
|
"expired": false
|
||||||
"turns": null,
|
|
||||||
"startRound": null,
|
|
||||||
"startTurn": null
|
|
||||||
},
|
},
|
||||||
"description": "<p>While flying, the Bat gains a +3 bonus to their Difficulty.</p>",
|
"description": "<p>While flying, the Bat gains a +3 bonus to their Difficulty.</p>",
|
||||||
"origin": null,
|
"origin": null,
|
||||||
|
|
@ -274,6 +272,9 @@
|
||||||
"_stats": {
|
"_stats": {
|
||||||
"compendiumSource": null
|
"compendiumSource": null
|
||||||
},
|
},
|
||||||
|
"start": null,
|
||||||
|
"showIcon": 1,
|
||||||
|
"folder": null,
|
||||||
"_key": "!actors.items.effects!tBWHW00epmMnkawe.gx22MpD8fWoi8klZ.qZfNiqw1iAIxeuYg"
|
"_key": "!actors.items.effects!tBWHW00epmMnkawe.gx22MpD8fWoi8klZ.qZfNiqw1iAIxeuYg"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|
|
||||||
|
|
@ -138,12 +138,9 @@
|
||||||
"src": "systems/daggerheart/assets/icons/documents/actors/dragon-head.svg",
|
"src": "systems/daggerheart/assets/icons/documents/actors/dragon-head.svg",
|
||||||
"anchorX": 0.5,
|
"anchorX": 0.5,
|
||||||
"anchorY": 0.5,
|
"anchorY": 0.5,
|
||||||
"offsetX": 0,
|
|
||||||
"offsetY": 0,
|
|
||||||
"fit": "contain",
|
"fit": "contain",
|
||||||
"scaleX": 1,
|
"scaleX": 1,
|
||||||
"scaleY": 1,
|
"scaleY": 1,
|
||||||
"rotation": 0,
|
|
||||||
"tint": "#ffffff",
|
"tint": "#ffffff",
|
||||||
"alphaThreshold": 0.75
|
"alphaThreshold": 0.75
|
||||||
},
|
},
|
||||||
|
|
@ -194,7 +191,7 @@
|
||||||
"saturation": 0,
|
"saturation": 0,
|
||||||
"contrast": 0
|
"contrast": 0
|
||||||
},
|
},
|
||||||
"detectionModes": [],
|
"detectionModes": {},
|
||||||
"occludable": {
|
"occludable": {
|
||||||
"radius": 0
|
"radius": 0
|
||||||
},
|
},
|
||||||
|
|
@ -220,7 +217,8 @@
|
||||||
"flags": {},
|
"flags": {},
|
||||||
"randomImg": false,
|
"randomImg": false,
|
||||||
"appendNumber": false,
|
"appendNumber": false,
|
||||||
"prependAdjective": false
|
"prependAdjective": false,
|
||||||
|
"depth": 1
|
||||||
},
|
},
|
||||||
"items": [
|
"items": [
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
"id": "daggerheart",
|
"id": "daggerheart",
|
||||||
"title": "Daggerheart",
|
"title": "Daggerheart",
|
||||||
"description": "An unofficial implementation of the Daggerheart system",
|
"description": "An unofficial implementation of the Daggerheart system",
|
||||||
"version": "2.2.1",
|
"version": "2.2.3",
|
||||||
"compatibility": {
|
"compatibility": {
|
||||||
"minimum": "14.359",
|
"minimum": "14.359",
|
||||||
"verified": "14.360",
|
"verified": "14.360",
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
},
|
},
|
||||||
"url": "https://github.com/Foundryborne/daggerheart",
|
"url": "https://github.com/Foundryborne/daggerheart",
|
||||||
"manifest": "https://raw.githubusercontent.com/Foundryborne/daggerheart/v14/system.json",
|
"manifest": "https://raw.githubusercontent.com/Foundryborne/daggerheart/v14/system.json",
|
||||||
"download": "https://github.com/Foundryborne/daggerheart/releases/download/2.2.1/system.zip",
|
"download": "https://github.com/Foundryborne/daggerheart/releases/download/2.2.3/system.zip",
|
||||||
"authors": [
|
"authors": [
|
||||||
{
|
{
|
||||||
"name": "WBHarry"
|
"name": "WBHarry"
|
||||||
|
|
|
||||||
38
templates/dialogs/tagTeamDialog/result.hbs
Normal file
38
templates/dialogs/tagTeamDialog/result.hbs
Normal file
|
|
@ -0,0 +1,38 @@
|
||||||
|
<section class="tag-team-roll tab {{#if tabs.tagTeamRoll.active}} active{{/if}}" data-group="{{tabs.tagTeamRoll.group}}" data-tab="{{tabs.tagTeamRoll.id}}">
|
||||||
|
<div class="tag-team-roll-container {{#unless isEditable}}inactive{{/unless}}">
|
||||||
|
<div class="results-container">
|
||||||
|
<span class="result-container-label">{{localize "DAGGERHEART.GENERAL.result.plural"}}</span>
|
||||||
|
<div class="results-inner-container">
|
||||||
|
{{#if hintText}}
|
||||||
|
<div class="hint">{{localize hintText}}</div>
|
||||||
|
{{else}}
|
||||||
|
{{#if joinedRoll.roll}}
|
||||||
|
<div class="result-container">
|
||||||
|
<span class="result-section-label">{{localize "DAGGERHEART.GENERAL.dualityRoll"}}</span>
|
||||||
|
<div class="result-info">
|
||||||
|
<div class="damage-info">{{joinedRoll.roll.total}}</div>
|
||||||
|
<div>{{localize "DAGGERHEART.GENERAL.withThing" thing=joinedRoll.roll.totalLabel}}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
{{#if joinedRoll.rollData.options.hasDamage}}
|
||||||
|
<div class="result-container">
|
||||||
|
<span class="result-section-label">{{localize "DAGGERHEART.GENERAL.damage"}}</span>
|
||||||
|
{{#each joinedRoll.rollData.options.damage as |damage key|}}
|
||||||
|
<div class="result-info">
|
||||||
|
<div>{{localize (concat "DAGGERHEART.CONFIG.HealingType." key ".name")}}</div>
|
||||||
|
<div class="damage-info">{{damage.total}}</div>
|
||||||
|
</div>
|
||||||
|
{{/each}}
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="finish-container">
|
||||||
|
<button type="button" data-action="cancelRoll">{{localize "DAGGERHEART.APPLICATIONS.TagTeamSelect.cancelTagTeamRoll"}}</button>
|
||||||
|
<button type="button" data-action="finishRoll" {{#if hintText}}disabled{{/if}} class="finish-button">{{localize "DAGGERHEART.APPLICATIONS.TagTeamSelect.finishTagTeamRoll"}}</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
@ -1,38 +1,9 @@
|
||||||
<section class="tag-team-roll tab {{#if tabs.tagTeamRoll.active}} active{{/if}}" data-group="{{tabs.tagTeamRoll.group}}" data-tab="{{tabs.tagTeamRoll.id}}">
|
<div class="tab {{#if tabs.tagTeamRoll.active}}active{{/if}}" data-group="{{tabs.tagTeamRoll.group}}" data-tab="{{tabs.tagTeamRoll.id}}">
|
||||||
<div class="tag-team-roll-container {{#unless isEditable}}inactive{{/unless}}">
|
<div class="team-container">
|
||||||
<div class="results-container">
|
{{#each memberKeys as |key|}}
|
||||||
<span class="result-container-label">{{localize "DAGGERHEART.GENERAL.result.plural"}}</span>
|
<div data-application-part="{{key}}"></div>
|
||||||
<div class="results-inner-container">
|
|
||||||
{{#if hintText}}
|
|
||||||
<div class="hint">{{localize hintText}}</div>
|
|
||||||
{{else}}
|
|
||||||
{{#if joinedRoll.roll}}
|
|
||||||
<div class="result-container">
|
|
||||||
<span class="result-section-label">{{localize "DAGGERHEART.GENERAL.dualityRoll"}}</span>
|
|
||||||
<div class="result-info">
|
|
||||||
<div class="damage-info">{{joinedRoll.roll.total}}</div>
|
|
||||||
<div>{{localize "DAGGERHEART.GENERAL.withThing" thing=joinedRoll.roll.totalLabel}}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{{/if}}
|
|
||||||
{{#if joinedRoll.rollData.options.hasDamage}}
|
|
||||||
<div class="result-container">
|
|
||||||
<span class="result-section-label">{{localize "DAGGERHEART.GENERAL.damage"}}</span>
|
|
||||||
{{#each joinedRoll.rollData.options.damage as |damage key|}}
|
|
||||||
<div class="result-info">
|
|
||||||
<div>{{localize (concat "DAGGERHEART.CONFIG.HealingType." key ".name")}}</div>
|
|
||||||
<div class="damage-info">{{damage.total}}</div>
|
|
||||||
</div>
|
|
||||||
{{/each}}
|
{{/each}}
|
||||||
</div>
|
</div>
|
||||||
{{/if}}
|
<div data-application-part="rollSelection"></div>
|
||||||
{{/if}}
|
<div data-application-part="result"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="finish-container">
|
|
||||||
<button type="button" data-action="cancelRoll">{{localize "DAGGERHEART.APPLICATIONS.TagTeamSelect.cancelTagTeamRoll"}}</button>
|
|
||||||
<button type="button" data-action="finishRoll" {{#if hintText}}disabled{{/if}} class="finish-button">{{localize "DAGGERHEART.APPLICATIONS.TagTeamSelect.finishTagTeamRoll"}}</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue