Completed

This commit is contained in:
WBHarry 2026-04-19 15:20:38 +02:00
parent 58b855389d
commit 774141a8da
8 changed files with 94 additions and 66 deletions

View file

@ -7,26 +7,31 @@ export default class DHAbilityUse extends foundry.abstract.TypeDataModel {
img: new fields.StringField({}),
name: new fields.StringField({}),
description: new fields.StringField({}),
actions: new fields.ArrayField(
new fields.ObjectField({
name: new fields.StringField({}),
damage: new fields.SchemaField({
type: new fields.StringField({}),
value: new fields.StringField({})
}),
healing: new fields.SchemaField({
type: new fields.StringField({}),
value: new fields.StringField({})
}),
cost: new fields.SchemaField({
type: new fields.StringField({}),
value: new fields.NumberField({})
}),
target: new fields.SchemaField({
type: new fields.StringField({ nullable: true })
})
})
)
source: new fields.SchemaField({
actor: new fields.StringField(),
item: new fields.StringField(),
action: new fields.StringField()
}),
};
}
get actionActor() {
if (!this.source.actor) return null;
return fromUuidSync(this.source.actor);
}
get actionItem() {
const actionActor = this.actionActor;
if (!actionActor || !this.source.item) return null;
const item = actionActor.items.get(this.source.item);
return item ? item.system.actionsList?.find(a => a.id === this.source.action) : null;
}
get action() {
const { actionItem: itemAction } = this;
if (!this.source.action) return null;
if (itemAction) return itemAction;
return null;
}
}

View file

@ -9,6 +9,11 @@ export default class AreaField extends fields.ArrayField {
/** @inheritDoc */
constructor(options = {}, context = {}) {
const element = new fields.SchemaField({
name: new fields.StringField({
nullable: false,
initial: 'Area',
label: 'DAGGERHEART.GENERAL.name'
}),
type: new fields.StringField({
nullable: false,
choices: CONFIG.DH.ACTIONS.areaTypes,

View file

@ -281,8 +281,14 @@ export function ActionMixin(Base) {
name: this.name,
img: this.baseAction ? this.parent.parent.img : this.img,
tags: this.tags ? this.tags : ['Spell', 'Arcana', 'Lv 10'],
area: this.area,
summon: this.summon
},
source: {
actor: this.actor.uuid,
item: this.item.id,
action: this.id,
},
itemOrigin: this.item,
description: this.description || (this.item instanceof Item ? this.item.system.description : '')
};

View file

@ -254,53 +254,51 @@ export default class DhpChatMessage extends foundry.documents.ChatMessage {
}
async onCreateAreas(event) {
let selectedArea = null;
if (this.system.action.area.length === 1)
selectedArea = this.system.action.area[0];
else if(this.system.action.area.length > 1) {
/* Pop a selection. Possibly a context menu? */
// new foundry.applications.ux.ContextMenu.implementation(
// event.target,
// '.scene-environment',
// this.system.action.area.map((area, index) => ({
// name: index,
// callback: () => {
const createArea = async (selectedArea) => {
const effects = selectedArea.effects.map(effect => this.system.action.item.effects.get(effect).uuid);
const { shape: type, size: range } = selectedArea;
const shapeData = CONFIG.Canvas.layers.regions.layerClass.getTemplateShape({ type, range });
// }
// })),
// {
// jQuery: false,
// fixed: true
// }
// );
// CONFIG.ux.ContextMenu.triggerContextMenu(event, '.scene-environment');
await canvas.regions.placeRegion(
{
name: selectedArea.name,
shapes: [shapeData],
restriction: { enabled: false, type: 'move', priority: 0 },
behaviors: [{
name: game.i18n.localize('TYPES.RegionBehavior.applyActiveEffect'),
type: 'applyActiveEffect',
system: {
effects: effects
}
}],
displayMeasurements: true,
locked: false,
ownership: { default: CONST.DOCUMENT_OWNERSHIP_LEVELS.NONE },
visibility: CONST.REGION_VISIBILITY.ALWAYS
},
{ create: true }
);
}
if(!selectedArea) return;
const effects = selectedArea.effects.map(effect => this.system.action.item.effects.get(effect).uuid);
const { shape: type, size: range } = this.system.action.area[0];
const shapeData = CONFIG.Canvas.layers.regions.layerClass.getTemplateShape({ type, range });
if (this.system.action.area.length === 1)
createArea(this.system.action.area[0]);
else if(this.system.action.area.length > 1) {
/* Pop a selection. Possibly a context menu? */
new foundry.applications.ux.ContextMenu.implementation(
event.target,
'.action-areas',
this.system.action.area.map((area, index) => ({
name: area.name,
callback: () => createArea(this.system.action.area[index]),
})),
{
jQuery: false,
fixed: true
}
);
await canvas.regions.placeRegion(
{
name: 'Test',
shapes: [shapeData],
restriction: { enabled: false, type: 'move', priority: 0 },
behaviors: [{
name: game.i18n.localize('TYPES.RegionBehavior.applyActiveEffect'),
type: 'applyActiveEffect',
system: {
effects: effects
}
}],
displayMeasurements: true,
locked: false,
ownership: { default: CONST.DOCUMENT_OWNERSHIP_LEVELS.NONE },
visibility: CONST.REGION_VISIBILITY.ALWAYS
},
{ create: true }
);
CONFIG.ux.ContextMenu.triggerContextMenu(event, '.action-areas');
}
}
filterPermTargets(targets) {

View file

@ -629,7 +629,8 @@
height: 32px;
flex: 1;
&.no-flex {
&.end-button {
margin-left: auto;
flex: 0;
}
}
@ -703,6 +704,11 @@
}
}
.action-roll-buttons {
width: 100%;
padding: 0 8px;
}
.description {
padding: 8px;

View file

@ -6,11 +6,14 @@
{{#each source as |area index|}}
{{#unless @first}}<line-div></line-div>{{/unless}}
<div class="nest-inputs">
{{formField ../fields.name value=area.name name=(concat "area." index ".name") localize=true}}
<a class="btn" data-tooltip="{{localize "CONTROLS.CommonDelete"}}" data-action="removeElement" data-index="{{index}}"><i class="fas fa-trash"></i></a>
</div>
<div class="nest-inputs">
{{formField ../fields.type value=area.type name=(concat "area." index ".type") localize=true}}
{{formField ../fields.shape value=area.shape name=(concat "area." index ".shape") localize=true}}
{{formField ../fields.size value=area.size name=(concat "area." index ".size") localize=true}}
<a class="btn" data-tooltip="{{localize "CONTROLS.CommonDelete"}}" data-action="removeElement" data-index="{{index}}"><i class="fas fa-trash"></i></a>
</div>
<div class="sub-section-header">

View file

@ -26,4 +26,9 @@
{{/if}}
</div>
</details>
{{#if action.area.length}}
<div class="roll-buttons action-roll-buttons">
<button class="action-areas end-button"><i class="fa-solid fa-crosshairs"></i></button>
</div>
{{/if}}
</div>

View file

@ -14,5 +14,5 @@
{{/unless}}
{{/if}}
{{#if (and hasEffect)}}<button class="duality-action-effect">{{localize "DAGGERHEART.UI.Chat.attackRoll.applyEffect"}}</button>{{/if}}
{{#if areas.length}}<button class="action-areas no-flex"><i class="fa-solid fa-crosshairs"></i></button>{{/if}}
{{#if areas.length}}<button class="action-areas end-button"><i class="fa-solid fa-crosshairs"></i></button>{{/if}}
</div>