From 355f55e2bd426143b4b1b0670096d0981d820f3b Mon Sep 17 00:00:00 2001 From: macniel Date: Fri, 17 Oct 2025 21:52:40 +0200 Subject: [PATCH] finally fixes the stubborn tab error --- src/main.mjs | 3 +- src/module/data/character.mjs | 2 + src/module/data/profession.mjs | 14 + src/module/documents/profession.mjs | 9 + src/module/sheets/character/social.mjs | 20 + src/module/sheets/characterSheet.mjs | 152 ++++- src/module/xml-import/xml-import.mjs | 35 +- src/style/atoms/_typography.scss | 5 + src/style/molecules/_attributes.scss | 4 - src/style/molecules/_pill.scss | 19 + src/style/molecules/_richtext-editor.scss | 10 +- src/style/organisms/_character-sheet.scss | 625 ++---------------- .../organisms/character-tabs/_attributes.scss | 121 ++++ .../organisms/character-tabs/_combat.scss | 190 ++++++ .../organisms/character-tabs/_inventory.scss | 42 ++ .../organisms/character-tabs/_liturgies.scss | 63 ++ src/style/organisms/character-tabs/_meta.scss | 64 ++ .../organisms/character-tabs/_social.scss | 38 ++ .../organisms/character-tabs/_spells.scss | 108 +++ src/style/styles.scss | 12 +- src/system.json | 8 + src/templates/actor/character/main-sheet.hbs | 20 +- .../actor/character/tab-equipment.hbs | 88 +-- src/templates/actor/character/tab-meta.hbs | 60 +- src/templates/actor/character/tab-social.hbs | 40 ++ 25 files changed, 1004 insertions(+), 748 deletions(-) create mode 100644 src/module/data/profession.mjs create mode 100644 src/module/documents/profession.mjs create mode 100644 src/module/sheets/character/social.mjs create mode 100644 src/style/molecules/_pill.scss create mode 100644 src/style/organisms/character-tabs/_attributes.scss create mode 100644 src/style/organisms/character-tabs/_combat.scss create mode 100644 src/style/organisms/character-tabs/_inventory.scss create mode 100644 src/style/organisms/character-tabs/_liturgies.scss create mode 100644 src/style/organisms/character-tabs/_meta.scss create mode 100644 src/style/organisms/character-tabs/_social.scss create mode 100644 src/style/organisms/character-tabs/_spells.scss create mode 100644 src/templates/actor/character/tab-social.hbs diff --git a/src/main.mjs b/src/main.mjs index ddfa2dd7..ec48819c 100644 --- a/src/main.mjs +++ b/src/main.mjs @@ -21,6 +21,7 @@ import {SpecialAbilitySheet} from "./module/sheets/specialAbilitySheet.mjs"; import {ActiveEffectSheet} from "./module/sheets/ActiveEffectSheet.mjs"; import {ActiveEffectDataModel} from "./module/data/activeeffect.mjs"; import {Trefferzone, Wunde, Zonenruestung, Zonenwunde} from "./module/data/Trefferzone.js"; +import {ProfessionDataModel} from "./module/data/profession.mjs"; async function preloadHandlebarsTemplates() { return foundry.applications.handlebars.loadTemplates([ @@ -70,6 +71,7 @@ Hooks.once("init", () => { Blessing: BlessingDataModel, SpecialAbility: SpecialAbilityDataModel, ActiveEffect: ActiveEffectDataModel, + Profession: ProfessionDataModel, } CONFIG.Combat.initiative = { @@ -126,7 +128,6 @@ Hooks.once("init", () => { makeDefault: true, label: 'DSA41.SpecialAbilityLabels.Item' }) - foundry.documents.collections.Items.registerSheet('dsa41.activeEffect', ActiveEffectSheet, { types: ['ActiveEffect'], makeDefault: true, diff --git a/src/module/data/character.mjs b/src/module/data/character.mjs index b6e5eb4b..433c8865 100644 --- a/src/module/data/character.mjs +++ b/src/module/data/character.mjs @@ -29,6 +29,8 @@ export class PlayerCharacterDataModel extends foundry.abstract.TypeDataModel { familie: new HTMLField(), titel: new StringField(), stand: new StringField(), + verbindungen: new HTMLField(), + notizen: new HTMLField(), }), setEquipped: new NumberField({required: true, initial: 0, max: 3, integer: true}), ini: new SchemaField({ diff --git a/src/module/data/profession.mjs b/src/module/data/profession.mjs new file mode 100644 index 00000000..9b7b1cfe --- /dev/null +++ b/src/module/data/profession.mjs @@ -0,0 +1,14 @@ +import BaseItem from "./base-item.mjs"; + +const {BooleanField, StringField, HTMLField} = foundry.data.fields; + +export class ProfessionDataModel extends BaseItem { + + static defineSchema() { + return { + description: new HTMLField(), + revealed: new BooleanField(), + alias: new StringField(), + } + } +} \ No newline at end of file diff --git a/src/module/documents/profession.mjs b/src/module/documents/profession.mjs new file mode 100644 index 00000000..2dfb3529 --- /dev/null +++ b/src/module/documents/profession.mjs @@ -0,0 +1,9 @@ +export class Profession extends Item { + /** + * Augment the basic Item data model with additional dynamic data. + */ + prepareData() { + super.prepareData(); + } + +} diff --git a/src/module/sheets/character/social.mjs b/src/module/sheets/character/social.mjs new file mode 100644 index 00000000..c97eb622 --- /dev/null +++ b/src/module/sheets/character/social.mjs @@ -0,0 +1,20 @@ +export default { + _prepareContext: (context, object) => { + const actorData = context.document + context.system = actorData.system + context.flags = actorData.flags + context.derived = context.document.system + context.originalName = actorData.name + context.name = context.derived.name ?? actorData.name + context.effects = actorData.effects ?? [] + + return context + }, + _onRender: (context, options) => { + + }, + _getTabConfig: (group) => { + group.tabs.push({id: "social", group: "sheet", label: "Soziales"}) + }, + template: `systems/DSA_4-1/templates/actor/character/tab-social.hbs` +} \ No newline at end of file diff --git a/src/module/sheets/characterSheet.mjs b/src/module/sheets/characterSheet.mjs index 12fe6951..d79341f9 100644 --- a/src/module/sheets/characterSheet.mjs +++ b/src/module/sheets/characterSheet.mjs @@ -1,11 +1,12 @@ -import Meta from "./character/meta.mjs" import Attributes from "./character/attributes.mjs" import Combat from "./character/combat.mjs" -import Equipment from "./character/equipment.mjs" -import Skills from "./character/skills.mjs" -import Spells from "./character/spells.mjs" -import Liturgies from "./character/liturgies.mjs" import Effects from "./character/effects.mjs" +import Equipment from "./character/equipment.mjs" +import Liturgies from "./character/liturgies.mjs" +import Meta from "./character/meta.mjs" +import Skills from "./character/skills.mjs" +import Social from "./character/social.mjs"; +import Spells from "./character/spells.mjs" const {HandlebarsApplicationMixin} = foundry.applications.api const {ActorSheetV2} = foundry.applications.sheets @@ -36,15 +37,7 @@ class CharacterSheet extends HandlebarsApplicationMixin(ActorSheetV2) { static TABS = { sheet: { - tabs: [ - {id: 'meta', group: 'sheet', label: 'Meta'}, - // {id: 'attributes', group: 'sheet', label: 'Eigenschaften'}, - // {id: 'combat', group: 'sheet', label: 'Kampf'}, - // {id: 'equipment', group: 'sheet', label: 'Inventar'}, - // {id: 'skills', group: 'sheet', label: 'Talente'}, - // {id: 'spells', group: 'sheet', label: 'Zauber'}, - // {id: 'liturgies', group: 'sheet', label: 'Liturgien'}, - ], + tabs: [], initial: 'meta' } } @@ -57,6 +50,9 @@ class CharacterSheet extends HandlebarsApplicationMixin(ActorSheetV2) { meta: { template: Meta.template }, + social: { + template: Social.template + }, attributes: { template: Attributes.template }, @@ -69,6 +65,9 @@ class CharacterSheet extends HandlebarsApplicationMixin(ActorSheetV2) { skills: { template: Skills.template }, + spells: { + template: Spells.template + }, liturgies: { template: Liturgies.template }, @@ -112,6 +111,8 @@ class CharacterSheet extends HandlebarsApplicationMixin(ActorSheetV2) { _getTabsConfig(group) { const tabs = foundry.utils.deepClone(super._getTabsConfig(group)) + Meta._getTabConfig(tabs, this); + Social._getTabConfig(tabs, this); Attributes._getTabConfig(tabs, this) Combat._getTabConfig(tabs, this) Equipment._getTabConfig(tabs, this) @@ -125,12 +126,36 @@ class CharacterSheet extends HandlebarsApplicationMixin(ActorSheetV2) { async _preparePartContext(partId, context) { switch (partId) { case "form": + + const findEquipmentOnSlot = (slot, setNumber, object) => { + return object.items.get(object.system.heldenausruestung[setNumber]?.[slot]) + } + const actorData = context.document context.system = actorData.system + context.isOwner = actorData.isOwner context.flags = actorData.flags context.derived = context.document.system + context.professions = actorData.items.filter(p => p.type === 'Profession').map(p => { + // is tarnidentitaet revealed? + if (p.system.revealed) { + return { + id: p.id, + name: p.name, + alias: p.system.alias, + } + } else { + return { + id: p.id, + name: p.system.alias ?? p.name, + alias: p.name, + } + } + }) + context.originalName = actorData.name context.name = context.derived.name ?? actorData.name + context.img = actorData.img context.effects = actorData.effects ?? [] context.maxWounds = actorData.system.wunden.max ?? 3 @@ -145,6 +170,89 @@ class CharacterSheet extends HandlebarsApplicationMixin(ActorSheetV2) { context.ausdauer = game.settings.get("DSA_4-1", "optional_ausdauer") context.colorfulDice = game.settings.get('DSA_4-1', 'optional_colorfuldice') + + context.inidice = actorData.system.ini.wuerfel + context.inivalue = actorData.system.ini.aktuell + context.inimod = actorData.system.ini.mod + + context.aupper = Math.min((actorData.system.aup.aktuell / actorData.system.aup.max) * 100, 100) + context.lepper = Math.min((actorData.system.lep.aktuell / actorData.system.lep.max) * 100, 100) + context.keper = Math.min((actorData.system.kap.aktuell / actorData.system.kap.max) * 100, 100) + context.aspper = Math.min((actorData.system.asp.aktuell / actorData.system.asp.max) * 100, 100) + context.lepcurrent = actorData.system.lep.aktuell ?? 0 + + context.aupcurrent = actorData.system.aup.aktuell ?? 0 + + const fernkampf = findEquipmentOnSlot("fernkampf", actorData.system.setEquipped, actorData) + const links = findEquipmentOnSlot("links", actorData.system.setEquipped, actorData) + const rechts = findEquipmentOnSlot("rechts", actorData.system.setEquipped, actorData) + context.attacks = []; + + if (fernkampf) { + const fkitems = fernkampf.system.rangedSkills.map((skillInQuestion) => actorData.items.find(p => p.name === skillInQuestion)) + fkitems.forEach(async skill => { + const obj = await skill + context.attacks.push({ + name: obj.name, + using: fernkampf.name, + atroll: `1d20cs<${object.system.fk.aktuell + obj.system.at}`, + at: `${object.system.fk.aktuell + obj.system.at}`, + tproll: `${fernkampf.system.rangedAttackDamage}`, // TODO consider adding TP/KK mod and Range mod + tp: `${fernkampf.system.rangedAttackDamage}`, + iniroll: `(${context.inidice})d6 + ${context.inivalue + fernkampf.system.iniModifier ?? 0}`, + ini: `${context.inidice}w6 + ${context.inivalue + fernkampf.system.iniModifier ?? 0}`, + }) + }) + } + if (links) { + const meitems = [] + links.system.meleeSkills.forEach((skillInQuestion) => { + const item = actorData.items.find(p => p.name === skillInQuestion) + if (item) { + meitems.push(item) + } + }) + meitems.forEach(skill => { + const obj = skill + context.attacks.push({ + name: obj.name, + using: links.name, + atroll: `1d20cs<${object.system.at.links.aktuell + obj.system.at + links.system.attackModifier}`, // TODO consider adding W/M + at: `${object.system.at.links.aktuell + obj.system.at + links.system.attackModifier}`, + paroll: `1d20cs<${object.system.pa.links.aktuell + obj.system.pa + links.system.parryModifier}`, // TODO consider adding W/M + pa: `${object.system.pa.links.aktuell + obj.system.pa + links.system.parryModifier}`, + tproll: `${links.system.meleeAttackDamage}`, // TODO consider adding TP/KK mod + tp: `${links.system.meleeAttackDamage}`, + iniroll: `(${context.inidice})d6 + ${context.inivalue + links.system.iniModifier ?? 0}`, + ini: `${context.inidice}w6 + ${context.inivalue + links.system.iniModifier ?? 0}`, + }) + }) + } + if (rechts) { + const meitems = [] + rechts.system.meleeSkills.forEach((skillInQuestion) => { + const item = actorData.items.find(p => p.name === skillInQuestion) + if (item) { + meitems.push(item) + } + }) + meitems.forEach(skill => { + const obj = skill + context.attacks.push({ + name: obj.name, + using: rechts.name, + atroll: `1d20cs<${object.system.at.rechts.aktuell + obj.system.at + rechts.system.attackModifier}`, // TODO consider adding W/M + at: `${object.system.at.rechts.aktuell + obj.system.at + rechts.system.attackModifier}`, + paroll: `1d20cs<${object.system.pa.rechts.aktuell + obj.system.pa + rechts.system.parryModifier}`, // TODO consider adding W/M + pa: `${object.system.pa.rechts.aktuell + obj.system.pa + rechts.system.parryModifier}`, + tproll: `${rechts.system.meleeAttackDamage}`, // TODO consider adding TP/KK mod + tp: `${rechts.system.meleeAttackDamage}`, + iniroll: `(${context.inidice})d6 + ${context.inivalue + rechts.system.iniModifier ?? 0}`, + ini: `${context.inidice}w6 + ${context.inivalue + rechts.system.iniModifier ?? 0}`, + }) + }) + } + context.attributes = [ { eigenschaft: "mu", @@ -198,7 +306,10 @@ class CharacterSheet extends HandlebarsApplicationMixin(ActorSheetV2) { break; case "meta": - Meta._prepareContext(context, this.object) + await Meta._prepareContext(context, this.object) + break + case "social": + await Social._prepareContext(context, this.object) break case "attributes": await Attributes._prepareContext(context, this.object) @@ -207,19 +318,19 @@ class CharacterSheet extends HandlebarsApplicationMixin(ActorSheetV2) { await Combat._prepareContext(context, this.object) break case "equipment": - Equipment._prepareContext(context, this.object) + await Equipment._prepareContext(context, this.object) break case "skills": - Skills._prepareContext(context, this.object) + await Skills._prepareContext(context, this.object) break case "spells": - Spells._prepareContext(context, this.object) + await Spells._prepareContext(context, this.object) break case "liturgies": - Liturgies._prepareContext(context, this.object) + await Liturgies._prepareContext(context, this.object) break case "effects": - Effects._prepareContext(context, this.object) + await Effects._prepareContext(context, this.object) break } return context @@ -227,6 +338,7 @@ class CharacterSheet extends HandlebarsApplicationMixin(ActorSheetV2) { _onRender(context, options) { Meta._onRender(context, options, this.element) + Social._onRender(context, options, this.element) Attributes._onRender(context, options, this.element) Combat._onRender(context, options, this.element) Effects._onRender(context, options, this.element) diff --git a/src/module/xml-import/xml-import.mjs b/src/module/xml-import/xml-import.mjs index 1e7eadce..f24f3189 100644 --- a/src/module/xml-import/xml-import.mjs +++ b/src/module/xml-import/xml-import.mjs @@ -1,6 +1,7 @@ import {LiturgyData} from "../data/miracle/liturgydata.mjs"; import {BlessingDataModel} from "../data/blessing.mjs"; import {Blessing} from "../documents/blessing.mjs"; +import {Profession} from "../documents/profession.mjs"; let months = [ "Praios", @@ -232,6 +233,28 @@ function mapMiracles(actor, liturgies) { } } +function mapProfessions(actor, professions) { + if (professions.string) { + professions = {hauptprofession: professions} + } + Object.values(professions).forEach(profession => { + actor.createEmbeddedDocuments('Item', [ + new Profession({ + name: profession.string, + type: "Profession", + system: { + description: "", + alias: profession.tarnidentitaet ? profession.tarnidentitaet : profession.string, + revealed: !profession.tarnidentitaet + } + }) + ]) + }) + // actor.update({"system.meta.professions": professions}) + + +} + /** * parses a json into a fitting character-json * @param rawJson the json parsed from the Helden-Software XML @@ -244,17 +267,7 @@ function mapRawJson(actor, rawJson) { json.meta = {} json.meta.spezies = held.basis.rasse.string json.meta.kultur = held.basis.kultur.string - let professions = [] - for (let profession in held.basis.ausbildungen.ausbildung) { - profession = held.basis.ausbildungen.ausbildung[profession] - if (profession.tarnidentitaet) { - professions = [profession.tarnidentitaet] - break; - } - let professionString = profession.string - professions.push(professionString) - } - json.meta.professions = professions + mapProfessions(actor, held.basis.ausbildungen.ausbildung) json.meta.geschlecht = held.basis.geschlecht.name json.meta.haarfarbe = held.basis.rasse.aussehen.haarfarbe json.meta.groesse = held.basis.rasse.groesse.value diff --git a/src/style/atoms/_typography.scss b/src/style/atoms/_typography.scss index 550bf4cf..109ead76 100644 --- a/src/style/atoms/_typography.scss +++ b/src/style/atoms/_typography.scss @@ -8,6 +8,11 @@ font-weight: bold; } + input, + .rkp .pill { + font-family: Andalus, sans-serif; + } + .editor.prosemirror.active, .editor.prosemirror.inactive { font-family: Gentium, sans-serif; } diff --git a/src/style/molecules/_attributes.scss b/src/style/molecules/_attributes.scss index 5bcbd8ed..3c8ef194 100644 --- a/src/style/molecules/_attributes.scss +++ b/src/style/molecules/_attributes.scss @@ -9,10 +9,6 @@ position: relative; .attributes { - position: absolute; - top: 8px; - right: 4px; - height: 48px; display: flex; .attribute.rollable { diff --git a/src/style/molecules/_pill.scss b/src/style/molecules/_pill.scss new file mode 100644 index 00000000..3c8ba82c --- /dev/null +++ b/src/style/molecules/_pill.scss @@ -0,0 +1,19 @@ +.application.sheet.dsa41 { + + .pill { + + height: 24px; + line-height: 24px; + font-size: 14px; + vertical-align: middle; + padding: 1px 4px; + margin-right: 4px; + border-radius: 8px; + border: 1px solid orange; + color: orange; + background-color: rgba(0, 0, 0, 0.6); + box-shadow: 1px 1px 1px rgba(0, 0, 0, 0.5), inset -1px -1px 0 rgba(0, 0, 0, 0.1); + display: inline-block; + } + +} \ No newline at end of file diff --git a/src/style/molecules/_richtext-editor.scss b/src/style/molecules/_richtext-editor.scss index 1f1e331d..ffe51fae 100644 --- a/src/style/molecules/_richtext-editor.scss +++ b/src/style/molecules/_richtext-editor.scss @@ -1,7 +1,13 @@ -.dsa41.sheet { +.application.sheet.dsa41 { - .editor.prosemirror.active, .editor.prosemirror.inactive { + .editor.prosemirror { flex: 1; + background-color: rgba(0, 0, 0, 0.1); + box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.1); + border: 1px solid #666; + outline: 1px solid transparent; + border-radius: 4px; + } } \ No newline at end of file diff --git a/src/style/organisms/_character-sheet.scss b/src/style/organisms/_character-sheet.scss index e0180656..1240a2a9 100644 --- a/src/style/organisms/_character-sheet.scss +++ b/src/style/organisms/_character-sheet.scss @@ -1,6 +1,14 @@ @use "sass:color"; @use "../atoms/numbers"; @use "../atoms/colours" as colour; +@use "./character-tabs/meta"; +@use "./character-tabs/social"; +@use "./character-tabs/attributes"; +@use "./character-tabs/inventory"; +@use "./character-tabs/combat"; +@use "./character-tabs/spells"; +@use "./character-tabs/liturgies"; + .application.sheet.dsa41.actor.character { @@ -20,15 +28,24 @@ left: 0; height: $attribute-height; right: 0; + display: grid; + grid-template-columns: 1fr max-content; + gap: 0 8px; + + .name { + border: unset; + font-size: large; + } + } div.head-data { position: absolute; - left: 0; - top: $attribute-height; - width: $sidebar-width; - bottom: 0; - padding: 8px; + left: 16px; + top: $attribute-height+30px; + width: $sidebar-width - 16px; + bottom: 16px; + padding: 0; .profile-img { @@ -38,609 +55,49 @@ nav.sheet-tabs.tabs { position: absolute; - left: $sidebar-width; - top: $attribute-height+$tabs-spacing; - right: 0; + left: $sidebar-width+16px; + top: $attribute-height+$tabs-spacing+13px; + right: 16px; height: $tabs-height; } section.tab { position: absolute; - top: $attribute-height+$tabs-height+$tabs-spacing+4px; - left: $sidebar-width; - right: 4px; - bottom: 4px; - padding: 8px; + top: $attribute-height+$tabs-height+$tabs-spacing+21px; + left: $sidebar-width+16px; + right: 16px; + bottom: 16px; + padding: 0; overflow: auto; } - .tab.overview.active { - - display: flex; - flex-direction: column; - height: 100%; - - .meta-data { - flex: 0; - - columns: 2; - gap: 0 16px; - - - div { - break-inside: avoid; - padding: 4px 0; - } - - .double { - display: grid; - grid-template-columns: 1fr 1fr; - grid-template-areas: 'label label' 'left right'; - gap: 0 8px; - - label { - grid-area: label; - } - } - - .editor { - background-color: rgba(0, 0, 0, 0.2) - } - - & + .meta-data { - flex: 1; - } - } - - .meta-data.html { - - & > div { - display: flex; - flex-direction: column; - height: 100%; - - label { - flex: 0; - } - - .editor { - flex: 1; - } - } - - } + .tab.meta.active { + @include meta.tab; + } + .tab.social.active { + @include social.tab; } .tab.attributes.active { - height: 100%; - - .attribute { - padding: 8px 0; - display: flex; - gap: 0 8px; - - label { - width: 120px; - text-align: right; - vertical-align: middle; - line-height: 24px; - } - - input { - max-width: 80px; - text-align: right; - } - - .mod { - color: grey; - text-shadow: 0 -1px 0 #ccc; - box-Shadow: 1px 1px 1px rgba(0, 0, 0, 0.5); - border-radius: 4px; - height: 24px; - width: 24px; - background: linear-gradient(0deg, rgba(24, 24, 24, 1) 0%, rgba(80, 80, 80, 1) 100%);; - display: inline-block; - text-align: center; - vertical-align: middle; - line-height: 24px; - margin-left: 4px; - } - - } - - .attributes-overview { - - columns: 2; - gap: 0 16px; - - } - - .resource-overview { - - .attribute { - - } - - } - - .advantages, .special-abilities { - margin-bottom: 16px; - - ul { - list-style-type: none; - padding: 0; - margin: 0; - text-indent: 0; - - li { - display: inline-block; - } - - .advantage, .special-ability { - position: relative; - border: 1px solid gold; - box-shadow: 2px 2px 4px #000; - border-radius: 8px; - height: 24px; - color: gold; - text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.2); - display: inline-block; - padding: 0 8px; - margin-left: 0; - margin-bottom: 4px; - background-image: url("../../assets/velvet_button.png"); - background-repeat: repeat-y; - background-size: cover; - - span { - position: relative; - z-index: 2; - line-height: 24px; - vertical-align: middle; - } - - &.special-ability { - &::after { - background: rgba(128, 0, 96, 0.5); - } - } - - &::after { - content: ""; - position: absolute; - left: 0; - top: 0; - right: 0; - bottom: 0; - border-radius: 8px; - background: rgba(0, 128, 0, 0.5); - } - - & + .advantage, & + .special-ability { - margin-left: 8px; - } - - &.disadvantage { - font-style: italic; - - &::after { - background: rgba(128, 0, 0, 0.5); - } - } - } - } - - } - - + @include attributes.tab; } - .backpack.active { - display: grid; - grid-template-columns: 1fr 320px; - grid-template-rows: 74px 1fr; - gap: 10px; - height: 100%; - grid-template-areas: - "capacity capacity" - "inventory equipment"; - - .capacity { - - grid-area: capacity; - - .resource { - - position: relative; - border: 1px inset #ccc; - background-color: rgba(0, 0, 0, 0.2); - height: 8px; - - span.fill { - position: absolute; - left: 0; - top: 0; - bottom: 0; - background: linear-gradient(to bottom, #0bad29 0%, #11f128 50%, #0cde24 51%, #6ff77b 100%); - } - - } - } - - .inventory { - grid-area: inventory; - - .equipment:hover { - .item-name { - text-shadow: 0 0 10px rgb(255 0 0); - } - } - } + .inventory.active { + @include inventory.tab; } .tab.combat.active { - - display: grid; - - grid-template-columns: 1fr 320px; - grid-template-rows: 32px 32px 1fr; - grid-template-areas: "res res" "wounds wounds" "actions actions"; - gap: 10px; - - .tab-resources { - grid-area: res; - } - - .wounds { - position: relative; - height: 24px; - display: flex; - margin-bottom: 8px; - padding-left: 130px; - grid-area: wounds; - - label { - position: absolute; - left: 0; - top: 0; - line-height: 24px; - width: 120px; - bottom: 0; - vertical-align: middle; - text-align: right; - height: 24px; - display: inline-block; - z-index: 2; - } - - .filled-segment { - border: 1px solid black; - background-image: url('/systems/DSA_4-1/assets/gradient.png'); - background-size: 24px 100%; - position: relative; - flex: 1; - text-align: center; - vertical-align: middle; - line-height: 24px; - color: white; - text-shadow: 2px 2px 0 rgba(0, 0, 0, 0.3); - background-color: rgba(255, 0, 0, 0.8); - background-blend-mode: multiply; - - } - - .empty-segment { - border: 1px solid black; - background-image: url('/systems/DSA_4-1/assets/gradient.png'); - background-size: 32px 100%; - position: relative; - flex: 1; - text-align: center; - vertical-align: middle; - line-height: 24px; - color: gold; - text-shadow: 2px 2px 0 rgba(0, 0, 0, 0.3); - background-color: rgba(0, 0, 0, 0.8); - background-blend-mode: multiply; - - } - - } - - .actions { - grid-area: actions; - } - - &.zones { - grid-template-areas: "res res" "wounds wounds" "actions paperdoll"; - - .paperdoll { - grid-area: paperdoll; - - div { - position: relative; - margin-left: 9px; - margin-top: 42px; - - .wound { - position: absolute; - width: 32px; - height: 32px; - border-radius: 16px; - border: 1px solid black; - background-color: rgba(0, 0, 0, 0.5); - box-shadow: 1px 1px 1px rgba(0, 0, 0, 0.3); - line-height: 32px; - vertical-align: middle; - text-align: center; - color: red; - - - &.armlinks { - top: 146px; - left: 210px; - } - - &.armrechts { - top: 146px; - left: 60px; - } - - &.beinlinks { - top: 346px; - left: 210px; - } - - &.beinrechts { - top: 346px; - left: 60px; - } - - &.bauch { - top: 166px; - left: 136px; - } - - &.kopf { - top: 6px; - left: 136px - } - - &.brust { - top: 86px; - left: 110px; - } - - } - - .armor { - position: absolute; - width: 32px; - height: 32px; - border-radius: 0 0 16px 16px; - line-height: 32px; - vertical-align: middle; - text-align: center; - border: 1px solid silver; - background-color: rgba(0, 0, 0, 0.5); - box-shadow: 1px 1px 1px rgba(0, 0, 0, 0.3); - color: silver; - - &.armlinks { - top: 180px; - left: 210px; - } - - &.armrechts { - top: 180px; - left: 60px; - } - - &.beinlinks { - top: 380px; - left: 210px; - } - - &.beinrechts { - top: 380px; - left: 60px; - } - - &.bauch { - top: 200px; - left: 136px; - } - - &.kopf { - top: 40px; - left: 136px - } - - &.brust { - top: 120px; - left: 110px; - } - } - } - - } - - } - - + @include combat.tab; } .tab.spells { - - tr { - height: 24px; - margin: 0; - padding: 0; - } - - td { - margin: 0; - padding: 0; - height: 24px; - } - - $color: #05f; - - .spell.rollable svg { - width: 24px; - height: 24px; - top: 1px; - z-index: 1; - position: relative; - - .border { - fill: #0000; - } - - .center { - fill: $color; - stroke: colour.$rollable-die-border-color; - } - - .topleft { - fill: color.adjust($color, $lightness: numbers.$lighter_factor); - stroke: colour.$rollable-die-border-color; - } - - .bottomleft { - fill: color.adjust($color, $lightness: numbers.$lightest_factor); - stroke: colour.$rollable-die-border-color; - } - - .topright { - fill: color.adjust($color, $lightness: numbers.$darken_factor); - stroke: colour.$rollable-die-border-color; - } - - .bottomright, .bottom { - fill: color.adjust($color, $lightness: numbers.$darkest_factor); - stroke: colour.$rollable-die-border-color; - } - } - - .die-column { - width: 24px; - } - - .clickable { - span { - position: relative; - z-index: 1; - } - } - - tbody { - - tr { - - position: relative; - - &::after { - content: ''; - background-image: linear-gradient(to right, rgba(color.scale($color, $lightness: numbers.$zebra_light), numbers.$start_gradient), rgba(color.scale($color, $lightness: numbers.$zebra_light), numbers.$end_2_gradient)); - border-top-right-radius: 8px; - border-bottom-right-radius: 8px; - position: absolute; - top: 2px; - left: 12px; - bottom: 2px; - right: 33%; - z-index: 0; - pointer-events: none; - } - - &:nth-child(odd) { - &::after { - background-image: linear-gradient(to right, rgba(color.scale($color, $lightness: numbers.$zebra_dark), numbers.$start_gradient), rgba(color.scale($color, $lightness: numbers.$zebra_dark), numbers.$end_2_gradient)); - } - } - } - - } - - .merkmal-list { - list-style: none; - margin: 0; - padding: 0; - text-indent: 0; - - li { - display: inline-block; - padding: 0 4px; - } - } - + @include spells.tab; } .tab.liturgies { - - table { - border-top: unset; - border-bottom: unset; - position: relative; - } - - .liturgy-header { - background: unset; - border: unset; - - tr { - height: 90px; - - th { - vertical-align: middle; - color: black; - text-shadow: 2px 2px 1px rgba(0, 0, 0, 0.2); - } - } - } - - td, th { - padding-left: 8px; - } - } - - .tab-resources { - display: flex; - justify-content: center; - gap: 0 16px; - padding-bottom: 8px; - - & > div { - - - height: 32px; - position: relative; - - label { - width: 80px; - line-height: 32px; - vertical-align: middle; - } - - input { - display: inline-block; - width: 40px; - height: 32px; - } - - span.inline { - line-height: 32px; - vertical-align: middle; - width: 40px; - text-align: center; - } - - - } - + @include liturgies.tab; } } diff --git a/src/style/organisms/character-tabs/_attributes.scss b/src/style/organisms/character-tabs/_attributes.scss new file mode 100644 index 00000000..e9a959bb --- /dev/null +++ b/src/style/organisms/character-tabs/_attributes.scss @@ -0,0 +1,121 @@ +@mixin tab { + height: 100%; + + .attribute { + padding: 8px 0; + display: flex; + gap: 0 8px; + + label { + width: 120px; + text-align: right; + vertical-align: middle; + line-height: 24px; + } + + input { + max-width: 80px; + text-align: right; + } + + .mod { + color: grey; + text-shadow: 0 -1px 0 #ccc; + box-Shadow: 1px 1px 1px rgba(0, 0, 0, 0.5); + border-radius: 4px; + height: 24px; + width: 24px; + background: linear-gradient(0deg, rgba(24, 24, 24, 1) 0%, rgba(80, 80, 80, 1) 100%);; + display: inline-block; + text-align: center; + vertical-align: middle; + line-height: 24px; + margin-left: 4px; + } + + } + + .attributes-overview { + + columns: 2; + gap: 0 16px; + + } + + .resource-overview { + + .attribute { + + } + + } + + .advantages, .special-abilities { + margin-bottom: 16px; + + ul { + list-style-type: none; + padding: 0; + margin: 0; + text-indent: 0; + + li { + display: inline-block; + } + + .advantage, .special-ability { + position: relative; + border: 1px solid gold; + box-shadow: 2px 2px 4px #000; + border-radius: 8px; + height: 24px; + color: gold; + text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.2); + display: inline-block; + padding: 0 8px; + margin-left: 0; + margin-bottom: 4px; + background-image: url("../../assets/velvet_button.png"); + background-repeat: repeat-y; + background-size: cover; + + span { + position: relative; + z-index: 2; + line-height: 24px; + vertical-align: middle; + } + + &.special-ability { + &::after { + background: rgba(128, 0, 96, 0.5); + } + } + + &::after { + content: ""; + position: absolute; + left: 0; + top: 0; + right: 0; + bottom: 0; + border-radius: 8px; + background: rgba(0, 128, 0, 0.5); + } + + & + .advantage, & + .special-ability { + margin-left: 8px; + } + + &.disadvantage { + font-style: italic; + + &::after { + background: rgba(128, 0, 0, 0.5); + } + } + } + } + + } +} diff --git a/src/style/organisms/character-tabs/_combat.scss b/src/style/organisms/character-tabs/_combat.scss new file mode 100644 index 00000000..adad410d --- /dev/null +++ b/src/style/organisms/character-tabs/_combat.scss @@ -0,0 +1,190 @@ +@mixin tab { + + display: grid; + + grid-template-columns: 1fr 320px; + grid-template-rows: 32px 32px 1fr; + grid-template-areas: "res res" "wounds wounds" "actions actions"; + gap: 10px; + + .tab-resources { + grid-area: res; + } + + .wounds { + position: relative; + height: 24px; + display: flex; + margin-bottom: 8px; + padding-left: 130px; + grid-area: wounds; + + label { + position: absolute; + left: 0; + top: 0; + line-height: 24px; + width: 120px; + bottom: 0; + vertical-align: middle; + text-align: right; + height: 24px; + display: inline-block; + z-index: 2; + } + + .filled-segment { + border: 1px solid black; + background-image: url('/systems/DSA_4-1/assets/gradient.png'); + background-size: 24px 100%; + position: relative; + flex: 1; + text-align: center; + vertical-align: middle; + line-height: 24px; + color: white; + text-shadow: 2px 2px 0 rgba(0, 0, 0, 0.3); + background-color: rgba(255, 0, 0, 0.8); + background-blend-mode: multiply; + + } + + .empty-segment { + border: 1px solid black; + background-image: url('/systems/DSA_4-1/assets/gradient.png'); + background-size: 32px 100%; + position: relative; + flex: 1; + text-align: center; + vertical-align: middle; + line-height: 24px; + color: gold; + text-shadow: 2px 2px 0 rgba(0, 0, 0, 0.3); + background-color: rgba(0, 0, 0, 0.8); + background-blend-mode: multiply; + + } + + } + + .actions { + grid-area: actions; + } + + &.zones { + grid-template-areas: "res res" "wounds wounds" "actions paperdoll"; + + .paperdoll { + grid-area: paperdoll; + + div { + position: relative; + margin-left: 9px; + margin-top: 42px; + + .wound { + position: absolute; + width: 32px; + height: 32px; + border-radius: 16px; + border: 1px solid black; + background-color: rgba(0, 0, 0, 0.5); + box-shadow: 1px 1px 1px rgba(0, 0, 0, 0.3); + line-height: 32px; + vertical-align: middle; + text-align: center; + color: red; + + + &.armlinks { + top: 146px; + left: 210px; + } + + &.armrechts { + top: 146px; + left: 60px; + } + + &.beinlinks { + top: 346px; + left: 210px; + } + + &.beinrechts { + top: 346px; + left: 60px; + } + + &.bauch { + top: 166px; + left: 136px; + } + + &.kopf { + top: 6px; + left: 136px + } + + &.brust { + top: 86px; + left: 110px; + } + + } + + .armor { + position: absolute; + width: 32px; + height: 32px; + border-radius: 0 0 16px 16px; + line-height: 32px; + vertical-align: middle; + text-align: center; + border: 1px solid silver; + background-color: rgba(0, 0, 0, 0.5); + box-shadow: 1px 1px 1px rgba(0, 0, 0, 0.3); + color: silver; + + &.armlinks { + top: 180px; + left: 210px; + } + + &.armrechts { + top: 180px; + left: 60px; + } + + &.beinlinks { + top: 380px; + left: 210px; + } + + &.beinrechts { + top: 380px; + left: 60px; + } + + &.bauch { + top: 200px; + left: 136px; + } + + &.kopf { + top: 40px; + left: 136px + } + + &.brust { + top: 120px; + left: 110px; + } + } + } + + } + + } + +} \ No newline at end of file diff --git a/src/style/organisms/character-tabs/_inventory.scss b/src/style/organisms/character-tabs/_inventory.scss new file mode 100644 index 00000000..94846cef --- /dev/null +++ b/src/style/organisms/character-tabs/_inventory.scss @@ -0,0 +1,42 @@ +@mixin tab { + display: grid; + grid-template-columns: 1fr 320px; + grid-template-rows: 74px 1fr; + gap: 10px; + height: 100%; + grid-template-areas: +"capacity capacity" +"inventory equipment"; + + .capacity { + + grid-area: capacity; + + .resource { + + position: relative; + border: 1px inset #ccc; + background-color: rgba(0, 0, 0, 0.2); + height: 8px; + + span.fill { + position: absolute; + left: 0; + top: 0; + bottom: 0; + background: linear-gradient(to bottom, #0bad29 0%, #11f128 50%, #0cde24 51%, #6ff77b 100%); + } + + } + } + + .inventory { + grid-area: inventory; + + .equipment:hover { + .item-name { + text-shadow: 0 0 10px rgb(255 0 0); + } + } + } +} \ No newline at end of file diff --git a/src/style/organisms/character-tabs/_liturgies.scss b/src/style/organisms/character-tabs/_liturgies.scss new file mode 100644 index 00000000..d780da26 --- /dev/null +++ b/src/style/organisms/character-tabs/_liturgies.scss @@ -0,0 +1,63 @@ +@mixin tab { + + table { + border-top: unset; + border-bottom: unset; + position: relative; + } + + .liturgy-header { + background: unset; + border: unset; + + tr { + height: 90px; + + th { + vertical-align: middle; + color: black; + text-shadow: 2px 2px 1px rgba(0, 0, 0, 0.2); + } + } + } + + td, th { + padding-left: 8px; + } +} + +.tab-resources { + display: flex; + justify-content: center; + gap: 0 16px; + padding-bottom: 8px; + + & > div { + + + height: 32px; + position: relative; + + label { + width: 80px; + line-height: 32px; + vertical-align: middle; + } + + input { + display: inline-block; + width: 40px; + height: 32px; + } + + span.inline { + line-height: 32px; + vertical-align: middle; + width: 40px; + text-align: center; + } + + + } + +} \ No newline at end of file diff --git a/src/style/organisms/character-tabs/_meta.scss b/src/style/organisms/character-tabs/_meta.scss new file mode 100644 index 00000000..62876997 --- /dev/null +++ b/src/style/organisms/character-tabs/_meta.scss @@ -0,0 +1,64 @@ +@mixin tab { + + display: flex; + flex-direction: column; + + .meta-data { + flex: 0; + height: unset; + columns: 2; + gap: 0 16px; + + + div { + break-inside: avoid; + } + + .meta-line { + display: grid; + grid-template-columns: 1fr 1fr 1fr; + gap: 0 8px; + padding-bottom: 8px; + } + + .double { + display: grid; + grid-template-columns: 1fr 1fr; + grid-template-areas: 'label label' 'left right'; + gap: 0 8px; + + label { + grid-area: label; + } + } + + & + .meta-data { + flex: 1; + } + } + + .meta-data.html { + height: unset; + display: flex; + flex-direction: row; + gap: 0 8px; + flex: 1; + + & > div { + flex: 1; + display: flex; + flex-direction: column; + height: 100%; + + label { + flex: 0; + } + + .editor { + flex: 1; + } + } + + } + +} diff --git a/src/style/organisms/character-tabs/_social.scss b/src/style/organisms/character-tabs/_social.scss new file mode 100644 index 00000000..bbfc49e7 --- /dev/null +++ b/src/style/organisms/character-tabs/_social.scss @@ -0,0 +1,38 @@ +@mixin tab { + + display: flex; + flex-direction: column; + + .social-line { + flex: 0; + height: unset; + display: grid; + grid-template-columns: 1fr 1fr 80px; + } + + .meta-data.html { + + height: unset; + display: flex; + flex-direction: row; + gap: 0 8px; + flex: 1; + + & > div { + display: flex; + flex-direction: column; + height: 100%; + flex: 1; + + label { + flex: 0; + } + + .editor { + flex: 1; + } + } + + } + +} diff --git a/src/style/organisms/character-tabs/_spells.scss b/src/style/organisms/character-tabs/_spells.scss new file mode 100644 index 00000000..433d556d --- /dev/null +++ b/src/style/organisms/character-tabs/_spells.scss @@ -0,0 +1,108 @@ +@use "sass:color"; +@use "../../atoms/numbers"; +@use "../../atoms/colours" as colour; + +@mixin tab { + tr { + height: 24px; + margin: 0; + padding: 0; + } + + td { + margin: 0; + padding: 0; + height: 24px; + } + + $color: #05f; + + .spell.rollable svg { + width: 24px; + height: 24px; + top: 1px; + z-index: 1; + position: relative; + + .border { + fill: #0000; + } + + .center { + fill: $color; + stroke: colour.$rollable-die-border-color; + } + + .topleft { + fill: color.adjust($color, $lightness: numbers.$lighter_factor); + stroke: colour.$rollable-die-border-color; + } + + .bottomleft { + fill: color.adjust($color, $lightness: numbers.$lightest_factor); + stroke: colour.$rollable-die-border-color; + } + + .topright { + fill: color.adjust($color, $lightness: numbers.$darken_factor); + stroke: colour.$rollable-die-border-color; + } + + .bottomright, .bottom { + fill: color.adjust($color, $lightness: numbers.$darkest_factor); + stroke: colour.$rollable-die-border-color; + } + } + + .die-column { + width: 24px; + } + + .clickable { + span { + position: relative; + z-index: 1; + } + } + + tbody { + + tr { + + position: relative; + + &::after { + content: ''; + background-image: linear-gradient(to right, rgba(color.scale($color, $lightness: numbers.$zebra_light), numbers.$start_gradient), rgba(color.scale($color, $lightness: numbers.$zebra_light), numbers.$end_2_gradient)); + border-top-right-radius: 8px; + border-bottom-right-radius: 8px; + position: absolute; + top: 2px; + left: 12px; + bottom: 2px; + right: 33%; + z-index: 0; + pointer-events: none; + } + + &:nth-child(odd) { + &::after { + background-image: linear-gradient(to right, rgba(color.scale($color, $lightness: numbers.$zebra_dark), numbers.$start_gradient), rgba(color.scale($color, $lightness: numbers.$zebra_dark), numbers.$end_2_gradient)); + } + } + } + + } + + .merkmal-list { + list-style: none; + margin: 0; + padding: 0; + text-indent: 0; + + li { + display: inline-block; + padding: 0 4px; + } + } +} \ No newline at end of file diff --git a/src/style/styles.scss b/src/style/styles.scss index b34105ce..97ef261f 100644 --- a/src/style/styles.scss +++ b/src/style/styles.scss @@ -1,20 +1,22 @@ @use "atoms/fonts"; @use "atoms/typography"; @use "atoms/svg"; +@use "molecules/pill"; @use "molecules/rollable"; @use "molecules/lists"; @use "molecules/attributes"; @use "molecules/sidebar-elements"; + +@use "molecules/tabs"; +@use "molecules/paperdoll"; +@use "molecules/player-action"; +@use "molecules/liturgy-banner"; +@use "molecules/richtext-editor"; @use "organisms/character-sheet"; @use "organisms/group-sheet"; -@use "molecules/tabs"; @use "organisms/equipment-sheet"; -@use "molecules/paperdoll"; @use "organisms/creature-sheet"; -@use "molecules/player-action"; @use "organisms/modify-liturgy"; -@use "molecules/liturgy-banner"; @use "organisms/skill-sheet"; @use "organisms/active-effect-sheet"; @use "organisms/advantage-sheet"; -@use "molecules/richtext-editor"; \ No newline at end of file diff --git a/src/system.json b/src/system.json index 64166527..ae1ac3de 100644 --- a/src/system.json +++ b/src/system.json @@ -127,6 +127,14 @@ } }, "Item": { + "Profession": { + "htmlFields": [ + "description" + ], + "booleanFields": [ + "revealed" + ] + }, "Equipment": { "stringFields": [ "name", diff --git a/src/templates/actor/character/main-sheet.hbs b/src/templates/actor/character/main-sheet.hbs index 089a3ae1..9f4c6003 100644 --- a/src/templates/actor/character/main-sheet.hbs +++ b/src/templates/actor/character/main-sheet.hbs @@ -3,7 +3,19 @@ {{!-- Sheet Header --}}
{{!-- Header stuff goes here --}} +
+
+ +
+ {{system.meta.spezies}} + {{system.meta.kultur}} + {{#each professions}} + {{this.name}} + {{/each}} +
+
{{#each attributes}} {{> "systems/DSA_4-1/templates/ui/partial-attribute-button.hbs" this}} @@ -13,10 +25,8 @@
-

- - + + {{/each}} - -
{{!-- Sheet Tab Navigation --}} diff --git a/src/templates/actor/character/tab-equipment.hbs b/src/templates/actor/character/tab-equipment.hbs index 526254f3..213deb5c 100644 --- a/src/templates/actor/character/tab-equipment.hbs +++ b/src/templates/actor/character/tab-equipment.hbs @@ -1,85 +1,5 @@ -
-
-

Kampftalente

-
    - {{#each skills.Kampf}} -
  • - {{> "systems/DSA_4-1/templates/ui/partial-rollable-weaponskill-button.hbs" this}} -
  • - {{/each}} -
-
-
-

Körperliche Talente

-
    -
  • - {{#each skills.Körperlich}} -
  • - {{> "systems/DSA_4-1/templates/ui/partial-rollable-button.hbs" this}} -
  • - {{/each}} -
-
-
-

Gesellschaftliche Talente

-
    -
  • - {{#each skills.Gesellschaft}} -
  • - {{> "systems/DSA_4-1/templates/ui/partial-rollable-button.hbs" this}} -
  • - {{/each}} -
-
-
-

Natur Talente

-
    -
  • - {{#each skills.Natur}} -
  • - {{> "systems/DSA_4-1/templates/ui/partial-rollable-button.hbs" this}} -
  • - {{/each}} -
-
-
-

Wissenstalente

-
    -
  • - {{#each skills.Wissen}} -
  • - {{> "systems/DSA_4-1/templates/ui/partial-rollable-button.hbs" this}} -
  • - {{/each}} -
-
-
-

Schriften & Sprachen

-
    -
  • - {{#each skills.Schriften}} -
  • - {{> "systems/DSA_4-1/templates/ui/partial-rollable-language-button.hbs" this}} -
  • - {{/each}} - {{#each skills.Sprachen}} -
  • - {{> "systems/DSA_4-1/templates/ui/partial-rollable-language-button.hbs" this}} -
  • - {{/each}} -
-
-
-

Handwerkliche Talente

-
    -
  • - {{#each skills.Handwerk}} -
  • - {{> "systems/DSA_4-1/templates/ui/partial-rollable-button.hbs" this}} -
  • - {{/each}} -
-
+
+ To be done
\ No newline at end of file diff --git a/src/templates/actor/character/tab-meta.hbs b/src/templates/actor/character/tab-meta.hbs index 324470dc..71fa322e 100644 --- a/src/templates/actor/character/tab-meta.hbs +++ b/src/templates/actor/character/tab-meta.hbs @@ -4,32 +4,18 @@
\ No newline at end of file diff --git a/src/templates/actor/character/tab-social.hbs b/src/templates/actor/character/tab-social.hbs new file mode 100644 index 00000000..d4a5256c --- /dev/null +++ b/src/templates/actor/character/tab-social.hbs @@ -0,0 +1,40 @@ +
+ + + +
\ No newline at end of file