feat: wip work on making classes configurable

This commit is contained in:
Johannes Loher 2022-02-16 01:32:50 +01:00
parent d35b80f393
commit cc7cb4a01d
24 changed files with 426 additions and 93 deletions

View file

@ -209,6 +209,28 @@
"DS4.CharacterProgressionProgressPoints": "Lernpunkte", "DS4.CharacterProgressionProgressPoints": "Lernpunkte",
"DS4.CharacterSlayerPoints": "Slayerpunkte", "DS4.CharacterSlayerPoints": "Slayerpunkte",
"DS4.CharacterSlayerPointsAbbr": "SP", "DS4.CharacterSlayerPointsAbbr": "SP",
"DS4.ClassNone": "Keine",
"DS4.ClassFighter": "Krieger",
"DS4.ClassScout": "Späher",
"DS4.ClassHealer": "Heiler",
"DS4.ClassWizard": "Zauberer",
"DS4.ClassSorcerer": "Schwarzmagier",
"DS4.HeroClassNone": "Keine",
"DS4.HeroClassBerserker": "Berserker",
"DS4.HeroClassWeaponMaster": "Waffenmeister",
"DS4.HeroClassPaladin": "Paladin",
"DS4.HeroClassAssassin": "Attentäter",
"DS4.HeroClassRanger": "Waldläufer",
"DS4.HeroClassRogue": "Meisterdieb",
"DS4.HeroClassCleric": "Kleriker",
"DS4.HeroClassDruid": "Druide",
"DS4.HeroClassMonk": "Kampfmönch",
"DS4.HeroClassArchmage": "Erzmagier",
"DS4.HeroClassElementalist": "Elementarist",
"DS4.HeroClassBattleMage": "Kriegszauberer",
"DS4.HeroClassBloodMage": "Blutmagier",
"DS4.HeroClassDemonologist": "Dämonologe",
"DS4.HeroClassNecromancer": "Nekromant",
"DS4.TalentRank": "Rang", "DS4.TalentRank": "Rang",
"DS4.SortByTalentRank": "Nach Rang sortieren", "DS4.SortByTalentRank": "Nach Rang sortieren",
"DS4.TalentRankBase": "Erworben", "DS4.TalentRankBase": "Erworben",
@ -314,6 +336,9 @@
"DS4.SettingUseSlayingDiceForAutomatedChecksHint": "Benutze Slayende Würfel bei automatisierten Proben.", "DS4.SettingUseSlayingDiceForAutomatedChecksHint": "Benutze Slayende Würfel bei automatisierten Proben.",
"DS4.SettingShowSlayerPointsName": "Slayerpunkte", "DS4.SettingShowSlayerPointsName": "Slayerpunkte",
"DS4.SettingShowSlayerPointsHint": "Zeige Slayerpunkte im Charakterbogen an.", "DS4.SettingShowSlayerPointsHint": "Zeige Slayerpunkte im Charakterbogen an.",
"DS4.MenuClassesName": "Klassenkonfiguration",
"DS4.MenuClassesHint": "Konfiguriere welche Klassen und Heldenklassen verwendet werden können.",
"DS4.MenuClassesLabel": "Klassen Konfigurieren",
"DS4.Checks": "Proben", "DS4.Checks": "Proben",
"DS4.ChecksAppraise": "Schätzen", "DS4.ChecksAppraise": "Schätzen",
"DS4.ChecksChangeSpell": "Zauber Wechseln", "DS4.ChecksChangeSpell": "Zauber Wechseln",

View file

@ -209,6 +209,28 @@
"DS4.CharacterProgressionProgressPoints": "Progress Points", "DS4.CharacterProgressionProgressPoints": "Progress Points",
"DS4.CharacterSlayerPoints": "Slayer Points", "DS4.CharacterSlayerPoints": "Slayer Points",
"DS4.CharacterSlayerPointsAbbr": "SP", "DS4.CharacterSlayerPointsAbbr": "SP",
"DS4.ClassNone": "None",
"DS4.ClassFighter": "Fighter",
"DS4.ClassScout": "Scout",
"DS4.ClassHealer": "Healer",
"DS4.ClassWizard": "Wizard",
"DS4.ClassSorcerer": "Sorcerer",
"DS4.HeroClassNone": "None",
"DS4.HeroClassBerserker": "Berserker",
"DS4.HeroClassWeaponMaster": "Weapon Master",
"DS4.HeroClassPaladin": "Paladin",
"DS4.HeroClassAssassin": "Assasin",
"DS4.HeroClassRanger": "Ranger",
"DS4.HeroClassRogue": "Rogue",
"DS4.HeroClassCleric": "Cleric",
"DS4.HeroClassDruid": "Druid",
"DS4.HeroClassMonk": "Monk",
"DS4.HeroClassArchmage": "Archmage",
"DS4.HeroClassElementalist": "Elementalist",
"DS4.HeroClassBattleMage": "Battle Mage",
"DS4.HeroClassBloodMage": "Blood Mage",
"DS4.HeroClassDemonologist": "Demonologist",
"DS4.HeroClassNecromancer": "Necromancer",
"DS4.TalentRank": "Rank", "DS4.TalentRank": "Rank",
"DS4.SortByTalentRank": "Sort by Rank", "DS4.SortByTalentRank": "Sort by Rank",
"DS4.TalentRankBase": "Acquired", "DS4.TalentRankBase": "Acquired",
@ -314,6 +336,9 @@
"DS4.SettingUseSlayingDiceForAutomatedChecksHint": "Use Slaying Dice for automated checks.", "DS4.SettingUseSlayingDiceForAutomatedChecksHint": "Use Slaying Dice for automated checks.",
"DS4.SettingShowSlayerPointsName": "Slayer Points", "DS4.SettingShowSlayerPointsName": "Slayer Points",
"DS4.SettingShowSlayerPointsHint": "Show Slayer Points in the character sheet.", "DS4.SettingShowSlayerPointsHint": "Show Slayer Points in the character sheet.",
"DS4.MenuClassesName": "Class Configuration",
"DS4.MenuClassesHint": "Configure which classes and hero classes can be used.",
"DS4.MenuClassesLabel": "Configure Classes",
"DS4.Checks": "Checks", "DS4.Checks": "Checks",
"DS4.ChecksAppraise": "Appraise", "DS4.ChecksAppraise": "Appraise",
"DS4.ChecksChangeSpell": "Change Spell", "DS4.ChecksChangeSpell": "Change Spell",

View file

@ -60,6 +60,7 @@ const config = {
rename: (name, extension) => `${name.replace(".json", ".db")}.${extension}`, rename: (name, extension) => `${name.replace(".json", ".db")}.${extension}`,
}, },
], ],
verbose: true,
}), }),
isProduction && terser({ ecma: 2020, keep_fnames: true }), isProduction && terser({ ecma: 2020, keep_fnames: true }),
], ],

View file

@ -15,8 +15,8 @@
&__img { &__img {
border: none; border: none;
cursor: pointer; cursor: pointer;
height: 100px; height: 125px;
width: 100px; width: 125px;
} }
&__data { &__data {

View file

@ -11,11 +11,17 @@
.ds4-actor-properties { .ds4-actor-properties {
@include mixins.mark-invalid-or-disabled-input; @include mixins.mark-invalid-or-disabled-input;
display: flex; column-gap: 0.25em;
gap: 0.25em; display: grid;
grid-template-columns: repeat(4, 1fr);
&__property { &__property {
flex: 1; text-align: center;
width: 100%;
&--wide {
grid-column: 1 / -1;
}
} }
&__property-label { &__property-label {

View file

@ -9,7 +9,7 @@
@use "../../utils/mixins"; @use "../../utils/mixins";
@use "../../utils/variables"; @use "../../utils/variables";
.ds4-actor-progression { .ds4-actor-resources {
@include mixins.mark-invalid-or-disabled-input; @include mixins.mark-invalid-or-disabled-input;
display: flex; display: flex;
gap: 0.5em; gap: 0.5em;

View file

@ -5,6 +5,6 @@
*/ */
.ds4-actor-sheet { .ds4-actor-sheet {
min-height: 625px; min-height: 655px;
min-width: 650px; min-width: 650px;
} }

View file

@ -23,8 +23,8 @@
// actor // actor
@use "components/actor/actor_header"; @use "components/actor/actor_header";
@use "components/actor/actor_progression";
@use "components/actor/actor_properties"; @use "components/actor/actor_properties";
@use "components/actor/actor_resources";
@use "components/actor/actor_sheet"; @use "components/actor/actor_sheet";
@use "components/actor/biography"; @use "components/actor/biography";
@use "components/actor/check"; @use "components/actor/check";

View file

@ -25,7 +25,7 @@ export class DS4ActorSheet extends ActorSheet<ActorSheet.Options, DS4ActorSheetD
static get defaultOptions(): ActorSheet.Options { static get defaultOptions(): ActorSheet.Options {
return foundry.utils.mergeObject(super.defaultOptions, { return foundry.utils.mergeObject(super.defaultOptions, {
classes: ["sheet", "ds4-actor-sheet"], classes: ["sheet", "ds4-actor-sheet"],
height: 625, height: 655,
scrollY: [".ds4-sheet-body"], scrollY: [".ds4-sheet-body"],
tabs: [{ navSelector: ".ds4-sheet-tab-nav", contentSelector: ".ds4-sheet-body", initial: "values" }], tabs: [{ navSelector: ".ds4-sheet-tab-nav", contentSelector: ".ds4-sheet-body", initial: "values" }],
dragDrop: [ dragDrop: [
@ -61,12 +61,14 @@ export class DS4ActorSheet extends ActorSheet<ActorSheet.Options, DS4ActorSheetD
}); });
const enrichedEffects = await Promise.all(enrichedEffectPromises); const enrichedEffects = await Promise.all(enrichedEffectPromises);
const settings = getDS4Settings();
const data = { const data = {
...this.addTooltipsToData(await super.getData()), ...this.addTooltipsToData(await super.getData()),
config: DS4, config: DS4,
itemsByType, itemsByType,
enrichedEffects, enrichedEffects,
settings: getDS4Settings(), settings,
}; };
return data; return data;
} }
@ -409,7 +411,7 @@ export class DS4ActorSheet extends ActorSheet<ActorSheet.Options, DS4ActorSheetD
} }
} }
interface DS4ActorSheetData extends ActorSheet.Data { export interface DS4ActorSheetData extends ActorSheet.Data {
config: typeof DS4; config: typeof DS4;
itemsByType: Record<string, foundry.data.ItemData[]>; itemsByType: Record<string, foundry.data.ItemData[]>;
enrichedEffects: EnrichedActiveEffectDataSource[]; enrichedEffects: EnrichedActiveEffectDataSource[];

View file

@ -2,16 +2,51 @@
// //
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
import { DS4ActorSheet } from "../actor-sheet"; import { DS4ActorSheet, DS4ActorSheetData } from "../actor-sheet";
import type { DS4Actor } from "../actor";
import type { Classes, HeroClasses } from "../../apps/class-config";
/** /**
* The Sheet class for DS4 Character Actors * The Sheet class for DS4 Character Actors
*/ */
export class DS4CharacterActorSheet extends DS4ActorSheet { export class DS4CharacterSheet extends DS4ActorSheet {
/** @override */ /** @override */
static get defaultOptions(): ActorSheet.Options { static get defaultOptions(): ActorSheet.Options {
return foundry.utils.mergeObject(super.defaultOptions, { return foundry.utils.mergeObject(super.defaultOptions, {
classes: ["sheet", "ds4-actor-sheet", "ds4-character-sheet"], classes: ["sheet", "ds4-actor-sheet", "ds4-character-sheet"],
}); });
} }
/** @override */
async getData(): Promise<DS4CharacterSheetData> {
const data = await super.getData();
const settings = data.settings;
const classes: Classes = {
none: { name: "DS4.ClassNone", hasSpellCasterConfiguration: false },
...settings.classes,
};
const heroClasses: HeroClasses = Object.fromEntries([
["none", { name: "DS4.HeroClassNone", baseClass: "none", hasSpellCasterConfiguration: false }],
...Object.entries(settings.heroClasses).filter(
([, value]) => this.actor.data.data.baseInfo.class === value.baseClass,
),
]);
return {
...data,
classes,
heroClasses,
};
}
}
export interface DS4CharacterSheet {
object: DS4Actor & { data: { type: "character"; _source: { type: "character" } } };
}
interface DS4CharacterSheetData extends DS4ActorSheetData {
classes: Classes;
heroClasses: HeroClasses;
} }

View file

@ -7,7 +7,7 @@ import { DS4ActorSheet } from "../actor-sheet";
/** /**
* The Sheet class for DS4 Creature Actors * The Sheet class for DS4 Creature Actors
*/ */
export class DS4CreatureActorSheet extends DS4ActorSheet { export class DS4CreatureSheet extends DS4ActorSheet {
/** @override */ /** @override */
static get defaultOptions(): ActorSheet.Options { static get defaultOptions(): ActorSheet.Options {
return foundry.utils.mergeObject(super.defaultOptions, { return foundry.utils.mergeObject(super.defaultOptions, {

67
src/apps/class-config.ts Normal file
View file

@ -0,0 +1,67 @@
// SPDX-FileCopyrightText: 2022 Johannes Loher
//
// SPDX-License-Identifier: MIT
import { DS4 } from "../config";
import { getGame } from "../helpers";
export class ClassConfig extends FormApplication<FormApplicationOptions, ClassConfigData, undefined> {
static get defaultOptions() {
return foundry.utils.mergeObject(super.defaultOptions, {
template: "systems/ds4/templates/apps/class-config.hbs",
});
}
static get defaultClasses(): Classes {
return Object.fromEntries(
Object.entries(DS4.defaultClasses).map(([key, { i18nKey: name, hasSpellCasterConfiguration }]) => [
key,
{ name, hasSpellCasterConfiguration },
]),
);
}
static get defaultHeroClasses(): HeroClasses {
return Object.fromEntries(
Object.entries(DS4.defaultHeroClasses).map(
([key, { i18nKey: name, baseClass, hasSpellCasterConfiguration }]) => [
key,
{ name, baseClass, hasSpellCasterConfiguration },
],
),
);
}
/** @override */
getData(): ClassConfigData {
const game = getGame();
return {
classes: game.settings.get("ds4", "classes"),
heroClasses: game.settings.get("ds4", "heroClasses"),
};
}
protected _updateObject(event: Event, formData?: object): Promise<unknown> {
throw new Error("Method not implemented.");
}
}
interface Class {
name: string;
hasSpellCasterConfiguration: boolean;
}
export type Classes = Record<string, Class>;
interface HeroClass {
name: string;
baseClass: string;
hasSpellCasterConfiguration: boolean;
}
export type HeroClasses = Record<string, HeroClass>;
interface ClassConfigData {
classes: Classes;
heroClasses: HeroClasses;
}

View file

@ -426,4 +426,105 @@ export const DS4 = {
eyeColor: "String", eyeColor: "String",
specialCharacteristics: "String", specialCharacteristics: "String",
}, },
defaultClasses: {
fighter: {
i18nKey: "DS4.ClassFighter",
hasSpellCasterConfiguration: false,
},
scout: {
i18nKey: "DS4.ClassScout",
hasSpellCasterConfiguration: false,
},
healer: {
i18nKey: "DS4.ClassHealer",
hasSpellCasterConfiguration: true,
},
wizard: {
i18nKey: "DS4.ClassWizard",
hasSpellCasterConfiguration: true,
},
sorcerer: {
i18nKey: "DS4.ClassSorcerer",
hasSpellCasterConfiguration: true,
},
},
defaultHeroClasses: {
berserker: {
i18nKey: "DS4.HeroClassBerserker",
baseClass: "fighter",
hasSpellCasterConfiguration: false,
},
weaponMaster: {
i18nKey: "DS4.HeroClassWeaponMaster",
baseClass: "fighter",
hasSpellCasterConfiguration: false,
},
paladin: {
i18nKey: "DS4.HeroClassPaladin",
baseClass: "fighter",
hasSpellCasterConfiguration: true,
},
assassin: {
i18nKey: "DS4.HeroClassAssassin",
baseClass: "scout",
hasSpellCasterConfiguration: false,
},
ranger: {
i18nKey: "DS4.HeroClassRanger",
baseClass: "scout",
hasSpellCasterConfiguration: false,
},
rogue: {
i18nKey: "DS4.HeroClassRogue",
baseClass: "scout",
hasSpellCasterConfiguration: false,
},
cleric: {
i18nKey: "DS4.HeroClassCleric",
baseClass: "healer",
hasSpellCasterConfiguration: false,
},
druid: {
i18nKey: "DS4.HeroClassDruid",
baseClass: "healer",
hasSpellCasterConfiguration: false,
},
monk: {
i18nKey: "DS4.HeroClassMonk",
baseClass: "healer",
hasSpellCasterConfiguration: false,
},
archmage: {
i18nKey: "DS4.HeroClassArchmage",
baseClass: "wizard",
hasSpellCasterConfiguration: false,
},
elementalist: {
i18nKey: "DS4.HeroClassElementalist",
baseClass: "wizard",
hasSpellCasterConfiguration: false,
},
battleMage: {
i18nKey: "DS4.HeroClassBattleMage",
baseClass: "wizard",
hasSpellCasterConfiguration: false,
},
bloodMage: {
i18nKey: "DS4.HeroClassBloodMage",
baseClass: "sorcerer",
hasSpellCasterConfiguration: false,
},
demonologist: {
i18nKey: "DS4.HeroClassDemonologist",
baseClass: "sorcerer",
hasSpellCasterConfiguration: false,
},
necromancer: {
i18nKey: "DS4.HeroClassNecromancer",
baseClass: "sorcerer",
hasSpellCasterConfiguration: false,
},
},
}; };

4
src/global.d.ts vendored
View file

@ -2,12 +2,16 @@
// //
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
import type { Classes, HeroClasses } from "./apps/class-config";
declare global { declare global {
namespace ClientSettings { namespace ClientSettings {
interface Values { interface Values {
"ds4.systemMigrationVersion": number; "ds4.systemMigrationVersion": number;
"ds4.useSlayingDiceForAutomatedChecks": boolean; "ds4.useSlayingDiceForAutomatedChecks": boolean;
"ds4.showSlayerPoints": boolean; "ds4.showSlayerPoints": boolean;
"ds4.classes": Classes;
"ds4.heroClasses": HeroClasses;
} }
} }

View file

@ -7,7 +7,7 @@
export default async function registerHandlebarsPartials(): Promise<void> { export default async function registerHandlebarsPartials(): Promise<void> {
const templatePaths = [ const templatePaths = [
"systems/ds4/templates/sheets/actor/components/actor-header.hbs", "systems/ds4/templates/sheets/actor/components/actor-header.hbs",
"systems/ds4/templates/sheets/actor/components/actor-progression.hbs", "systems/ds4/templates/sheets/actor/components/actor-resources.hbs",
"systems/ds4/templates/sheets/actor/components/biography.hbs", "systems/ds4/templates/sheets/actor/components/biography.hbs",
"systems/ds4/templates/sheets/actor/components/character-properties.hbs", "systems/ds4/templates/sheets/actor/components/character-properties.hbs",
"systems/ds4/templates/sheets/actor/components/check.hbs", "systems/ds4/templates/sheets/actor/components/check.hbs",

View file

@ -5,8 +5,8 @@
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
import { DS4ActiveEffect } from "../active-effect"; import { DS4ActiveEffect } from "../active-effect";
import { DS4CharacterActorSheet } from "../actor/character/character-sheet"; import { DS4CharacterSheet } from "../actor/character/character-sheet";
import { DS4CreatureActorSheet } from "../actor/creature/creature-sheet"; import { DS4CreatureSheet } from "../actor/creature/creature-sheet";
import { DS4ActorProxy } from "../actor/proxy"; import { DS4ActorProxy } from "../actor/proxy";
import { DS4ChatMessage } from "../chat-message"; import { DS4ChatMessage } from "../chat-message";
import { DS4 } from "../config"; import { DS4 } from "../config";
@ -66,8 +66,8 @@ async function init() {
registerSystemSettings(); registerSystemSettings();
Actors.unregisterSheet("core", ActorSheet); Actors.unregisterSheet("core", ActorSheet);
Actors.registerSheet("ds4", DS4CharacterActorSheet, { types: ["character"], makeDefault: true }); Actors.registerSheet("ds4", DS4CharacterSheet, { types: ["character"], makeDefault: true });
Actors.registerSheet("ds4", DS4CreatureActorSheet, { types: ["creature"], makeDefault: true }); Actors.registerSheet("ds4", DS4CreatureSheet, { types: ["creature"], makeDefault: true });
Items.unregisterSheet("core", ItemSheet); Items.unregisterSheet("core", ItemSheet);
Items.registerSheet("ds4", DS4ItemSheet, { makeDefault: true }); Items.registerSheet("ds4", DS4ItemSheet, { makeDefault: true });

View file

@ -2,6 +2,7 @@
// //
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
import { ClassConfig, Classes, HeroClasses } from "./apps/class-config";
import { getGame } from "./helpers"; import { getGame } from "./helpers";
export function registerSystemSettings(): void { export function registerSystemSettings(): void {
@ -11,7 +12,6 @@ export function registerSystemSettings(): void {
* Track the migrations version of the latest migration that has been applied * Track the migrations version of the latest migration that has been applied
*/ */
game.settings.register("ds4", "systemMigrationVersion", { game.settings.register("ds4", "systemMigrationVersion", {
name: "System Migration Version",
scope: "world", scope: "world",
config: false, config: false,
type: Number, type: Number,
@ -35,12 +35,37 @@ export function registerSystemSettings(): void {
type: Boolean, type: Boolean,
default: false, default: false,
}); });
game.settings.register("ds4", "classes", {
scope: "world",
config: false,
default: ClassConfig.defaultClasses,
onChange: rerenderApplications(isActorSheet, isSpellSheet),
});
game.settings.register("ds4", "heroClasses", {
scope: "world",
config: false,
default: ClassConfig.defaultHeroClasses,
onChange: rerenderApplications(isActorSheet, isSpellSheet),
});
game.settings.registerMenu("ds4", "classes", {
name: "DS4.MenuClassesName",
hint: "DS4.MenuClassesHint",
label: "DS4.MenuClassesLabel",
icon: "fas fa-chess",
restricted: true,
type: ClassConfig,
});
} }
export interface DS4Settings { export interface DS4Settings {
systemMigrationVersion: number; systemMigrationVersion: number;
useSlayingDiceForAutomatedChecks: boolean; useSlayingDiceForAutomatedChecks: boolean;
showSlayerPoints: boolean; showSlayerPoints: boolean;
classes: Classes;
heroClasses: HeroClasses;
} }
export function getDS4Settings(): DS4Settings { export function getDS4Settings(): DS4Settings {
@ -49,5 +74,24 @@ export function getDS4Settings(): DS4Settings {
systemMigrationVersion: game.settings.get("ds4", "systemMigrationVersion"), systemMigrationVersion: game.settings.get("ds4", "systemMigrationVersion"),
useSlayingDiceForAutomatedChecks: game.settings.get("ds4", "useSlayingDiceForAutomatedChecks"), useSlayingDiceForAutomatedChecks: game.settings.get("ds4", "useSlayingDiceForAutomatedChecks"),
showSlayerPoints: game.settings.get("ds4", "showSlayerPoints"), showSlayerPoints: game.settings.get("ds4", "showSlayerPoints"),
classes: game.settings.get("ds4", "classes"),
heroClasses: game.settings.get("ds4", "heroClasses"),
}; };
} }
function rerenderApplications(...conditions: ((app: Application) => boolean)[]): () => void {
return () => {
outer: for (const app of Object.values(ui.windows)) {
for (const condition of conditions) {
if (condition(app)) {
app.render(false);
break outer;
}
}
app.render(false);
}
};
}
const isActorSheet = (app: Application): boolean => app instanceof ActorSheet;
const isSpellSheet = (app: Application): boolean => app instanceof ItemSheet && app.item.type === "spell";

View file

@ -87,8 +87,8 @@
"templates": ["base"], "templates": ["base"],
"baseInfo": { "baseInfo": {
"race": "", "race": "",
"class": "", "class": "none",
"heroClass": "", "heroClass": "none",
"culture": "" "culture": ""
}, },
"progression": { "progression": {

View file

@ -0,0 +1,19 @@
{{!--
SPDX-FileCopyrightText: 2022 Johannes Loher
SPDX-License-Identifier: MIT
--}}
<form>
<ul>
{{#each classes as | value key |}}
<li>{{localize value.name}}</li>
{{/each}}
</ul>
<hr />
<ul>
{{#each heroClasses as | value key |}}
<li>{{localize value.name}}</li>
{{/each}}
</ul>
</form>

View file

@ -20,8 +20,9 @@ SPDX-License-Identifier: MIT
<input class="ds4-actor-header__name-input" name="name" type="text" id="name-{{data._id}}" <input class="ds4-actor-header__name-input" name="name" type="text" id="name-{{data._id}}"
value="{{data.name}}" placeholder="{{localize 'DS4.ActorName'}}" /> value="{{data.name}}" placeholder="{{localize 'DS4.ActorName'}}" />
</h1> </h1>
{{> systems/ds4/templates/sheets/actor/components/actor-progression.hbs}} {{> systems/ds4/templates/sheets/actor/components/actor-resources.hbs}}
</div> </div>
<div class="ds4-actor-header__data-row"> <div class="ds4-actor-header__data-row">
{{> @partial-block}} {{> @partial-block}}
</div> </div>

View file

@ -1,48 +0,0 @@
{{!--
SPDX-FileCopyrightText: 2021 Johannes Loher
SPDX-FileCopyrightText: 2021 Oliver Rümpelein
SPDX-FileCopyrightText: 2021 Gesina Schwalbe
SPDX-License-Identifier: MIT
--}}
<div class="ds4-actor-progression">
<div class="ds4-actor-progression__entry">
<h2 class="ds4-actor-progression__label"><label for="data.combatValues.hitPoints.value-{{data._id}}"
title="{{localize 'DS4.CombatValuesHitPointsCurrent'}}">{{localize
"DS4.CombatValuesHitPointsCurrentAbbr"}}</label>
</h2>
<input class="ds4-actor-progression__input" type="number" name="data.combatValues.hitPoints.value"
id="data.combatValues.hitPoints.value-{{data._id}}" value="{{data.data.combatValues.hitPoints.value}}"
data-dtype="Number" />
</div>
{{#if (eq data.type "character")}}
{{#if settings.showSlayerPoints}}
<div class="ds4-actor-progression__entry">
<h2 class="ds4-actor-progression__label"><label for="data.slayersPoints.value-{{data._id}}"
title="{{localize 'DS4.CharacterSlayerPoints'}}">{{localize "DS4.CharacterSlayerPointsAbbr"}}</label>
</h2>
<input class="ds4-actor-progression__input ds4-actor-progression__input--slayer-points" type="number"
max="{{data.data.slayerPoints.max}}" min="0" step="1" name="data.slayerPoints.value"
id="data.slayersPoints.value-{{data._id}}" value="{{data.data.slayerPoints.value}}" data-dtype="Number" />
</div>
{{/if}}
<div class="ds4-actor-progression__entry">
<h2 class="ds4-actor-progression__label"><label for="data.progression.level-{{data._id}}"
title="{{localize 'DS4.CharacterProgressionLevel'}}">{{localize
"DS4.CharacterProgressionLevelAbbr"}}</label>
</h2>
<input class="ds4-actor-progression__input" type="number" min="0" name="data.progression.level"
id="data.progression.level-{{data._id}}" value="{{data.data.progression.level}}" data-dtype="Number" />
</div>
<div class="ds4-actor-progression__entry">
<h2 class="ds4-actor-progression__label"><label for="data.progression.experiencePoints-{{data._id}}"
title="{{localize 'DS4.CharacterProgressionExperiencePoints'}}">{{localize
"DS4.CharacterProgressionExperiencePointsAbbr"}}</label>
</h2>
<input class="ds4-actor-progression__input" type="number" min="0" name="data.progression.experiencePoints"
id="data.progression.experiencePoints-{{data._id}}" value="{{data.data.progression.experiencePoints}}"
data-dtype="Number" />
</div>
{{/if}}
</div>

View file

@ -0,0 +1,29 @@
{{!--
SPDX-FileCopyrightText: 2021 Johannes Loher
SPDX-FileCopyrightText: 2021 Oliver Rümpelein
SPDX-FileCopyrightText: 2021 Gesina Schwalbe
SPDX-License-Identifier: MIT
--}}
<div class="ds4-actor-resources">
<div class="ds4-actor-resources__entry">
<h2 class="ds4-actor-resources__label"><label for="data.combatValues.hitPoints.value-{{data._id}}"
title="{{localize 'DS4.CombatValuesHitPointsCurrent'}}">{{localize
"DS4.CombatValuesHitPointsCurrentAbbr"}}</label>
</h2>
<input class="ds4-actor-resources__input" type="number" name="data.combatValues.hitPoints.value"
id="data.combatValues.hitPoints.value-{{data._id}}" value="{{data.data.combatValues.hitPoints.value}}"
data-dtype="Number" />
</div>
{{#if (and (eq data.type "character") settings.showSlayerPoints)}}
<div class="ds4-actor-resources__entry">
<h2 class="ds4-actor-resources__label"><label for="data.slayersPoints.value-{{data._id}}"
title="{{localize 'DS4.CharacterSlayerPoints'}}">{{localize "DS4.CharacterSlayerPointsAbbr"}}</label>
</h2>
<input class="ds4-actor-resources__input ds4-actor-resources__input--slayer-points" type="number"
max="{{data.data.slayerPoints.max}}" min="0" step="1" name="data.slayerPoints.value"
id="data.slayersPoints.value-{{data._id}}" value="{{data.data.slayerPoints.value}}" data-dtype="Number" />
</div>
{{/if}}
</div>

View file

@ -9,15 +9,15 @@ SPDX-License-Identifier: MIT
<div class="ds4-actor-properties"> <div class="ds4-actor-properties">
<div class="ds4-actor-properties__property"> <div class="ds4-actor-properties__property">
<label class="ds4-actor-properties__property-label" <label class="ds4-actor-properties__property-label"
for="data.baseInfo.race-{{data._id}}">{{config.i18n.characterBaseInfo.race}}</label> for="data.progression.level-{{data._id}}">{{config.i18n.characterProgression.level}}</label>
<input type="text" name="data.baseInfo.race" id="data.baseInfo.race-{{data._id}}" <input type="text" name="data.progression.level" id="data.progression.level-{{data._id}}"
value="{{data.data.baseInfo.race}}" data-dtype="String" /> value="{{data.data.progression.level}}" data-dtype="Number" />
</div> </div>
<div class="ds4-actor-properties__property"> <div class="ds4-actor-properties__property">
<label class="ds4-actor-properties__property-label" <label class="ds4-actor-properties__property-label"
for="data.baseInfo.culture-{{data._id}}">{{config.i18n.characterBaseInfo.culture}}</label> for="data.progression.experiencePoints-{{data._id}}">{{config.i18n.characterProgression.experiencePoints}}</label>
<input id="data.baseInfo.culture-{{data._id}}" type="text" name="data.baseInfo.culture" <input type="text" name="data.progression.experiencePoints" id="data.progression.experiencePoints-{{data._id}}"
value="{{data.data.baseInfo.culture}}" data-dtype="String" /> value="{{data.data.progression.experiencePoints}}" data-dtype="Number" />
</div> </div>
<div class="ds4-actor-properties__property"> <div class="ds4-actor-properties__property">
<label class="ds4-actor-properties__property-label" <label class="ds4-actor-properties__property-label"
@ -48,16 +48,38 @@ SPDX-License-Identifier: MIT
value="{{data.data.progression.talentPoints.total}}" data-dtype="Number" /> value="{{data.data.progression.talentPoints.total}}" data-dtype="Number" />
</div> </div>
</div> </div>
<div class="ds4-actor-properties__property">
<label class="ds4-actor-properties__property-label"
for="data.baseInfo.race-{{data._id}}">{{config.i18n.characterBaseInfo.race}}</label>
<input type="text" name="data.baseInfo.race" id="data.baseInfo.race-{{data._id}}"
value="{{data.data.baseInfo.race}}" data-dtype="String" />
</div>
<div class="ds4-actor-properties__property">
<label class="ds4-actor-properties__property-label"
for="data.baseInfo.culture-{{data._id}}">{{config.i18n.characterBaseInfo.culture}}</label>
<input id="data.baseInfo.culture-{{data._id}}" type="text" name="data.baseInfo.culture"
value="{{data.data.baseInfo.culture}}" data-dtype="String" />
</div>
<div class="ds4-actor-properties__property"> <div class="ds4-actor-properties__property">
<label class="ds4-actor-properties__property-label" <label class="ds4-actor-properties__property-label"
for="data.baseInfo.class-{{data._id}}">{{config.i18n.characterBaseInfo.class}}</label> for="data.baseInfo.class-{{data._id}}">{{config.i18n.characterBaseInfo.class}}</label>
<input type="text" id="data.baseInfo.class-{{data._id}}" name="data.baseInfo.class" <select class="ds4-actor-properties__property-select" id="data.baseInfo.class-{{data._id}}" name="data.baseInfo.class" data-dtype="String">
value="{{data.data.baseInfo.class}}" data-dtype="String" /> {{#select data.data.baseInfo.class}}
{{#each classes as |value key|}}
<option value="{{key}}">{{localize value.name}}</option>
{{/each}}
{{/select}}
</select>
</div> </div>
<div class="ds4-actor-properties__property"> <div class="ds4-actor-properties__property">
<label class="ds4-actor-properties__property-label" <label class="ds4-actor-properties__property-label"
for="data.baseInfo.heroClass-{{data._id}}">{{config.i18n.characterBaseInfo.heroClass}}</label> for="data.baseInfo.heroClass-{{data._id}}">{{config.i18n.characterBaseInfo.heroClass}}</label>
<input type="text" id="data.baseInfo.heroClass-{{data._id}}" name="data.baseInfo.heroClass" <select class="ds4-actor-properties__property-select" id="data.baseInfo.heroClass-{{data._id}}" name="data.baseInfo.heroClass" data-dtype="String">
value="{{data.data.baseInfo.heroClass}}" data-dtype="String" /> {{#select data.data.baseInfo.heroClass}}
{{#each heroClasses as |value key|}}
<option value="{{key}}">{{localize value.name}}</option>
{{/each}}
{{/select}}
</select>
</div> </div>
</div> </div>

View file

@ -19,18 +19,6 @@ SPDX-License-Identifier: MIT
{{/select}} {{/select}}
</select> </select>
</div> </div>
<div class="ds4-actor-properties__property">
<label class="ds4-actor-properties__property-label"
for="data.baseInfo.loot-{{data._id}}">{{config.i18n.creatureBaseInfo.loot}}</label>
<input type="text" id="data.baseInfo.loot-{{data._id}}" name="data.baseInfo.loot"
value="{{data.data.baseInfo.loot}}" data-dtype="String" />
</div>
<div class="ds4-actor-properties__property">
<label class="ds4-actor-properties__property-label"
for="data.baseInfo.foeFactor-{{data._id}}">{{config.i18n.creatureBaseInfo.foeFactor}}</label>
<input type="text" id="data.baseInfo.foeFactor-{{data._id}}" name="data.baseInfo.foeFactor"
value="{{data.data.baseInfo.foeFactor}}" data-dtype="Number" />
</div>
<div class="ds4-actor-properties__property"> <div class="ds4-actor-properties__property">
<label class="ds4-actor-properties__property-label" <label class="ds4-actor-properties__property-label"
for="data.baseInfo.sizeCategory-{{data._id}}">{{config.i18n.creatureBaseInfo.sizeCategory}}</label> for="data.baseInfo.sizeCategory-{{data._id}}">{{config.i18n.creatureBaseInfo.sizeCategory}}</label>
@ -43,10 +31,22 @@ SPDX-License-Identifier: MIT
{{/select}} {{/select}}
</select> </select>
</div> </div>
<div class="ds4-actor-properties__property">
<label class="ds4-actor-properties__property-label"
for="data.baseInfo.foeFactor-{{data._id}}">{{config.i18n.creatureBaseInfo.foeFactor}}</label>
<input type="text" id="data.baseInfo.foeFactor-{{data._id}}" name="data.baseInfo.foeFactor"
value="{{data.data.baseInfo.foeFactor}}" data-dtype="Number" />
</div>
<div class="ds4-actor-properties__property"> <div class="ds4-actor-properties__property">
<label class="ds4-actor-properties__property-label" <label class="ds4-actor-properties__property-label"
for="data.baseInfo.experiencePoints-{{data._id}}">{{config.i18n.creatureBaseInfo.experiencePoints}}</label> for="data.baseInfo.experiencePoints-{{data._id}}">{{config.i18n.creatureBaseInfo.experiencePoints}}</label>
<input type="text" id="data.baseInfo.experiencePoints-{{data._id}}" name="data.baseInfo.experiencePoints" <input type="text" id="data.baseInfo.experiencePoints-{{data._id}}" name="data.baseInfo.experiencePoints"
value="{{data.data.baseInfo.experiencePoints}}" data-dtype="Number" /> value="{{data.data.baseInfo.experiencePoints}}" data-dtype="Number" />
</div> </div>
<div class="ds4-actor-properties__property ds4-actor-properties__property--wide">
<label class="ds4-actor-properties__property-label"
for="data.baseInfo.loot-{{data._id}}">{{config.i18n.creatureBaseInfo.loot}}</label>
<input type="text" id="data.baseInfo.loot-{{data._id}}" name="data.baseInfo.loot"
value="{{data.data.baseInfo.loot}}" data-dtype="String" />
</div>
</div> </div>