Improve typing of DS4Item and DS4Actor

This commit is contained in:
Johannes Loher 2021-02-05 03:42:42 +01:00
parent b657633c7f
commit 5598255d6e
5 changed files with 94 additions and 63 deletions

View file

@ -1,23 +1,31 @@
import { ModifiableData, ResourceData, UsableResource } from "../common/common-data"; import { ModifiableData, ResourceData, UsableResource } from "../common/common-data";
import { DS4 } from "../config";
import { DS4ItemData } from "../item/item-data"; import { DS4ItemData } from "../item/item-data";
export type DS4ActorData = Actor.Data<DS4ActorDataType, DS4ItemData>; export type DS4ActorData = DS4CharacterData | DS4CreatureData;
type DS4ActorDataType = DS4ActorDataCharacter | DS4ActorDataCreature; type ActorType = keyof typeof DS4.i18n.actorTypes;
interface DS4ActorDataBase { interface DS4ActorDataHelper<T, U extends ActorType> extends Actor.Data<T, DS4ItemData> {
attributes: DS4ActorDataAttributes; type: U;
traits: DS4ActorDataTraits;
combatValues: DS4ActorDataCombatValues;
} }
interface DS4ActorDataAttributes { type DS4CharacterData = DS4ActorDataHelper<DS4CharacterDataData, "character">;
type DS4CreatureData = DS4ActorDataHelper<DS4CreatureDataData, "creature">;
interface DS4ActorDataDataBase {
attributes: DS4ActorDataDataAttributes;
traits: DS4ActorDataDataTraits;
combatValues: DS4ActorDataDataCombatValues;
}
interface DS4ActorDataDataAttributes {
body: ModifiableData<number>; body: ModifiableData<number>;
mobility: ModifiableData<number>; mobility: ModifiableData<number>;
mind: ModifiableData<number>; mind: ModifiableData<number>;
} }
interface DS4ActorDataTraits { interface DS4ActorDataDataTraits {
strength: ModifiableData<number>; strength: ModifiableData<number>;
constitution: ModifiableData<number>; constitution: ModifiableData<number>;
agility: ModifiableData<number>; agility: ModifiableData<number>;
@ -26,7 +34,7 @@ interface DS4ActorDataTraits {
aura: ModifiableData<number>; aura: ModifiableData<number>;
} }
interface DS4ActorDataCombatValues { interface DS4ActorDataDataCombatValues {
hitPoints: ResourceData<number>; hitPoints: ResourceData<number>;
defense: ModifiableData<number>; defense: ModifiableData<number>;
initiative: ModifiableData<number>; initiative: ModifiableData<number>;
@ -37,34 +45,32 @@ interface DS4ActorDataCombatValues {
targetedSpellcasting: ModifiableData<number>; targetedSpellcasting: ModifiableData<number>;
} }
interface DS4ActorDataCharacter extends DS4ActorDataBase { interface DS4CharacterDataData extends DS4ActorDataDataBase {
baseInfo: DS4ActorDataCharacterBaseInfo; baseInfo: DS4CharacterDataDataBaseInfo;
progression: DS4ActorDataCharacterProgression; progression: DS4CharacterDataDataProgression;
language: DS4ActorDataCharacterLanguage; language: DS4CharacterDataDataLanguage;
profile: DS4ActorDataCharacterProfile; profile: DS4CharacterDataDataProfile;
currency: DS4ActorDataCharacterCurrency; currency: DS4CharacterDataDataCurrency;
} }
interface DS4CharacterDataDataBaseInfo {
interface DS4ActorDataCharacterBaseInfo {
race: string; race: string;
class: string; class: string;
heroClass: string; heroClass: string;
culture: string; culture: string;
} }
interface DS4CharacterDataDataProgression {
interface DS4ActorDataCharacterProgression {
level: number; level: number;
experiencePoints: number; experiencePoints: number;
talentPoints: UsableResource<number>; talentPoints: UsableResource<number>;
progressPoints: UsableResource<number>; progressPoints: UsableResource<number>;
} }
interface DS4ActorDataCharacterLanguage { interface DS4CharacterDataDataLanguage {
languages: string; languages: string;
alphabets: string; alphabets: string;
} }
interface DS4ActorDataCharacterProfile { interface DS4CharacterDataDataProfile {
biography: string; biography: string;
gender: string; gender: string;
birthday: string; birthday: string;
@ -77,21 +83,21 @@ interface DS4ActorDataCharacterProfile {
specialCharacteristics: string; specialCharacteristics: string;
} }
interface DS4ActorDataCharacterCurrency { interface DS4CharacterDataDataCurrency {
gold: number; gold: number;
silver: number; silver: number;
copper: number; copper: number;
} }
interface DS4ActorDataCreature extends DS4ActorDataBase { interface DS4CreatureDataData extends DS4ActorDataDataBase {
baseInfo: DS4ActorDataCreatureBaseInfo; baseInfo: DS4CreatureDataDataBaseInfo;
} }
type CreatureType = "animal" | "construct" | "humanoid" | "magicalEntity" | "plantBeing" | "undead"; type CreatureType = "animal" | "construct" | "humanoid" | "magicalEntity" | "plantBeing" | "undead";
type SizeCategory = "tiny" | "small" | "normal" | "large" | "huge" | "colossal"; type SizeCategory = "tiny" | "small" | "normal" | "large" | "huge" | "colossal";
interface DS4ActorDataCreatureBaseInfo { interface DS4CreatureDataDataBaseInfo {
loot: string; loot: string;
foeFactor: number; foeFactor: number;
creatureType: CreatureType; creatureType: CreatureType;

View file

@ -1,6 +1,6 @@
import { ModifiableData } from "../common/common-data"; import { ModifiableData } from "../common/common-data";
import { DS4Item } from "../item/item"; import { DS4Item } from "../item/item";
import { DS4Armor, DS4Shield, ItemType } from "../item/item-data"; import { ItemType } from "../item/item-data";
import { DS4ActorData } from "./actor-data"; import { DS4ActorData } from "./actor-data";
export class DS4Actor extends Actor<DS4ActorData, DS4Item> { export class DS4Actor extends Actor<DS4ActorData, DS4Item> {
@ -84,10 +84,13 @@ export class DS4Actor extends Actor<DS4ActorData, DS4Item> {
*/ */
private _calculateArmorValueOfEquippedItems(): number { private _calculateArmorValueOfEquippedItems(): number {
return this.items return this.items
.filter((item) => ["armor", "shield"].includes(item.type)) .map((item) => {
.map((item) => item.data.data as DS4Armor | DS4Shield) if (item.data.type === "armor" || item.data.type === "shield") {
.filter((itemData) => itemData.equipped) return item.data.data.equipped ? item.data.data.armorValue : 0;
.map((itemData) => itemData.armorValue) } else {
return 0;
}
})
.reduce((a, b) => a + b, 0); .reduce((a, b) => a + b, 0);
} }

View file

@ -128,7 +128,7 @@ export class DS4ActorSheet extends ActorSheet<unknown, DS4Actor> {
* @param {JQuery.ChangeEvent<HTMLElement>} ev The originating change event * @param {JQuery.ChangeEvent<HTMLElement>} ev The originating change event
* @private * @private
*/ */
private _onItemChange(ev: JQuery.ChangeEvent<HTMLElement>): void { private _onItemChange(ev: JQuery.ChangeEvent): void {
ev.preventDefault(); ev.preventDefault();
console.log("Current target:", $(ev.currentTarget).get(0)["name"]); console.log("Current target:", $(ev.currentTarget).get(0)["name"]);
const el: HTMLFormElement = $(ev.currentTarget).get(0); const el: HTMLFormElement = $(ev.currentTarget).get(0);

View file

@ -3,35 +3,53 @@ import { DS4 } from "../config";
export type ItemType = keyof typeof DS4.i18n.itemTypes; export type ItemType = keyof typeof DS4.i18n.itemTypes;
export type DS4ItemData = Item.Data<DS4ItemDataType>; export type DS4ItemData =
| DS4WeaponData
| DS4ArmorData
| DS4ShieldData
| DS4SpellData
| DS4TrinketData
| DS4EquipmentData
| DS4TalentData
| DS4RacialAbilityData
| DS4LanguageData
| DS4AlphabetData
| DS4SpecialCreatureAbilityData;
type DS4ItemDataType = interface DS4ItemDataHelper<T, U extends ItemType> extends Item.Data<T> {
| DS4Weapon type: U;
| DS4Armor }
| DS4Shield
| DS4Spell type DS4WeaponData = DS4ItemDataHelper<DS4WeaponDataData, "weapon">;
| DS4Trinket type DS4ArmorData = DS4ItemDataHelper<DS4ArmorDataData, "armor">;
| DS4Equipment type DS4ShieldData = DS4ItemDataHelper<DS4ShieldDataData, "shield">;
| DS4Talent type DS4SpellData = DS4ItemDataHelper<DS4SpellDataData, "spell">;
| DS4RacialAbility type DS4TrinketData = DS4ItemDataHelper<DS4TrinketDataData, "trinket">;
| DS4Language type DS4EquipmentData = DS4ItemDataHelper<DS4EquipmentDataData, "equipment">;
| DS4Alphabet type DS4TalentData = DS4ItemDataHelper<DS4TalentDataData, "talent">;
| DS4SpecialCreatureAbility; type DS4RacialAbilityData = DS4ItemDataHelper<DS4RacialAbilityDataData, "racialAbility">;
type DS4LanguageData = DS4ItemDataHelper<DS4LanguageDataData, "language">;
type DS4AlphabetData = DS4ItemDataHelper<DS4AlphabetDataData, "alphabet">;
type DS4SpecialCreatureAbilityData = DS4ItemDataHelper<DS4SpecialCreatureAbilityDataData, "specialCreatureAbility">;
// types // types
interface DS4Weapon extends DS4ItemBase, DS4ItemPhysical, DS4ItemEquipable { interface DS4WeaponDataData extends DS4ItemDataDataBase, DS4ItemDataDataPhysical, DS4ItemDataDataEquipable {
attackType: "melee" | "ranged" | "meleeRanged"; attackType: "melee" | "ranged" | "meleeRanged";
weaponBonus: number; weaponBonus: number;
opponentDefense: number; opponentDefense: number;
} }
export interface DS4Armor extends DS4ItemBase, DS4ItemPhysical, DS4ItemEquipable, DS4ItemProtective { interface DS4ArmorDataData
extends DS4ItemDataDataBase,
DS4ItemDataDataPhysical,
DS4ItemDataDataEquipable,
DS4ItemDataDataProtective {
armorMaterialType: "cloth" | "leather" | "chain" | "plate"; armorMaterialType: "cloth" | "leather" | "chain" | "plate";
armorType: "body" | "helmet" | "vambrace" | "greaves" | "vambraceGreaves"; armorType: "body" | "helmet" | "vambrace" | "greaves" | "vambraceGreaves";
} }
export interface DS4Talent extends DS4ItemBase { interface DS4TalentDataData extends DS4ItemDataDataBase {
rank: DS4TalentRank; rank: DS4TalentRank;
} }
@ -39,7 +57,7 @@ interface DS4TalentRank extends ModifiableData<number> {
max: number; max: number;
} }
interface DS4Spell extends DS4ItemBase, DS4ItemEquipable { interface DS4SpellDataData extends DS4ItemDataDataBase, DS4ItemDataDataEquipable {
spellType: "spellcasting" | "targetedSpellcasting"; spellType: "spellcasting" | "targetedSpellcasting";
bonus: string; bonus: string;
spellCategory: spellCategory:
@ -59,37 +77,41 @@ interface DS4Spell extends DS4ItemBase, DS4ItemEquipable {
scrollPrice: number; scrollPrice: number;
} }
export interface DS4Shield extends DS4ItemBase, DS4ItemPhysical, DS4ItemEquipable, DS4ItemProtective {} interface DS4ShieldDataData
interface DS4Trinket extends DS4ItemBase, DS4ItemPhysical, DS4ItemEquipable {} extends DS4ItemDataDataBase,
interface DS4Equipment extends DS4ItemBase, DS4ItemPhysical {} DS4ItemDataDataPhysical,
type DS4RacialAbility = DS4ItemBase; DS4ItemDataDataEquipable,
type DS4Language = DS4ItemBase; DS4ItemDataDataProtective {}
type DS4Alphabet = DS4ItemBase; interface DS4TrinketDataData extends DS4ItemDataDataBase, DS4ItemDataDataPhysical, DS4ItemDataDataEquipable {}
interface DS4SpecialCreatureAbility extends DS4ItemBase { interface DS4EquipmentDataData extends DS4ItemDataDataBase, DS4ItemDataDataPhysical {}
type DS4RacialAbilityDataData = DS4ItemDataDataBase;
type DS4LanguageDataData = DS4ItemDataDataBase;
type DS4AlphabetDataData = DS4ItemDataDataBase;
interface DS4SpecialCreatureAbilityDataData extends DS4ItemDataDataBase {
experiencePoints: number; experiencePoints: number;
} }
// templates // templates
interface DS4ItemBase { interface DS4ItemDataDataBase {
description: string; description: string;
} }
interface DS4ItemPhysical { interface DS4ItemDataDataPhysical {
quantity: number; quantity: number;
price: number; price: number;
availability: "hamlet" | "village" | "city" | "elves" | "dwarves" | "nowhere" | "unset"; availability: "hamlet" | "village" | "city" | "elves" | "dwarves" | "nowhere" | "unset";
storageLocation: string; storageLocation: string;
} }
export function isDS4ItemDataTypePhysical(input: DS4ItemDataType): boolean { export function isDS4ItemDataTypePhysical(input: DS4ItemData["data"]): boolean {
return "quantity" in input && "price" in input && "availability" in input && "storageLocation" in input; return "quantity" in input && "price" in input && "availability" in input && "storageLocation" in input;
} }
interface DS4ItemEquipable { interface DS4ItemDataDataEquipable {
equipped: boolean; equipped: boolean;
} }
interface DS4ItemProtective { interface DS4ItemDataDataProtective {
armorValue: number; armorValue: number;
} }

View file

@ -1,4 +1,4 @@
import { DS4ItemData, DS4Talent } from "./item-data"; import { DS4ItemData } from "./item-data";
/** /**
* Extend the basic Item with some very simple modifications. * Extend the basic Item with some very simple modifications.
@ -19,8 +19,8 @@ export class DS4Item extends Item<DS4ItemData> {
} }
prepareDerivedData(): void { prepareDerivedData(): void {
if (this.type === "talent") { if (this.data.type === "talent") {
const data = this.data.data as DS4Talent; const data = this.data.data;
data.rank.total = data.rank.base + data.rank.mod; data.rank.total = data.rank.base + data.rank.mod;
} }
} }