mirror of
https://github.com/Foundryborne/daggerheart.git
synced 2026-01-12 03:31:07 +01:00
Reworked Action storage
This commit is contained in:
parent
3333a9e00a
commit
ce593d02f3
16 changed files with 196 additions and 23 deletions
|
|
@ -286,6 +286,7 @@ const preloadHandlebarsTemplates = async function () {
|
|||
return foundry.applications.handlebars.loadTemplates([
|
||||
'systems/daggerheart/templates/sheets/global/tabs/tab-navigation.hbs',
|
||||
'systems/daggerheart/templates/sheets/global/partials/inventory-item.hbs',
|
||||
'systems/daggerheart/templates/sheets/global/partials/action-item.hbs',
|
||||
'systems/daggerheart/templates/sheets/global/partials/domain-card-item.hbs',
|
||||
'systems/daggerheart/templates/sheets/global/partials/inventory-fieldset-items.hbs',
|
||||
|
||||
|
|
|
|||
16
lang/en.json
16
lang/en.json
|
|
@ -501,6 +501,20 @@
|
|||
"bonded": "When you mark your last Hit Point, your companion rushes to your side to comfort you. Roll a number of d6s equal to the unmarked Stress slots they have and mark them. If any roll a 6, your companion helps you up. Clear your last Hit Point and return to the scene.",
|
||||
"aware": "Your companion gains a permanent +2 bonus to their Evasion."
|
||||
},
|
||||
"Actions": {
|
||||
"CreatureComfort": {
|
||||
"Name": "Creature Comfort",
|
||||
"Description": "Once per rest, when you take time during a quiet moment to give your companion love and attention, you can gain a Hope or you can both clear a Stress."
|
||||
},
|
||||
"Armored": {
|
||||
"Name": "Armored",
|
||||
"Description": "When your companion takes damage, you can mark one of your Armor Slots instead of marking one of their Stress."
|
||||
},
|
||||
"Bonded": {
|
||||
"Name": "Bonded",
|
||||
"Description": "When you mark your last Hit Point, your companion rushes to your side to comfort you. Roll a number of d6s equal to the unmarked Stress slots they have and mark them. If any roll a 6, your companion helps you up. Clear your last Hit Point and return to the scene."
|
||||
}
|
||||
},
|
||||
"Tier2": {
|
||||
"Label": "Levels 2-4",
|
||||
"InfoLabel": "At Level 2, gain an additional Experience at +2 and gain a +1 bonus to your Proficiency.",
|
||||
|
|
@ -1146,6 +1160,8 @@
|
|||
"CharacterSetup": "Character setup isn't done yet",
|
||||
"Level": "Level",
|
||||
"LevelUp": "You can level up",
|
||||
"Actions": "Actions",
|
||||
"CompanionActions": "Companion Actions",
|
||||
"Tabs": {
|
||||
"Features": "Features",
|
||||
"Inventory": "Inventory",
|
||||
|
|
|
|||
|
|
@ -143,7 +143,7 @@ export default class AncestrySelectionDialog extends HandlebarsApplicationMixin(
|
|||
}
|
||||
|
||||
static _onEditImage() {
|
||||
const fp = new FilePicker({
|
||||
const fp = new foundry.applications.apps.FilePicker.implementation({
|
||||
current: this.data.ancestryInfo.img,
|
||||
type: 'image',
|
||||
redirectToRoot: ['icons/svg/mystery-man.svg'],
|
||||
|
|
|
|||
|
|
@ -160,7 +160,7 @@ class Countdowns extends HandlebarsApplicationMixin(ApplicationV2) {
|
|||
static onEditImage(_, target) {
|
||||
const setting = game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Countdowns)[this.basePath];
|
||||
const current = setting.countdowns[target.dataset.countdown].img;
|
||||
const fp = new FilePicker({
|
||||
const fp = new foundry.applications.apps.FilePicker.implementation({
|
||||
current,
|
||||
type: 'image',
|
||||
callback: async path => this.updateImage.bind(this)(path, target.dataset.countdown),
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ export default class DhSettingsActionView extends HandlebarsApplicationMixin(App
|
|||
}
|
||||
|
||||
static onEditImage() {
|
||||
const fp = new FilePicker({
|
||||
const fp = new foundry.applications.apps.FilePicker.implementation({
|
||||
current: this.img,
|
||||
type: 'image',
|
||||
callback: async path => {
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@ import DaggerheartSheet from './daggerheart-sheet.mjs';
|
|||
import { abilities } from '../../config/actorConfig.mjs';
|
||||
import DhCharacterlevelUp from '../levelup/characterLevelup.mjs';
|
||||
import DhCharacterCreation from '../characterCreation.mjs';
|
||||
import DHActionConfig from '../config/Action.mjs';
|
||||
import { DHBaseAction } from '../../data/action/action.mjs';
|
||||
|
||||
const { ActorSheetV2 } = foundry.applications.sheets;
|
||||
const { TextEditor } = foundry.applications.ux;
|
||||
|
|
@ -51,6 +53,7 @@ export default class CharacterSheet extends DaggerheartSheet(ActorSheetV2) {
|
|||
levelManagement: this.levelManagement,
|
||||
editImage: this._onEditImage,
|
||||
triggerContextMenu: this.triggerContextMenu
|
||||
// editAction: this.editAction,
|
||||
},
|
||||
window: {
|
||||
resizable: true
|
||||
|
|
@ -303,17 +306,27 @@ export default class CharacterSheet extends DaggerheartSheet(ActorSheetV2) {
|
|||
}
|
||||
|
||||
getItem(element) {
|
||||
const itemId = (element.target ?? element).closest('[data-item-id]').dataset.itemId,
|
||||
const listElement = (element.target ?? element).closest('[data-item-id]');
|
||||
if (listElement.dataset.isAction) return this.getAction(listElement);
|
||||
|
||||
const itemId = listElement.dataset.itemId,
|
||||
item = this.document.items.get(itemId);
|
||||
return item;
|
||||
}
|
||||
|
||||
getAction(listElement) {
|
||||
const target = listElement.dataset.partner === 'true' ? this.document.system.companion : this.document;
|
||||
if (!target) return null;
|
||||
|
||||
return target.system.actions.find(x => x.id === listElement.dataset.itemId);
|
||||
}
|
||||
|
||||
static triggerContextMenu(event, button) {
|
||||
return CONFIG.ux.ContextMenu.triggerContextMenu(event);
|
||||
}
|
||||
|
||||
static _onEditImage() {
|
||||
const fp = new FilePicker({
|
||||
const fp = new foundry.applications.apps.FilePicker.implementation({
|
||||
current: this.document.img,
|
||||
type: 'image',
|
||||
redirectToRoot: ['icons/svg/mystery-man.svg'],
|
||||
|
|
@ -616,10 +629,15 @@ export default class CharacterSheet extends DaggerheartSheet(ActorSheetV2) {
|
|||
}
|
||||
}
|
||||
|
||||
static async viewObject(event, button) {
|
||||
static async viewObject(event) {
|
||||
const item = this.getItem(event);
|
||||
if (!item) return;
|
||||
item.sheet.render(true);
|
||||
|
||||
if (item instanceof DHBaseAction) {
|
||||
new DHActionConfig(item).render({ force: true });
|
||||
} else {
|
||||
item.sheet.render(true);
|
||||
}
|
||||
}
|
||||
|
||||
editItem(event) {
|
||||
|
|
@ -672,10 +690,16 @@ export default class CharacterSheet extends DaggerheartSheet(ActorSheetV2) {
|
|||
this.render();
|
||||
}
|
||||
|
||||
static async deleteItem(event, button) {
|
||||
static async deleteItem(event) {
|
||||
const item = this.getItem(event);
|
||||
if (!item) return;
|
||||
await item.delete();
|
||||
|
||||
if (item instanceof DHBaseAction) {
|
||||
const newActions = item.parent.actions.filter(x => x.id !== item.id);
|
||||
await item.parent.parent.update({ ['system.actions']: newActions });
|
||||
} else {
|
||||
await item.delete();
|
||||
}
|
||||
}
|
||||
|
||||
static async setItemQuantity(button, value) {
|
||||
|
|
@ -711,7 +735,30 @@ export default class CharacterSheet extends DaggerheartSheet(ActorSheetV2) {
|
|||
}
|
||||
|
||||
static async toChat(event, button) {
|
||||
if (button?.dataset?.type === 'experience') {
|
||||
const item = event.dataset ? event : button.closest(['[data-item-id']);
|
||||
if (item?.dataset.isAction) {
|
||||
const action = this.getAction(item);
|
||||
const cls = getDocumentClass('ChatMessage');
|
||||
const systemData = {
|
||||
title: action.name,
|
||||
origin: this,
|
||||
img: action.img,
|
||||
name: action.name,
|
||||
description: action.description,
|
||||
actions: []
|
||||
};
|
||||
const msg = new cls({
|
||||
type: 'abilityUse',
|
||||
user: game.user.id,
|
||||
system: systemData,
|
||||
content: await foundry.applications.handlebars.renderTemplate(
|
||||
'systems/daggerheart/templates/chat/ability-use.hbs',
|
||||
systemData
|
||||
)
|
||||
});
|
||||
|
||||
cls.create(msg.toObject());
|
||||
} else if (button?.dataset?.type === 'experience') {
|
||||
const experience = this.document.system.experiences[button.dataset.uuid];
|
||||
const cls = getDocumentClass('ChatMessage');
|
||||
const systemData = {
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ export default function DhpApplicationMixin(Base) {
|
|||
const attr = target.dataset.edit;
|
||||
const current = foundry.utils.getProperty(this.document, attr);
|
||||
const { img } = this.document.constructor.getDefaultArtwork?.(this.document.toObject()) ?? {};
|
||||
const fp = new FilePicker({
|
||||
const fp = new foundry.applications.apps.FilePicker.implementation({
|
||||
current,
|
||||
type: 'image',
|
||||
redirectToRoot: img ? [img] : [],
|
||||
|
|
|
|||
|
|
@ -130,7 +130,11 @@ export class DHBaseAction extends foundry.abstract.DataModel {
|
|||
}
|
||||
|
||||
get actor() {
|
||||
return this.item instanceof DhpActor ? this.item : this.item?.actor;
|
||||
return this.item instanceof DhpActor
|
||||
? this.item
|
||||
: this.item?.parent instanceof DhpActor
|
||||
? this.item.parent
|
||||
: this.item?.actor;
|
||||
}
|
||||
|
||||
get chatTemplate() {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import { burden } from '../../config/generalConfig.mjs';
|
||||
import ActionField from '../fields/actionField.mjs';
|
||||
import ForeignDocumentUUIDField from '../fields/foreignDocumentUUIDField.mjs';
|
||||
import DhLevelData from '../levelData.mjs';
|
||||
import BaseDataActor from './base.mjs';
|
||||
|
|
@ -96,6 +97,7 @@ export default class DhCharacter extends BaseDataActor {
|
|||
value: new ForeignDocumentUUIDField({ type: 'Item', nullable: true }),
|
||||
subclass: new ForeignDocumentUUIDField({ type: 'Item', nullable: true })
|
||||
}),
|
||||
actions: new fields.ArrayField(new ActionField()),
|
||||
levelData: new fields.EmbeddedDataField(DhLevelData),
|
||||
bonuses: new fields.SchemaField({
|
||||
armorScore: new fields.NumberField({ integer: true, initial: 0 }),
|
||||
|
|
@ -155,6 +157,17 @@ export default class DhCharacter extends BaseDataActor {
|
|||
return this.parent.items.find(x => x.type === 'community') ?? null;
|
||||
}
|
||||
|
||||
// get actions() {
|
||||
// const generalActions = []; // Add in things like Sprint etc
|
||||
// const levelupActions = this.levelData.actions.filter(x => !x.partner).map(x => x.value);
|
||||
|
||||
// return [...generalActions, ...levelupActions];
|
||||
// }
|
||||
|
||||
get companionActions() {
|
||||
return this.companion ? this.companion.system.actions : [];
|
||||
}
|
||||
|
||||
get needsCharacterSetup() {
|
||||
return !this.class.value || !this.class.subclass;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -72,6 +72,7 @@ export default class DhCompanion extends BaseDataActor {
|
|||
}
|
||||
}
|
||||
}),
|
||||
actions: new fields.ArrayField(new ActionField()),
|
||||
levelData: new fields.EmbeddedDataField(DhLevelData)
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,7 +42,8 @@ export default class DhLevelData extends foundry.abstract.DataModel {
|
|||
amount: new fields.NumberField({ integer: true }),
|
||||
data: new fields.ArrayField(new fields.StringField({ required: true })),
|
||||
secondaryData: new fields.TypedObjectField(new fields.StringField({ required: true })),
|
||||
itemUuid: new fields.StringField({ required: true })
|
||||
itemUuid: new fields.StringField({ required: true }),
|
||||
actionIds: new fields.ArrayField(new fields.StringField())
|
||||
})
|
||||
)
|
||||
})
|
||||
|
|
@ -50,6 +51,10 @@ export default class DhLevelData extends foundry.abstract.DataModel {
|
|||
};
|
||||
}
|
||||
|
||||
get actions() {
|
||||
return Object.values(this.levelups).flatMap(level => level.selections.flatMap(s => s.actions));
|
||||
}
|
||||
|
||||
get canLevelUp() {
|
||||
return this.level.current < this.level.changed;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -65,14 +65,29 @@ export const CompanionLevelOptionType = {
|
|||
},
|
||||
creatureComfort: {
|
||||
id: 'creatureComfort',
|
||||
label: 'Creature Comfort'
|
||||
// actions: [
|
||||
|
||||
// ],
|
||||
label: 'Creature Comfort',
|
||||
actions: [
|
||||
{
|
||||
name: 'DAGGERHEART.LevelUp.Actions.CreatureComfort.Name',
|
||||
img: 'icons/magic/life/heart-cross-purple-orange.webp',
|
||||
type: 'attack',
|
||||
actionType: 'passive',
|
||||
description: 'DAGGERHEART.LevelUp.Actions.CreatureComfort.Description'
|
||||
}
|
||||
]
|
||||
},
|
||||
armored: {
|
||||
id: 'armored',
|
||||
label: 'Armored'
|
||||
label: 'Armored',
|
||||
actions: [
|
||||
{
|
||||
name: 'DAGGERHEART.LevelUp.Actions.Armored.Name',
|
||||
img: 'icons/equipment/shield/kite-wooden-oak-glow.webp',
|
||||
type: 'attack',
|
||||
actionType: 'passive',
|
||||
description: 'DAGGERHEART.LevelUp.Actions.Armored.Description'
|
||||
}
|
||||
]
|
||||
},
|
||||
vicious: {
|
||||
id: 'vicious',
|
||||
|
|
@ -84,7 +99,16 @@ export const CompanionLevelOptionType = {
|
|||
},
|
||||
bonded: {
|
||||
id: 'bonded',
|
||||
label: 'Bonded'
|
||||
label: 'Bonded',
|
||||
actions: [
|
||||
{
|
||||
name: 'DAGGERHEART.LevelUp.Actions.Bonded.Name',
|
||||
img: 'icons/magic/life/heart-red-blue.webp',
|
||||
type: 'attack',
|
||||
actionType: 'passive',
|
||||
description: 'DAGGERHEART.LevelUp.Actions.Bonded.Description'
|
||||
}
|
||||
]
|
||||
},
|
||||
aware: {
|
||||
id: 'aware',
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
import DamageSelectionDialog from '../applications/damageSelectionDialog.mjs';
|
||||
import { GMUpdateEvent, socketEvent } from '../helpers/socket.mjs';
|
||||
import DamageReductionDialog from '../applications/damageReductionDialog.mjs';
|
||||
import { actionsTypes } from '../data/_module.mjs';
|
||||
import { LevelOptionType } from '../data/levelTier.mjs';
|
||||
|
||||
export default class DhpActor extends Actor {
|
||||
async _preCreate(data, options, user) {
|
||||
|
|
@ -20,10 +22,6 @@ export default class DhpActor extends Actor {
|
|||
async updateLevel(newLevel) {
|
||||
if (!['character', 'companion'].includes(this.type) || newLevel === this.system.levelData.level.changed) return;
|
||||
|
||||
if (this.system.companion) {
|
||||
this.system.companion.updateLevel(newLevel);
|
||||
}
|
||||
|
||||
if (newLevel > this.system.levelData.level.current) {
|
||||
const maxLevel = Object.values(
|
||||
game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.LevelTiers).tiers
|
||||
|
|
@ -122,10 +120,15 @@ export default class DhpActor extends Actor {
|
|||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (this.system.companion) {
|
||||
this.system.companion.updateLevel(newLevel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async levelUp(levelupData) {
|
||||
const actions = [];
|
||||
const levelups = {};
|
||||
for (var levelKey of Object.keys(levelupData)) {
|
||||
const level = levelupData[levelKey];
|
||||
|
|
@ -150,6 +153,7 @@ export default class DhpActor extends Actor {
|
|||
}
|
||||
|
||||
let multiclass = null;
|
||||
const actionIds = [];
|
||||
const domainCards = [];
|
||||
const subclassFeatureState = { class: null, multiclass: null };
|
||||
const selections = [];
|
||||
|
|
@ -158,6 +162,27 @@ export default class DhpActor extends Actor {
|
|||
for (var checkboxNr of Object.keys(selection)) {
|
||||
const checkbox = selection[checkboxNr];
|
||||
|
||||
const tierOption = LevelOptionType[checkbox.type];
|
||||
for (var actionData of tierOption.actions ?? []) {
|
||||
const cls = actionsTypes[actionData.type];
|
||||
const actionId = foundry.utils.randomID();
|
||||
actionIds.push(actionId);
|
||||
actions.push(
|
||||
new cls(
|
||||
{
|
||||
// ...cls.getSourceConfig(target),
|
||||
...actionData,
|
||||
_id: actionId,
|
||||
name: game.i18n.localize(actionData.name),
|
||||
description: game.i18n.localize(actionData.description)
|
||||
},
|
||||
{
|
||||
parent: this
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if (checkbox.type === 'multiclass') {
|
||||
multiclass = {
|
||||
...checkbox,
|
||||
|
|
@ -255,6 +280,7 @@ export default class DhpActor extends Actor {
|
|||
|
||||
await this.update({
|
||||
system: {
|
||||
actions: [...this.system.actions, ...actions],
|
||||
levelData: {
|
||||
level: {
|
||||
current: this.system.levelData.level.changed
|
||||
|
|
@ -263,6 +289,10 @@ export default class DhpActor extends Actor {
|
|||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (this.system.companion) {
|
||||
this.system.companion.updateLevel(this.system.levelData.level.changed);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -10,6 +10,12 @@
|
|||
{{#if document.system.class.subclass}}
|
||||
{{> 'systems/daggerheart/templates/sheets/global/partials/inventory-fieldset-items.hbs' title=(concat (localize 'TYPES.Item.subclass') ' - ' document.system.class.subclass.name) type='subclass'}}
|
||||
{{/if}}
|
||||
{{#if document.system.actions}}
|
||||
{{> 'systems/daggerheart/templates/sheets/global/partials/inventory-fieldset-items.hbs' title=(localize "DAGGERHEART.Sheets.PC.Actions") type='actions'}}
|
||||
{{/if}}
|
||||
{{#if document.system.companionActions}}
|
||||
{{> 'systems/daggerheart/templates/sheets/global/partials/inventory-fieldset-items.hbs' title=(localize "DAGGERHEART.Sheets.PC.CompanionActions") type='companionActions'}}
|
||||
{{/if}}
|
||||
{{#if document.system.community}}
|
||||
{{> 'systems/daggerheart/templates/sheets/global/partials/inventory-fieldset-items.hbs' title=(concat (localize 'TYPES.Item.community') ' - ' document.system.community.name) type='community'}}
|
||||
{{/if}}
|
||||
|
|
|
|||
16
templates/sheets/global/partials/action-item.hbs
Normal file
16
templates/sheets/global/partials/action-item.hbs
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
<li class="inventory-item" data-item-id="{{item.id}}" data-is-action="true" data-partner="{{partner}}">
|
||||
<img src="{{item.img}}" class="item-img" data-action="useItem" />
|
||||
<div class="item-label">
|
||||
<div class="item-name">{{item.name}}</div>
|
||||
{{!-- <div class="item-tags">
|
||||
<div class="tag">
|
||||
</div>
|
||||
<div class="tag">
|
||||
</div>
|
||||
</div> --}}
|
||||
</div>
|
||||
<div class="controls">
|
||||
<a data-action="toChat" data-tooltip="{{localize 'DAGGERHEART.Tooltip.sendToChat'}}"><i class="fa-regular fa-message"></i></a>
|
||||
<a data-action="triggerContextMenu" data-tooltip="{{localize 'DAGGERHEART.Tooltip.moreOptions'}}"><i class="fa-solid fa-ellipsis-vertical"></i></a>
|
||||
</div>
|
||||
</li>
|
||||
|
|
@ -34,6 +34,16 @@
|
|||
{{> 'systems/daggerheart/templates/sheets/global/partials/inventory-item.hbs' item=effect type=../type}}
|
||||
{{/if}}
|
||||
{{/each}}
|
||||
{{#each document.system.actions as |action|}}
|
||||
{{#if (or (eq ../type 'actions'))}}
|
||||
{{> 'systems/daggerheart/templates/sheets/global/partials/action-item.hbs' item=action}}
|
||||
{{/if}}
|
||||
{{/each}}
|
||||
{{#each document.system.companionActions as |action|}}
|
||||
{{#if (or (eq ../type 'companionActions'))}}
|
||||
{{> 'systems/daggerheart/templates/sheets/global/partials/action-item.hbs' item=action partner=true}}
|
||||
{{/if}}
|
||||
{{/each}}
|
||||
{{/unless}}
|
||||
|
||||
</ul>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue