Merge remote-tracking branch 'origin/master' into 008-chatRollInterface

This commit is contained in:
Oliver Rümpelein 2021-01-08 18:32:36 +01:00
commit c89278992f
43 changed files with 1137 additions and 640 deletions

View file

@ -16,8 +16,10 @@
@import "scss/components/basic_property";
@import "scss/components/tabs";
@import "scss/components/items";
@import "scss/components/talents";
@import "scss/components/description";
@import "scss/components/character_values";
@import "scss/components/attributes_traits";
@import "scss/components/combat_values";
@import "scss/components/character_progression";
}

View file

@ -1,10 +1,12 @@
{
"DS4.UserInteractionAddItem": "Add item",
"DS4.NotOwned": "No owner",
"DS4.Description": "Description",
"DS4.DescriptionAbbr": "Desc",
"DS4.Details": "Details",
"DS4.Effects": "Effects",
"DS4.HeadingDescription": "Description",
"DS4.HeadingDetails": "Details",
"DS4.HeadingEffects": "Effects",
"DS4.HeadingInventory": "Inventory",
"DS4.HeadingProfile": "Profile",
"DS4.HeadingTalents": "Talents & Abilities",
"DS4.AttackType": "Attack Type",
"DS4.AttackTypeAbbr": "AT",
"DS4.WeaponBonus": "Weapon Bonus",
@ -29,10 +31,19 @@
"DS4.ItemAvailabilityNowhere": "Nowhere",
"DS4.ItemName": "Name",
"DS4.ItemTypeWeapon": "Weapon",
"DS4.ItemTypeWeaponPlural": "Weapons",
"DS4.ItemTypeArmor": "Armor",
"DS4.ItemTypeArmorPlural": "Armor",
"DS4.ItemTypeShield": "Shield",
"DS4.ItemTypeShieldPlural": "Shields",
"DS4.ItemTypeTrinket": "Trinket",
"DS4.ItemTypeTrinketPlural": "Trinkets",
"DS4.ItemTypeEquipment": "Equipment",
"DS4.ItemTypeEquipmentPlural": "Equipment",
"DS4.ItemTypeTalent": "Talent",
"DS4.ItemTypeTalentPlural": "Talents",
"DS4.ItemTypeRacialAbility": "Racial Ability",
"DS4.ItemTypeRacialAbilityPlural": "Racial Abilities",
"DS4.ArmorType": "Armor Type",
"DS4.ArmorTypeAbbr": "AT",
"DS4.ArmorMaterialType": "Material Type",
@ -78,8 +89,26 @@
"DS4.BaseInfoClass": "Class",
"DS4.BaseInfoHeroClass": "Hero Class",
"DS4.BaseInfoRacialAbilities": "Racial Abilites",
"DS4.BaseInfoCulture": "Culture",
"DS4.ProgressionLevel": "Level",
"DS4.ProgressionExperiencePoints": "Experience Points",
"DS4.ProgressionTalentPoints": "Talent Points",
"DS4.ProgressionProgressPoints": "Progress Points"
"DS4.ProgressionProgressPoints": "Progress Points",
"DS4.TalentRank": "Rank",
"DS4.TalentRankBase": "Acquired Ranks",
"DS4.TalentRankMax": "Maximum Ranks",
"DS4.TalentRankMod": "Additional Ranks",
"DS4.TalentRankTotal": "Total Ranks",
"DS4.LanguageLanguages": "Languages",
"DS4.LanguageAlphabets": "Alphabets",
"DS4.ProfileGender": "Gender",
"DS4.ProfileBirthday": "Birthday",
"DS4.ProfileBirthplace": "Birthplace",
"DS4.ProfileAge": "Age",
"DS4.ProfileHeight": "Height",
"DS4.ProfilHairColor": "Hair Color",
"DS4.ProfileWeight": "Weight",
"DS4.ProfileEyeColor": "Eye Color",
"DS4.ProfileSpecialCharacteristics": "Special Characteristics",
"DS4.WarningManageActiveEffectOnOwnedItem": "Managing Active Effects within an Owned Item is not currently supported and will be added in a subsequent update."
}

View file

@ -4,6 +4,8 @@ export interface DS4ActorDataType {
combatValues: DS4ActorDataCombatValues;
baseInfo: DS4ActorDataBaseInfo;
progression: DS4ActorDataProgression;
language: DS4ActorDataLanguage;
profile: DS4ActorDataProfile;
}
interface DS4ActorDataAttributes {
@ -23,8 +25,9 @@ interface UsableResource<T> {
used: T;
}
interface CurrentData<T> extends ModifiableData<T> {
current: T;
interface ResourceData<T> extends ModifiableData<T> {
value: T;
max?: T;
}
// Blueprint in case we need more detailed differentiation
@ -40,7 +43,7 @@ interface DS4ActorDataTraits {
}
interface DS4ActorDataCombatValues {
hitPoints: CurrentData<number>;
hitPoints: ResourceData<number>;
defense: ModifiableData<number>;
initiative: ModifiableData<number>;
movement: ModifiableData<number>;
@ -55,6 +58,7 @@ interface DS4ActorDataBaseInfo {
class: string;
heroClass: string;
racialAbilities: string;
culture: string;
}
interface DS4ActorDataProgression {
@ -63,3 +67,20 @@ interface DS4ActorDataProgression {
talentPoints: UsableResource<number>;
progressPoints: UsableResource<number>;
}
interface DS4ActorDataLanguage {
languages: string;
alphabets: string;
}
interface DS4ActorDataProfile {
gender: string;
birthday: string;
birthplace: string;
age: number;
height: number;
hairColor: string;
weight: number;
eyeColor: string;
specialCharacteristics: string;
}

View file

@ -18,5 +18,7 @@ export class DS4Actor extends Actor<DS4ActorDataType, DS4ItemDataType, DS4Item>
Object.values(combatValues).forEach(
(combatValue: ModifiableData<number>) => (combatValue.total = combatValue.base + combatValue.mod),
);
combatValues.hitPoints.max = combatValues.hitPoints.total;
}
}

View file

@ -48,6 +48,8 @@ export const DS4 = {
shield: "DS4.ItemTypeShield",
trinket: "DS4.ItemTypeTrinket",
equipment: "DS4.ItemTypeEquipment",
talent: "DS4.ItemTypeTalent",
racialAbility: "DS4.ItemTypeRacialAbility",
},
/**
@ -135,10 +137,11 @@ export const DS4 = {
class: "DS4.BaseInfoClass",
heroClass: "DS4.BaseInfoHeroClass",
racialAbilities: "DS4.BaseInfoRacialAbilities",
culture: "DS4.BaseInfoCulture",
},
/**
* Definme the progression info of a character
* Define the progression info of a character
*/
progression: {
level: "DS4.ProgressionLevel",
@ -146,4 +149,42 @@ export const DS4 = {
talentPoints: "DS4.ProgressionTalentPoints",
progressPoints: "DS4.ProgressionProgressPoints",
},
/**
* Define the language info of a character
*/
language: {
languages: "DS4.LanguageLanguages",
alphabets: "DS4.LanguageAlphabets",
},
/**
* Define the profile info of a character
*/
profile: {
gender: "DS4.ProfileGender",
birthday: "DS4.ProfileBirthday",
birthplace: "DS4.ProfileBirthplace",
age: "DS4.ProfileAge",
height: "DS4.ProfileHeight",
hairColor: "DS4.ProfilHairColor",
weight: "DS4.ProfileWeight",
eyeColor: "DS4.ProfileEyeColor",
specialCharacteristics: "DS4.ProfileSpecialCharacteristics",
},
/**
* Define the profile info types for hanndlebars of a character
*/
profileDTypes: {
gender: "String",
birthday: "String",
birthplace: "String",
age: "Number",
height: "Number",
hairColor: "String",
weight: "Number",
eyeColor: "String",
specialCharacteristics: "String",
},
};

View file

@ -46,8 +46,13 @@ async function registerHandlebarsPartials() {
"systems/ds4/templates/item/partials/effects.hbs",
"systems/ds4/templates/item/partials/body.hbs",
"systems/ds4/templates/actor/partials/items-overview.hbs",
"systems/ds4/templates/actor/partials/talents-overview.hbs",
"systems/ds4/templates/actor/partials/overview-add-button.hbs",
"systems/ds4/templates/actor/partials/overview-control-buttons.hbs",
"systems/ds4/templates/actor/partials/attributes-traits.hbs",
"systems/ds4/templates/actor/partials/combat-values.hbs",
"systems/ds4/templates/actor/partials/profile.hbs",
"systems/ds4/templates/actor/partials/character-progression.hbs",
];
return loadTemplates(templatePaths);
}
@ -75,6 +80,8 @@ Hooks.once("setup", function () {
"combatValues",
"baseInfo",
"progression",
"language",
"profile",
];
// Exclude some from sorting where the default order matters

View file

@ -1,5 +1,13 @@
// TODO: Actually add a type for data
export type DS4ItemDataType = DS4Weapon | DS4Armor | DS4Shield | DS4Trinket | DS4Equipment;
import { ModifiableData } from "../actor/actor-data";
export type DS4ItemDataType =
| DS4Weapon
| DS4Armor
| DS4Shield
| DS4Trinket
| DS4Equipment
| DS4Talent
| DS4RacialAbility;
// types
@ -14,9 +22,18 @@ interface DS4Armor extends DS4ItemBase, DS4ItemPhysical, DS4ItemEquipable, DS4It
armorType: "body" | "helmet" | "vambrace" | "greaves" | "vambraceGreaves";
}
export interface DS4Talent extends DS4ItemBase {
rank: DS4TalentRank;
}
interface DS4TalentRank extends ModifiableData<number> {
max: number;
}
interface DS4Shield extends DS4ItemBase, DS4ItemPhysical, DS4ItemEquipable, DS4ItemProtective {}
interface DS4Trinket extends DS4ItemBase, DS4ItemPhysical, DS4ItemEquipable {}
interface DS4Equipment extends DS4ItemBase, DS4ItemPhysical {}
type DS4RacialAbility = DS4ItemBase;
// templates
@ -30,6 +47,10 @@ interface DS4ItemPhysical {
storageLocation: string;
}
export function isDS4ItemDataTypePhysical(input: DS4ItemDataType): boolean {
return "quantity" in input && "price" in input && "availability" in input && "storageLocation" in input;
}
interface DS4ItemEquipable {
equipped: boolean;
}

View file

@ -1,5 +1,5 @@
import { DS4Item } from "./item";
import { DS4ItemDataType } from "./item-data";
import { DS4ItemDataType, isDS4ItemDataTypePhysical } from "./item-data";
/**
* Extend the basic ItemSheet with some very simple modifications
@ -26,7 +26,13 @@ export class DS4ItemSheet extends ItemSheet<DS4ItemDataType, DS4Item> {
/** @override */
getData(): ItemSheetData<DS4ItemDataType, DS4Item> {
const data = { ...super.getData(), config: CONFIG.DS4, isOwned: this.item.isOwned, actor: this.item.actor };
const data = {
...super.getData(),
config: CONFIG.DS4,
isOwned: this.item.isOwned,
actor: this.item.actor,
isPhysical: isDS4ItemDataTypePhysical(this.item.data.data),
};
console.log(data);
return data;
}
@ -54,29 +60,38 @@ export class DS4ItemSheet extends ItemSheet<DS4ItemDataType, DS4Item> {
if (!this.options.editable) return;
html.find(".effect-create").on("click", this._onEffectCreate.bind(this));
html.find(".effect-edit").on("click", (ev) => {
const li = $(ev.currentTarget).parents(".effect");
console.log(li.data("effectId"));
const effect = this.item.effects.get(li.data("effectId"));
effect.sheet.render(true);
});
html.find(".effect-delete").on("click", async (ev) => {
const li = $(ev.currentTarget).parents(".effect");
await this.item.deleteEmbeddedEntity("ActiveEffect", li.data("effectId"));
});
html.find(".effect-control").on("click", this._onManageActiveEffect.bind(this));
}
/**
* Handle creating a new ActiveEffect for the item using initial data defined in the HTML dataset
* Handle management of ActiveEffects.
* @param {Event} event The originating click event
* @private
*/
private async _onEffectCreate(event: JQuery.ClickEvent): Promise<unknown> {
private async _onManageActiveEffect(event: JQuery.ClickEvent): Promise<unknown> {
event.preventDefault();
if (this.item.isOwned) {
return ui.notifications.warn(game.i18n.localize("DS4.WarningManageActiveEffectOnOwnedItem"));
}
const a = event.currentTarget;
const li = $(a).parents(".effect");
switch (a.dataset["action"]) {
case "create":
return this._createActiveEffect();
case "edit":
const effect = this.item.effects.get(li.data("effectId"));
return effect.sheet.render(true);
case "delete": {
return this.item.deleteEmbeddedEntity("ActiveEffect", li.data("effectId"));
}
}
}
/**
* Create a new ActiveEffect for the item using default data.
*/
private async _createActiveEffect(): Promise<unknown> {
const label = `New Effect`;
const createData = {

View file

@ -1,6 +1,6 @@
import { DS4Actor } from "../actor/actor";
import { DS4ActorDataType } from "../actor/actor-data";
import { DS4ItemDataType } from "./item-data";
import { DS4ItemDataType, DS4Talent } from "./item-data";
/**
* Extend the basic Item with some very simple modifications.
@ -12,10 +12,18 @@ export class DS4Item extends Item<DS4ItemDataType, DS4ActorDataType, DS4Actor> {
*/
prepareData(): void {
super.prepareData();
this.prepareDerivedData();
// Get the Item's data
// const itemData = this.data;
// const actorData = this.actor ? this.actor.data : {};
// const data = itemData.data;
}
prepareDerivedData(): void {
if (this.type === "talent") {
const data = this.data.data as DS4Talent;
data.rank.total = data.rank.base + data.rank.mod;
}
}
}

View file

@ -8,7 +8,6 @@
}
.attribute-value {
border: 2px groove $c-border-groove;
line-height: $default-input-height;
font-size: 1.5em;
text-align: center;
padding-left: 2px;
@ -17,6 +16,7 @@
input,
.attribute-value-total {
grid-column: span 2;
line-height: $default-input-height;
}
}
}
@ -32,7 +32,6 @@
.trait-value {
border: 2px groove $c-border-groove;
font-size: 1.5em;
line-height: $default-input-height;
text-align: center;
padding-left: 2px;
padding-right: 2px;
@ -40,6 +39,7 @@
input,
.trait-value-total {
grid-column: span 2;
line-height: $default-input-height;
}
}
}

View file

@ -1,13 +1,25 @@
.basic-properties {
flex: 0 0 100%;
gap: 2px;
.basic-property {
.basic-property-label {
display: grid;
align-content: end;
padding-left: 1px;
padding-right: 1px;
& > label {
font-weight: bold;
}
.basic-property-select {
& > select {
display: block;
width: 100%;
}
.input-divider {
text-align: center;
}
@include mark-invalid-or-disabled-input;
}
}

View file

@ -0,0 +1,28 @@
.progression {
.progression-entry {
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: flex-end;
align-items: center;
padding-right: 3px;
h2.progression-label {
font-family: $font-heading;
display: block;
height: 50px;
padding: 0px;
color: $c-light-grey;
border: none;
line-height: 50px;
margin: $header-top-margin 0;
text-align: right;
//flex: 0;
}
input.progression-value {
margin-left: 5px;
flex: 0 0 40px;
text-align: left;
}
}
}

View file

@ -9,7 +9,7 @@
.side-property {
margin: 2px 0;
display: grid;
grid-template-columns: 40% auto;
grid-template-columns: minmax(30%, auto) auto;
justify-content: left;
label {
@ -23,6 +23,8 @@
width: calc(100% - 2px);
}
@include mark-invalid-or-disabled-input;
input[type="checkbox"] {
width: auto;
height: 100%;
@ -31,6 +33,10 @@
}
}
.description {
height: 100%;
}
.sheet-body .tab .editor {
height: 100%;
}

View file

@ -43,7 +43,7 @@ header.sheet-header {
display: block;
height: 50px;
padding: 0px;
flex: 0 0 0;
flex: 0 0 auto;
color: $c-light-grey;
border: none;
line-height: 50px;

View file

@ -31,6 +31,7 @@
input {
border: 0;
padding: 0;
background-color: transparent;
}
input[type="checkbox"] {
@ -38,6 +39,8 @@
height: 100%;
margin: 0px;
}
@include mark-invalid-or-disabled-input;
}
.item-name {
@ -54,9 +57,6 @@
width: 2.5em;
padding: 0;
}
.item-num-val:invalid {
background-color: color.mix(lightcoral, $c-light-grey, 25%);
}
.item-description {
font-size: 75%;

View file

@ -0,0 +1,3 @@
.talent-ranks-equation {
text-align: center;
}

View file

@ -18,6 +18,9 @@
.flex1 {
flex: 1;
}
.flex125 {
flex: 1.25;
}
.flex15 {
flex: 1.5;
}
@ -51,6 +54,9 @@
.flex1 {
flex: 1;
}
.flex125 {
flex: 1.25;
}
.flex15 {
flex: 1.5;
}

View file

@ -28,8 +28,8 @@
}
.grid-6col {
grid-column: span 5 / span 5;
grid-template-columns: repeat(5, minmax(0, 1fr));
grid-column: span 6 / span 6;
grid-template-columns: repeat(6, minmax(0, 1fr));
}
.grid-7col {

View file

@ -1,5 +1,12 @@
.window-app {
font-family: $font-primary;
input[type="text"],
input[type="number"],
input[type="password"],
input[type="date"],
input[type="time"] {
width: 100%;
}
}
.rollable {

View file

@ -2,3 +2,4 @@ $c-white: #fff;
$c-black: #000;
$c-light-grey: #777;
$c-border-groove: #eeede0;
$c-invalid-input: rgba(lightcoral, 50%);

View file

@ -19,3 +19,12 @@
display: grid;
place-items: center;
}
@mixin mark-invalid-or-disabled-input {
input:invalid {
background-color: $c-invalid-input;
}
input:disabled {
background-color: transparent;
}
}

View file

@ -20,9 +20,9 @@
],
"gridDistance": 1,
"gridUnits": "m",
"primaryTokenAttribute": "combatValues.hitPoints.current",
"primaryTokenAttribute": "combatValues.hitPoints",
"url": "https://git.f3l.de/dungeonslayers/ds4",
"manifest": "https://git.f3l.de/dungeonslayers/ds4/-/blob/master/src/system.json",
"download": "https://git.f3l.de/dungeonslayers/ds4/-/archive/master/ds4-master.zip",
"manifest": "https://git.f3l.de/dungeonslayers/ds4/-/raw/master/src/system.json?inline=false",
"download": "https://git.f3l.de/dungeonslayers/ds4/-/jobs/artifacts/0.1.0/download?job=build",
"license": "MIT"
}

View file

@ -48,7 +48,7 @@
"hitPoints": {
"base": 0,
"mod": 0,
"current": 0
"value": 0
},
"defense": {
"base": 0,
@ -83,7 +83,8 @@
"race": "",
"class": "",
"heroClass": "",
"racialAbilities": ""
"racialAbilities": "",
"culture": ""
},
"progression": {
"level": 0,
@ -96,11 +97,26 @@
"total": 0,
"used": 0
}
},
"language": {
"languages": "",
"alphabets": ""
},
"profile": {
"gender": "",
"birthday": "",
"birthplace": "",
"age": 0,
"height": 0,
"hairColor": "",
"weight": 0,
"eyeColor": "",
"specialCharacteristics": ""
}
}
},
"Item": {
"types": ["weapon", "armor", "shield", "trinket", "equipment"],
"types": ["weapon", "armor", "shield", "trinket", "equipment", "talent", "racialAbility"],
"templates": {
"base": {
"description": ""
@ -137,6 +153,17 @@
},
"equipment": {
"templates": ["base", "physical"]
},
"talent": {
"templates": ["base"],
"rank": {
"base": 0,
"max": 0,
"mod": 0
}
},
"racialAbility": {
"templates": ["base"]
}
}
}

View file

@ -2,96 +2,66 @@
{{!-- Sheet Header --}}
<header class="sheet-header">
<img class="profile-img" src="{{actor.img}}" data-edit="img" title="{{actor.name}}" height="100" width="100" />
<div class="header-fields">
<div class="header-fields flexrow">
<h1 class="charname"><input name="name" type="text" value="{{actor.name}}" placeholder="Name" /></h1>
</div>
<div class="character-values">
{{!-- The grid classes are defined in scss/global/_grid.scss. To use, use both the "grid" and "grid-Ncol"
class where "N" can be any number from 1 to 12 and will create that number of columns. --}}
<div class="base-infos grid grid-3col">
{{!-- "flex-group-center" is also defined in the _grid.scss file and it will add a small amount of
padding, a border, and will center all of its child elements content and text. --}}
<div class="base-info flex-group-center">
<label for="data.baseInfo.race" class="base-info-label">{{config.baseInfo.race}}</label>
<div class="base-info-content flexrow flex-center flex-between">
<input type="text" name="data.baseInfo.race" value="{{data.baseInfo.race}}"
data-dtype="String" />
{{> systems/ds4/templates/actor/partials/character-progression.hbs}}
<div class="flexrow basic-properties">
<div class="basic-property">
<label class="basic-property-label" for="data.baseInfo.race">{{config.baseInfo.race}}</label>
<input type="text" name="data.baseInfo.race" value="{{data.baseInfo.race}}" data-dtype="String" />
</div>
<div class="basic-property">
<label class="basic-property-label" for="data.baseInfo.culture">{{config.baseInfo.culture}}</label>
<input type="text" name="data.baseInfo.culture" value="{{data.baseInfo.culture}}"
data-dtype="String" />
</div>
<div class="basic-property flex125">
<label class="basic-property-label"
for="data.progression.progressPoints.used">{{config.progression.progressPoints}}</label>
<div class="flexrow">
<input type="number" name="data.progression.progressPoints.used"
value="{{data.progression.progressPoints.used}}" data-dtype="Number" /><span
class="input-divider"> /
</span><input type="number" name="data.progression.progressPoints.total"
value="{{data.progression.progressPoints.total}}" data-dtype="Number" />
</div>
</div>
<div class="base-info flex-group-center">
<div class="grid grid-3col">
<div class="base-info flex-group-center">
<label for="data.progression.level"
class="base-info-label">{{config.progression.level}}</label>
<div class="base-info-content flexrow flex-center flex-between">
<input type="text" name="data.progression.level" value="{{data.progression.level}}"
data-dtype="Number" />
</div>
</div>
<div class="base-info flex-group-center">
<label for="data.progression.progressPoints"
class="base-info-label">{{config.progression.progressPoints}}</label>
<div class="base-info-content flexrow flex-center flex-between">
<input type="text" name="data.progression.progressPoints.used"
value="{{data.progression.progressPoints.used}}" data-dtype="Number" /><span> /
</span><input type="text" name="data.progression.progressPoints.total"
value="{{data.progression.progressPoints.total}}" data-dtype="Number" />
</div>
</div>
<div class="base-info flex-group-center">
<label for="data.progression.talentPoints"
class="base-info-label">{{config.progression.talentPoints}}</label>
<div class="base-info-content flexrow flex-center flex-between">
<input type="text" name="data.progression.talentPoints.used"
value="{{data.progression.talentPoints.used}}" data-dtype="Number" /><span> /
</span><input type="text" name="data.progression.talentPoints.total"
value="{{data.progression.talentPoints.total}}" data-dtype="Number" />
</div>
</div>
<div class="basic-property flex125">
<label class="basic-property-label"
for="data.progression.talentPoints.used">{{config.progression.talentPoints}}</label>
<div class="flexrow">
<input type="number" name="data.progression.talentPoints.used"
value="{{data.progression.talentPoints.used}}" data-dtype="Number" /><span
class="input-divider"> /
</span><input type="number" name="data.progression.talentPoints.total"
value="{{data.progression.talentPoints.total}}" data-dtype="Number" />
</div>
</div>
<div class="base-info flex-group-center">
<label for="data.baseInfo.class" class="base-info-label">{{config.baseInfo.class}}</label>
<div class="base-info-content flexrow flex-center flex-between">
<input type="text" name="data.baseInfo.class" value="{{data.baseInfo.class}}"
data-dtype="String" />
</div>
<div class="basic-property">
<label class="basic-property-label" for="data.baseInfo.class">{{config.baseInfo.class}}</label>
<input type="text" name="data.baseInfo.class" value="{{data.baseInfo.class}}" data-dtype="String" />
</div>
<div class="base-info flex-group-center">
<label for="data.baseInfo.racialAbilities"
class="base-info-label">{{config.baseInfo.racialAbilities}}</label>
<div class="base-info-content flexrow flex-center flex-between">
<input type="text" name="data.baseInfo.racialAbilities"
value="{{data.baseInfo.racialAbilities}}" data-dtype="String" />
</div>
</div>
<div class="base-info flex-group-center">
<label for="data.progression.experiencePoints"
class="base-info-label">{{config.progression.experiencePoints}}</label>
<div class="base-info-content flexrow flex-center flex-between">
<input type="text" name="data.progression.experiencePoints"
value="{{data.progression.experiencePoints}}" data-dtype="Number" />
</div>
</div>
<div class="base-info flex-group-center">
<label for="data.baseInfo.heroClass" class="base-info-label">{{config.baseInfo.heroClass}}</label>
<div class="base-info-content flexrow flex-center flex-between">
<input type="text" name="data.baseInfo.heroClass" value="{{data.baseInfo.heroClass}}"
data-dtype="String" />
</div>
<div class="basic-property">
<label class="basic-property-label"
for="data.baseInfo.heroClass">{{config.baseInfo.heroClass}}</label>
<input type="text" name="data.baseInfo.heroClass" value="{{data.baseInfo.heroClass}}"
data-dtype="String" />
</div>
</div>
</div>
<div class="character-values">
{{> systems/ds4/templates/actor/partials/attributes-traits.hbs}}
{{> systems/ds4/templates/actor/partials/combat-values.hbs}}
</div>
</header>
{{!-- Sheet Tab Navigation --}}
<nav class="sheet-tabs tabs" data-group="primary">
<a class="item" data-tab="description">Description</a>
<a class="item" data-tab="items">Items</a>
<a class="item" data-tab="description">{{localize 'DS4.HeadingDescription'}}</a>
<a class="item" data-tab="talents">{{localize 'DS4.HeadingTalents'}}</a>
<a class="item" data-tab="profile">{{localize "DS4.HeadingProfile"}}</a>
<a class="item" data-tab="inventory">{{localize 'DS4.HeadingInventory'}}</a>
</nav>
{{!-- Sheet Body --}}
@ -101,6 +71,12 @@
{{editor content=data.biography target="data.biography" button=true owner=owner editable=editable}}
</div>
{{! Profile Tab --}}
{{> systems/ds4/templates/actor/partials/profile.hbs}}
{{!-- Talents Tab --}}
{{> systems/ds4/templates/actor/partials/talents-overview.hbs}}
{{!-- Items Tab --}}
{{> systems/ds4/templates/actor/partials/items-overview.hbs}}
</section>

