mirror of
https://github.com/Foundryborne/daggerheart.git
synced 2026-03-07 14:36:13 +01:00
Merged with v14-Dev
This commit is contained in:
commit
26503187a2
126 changed files with 2540 additions and 1260 deletions
|
|
@ -1,4 +1,4 @@
|
|||
import { refreshIsAllowed } from '../../helpers/utils.mjs';
|
||||
import { expireActiveEffects, refreshIsAllowed } from '../../helpers/utils.mjs';
|
||||
|
||||
const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api;
|
||||
|
||||
|
|
@ -264,6 +264,8 @@ export default class DhpDowntime extends HandlebarsApplicationMixin(ApplicationV
|
|||
await feature.update({ 'system.resource.value': resetValue });
|
||||
}
|
||||
|
||||
expireActiveEffects(this.actor, [this.shortRest ? 'shortRest' : 'longRest']);
|
||||
|
||||
this.close();
|
||||
} else {
|
||||
this.render();
|
||||
|
|
|
|||
|
|
@ -166,6 +166,17 @@ export default class DhActiveEffectConfig extends foundry.applications.sheets.Ac
|
|||
}));
|
||||
}
|
||||
break;
|
||||
case 'settings':
|
||||
const groups = {
|
||||
time: _loc('EFFECT.DURATION.UNITS.GROUPS.time'),
|
||||
combat: _loc('EFFECT.DURATION.UNITS.GROUPS.combat')
|
||||
};
|
||||
partContext.durationUnits = CONST.ACTIVE_EFFECT_DURATION_UNITS.map(value => ({
|
||||
value,
|
||||
label: _loc(`EFFECT.DURATION.UNITS.${value}`),
|
||||
group: CONST.ACTIVE_EFFECT_TIME_DURATION_UNITS.includes(value) ? groups.time : groups.combat
|
||||
}));
|
||||
break;
|
||||
case 'changes':
|
||||
const fields = this.document.system.schema.fields.changes.element.fields;
|
||||
partContext.changes = await Promise.all(
|
||||
|
|
@ -206,4 +217,26 @@ export default class DhActiveEffectConfig extends foundry.applications.sheets.Ac
|
|||
)
|
||||
);
|
||||
}
|
||||
|
||||
/** @inheritDoc */
|
||||
_onChangeForm(_formConfig, event) {
|
||||
if (foundry.utils.isElementInstanceOf(event.target, 'select') && event.target.name === 'system.duration.type') {
|
||||
const durationSection = this.element.querySelector('.custom-duration-section');
|
||||
if (event.target.value === 'custom') durationSection.classList.add('visible');
|
||||
else durationSection.classList.remove('visible');
|
||||
|
||||
const durationDescription = this.element.querySelector('.duration-description');
|
||||
if (event.target.value === 'temporary') durationDescription.classList.add('visible');
|
||||
else durationDescription.classList.remove('visible');
|
||||
}
|
||||
}
|
||||
|
||||
/** @inheritDoc */
|
||||
_processFormData(event, form, formData) {
|
||||
const submitData = super._processFormData(event, form, formData);
|
||||
if (submitData.start && !submitData.start.time) submitData.start.time = '0';
|
||||
else if (!submitData) submitData.start = null;
|
||||
|
||||
return submitData;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { refreshIsAllowed } from '../../../helpers/utils.mjs';
|
||||
import { expireActiveEffects, refreshIsAllowed } from '../../../helpers/utils.mjs';
|
||||
|
||||
const { HandlebarsApplicationMixin } = foundry.applications.api;
|
||||
const { AbstractSidebarTab } = foundry.applications.sidebar;
|
||||
|
|
@ -58,6 +58,8 @@ export default class DaggerheartMenu extends HandlebarsApplicationMixin(Abstract
|
|||
const refreshedActors = {};
|
||||
for (let actor of game.actors) {
|
||||
if (['character', 'adversary'].includes(actor.type) && actor.prototypeToken.actorLink) {
|
||||
expireActiveEffects(actor, types);
|
||||
|
||||
const updates = {};
|
||||
for (let item of actor.items) {
|
||||
if (item.system.metadata?.hasResource && refreshIsAllowed(types, item.system.resource?.recovery)) {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import { AdversaryBPPerEncounter } from '../../config/encounterConfig.mjs';
|
||||
import { expireActiveEffects } from '../../helpers/utils.mjs';
|
||||
|
||||
export default class DhCombatTracker extends foundry.applications.sidebar.tabs.CombatTracker {
|
||||
static DEFAULT_OPTIONS = {
|
||||
|
|
@ -177,6 +178,8 @@ export default class DhCombatTracker extends foundry.applications.sidebar.tabs.C
|
|||
if (autoPoints) {
|
||||
update.system.actionTokens = Math.max(combatant.system.actionTokens - 1, 0);
|
||||
}
|
||||
|
||||
if (combatant.actor) expireActiveEffects(combatant.actor, [CONFIG.DH.GENERAL.activeEffectDurations.act.id]);
|
||||
}
|
||||
|
||||
await this.viewed.update({
|
||||
|
|
|
|||
|
|
@ -896,3 +896,34 @@ export const activeEffectArmorInteraction = {
|
|||
active: { id: 'active', label: 'DAGGERHEART.CONFIG.ArmorInteraction.active.label' },
|
||||
inactive: { id: 'inactive', label: 'DAGGERHEART.CONFIG.ArmorInteraction.inactive.label' }
|
||||
};
|
||||
|
||||
export const activeEffectDurations = {
|
||||
temporary: {
|
||||
id: 'temporary',
|
||||
label: 'DAGGERHEART.CONFIG.ActiveEffectDuration.temporary'
|
||||
},
|
||||
act: {
|
||||
id: 'act',
|
||||
label: 'DAGGERHEART.CONFIG.ActiveEffectDuration.act'
|
||||
},
|
||||
scene: {
|
||||
id: 'scene',
|
||||
label: 'DAGGERHEART.CONFIG.ActiveEffectDuration.scene'
|
||||
},
|
||||
shortRest: {
|
||||
id: 'shortRest',
|
||||
label: 'DAGGERHEART.CONFIG.ActiveEffectDuration.shortRest'
|
||||
},
|
||||
longRest: {
|
||||
id: 'longRest',
|
||||
label: 'DAGGERHEART.CONFIG.ActiveEffectDuration.longRest'
|
||||
},
|
||||
session: {
|
||||
id: 'session',
|
||||
label: 'DAGGERHEART.CONFIG.ActiveEffectDuration.session'
|
||||
},
|
||||
custom: {
|
||||
id: 'custom',
|
||||
label: 'DAGGERHEART.CONFIG.ActiveEffectDuration.custom'
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -33,6 +33,14 @@ export default class BaseEffect extends foundry.data.ActiveEffectTypeDataModel {
|
|||
priority: new fields.NumberField()
|
||||
})
|
||||
),
|
||||
duration: new fields.SchemaField({
|
||||
type: new fields.StringField({
|
||||
choices: CONFIG.DH.GENERAL.activeEffectDurations,
|
||||
blank: true,
|
||||
label: 'DAGGERHEART.GENERAL.type'
|
||||
}),
|
||||
description: new fields.HTMLField({ label: 'DAGGERHEART.GENERAL.description' })
|
||||
}),
|
||||
rangeDependence: new fields.SchemaField({
|
||||
enabled: new fields.BooleanField({
|
||||
required: true,
|
||||
|
|
|
|||
|
|
@ -1,11 +1,12 @@
|
|||
import DHAdversarySettings from '../../applications/sheets-configs/adversary-settings.mjs';
|
||||
import { ActionField } from '../fields/actionField.mjs';
|
||||
import BaseDataActor, { commonActorRules } from './base.mjs';
|
||||
import { commonActorRules } from './base.mjs';
|
||||
import DhCreature from './creature.mjs';
|
||||
import { resourceField, bonusField } from '../fields/actorField.mjs';
|
||||
import { calculateExpectedValue, parseTermsFromSimpleFormula } from '../../helpers/utils.mjs';
|
||||
import { adversaryExpectedDamage, adversaryScalingData } from '../../config/actorConfig.mjs';
|
||||
|
||||
export default class DhpAdversary extends BaseDataActor {
|
||||
export default class DhpAdversary extends DhCreature {
|
||||
static LOCALIZATION_PREFIXES = ['DAGGERHEART.ACTORS.Adversary'];
|
||||
|
||||
static get metadata() {
|
||||
|
|
|
|||
|
|
@ -1,12 +1,13 @@
|
|||
import { burden } from '../../config/generalConfig.mjs';
|
||||
import ForeignDocumentUUIDField from '../fields/foreignDocumentUUIDField.mjs';
|
||||
import DhLevelData from '../levelData.mjs';
|
||||
import BaseDataActor, { commonActorRules } from './base.mjs';
|
||||
import { commonActorRules } from './base.mjs';
|
||||
import DhCreature from './creature.mjs';
|
||||
import { attributeField, resourceField, stressDamageReductionRule, bonusField } from '../fields/actorField.mjs';
|
||||
import { ActionField } from '../fields/actionField.mjs';
|
||||
import DHCharacterSettings from '../../applications/sheets-configs/character-settings.mjs';
|
||||
|
||||
export default class DhCharacter extends BaseDataActor {
|
||||
export default class DhCharacter extends DhCreature {
|
||||
/**@override */
|
||||
static LOCALIZATION_PREFIXES = ['DAGGERHEART.ACTORS.Character'];
|
||||
|
||||
|
|
@ -144,14 +145,6 @@ export default class DhCharacter extends BaseDataActor {
|
|||
}
|
||||
}
|
||||
}),
|
||||
advantageSources: new fields.ArrayField(new fields.StringField(), {
|
||||
label: 'DAGGERHEART.ACTORS.Character.advantageSources.label',
|
||||
hint: 'DAGGERHEART.ACTORS.Character.advantageSources.hint'
|
||||
}),
|
||||
disadvantageSources: new fields.ArrayField(new fields.StringField(), {
|
||||
label: 'DAGGERHEART.ACTORS.Character.disadvantageSources.label',
|
||||
hint: 'DAGGERHEART.ACTORS.Character.disadvantageSources.hint'
|
||||
}),
|
||||
levelData: new fields.EmbeddedDataField(DhLevelData),
|
||||
bonuses: new fields.SchemaField({
|
||||
roll: new fields.SchemaField({
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import BaseDataActor from './base.mjs';
|
||||
import DhCreature from './creature.mjs';
|
||||
import DhLevelData from '../levelData.mjs';
|
||||
import ForeignDocumentUUIDField from '../fields/foreignDocumentUUIDField.mjs';
|
||||
import { ActionField } from '../fields/actionField.mjs';
|
||||
|
|
@ -6,7 +6,7 @@ import { adjustDice, adjustRange } from '../../helpers/utils.mjs';
|
|||
import DHCompanionSettings from '../../applications/sheets-configs/companion-settings.mjs';
|
||||
import { resourceField, bonusField } from '../fields/actorField.mjs';
|
||||
|
||||
export default class DhCompanion extends BaseDataActor {
|
||||
export default class DhCompanion extends DhCreature {
|
||||
static LOCALIZATION_PREFIXES = ['DAGGERHEART.ACTORS.Companion'];
|
||||
|
||||
/**@inheritdoc */
|
||||
|
|
|
|||
20
module/data/actor/creature.mjs
Normal file
20
module/data/actor/creature.mjs
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
import BaseDataActor from './base.mjs';
|
||||
|
||||
export default class DhCreature extends BaseDataActor {
|
||||
/**@inheritdoc */
|
||||
static defineSchema() {
|
||||
const fields = foundry.data.fields;
|
||||
|
||||
return {
|
||||
...super.defineSchema(),
|
||||
advantageSources: new fields.ArrayField(new fields.StringField(), {
|
||||
label: 'DAGGERHEART.ACTORS.Character.advantageSources.label',
|
||||
hint: 'DAGGERHEART.ACTORS.Character.advantageSources.hint'
|
||||
}),
|
||||
disadvantageSources: new fields.ArrayField(new fields.StringField(), {
|
||||
label: 'DAGGERHEART.ACTORS.Character.disadvantageSources.label',
|
||||
hint: 'DAGGERHEART.ACTORS.Character.disadvantageSources.hint'
|
||||
})
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -192,6 +192,11 @@ export default class DhAutomation extends foundry.abstract.DataModel {
|
|||
})
|
||||
})
|
||||
}),
|
||||
autoExpireActiveEffects: new fields.BooleanField({
|
||||
required: true,
|
||||
initial: true,
|
||||
label: 'DAGGERHEART.SETTINGS.Automation.FIELDS.autoExpireActiveEffects.label'
|
||||
}),
|
||||
triggers: new fields.SchemaField({
|
||||
enabled: new fields.BooleanField({
|
||||
nullable: false,
|
||||
|
|
|
|||
|
|
@ -409,7 +409,9 @@ export default class DualityRoll extends D20Roll {
|
|||
difficulty: message.system.roll.difficulty ? Number(message.system.roll.difficulty) : null
|
||||
}
|
||||
});
|
||||
newRoll.extra = newRoll.extra.slice(2);
|
||||
|
||||
const extraIndex = newRoll.advantage ? 3 : 2;
|
||||
newRoll.extra = newRoll.extra.slice(extraIndex);
|
||||
|
||||
const tagTeamSettings = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.TagTeamRoll);
|
||||
|
||||
|
|
|
|||
|
|
@ -52,6 +52,20 @@ export default class DhActiveEffect extends foundry.documents.ActiveEffect {
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether this Active Effect is eligible to be registered with the {@link ActiveEffectRegistry}
|
||||
*/
|
||||
get isExpiryTrackable() {
|
||||
return (
|
||||
this.persisted &&
|
||||
!this.inCompendium &&
|
||||
this.modifiesActor &&
|
||||
this.start &&
|
||||
this.isTemporary &&
|
||||
!this.isExpired
|
||||
);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
/* Event Handlers */
|
||||
/* -------------------------------------------- */
|
||||
|
|
|
|||
|
|
@ -477,6 +477,8 @@ export async function waitForDiceSoNice(message) {
|
|||
}
|
||||
|
||||
export function refreshIsAllowed(allowedTypes, typeToCheck) {
|
||||
if (!allowedTypes) return true;
|
||||
|
||||
switch (typeToCheck) {
|
||||
case CONFIG.DH.GENERAL.refreshTypes.scene.id:
|
||||
case CONFIG.DH.GENERAL.refreshTypes.session.id:
|
||||
|
|
@ -493,6 +495,34 @@ export function refreshIsAllowed(allowedTypes, typeToCheck) {
|
|||
}
|
||||
}
|
||||
|
||||
function expireActiveEffectIsAllowed(allowedTypes, typeToCheck) {
|
||||
if (typeToCheck === CONFIG.DH.GENERAL.activeEffectDurations.act.id) return true;
|
||||
|
||||
return refreshIsAllowed(allowedTypes, typeToCheck);
|
||||
}
|
||||
|
||||
export function expireActiveEffects(actor, allowedTypes = null) {
|
||||
const shouldExpireEffects = game.settings.get(
|
||||
CONFIG.DH.id,
|
||||
CONFIG.DH.SETTINGS.gameSettings.Automation
|
||||
).autoExpireActiveEffects;
|
||||
if (!shouldExpireEffects) return;
|
||||
|
||||
const effectsToExpire = actor
|
||||
.getActiveEffects()
|
||||
.filter(effect => {
|
||||
if (!effect.system?.duration.type) return false;
|
||||
|
||||
const { temporary, custom } = CONFIG.DH.GENERAL.activeEffectDurations;
|
||||
if ([temporary.id, custom.id].includes(effect.system.duration.type)) return false;
|
||||
|
||||
return expireActiveEffectIsAllowed(allowedTypes, effect.system.duration.type);
|
||||
})
|
||||
.map(x => x.id);
|
||||
|
||||
actor.deleteEmbeddedDocuments('ActiveEffect', effectsToExpire);
|
||||
}
|
||||
|
||||
export async function getCritDamageBonus(formula) {
|
||||
const critRoll = new Roll(formula);
|
||||
return critRoll.dice.reduce((acc, dice) => acc + dice.faces * dice.number, 0);
|
||||
|
|
@ -507,6 +537,8 @@ export function htmlToText(html) {
|
|||
|
||||
export function getIconVisibleActiveEffects(effects) {
|
||||
return effects.filter(effect => {
|
||||
if (!(effect instanceof game.system.api.documents.DhActiveEffect)) return true;
|
||||
|
||||
const alwaysShown = effect.showIcon === CONST.ACTIVE_EFFECT_SHOW_ICON.ALWAYS;
|
||||
const conditionalShown = effect.showIcon === CONST.ACTIVE_EFFECT_SHOW_ICON.CONDITIONAL && !effect.transfer; // TODO: system specific logic
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue