This commit is contained in:
WBHarry 2025-07-04 01:22:18 +02:00
parent 72dfc54705
commit 266a2806ab
13 changed files with 102 additions and 52 deletions

View file

@ -1666,8 +1666,8 @@
"Config": { "Config": {
"Beastform": { "Beastform": {
"label": "Beastform", "label": "Beastform",
"exact": "Exact", "exact": "Beastform Max Tier",
"exactPlaceholder": "Character tier is used" "exactHint": "The Character's Tier is used if empty"
} }
} }
}, },

View file

@ -38,7 +38,7 @@ export default class DHActionConfig extends DaggerheartSheet(ApplicationV2) {
} }
}; };
static CLEAN_ARRAYS = ["damage.parts", "cost", "effects"]; static CLEAN_ARRAYS = ['damage.parts', 'cost', 'effects'];
_getTabs() { _getTabs() {
const tabs = { const tabs = {
@ -69,7 +69,13 @@ export default class DHActionConfig extends DaggerheartSheet(ApplicationV2) {
context.disableOption = this.disableOption.bind(this); context.disableOption = this.disableOption.bind(this);
context.isNPC = this.action.actor && this.action.actor.type !== 'character'; context.isNPC = this.action.actor && this.action.actor.type !== 'character';
context.hasRoll = this.action.hasRoll; context.hasRoll = this.action.hasRoll;
console.log(context)
const settingsTiers = game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.LevelTiers).tiers;
context.tierOptions = [
{ key: 1, label: game.i18n.localize('DAGGERHEART.Tiers.tier1') },
...Object.values(settingsTiers).map(x => ({ key: x.tier, label: x.name }))
];
return context; return context;
} }
@ -97,9 +103,9 @@ export default class DHActionConfig extends DaggerheartSheet(ApplicationV2) {
_prepareSubmitData(event, formData) { _prepareSubmitData(event, formData) {
const submitData = foundry.utils.expandObject(formData.object); const submitData = foundry.utils.expandObject(formData.object);
for ( const keyPath of this.constructor.CLEAN_ARRAYS ) { for (const keyPath of this.constructor.CLEAN_ARRAYS) {
const data = foundry.utils.getProperty(submitData, keyPath); const data = foundry.utils.getProperty(submitData, keyPath);
if ( data ) foundry.utils.setProperty(submitData, keyPath, Object.values(data)); if (data) foundry.utils.setProperty(submitData, keyPath, Object.values(data));
} }
return submitData; return submitData;
} }

View file

@ -103,7 +103,6 @@ export default class DHAdversarySettings extends HandlebarsApplicationMixin(Appl
context.systemFields = this.actor.system.schema.fields; context.systemFields = this.actor.system.schema.fields;
context.systemFields.attack.fields = this.actor.system.attack.schema.fields; context.systemFields.attack.fields = this.actor.system.attack.schema.fields;
context.isNPC = true; context.isNPC = true;
console.log(context);
return context; return context;
} }

View file

@ -44,7 +44,7 @@ export default class BeastformSheet extends DHBaseItemSheet {
static editFeature(event) { static editFeature(event) {
const target = event.target.closest('[data-action="editFeature"]'); const target = event.target.closest('[data-action="editFeature"]');
const feature = this.document.system.features[target.dataset.index]; const feature = this.document.system.features[target.dataset.index];
feature.sheet.render(true); feature.sheet.render({ force: true });
} }
static async removeFeature(_, target) { static async removeFeature(_, target) {
@ -52,7 +52,6 @@ export default class BeastformSheet extends DHBaseItemSheet {
await this.document.update({ await this.document.update({
'system.features': current.filter((_, index) => index !== Number(target.dataset.index)) 'system.features': current.filter((_, index) => index !== Number(target.dataset.index))
}); });
this.render();
} }
async _onDrop(event) { async _onDrop(event) {

View file

@ -275,18 +275,6 @@ export class DHBaseAction extends foundry.abstract.DataModel {
}) */ }) */
} }
if (this instanceof DhBeastformAction) {
config.beastform = this.prepareBeastformConfig();
const abort = await this.handleActiveTransformations();
if (abort) return;
const beastformUuid = await BeastformDialog.configure(config);
if (!beastformUuid) return;
await this.transform(beastformUuid);
}
if (this.doFollowUp()) { if (this.doFollowUp()) {
if (this.rollDamage) await this.rollDamage(event, config); if (this.rollDamage) await this.rollDamage(event, config);
if (this.rollHealing) await this.rollHealing(event, config); if (this.rollHealing) await this.rollHealing(event, config);
@ -779,11 +767,23 @@ export class DHMacroAction extends DHBaseAction {
export class DhBeastformAction extends DHBaseAction { export class DhBeastformAction extends DHBaseAction {
static extraSchemas = ['beastform']; static extraSchemas = ['beastform'];
async use(event, ...args) {
const beastformConfig = this.prepareBeastformConfig();
const abort = await this.handleActiveTransformations();
if (abort) return;
const beastformUuid = await BeastformDialog.configure(beastformConfig);
if (!beastformUuid) return;
await this.transform(beastformUuid);
}
prepareBeastformConfig(config) { prepareBeastformConfig(config) {
const settingsTier = game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.LevelTiers).tiers; const settingsTiers = game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.LevelTiers).tiers;
const actorLevel = this.actor.system.levelData.level.current; const actorLevel = this.actor.system.levelData.level.current;
const actorTier = const actorTier =
Object.values(settingsTier).find( Object.values(settingsTiers).find(
tier => actorLevel >= tier.levels.start && actorLevel <= tier.levels.end tier => actorLevel >= tier.levels.start && actorLevel <= tier.levels.end
) ?? 1; ) ?? 1;

View file

@ -4,7 +4,6 @@ export default class BeastformEffect extends foundry.abstract.TypeDataModel {
static defineSchema() { static defineSchema() {
const fields = foundry.data.fields; const fields = foundry.data.fields;
return { return {
isBeastform: new fields.BooleanField({ initial: false }),
characterTokenData: new fields.SchemaField({ characterTokenData: new fields.SchemaField({
tokenImg: new fields.FilePathField({ tokenImg: new fields.FilePathField({
categories: ['IMAGE'], categories: ['IMAGE'],
@ -34,13 +33,8 @@ export default class BeastformEffect extends foundry.abstract.TypeDataModel {
await updateActorTokens(this.parent.parent, update); await updateActorTokens(this.parent.parent, update);
for (var feature of this.parent.parent.items.filter(x => this.featureIds.includes(x.id))) { await this.parent.parent.deleteEmbeddedDocuments('Item', this.featureIds);
await feature.delete(); await this.parent.parent.deleteEmbeddedDocuments('ActiveEffect', this.effectIds);
}
for (var effect of this.parent.parent.effects.filter(x => this.effectIds.includes(x.id))) {
await effect.delete();
}
} }
} }
} }

View file

@ -43,14 +43,16 @@ export default class DHBeastform extends BaseDataItem {
const allowed = await super._preCreate(data, options, user); const allowed = await super._preCreate(data, options, user);
if (allowed === false) return; if (allowed === false) return;
if (this.actor?.type !== 'character') { if (!this.actor) return;
ui.notifications.error(game.i18n.localize('DAGGERHEART.UI.beastformInapplicable'));
return; if (this.actor.type !== 'character') {
ui.notifications.error(game.i18n.localize('DAGGERHEART.UI.notifications.beastformInapplicable'));
return false;
} }
if (this.actor.items.find(x => x.type === 'beastform')) { if (this.actor.items.find(x => x.type === 'beastform')) {
ui.notifications.error(game.i18n.localize('DAGGERHEART.UI.beastformAlreadyApplied')); ui.notifications.error(game.i18n.localize('DAGGERHEART.UI.notifications.beastformAlreadyApplied'));
return; return false;
} }
const features = await this.parent.parent.createEmbeddedDocuments( const features = await this.parent.parent.createEmbeddedDocuments(

View file

@ -12,7 +12,6 @@ export default class BeastformDialog extends HandlebarsApplicationMixin(Applicat
static DEFAULT_OPTIONS = { static DEFAULT_OPTIONS = {
tag: 'form', tag: 'form',
id: 'beastform-selection',
classes: ['daggerheart', 'views', 'dh-style', 'beastform-selection'], classes: ['daggerheart', 'views', 'dh-style', 'beastform-selection'],
position: { position: {
width: 600, width: 600,
@ -42,11 +41,10 @@ export default class BeastformDialog extends HandlebarsApplicationMixin(Applicat
async _prepareContext(_options) { async _prepareContext(_options) {
const context = await super._prepareContext(_options); const context = await super._prepareContext(_options);
context.configData = this.configData;
context.beastformTiers = game.items.reduce((acc, x) => { context.beastformTiers = game.items.reduce((acc, x) => {
const tier = tiers[x.system.tier]; const tier = tiers[x.system.tier];
if (x.type !== 'beastform' || tier.value > context.configData.beastform.tierLimit) return acc; if (x.type !== 'beastform' || tier.value > this.configData.tierLimit) return acc;
if (!acc[tier.value]) acc[tier.value] = { label: game.i18n.localize(tier.label), values: {} }; if (!acc[tier.value]) acc[tier.value] = { label: game.i18n.localize(tier.label), values: {} };
acc[tier.value].values[x.uuid] = { selected: this.selected == x.uuid, value: x }; acc[tier.value].values[x.uuid] = { selected: this.selected == x.uuid, value: x };

View file

@ -51,7 +51,6 @@ export default class D20RollDialog extends HandlebarsApplicationMixin(Applicatio
}; };
async _prepareContext(_options) { async _prepareContext(_options) {
console.log(this.config, this.roll);
const context = await super._prepareContext(_options); const context = await super._prepareContext(_options);
context.hasRoll = !!this.config.roll; context.hasRoll = !!this.config.roll;
context.roll = this.roll; context.roll = this.roll;

View file

@ -299,12 +299,10 @@ export const updateActorTokens = async (actor, update) => {
await actor.prototypeToken.update(update); await actor.prototypeToken.update(update);
/* Update the tokens in all scenes belonging to Actor */ /* Update the tokens in all scenes belonging to Actor */
for (let scene of game.scenes) { for (let token of actor.getDependentTokens()) {
for (let token of scene.tokens) { const tokenActor = token.baseActor ?? token.actor;
const tokenActor = token.baseActor ?? token.actor; if (tokenActor?.id === actor.id) {
if (tokenActor?.id === actor.id) { await token.update(update);
await token.update(update);
}
} }
} }
}; };

View file

@ -372,7 +372,6 @@ div.daggerheart.views.multiclass {
} }
} }
.roll-dialog-experience-container { .roll-dialog-experience-container {
display: flex; display: flex;
align-items: flex-start; align-items: flex-start;
@ -509,6 +508,34 @@ div.daggerheart.views.multiclass {
} }
} }
.hint-group {
display: flex;
flex-direction: column;
align-items: end;
.form-fields {
width: 100%;
display: flex;
align-items: center;
label {
flex: 1;
}
input,
select {
flex: 3;
}
}
.hint {
margin: 4px 0 0 0;
font-size: 12px;
font-style: italic;
opacity: 0.6;
}
}
.data-form-array { .data-form-array {
border: 1px solid var(--color-fieldset-border); border: 1px solid var(--color-fieldset-border);
padding: 0.5rem; padding: 0.5rem;

View file

@ -2329,6 +2329,29 @@ div.daggerheart.views.multiclass {
width: 1.5rem; width: 1.5rem;
height: 1.5rem; height: 1.5rem;
} }
.daggerheart.views.action .action-category .action-category-data .hint-group {
display: flex;
flex-direction: column;
align-items: end;
}
.daggerheart.views.action .action-category .action-category-data .hint-group .form-fields {
width: 100%;
display: flex;
align-items: center;
}
.daggerheart.views.action .action-category .action-category-data .hint-group .form-fields label {
flex: 1;
}
.daggerheart.views.action .action-category .action-category-data .hint-group .form-fields input,
.daggerheart.views.action .action-category .action-category-data .hint-group .form-fields select {
flex: 3;
}
.daggerheart.views.action .action-category .action-category-data .hint-group .hint {
margin: 4px 0 0 0;
font-size: 12px;
font-style: italic;
opacity: 0.6;
}
.daggerheart.views.action .action-category .action-category-data .data-form-array { .daggerheart.views.action .action-category .action-category-data .data-form-array {
border: 1px solid var(--color-fieldset-border); border: 1px solid var(--color-fieldset-border);
padding: 0.5rem; padding: 0.5rem;

View file

@ -4,9 +4,14 @@
</legend> </legend>
<div class="action-category-data open"> <div class="action-category-data open">
{{formGroup <div class="hint-group">
@root.fields.beastform.fields.tierAccess.fields.exact value=@root.source.beastform.tierAccess.exact name="beastform.tierAccess.exact" <div class="form-fields">
placeholder=(localize "DAGGERHEART.Actions.Config.Beastform.exactPlaceholder") label="DAGGERHEART.Actions.Config.Beastform.exact" localize=true <label>{{localize "DAGGERHEART.Actions.Config.Beastform.exact"}}</label>
}} <select name="beastform.tierAccess.exact" data-dtype="Number">
{{selectOptions tierOptions selected=@root.source.beastform.tierAccess.exact labelAttr="label" valueAttr="key" blank="" }}
</select>
</div>
<p class="hint">{{localize "DAGGERHEART.Actions.Config.Beastform.exactHint"}}</p>
</div>
</div> </div>
</fieldset> </fieldset>