View file

@ -0,0 +1,15 @@
<div class="progression flexrow">
<div class="progression-entry">
<h2 class="progression-label"><label for="data.progression.level">{{config.progression.level}}</label>
</h2>
<input class="progression-value" type="number" name="data.progression.level" value="{{data.progression.level}}"
data-dtype="Number" />
</div>
<div class="progression-entry">
<h2 class="progression-label"><label
for="data.progression.experiencePoints">{{config.progression.experiencePoints}}</label>
</h2>
<input class="progression-value" type="number" name="data.progression.experiencePoints"
value="{{data.progression.experiencePoints}}" data-dtype="Number" />
</div>
</div>

View file

@ -5,29 +5,6 @@
{{!-- INLINE PARTIAL DEFINITIONS --}}
{{!-- ======================================================================== --}}
{{!--
!-- Render an "add" button for a given data type.
!--
!-- @param datType: hand over the dataType to the partial as hash parameter
--}}
{{#*inline "addItemButton"}}
<div class="item-controls">
<a class="item-control item-create" title="Create item" data-type="{{dataType}}">
<i class="fas fa-plus"></i>
{{localize 'DS4.UserInteractionAddItem'}}</a>
</div>
{{/inline}}
{{!--
!-- Render a group of an "edit" and a "delete" button for the current item.
!-- The current item is defined by the data-item-id HTML property of the parent li element.
--}}
{{#*inline "itemControlButtons"}}
<div class="item-controls">
<a class="item-control item-edit" title="Edit Item"><i class="fas fa-edit"></i></a>
<a class="item-control item-delete" title="Delete Item"><i class="fas fa-trash"></i></a>
</div>
{{/inline}}
{{!--
!-- Render a header row for a given data type.
@ -55,9 +32,9 @@
{{!-- item type specifics --}}
{{> @partial-block }}
{{!-- description --}}
<div class="flex4">{{localize 'DS4.Description'}}</div>
<div class="flex4">{{localize 'DS4.HeadingDescription'}}</div>
{{!-- add button --}}
{{> addItemButton dataType=dataType }}
{{> systems/ds4/templates/actor/partials/overview-add-button.hbs dataType=dataType }}
</li>
{{/inline}}
@ -94,7 +71,7 @@
{{!-- description --}}
<div class="flex4 item-description">{{{item.data.data.description}}}</div>
{{!-- control buttons --}}
{{> itemControlButtons}}
{{> systems/ds4/templates/actor/partials/overview-control-buttons.hbs }}
</li>
{{/inline}}
@ -102,10 +79,10 @@
{{!-- ======================================================================== --}}
<div class="tab items" data-group="primary" data-tab="items">
<div class="tab inventory" data-group="primary" data-tab="inventory">
{{!-- WEAPONS --}}
<h4 class="items-list-title">{{localize 'DS4.ItemTypeWeapon'}}</h4>
<h4 class="items-list-title">{{localize 'DS4.ItemTypeWeaponPlural'}}</h4>
<ol class="items-list">
{{#> itemListHeader dataType='weapon'}}
<div class="flex05 item-image" title="{{localize 'DS4.AttackType'}}">{{localize 'DS4.AttackTypeAbbr'}}</div>
@ -129,7 +106,7 @@
</ol>
{{!-- ARMOR --}}
<h4 class="items-list-title">{{localize 'DS4.ItemTypeArmor'}}</h4>
<h4 class="items-list-title">{{localize 'DS4.ItemTypeArmorPlural'}}</h4>
<ol class="items-list">
{{#> itemListHeader dataType='armor'}}
<div title="{{localize 'DS4.ArmorMaterialType'}}">{{localize 'DS4.ArmorMaterialTypeAbbr'}}</div>
@ -153,7 +130,7 @@
{{!-- SHIELD --}}
<h4 class="items-list-title">{{localize 'DS4.ItemTypeShield'}}</h4> {{!-- SPECIFIC --}}
<h4 class="items-list-title">{{localize 'DS4.ItemTypeShieldPlural'}}</h4> {{!-- SPECIFIC --}}
<ol class="items-list">
{{#> itemListHeader dataType='shield' }}
<div class="flex05 item-num-val" title="{{localize 'DS4.ArmorValue'}}">
@ -168,7 +145,7 @@
</ol>
{{!-- TRINKET --}}
<h4 class="items-list-title">{{localize 'DS4.ItemTypeTrinket'}}</h4>
<h4 class="items-list-title">{{localize 'DS4.ItemTypeTrinketPlural'}}</h4>
<ol class="items-list">
{{#> itemListHeader dataType='trinket'}}
<div class="flex2">{{localize 'DS4.StorageLocation'}}</div>
@ -182,7 +159,7 @@
</ol>
{{!-- EQUIPMENT --}}
<h4 class="items-list-title">{{localize 'DS4.ItemTypeEquipment'}}</h4>
<h4 class="items-list-title">{{localize 'DS4.ItemTypeEquipmentPlural'}}</h4>
<ol class="items-list">
{{#> itemListHeader dataType='equipment'}}
<div class="flex2">{{localize 'DS4.StorageLocation'}}</div>

View file

@ -0,0 +1,11 @@
{{!
!-- Render an "add" button for adding an item of given data type.
!--
!-- @param datType: hand over the dataType to the partial as hash parameter
}}
<div class="item-controls">
<a class="item-control item-create" title="Create item" data-type="{{dataType}}">
<i class="fas fa-plus"></i>
{{localize "DS4.UserInteractionAddItem"}}
</a>
</div>

View file

@ -0,0 +1,8 @@
{{!--
!-- Render a group of an "edit" and a "delete" button for the current item.
!-- The current item is defined by the data-item-id HTML property of the parent li element.
--}}
<div class="item-controls">
<a class="item-control item-edit" title="Edit Item"><i class="fas fa-edit"></i></a>
<a class="item-control item-delete" title="Delete Item"><i class="fas fa-trash"></i></a>
</div>

View file

@ -0,0 +1,13 @@
<div class="tab profile" data-group="primary" data-tab="profile">
<div class="grid grid-2col">
{{#each data.profile as |profile-data-value profile-data-key|}}
<div class="profile-entry">
<label for="data.profile.{{profile-data-key}}">
{{lookup ../config.profile profile-data-key}}
</label>
<input type="text" name="data.profile.{{profile-data-key}}" value="{{profile-data-value}}"
data-dtype="{{lookup ../config/profileDTypes profile-data-key}}" />
</div>
{{/each}}
</div>
</div>

View file

@ -0,0 +1,123 @@
{{!-- ======================================================================== --}}
{{!-- INLINE PARTIAL DEFINITIONS --}}
{{!-- ======================================================================== --}}
{{!-- TODO: remove duplicate add and delete button definition --}}
{{!--
!-- Render an input element for a rank value property of an item.
!--
!-- @param item: the item
!-- @param property: the key of the property in item.data.data (if 'base', the max value is set automatically)
!-- @param disabled: if given, is placed plainly into the input as HTML property;
!-- meant to be set to "disabled" to disable the input element
--}}
{{#*inline "talentRankValue"}}
<input class="item-num-val item-change" data-dtype="Number" type="number" min="0" step="1" {{#if (eq property 'base' )
}}max="{{item.data.data.rank.max}}" {{/if}} {{disabled}} data-property="data.rank.{{property}}"
value="{{lookup item.data.data.rank property}}" title="{{localize localizeString}}" />
{{/inline}}
{{!--
!-- Render a talent list row from a given item.
!-- It is a flexbox with a child for each item value of interest.
!-- The partial assumes a variable item to be given in the context.
!--
!-- @param item: hand over the item to the partial as hash parameter
!-- @param partial-block: hand over custom children of the flexbox in the partial block.
--}}
{{#*inline "talentListEntry"}}
<li class="item flexrow" data-item-id="{{item._id}}">
{{!-- image --}}
<div class="flex05 item-image">
<img src="{{item.img}}" title="{{item.name}}" width="24" height="24" />
</div>
{{!-- name --}}
<input class="flex2 item-name item-change" type="text" value="{{item.name}}" data-dtype="String"
data-property="name" title="{{localize 'DS4.ItemName'}}">
<div class="flex3 flexrow talent-ranks-equation">
{{!-- acquired rank --}}
{{> talentRankValue item=item property='base' localizeString='DS4.TalentRankBase'}}
<span> ( of </span>
{{!-- maximum acquirable rank --}}
{{> talentRankValue item=item property='max' localizeString='DS4.TalentRankMax'}}
<span>) + </span>
{{!-- additional ranks --}}
{{> talentRankValue item=item property='mod' localizeString='DS4.TalentRankMod'}}
<span> = </span>
{{!-- derived total rank --}}
{{> talentRankValue item=item property='total' localizeString='DS4.TalentRankTotal' disabled='disabled'}}
</div>
{{!-- description --}}
<div class="flex4 item-description">{{{item.data.data.description}}}</div>
{{!-- control buttons --}}
{{> systems/ds4/templates/actor/partials/overview-control-buttons.hbs }}
</li>
{{/inline}}
{{!--
!-- Render a racial ability list row from a given item.
!-- It is a flexbox with a child for each item value of interest.
!-- The partial assumes a variable item to be given in the context.
!--
!-- @param item: hand over the item to the partial as hash parameter
!-- @param partial-block: hand over custom children of the flexbox in the partial block.
--}}
{{#*inline "racialAbilityListEntry"}}
<li class="item flexrow" data-item-id="{{item._id}}">
{{!-- image --}}
<div class="flex05 item-image">
<img src="{{item.img}}" title="{{item.name}}" width="24" height="24" />
</div>
{{!-- name --}}
<input class="flex1 item-name item-change" type="text" value="{{item.name}}" data-dtype="String"
data-property="name" title="{{localize 'DS4.ItemName'}}">
{{!-- description --}}
<div class="flex3 item-description">{{{item.data.data.description}}}</div>
{{!-- control buttons --}}
{{> systems/ds4/templates/actor/partials/overview-control-buttons.hbs }}
</li>
{{/inline}}
{{!-- ======================================================================== --}}
<div class="tab items" data-group="primary" data-tab="talents">
<h4 class="items-list-title">{{localize 'DS4.ItemTypeTalentPlural'}}</h4>
<ol class="items-list">
<li class="item flexrow item-header">
{{!-- image --}}
<div class="flex05 item-image"></div>
{{!-- name --}}
<div class="flex2 item-name">{{localize 'DS4.ItemName'}}</div>
{{!-- rank info --}}
<div class="flex3">{{localize 'DS4.TalentRank'}}</div>
{{!-- description --}}
<div class="flex4">{{localize 'DS4.HeadingDescription'}}</div>
{{!-- add button --}}
{{> systems/ds4/templates/actor/partials/overview-add-button.hbs dataType='talent' }}
</li>
{{#each itemsByType.talent as |item id|}}
{{> talentListEntry item=item}}
{{/each}}
</ol>
<h4 class="items-list-title">{{localize 'DS4.ItemTypeRacialAbilityPlural'}}</h4>
<ol class="items-list">
<li class="item flexrow item-header">
{{!-- image --}}
<div class="flex05 item-image"></div>
{{!-- name --}}
<div class="flex1 item-name">{{localize 'DS4.ItemName'}}</div>
{{!-- description --}}
<div class="flex3">{{localize 'DS4.HeadingDescription'}}</div>
{{!-- add button --}}
{{> systems/ds4/templates/actor/partials/overview-add-button.hbs dataType='racialAbility' }}
</li>
{{#each itemsByType.racialAbility as |item id|}}
{{> racialAbilityListEntry item=item}}
{{/each}}
</ol>
</div>

View file

@ -6,8 +6,8 @@
<h2 class="item-type">{{localize (lookup config.itemTypes item.type)}}</h2>
<div class="grid grid-3col basic-properties">
<div class="basic-property">
<label class="basic-property-label">{{localize "DS4.ArmorType"}}</label>
<select class="basic-property-select" name="data.armorType" data-type="String">
<label>{{localize "DS4.ArmorType"}}</label>
<select name="data.armorType" data-type="String">
{{#select data.armorType}}
{{#each config.armorTypes as |value key|}}
<option value="{{key}}">{{value}}</option>
@ -16,8 +16,8 @@
</select>
</div>
<div class="basic-property">
<label class="basic-property-label">{{localize "DS4.ArmorMaterialType"}}</label>
<select class="basic-property-select" name="data.armorMaterialType" data-type="String">
<label>{{localize "DS4.ArmorMaterialType"}}</label>
<select name="data.armorMaterialType" data-type="String">
{{#select data.armorMaterialType}}
{{#each config.armorMaterialTypes as |value key|}}
<option value="{{key}}">{{value}}</option>
@ -26,8 +26,8 @@
</select>
</div>
<div class="basic-property">
<label class="basic-property-label">{{localize "DS4.ArmorValue"}}</label>
<input class="basic-property-input" type="text" name="data.armorValue" value="{{data.armorValue}}"
<label>{{localize "DS4.ArmorValue"}}</label>
<input type="text" name="data.armorValue" value="{{data.armorValue}}"
placeholder="0" data-dtype="Number" />
</div>
</div>

View file

@ -2,9 +2,11 @@
{{!-- Sheet Tab Navigation --}}
<nav class="sheet-tabs tabs" data-group="primary">
<a class="item" data-tab="description">{{localize "DS4.Description"}}</a>
<a class="item" data-tab="effects">{{localize "DS4.Effects"}}</a>
<a class="item" data-tab="details">{{localize "DS4.Details"}}</a>
<a class="item" data-tab="description">{{localize "DS4.HeadingDescription"}}</a>
<a class="item" data-tab="effects">{{localize "DS4.HeadingEffects"}}</a>
{{#if isPhysical}}
<a class="item" data-tab="details">{{localize "DS4.HeadingDetails"}}</a>
{{/if}}
</nav>
{{!-- Sheet Body --}}
@ -13,10 +15,12 @@
{{!-- Description Tab --}}
{{> systems/ds4/templates/item/partials/description.hbs}}
{{!-- Details Tab --}}
{{> systems/ds4/templates/item/partials/details.hbs}}
{{!-- Effects Tab --}}
{{> systems/ds4/templates/item/partials/effects.hbs}}
{{#if isPhysical}}
{{!-- Details Tab --}}
{{> systems/ds4/templates/item/partials/details.hbs}}
{{/if}}
</section>

View file

@ -11,19 +11,21 @@
<a class="entity-link" draggable="true" data-entity="Actor" data-id="{{actor._id}}"><i
class="fas fa-user"></i>{{actor.name}}</a>
</div>
<div class="side-property">
<label for="data.quantity">{{localize 'DS4.Quantity'}}</label>
<input type="number" min="0" step="1" data-dtype="Number" name="data.quantity" value="{{data.quantity}}" />
</div>
<div class="side-property">
<label for="data.storageLocation">{{localize 'DS4.StorageLocation'}}</label>
<input type="text" data-dtype="String" name="data.storageLocation" value="{{data.storageLocation}}" />
</div>
{{#if isPhysical}}
<div class="side-property">
<label for="data.quantity">{{localize 'DS4.Quantity'}}</label>
<input type="number" min="0" step="1" data-dtype="Number" name="data.quantity" value="{{data.quantity}}" />
</div>
<div class="side-property">
<label for="data.storageLocation">{{localize 'DS4.StorageLocation'}}</label>
<input type="text" data-dtype="String" name="data.storageLocation" value="{{data.storageLocation}}" />
</div>
{{/if}}
{{else}}
{{localize "DS4.NotOwned"}}
<span>{{localize "DS4.NotOwned"}}</span>
{{/if}}
</div>
<div class="description">
<div class="description" title="{{localize 'DS4.HeadingDescription'}}">
{{editor content=data.description target="data.description" button=true owner=owner editable=editable}}
</div>
</div>

View file

@ -5,16 +5,16 @@
<div class="effect-image"></div>
<div class="effect-name">Name</div>
<div class="effect-controls">
<a class="effect-control effect-create" title="Create Effect"><i
class="fas fa-plus"></i> Add effect</a>
<a class="effect-control" data-action="create" title="Create Effect"><i class="fas fa-plus"></i> Add
effect</a>
</div>
</li>
{{#each item.effects as |effect id|}}
<li class="effect flexrow" data-effect-id="{{effect._id}}">
<h4 class="effect-name">{{effect.label}}</h4>
<div class="effect-controls">
<a class="effect-control effect-edit" title="Edit Effect"><i class="fas fa-edit"></i></a>
<a class="effect-control effect-delete" title="Delete Effect"><i class="fas fa-trash"></i></a>
<a class="effect-control" data-action="edit" title="Edit Effect"><i class="fas fa-edit"></i></a>
<a class="effect-control" data-action="delete" title="Delete Effect"><i class="fas fa-trash"></i></a>
</div>
</li>
{{/each}}

View file

@ -0,0 +1,13 @@
<form class="{{cssClass}}" autocomplete="off">
<header class="sheet-header">
<img class="profile-img" src="{{item.img}}" data-edit="img" title="{{item.name}}" />
<div class="header-fields flexrow">
<h1 class="charname"><input name="name" type="text" value="{{item.name}}" placeholder="Name" /></h1>
<h2 class="item-type">{{localize (lookup config.itemTypes item.type)}}</h2>
</div>
</header>
{{!-- Common Item body --}}
{{> systems/ds4/templates/item/partials/body.hbs}}
</form>

View file

@ -6,8 +6,8 @@
<h2 class="item-type">{{localize (lookup config.itemTypes item.type)}}</h2>
<div class="grid grid-1col basic-properties">
<div class="basic-property">
<label class="basic-property-label">{{localize "DS4.ArmorValue"}}</label>
<input class="basic-property-input" type="text" name="data.armorValue" value="{{data.armorValue}}"
<label>{{localize "DS4.ArmorValue"}}</label>
<input type="text" name="data.armorValue" value="{{data.armorValue}}"
placeholder="0" data-dtype="Number" />
</div>
</div>

View file

@ -0,0 +1,37 @@
{{!-- ======================================================================== --}}
{{!-- INLINE PARTIAL DEFINITIONS --}}
{{!-- ======================================================================== --}}
{{#*inline "talentRankBasicProperty" }}
<div class="basic-property">
<label for="data.rank.{{property}}">{{localize localizeString}}</label>
<input type="number" min="0" step="1" data-dtype="Number" {{disabled}}
{{#if (eq property 'base') }}max="{{data.rank.max}}"{{/if}}
name="data.rank.{{property}}" value="{{lookup data.rank property}}" />
</div>
{{/inline}}
{{!-- ======================================================================== --}}
<form class="{{cssClass}}" autocomplete="off">
<header class="sheet-header">
<img class="profile-img" src="{{item.img}}" data-edit="img" title="{{item.name}}" />
<div class="header-fields flexrow">
<h1 class="charname"><input name="name" type="text" value="{{item.name}}" placeholder="Name" /></h1>
<h2 class="item-type">{{localize (lookup config.itemTypes item.type)}}</h2>
<div class="grid grid-4col basic-properties">
{{> talentRankBasicProperty data=data property='base' localizeString='DS4.TalentRankBase' }}
{{> talentRankBasicProperty data=data property='max' localizeString='DS4.TalentRankMax'}}
{{> talentRankBasicProperty data=data property='mod' localizeString='DS4.TalentRankMod'}}
{{> talentRankBasicProperty data=data property='total' localizeString='DS4.TalentRankTotal' disabled='disabled'}}
</div>
</div>
</header>
{{!-- Common Item body --}}
{{> systems/ds4/templates/item/partials/body.hbs}}
</form>

View file

@ -6,8 +6,8 @@
<h2 class="item-type">{{localize (lookup config.itemTypes item.type)}}</h2>
<div class="grid grid-3col basic-properties">
<div class="basic-property">
<label class="basic-property-label">{{localize "DS4.AttackType"}}</label>
<select class="basic-property-select" name="data.attackType" data-type="String">
<label>{{localize "DS4.AttackType"}}</label>
<select name="data.attackType" data-type="String">
{{#select data.attackType}}
{{#each config.attackTypes as |value key|}}
<option value="{{key}}">{{value}}</option>
@ -16,13 +16,13 @@
</select>
</div>
<div class="basic-property">
<label class="basic-property-label">{{localize "DS4.WeaponBonus"}}</label>
<input class="basic-property-input" type="number" name="data.weaponBonus" value="{{data.weaponBonus}}"
<label>{{localize "DS4.WeaponBonus"}}</label>
<input type="number" name="data.weaponBonus" value="{{data.weaponBonus}}"
placeholder="0" data-dtype="Number" />
</div>
<div class="basic-property">
<label class="basic-property-label">{{localize "DS4.OpponentDefense"}}</label>
<input class="basic-property-input" type="number" name="data.opponentDefense"
<label>{{localize "DS4.OpponentDefense"}}</label>
<input type="number" name="data.opponentDefense"
value="{{data.opponentDefense}}" placeholder="0" data-dtype="Number" />
</div>
</div>