mirror of
https://github.com/Foundryborne/daggerheart.git
synced 2026-06-08 13:48:11 +02:00
Merge branch 'main' into feature/In-Front-Template
This commit is contained in:
commit
9454fe0525
14 changed files with 184 additions and 89 deletions
|
|
@ -18,6 +18,7 @@ import {
|
||||||
} from './module/systemRegistration/_module.mjs';
|
} from './module/systemRegistration/_module.mjs';
|
||||||
import { placeables } from './module/canvas/_module.mjs';
|
import { placeables } from './module/canvas/_module.mjs';
|
||||||
import { registerRollDiceHooks } from './module/dice/dhRoll.mjs';
|
import { registerRollDiceHooks } from './module/dice/dhRoll.mjs';
|
||||||
|
import { registerDHActorHooks } from './module/documents/actor.mjs';
|
||||||
|
|
||||||
Hooks.once('init', () => {
|
Hooks.once('init', () => {
|
||||||
CONFIG.DH = SYSTEM;
|
CONFIG.DH = SYSTEM;
|
||||||
|
|
@ -156,6 +157,7 @@ Hooks.on('ready', () => {
|
||||||
socketRegistration.registerSocketHooks();
|
socketRegistration.registerSocketHooks();
|
||||||
registerCountdownApplicationHooks();
|
registerCountdownApplicationHooks();
|
||||||
registerRollDiceHooks();
|
registerRollDiceHooks();
|
||||||
|
registerDHActorHooks();
|
||||||
});
|
});
|
||||||
|
|
||||||
Hooks.once('dicesoniceready', () => {});
|
Hooks.once('dicesoniceready', () => {});
|
||||||
|
|
|
||||||
|
|
@ -1132,6 +1132,7 @@
|
||||||
"examples": { "label": "Examples" },
|
"examples": { "label": "Examples" },
|
||||||
"advantageOn": { "label": "Gain Advantage On" },
|
"advantageOn": { "label": "Gain Advantage On" },
|
||||||
"tokenImg": { "label": "Token Image" },
|
"tokenImg": { "label": "Token Image" },
|
||||||
|
"tokenRingImg": { "label": "Subject Texture" },
|
||||||
"tokenSize": {
|
"tokenSize": {
|
||||||
"placeholder": "Using character dimensions",
|
"placeholder": "Using character dimensions",
|
||||||
"height": { "label": "Height" },
|
"height": { "label": "Height" },
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import { damageKeyToNumber, getDamageLabel } from '../../helpers/utils.mjs';
|
import { damageKeyToNumber, getDamageLabel } from '../../helpers/utils.mjs';
|
||||||
|
|
||||||
const { ApplicationV2, HandlebarsApplicationMixin } = foundry.applications.api;
|
const { DialogV2, ApplicationV2, HandlebarsApplicationMixin } = foundry.applications.api;
|
||||||
|
|
||||||
export default class DamageReductionDialog extends HandlebarsApplicationMixin(ApplicationV2) {
|
export default class DamageReductionDialog extends HandlebarsApplicationMixin(ApplicationV2) {
|
||||||
constructor(resolve, reject, actor, damage) {
|
constructor(resolve, reject, actor, damage) {
|
||||||
|
|
@ -122,7 +122,7 @@ export default class DamageReductionDialog extends HandlebarsApplicationMixin(Ap
|
||||||
getDamageInfo = () => {
|
getDamageInfo = () => {
|
||||||
const selectedArmorMarks = Object.values(this.marks.armor).filter(x => x.selected);
|
const selectedArmorMarks = Object.values(this.marks.armor).filter(x => x.selected);
|
||||||
const selectedStressMarks = Object.values(this.marks.stress).filter(x => x.selected);
|
const selectedStressMarks = Object.values(this.marks.stress).filter(x => x.selected);
|
||||||
const stressReductions = Object.values(this.availableStressReductions).filter(red => red.selected);
|
const stressReductions = Object.values(this.availableStressReductions ?? {}).filter(red => red.selected);
|
||||||
const currentMarks =
|
const currentMarks =
|
||||||
this.actor.system.armor.system.marks.value + selectedArmorMarks.length + selectedStressMarks.length;
|
this.actor.system.armor.system.marks.value + selectedArmorMarks.length + selectedStressMarks.length;
|
||||||
|
|
||||||
|
|
@ -210,9 +210,17 @@ export default class DamageReductionDialog extends HandlebarsApplicationMixin(Ap
|
||||||
|
|
||||||
async close(fromSave) {
|
async close(fromSave) {
|
||||||
if (!fromSave) {
|
if (!fromSave) {
|
||||||
this.reject();
|
this.resolve();
|
||||||
}
|
}
|
||||||
|
|
||||||
await super.close({});
|
await super.close({});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static async armorStackQuery({actorId, damage}) {
|
||||||
|
return new Promise(async (resolve, reject) => {
|
||||||
|
const actor = await fromUuid(actorId);
|
||||||
|
if(!actor || !actor?.isOwner) reject();
|
||||||
|
new DamageReductionDialog(resolve, reject, actor, damage).render({ force: true });
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -188,7 +188,17 @@ export default class CharacterSheet extends DHBaseActorSheet {
|
||||||
* @param {HTMLElement} el
|
* @param {HTMLElement} el
|
||||||
* @returns {foundry.documents.Item?}
|
* @returns {foundry.documents.Item?}
|
||||||
*/
|
*/
|
||||||
const getItem = el => this.actor.items.get(el.closest('[data-item-id]')?.dataset.itemId);
|
const getItem = element => {
|
||||||
|
const listElement = (element.target ?? element).closest('[data-item-id]');
|
||||||
|
const itemId = listElement.dataset.itemId;
|
||||||
|
|
||||||
|
switch (listElement.dataset.type) {
|
||||||
|
case 'effect':
|
||||||
|
return this.document.effects.get(itemId);
|
||||||
|
default:
|
||||||
|
return this.document.items.get(itemId);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -30,8 +30,17 @@ export default class BeastformSheet extends DHBaseItemSheet {
|
||||||
};
|
};
|
||||||
|
|
||||||
/**@inheritdoc */
|
/**@inheritdoc */
|
||||||
async _preparePartContext(partId, context) {
|
async _prepareContext(_options) {
|
||||||
await super._preparePartContext(partId, context);
|
const context = await super._prepareContext(_options);
|
||||||
|
|
||||||
|
context.document = context.document.toObject();
|
||||||
|
context.document.effects = this.document.effects.map(effect => {
|
||||||
|
const data = effect.toObject();
|
||||||
|
data.id = effect.id;
|
||||||
|
if (effect.type === 'beastform') data.mandatory = true;
|
||||||
|
|
||||||
|
return data;
|
||||||
|
});
|
||||||
|
|
||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -215,7 +215,7 @@ export default class DhpChatLog extends foundry.applications.sidebar.tabs.ChatLo
|
||||||
if (message.system.onSave && message.system.targets.find(t => t.id === target.id)?.saved?.success === true)
|
if (message.system.onSave && message.system.targets.find(t => t.id === target.id)?.saved?.success === true)
|
||||||
damage = Math.ceil(damage * (CONFIG.DH.ACTIONS.damageOnSave[message.system.onSave]?.mod ?? 1));
|
damage = Math.ceil(damage * (CONFIG.DH.ACTIONS.damageOnSave[message.system.onSave]?.mod ?? 1));
|
||||||
|
|
||||||
await target.actor.takeDamage(damage, message.system.roll.type);
|
target.actor.takeDamage(damage, message.system.roll.type);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -227,7 +227,7 @@ export default class DhpChatLog extends foundry.applications.sidebar.tabs.ChatLo
|
||||||
ui.notifications.info(game.i18n.localize('DAGGERHEART.UI.Notifications.noTargetsSelected'));
|
ui.notifications.info(game.i18n.localize('DAGGERHEART.UI.Notifications.noTargetsSelected'));
|
||||||
|
|
||||||
for (var target of targets) {
|
for (var target of targets) {
|
||||||
await target.actor.takeHealing([{ value: message.system.roll.total, type: message.system.roll.type }]);
|
target.actor.takeHealing([{ value: message.system.roll.total, type: message.system.roll.type }]);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,11 @@ export default class BeastformEffect extends foundry.abstract.TypeDataModel {
|
||||||
base64: false,
|
base64: false,
|
||||||
nullable: true
|
nullable: true
|
||||||
}),
|
}),
|
||||||
|
tokenRingImg: new fields.FilePathField({
|
||||||
|
initial: 'icons/svg/mystery-man.svg',
|
||||||
|
categories: ['IMAGE'],
|
||||||
|
base64: false
|
||||||
|
}),
|
||||||
tokenSize: new fields.SchemaField({
|
tokenSize: new fields.SchemaField({
|
||||||
height: new fields.NumberField({ integer: true, nullable: true }),
|
height: new fields.NumberField({ integer: true, nullable: true }),
|
||||||
width: new fields.NumberField({ integer: true, nullable: true })
|
width: new fields.NumberField({ integer: true, nullable: true })
|
||||||
|
|
@ -28,6 +33,11 @@ export default class BeastformEffect extends foundry.abstract.TypeDataModel {
|
||||||
width: this.characterTokenData.tokenSize.width,
|
width: this.characterTokenData.tokenSize.width,
|
||||||
texture: {
|
texture: {
|
||||||
src: this.characterTokenData.tokenImg
|
src: this.characterTokenData.tokenImg
|
||||||
|
},
|
||||||
|
ring: {
|
||||||
|
subject: {
|
||||||
|
texture: this.characterTokenData.tokenRingImg
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ import ForeignDocumentUUIDArrayField from '../fields/foreignDocumentUUIDArrayFie
|
||||||
import BaseDataItem from './base.mjs';
|
import BaseDataItem from './base.mjs';
|
||||||
|
|
||||||
export default class DHBeastform extends BaseDataItem {
|
export default class DHBeastform extends BaseDataItem {
|
||||||
static LOCALIZATION_PREFIXES = ['DAGGERHEART.Sheets.Beastform'];
|
static LOCALIZATION_PREFIXES = ['DAGGERHEART.ITEMS.Beastform'];
|
||||||
|
|
||||||
/** @inheritDoc */
|
/** @inheritDoc */
|
||||||
static get metadata() {
|
static get metadata() {
|
||||||
|
|
@ -29,12 +29,17 @@ export default class DHBeastform extends BaseDataItem {
|
||||||
categories: ['IMAGE'],
|
categories: ['IMAGE'],
|
||||||
base64: false
|
base64: false
|
||||||
}),
|
}),
|
||||||
|
tokenRingImg: new fields.FilePathField({
|
||||||
|
initial: 'icons/svg/mystery-man.svg',
|
||||||
|
categories: ['IMAGE'],
|
||||||
|
base64: false
|
||||||
|
}),
|
||||||
tokenSize: new fields.SchemaField({
|
tokenSize: new fields.SchemaField({
|
||||||
height: new fields.NumberField({ integer: true, min: 1, initial: null, nullable: true }),
|
height: new fields.NumberField({ integer: true, min: 1, initial: null, nullable: true }),
|
||||||
width: new fields.NumberField({ integer: true, min: 1, initial: null, nullable: true })
|
width: new fields.NumberField({ integer: true, min: 1, initial: null, nullable: true })
|
||||||
}),
|
}),
|
||||||
examples: new fields.StringField(),
|
examples: new fields.StringField(),
|
||||||
advantageOn: new fields.ArrayField(new fields.StringField()),
|
advantageOn: new fields.StringField(),
|
||||||
features: new ForeignDocumentUUIDArrayField({ type: 'Item' })
|
features: new ForeignDocumentUUIDArrayField({ type: 'Item' })
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
@ -56,40 +61,54 @@ export default class DHBeastform extends BaseDataItem {
|
||||||
'Item',
|
'Item',
|
||||||
this.features.map(x => x.toObject())
|
this.features.map(x => x.toObject())
|
||||||
);
|
);
|
||||||
const effects = await this.parent.parent.createEmbeddedDocuments(
|
|
||||||
|
const extraEffects = await this.parent.parent.createEmbeddedDocuments(
|
||||||
'ActiveEffect',
|
'ActiveEffect',
|
||||||
this.parent.effects.map(x => x.toObject())
|
this.parent.effects.filter(x => x.type !== 'beastform').map(x => x.toObject())
|
||||||
);
|
);
|
||||||
|
|
||||||
await this.parent.parent.createEmbeddedDocuments('ActiveEffect', [
|
const beastformEffect = this.parent.effects.find(x => x.type === 'beastform');
|
||||||
{
|
await beastformEffect.updateSource({
|
||||||
type: 'beastform',
|
system: {
|
||||||
name: game.i18n.localize('DAGGERHEART.ITEMS.Beastform.beastformEffect'),
|
characterTokenData: {
|
||||||
img: 'icons/creatures/abilities/paw-print-pair-purple.webp',
|
tokenImg: this.parent.parent.prototypeToken.texture.src,
|
||||||
system: {
|
tokenRingImg: this.parent.parent.prototypeToken.ring.subject.texture,
|
||||||
isBeastform: true,
|
tokenSize: {
|
||||||
characterTokenData: {
|
height: this.parent.parent.prototypeToken.height,
|
||||||
tokenImg: this.parent.parent.prototypeToken.texture.src,
|
width: this.parent.parent.prototypeToken.width
|
||||||
tokenSize: {
|
}
|
||||||
height: this.parent.parent.prototypeToken.height,
|
},
|
||||||
width: this.parent.parent.prototypeToken.width
|
advantageOn: this.advantageOn,
|
||||||
}
|
featureIds: features.map(x => x.id),
|
||||||
},
|
effectIds: extraEffects.map(x => x.id)
|
||||||
advantageOn: this.advantageOn,
|
|
||||||
featureIds: features.map(x => x.id),
|
|
||||||
effectIds: effects.map(x => x.id)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
]);
|
});
|
||||||
|
|
||||||
|
await this.parent.parent.createEmbeddedDocuments('ActiveEffect', [beastformEffect.toObject()]);
|
||||||
|
|
||||||
await updateActorTokens(this.parent.parent, {
|
await updateActorTokens(this.parent.parent, {
|
||||||
height: this.tokenSize.height,
|
height: this.tokenSize.height,
|
||||||
width: this.tokenSize.width,
|
width: this.tokenSize.width,
|
||||||
texture: {
|
texture: {
|
||||||
src: this.tokenImg
|
src: this.tokenImg
|
||||||
|
},
|
||||||
|
ring: {
|
||||||
|
subject: {
|
||||||
|
texture: this.tokenRingImg
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_onCreate() {
|
||||||
|
this.parent.createEmbeddedDocuments('ActiveEffect', [
|
||||||
|
{
|
||||||
|
type: 'beastform',
|
||||||
|
name: game.i18n.localize('DAGGERHEART.ITEMS.Beastform.beastformEffect'),
|
||||||
|
img: 'icons/creatures/abilities/paw-print-pair-purple.webp'
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,19 @@
|
||||||
import DamageSelectionDialog from '../applications/dialogs/damageSelectionDialog.mjs';
|
import DamageSelectionDialog from '../applications/dialogs/damageSelectionDialog.mjs';
|
||||||
import { GMUpdateEvent, socketEvent } from '../systemRegistration/socket.mjs';
|
import { emitAsGM, emitAsOwner, GMUpdateEvent, socketEvent } from '../systemRegistration/socket.mjs';
|
||||||
import DamageReductionDialog from '../applications/dialogs/damageReductionDialog.mjs';
|
import DamageReductionDialog from '../applications/dialogs/damageReductionDialog.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';
|
||||||
|
|
||||||
export default class DhpActor extends foundry.documents.Actor {
|
export default class DhpActor extends Actor {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the first Actor active owner.
|
||||||
|
*/
|
||||||
|
get owner() {
|
||||||
|
const user = this.hasPlayerOwner && game.users.players.find(u => this.testUserPermission(u, "OWNER") && u.active);;
|
||||||
|
if(!user) return game.user.isGM ? game.user : null;
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether this actor is an NPC.
|
* Whether this actor is an NPC.
|
||||||
|
|
@ -440,49 +449,40 @@ export default class DhpActor extends foundry.documents.Actor {
|
||||||
}
|
}
|
||||||
|
|
||||||
async takeDamage(damage, type) {
|
async takeDamage(damage, type) {
|
||||||
|
if (Hooks.call(`${CONFIG.DH.id}.preTakeDamage`, this, damage, type) === false) return null;
|
||||||
|
|
||||||
if (this.type === 'companion') {
|
if (this.type === 'companion') {
|
||||||
await this.modifyResource([{ value: 1, type: 'stress' }]);
|
await this.modifyResource([{ value: 1, type: 'stress' }]);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const hpDamage =
|
const hpDamage = this.convertDamageToThreshold(damage);
|
||||||
damage >= this.system.damageThresholds.severe
|
|
||||||
? 3
|
if (Hooks.call(`${CONFIG.DH.id}.postDamageTreshold`, this, hpDamage, damage, type) === false) return null;
|
||||||
: damage >= this.system.damageThresholds.major
|
|
||||||
? 2
|
if(!hpDamage) return;
|
||||||
: damage >= this.system.damageThresholds.minor
|
|
||||||
? 1
|
const updates = [{ value: hpDamage, type: 'hitPoints' }];
|
||||||
: 0;
|
|
||||||
|
|
||||||
if (
|
if (
|
||||||
this.type === 'character' &&
|
this.type === 'character' &&
|
||||||
this.system.armor &&
|
this.system.armor &&
|
||||||
this.system.armor.system.marks.value < this.system.armorScore
|
this.system.armor.system.marks.value < this.system.armorScore
|
||||||
) {
|
) {
|
||||||
new Promise((resolve, reject) => {
|
const armorStackResult = await this.owner.query('armorStack', {actorId: this.uuid, damage: hpDamage});
|
||||||
new DamageReductionDialog(resolve, reject, this, hpDamage).render(true);
|
if(armorStackResult) {
|
||||||
})
|
const { modifiedDamage, armorSpent, stressSpent } = armorStackResult;
|
||||||
.then(async ({ modifiedDamage, armorSpent, stressSpent }) => {
|
updates.find(u => u.type === 'hitPoints').value = modifiedDamage;
|
||||||
const resources = [
|
updates.push(
|
||||||
{ value: modifiedDamage, type: 'hitPoints' },
|
...(armorSpent ? [{ value: armorSpent, type: 'armorStack' }] : []),
|
||||||
...(armorSpent ? [{ value: armorSpent, type: 'armorStack' }] : []),
|
...(stressSpent ? [{ value: stressSpent, type: 'stress' }] : [])
|
||||||
...(stressSpent ? [{ value: stressSpent, type: 'stress' }] : [])
|
);
|
||||||
];
|
}
|
||||||
await this.modifyResource(resources);
|
|
||||||
})
|
|
||||||
.catch(() => {
|
|
||||||
const cls = getDocumentClass('ChatMessage');
|
|
||||||
const msg = new cls({
|
|
||||||
user: game.user.id,
|
|
||||||
content: game.i18n.format('DAGGERHEART.UI.Notifications.damageIgnore', {
|
|
||||||
character: this.name
|
|
||||||
})
|
|
||||||
});
|
|
||||||
cls.create(msg.toObject());
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
await this.modifyResource([{ value: hpDamage, type: 'hitPoints' }]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
await this.modifyResource(updates);
|
||||||
|
|
||||||
|
if (Hooks.call(`${CONFIG.DH.id}.postTakeDamage`, this, damage, type) === false) return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
async takeHealing(resources) {
|
async takeHealing(resources) {
|
||||||
|
|
@ -492,6 +492,8 @@ export default class DhpActor extends foundry.documents.Actor {
|
||||||
|
|
||||||
async modifyResource(resources) {
|
async modifyResource(resources) {
|
||||||
if (!resources.length) return;
|
if (!resources.length) return;
|
||||||
|
|
||||||
|
if(resources.find(r => r.type === 'stress')) this.convertStressDamageToHP(resources);
|
||||||
let updates = { actor: { target: this, resources: {} }, armor: { target: this.system.armor, resources: {} } };
|
let updates = { actor: { target: this, resources: {} }, armor: { target: this.system.armor, resources: {} } };
|
||||||
resources.forEach(r => {
|
resources.forEach(r => {
|
||||||
switch (r.type) {
|
switch (r.type) {
|
||||||
|
|
@ -519,7 +521,8 @@ export default class DhpActor extends foundry.documents.Actor {
|
||||||
});
|
});
|
||||||
Object.values(updates).forEach(async u => {
|
Object.values(updates).forEach(async u => {
|
||||||
if (Object.keys(u.resources).length > 0) {
|
if (Object.keys(u.resources).length > 0) {
|
||||||
if (game.user.isGM) {
|
await emitAsGM(GMUpdateEvent.UpdateDocument, u.target.update.bind(u.target), u.resources, u.target.uuid);
|
||||||
|
/* if (game.user.isGM) {
|
||||||
await u.target.update(u.resources);
|
await u.target.update(u.resources);
|
||||||
} else {
|
} else {
|
||||||
await game.socket.emit(`system.${CONFIG.DH.id}`, {
|
await game.socket.emit(`system.${CONFIG.DH.id}`, {
|
||||||
|
|
@ -530,8 +533,34 @@ export default class DhpActor extends foundry.documents.Actor {
|
||||||
update: u.resources
|
update: u.resources
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
} */
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
convertDamageToThreshold(damage) {
|
||||||
|
return damage >= this.system.damageThresholds.severe
|
||||||
|
? 3
|
||||||
|
: damage >= this.system.damageThresholds.major
|
||||||
|
? 2
|
||||||
|
: damage >= this.system.damageThresholds.minor
|
||||||
|
? 1
|
||||||
|
: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
convertStressDamageToHP(resources) {
|
||||||
|
const stressDamage = resources.find(r => r.type === 'stress'),
|
||||||
|
newValue = this.system.resources.stress.value + stressDamage.value;
|
||||||
|
if(newValue <= this.system.resources.stress.maxTotal) return;
|
||||||
|
const hpDamage = resources.find(r => r.type === 'hitPoints');
|
||||||
|
if(hpDamage) hpDamage.value++;
|
||||||
|
else resources.push({
|
||||||
|
type: 'hitPoints',
|
||||||
|
value: 1
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const registerDHActorHooks = () => {
|
||||||
|
CONFIG.queries.armorStack = DamageReductionDialog.armorStackQuery;
|
||||||
|
}
|
||||||
|
|
@ -63,21 +63,28 @@ export const registerSocketHooks = () => {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const emitAsGM = async (eventName, callback, args) => {
|
export const emitAsGM = async (eventName, callback, update, uuid = null) => {
|
||||||
if(!game.user.isGM) {
|
if(!game.user.isGM) {
|
||||||
return new Promise(async (resolve, reject) => {
|
return await game.socket.emit(`system.${CONFIG.DH.id}`, {
|
||||||
try {
|
action: socketEvent.GMUpdate,
|
||||||
const response = await game.socket.emit(`system.${CONFIG.DH.id}`, {
|
data: {
|
||||||
action: socketEvent.GMUpdate,
|
action: eventName,
|
||||||
data: {
|
uuid,
|
||||||
action: eventName,
|
update
|
||||||
update: args
|
|
||||||
}
|
|
||||||
});
|
|
||||||
resolve(response);
|
|
||||||
} catch (error) {
|
|
||||||
reject(error);
|
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
} else return callback(args);
|
} else return callback(update);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const emitAsOwner = (eventName, userId, args) => {
|
||||||
|
if(userId === game.user.id) return;
|
||||||
|
if(!eventName || !userId) return false;
|
||||||
|
game.socket.emit(`system.${CONFIG.DH.id}`, {
|
||||||
|
action: eventName,
|
||||||
|
data: {
|
||||||
|
userId,
|
||||||
|
...args
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
<span>{{effect.name}}</span>
|
<span>{{effect.name}}</span>
|
||||||
<div class="controls">
|
<div class="controls">
|
||||||
<a data-action="editDoc" data-type="ActiveEffect" data-doc-id="{{effect.id}}"><i class="fa-solid fa-pen-to-square"></i></a>
|
<a data-action="editDoc" data-type="ActiveEffect" data-doc-id="{{effect.id}}"><i class="fa-solid fa-pen-to-square"></i></a>
|
||||||
<a data-action="deleteDoc" data-type="ActiveEffect" data-doc-id="{{effect.id}}"><i class="fa-solid fa-trash"></i></a>
|
<a data-action="deleteDoc" data-type="ActiveEffect" data-doc-id="{{effect.id}}" {{disabled effect.mandatory}}><i class="fa-solid fa-trash icon-button {{disabled effect.mandatory}}"></i></a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{{/each}}
|
{{/each}}
|
||||||
|
|
|
||||||
|
|
@ -8,11 +8,7 @@
|
||||||
{{formGroup systemFields.examples value=source.system.examples localize=true}}
|
{{formGroup systemFields.examples value=source.system.examples localize=true}}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<fieldset class="two-columns">
|
{{formGroup systemFields.advantageOn value=source.system.advantageOn localize=true}}
|
||||||
<legend>{{localize "DAGGERHEART.ITEMS.Beastform.FIELDS.advantageOn.label"}}</legend>
|
|
||||||
|
|
||||||
{{!-- {{formGroup systemFields.examples value=source.system.examples localize=true}} --}}
|
|
||||||
</fieldset>
|
|
||||||
|
|
||||||
<fieldset class="two-columns even">
|
<fieldset class="two-columns even">
|
||||||
<legend>{{localize "DAGGERHEART.ITEMS.Beastform.tokenTitle"}}</legend>
|
<legend>{{localize "DAGGERHEART.ITEMS.Beastform.tokenTitle"}}</legend>
|
||||||
|
|
@ -21,6 +17,10 @@
|
||||||
{{formGroup systemFields.tokenImg value=source.system.tokenImg localize=true}}
|
{{formGroup systemFields.tokenImg value=source.system.tokenImg localize=true}}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="full-width">
|
||||||
|
{{formGroup systemFields.tokenRingImg value=source.system.tokenRingImg localize=true}}
|
||||||
|
</div>
|
||||||
|
|
||||||
{{formGroup systemFields.tokenSize.fields.height value=source.system.tokenSize.height localize=true placeholder=(localize "DAGGERHEART.ITEMS.Beastform.FIELDS.tokenSize.placeholder") }}
|
{{formGroup systemFields.tokenSize.fields.height value=source.system.tokenSize.height localize=true placeholder=(localize "DAGGERHEART.ITEMS.Beastform.FIELDS.tokenSize.placeholder") }}
|
||||||
{{formGroup systemFields.tokenSize.fields.width value=source.system.tokenSize.width localize=true placeholder=(localize "DAGGERHEART.ITEMS.Beastform.FIELDS.tokenSize.placeholder")}}
|
{{formGroup systemFields.tokenSize.fields.width value=source.system.tokenSize.width localize=true placeholder=(localize "DAGGERHEART.ITEMS.Beastform.FIELDS.tokenSize.placeholder")}}
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,7 @@
|
||||||
<div class="dice-result">
|
<div class="dice-result">
|
||||||
{{#if damage.roll}}
|
{{#if damage.roll}}
|
||||||
<div class="dice-actions">
|
<div class="dice-actions">
|
||||||
<button class="damage-button">{{localize "DAGGERHEART.UI.Chat.DamageRoll.dealDamage"}}</button>
|
<button class="damage-button">{{localize "DAGGERHEART.UI.Chat.damageRoll.dealDamage"}}</button>
|
||||||
</div>
|
</div>
|
||||||
{{else}}
|
{{else}}
|
||||||
<div class="flexrow">
|
<div class="flexrow">
|
||||||
|
|
|
||||||
|
|
@ -134,7 +134,7 @@
|
||||||
<div class="dice-actions{{#unless (or hasDamage hasHealing)}} duality-alone{{/unless}}">
|
<div class="dice-actions{{#unless (or hasDamage hasHealing)}} duality-alone{{/unless}}">
|
||||||
{{#if hasDamage}}
|
{{#if hasDamage}}
|
||||||
{{#if damage.roll}}
|
{{#if damage.roll}}
|
||||||
<button class="duality-action damage-button" data-target-hit="true" data-value="{{roll.total}}"><span>Deal Damage</span></button>
|
<button class="duality-action damage-button" data-target-hit="true" data-value="{{roll.total}}"><span>{{localize "DAGGERHEART.UI.Chat.damageRoll.dealDamage"}}</span></button>
|
||||||
{{else}}
|
{{else}}
|
||||||
<button class="duality-action duality-action-damage" data-value="{{roll.total}}"><span>{{localize "DAGGERHEART.UI.Chat.attackRoll.rollDamage"}}</span></button>
|
<button class="duality-action duality-action-damage" data-value="{{roll.total}}"><span>{{localize "DAGGERHEART.UI.Chat.attackRoll.rollDamage"}}</span></button>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue