mirror of
https://github.com/Foundryborne/daggerheart.git
synced 2026-03-07 14:36:13 +01:00
Merge branch 'v14-Dev' into v14/conditional-effects
This commit is contained in:
commit
1ba08e2f51
81 changed files with 503 additions and 140 deletions
|
|
@ -112,7 +112,10 @@ export default class DhSceneConfigSettings extends foundry.applications.sheets.S
|
|||
/** @override */
|
||||
async _processSubmitData(event, form, submitData, options) {
|
||||
if (!submitData.flags) submitData.flags = {};
|
||||
submitData.flags.daggerheart = this.daggerheartFlag.toObject();
|
||||
submitData.flags.daggerheart = foundry.utils.mergeObject(
|
||||
this.daggerheartFlag.toObject(),
|
||||
submitData.flags.daggerheart
|
||||
);
|
||||
submitData.flags.daggerheart.sceneEnvironments = submitData.flags.daggerheart.sceneEnvironments.filter(x =>
|
||||
foundry.utils.fromUuidSync(x)
|
||||
);
|
||||
|
|
|
|||
|
|
@ -68,9 +68,9 @@ export default class DHEnvironmentSettings extends DHBaseActorSettings {
|
|||
*/
|
||||
static async #addCategory() {
|
||||
await this.actor.update({
|
||||
[`system.potentialAdversaries.${foundry.utils.randomID()}.label`]: game.i18n.localize(
|
||||
'DAGGERHEART.ACTORS.Environment.newAdversary'
|
||||
)
|
||||
[`system.potentialAdversaries.${foundry.utils.randomID()}`]: {
|
||||
label: game.i18n.localize('DAGGERHEART.ACTORS.Environment.newAdversary')
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -138,4 +138,8 @@ export default class DHEnvironmentSettings extends DHBaseActorSettings {
|
|||
this.render();
|
||||
}
|
||||
}
|
||||
|
||||
async _onDropItem(event, item) {
|
||||
console.log(item);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -404,18 +404,18 @@ export default function DHApplicationMixin(Base) {
|
|||
{
|
||||
name: 'disableEffect',
|
||||
icon: 'fa-solid fa-lightbulb',
|
||||
condition: target => {
|
||||
const doc = getDocFromElementSync(target);
|
||||
return doc && !doc.disabled && doc.type !== 'beastform';
|
||||
condition: element => {
|
||||
const target = element.closest('[data-item-uuid]');
|
||||
return !target.dataset.disabled && target.dataset.itemType !== 'beastform';
|
||||
},
|
||||
callback: async target => (await getDocFromElement(target)).update({ disabled: true })
|
||||
},
|
||||
{
|
||||
name: 'enableEffect',
|
||||
icon: 'fa-regular fa-lightbulb',
|
||||
condition: target => {
|
||||
const doc = getDocFromElementSync(target);
|
||||
return doc && doc.disabled && doc.type !== 'beastform';
|
||||
condition: element => {
|
||||
const target = element.closest('[data-item-uuid]');
|
||||
return target.dataset.disabled && target.dataset.itemType !== 'beastform';
|
||||
},
|
||||
callback: async target => (await getDocFromElement(target)).update({ disabled: false })
|
||||
}
|
||||
|
|
@ -509,9 +509,9 @@ export default function DHApplicationMixin(Base) {
|
|||
options.push({
|
||||
name: 'CONTROLS.CommonDelete',
|
||||
icon: 'fa-solid fa-trash',
|
||||
condition: target => {
|
||||
const doc = getDocFromElementSync(target);
|
||||
return doc && doc.type !== 'beastform';
|
||||
condition: element => {
|
||||
const target = element.closest('[data-item-uuid]');
|
||||
return target.dataset.itemType !== 'beastform';
|
||||
},
|
||||
callback: async (target, event) => {
|
||||
const doc = await getDocFromElement(target);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
export { default as DhMeasuredTemplate } from './measuredTemplate.mjs';
|
||||
export { default as DhRuler } from './ruler.mjs';
|
||||
export { default as DhRegion } from './region.mjs';
|
||||
export { default as DhRegionLayer } from './regionLayer.mjs';
|
||||
export { default as DhTokenPlaceable } from './token.mjs';
|
||||
export { default as DhTokenRuler } from './tokenRuler.mjs';
|
||||
|
|
|
|||
12
module/canvas/placeables/region.mjs
Normal file
12
module/canvas/placeables/region.mjs
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
import DhMeasuredTemplate from './measuredTemplate.mjs';
|
||||
|
||||
export default class DhRegion extends foundry.canvas.placeables.Region {
|
||||
/**@inheritdoc */
|
||||
_formatMeasuredDistance(distance) {
|
||||
const range = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.variantRules).rangeMeasurement;
|
||||
if (!range.enabled) return super._formatMeasuredDistance(distance);
|
||||
|
||||
const { distance: resultDistance, units } = DhMeasuredTemplate.getRangeLabels(distance, range);
|
||||
return `${resultDistance} ${units}`;
|
||||
}
|
||||
}
|
||||
|
|
@ -55,30 +55,58 @@ export default class DhTokenPlaceable extends foundry.canvas.placeables.Token {
|
|||
if (this === target) return 0;
|
||||
|
||||
const originPoint = this.center;
|
||||
const destinationPoint = target.center;
|
||||
const targetPoint = target.center;
|
||||
const thisBounds = this.bounds;
|
||||
const targetBounds = target.bounds;
|
||||
const adjacencyBuffer = canvas.grid.distance * 1.75; // handles diagonals with one square elevation difference
|
||||
|
||||
// Figure out the elevation difference.
|
||||
// This intends to return "grid distance" for adjacent ones, so we add that number if not overlapping.
|
||||
const sizePerUnit = canvas.grid.size / canvas.grid.distance;
|
||||
const thisHeight = Math.max(thisBounds.width, thisBounds.height) / sizePerUnit;
|
||||
const targetHeight = Math.max(targetBounds.width, targetBounds.height) / sizePerUnit;
|
||||
const thisElevation = [this.document.elevation, this.document.elevation + thisHeight];
|
||||
const targetElevation = [target.document.elevation, target.document.elevation + targetHeight];
|
||||
const isSameAltitude =
|
||||
thisElevation[0] < targetElevation[1] && // bottom of this must be at or below the top of target
|
||||
thisElevation[1] > targetElevation[0]; // top of this must be at or above the bottom of target
|
||||
const [lower, higher] = [targetElevation, thisElevation].sort((a, b) => a[1] - b[1]);
|
||||
const elevation = isSameAltitude ? 0 : higher[0] - lower[1] + canvas.grid.distance;
|
||||
|
||||
// Compute for gridless. This version returns circular edge to edge + grid distance,
|
||||
// so that tokens that are touching return 5.
|
||||
if (canvas.grid.type === CONST.GRID_TYPES.GRIDLESS) {
|
||||
const boundsCorrection = canvas.grid.distance / canvas.grid.size;
|
||||
const originRadius = (this.bounds.width * boundsCorrection) / 2;
|
||||
const targetRadius = (target.bounds.width * boundsCorrection) / 2;
|
||||
const distance = canvas.grid.measurePath([originPoint, destinationPoint]).distance;
|
||||
return Math.floor(distance - originRadius - targetRadius + canvas.grid.distance);
|
||||
const originRadius = (thisBounds.width * boundsCorrection) / 2;
|
||||
const targetRadius = (targetBounds.width * boundsCorrection) / 2;
|
||||
const measuredDistance = canvas.grid.measurePath([
|
||||
{ ...originPoint, elevation: 0 },
|
||||
{ ...targetPoint, elevation }
|
||||
]).distance;
|
||||
const distance = Math.floor(measuredDistance - originRadius - targetRadius + canvas.grid.distance);
|
||||
return Math.min(distance, distance > adjacencyBuffer ? Infinity : canvas.grid.distance);
|
||||
}
|
||||
|
||||
// Compute what the closest grid space of each token is, then compute that distance
|
||||
const originEdge = this.#getEdgeBoundary(this.bounds, originPoint, destinationPoint);
|
||||
const targetEdge = this.#getEdgeBoundary(target.bounds, originPoint, destinationPoint);
|
||||
const adjustedOriginPoint = canvas.grid.getTopLeftPoint({
|
||||
x: originEdge.x + Math.sign(originPoint.x - originEdge.x),
|
||||
y: originEdge.y + Math.sign(originPoint.y - originEdge.y)
|
||||
});
|
||||
const adjustDestinationPoint = canvas.grid.getTopLeftPoint({
|
||||
x: targetEdge.x + Math.sign(destinationPoint.x - targetEdge.x),
|
||||
y: targetEdge.y + Math.sign(destinationPoint.y - targetEdge.y)
|
||||
});
|
||||
return canvas.grid.measurePath([adjustedOriginPoint, adjustDestinationPoint]).distance;
|
||||
const originEdge = this.#getEdgeBoundary(thisBounds, originPoint, targetPoint);
|
||||
const targetEdge = this.#getEdgeBoundary(targetBounds, originPoint, targetPoint);
|
||||
const adjustedOriginPoint = originEdge
|
||||
? canvas.grid.getTopLeftPoint({
|
||||
x: originEdge.x + Math.sign(originPoint.x - originEdge.x),
|
||||
y: originEdge.y + Math.sign(originPoint.y - originEdge.y)
|
||||
})
|
||||
: originPoint;
|
||||
const adjustDestinationPoint = targetEdge
|
||||
? canvas.grid.getTopLeftPoint({
|
||||
x: targetEdge.x + Math.sign(targetPoint.x - targetEdge.x),
|
||||
y: targetEdge.y + Math.sign(targetPoint.y - targetEdge.y)
|
||||
})
|
||||
: targetPoint;
|
||||
const distance = canvas.grid.measurePath([
|
||||
{ ...adjustedOriginPoint, elevation: 0 },
|
||||
{ ...adjustDestinationPoint, elevation }
|
||||
]).distance;
|
||||
return Math.min(distance, distance > adjacencyBuffer ? Infinity : canvas.grid.distance);
|
||||
}
|
||||
|
||||
_onHoverIn(event, options) {
|
||||
|
|
@ -104,8 +132,7 @@ export default class DhTokenPlaceable extends foundry.canvas.placeables.Token {
|
|||
|
||||
// Determine the actual range
|
||||
const ranges = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.variantRules).rangeMeasurement;
|
||||
const distanceNum = originToken.distanceTo(this);
|
||||
const distanceResult = DhMeasuredTemplate.getRangeLabels(distanceNum, ranges);
|
||||
const distanceResult = DhMeasuredTemplate.getRangeLabels(originToken.distanceTo(this), ranges);
|
||||
const distanceLabel = `${distanceResult.distance} ${distanceResult.units}`.trim();
|
||||
|
||||
// Create the element
|
||||
|
|
@ -157,11 +184,6 @@ export default class DhTokenPlaceable extends foundry.canvas.placeables.Token {
|
|||
return null;
|
||||
}
|
||||
|
||||
/** Tests if the token is at least adjacent with another, with some leeway for diagonals */
|
||||
isAdjacentWith(token) {
|
||||
return this.distanceTo(token) <= canvas.grid.distance * 1.5;
|
||||
}
|
||||
|
||||
/** @inheritDoc */
|
||||
_drawBar(number, bar, data) {
|
||||
const val = Number(data.value);
|
||||
|
|
|
|||
|
|
@ -74,8 +74,8 @@ export const range = {
|
|||
export const templateTypes = {
|
||||
CIRCLE: 'circle',
|
||||
CONE: 'cone',
|
||||
RECTANGLE: 'rect',
|
||||
RAY: 'ray',
|
||||
RECTANGLE: 'rectangle',
|
||||
LINE: 'line',
|
||||
EMANATION: 'emanation',
|
||||
INFRONT: 'inFront'
|
||||
};
|
||||
|
|
|
|||
|
|
@ -190,6 +190,10 @@ export default class DhpAdversary extends DhCreature {
|
|||
}
|
||||
}
|
||||
|
||||
prepareDerivedData() {
|
||||
this.attack.roll.isStandardAttack = true;
|
||||
}
|
||||
|
||||
_getTags() {
|
||||
const tags = [
|
||||
game.i18n.localize(`DAGGERHEART.GENERAL.Tiers.${this.tier}`),
|
||||
|
|
|
|||
|
|
@ -670,7 +670,7 @@ export default class DhCharacter extends DhCreature {
|
|||
};
|
||||
|
||||
const globalHopeMax = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Homebrew).maxHope;
|
||||
this.resources.hope.max = globalHopeMax - this.scars;
|
||||
this.resources.hope.max = globalHopeMax;
|
||||
this.resources.hitPoints.max += this.class.value?.system?.hitPoints ?? 0;
|
||||
|
||||
/* Companion Related Data */
|
||||
|
|
@ -694,6 +694,7 @@ export default class DhCharacter extends DhCreature {
|
|||
}
|
||||
}
|
||||
|
||||
this.resources.hope.max -= this.scars;
|
||||
this.resources.hope.value = Math.min(baseHope, this.resources.hope.max);
|
||||
this.attack.roll.trait = this.rules.attack.roll.trait ?? this.attack.roll.trait;
|
||||
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ export default class DhEnvironment extends BaseDataActor {
|
|||
potentialAdversaries: new fields.TypedObjectField(
|
||||
new fields.SchemaField({
|
||||
label: new fields.StringField(),
|
||||
adversaries: new ForeignDocumentUUIDArrayField({ type: 'Actor' })
|
||||
adversaries: new ForeignDocumentUUIDArrayField({ type: 'Actor' }, { required: false, initial: [] })
|
||||
})
|
||||
),
|
||||
notes: new fields.HTMLField()
|
||||
|
|
|
|||
|
|
@ -165,7 +165,8 @@ export default class DamageField extends fields.SchemaField {
|
|||
if (data.hasRoll && part.resultBased && data.roll.result.duality === -1) return part.valueAlt;
|
||||
|
||||
const isAdversary = this.actor.type === 'adversary';
|
||||
if (isAdversary && this.actor.system.type === CONFIG.DH.ACTOR.adversaryTypes.horde.id) {
|
||||
const isHorde = this.actor.system.type === CONFIG.DH.ACTOR.adversaryTypes.horde.id;
|
||||
if (isAdversary && isHorde && this.roll?.isStandardAttack) {
|
||||
const hasHordeDamage = this.actor.effects.find(x => x.type === 'horde');
|
||||
if (hasHordeDamage && !hasHordeDamage.disabled) return part.valueAlt;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ export default class ForeignDocumentUUIDArrayField extends foundry.data.fields.A
|
|||
|
||||
/** @inheritdoc */
|
||||
initialize(value, model, options = {}) {
|
||||
const v = super.initialize(value, model, options);
|
||||
const v = super.initialize(value ?? [], model, options);
|
||||
return () => {
|
||||
const data = v.map(entry => (typeof entry === 'function' ? entry() : entry));
|
||||
return this.options.prune ? data.filter(d => !!d) : data;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import BaseDataItem from './base.mjs';
|
||||
import ItemLinkFields from '../../data/fields/itemLinkFields.mjs';
|
||||
import { getFeaturesHTMLData } from '../../helpers/utils.mjs';
|
||||
|
||||
export default class DHAncestry extends BaseDataItem {
|
||||
/** @inheritDoc */
|
||||
|
|
@ -19,7 +20,6 @@ export default class DHAncestry extends BaseDataItem {
|
|||
};
|
||||
}
|
||||
|
||||
|
||||
/* -------------------------------------------- */
|
||||
|
||||
/**@override */
|
||||
|
|
@ -42,4 +42,18 @@ export default class DHAncestry extends BaseDataItem {
|
|||
get secondaryFeature() {
|
||||
return this.features.find(x => x.type === CONFIG.DH.ITEM.featureSubTypes.secondary)?.item;
|
||||
}
|
||||
|
||||
/**@inheritdoc */
|
||||
async getDescriptionData() {
|
||||
const baseDescription = this.description;
|
||||
const features = await getFeaturesHTMLData(this.features);
|
||||
|
||||
if (!features.length) return { prefix: null, value: baseDescription, suffix: null };
|
||||
const suffix = await foundry.applications.handlebars.renderTemplate(
|
||||
'systems/daggerheart/templates/sheets/items/description.hbs',
|
||||
{ label: 'DAGGERHEART.ITEMS.Ancestry.featuresLabel', features }
|
||||
);
|
||||
|
||||
return { prefix: null, value: baseDescription, suffix };
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -59,11 +59,10 @@ export default class DHArmor extends AttachableItem {
|
|||
const baseDescription = this.description;
|
||||
const allFeatures = CONFIG.DH.ITEM.allArmorFeatures();
|
||||
const features = this.armorFeatures.map(x => allFeatures[x.value]);
|
||||
if (!features.length) return { prefix: null, value: baseDescription, suffix: null };
|
||||
|
||||
const prefix = await foundry.applications.handlebars.renderTemplate(
|
||||
'systems/daggerheart/templates/sheets/items/armor/description.hbs',
|
||||
{ features }
|
||||
{ item: this.parent, features }
|
||||
);
|
||||
|
||||
return { prefix, value: baseDescription, suffix: null };
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import BaseDataItem from './base.mjs';
|
|||
import ForeignDocumentUUIDField from '../fields/foreignDocumentUUIDField.mjs';
|
||||
import ForeignDocumentUUIDArrayField from '../fields/foreignDocumentUUIDArrayField.mjs';
|
||||
import ItemLinkFields from '../fields/itemLinkFields.mjs';
|
||||
import { addLinkedItemsDiff, updateLinkedItemApps } from '../../helpers/utils.mjs';
|
||||
import { addLinkedItemsDiff, getFeaturesHTMLData, updateLinkedItemApps } from '../../helpers/utils.mjs';
|
||||
|
||||
export default class DHClass extends BaseDataItem {
|
||||
/** @inheritDoc */
|
||||
|
|
@ -163,4 +163,56 @@ export default class DHClass extends BaseDataItem {
|
|||
|
||||
updateLinkedItemApps(options, this.parent.sheet);
|
||||
}
|
||||
|
||||
/**@inheritdoc */
|
||||
async getDescriptionData() {
|
||||
const baseDescription = this.description;
|
||||
|
||||
const getDomainLabel = domain => {
|
||||
const data = CONFIG.DH.DOMAIN.allDomains()[domain];
|
||||
return data ? game.i18n.localize(data.label) : '';
|
||||
};
|
||||
let domainsLabel = '';
|
||||
if (this.domains.length) {
|
||||
if (this.domains.length === 1) domainsLabel = getDomainLabel(this.domains[0]);
|
||||
else {
|
||||
const firstDomains = this.domains
|
||||
.slice(0, this.domains.length - 1)
|
||||
.map(getDomainLabel)
|
||||
.join(', ');
|
||||
const lastDomain = getDomainLabel(this.domains[this.domains.length - 1]);
|
||||
domainsLabel = game.i18n.format('DAGGERHEART.GENERAL.thingsAndThing', {
|
||||
things: firstDomains,
|
||||
thing: lastDomain
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const classItems = [];
|
||||
for (const itemData of this.inventory.choiceB) {
|
||||
const linkData = [
|
||||
undefined,
|
||||
'UUID', // type
|
||||
itemData.uuid // target
|
||||
];
|
||||
const contentLink = await foundry.applications.ux.TextEditor.implementation._createContentLink(linkData);
|
||||
classItems.push(contentLink.outerHTML);
|
||||
}
|
||||
|
||||
const hopeFeatures = await getFeaturesHTMLData(this.hopeFeatures);
|
||||
const classFeatures = await getFeaturesHTMLData(this.classFeatures);
|
||||
|
||||
const suffix = await foundry.applications.handlebars.renderTemplate(
|
||||
'systems/daggerheart/templates/sheets/items/class/description.hbs',
|
||||
{
|
||||
class: this.parent,
|
||||
domains: domainsLabel,
|
||||
classItems,
|
||||
hopeFeatures,
|
||||
classFeatures
|
||||
}
|
||||
);
|
||||
|
||||
return { prefix: null, value: baseDescription, suffix };
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import { getFeaturesHTMLData } from '../../helpers/utils.mjs';
|
||||
import ForeignDocumentUUIDArrayField from '../fields/foreignDocumentUUIDArrayField.mjs';
|
||||
import BaseDataItem from './base.mjs';
|
||||
|
||||
|
|
@ -24,4 +25,17 @@ export default class DHCommunity extends BaseDataItem {
|
|||
/**@override */
|
||||
static DEFAULT_ICON = 'systems/daggerheart/assets/icons/documents/items/village.svg';
|
||||
|
||||
/**@inheritdoc */
|
||||
async getDescriptionData() {
|
||||
const baseDescription = this.description;
|
||||
const features = await getFeaturesHTMLData(this.features);
|
||||
|
||||
if (!features.length) return { prefix: null, value: baseDescription, suffix: null };
|
||||
const suffix = await foundry.applications.handlebars.renderTemplate(
|
||||
'systems/daggerheart/templates/sheets/items/description.hbs',
|
||||
{ label: 'DAGGERHEART.ITEMS.Community.featuresLabel', features }
|
||||
);
|
||||
|
||||
return { prefix: null, value: baseDescription, suffix };
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import { getFeaturesHTMLData } from '../../helpers/utils.mjs';
|
||||
import ForeignDocumentUUIDField from '../fields/foreignDocumentUUIDField.mjs';
|
||||
import ItemLinkFields from '../fields/itemLinkFields.mjs';
|
||||
import BaseDataItem from './base.mjs';
|
||||
|
|
@ -89,4 +90,28 @@ export default class DHSubclass extends BaseDataItem {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**@inheritdoc */
|
||||
async getDescriptionData() {
|
||||
const baseDescription = this.description;
|
||||
|
||||
const spellcastTrait = this.spellcastingTrait
|
||||
? game.i18n.localize(CONFIG.DH.ACTOR.abilities[this.spellcastingTrait].label)
|
||||
: null;
|
||||
const foundationFeatures = await getFeaturesHTMLData(this.foundationFeatures);
|
||||
const specializationFeatures = await getFeaturesHTMLData(this.specializationFeatures);
|
||||
const masteryFeatures = await getFeaturesHTMLData(this.masteryFeatures);
|
||||
|
||||
const suffix = await foundry.applications.handlebars.renderTemplate(
|
||||
'systems/daggerheart/templates/sheets/items/subclass/description.hbs',
|
||||
{
|
||||
spellcastTrait,
|
||||
foundationFeatures,
|
||||
specializationFeatures,
|
||||
masteryFeatures
|
||||
}
|
||||
);
|
||||
|
||||
return { prefix: null, value: baseDescription, suffix };
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -113,13 +113,26 @@ export default class DHWeapon extends AttachableItem {
|
|||
/**@inheritdoc */
|
||||
async getDescriptionData() {
|
||||
const baseDescription = this.description;
|
||||
|
||||
const tier = game.i18n.localize(`DAGGERHEART.GENERAL.Tiers.${this.tier}`);
|
||||
const trait = game.i18n.localize(CONFIG.DH.ACTOR.abilities[this.attack.roll.trait].label);
|
||||
const range = game.i18n.localize(`DAGGERHEART.CONFIG.Range.${this.attack.range}.name`);
|
||||
const damage = Roll.replaceFormulaData(this.attack.damageFormula, this.parent.parent ?? this.parent);
|
||||
const burden = game.i18n.localize(CONFIG.DH.GENERAL.burden[this.burden].label);
|
||||
|
||||
const allFeatures = CONFIG.DH.ITEM.allWeaponFeatures();
|
||||
const features = this.weaponFeatures.map(x => allFeatures[x.value]);
|
||||
if (!features.length) return { prefix: null, value: baseDescription, suffix: null };
|
||||
|
||||
const prefix = await foundry.applications.handlebars.renderTemplate(
|
||||
'systems/daggerheart/templates/sheets/items/weapon/description.hbs',
|
||||
{ features }
|
||||
{
|
||||
features,
|
||||
tier,
|
||||
trait,
|
||||
range,
|
||||
damage,
|
||||
burden
|
||||
}
|
||||
);
|
||||
|
||||
return { prefix, value: baseDescription, suffix: null };
|
||||
|
|
|
|||
|
|
@ -49,6 +49,8 @@ export default function DhTemplateEnricher(match, _options) {
|
|||
}
|
||||
|
||||
export const renderMeasuredTemplate = async event => {
|
||||
const { LINE, RECTANGLE, INFRONT, CONE } = CONFIG.DH.GENERAL.templateTypes;
|
||||
|
||||
const button = event.currentTarget,
|
||||
type = button.dataset.type,
|
||||
range = button.dataset.range,
|
||||
|
|
@ -57,13 +59,9 @@ export const renderMeasuredTemplate = async event => {
|
|||
|
||||
if (!type || !range || !game.canvas.scene) return;
|
||||
|
||||
const usedType = type === 'inFront' ? 'cone' : type === 'emanation' ? 'circle' : type;
|
||||
const usedType = type === 'inFront' ? 'cone' : type;
|
||||
const usedAngle =
|
||||
type === CONFIG.DH.GENERAL.templateTypes.CONE
|
||||
? (angle ?? CONFIG.MeasuredTemplate.defaults.angle)
|
||||
: type === CONFIG.DH.GENERAL.templateTypes.INFRONT
|
||||
? '180'
|
||||
: undefined;
|
||||
type === CONE ? (angle ?? CONFIG.MeasuredTemplate.defaults.angle) : type === INFRONT ? '180' : undefined;
|
||||
|
||||
let baseDistance = range;
|
||||
if (Number.isNaN(Number(range))) {
|
||||
|
|
@ -71,16 +69,32 @@ export const renderMeasuredTemplate = async event => {
|
|||
range
|
||||
];
|
||||
}
|
||||
const distance = type === CONFIG.DH.GENERAL.templateTypes.EMANATION ? baseDistance + 2.5 : baseDistance;
|
||||
const radius = (distance / game.scenes.active.grid.distance) * game.scenes.active.grid.size;
|
||||
|
||||
const dimensionConstant = game.scenes.active.grid.size / game.scenes.active.grid.distance;
|
||||
|
||||
baseDistance *= dimensionConstant;
|
||||
|
||||
const length = baseDistance;
|
||||
const radius = length;
|
||||
|
||||
const shapeWidth = type === LINE ? 5 * dimensionConstant : type === RECTANGLE ? length : undefined;
|
||||
|
||||
const { width, height } = game.canvas.scene.dimensions;
|
||||
const shapeData = {
|
||||
x: width / 2,
|
||||
y: height / 2,
|
||||
base: {
|
||||
type: 'token',
|
||||
x: 0,
|
||||
y: 0,
|
||||
width: 1,
|
||||
height: 1,
|
||||
shape: game.canvas.grid.isHexagonal ? CONST.TOKEN_SHAPES.ELLIPSE_1 : CONST.TOKEN_SHAPES.RECTANGLE_1
|
||||
},
|
||||
t: usedType,
|
||||
distance: distance,
|
||||
width: type === CONFIG.DH.GENERAL.templateTypes.RAY ? 5 : undefined,
|
||||
length: length,
|
||||
width: shapeWidth,
|
||||
height: length,
|
||||
angle: usedAngle,
|
||||
radius: radius,
|
||||
direction: direction,
|
||||
|
|
|
|||
|
|
@ -541,6 +541,21 @@ export function getIconVisibleActiveEffects(effects) {
|
|||
return !effect.active && (alwaysShown || conditionalShown);
|
||||
});
|
||||
}
|
||||
export async function getFeaturesHTMLData(features) {
|
||||
const result = [];
|
||||
for (const feature of features) {
|
||||
if (feature) {
|
||||
const base = feature.item ?? feature;
|
||||
const item = base.system ? base : await foundry.utils.fromUuid(base.uuid);
|
||||
const itemDescription = await foundry.applications.ux.TextEditor.implementation.enrichHTML(
|
||||
item.system.description
|
||||
);
|
||||
result.push({ label: item.name, description: itemDescription });
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a simple flavor-less formula with only +/- operators, returns a list of damage partial terms.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue