mirror of
https://github.com/Foundryborne/daggerheart.git
synced 2026-01-12 03:31:07 +01:00
[Feature] 494 - Adversaries Tier 1 (#500)
* Some work * More work * Finished Tier 1
This commit is contained in:
parent
3014be79ad
commit
263dfa69ae
70 changed files with 15171 additions and 972 deletions
|
|
@ -311,8 +311,12 @@ export default function DHApplicationMixin(Base) {
|
|||
name: 'CONTROLS.CommonEdit',
|
||||
icon: 'fa-solid fa-pen-to-square',
|
||||
condition: target => {
|
||||
const { dataset } = target.closest('[data-item-uuid]');
|
||||
const doc = getDocFromElementSync(target);
|
||||
return !doc || !doc.hasOwnProperty('systemPath') || doc.inCollection;
|
||||
return (
|
||||
(!dataset.noCompendiumEdit && !doc) ||
|
||||
(doc && (!doc?.hasOwnProperty('systemPath') || doc?.inCollection))
|
||||
);
|
||||
},
|
||||
callback: async target => (await getDocFromElement(target)).sheet.render({ force: true })
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,6 +43,12 @@ export const range = {
|
|||
}
|
||||
};
|
||||
|
||||
export const templateTypes = {
|
||||
...CONST.MEASURED_TEMPLATE_TYPES,
|
||||
EMANATION: 'emanation',
|
||||
INFRONT: 'inFront'
|
||||
};
|
||||
|
||||
export const rangeInclusion = {
|
||||
withinRange: {
|
||||
id: 'withinRange',
|
||||
|
|
|
|||
|
|
@ -10,10 +10,8 @@ export default class DHDamageAction extends DHBaseAction {
|
|||
|
||||
const isAdversary = this.actor.type === 'adversary';
|
||||
if (isAdversary && this.actor.system.type === CONFIG.DH.ACTOR.adversaryTypes.horde.id) {
|
||||
const hasHordeDamage = this.actor.effects.find(
|
||||
x => x.name === game.i18n.localize('DAGGERHEART.CONFIG.AdversaryType.horde.label')
|
||||
);
|
||||
if (hasHordeDamage) return part.valueAlt;
|
||||
const hasHordeDamage = this.actor.effects.find(x => x.type === 'horde');
|
||||
if (hasHordeDamage && !hasHordeDamage.disabled) return part.valueAlt;
|
||||
}
|
||||
|
||||
return formulaValue;
|
||||
|
|
@ -47,7 +45,9 @@ export default class DHDamageAction extends DHBaseAction {
|
|||
formulas = this.formatFormulas(formulas, systemData);
|
||||
|
||||
const config = {
|
||||
title: game.i18n.format(`DAGGERHEART.UI.Chat.${ this.type === 'healing' ? 'healing' : 'damage'}Roll.title`, { damage: game.i18n.localize(this.name) }),
|
||||
title: game.i18n.format(`DAGGERHEART.UI.Chat.${this.type === 'healing' ? 'healing' : 'damage'}Roll.title`, {
|
||||
damage: game.i18n.localize(this.name)
|
||||
}),
|
||||
roll: formulas,
|
||||
targets: systemData.targets?.filter(t => t.hit) ?? data.targets,
|
||||
hasSave: this.hasSave,
|
||||
|
|
|
|||
|
|
@ -1,9 +1,11 @@
|
|||
import BaseEffect from './baseEffect.mjs';
|
||||
import BeastformEffect from './beastformEffect.mjs';
|
||||
import HordeEffect from './hordeEffect.mjs';
|
||||
|
||||
export { BaseEffect, BeastformEffect };
|
||||
export { BaseEffect, BeastformEffect, HordeEffect };
|
||||
|
||||
export const config = {
|
||||
base: BaseEffect,
|
||||
beastform: BeastformEffect
|
||||
beastform: BeastformEffect,
|
||||
horde: HordeEffect
|
||||
};
|
||||
|
|
|
|||
3
module/data/activeEffect/hordeEffect.mjs
Normal file
3
module/data/activeEffect/hordeEffect.mjs
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
import BaseEffect from './baseEffect.mjs';
|
||||
|
||||
export default class HordeEffect extends BaseEffect {}
|
||||
|
|
@ -117,29 +117,46 @@ export default class DhpAdversary extends BaseDataActor {
|
|||
if (allowed === false) return false;
|
||||
|
||||
if (this.type === CONFIG.DH.ACTOR.adversaryTypes.horde.id) {
|
||||
if (changes.system?.resources?.hitPoints?.value) {
|
||||
const halfHP = Math.ceil(this.resources.hitPoints.max / 2);
|
||||
const newHitPoints = changes.system.resources.hitPoints.value;
|
||||
const previouslyAboveHalf = this.resources.hitPoints.value < halfHP;
|
||||
const loweredBelowHalf = previouslyAboveHalf && newHitPoints >= halfHP;
|
||||
const raisedAboveHalf = !previouslyAboveHalf && newHitPoints < halfHP;
|
||||
if (loweredBelowHalf) {
|
||||
await this.parent.createEmbeddedDocuments('ActiveEffect', [
|
||||
{
|
||||
name: game.i18n.localize('DAGGERHEART.CONFIG.AdversaryType.horde.label'),
|
||||
img: 'icons/magic/movement/chevrons-down-yellow.webp',
|
||||
disabled: !game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation)
|
||||
.hordeDamage
|
||||
}
|
||||
]);
|
||||
} else if (raisedAboveHalf) {
|
||||
const hordeEffects = this.parent.effects.filter(
|
||||
x => x.name === game.i18n.localize('DAGGERHEART.CONFIG.AdversaryType.horde.label')
|
||||
);
|
||||
await this.parent.deleteEmbeddedDocuments(
|
||||
'ActiveEffect',
|
||||
hordeEffects.map(x => x.id)
|
||||
);
|
||||
const autoHordeDamage = game.settings.get(
|
||||
CONFIG.DH.id,
|
||||
CONFIG.DH.SETTINGS.gameSettings.Automation
|
||||
).hordeDamage;
|
||||
if (autoHordeDamage && changes.system?.resources?.hitPoints?.value) {
|
||||
const hordeActiveEffect = this.parent.effects.find(x => x.type === 'horde');
|
||||
if (hordeActiveEffect) {
|
||||
const halfHP = Math.ceil(this.resources.hitPoints.max / 2);
|
||||
const newHitPoints = changes.system.resources.hitPoints.value;
|
||||
const previouslyAboveHalf = this.resources.hitPoints.value < halfHP;
|
||||
const loweredBelowHalf = previouslyAboveHalf && newHitPoints >= halfHP;
|
||||
const raisedAboveHalf = !previouslyAboveHalf && newHitPoints < halfHP;
|
||||
if (loweredBelowHalf) {
|
||||
await hordeActiveEffect.update({ disabled: false });
|
||||
} else if (raisedAboveHalf) {
|
||||
await hordeActiveEffect.update({ disabled: true });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_onUpdate(changes, options, userId) {
|
||||
super._onUpdate(changes, options, userId);
|
||||
|
||||
if (game.user.id === userId) {
|
||||
if (changes.system.type) {
|
||||
const existingHordeEffect = this.parent.effects.find(x => x.type === 'horde');
|
||||
if (changes.system.type === CONFIG.DH.ACTOR.adversaryTypes.horde.id) {
|
||||
if (!existingHordeEffect)
|
||||
this.parent.createEmbeddedDocuments('ActiveEffect', [
|
||||
{
|
||||
type: 'horde',
|
||||
name: game.i18n.localize('DAGGERHEART.CONFIG.AdversaryType.horde.label'),
|
||||
img: 'icons/magic/movement/chevrons-down-yellow.webp',
|
||||
disabled: true
|
||||
}
|
||||
]);
|
||||
} else {
|
||||
existingHordeEffect?.delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
import { itemAbleRollParse } from '../helpers/utils.mjs';
|
||||
|
||||
export default class DhActiveEffect extends foundry.documents.ActiveEffect {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
/* Properties */
|
||||
/* -------------------------------------------- */
|
||||
|
|
@ -78,8 +77,8 @@ export default class DhActiveEffect extends foundry.documents.ActiveEffect {
|
|||
|
||||
/**
|
||||
* Altered Foundry safeEval to allow non-numeric return
|
||||
* @param {string} expression
|
||||
* @returns
|
||||
* @param {string} expression
|
||||
* @returns
|
||||
*/
|
||||
static effectSafeEval(expression) {
|
||||
let result;
|
||||
|
|
@ -95,13 +94,15 @@ export default class DhActiveEffect extends foundry.documents.ActiveEffect {
|
|||
}
|
||||
|
||||
/**
|
||||
* Generates a list of localized tags based on this item's type-specific properties.
|
||||
* @returns {string[]} An array of localized tag strings.
|
||||
*/
|
||||
* Generates a list of localized tags based on this item's type-specific properties.
|
||||
* @returns {string[]} An array of localized tag strings.
|
||||
*/
|
||||
_getTags() {
|
||||
const tags = [
|
||||
`${game.i18n.localize(this.parent.system.metadata.label)}: ${this.parent.name}`,
|
||||
game.i18n.localize(this.isTemporary ? 'DAGGERHEART.EFFECTS.Duration.temporary' : 'DAGGERHEART.EFFECTS.Duration.passive')
|
||||
game.i18n.localize(
|
||||
this.isTemporary ? 'DAGGERHEART.EFFECTS.Duration.temporary' : 'DAGGERHEART.EFFECTS.Duration.passive'
|
||||
)
|
||||
];
|
||||
|
||||
for (const statusId of this.statuses) {
|
||||
|
|
|
|||
|
|
@ -74,8 +74,8 @@ export default class DHItem extends foundry.documents.Item {
|
|||
isInventoryItem === true
|
||||
? 'Inventory Items' //TODO localize
|
||||
: isInventoryItem === false
|
||||
? 'Character Items' //TODO localize
|
||||
: 'Other'; //TODO localize
|
||||
? 'Character Items' //TODO localize
|
||||
: 'Other'; //TODO localize
|
||||
|
||||
return { value: type, label, group };
|
||||
}
|
||||
|
|
@ -137,10 +137,10 @@ export default class DHItem extends foundry.documents.Item {
|
|||
this.type === 'ancestry'
|
||||
? game.i18n.localize('DAGGERHEART.UI.Chat.foundationCard.ancestryTitle')
|
||||
: this.type === 'community'
|
||||
? game.i18n.localize('DAGGERHEART.UI.Chat.foundationCard.communityTitle')
|
||||
: this.type === 'feature'
|
||||
? game.i18n.localize('TYPES.Item.feature')
|
||||
: game.i18n.localize('DAGGERHEART.UI.Chat.foundationCard.subclassFeatureTitle'),
|
||||
? game.i18n.localize('DAGGERHEART.UI.Chat.foundationCard.communityTitle')
|
||||
: this.type === 'feature'
|
||||
? game.i18n.localize('TYPES.Item.feature')
|
||||
: game.i18n.localize('DAGGERHEART.UI.Chat.foundationCard.subclassFeatureTitle'),
|
||||
origin: origin,
|
||||
img: this.img,
|
||||
name: this.name,
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ export default function DhTemplateEnricher(match, _options) {
|
|||
if (split.length === 2) {
|
||||
switch (split[0]) {
|
||||
case 'type':
|
||||
const matchedType = Object.values(CONST.MEASURED_TEMPLATE_TYPES).find(
|
||||
const matchedType = Object.values(CONFIG.DH.GENERAL.templateTypes).find(
|
||||
x => x.toLowerCase() === split[1]
|
||||
);
|
||||
type = matchedType;
|
||||
|
|
@ -28,10 +28,12 @@ export default function DhTemplateEnricher(match, _options) {
|
|||
|
||||
if (!type || !range) return match[0];
|
||||
|
||||
const label = game.i18n.localize(`DAGGERHEART.CONFIG.TemplateTypes.${type}`);
|
||||
|
||||
const templateElement = document.createElement('span');
|
||||
templateElement.innerHTML = `
|
||||
<button class="measured-template-button" data-type="${type}" data-range="${range}">
|
||||
${game.i18n.localize(`TEMPLATE.TYPES.${type}`)} - ${game.i18n.localize(`DAGGERHEART.CONFIG.Range.${range}.name`)}
|
||||
${label} - ${game.i18n.localize(`DAGGERHEART.CONFIG.Range.${range}.name`)}
|
||||
</button>
|
||||
`;
|
||||
|
||||
|
|
@ -45,16 +47,26 @@ export const renderMeasuredTemplate = async event => {
|
|||
|
||||
if (!type || !range || !game.canvas.scene) return;
|
||||
|
||||
const distance = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.RangeMeasurement)[range];
|
||||
const usedType = type === 'inFront' ? 'cone' : type === 'emanation' ? 'circle' : type;
|
||||
const angle =
|
||||
type === CONST.MEASURED_TEMPLATE_TYPES.CONE
|
||||
? CONFIG.MeasuredTemplate.defaults.angle
|
||||
: type === CONFIG.DH.GENERAL.templateTypes.INFRONT
|
||||
? '180'
|
||||
: undefined;
|
||||
|
||||
const baseDistance = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.RangeMeasurement)[range];
|
||||
const distance = type === CONFIG.DH.GENERAL.templateTypes.EMANATION ? baseDistance + 2.5 : baseDistance;
|
||||
|
||||
const { width, height } = game.canvas.scene.dimensions;
|
||||
canvas.scene.createEmbeddedDocuments('MeasuredTemplate', [
|
||||
{
|
||||
x: width / 2,
|
||||
y: height / 2,
|
||||
t: type,
|
||||
t: usedType,
|
||||
distance: distance,
|
||||
width: type === CONST.MEASURED_TEMPLATE_TYPES.RAY ? 5 : undefined,
|
||||
angle: type === CONST.MEASURED_TEMPLATE_TYPES.CONE ? CONFIG.MeasuredTemplate.defaults.angle : undefined
|
||||
angle: angle
|
||||
}
|
||||
]);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ export { DhDamageEnricher, DhDualityRollEnricher, DhEffectEnricher, DhTemplateEn
|
|||
|
||||
export const enricherConfig = [
|
||||
{
|
||||
pattern: /^@Damage\[(.*)\]({.*})?$/g,
|
||||
pattern: /@Damage\[(.*)\]({.*})?/g,
|
||||
enricher: DhDamageEnricher
|
||||
},
|
||||
{
|
||||
|
|
@ -15,11 +15,11 @@ export const enricherConfig = [
|
|||
enricher: DhDualityRollEnricher
|
||||
},
|
||||
{
|
||||
pattern: /^@Effect\[(.*)\]({.*})?$/g,
|
||||
pattern: /@Effect\[(.*)\]({.*})?/g,
|
||||
enricher: DhEffectEnricher
|
||||
},
|
||||
{
|
||||
pattern: /^@Template\[(.*)\]({.*})?$/g,
|
||||
pattern: /@Template\[(.*)\]({.*})?/g,
|
||||
enricher: DhTemplateEnricher
|
||||
}
|
||||
];
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue