diff --git a/lang/en.json b/lang/en.json index e13d6165..78532b49 100755 --- a/lang/en.json +++ b/lang/en.json @@ -328,6 +328,26 @@ } } }, + "Environment": { + "Type": { + "Exploration": { + "label": "Exploration", + "description": "" + }, + "Social": { + "label": "Social", + "description": "" + }, + "Traversal": { + "label": "Traversal", + "description": "" + }, + "Event": { + "label": "Event", + "description": "" + } + } + }, "Domains": { "Arcana": { "Description": "This is the domain of the innate or instinctual use of magic. Those who walk this path tap into the raw, enigmatic forces of the realms to manipulate both the elements and their own energy. Arcana offers wielders a volatile power, but it is incredibly potent when correctly channeled." @@ -1055,9 +1075,33 @@ "Attack": "Attack" }, "Environment": { - "ToneAndFeel": "Tone And feel", - "PotentialAdversaries": "Potential Adversaries", - "NewFeature": "New Feature" + "FIELDS": { + "tier": { + "label": "Tier" + }, + "type": { + "label": "Type" + }, + "difficulty": { + "label": "Difficulty" + } + }, + "Tabs": { + "Main": "Data", + "Information": "Information" + }, + "general": "General", + "newAdversary": "New Adversary", + "newFeature": "New feature", + "description": "Description", + "impulses": "Impulses", + "potentialAdversaries": { + "label": "Potential Adversaries", + "placeholder": "Optionally drag and drop adversaries here" + }, + "features": { + "label": "Features" + } }, "Armor": { "baseScore": "Base Score", diff --git a/module/applications/sheets/environment.mjs b/module/applications/sheets/environment.mjs index 8799d41a..7c59fd55 100644 --- a/module/applications/sheets/environment.mjs +++ b/module/applications/sheets/environment.mjs @@ -1,78 +1,60 @@ import DaggerheartSheet from './daggerheart-sheet.mjs'; -const { DocumentSheetV2 } = foundry.applications.api; -export default class DhpEnvironment extends DaggerheartSheet(DocumentSheetV2) { - constructor(options) { - super(options); - - this.editMode = false; - } - +const { ActorSheetV2 } = foundry.applications.sheets; +export default class DhpEnvironment extends DaggerheartSheet(ActorSheetV2) { static DEFAULT_OPTIONS = { tag: 'form', - classes: ['daggerheart', 'sheet', 'adversary', 'environment'], + classes: ['daggerheart', 'sheet', 'actor', 'dh-style', 'environment'], position: { - width: 600, - height: 'auto' + width: 450, + height: 1000 }, actions: { - toggleSlider: this.toggleSlider, - viewFeature: this.viewFeature, + addAdversary: this.addAdversary, addFeature: this.addFeature, - removeFeature: this.removeFeature, - addTone: this.addTone, - removeTone: this.removeTone, - useFeature: this.useFeature + deleteProperty: this.deleteProperty, + viewAdversary: this.viewAdversary }, form: { handler: this._updateForm, - closeOnSubmit: false, - submitOnChange: true - } + submitOnChange: true, + closeOnSubmit: false + }, + dragDrop: [{ dragSelector: null, dropSelector: '.adversary-container' }] }; - /** @override */ static PARTS = { - form: { - id: 'form', - template: 'systems/daggerheart/templates/sheets/environment.hbs' - } + header: { template: 'systems/daggerheart/templates/sheets/actors/environment/header.hbs' }, + tabs: { template: 'systems/daggerheart/templates/sheets/global/tabs/tab-navigation.hbs' }, + main: { template: 'systems/daggerheart/templates/sheets/actors/environment/main.hbs' }, + information: { template: 'systems/daggerheart/templates/sheets/actors/environment/information.hbs' } }; - /* -------------------------------------------- */ - - /** @inheritDoc */ - get title() { - return `${game.i18n.localize('Environment')} - ${this.document.name}`; - } + static TABS = { + main: { + active: true, + cssClass: '', + group: 'primary', + id: 'main', + icon: null, + label: 'DAGGERHEART.Sheets.Environment.Tabs.Main' + }, + information: { + active: false, + cssClass: '', + group: 'primary', + id: 'information', + icon: null, + label: 'DAGGERHEART.Sheets.Environment.Tabs.Information' + } + }; async _prepareContext(_options) { - return { - title: `${this.document.name} - ${game.i18n.localize(SYSTEM.ACTOR.adversaryTypes[this.document.system.type].name)}`, - user: this.document, - source: this.document.toObject(), - fields: this.document.schema.fields, - data: { - type: game.i18n.localize(SYSTEM.ACTOR.adversaryTypes[this.document.system.type].name), - features: this.document.items.reduce((acc, x) => { - if (x.type === 'feature') { - const feature = x.toObject(); - acc.push({ - ...feature, - system: { - ...feature.system, - actionType: game.i18n.localize(SYSTEM.ITEM.actionTypes[feature.system.actionType].name) - }, - uuid: x.uuid - }); - } + const context = await super._prepareContext(_options); + context.document = this.document; + context.tabs = super._getTabs(this.constructor.TABS); - return acc; - }, []) - }, - editMode: this.editMode, - config: SYSTEM - }; + return context; } static async _updateForm(event, _, formData) { @@ -80,60 +62,41 @@ export default class DhpEnvironment extends DaggerheartSheet(DocumentSheetV2) { this.render(); } - static toggleSlider() { - this.editMode = !this.editMode; + static async addAdversary() { + await this.document.update({ + [`system.potentialAdversaries.${foundry.utils.randomID()}.label`]: game.i18n.localize( + 'DAGGERHEART.Sheets.Environment.newAdversary' + ) + }); this.render(); } - static async viewFeature(_, button) { - const move = await fromUuid(button.dataset.feature); - move.sheet.render(true); - } - static async addFeature() { - const result = await this.document.createEmbeddedDocuments('Item', [ - { - name: game.i18n.localize('DAGGERHEART.Sheets.Environment.NewFeature'), - type: 'feature' - } - ]); - - await result[0].sheet.render(true); + ui.notifications.error('Not Implemented yet. Awaiting datamodel rework'); } - static async removeFeature(_, button) { - await this.document.items.find(x => x.uuid === button.dataset.feature).delete(); + static async deleteProperty(_, target) { + await this.document.update({ [`${target.dataset.path}.-=${target.id}`]: null }); + this.render(); } - static async addTone() { - await this.document.update({ 'system.toneAndFeel': [...this.document.system.toneAndFeel, ''] }); + static async viewAdversary(_, button) { + const adversary = foundry.utils.getProperty( + this.document.system.potentialAdversaries, + `${button.dataset.potentialAdversary}.adversaries.${button.dataset.adversary}` + ); + adversary.sheet.render(true); } - static async removeTone(button) { - await this.document.update({ - 'system.toneAndFeel': this.document.system.toneAndFeel.filter( - (_, index) => index !== Number.parseInt(button.dataset.tone) - ) - }); - } - - static async useFeature(_, button) { - const item = this.document.items.find(x => x.uuid === button.dataset.feature); - - const cls = getDocumentClass('ChatMessage'); - const msg = new cls({ - user: game.user.id, - content: await foundry.applications.handlebars.renderTemplate( - 'systems/daggerheart/templates/chat/ability-use.hbs', - { - title: game.i18n.format('DAGGERHEART.Chat.EnvironmentTitle', { - actionType: button.dataset.actionType - }), - card: { name: item.name, img: item.img, description: item.system.description } - } - ) - }); - - cls.create(msg.toObject()); + async _onDrop(event) { + const data = TextEditor.getDragEventData(event); + const item = await fromUuid(data.uuid); + if (item.type === 'adversary') { + const target = event.target.closest('.adversary-container'); + const path = `system.potentialAdversaries.${target.dataset.potentialAdversary}.adversaries.${item.id}`; + await this.document.update({ + [path]: item.uuid + }); + } } } diff --git a/module/config/actorConfig.mjs b/module/config/actorConfig.mjs index b851cee1..dcd85cdb 100644 --- a/module/config/actorConfig.mjs +++ b/module/config/actorConfig.mjs @@ -133,6 +133,25 @@ export const adversaryTypes = { } }; +export const environmentTypes = { + exploration: { + label: 'DAGGERHEART.Environment.Type.Exploration.label', + description: 'DAGGERHEART.Environment.Type.Exploration.description' + }, + social: { + label: 'DAGGERHEART.Environment.Type.Social.label', + description: 'DAGGERHEART.Environment.Type.Social.description' + }, + traversal: { + label: 'DAGGERHEART.Environment.Type.Traversal.label', + description: 'DAGGERHEART.Environment.Type.Traversal.description' + }, + event: { + label: 'DAGGERHEART.Environment.Type.Event.label', + description: 'DAGGERHEART.Environment.Type.Event.description' + } +}; + export const adversaryTraits = { relentless: { name: 'DAGGERHEART.Adversary.Trait..Name', diff --git a/module/data/environment.mjs b/module/data/environment.mjs index 23e9cd25..a2cd7529 100644 --- a/module/data/environment.mjs +++ b/module/data/environment.mjs @@ -1,22 +1,28 @@ -export default class DhpEnvironment extends foundry.abstract.TypeDataModel { +import { environmentTypes } from '../config/actorConfig.mjs'; +import ForeignDocumentUUIDField from './fields/foreignDocumentUUIDField.mjs'; + +export default class DhEnvironment extends foundry.abstract.TypeDataModel { + static LOCALIZATION_PREFIXES = ['DAGGERHEART.Sheets.Environment']; + static defineSchema() { const fields = foundry.data.fields; return { - resources: new fields.SchemaField({}), - tier: new fields.StringField({ choices: Object.keys(SYSTEM.GENERAL.tiers), integer: false }), - type: new fields.StringField({ - choices: Object.keys(SYSTEM.ACTOR.adversaryTypes), - integer: false, - initial: Object.keys(SYSTEM.ACTOR.adversaryTypes).find(x => x === 'standard') + tier: new fields.StringField({ + required: true, + choices: SYSTEM.GENERAL.tiers, + initial: SYSTEM.GENERAL.tiers.tier1.id }), - description: new fields.StringField({}), - toneAndFeel: new fields.StringField({}), - difficulty: new fields.NumberField({ initial: 1, integer: true }), - potentialAdversaries: new fields.StringField({}) + type: new fields.StringField({ choices: environmentTypes }), + description: new fields.HTMLField(), + impulses: new fields.HTMLField(), + difficulty: new fields.NumberField({ required: true, initial: 11, integer: true }), + potentialAdversaries: new fields.TypedObjectField( + new fields.SchemaField({ + label: new fields.StringField(), + adversaries: new fields.TypedObjectField(new ForeignDocumentUUIDField({ type: 'Actor' })) + }) + ) + /* Features pending datamodel rework */ }; } - - get features() { - return this.parent.items.filter(x => x.type === 'feature'); - } } diff --git a/module/helpers/handlebarsHelper.mjs b/module/helpers/handlebarsHelper.mjs index 87d1fb7f..25dd0e5e 100644 --- a/module/helpers/handlebarsHelper.mjs +++ b/module/helpers/handlebarsHelper.mjs @@ -11,6 +11,7 @@ export default class RegisterHandlebarsHelpers { includes: this.includes, debug: this.debug, signedNumber: this.signedNumber, + length: this.length, switch: this.switch, case: this.case }); @@ -82,6 +83,10 @@ export default class RegisterHandlebarsHelpers { return number >= 0 ? `+${number}` : number; } + static length(obj) { + return Object.keys(obj).length; + } + static switch(value, options) { this.switch_value = value; this.switch_break = false; diff --git a/styles/daggerheart.css b/styles/daggerheart.css index 0c7a60e6..96b949fc 100755 --- a/styles/daggerheart.css +++ b/styles/daggerheart.css @@ -2858,6 +2858,28 @@ div.daggerheart.views.multiclass { .application.sheet.daggerheart.actor.dh-style.adversary .window-content { overflow: auto; } +.daggerheart.sheet.actor.environment .potential-adversary-container { + width: 100%; + height: 50px; +} +.daggerheart.sheet.actor.environment .potential-adversary-container .adversary-placeholder { + font-style: italic; + text-align: center; + opacity: 0.6; +} +.daggerheart.sheet.actor.environment .potential-adversary-container .adversaries-container { + display: flex; + gap: 8px; +} +.daggerheart.sheet.actor.environment .potential-adversary-container .adversaries-container .adversary-container { + border: 1px solid var(--color-dark-5); + border-radius: 6px; + padding: 0 2px; + font-weight: bold; + cursor: pointer; + background-image: url(../assets/parchments/dh-parchment-dark.png); + color: var(--color-light-3); +} .application.sheet.daggerheart.dh-style.feature .item-sheet-header { display: flex; } diff --git a/styles/daggerheart.less b/styles/daggerheart.less index d887d372..8ec94054 100755 --- a/styles/daggerheart.less +++ b/styles/daggerheart.less @@ -14,6 +14,7 @@ // new styles imports @import './less/actors/adversary.less'; +@import './less/actors/environment.less'; @import './less/items/feature.less'; @import './less/items/domainCard.less'; diff --git a/styles/less/actors/environment.less b/styles/less/actors/environment.less new file mode 100644 index 00000000..d534de38 --- /dev/null +++ b/styles/less/actors/environment.less @@ -0,0 +1,27 @@ +.daggerheart.sheet.actor.environment { + .potential-adversary-container { + width: 100%; + height: 50px; + + .adversary-placeholder { + font-style: italic; + text-align: center; + opacity: 0.6; + } + + .adversaries-container { + display: flex; + gap: 8px; + + .adversary-container { + border: 1px solid var(--color-dark-5); + border-radius: 6px; + padding: 0 2px; + font-weight: bold; + cursor: pointer; + background-image: url(../assets/parchments/dh-parchment-dark.png); + color: var(--color-light-3); + } + } + } +} diff --git a/system.json b/system.json index 20069250..c402b837 100644 --- a/system.json +++ b/system.json @@ -207,7 +207,9 @@ "adversary": { "htmlFields": ["description", "motivesAndTactics"] }, - "environment": {} + "environment": { + "htmlFields": ["description", "impulses"] + } }, "Item": { "ancestry": { diff --git a/templates/sheets/actors/environment/header.hbs b/templates/sheets/actors/environment/header.hbs new file mode 100644 index 00000000..a21f5f64 --- /dev/null +++ b/templates/sheets/actors/environment/header.hbs @@ -0,0 +1,9 @@ + + + + + + {{localize 'TYPES.Actor.environment'}} + + + \ No newline at end of file diff --git a/templates/sheets/actors/environment/information.hbs b/templates/sheets/actors/environment/information.hbs new file mode 100644 index 00000000..3b49a933 --- /dev/null +++ b/templates/sheets/actors/environment/information.hbs @@ -0,0 +1,16 @@ + + + {{localize "DAGGERHEART.Sheets.Environment.description"}} + + {{formInput systemFields.description value=source.system.description }} + + + {{localize "DAGGERHEART.Sheets.Environment.impulses"}} + + {{formInput systemFields.impulses value=source.system.impulses }} + + \ No newline at end of file diff --git a/templates/sheets/actors/environment/main.hbs b/templates/sheets/actors/environment/main.hbs new file mode 100644 index 00000000..a973cdc9 --- /dev/null +++ b/templates/sheets/actors/environment/main.hbs @@ -0,0 +1,37 @@ + + + {{localize "DAGGERHEART.Sheets.Environment.general"}} + + {{formGroup systemFields.tier value=source.system.tier localize=true }} + {{formGroup systemFields.type value=source.system.type localize=true }} + {{formGroup systemFields.difficulty value=source.system.difficulty localize=true }} + + + + {{localize "DAGGERHEART.Sheets.Environment.potentialAdversaries.label"}} + + {{#each source.system.potentialAdversaries}} + + + {{#if (eq (length this.adversaries) 0)}} + {{localize "DAGGERHEART.Sheets.Environment.potentialAdversaries.placeholder"}} + {{else}} + + {{#each this.adversaries as |adversary id|}} + {{adversary.name}} + {{/each}} + + {{/if}} + + {{/each}} + + + + {{localize "DAGGERHEART.Sheets.Environment.features.label"}} + + + \ No newline at end of file