feature/heldengruppe #48

Closed
macniel wants to merge 4 commits from feature/heldengruppe into feature/import-from-compendium
20 changed files with 1069 additions and 14 deletions

View File

@ -7,6 +7,10 @@ import { VornachteileDataModel } from "./module/data/vornachteile.mjs";
import { Character } from "./module/documents/character.mjs";
import { CharacterSheet } from "./module/sheets/characterSheet.mjs";
import { VornachteilSheet } from "./module/sheets/vornachteilSheet.mjs";
import {GroupDataModel} from "./module/data/group.mjs";
import {GroupSheet} from "./module/sheets/groupSheet.mjs";
import {EquipmentDataModel} from "./module/data/equipment.mjs";
import {AusruestungSheet} from "./module/sheets/equipmentSheet.mjs";
async function preloadHandlebarsTemplates() {
return loadTemplates([
@ -15,7 +19,9 @@ async function preloadHandlebarsTemplates() {
'systems/DSA_4-1/templates/ui/partial-attribute-button.hbs',
'systems/DSA_4-1/templates/ui/partial-talent-editable.hbs',
'systems/DSA_4-1/templates/ui/partial-die.hbs',
'systems/DSA_4-1/templates/ui/partial-advantage-button.hbs'
'systems/DSA_4-1/templates/ui/partial-advantage-button.hbs',
'systems/DSA_4-1/templates/ui/partial-equipment-button.hbs',
'systems/DSA_4-1/templates/ui/partial-array-editor.hbs'
]);
}
@ -31,12 +37,14 @@ Hooks.once("init", () => {
// Configure System Data Models.
CONFIG.Actor.dataModels = {
character: PlayerCharacterDataModel,
group: GroupDataModel
};
CONFIG.Item.dataModels = {
Skill: SkillDataModel,
Spell: SpellDataModel,
Advantage: VornachteileDataModel
Advantage: VornachteileDataModel,
Equipment: EquipmentDataModel,
}
CONFIG.Combat.initiative = {
@ -51,6 +59,11 @@ Hooks.once("init", () => {
makeDefault: true,
label: 'DSA41.CharacterLabels.Item'
})
Actors.registerSheet('dsa41.group', GroupSheet, {
types: ["group"],
makeDefault: true,
label : 'DSA41.GroupLabel.Item'
})
// Register sheet application classes
Items.registerSheet('dsa41.skill', SkillSheet, {
@ -68,12 +81,21 @@ Hooks.once("init", () => {
makeDefault: true,
label: 'DSA41.VornachteilLabels.Item'
})
Items.registerSheet('dsa41.equipment', AusruestungSheet, {
types: ["Equipment"],
makeDefault: true,
label: 'DSA41.AusruestungLabels.Item'
})
return preloadHandlebarsTemplates();
})
Hooks.on('dropActorSheetData', (actor, sheet, data) => {
return CharacterSheet.onDroppedData(actor, sheet, data);
if (actor.type === "character") {
return CharacterSheet.onDroppedData(actor, sheet, data);
} else {
return GroupSheet.onDroppedData(actor, sheet, data);
}
} )
Hooks.once("ready", async function() {

View File

@ -0,0 +1,41 @@
import BaseItem from "./base-item.mjs";
const {
ArrayField, NumberField, StringField, HTMLField
} = foundry.data.fields;
export class EquipmentDataModel extends BaseItem {
static defineSchema() {
return {
quantity: new NumberField({ required: true, integer: true, initial: 1}),
category: new ArrayField(new StringField({ required: true })),
description: new HTMLField(),
weight: new NumberField({ required: true }),
price: new StringField(),
breakFactor: new NumberField({ required: false }),
iniModifier: new NumberField({ required: false }),
attackModifier: new NumberField({ required: false }),
parryModifier: new NumberField({ required: false }),
meleeAttackModifier: new NumberField({ integer: true }),
meleeAttackModifierIncrement: new NumberField({ integer: true }),
meleeSkills: new ArrayField(
new StringField({ required: true }),
),
meleeAttackDamage: new StringField(),
rangedSkills: new ArrayField(
new StringField({ required: true }),
),
rangedRangeModifier: new StringField({ required: false }),
rangeRangeDamageModifier: new StringField({ required: false }),
rangedAttackDamage: new StringField(),
rangedReloadTime: new NumberField({ required: false }),
armorValue: new NumberField({ required: false }),
armorHandicap: new NumberField({ required: false }),
}
}
}

View File

@ -0,0 +1,20 @@
const {
SchemaField, NumberField, StringField, EmbeddedDocumentField, DocumentIdField, ArrayField, ForeignDocumentField
} = foundry.data.fields;
export class GroupDataModel extends foundry.abstract.TypeDataModel {
static defineSchema() {
return {
name: new StringField(),
inventory: new SchemaField({
quantity: new NumberField(),
item: new DocumentIdField(Item)
}),
characters: new ArrayField(
new DocumentIdField(Actor)
)
}
}
}

View File

@ -0,0 +1,10 @@
export class Equipment extends Item {
/**
* Augment the basic Item data model with additional dynamic data.
*/
prepareData() {
super.prepareData();
}
}

View File

@ -0,0 +1,12 @@
export class Group extends Actor {
/**
* @override
*/
prepareData() {
console.log("prepare", this);
super.prepareData();
}
}

View File

@ -34,6 +34,7 @@ export class CharacterSheet extends ActorSheet {
this.#addSkillsToContext(context)
this.#addAdvantagesToContext(context)
this.#addAttributesToContext(context)
this.#addEquipmentsToContext(context)
return context;
}
@ -152,6 +153,25 @@ export class CharacterSheet extends ActorSheet {
}
#addEquipmentsToContext(context) {
context.equipments = [];
const actorData = context.data;
context.carryingweight = 0;
Object.values(actorData.items).forEach( (item, index) => {
if (item.type === "Equipment") {
context.equipments.push({
index: index,
id: item._id,
quantity: item.system.quantity,
name: item.name,
})
context.carryingweight += item.system.quantity * item.system.weight;
}
})
context.maxcarryingcapacity = actorData.system.attribute.kk.aktuell
context.carryingpercentage = (context.carryingweight / context.maxcarryingcapacity)*100;
}
prepareEigenschaftRoll(actorData, name) {
return actorData.system.attribute[name.toLowerCase()].aktuell
}
@ -306,6 +326,11 @@ export class CharacterSheet extends ActorSheet {
evt.stopPropagation();
})
html.on('click', '.equipment', (evt) => {
this.openEmbeddedDocument(evt.target.parentElement.dataset.id);
evt.stopPropagation();
})
new ContextMenu(html, '.talent.rollable', [
{
name: "Entfernen",
@ -337,6 +362,17 @@ export class CharacterSheet extends ActorSheet {
li.addEventListener("dragstart", handler, false);
});
new ContextMenu(html, '.equipment', [
{
name: "Aus dem Inventar entfernen",
icon: '<i class="fa-solid fa-trash"></i>',
callback: (event) => {
this.object.deleteEmbeddedDocuments('Item', [event[0].dataset.id])
},
condition: () => true
}
]);
}
#handleDroppedSkill(actor, skill) {
@ -357,6 +393,16 @@ export class CharacterSheet extends ActorSheet {
}
}
#handleDroppedEquipment(actor, equipment) {
const array = Array.from(actor.items);
for ( let i = 0; i < array.length; i++ ) {
if (array[i].name === equipment.name) { // TODO: adjust item quantity if item is the same
console.log(equipment);
return false;
}
}
}
static getElementByName(collection, id) {
const array = Array.from(collection);
for (const element of array) {
@ -380,6 +426,9 @@ export class CharacterSheet extends ActorSheet {
return characterSheet.#handleDroppedSkill(actor, document); // on false cancel this whole operation
case "Advantage":
return characterSheet.#handleDroppedAdvantage(actor, document);
case "Equipment":
return characterSheet.#handleDroppedEquipment(actor, document);
default:
return false;
}

View File

@ -0,0 +1,109 @@
export class AusruestungSheet extends ItemSheet {
/**@override */
static get defaultOptions() {
return foundry.utils.mergeObject(super.defaultOptions, {
classes: ['dsa41', 'sheet', 'item', 'equipment'],
width: 520,
height: 480,
tabs: [
{
navSelector: '.sheet-tabs',
contentSelector: '.sheet-body',
initial: 'description',
},
],
});
}
/** @override */
get template() {
return `systems/DSA_4-1/templates/item/item-equipment-sheet.hbs`;
}
/** @override */
getData() {
// Retrieve the data structure from the base sheet. You can inspect or log
// the context variable to see the structure, but some key properties for
// sheets are the actor object, the data object, whether or not it's
// editable, the items array, and the effects array.
const context = super.getData();
// Use a safe clone of the actor data for further operations.
const equipmentData = context.data;
// Add the actor's data to context.data for easier access, as well as flags.
context.system = equipmentData.system;
context.flags = equipmentData.flags;
context.quantity = context.system.quantity;
context.description = context.system.description;
context.categoryAndOptions = {
options: {
Gegenstand: "Gegenstand",
Nahkampfwaffe: "Nahkampfwaffe",
Fernkampfwaffe: "Fernkampfwaffe",
Behälter: "Behälter",
Rüstung: "Rüstung",
},
entries: context.system.category,
targetField: "category"
};
context.isMeleeWeapon = context.system.category.includes("Nahkampfwaffe");
context.isRangedWeapon = context.system.category.includes("Fernkampfwaffe");
context.isContainer = context.system.category.includes("Behälter");
context.isArmor = context.system.category.includes("Rüstung");
context.price = context.system.price;
context.weight = context.system.weight;
context.meleeSkillsAndOptions = {
options: {
"": "",
Dolche: "Dolche",
Fechtwaffen: "Fechtwaffen",
Säbel: "Säbel",
Schwerter: "Schwerter",
Anderthalbhänder: "Anderthalbhänder",
"Zweihandschwerter/-säbel": "Zweihandschwerter/-säbel",
"Infanteriewaffen": "Infanteriewaffen",
"Speere": "Speere",
"Stäbe": "Stäbe",
"Hiebwaffen": "Hiebwaffen",
"Zweihand-Hiebwaffen": "Zweihand-Hiebwaffen",
"Kettenwaffen": "Kettenwaffen",
"Raufen": "Raufen"
},
entries: context.system.meleeSkills,
targetField: "meleeSkills"
}
context.rangedSkillsAndOptions = {
options: {
"": "",
"Wurfmesser": "Wurfmesser",
"Wurfspeer": "Wurfspeer",
"Wurfbeil": "Wurfbeil",
"Armbrust": "Armbrust",
"Bogen": "Bogen",
},
entries: context.system.rangedSkills,
targetField: "rangedSkills"
}
return context;
}
activateListeners(html) {
super.activateListeners(html);
html.on('change', '.array-editor select', (evt) => {
const addingValue = evt.currentTarget.value;
const fieldToTarget = evt.currentTarget.dataset.targetField;
const newSkills = [...this.object.system[fieldToTarget], addingValue];
this.object.update( { system: { [fieldToTarget]: newSkills }} );
evt.currentTarget.value = "";
})
// Everything below here is only needed if the sheet is editable
if (!this.isEditable) return;
}
}

View File

@ -0,0 +1,166 @@
export class GroupSheet extends ActorSheet {
/**@override */
static get defaultOptions() {
return foundry.utils.mergeObject(super.defaultOptions, {
classes: ['dsa41', 'sheet', 'actor', 'group'],
width: 520,
height: 480,
tabs: [
{
navSelector: '.sheet-tabs',
contentSelector: '.sheet-body',
initial: 'description',
},
],
});
}
/** @override */
async getData() {
const context = super.getData();
// Use a safe clone of the actor data for further operations.
const groupData = context.data;
// Add the actor's data to context.data for easier access, as well as flags.
context.system = groupData.system;
context.flags = groupData.flags;
context.characters = [];
for (const characterId of groupData.system.characters) {
const character = await game.actors.get(characterId)
context.characters.push(
{
img: character.img,
name: character.name,
id: character._id,
attributes: [
{name: "MU", value: character.system.attribute.mu.aktuell},
{name: "KL", value: character.system.attribute.kl.aktuell},
{name: "IN", value: character.system.attribute.in.aktuell},
{name: "CH", value: character.system.attribute.ch.aktuell},
{name: "FF", value: character.system.attribute.ff.aktuell},
{name: "GE", value: character.system.attribute.ge.aktuell},
{name: "KO", value: character.system.attribute.ko.aktuell},
{name: "KK", value: character.system.attribute.kk.aktuell},
],
advantages: character.items.filter((i) => i.type === "Advantage").map((advantage) => {
return {
name: advantage.name,
id: advantage._id,
value: advantage.system.value,
}
}),
skills: character.items.filter((i) => i.type === "Skill").map((skill) => {
return {
name: skill.name,
taw: skill.system.taw,
id: skill._id
}
}),
isLimited: character.isOwner || !character.limited,
isVisible: character.isOwner || character.visible,
isOwner: character.isOwner
}
)
}
context.equipments = [];
const actorData = context.data;
Object.values(actorData.items).forEach( (item, index) => {
if (item.type === "Equipment") {
context.equipments.push({
index: index,
id: item._id,
quantity: item.system.quantity,
name: item.name,
})
}
})
return await context;
}
/** @override */
get template() {
return `systems/DSA_4-1/templates/actor/group-sheet.hbs`;
}
static async onDroppedData(group, sheet, data) {
if (data.type === "Actor") {
const uuid = await foundry.utils.parseUuid(data.uuid);
const character = await (game.actors.get(uuid.id))
// check if character already is part of the group
if (group.system.characters.includes(character._id)) {
ui.notifications.warn(`${character.name} befindet sich bereits in der Heldengruppe ${group.name}`)
return false;
}
// update group
await group.update({
system: {
characters: [
...group.system.characters,
character._id
]
}
})
ui.notifications.info(`${character.name} ist der Heldengruppe ${group.name} beigetreten`)
}
if (data.type === "Equipment") {
const uuid = await foundry.utils.parseUuid(data.uuid);
const equipment = await (game.actors.get(uuid.id))
ui.notifications.info(`${equipment.name} befindet sich nun im Inventar der Heldengruppe ${group.name}`)
return true;
}
}
openEmbeddedDocument(documentId) {
this.object.items.get(documentId).sheet.render(true)
}
activateListeners(html) {
super.activateListeners(html);
html.on('click', '.owneroption.clickable', async (evt) => {
const dataset = evt.target.dataset;
const group = this.object;
switch (dataset.operation) {
case "removeFromParty":
const charactersWithoutMember = group.system.characters.filter(id => id !== dataset.id)
await group.update({
system: {
characters: charactersWithoutMember
}
})
}
});
html.on('click', '.header.clickable', async (evt) => {
const {id, operation} = evt.currentTarget.dataset;
if (operation === "openActorSheet") {
evt.stopPropagation();
(await game.actors.get(id)).sheet.render(true);
}
})
html.on('click', '.equipment', (evt) => {
this.openEmbeddedDocument(evt.target.dataset.id);
evt.stopPropagation();
})
new ContextMenu(html, '.equipment', [
{
name: "Aus dem Gruppeninventar entfernen",
icon: '<i class="fa-solid fa-trash"></i>',
callback: (event) => {
this.object.deleteEmbeddedDocuments('Item', [event[0].dataset.id])
},
condition: () => true
}
]);
}
}

View File

@ -52,6 +52,39 @@
overflow: auto;
}
.backpack {
position: absolute;
left: 0;
top: 0;
bottom: 0;
right: 0;
padding: 8px;
.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%);
}
}
.equipment:hover {
.item-name {
text-shadow: 0 0 10px rgb(255 0 0);
}
}
}
}
}

View File

@ -0,0 +1,136 @@
.app.window-app.dsa41.sheet.item.equipment {
.sheet-body {
position: relative;
top: 5px;
.tab.active {
padding: 4px;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
.tab.meta.active {
position: absolute;
display: grid;
grid-auto-columns: 1fr 1fr;
grid-template-columns: 80px auto;
grid-template-rows: 24px 48px auto 48px;
gap: 0px 0px;
grid-template-areas:
"category category"
"quantity name"
"description description"
"bottomline bottomline";
.name {
grid-area: name;
}
.bottomline {
grid-area: bottomline;
display: grid;
grid-template-columns: repeat(2, 1fr);
.named-value {
position: relative;
height: 48px;
label {
position: absolute;
left: 0;
top: 0;
bottom: 0;
width: 80px;
line-height: 24px;
vertical-align: middle;
input {
position: absolute;
left: 80px;
top: 0;
bottom: 0;
right: 0;
}
}
}
}
.category {
grid-area: category;
position: relative;
label {
line-height: 24px;
vertical-align: middle;
}
.array-editor {
position: absolute;
right: 0;
left: 80px;
top: 0;
bottom: 0;
ul {
list-style-type: none;
padding: 0;
margin: 0;
text-indent: 0;
li {
display: inline-block;
border: 1px solid #333;
background-color: rgba(255, 255, 255, 0.2);
border-radius: 12px;
line-height: 24px;
vertical-align: middle;
padding: 0 8px;
box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3);
}
}
select {
position: absolute;
right: 0;
top: 0;
}
}
}
.quantity {
grid-area: quantity;
}
.description {
grid-area: description;
position: relative;
label {
height: 14px;
}
.editor {
position: absolute;
top: 14px;
left: 0;
right: 0;
bottom: 0;
border-bottom: 1px inset #333;
}
}
}
}
}

View File

@ -0,0 +1,180 @@
.dsa41.sheet.actor.group {
.window-content {
display: unset;
position: relative;
}
.sheet-header {
.sheet-name {
font-size: 24pt;
height: 48px;
}
}
.sheet-tabs {
position: absolute;
left: 0;
right: 0;
top: 76px;
height: 32px;
padding: 0 16px;
}
.sheet-body {
position: absolute;
top: 98px;
left: 0;
bottom: 0;
right: 0;
padding: 8px;
margin: 8px;
div.tab {
height: 100%;
position: relative;
}
}
.characters-overview {
display: inline-flex;
overflow-x: auto;
height: 100%;
width: 100%;
gap: 8px;
&.minimal {
display: unset!important;
.character {
display: inline-block;
margin: 4px;
box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.5);
}
}
.character {
width: 192px;
position: relative;
.header {
position: relative;
height: 80px;
overflow: hidden;
left: 0;
right: 0;
img {
position: absolute;
top: 0;
height: 80px;
width: 100%;
left: 0;
right: 0;
&::before {
}
}
span.name {
position: absolute;
bottom: 0;
left: 0;
right: 0;
text-align: center;
background-color: rgba(0, 0, 0, 0.5);
color: white;
}
}
.mini-attributes {
display: grid;
height: 24px;
grid-template-columns: repeat(8, 1fr);
.mini-attribute {
border-left: 1px solid black;
position: relative;
width: 24px;
&:first-of-type {
border-left: 0;
}
.value {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
line-height: 100%;
vertical-align: middle;
text-align: center;
display: block;
}
.name {
position: absolute;
bottom: 0;
left: 0;
right: 0;
height: 14px;
text-align: center;
display: block;
}
}
}
.fixedElements {
position: absolute;
overflow: scroll;
top: 102px;
bottom: 20px;
left: 0;
right: 0;
.inline-list {
list-style: none;
padding: 0;
display: block;
.mini-skill, .mini-advantage {
display: inline-block;
padding: 0 4px;
&:hover {
text-shadow: 0 0 10px rgb(255 0 0);
}
}
}
}
.owneroptions {
position: absolute;
bottom: 0;
left: 0;
right: 0;
height: 36px;
}
}
}
.equipment:hover {
.item-name {
text-shadow: 0 0 10px rgb(255 0 0);
}
}
}

View File

@ -2,13 +2,14 @@
@use "./colours";
@use "./assets";
.dsa41.sheet.actor.character {
.dsa41.sheet {
nav.sheet-tabs.tabs {
position: relative;
display: flow;
border-top: unset;
border-bottom: unset;
a.item[data-tab] {

View File

@ -3,4 +3,6 @@
@use "_attributes";
@use "_sidebar-elements";
@use "_character-sheet";
@use "_group-sheet";
@use "_tabs";
@use "_equipment-sheet";

View File

@ -81,6 +81,9 @@
],
"documentTypes": {
"Actor": {
"group": {
},
"character": {
"numberFields": [
"groesse", "alter", "gewicht"
@ -98,6 +101,17 @@
}
},
"Item": {
"Equipment": {
"stringFields": [
"name", "category"
],
"htmlFields": [
"description"
],
"numberFields": [
"quantity"
]
},
"Advantage": {
"stringFields": [
"name"

View File

@ -67,10 +67,6 @@
</ul>
</div>
<div class="tab attributes" data-group="primary" data-tab="attributes">
</div>
<div class="tab combat" data-group="primary" data-tab="combat">
</div>
@ -150,6 +146,17 @@
</div>
<div class="tab backpack" data-group="primary" data-tab="backpack">
<div class="capacity">
<label>Tragkraft: {{this.carryingweight}} von maximal {{this.maxcarryingcapacity}} Stein</label>
<div class="resource">
<span class="fill" style="width: {{this.carryingpercentage}}%"></span>
</div>
</div>
{{#each equipments}}
{{> "systems/DSA_4-1/templates/ui/partial-equipment-button.hbs" this}}
{{/each}}
</div>
<div class="tab spells" data-group="primary" data-tab="spells">

View File

@ -0,0 +1,79 @@
<form class="{{cssClass}} {{actor.type}} flexcol" autocomplete="off">
{{!-- Sheet Header --}}
<header class="sheet-header">
<input class="sheet-name" type="text" name="actor.name" value="{{actor.name}}" />
</header>
{{!-- Sheet Tab Navigation --}}
<nav class="sheet-tabs tabs" data-group="primary">
<a class="item" data-tab="characters">Charaktere</a>
<a class="item" data-tab="inventory">Inventar</a>
</nav>
{{!-- Sheet Body --}}
<section class="sheet-body">
<div class="tab characters" data-group="primary" data-tab="characters">
{{#if actor.limited}}
<div class="characters-overview minimal">
{{#each characters}}
{{#if this.isVisible}}
<div class="character">
<div class="header clickable" data-id="{{this.id}}" data-operation="openActorSheet">
<img class="profile-img" src="{{this.img}}" style="object-fit: cover;" title="{{this.name}}" alt="{{this.name}}"/>
<span class="name">{{this.name}}</span>
</div>
</div>
{{/if}}
{{/each}}
</div>
{{else}}
<div class="characters-overview">
{{#each characters}}
{{#if this.isVisible}}
<div class="character">
<div class="header clickable" data-id="{{this.id}}" data-operation="openActorSheet">
<img class="profile-img" src="{{this.img}}" style="object-fit: cover;" title="{{this.name}}" alt="{{this.name}}"/>
<span class="name">{{this.name}}</span>
</div>
{{#if this.isLimited}}
<div class="mini-attributes">
{{#each this.attributes}}
<div class="mini-attribute" data-actor-id="{{actor.id}}" data-attribute="{{this.name}}" data-roll-data="{{this.value}}">
<span class="value">{{this.value}}</span>
<span class="name">{{this.name}}</span>
</div>
{{/each}}
</div>
<div class="fixedElements">
<ul class="inline-list">
{{#each skills}}<li class="mini-skill clickable" data-actor-id="{{this.id}}" data-id="{{this.id}}">{{this.name}}: {{this.taw}}</li>{{/each}}
</ul>
<ul class="inline-list">
{{#each advantages}}<li class="mini-advantage clickable" data-actor-id="{{this.id}}" data-id="{{this.id}}">{{this.name}} {{#if this.value}}[{{this.value}}]{{/if}}</li>{{/each}}
</ul>
</div>
{{/if}}
{{#if this.isOwner}}
<div class="owneroptions">
<button class="owneroption clickable" data-operation="removeFromParty" data-id="{{this.id}}">Leave Group</button>
</div>
{{/if}}
</div>
{{/if}}
{{/each}}
</div>
{{/if}}
</div>
<div class="tab inventory" data-group="primary" data-tab="inventory">
<ul>
{{#each equipments}}
{{> 'systems/DSA_4-1/templates/ui/partial-equipment-button.hbs' this}}
{{/each}}
</ul>
</div>
</section>
</form>

View File

@ -0,0 +1,160 @@
<form class="{{cssClass}} {{item.type}} flexcol" autocomplete="off">
{{!-- Sheet Tab Navigation --}}
<nav class="sheet-tabs tabs" style="flex: 0" data-group="primary">
<a class="item" data-tab="meta">Gegenstand</a>
{{#if isMeleeWeapon}}
<a class="item" data-tab="melee">Nahkampfwaffe</a>
{{/if}}
{{#if isRangedWeapon}}
<a class="item" data-tab="ranged">Fernkampfwaffe</a>
{{/if}}
{{#if isContainer}}
<a class="item" data-tab="container">Behälter</a>
{{/if}}
{{#if isArmor}}
<a class="item" data-tab="armor">Rüstung</a>
{{/if}}
</nav>
{{!-- Sheet Body --}}
<section class="sheet-body" style="flex: 1">
<div class="tab meta" data-group="primary" data-tab="meta">
<div class="name">
<label>Name
<input name="name" type="text" value="{{item.name}}" placeholder="Name"/>
</label>
</div>
<div class="quantity">
<label>Anzahl
<input type="number" name="system.quantity"
value="{{quantity}}" />
</label>
</div>
<div class="category"><label>Kategorie:
{{> "systems/DSA_4-1/templates/ui/partial-array-editor.hbs" this.categoryAndOptions}}
</label></div>
<div class="description">
<label>Beschreibungstext</label>
{{editor system.description target="system.description" button=true owner=owner editable=editable}}
</div>
<div class="bottomline">
<label class="named-value"><span>Preis (Silbertaler)</span>
<input type="number" name="system.price" value="{{price}}" />
</label>
<label class="named-value"><span>Gewicht (in Stein)</span>
<input type="number" name="system.weight" value="{{weight}}" />
</label>
</div>
</div>
{{#if isMeleeWeapon}}
<div class="tab melee" data-group="primary" data-tab="melee">
<div>
<label>TP
<input type="text" name="system.meleeAttackDamage" value="{{system.meleeAttackDamage}}" />
</label>
</div>
<div>
<label>TP/KK
<input name="system.meleeAttackModifier" type="number" value="{{system.meleeAttackModifier}}" />
<input name="system.meleeAttackModifierIncrement" type="number" value="{{system.meleeAttackModifierIncrement}}" />
</label>
</div>
<div>
<label>Geführte Talente
{{> "systems/DSA_4-1/templates/ui/partial-array-editor.hbs" this.meleeSkillsAndOptions}}
</label>
</div>
<div>
<label>Initiative
<input name="system.iniModifier" type="number" value="{{system.iniModifier}}" />
</label>
</div>
<div>
<label>Bruchfaktor
<input name="system.breakFactor" type="number" value="{{system.breakFactor}}" />
</label>
</div>
<div>
<label>Attacke
<input name="system.attackModifier" type="number" value="{{system.attackModifier}}" />
</label>
</div>
<div>
<label>Parade
<input name="system.parryModifier" type="number" value="{{system.parryModifier}}" />
</label>
</div>
</div>
{{/if}}
{{#if isRangedWeapon}}
<div class="tab ranged" data-group="primary" data-tab="ranged">
<div>
<label>TP
<input type="text" name="system.rangedAttackDamage" value="{{system.rangedAttackDamage}}" />
</label>
</div>
<div>
<label>Reichweiten
<input type="text" name="system.rangedRangeModifier" value="{{system.rangedRangeModifier}}" />
</label>
</div>
<div>
<label>TP+
<input type="text" name="system.rangeRangeDamageModifier" value="{{system.rangeRangeDamageModifier}}" />
</label>
</div>
<div>
<label>Geführte Talente
{{> "systems/DSA_4-1/templates/ui/partial-array-editor.hbs" this.rangedSkillsAndOptions}}
</label>
</div><div>
<label>Ladedauer (Aktionen)
<input type="text" name="system.rangedReloadTime" value="{{system.rangedReloadTime}}" />
</label>
</div>
</div>
{{/if}}
{{#if isContainer}}
<div class="tab container" data-group="primary" data-tab="container">
Behälter Specs
</div>
{{/if}}
{{#if isArmor}}
<div class="tab armor" data-group="primary" data-tab="armor">
<div>
<label>Gesamt Rüstungswert
<input type="text" name="system.armorValue" value="{{system.armorValue}}" />
</label>
</div>
<div>
<label>Gesamt Behinderung
<input type="text" name="system.armorHandicap" value="{{system.armorHandicap}}" />
</label>
</div>
<div>
<label>Initiative Modifaktor
<input type="text" name="system.iniModifier" value="{{system.iniModifier}}" />
</label>
</div>
<div>
<label>Bruchfaktor
<input type="text" name="system.breakFactor" value="{{system.breakFactor}}" />
</label>
</div>
<div>
<label>Attacke
<input type="text" name="system.attackModifier" value="{{system.attackModifier}}" />
</label>
</div>
<div>
<label>Parade
<input type="text" name="system.parryModifier" value="{{system.parryModifier}}" />
</label>
</div>
</div>
{{/if}}
</section>
</form>

View File

@ -53,9 +53,8 @@
</div>
<div class="tab description" data-group="primary" data-tab="description">
<div>
<label>Beschreibungstext
{{editor system.text target="system.talent" button=true owner=owner editable=editable}}
</label>
<label>Beschreibungstext</label>
{{editor system.talent target="system.talent" button=true owner=owner editable=editable}}
</div>
<div>
<label>Voraussetzung</label>

View File

@ -0,0 +1,11 @@
<div class="array-editor">
<ul>

Formatierung, das passt hier von der Einrückung nicht so ganz

Formatierung, das passt hier von der Einrückung nicht so ganz
{{#each entries}}
<li>{{this}}</li>
{{/each}}
</ul>
<select data-target-field="{{targetField}}">
{{selectOptions options inverted=true}}
</select>
</div>

View File

@ -0,0 +1,4 @@
<div class="equipment" data-id="{{this.id}}">
<span class="quantity">{{this.quantity}}</span>
<span class="item-name">{{this.name}}</span>
</div>