Merge branch 'document-subclasses' into 'master'
Document subclasses See merge request dungeonslayers/ds4!179
This commit is contained in:
commit
e33927b277
72 changed files with 1122 additions and 712 deletions
8
.vscode/settings.json
vendored
8
.vscode/settings.json
vendored
|
@ -6,5 +6,11 @@
|
|||
"eslint.nodePath": ".yarn/sdks",
|
||||
"prettier.prettierPath": ".yarn/sdks/prettier/index.js",
|
||||
"typescript.tsdk": ".yarn/sdks/typescript/lib",
|
||||
"typescript.enablePromptUseWorkspaceTsdk": true
|
||||
"typescript.enablePromptUseWorkspaceTsdk": true,
|
||||
"importSorter.generalConfiguration.sortOnBeforeSave": true,
|
||||
"importSorter.importStringConfiguration.maximumNumberOfImportExpressionsPerLine.type": "newLineEachExpressionAfterCountLimitExceptIfOnlyOne",
|
||||
"importSorter.importStringConfiguration.maximumNumberOfImportExpressionsPerLine.count": 120,
|
||||
"importSorter.importStringConfiguration.tabSize": 4,
|
||||
"importSorter.importStringConfiguration.quoteMark": "double",
|
||||
"importSorter.importStringConfiguration.trailingComma": "multiLine"
|
||||
}
|
||||
|
|
|
@ -256,11 +256,12 @@
|
|||
"DS4.ErrorDiceCoupFumbleOverlap": "Es gibt eine Überlappung zwischen Patzern und Immersiegen.",
|
||||
"DS4.ErrorSlayingDiceRecursionLimitExceeded": "Die maximale Rekursionstiefe für slayende Würfelwürfe wurde überschritten.",
|
||||
"DS4.ErrorInvalidNumberOfDice": "Ungültige Anzahl an Würfeln.",
|
||||
"DS4.ErrorInvalidActorType": "Ungültiger Aktortyp '{type}'.",
|
||||
"DS4.ErrorInvalidItemType": "Ungültiger Itemtyp '{type}'.",
|
||||
"DS4.ErrorDuringMigration": "Fehler während der Aktualisierung des DS4 Systems von Migrationsversion {currentVersion} auf {targetVersion}. Der Fehler trat während der Ausführung des Migrationsskripts mit der Version {migrationVersion} auf. Spätere Migrationsskripte wurden nicht ausgeführt. Mehr Details finden Sie in der Entwicklerkonsole (F12).",
|
||||
"DS4.ErrorDuringCompendiumMigration": "Fehler während der Aktualisierung Kompendiums '{pack}' für DS4 von Migrationsversion {currentVersion} auf {targetVersion}. Der Fehler trat während der Ausführung des Migrationsskripts mit der Version {migrationVersion} auf. Spätere Migrationsskripte wurden nicht ausgeführt. Mehr Details finden Sie in der Entwicklerkonsole (F12).",
|
||||
"DS4.ErrorCannotRollUnownedItem": "Für das Item '{name}' ({id}) kann nicht gewürfelt werden, da es keinem Aktor gehört.",
|
||||
"DS4.ErrorRollingForItemTypeNotPossible": "Würfeln ist für Items vom Typ '{type}' nicht möglich.",
|
||||
"DS4.ErrorWrongItemType": "Ein Item vom Type '{expectedType}' wurde erwartet aber das Item '{name}' ({id}) ist vom Typ '{actualType}'.",
|
||||
"DS4.ErrorUnexpectedAttackType": "Unerwartete Angriffsart '{actualType}', erwartete Angriffsarten: {expectedTypes}",
|
||||
"DS4.ErrorUnexpectedAttribute": "Unerwartetes Attribut '{actualAttribute}', erwartete Attribute: {expectedTypes}",
|
||||
"DS4.ErrorUnexpectedTrait": "Unerwartete Eigenschaft '{actualTrait}', erwartete Eigenschaften: {expectedTypes}",
|
||||
|
|
|
@ -256,11 +256,12 @@
|
|||
"DS4.ErrorDiceCoupFumbleOverlap": "There is an overlap between Fumbles and Coups.",
|
||||
"DS4.ErrorSlayingDiceRecursionLimitExceeded": "Maximum recursion depth for slaying dice roll exceeded.",
|
||||
"DS4.ErrorInvalidNumberOfDice": "Invalid number of dice.",
|
||||
"DS4.ErrorInvalidActorType": "Invalid actor type '{type}'.",
|
||||
"DS4.ErrorInvalidItemType": "Invalid item type '{type}'.",
|
||||
"DS4.ErrorDuringMigration": "Error while migrating DS4 system from migration version {currentVersion} to {targetVersion}. The error occurred during execution of migration script with version {migrationVersion}. Later migrations have not been executed. For more details, please look at the development console (F12).",
|
||||
"DS4.ErrorDuringCompendiumMigration": "Error while migrating compendium '{pack}' for DS4 from migration version {currentVersion} to {targetVersion}. The error occurred during execution of migration script with version {migrationVersion}. Later migrations have not been executed. For more details, please look at the development console (F12).",
|
||||
"DS4.ErrorCannotRollUnownedItem": "Rolling for item '{name}' ({id})is not possible because it is not owned.",
|
||||
"DS4.ErrorRollingForItemTypeNotPossible": "Rolling is not possible for items of type '{type}'.",
|
||||
"DS4.ErrorWrongItemType": "Expected an item of type '{expectedType}' but item '{name}' ({id}) is of type '{actualType}'.",
|
||||
"DS4.ErrorUnexpectedAttackType": "Unexpected attack type '{actualType}', expected it to be one of: {expectedTypes}",
|
||||
"DS4.ErrorUnexpectedAttribute": "Unexpected attribute '{actualAttribute}', expected it to be one of: {expectedTypes}",
|
||||
"DS4.ErrorUnexpectedTrait": "Unexpected trait '{actualTrait}', expected it to be one of: {expectedTypes}",
|
||||
|
|
|
@ -61,7 +61,7 @@
|
|||
"@commitlint/cli": "16.2.1",
|
||||
"@commitlint/config-conventional": "16.2.1",
|
||||
"@guanghechen/rollup-plugin-copy": "1.8.6",
|
||||
"@league-of-foundry-developers/foundry-vtt-types": "9.249.2",
|
||||
"@league-of-foundry-developers/foundry-vtt-types": "9.249.3",
|
||||
"@rollup/plugin-typescript": "8.3.0",
|
||||
"@seald-io/nedb": "2.2.1",
|
||||
"@types/fs-extra": "9.0.13",
|
||||
|
|
|
@ -2,8 +2,9 @@
|
|||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import { CooldownDuration, DS4SpellDataSourceData } from "../../../src/item/item-data-source";
|
||||
import { calculateSpellPrice } from "../../../src/item/type-specific-helpers/spell";
|
||||
import { calculateSpellPrice } from "../../../src/item/spell/calculate-spell-price";
|
||||
|
||||
import type { CooldownDuration, DS4SpellDataSourceData } from "../../../src/item/spell/spell-data-source";
|
||||
|
||||
const defaultData: DS4SpellDataSourceData = {
|
||||
description: "",
|
|
@ -4,7 +4,8 @@
|
|||
|
||||
import { DS4Actor } from "./actor/actor";
|
||||
import { getGame } from "./helpers";
|
||||
import { DS4Item } from "./item/item";
|
||||
|
||||
import type { DS4Item } from "./item/item";
|
||||
|
||||
declare global {
|
||||
interface DocumentClassConfig {
|
||||
|
|
45
src/actor/actor-data-properties-base.ts
Normal file
45
src/actor/actor-data-properties-base.ts
Normal file
|
@ -0,0 +1,45 @@
|
|||
// SPDX-FileCopyrightText: 2021 Johannes Loher
|
||||
// SPDX-FileCopyrightText: 2021 Oliver Rümpelein
|
||||
// SPDX-FileCopyrightText: 2021 Gesina Schwalbe
|
||||
// SPDX-FileCopyrightText: 2021 Siegfried Krug
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import { DS4 } from "../config";
|
||||
|
||||
import type { ModifiableDataBaseTotal, ResourceDataBaseTotalMax } from "../common/common-data";
|
||||
|
||||
export interface DS4ActorDataPropertiesDataBase {
|
||||
attributes: DS4ActorDataPropertiesDataAttributes;
|
||||
traits: DS4ActorDataPropertiesDataTraits;
|
||||
combatValues: DS4ActorDataPropertiesDataCombatValues;
|
||||
rolling: DS4ActorDataPropertiesDataRolling;
|
||||
checks: DS4ActorDataPropertiesDataChecks;
|
||||
}
|
||||
|
||||
type DS4ActorDataPropertiesDataAttributes = {
|
||||
[Key in keyof typeof DS4.i18n.attributes]: ModifiableDataBaseTotal<number>;
|
||||
};
|
||||
|
||||
type DS4ActorDataPropertiesDataTraits = { [Key in keyof typeof DS4.i18n.traits]: ModifiableDataBaseTotal<number> };
|
||||
|
||||
type DS4ActorDataPropertiesDataCombatValues = {
|
||||
[Key in keyof typeof DS4.i18n.combatValues]: Key extends "hitPoints"
|
||||
? ResourceDataBaseTotalMax<number>
|
||||
: ModifiableDataBaseTotal<number>;
|
||||
};
|
||||
|
||||
interface DS4ActorDataPropertiesDataRolling {
|
||||
maximumCoupResult: number;
|
||||
minimumFumbleResult: number;
|
||||
}
|
||||
|
||||
type DS4ActorDataPropertiesDataChecks = {
|
||||
[key in Check]: number;
|
||||
};
|
||||
|
||||
export type Check = keyof typeof DS4.i18n.checks;
|
||||
|
||||
export function isCheck(value: string): value is Check {
|
||||
return Object.keys(DS4.i18n.checks).includes(value);
|
||||
}
|
|
@ -1,17 +1,9 @@
|
|||
// SPDX-FileCopyrightText: 2021 Johannes Loher
|
||||
// SPDX-FileCopyrightText: 2022 Johannes Loher
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import { ModifiableDataBaseTotal, ResourceDataBaseTotalMax } from "../common/common-data";
|
||||
import { DS4 } from "../config";
|
||||
import {
|
||||
DS4CharacterDataSourceDataBaseInfo,
|
||||
DS4CharacterDataSourceDataCurrency,
|
||||
DS4CharacterDataSourceDataProfile,
|
||||
DS4CharacterDataSourceDataProgression,
|
||||
DS4CharacterDataSourceDataSlayerPoints,
|
||||
DS4CreatureDataSourceDataBaseInfo,
|
||||
} from "./actor-data-source";
|
||||
import type { DS4CharacterDataProperties } from "./character/character-data-properties";
|
||||
import type { DS4CreatureDataProperties } from "./creature/creature-data-properties";
|
||||
|
||||
declare global {
|
||||
interface DataConfig {
|
||||
|
@ -20,68 +12,3 @@ declare global {
|
|||
}
|
||||
|
||||
export type DS4ActorDataProperties = DS4CharacterDataProperties | DS4CreatureDataProperties;
|
||||
|
||||
interface DS4CharacterDataProperties {
|
||||
type: "character";
|
||||
data: DS4CharacterDataPropertiesData;
|
||||
}
|
||||
|
||||
interface DS4CreatureDataProperties {
|
||||
type: "creature";
|
||||
data: DS4CreatureDataPropertiesData;
|
||||
}
|
||||
|
||||
// templates
|
||||
|
||||
interface DS4ActorDataPropertiesDataBase {
|
||||
attributes: DS4ActorDataPropertiesDataAttributes;
|
||||
traits: DS4ActorDataPropertiesDataTraits;
|
||||
combatValues: DS4ActorDataPropertiesDataCombatValues;
|
||||
rolling: DS4ActorDataPropertiesDataRolling;
|
||||
checks: DS4ActorDataPropertiesDataChecks;
|
||||
}
|
||||
|
||||
type DS4ActorDataPropertiesDataAttributes = {
|
||||
[Key in keyof typeof DS4.i18n.attributes]: ModifiableDataBaseTotal<number>;
|
||||
};
|
||||
|
||||
type DS4ActorDataPropertiesDataTraits = { [Key in keyof typeof DS4.i18n.traits]: ModifiableDataBaseTotal<number> };
|
||||
|
||||
type DS4ActorDataPropertiesDataCombatValues = {
|
||||
[Key in keyof typeof DS4.i18n.combatValues]: Key extends "hitPoints"
|
||||
? ResourceDataBaseTotalMax<number>
|
||||
: ModifiableDataBaseTotal<number>;
|
||||
};
|
||||
|
||||
interface DS4ActorDataPropertiesDataRolling {
|
||||
maximumCoupResult: number;
|
||||
minimumFumbleResult: number;
|
||||
}
|
||||
|
||||
type DS4ActorDataPropertiesDataChecks = {
|
||||
[key in Check]: number;
|
||||
};
|
||||
|
||||
export type Check = keyof typeof DS4.i18n.checks;
|
||||
|
||||
export function isCheck(value: string): value is Check {
|
||||
return Object.keys(DS4.i18n.checks).includes(value);
|
||||
}
|
||||
|
||||
// types
|
||||
|
||||
interface DS4CreatureDataPropertiesData extends DS4ActorDataPropertiesDataBase {
|
||||
baseInfo: DS4CreatureDataSourceDataBaseInfo;
|
||||
}
|
||||
|
||||
interface DS4CharacterDataPropertiesData extends DS4ActorDataPropertiesDataBase {
|
||||
baseInfo: DS4CharacterDataSourceDataBaseInfo;
|
||||
progression: DS4CharacterDataSourceDataProgression;
|
||||
profile: DS4CharacterDataSourceDataProfile;
|
||||
currency: DS4CharacterDataSourceDataCurrency;
|
||||
slayerPoints: DS4CharacterDataPropertiesDataSlayerPoints;
|
||||
}
|
||||
|
||||
export interface DS4CharacterDataPropertiesDataSlayerPoints extends DS4CharacterDataSourceDataSlayerPoints {
|
||||
max: number;
|
||||
}
|
||||
|
|
44
src/actor/actor-data-source-base.ts
Normal file
44
src/actor/actor-data-source-base.ts
Normal file
|
@ -0,0 +1,44 @@
|
|||
// SPDX-FileCopyrightText: 2021 Johannes Loher
|
||||
// SPDX-FileCopyrightText: 2021 Oliver Rümpelein
|
||||
// SPDX-FileCopyrightText: 2021 Gesina Schwalbe
|
||||
// SPDX-FileCopyrightText: 2021 Siegfried Krug
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import { DS4 } from "../config";
|
||||
|
||||
import type { ModifiableData, ModifiableDataBase, ResourceData } from "../common/common-data";
|
||||
|
||||
export interface DS4ActorDataSourceDataBase {
|
||||
attributes: DS4ActorDataSourceDataAttributes;
|
||||
traits: DS4ActorDataSourceDataTraits;
|
||||
combatValues: DS4ActorDataSourceDataCombatValues;
|
||||
}
|
||||
|
||||
type DS4ActorDataSourceDataAttributes = { [Key in keyof typeof DS4.i18n.attributes]: ModifiableDataBase<number> };
|
||||
|
||||
type Attribute = keyof DS4ActorDataSourceDataAttributes;
|
||||
|
||||
export function isAttribute(value: unknown): value is Attribute {
|
||||
return (Object.keys(DS4.i18n.attributes) as Array<unknown>).includes(value);
|
||||
}
|
||||
|
||||
type DS4ActorDataSourceDataTraits = { [Key in keyof typeof DS4.i18n.traits]: ModifiableDataBase<number> };
|
||||
|
||||
type Trait = keyof DS4ActorDataSourceDataTraits;
|
||||
|
||||
export function isTrait(value: unknown): value is Trait {
|
||||
return (Object.keys(DS4.i18n.traits) as Array<unknown>).includes(value);
|
||||
}
|
||||
|
||||
type DS4ActorDataSourceDataCombatValues = {
|
||||
[Key in keyof typeof DS4.i18n.combatValues]: Key extends "hitPoints"
|
||||
? ResourceData<number>
|
||||
: ModifiableData<number>;
|
||||
};
|
||||
|
||||
type CombatValue = keyof DS4ActorDataSourceDataCombatValues;
|
||||
|
||||
export function isCombatValue(value: string): value is CombatValue {
|
||||
return (Object.keys(DS4.i18n.combatValues) as Array<unknown>).includes(value);
|
||||
}
|
|
@ -1,12 +1,9 @@
|
|||
// SPDX-FileCopyrightText: 2021 Johannes Loher
|
||||
// SPDX-FileCopyrightText: 2021 Oliver Rümpelein
|
||||
// SPDX-FileCopyrightText: 2021 Gesina Schwalbe
|
||||
// SPDX-FileCopyrightText: 2021 Siegfried Krug
|
||||
// SPDX-FileCopyrightText: 2022 Johannes Loher
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import { ModifiableData, ModifiableDataBase, ResourceData, UsableResource } from "../common/common-data";
|
||||
import { DS4 } from "../config";
|
||||
import type { DS4CharacterDataSource } from "./character/character-data-source";
|
||||
import type { DS4CreatureDataSource } from "./creature/creature-data-source";
|
||||
|
||||
declare global {
|
||||
interface SourceConfig {
|
||||
|
@ -15,111 +12,3 @@ declare global {
|
|||
}
|
||||
|
||||
export type DS4ActorDataSource = DS4CharacterDataSource | DS4CreatureDataSource;
|
||||
|
||||
interface DS4CharacterDataSource {
|
||||
type: "character";
|
||||
data: DS4CharacterDataSourceData;
|
||||
}
|
||||
|
||||
interface DS4CreatureDataSource {
|
||||
type: "creature";
|
||||
data: DS4CreatureDataSourceData;
|
||||
}
|
||||
|
||||
// templates
|
||||
|
||||
interface DS4ActorDataSourceDataBase {
|
||||
attributes: DS4ActorDataSourceDataAttributes;
|
||||
traits: DS4ActorDataSourceDataTraits;
|
||||
combatValues: DS4ActorDataSourceDataCombatValues;
|
||||
}
|
||||
|
||||
type DS4ActorDataSourceDataAttributes = { [Key in keyof typeof DS4.i18n.attributes]: ModifiableDataBase<number> };
|
||||
|
||||
type Attribute = keyof DS4ActorDataSourceDataAttributes;
|
||||
|
||||
export function isAttribute(value: unknown): value is Attribute {
|
||||
return (Object.keys(DS4.i18n.attributes) as Array<unknown>).includes(value);
|
||||
}
|
||||
|
||||
type DS4ActorDataSourceDataTraits = { [Key in keyof typeof DS4.i18n.traits]: ModifiableDataBase<number> };
|
||||
|
||||
type Trait = keyof DS4ActorDataSourceDataTraits;
|
||||
|
||||
export function isTrait(value: unknown): value is Trait {
|
||||
return (Object.keys(DS4.i18n.traits) as Array<unknown>).includes(value);
|
||||
}
|
||||
|
||||
type DS4ActorDataSourceDataCombatValues = {
|
||||
[Key in keyof typeof DS4.i18n.combatValues]: Key extends "hitPoints"
|
||||
? ResourceData<number>
|
||||
: ModifiableData<number>;
|
||||
};
|
||||
|
||||
type CombatValue = keyof DS4ActorDataSourceDataCombatValues;
|
||||
|
||||
export function isCombatValue(value: string): value is CombatValue {
|
||||
return (Object.keys(DS4.i18n.combatValues) as Array<unknown>).includes(value);
|
||||
}
|
||||
|
||||
// types
|
||||
|
||||
interface DS4CreatureDataSourceData extends DS4ActorDataSourceDataBase {
|
||||
baseInfo: DS4CreatureDataSourceDataBaseInfo;
|
||||
}
|
||||
|
||||
export interface DS4CreatureDataSourceDataBaseInfo {
|
||||
loot: string;
|
||||
foeFactor: number;
|
||||
creatureType: CreatureType;
|
||||
sizeCategory: SizeCategory;
|
||||
experiencePoints: number;
|
||||
description: string;
|
||||
}
|
||||
|
||||
type CreatureType = keyof typeof DS4.i18n.creatureTypes;
|
||||
|
||||
type SizeCategory = keyof typeof DS4.i18n.creatureSizeCategories;
|
||||
|
||||
interface DS4CharacterDataSourceData extends DS4ActorDataSourceDataBase {
|
||||
baseInfo: DS4CharacterDataSourceDataBaseInfo;
|
||||
progression: DS4CharacterDataSourceDataProgression;
|
||||
profile: DS4CharacterDataSourceDataProfile;
|
||||
currency: DS4CharacterDataSourceDataCurrency;
|
||||
slayerPoints: DS4CharacterDataSourceDataSlayerPoints;
|
||||
}
|
||||
export interface DS4CharacterDataSourceDataBaseInfo {
|
||||
race: string;
|
||||
class: string;
|
||||
heroClass: string;
|
||||
culture: string;
|
||||
}
|
||||
export interface DS4CharacterDataSourceDataProgression {
|
||||
level: number;
|
||||
experiencePoints: number;
|
||||
talentPoints: UsableResource<number>;
|
||||
progressPoints: UsableResource<number>;
|
||||
}
|
||||
|
||||
export interface DS4CharacterDataSourceDataProfile {
|
||||
biography: string;
|
||||
gender: string;
|
||||
birthday: string;
|
||||
birthplace: string;
|
||||
age: number;
|
||||
height: number;
|
||||
hairColor: string;
|
||||
weight: number;
|
||||
eyeColor: string;
|
||||
specialCharacteristics: string;
|
||||
}
|
||||
|
||||
export interface DS4CharacterDataSourceDataCurrency {
|
||||
gold: number;
|
||||
silver: number;
|
||||
copper: number;
|
||||
}
|
||||
|
||||
export interface DS4CharacterDataSourceDataSlayerPoints {
|
||||
value: number;
|
||||
}
|
||||
|
|
|
@ -5,15 +5,17 @@
|
|||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import { DS4ActiveEffect } from "../../active-effect";
|
||||
import { ModifiableDataBaseTotal } from "../../common/common-data";
|
||||
import { DS4 } from "../../config";
|
||||
import { getCanvas, getGame } from "../../helpers";
|
||||
import type { DS4Item } from "../../item/item";
|
||||
import { DS4Settings, getDS4Settings } from "../../settings";
|
||||
import notifications from "../../ui/notifications";
|
||||
import { enforce } from "../../utils";
|
||||
import { isCheck } from "../actor-data-properties";
|
||||
import { DS4ActiveEffect } from "../active-effect";
|
||||
import { DS4 } from "../config";
|
||||
import { getCanvas, getGame } from "../helpers";
|
||||
import { getDS4Settings } from "../settings";
|
||||
import notifications from "../ui/notifications";
|
||||
import { enforce } from "../utils";
|
||||
import { isCheck } from "./actor-data-properties-base";
|
||||
|
||||
import type { ModifiableDataBaseTotal } from "../common/common-data";
|
||||
import type { DS4Settings } from "../settings";
|
||||
import type { DS4Item } from "../item/item";
|
||||
|
||||
/**
|
||||
* The base sheet class for all {@link DS4Actor}s.
|
|
@ -3,15 +3,17 @@
|
|||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import { ModifiableDataBaseTotal } from "../common/common-data";
|
||||
import { DS4 } from "../config";
|
||||
import { getGame } from "../helpers";
|
||||
import { DS4Item } from "../item/item";
|
||||
import { DS4ArmorDataProperties, DS4ShieldDataProperties } from "../item/item-data-properties";
|
||||
import { ItemType } from "../item/item-data-source";
|
||||
import { createCheckRoll } from "../rolls/check-factory";
|
||||
import { Check } from "./actor-data-properties";
|
||||
import { isAttribute, isTrait } from "./actor-data-source";
|
||||
import { isAttribute, isTrait } from "./actor-data-source-base";
|
||||
|
||||
import type { ModifiableDataBaseTotal } from "../common/common-data";
|
||||
import type { DS4ArmorDataProperties } from "../item/armor/armor-data-properties";
|
||||
import type { DS4Item } from "../item/item";
|
||||
import type { ItemType } from "../item/item-data-source";
|
||||
import type { DS4ShieldDataProperties } from "../item/shield/shield-data-properties";
|
||||
import type { Check } from "./actor-data-properties-base";
|
||||
|
||||
declare global {
|
||||
interface DocumentClassConfig {
|
||||
|
@ -157,9 +159,6 @@ export class DS4Actor extends Actor {
|
|||
|
||||
this.data.data.combatValues.hitPoints.max = this.data.data.combatValues.hitPoints.total;
|
||||
this.data.data.checks.defend = this.data.data.combatValues.defense.total;
|
||||
if (this.data.type === "character") {
|
||||
this.data.data.slayerPoints.max = 3;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -167,32 +166,14 @@ export class DS4Actor extends Actor {
|
|||
* given in dot notation.
|
||||
*/
|
||||
get finalDerivedDataProperties(): string[] {
|
||||
return ["data.combatValues.hitPoints.max", "data.checks.defend"].concat(
|
||||
this.data.type === "character" ? ["data.slayerPoints.max"] : [],
|
||||
);
|
||||
return ["data.combatValues.hitPoints.max", "data.checks.defend"];
|
||||
}
|
||||
|
||||
/**
|
||||
* The list of item types that can be owned by this actor.
|
||||
*/
|
||||
get ownableItemTypes(): Array<ItemType> {
|
||||
switch (this.data.type) {
|
||||
case "character":
|
||||
return [
|
||||
"weapon",
|
||||
"armor",
|
||||
"shield",
|
||||
"equipment",
|
||||
"loot",
|
||||
"spell",
|
||||
"talent",
|
||||
"racialAbility",
|
||||
"language",
|
||||
"alphabet",
|
||||
];
|
||||
case "creature":
|
||||
return ["weapon", "armor", "shield", "equipment", "loot", "spell", "specialCreatureAbility"];
|
||||
}
|
||||
return ["weapon", "armor", "shield", "equipment", "loot", "spell"];
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
29
src/actor/character/character-data-properties.ts
Normal file
29
src/actor/character/character-data-properties.ts
Normal file
|
@ -0,0 +1,29 @@
|
|||
// SPDX-FileCopyrightText: 2022 Johannes Loher
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import type { DS4ActorDataPropertiesDataBase } from "../actor-data-properties-base";
|
||||
import type {
|
||||
DS4CharacterDataSourceDataBaseInfo,
|
||||
DS4CharacterDataSourceDataCurrency,
|
||||
DS4CharacterDataSourceDataProfile,
|
||||
DS4CharacterDataSourceDataProgression,
|
||||
DS4CharacterDataSourceDataSlayerPoints,
|
||||
} from "./character-data-source";
|
||||
|
||||
export interface DS4CharacterDataProperties {
|
||||
type: "character";
|
||||
data: DS4CharacterDataPropertiesData;
|
||||
}
|
||||
|
||||
interface DS4CharacterDataPropertiesData extends DS4ActorDataPropertiesDataBase {
|
||||
baseInfo: DS4CharacterDataSourceDataBaseInfo;
|
||||
progression: DS4CharacterDataSourceDataProgression;
|
||||
profile: DS4CharacterDataSourceDataProfile;
|
||||
currency: DS4CharacterDataSourceDataCurrency;
|
||||
slayerPoints: DS4CharacterDataPropertiesDataSlayerPoints;
|
||||
}
|
||||
|
||||
export interface DS4CharacterDataPropertiesDataSlayerPoints extends DS4CharacterDataSourceDataSlayerPoints {
|
||||
max: number;
|
||||
}
|
56
src/actor/character/character-data-source.ts
Normal file
56
src/actor/character/character-data-source.ts
Normal file
|
@ -0,0 +1,56 @@
|
|||
// SPDX-FileCopyrightText: 2022 Johannes Loher
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import type { UsableResource } from "../../common/common-data";
|
||||
import type { DS4ActorDataSourceDataBase } from "../actor-data-source-base";
|
||||
|
||||
export interface DS4CharacterDataSource {
|
||||
type: "character";
|
||||
data: DS4CharacterDataSourceData;
|
||||
}
|
||||
|
||||
interface DS4CharacterDataSourceData extends DS4ActorDataSourceDataBase {
|
||||
baseInfo: DS4CharacterDataSourceDataBaseInfo;
|
||||
progression: DS4CharacterDataSourceDataProgression;
|
||||
profile: DS4CharacterDataSourceDataProfile;
|
||||
currency: DS4CharacterDataSourceDataCurrency;
|
||||
slayerPoints: DS4CharacterDataSourceDataSlayerPoints;
|
||||
}
|
||||
|
||||
export interface DS4CharacterDataSourceDataBaseInfo {
|
||||
race: string;
|
||||
class: string;
|
||||
heroClass: string;
|
||||
culture: string;
|
||||
}
|
||||
|
||||
export interface DS4CharacterDataSourceDataProgression {
|
||||
level: number;
|
||||
experiencePoints: number;
|
||||
talentPoints: UsableResource<number>;
|
||||
progressPoints: UsableResource<number>;
|
||||
}
|
||||
|
||||
export interface DS4CharacterDataSourceDataProfile {
|
||||
biography: string;
|
||||
gender: string;
|
||||
birthday: string;
|
||||
birthplace: string;
|
||||
age: number;
|
||||
height: number;
|
||||
hairColor: string;
|
||||
weight: number;
|
||||
eyeColor: string;
|
||||
specialCharacteristics: string;
|
||||
}
|
||||
|
||||
export interface DS4CharacterDataSourceDataCurrency {
|
||||
gold: number;
|
||||
silver: number;
|
||||
copper: number;
|
||||
}
|
||||
|
||||
export interface DS4CharacterDataSourceDataSlayerPoints {
|
||||
value: number;
|
||||
}
|
|
@ -2,7 +2,7 @@
|
|||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import { DS4ActorSheet } from "./actor-sheet";
|
||||
import { DS4ActorSheet } from "../actor-sheet";
|
||||
|
||||
/**
|
||||
* The Sheet class for DS4 Character Actors
|
29
src/actor/character/character.ts
Normal file
29
src/actor/character/character.ts
Normal file
|
@ -0,0 +1,29 @@
|
|||
// SPDX-FileCopyrightText: 2022 Johannes Loher
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import { DS4Actor } from "../actor";
|
||||
|
||||
import type { ItemType } from "../../item/item-data-source";
|
||||
|
||||
export class DS4Character extends DS4Actor {
|
||||
/** @override */
|
||||
prepareFinalDerivedData(): void {
|
||||
super.prepareFinalDerivedData();
|
||||
this.data.data.slayerPoints.max = 3;
|
||||
}
|
||||
|
||||
/** @override */
|
||||
get finalDerivedDataProperties(): string[] {
|
||||
return [...super.finalDerivedDataProperties, "data.slayerPoints.max"];
|
||||
}
|
||||
|
||||
/** @override */
|
||||
get ownableItemTypes(): Array<ItemType> {
|
||||
return [...super.ownableItemTypes, "talent", "racialAbility", "language", "alphabet"];
|
||||
}
|
||||
}
|
||||
|
||||
export interface DS4Character {
|
||||
data: foundry.data.ActorData & { type: "character"; _source: { type: "character" } };
|
||||
}
|
15
src/actor/creature/creature-data-properties.ts
Normal file
15
src/actor/creature/creature-data-properties.ts
Normal file
|
@ -0,0 +1,15 @@
|
|||
// SPDX-FileCopyrightText: 2022 Johannes Loher
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import type { DS4ActorDataPropertiesDataBase } from "../actor-data-properties-base";
|
||||
import type { DS4CreatureDataSourceDataBaseInfo } from "./creature-data-source";
|
||||
|
||||
export interface DS4CreatureDataProperties {
|
||||
type: "creature";
|
||||
data: DS4CreatureDataPropertiesData;
|
||||
}
|
||||
|
||||
interface DS4CreatureDataPropertiesData extends DS4ActorDataPropertiesDataBase {
|
||||
baseInfo: DS4CreatureDataSourceDataBaseInfo;
|
||||
}
|
28
src/actor/creature/creature-data-source.ts
Normal file
28
src/actor/creature/creature-data-source.ts
Normal file
|
@ -0,0 +1,28 @@
|
|||
// SPDX-FileCopyrightText: 2022 Johannes Loher
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import type { DS4 } from "../../config";
|
||||
import type { DS4ActorDataSourceDataBase } from "../actor-data-source-base";
|
||||
|
||||
export interface DS4CreatureDataSource {
|
||||
type: "creature";
|
||||
data: DS4CreatureDataSourceData;
|
||||
}
|
||||
|
||||
interface DS4CreatureDataSourceData extends DS4ActorDataSourceDataBase {
|
||||
baseInfo: DS4CreatureDataSourceDataBaseInfo;
|
||||
}
|
||||
|
||||
export interface DS4CreatureDataSourceDataBaseInfo {
|
||||
loot: string;
|
||||
foeFactor: number;
|
||||
creatureType: CreatureType;
|
||||
sizeCategory: SizeCategory;
|
||||
experiencePoints: number;
|
||||
description: string;
|
||||
}
|
||||
|
||||
type CreatureType = keyof typeof DS4.i18n.creatureTypes;
|
||||
|
||||
type SizeCategory = keyof typeof DS4.i18n.creatureSizeCategories;
|
|
@ -2,7 +2,7 @@
|
|||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import { DS4ActorSheet } from "./actor-sheet";
|
||||
import { DS4ActorSheet } from "../actor-sheet";
|
||||
|
||||
/**
|
||||
* The Sheet class for DS4 Creature Actors
|
18
src/actor/creature/creature.ts
Normal file
18
src/actor/creature/creature.ts
Normal file
|
@ -0,0 +1,18 @@
|
|||
// SPDX-FileCopyrightText: 2022 Johannes Loher
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import { DS4Actor } from "../actor";
|
||||
|
||||
import type { ItemType } from "../../item/item-data-source";
|
||||
|
||||
export class DS4Creature extends DS4Actor {
|
||||
/** @override */
|
||||
get ownableItemTypes(): Array<ItemType> {
|
||||
return [...super.ownableItemTypes, "specialCreatureAbility"];
|
||||
}
|
||||
}
|
||||
|
||||
export interface DS4Creature {
|
||||
data: foundry.data.ActorData & { type: "creature"; _source: { type: "creature" } };
|
||||
}
|
23
src/actor/proxy.ts
Normal file
23
src/actor/proxy.ts
Normal file
|
@ -0,0 +1,23 @@
|
|||
// SPDX-FileCopyrightText: 2022 Johannes Loher
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import { getGame } from "../helpers";
|
||||
import { DS4Actor } from "./actor";
|
||||
import { DS4Character } from "./character/character";
|
||||
import { DS4Creature } from "./creature/creature";
|
||||
|
||||
const handler = {
|
||||
construct(_: typeof DS4Actor, args: ConstructorParameters<typeof DS4Actor>) {
|
||||
switch (args[0]?.type) {
|
||||
case "character":
|
||||
return new DS4Character(...args);
|
||||
case "creature":
|
||||
return new DS4Creature(...args);
|
||||
default:
|
||||
throw new Error(getGame().i18n.format("DS4.ErrorInvalidActorType", { type: args[0]?.type }));
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
export const DS4ActorProxy: typeof DS4Actor = new Proxy(DS4Actor, handler);
|
|
@ -3,6 +3,7 @@
|
|||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import "../scss/ds4.scss";
|
||||
|
||||
import registerForHooks from "./hooks/hooks";
|
||||
|
||||
registerForHooks();
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import { isCheck } from "../actor/actor-data-properties";
|
||||
import { isCheck } from "../actor/actor-data-properties-base";
|
||||
import { getGame } from "../helpers";
|
||||
import { DS4Item } from "../item/item";
|
||||
import { createRollCheckMacro } from "../macros/roll-check";
|
||||
|
|
|
@ -5,17 +5,17 @@
|
|||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import { DS4ActiveEffect } from "../active-effect";
|
||||
import { DS4Actor } from "../actor/actor";
|
||||
import { DS4CharacterActorSheet } from "../actor/sheets/character-sheet";
|
||||
import { DS4CreatureActorSheet } from "../actor/sheets/creature-sheet";
|
||||
import { DS4CharacterActorSheet } from "../actor/character/character-sheet";
|
||||
import { DS4CreatureActorSheet } from "../actor/creature/creature-sheet";
|
||||
import { DS4ActorProxy } from "../actor/proxy";
|
||||
import { DS4ChatMessage } from "../chat-message";
|
||||
import { DS4 } from "../config";
|
||||
import { preloadFonts as preloadFonts } from "../fonts";
|
||||
import { preloadFonts } from "../fonts";
|
||||
import registerHandlebarsHelpers from "../handlebars/handlebars-helpers";
|
||||
import registerHandlebarsPartials from "../handlebars/handlebars-partials";
|
||||
import { getGame } from "../helpers";
|
||||
import { DS4Item } from "../item/item";
|
||||
import { DS4ItemSheet } from "../item/item-sheet";
|
||||
import { DS4ItemProxy } from "../item/proxy";
|
||||
import logger from "../logger";
|
||||
import { macros } from "../macros/macros";
|
||||
import { migration } from "../migrations";
|
||||
|
@ -26,6 +26,9 @@ import registerSlayingDiceModifier from "../rolls/slaying-dice-modifier";
|
|||
import { registerSystemSettings } from "../settings";
|
||||
import { DS4TokenDocument } from "../token-document";
|
||||
|
||||
import type { DS4Actor } from "../actor/actor";
|
||||
import type { DS4Item } from "../item/item";
|
||||
|
||||
export default function registerForInitHook(): void {
|
||||
Hooks.once("init", init);
|
||||
}
|
||||
|
@ -34,8 +37,8 @@ async function init() {
|
|||
logger.info(`Initializing the DS4 Game System\n${DS4.ASCII}`);
|
||||
|
||||
getGame().ds4 = {
|
||||
DS4Actor,
|
||||
DS4Item,
|
||||
DS4Actor: DS4ActorProxy,
|
||||
DS4Item: DS4ItemProxy,
|
||||
DS4,
|
||||
createCheckRoll,
|
||||
migration,
|
||||
|
@ -44,8 +47,8 @@ async function init() {
|
|||
|
||||
CONFIG.DS4 = DS4;
|
||||
|
||||
CONFIG.Actor.documentClass = DS4Actor;
|
||||
CONFIG.Item.documentClass = DS4Item;
|
||||
CONFIG.Actor.documentClass = DS4ActorProxy;
|
||||
CONFIG.Item.documentClass = DS4ItemProxy;
|
||||
CONFIG.ActiveEffect.documentClass = DS4ActiveEffect;
|
||||
CONFIG.ChatMessage.documentClass = DS4ChatMessage;
|
||||
CONFIG.Token.documentClass = DS4TokenDocument;
|
||||
|
|
|
@ -20,9 +20,7 @@ export default function registerForRenderHooks(): void {
|
|||
* @param html - The {@link JQuery} representing the HTML of the application.
|
||||
*/
|
||||
function selectTargetInputOnFocus(app: Application, html: JQuery) {
|
||||
$(html)
|
||||
.find("input")
|
||||
.on("focus", (ev: JQuery.FocusEvent<HTMLInputElement>) => {
|
||||
html.find("input").on("focus", (ev: JQuery.FocusEvent<HTMLInputElement>) => {
|
||||
ev.currentTarget.select();
|
||||
});
|
||||
}
|
||||
|
|
13
src/item/alphabet/alphabet-data-properties.ts
Normal file
13
src/item/alphabet/alphabet-data-properties.ts
Normal file
|
@ -0,0 +1,13 @@
|
|||
// SPDX-FileCopyrightText: 2021 Johannes Loher
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import type { DS4ItemDataPropertiesDataRollable } from "../item-data-properties-base";
|
||||
import type { DS4AlphabetDataSourceData } from "./alphabet-data-source";
|
||||
|
||||
export interface DS4AlphabetDataProperties {
|
||||
type: "alphabet";
|
||||
data: DS4AlphabetDataPropertiesData;
|
||||
}
|
||||
|
||||
interface DS4AlphabetDataPropertiesData extends DS4AlphabetDataSourceData, DS4ItemDataPropertiesDataRollable {}
|
12
src/item/alphabet/alphabet-data-source.ts
Normal file
12
src/item/alphabet/alphabet-data-source.ts
Normal file
|
@ -0,0 +1,12 @@
|
|||
// SPDX-FileCopyrightText: 2022 Johannes Loher
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import type { DS4ItemDataSourceDataBase } from "../item-data-source-base";
|
||||
|
||||
export interface DS4AlphabetDataSource {
|
||||
type: "alphabet";
|
||||
data: DS4AlphabetDataSourceData;
|
||||
}
|
||||
|
||||
export type DS4AlphabetDataSourceData = DS4ItemDataSourceDataBase;
|
11
src/item/alphabet/alphabet.ts
Normal file
11
src/item/alphabet/alphabet.ts
Normal file
|
@ -0,0 +1,11 @@
|
|||
// SPDX-FileCopyrightText: 2022 Johannes Loher
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import { DS4Item } from "../item";
|
||||
|
||||
export class DS4Alphabet extends DS4Item {}
|
||||
|
||||
export interface DS4Alphabet {
|
||||
data: foundry.data.ItemData & { type: "alphabet"; _source: { type: "alphabet" } };
|
||||
}
|
13
src/item/armor/armor-data-properties.ts
Normal file
13
src/item/armor/armor-data-properties.ts
Normal file
|
@ -0,0 +1,13 @@
|
|||
// SPDX-FileCopyrightText: 2022 Johannes Loher
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import type { DS4ItemDataPropertiesDataRollable } from "../item-data-properties-base";
|
||||
import type { DS4ArmorDataSourceData } from "./armor-data-source";
|
||||
|
||||
export interface DS4ArmorDataProperties {
|
||||
type: "armor";
|
||||
data: DS4ArmorDataPropertiesData;
|
||||
}
|
||||
|
||||
interface DS4ArmorDataPropertiesData extends DS4ArmorDataSourceData, DS4ItemDataPropertiesDataRollable {}
|
25
src/item/armor/armor-data-source.ts
Normal file
25
src/item/armor/armor-data-source.ts
Normal file
|
@ -0,0 +1,25 @@
|
|||
// SPDX-FileCopyrightText: 2022 Johannes Loher
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import type { DS4 } from "../../config";
|
||||
import type {
|
||||
DS4ItemDataSourceDataBase,
|
||||
DS4ItemDataSourceDataEquipable,
|
||||
DS4ItemDataSourceDataPhysical,
|
||||
DS4ItemDataSourceDataProtective,
|
||||
} from "../item-data-source-base";
|
||||
|
||||
export interface DS4ArmorDataSource {
|
||||
type: "armor";
|
||||
data: DS4ArmorDataSourceData;
|
||||
}
|
||||
|
||||
export interface DS4ArmorDataSourceData
|
||||
extends DS4ItemDataSourceDataBase,
|
||||
DS4ItemDataSourceDataPhysical,
|
||||
DS4ItemDataSourceDataEquipable,
|
||||
DS4ItemDataSourceDataProtective {
|
||||
armorMaterialType: keyof typeof DS4.i18n.armorMaterialTypes;
|
||||
armorType: keyof typeof DS4.i18n.armorTypes;
|
||||
}
|
11
src/item/armor/armor.ts
Normal file
11
src/item/armor/armor.ts
Normal file
|
@ -0,0 +1,11 @@
|
|||
// SPDX-FileCopyrightText: 2022 Johannes Loher
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import { DS4Item } from "../item";
|
||||
|
||||
export class DS4Armor extends DS4Item {}
|
||||
|
||||
export interface DS4Armor {
|
||||
data: foundry.data.ItemData & { type: "armor"; _source: { type: "armor" } };
|
||||
}
|
13
src/item/equipment/equipment-data-properties.ts
Normal file
13
src/item/equipment/equipment-data-properties.ts
Normal file
|
@ -0,0 +1,13 @@
|
|||
// SPDX-FileCopyrightText: 2021 Johannes Loher
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import type { DS4ItemDataPropertiesDataRollable } from "../item-data-properties-base";
|
||||
import type { DS4EquipmentDataSourceData } from "./equipment-data-source";
|
||||
|
||||
export interface DS4EquipmentDataProperties {
|
||||
type: "equipment";
|
||||
data: DS4EquipmentDataPropertiesData;
|
||||
}
|
||||
|
||||
interface DS4EquipmentDataPropertiesData extends DS4EquipmentDataSourceData, DS4ItemDataPropertiesDataRollable {}
|
19
src/item/equipment/equipment-data-source.ts
Normal file
19
src/item/equipment/equipment-data-source.ts
Normal file
|
@ -0,0 +1,19 @@
|
|||
// SPDX-FileCopyrightText: 2022 Johannes Loher
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import type {
|
||||
DS4ItemDataSourceDataBase,
|
||||
DS4ItemDataSourceDataEquipable,
|
||||
DS4ItemDataSourceDataPhysical,
|
||||
} from "../item-data-source-base";
|
||||
|
||||
export interface DS4EquipmentDataSource {
|
||||
type: "equipment";
|
||||
data: DS4EquipmentDataSourceData;
|
||||
}
|
||||
|
||||
export interface DS4EquipmentDataSourceData
|
||||
extends DS4ItemDataSourceDataBase,
|
||||
DS4ItemDataSourceDataPhysical,
|
||||
DS4ItemDataSourceDataEquipable {}
|
11
src/item/equipment/equipment.ts
Normal file
11
src/item/equipment/equipment.ts
Normal file
|
@ -0,0 +1,11 @@
|
|||
// SPDX-FileCopyrightText: 2022 Johannes Loher
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import { DS4Item } from "../item";
|
||||
|
||||
export class DS4Equipment extends DS4Item {}
|
||||
|
||||
export interface DS4Equipment {
|
||||
data: foundry.data.ItemData & { type: "equipment"; _source: { type: "equipment" } };
|
||||
}
|
7
src/item/item-data-properties-base.ts
Normal file
7
src/item/item-data-properties-base.ts
Normal file
|
@ -0,0 +1,7 @@
|
|||
// SPDX-FileCopyrightText: 2021 Johannes Loher
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
export interface DS4ItemDataPropertiesDataRollable {
|
||||
rollable: boolean;
|
||||
}
|
|
@ -1,21 +1,18 @@
|
|||
// SPDX-FileCopyrightText: 2021 Johannes Loher
|
||||
// SPDX-FileCopyrightText: 2022 Johannes Loher
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import { ModifiableDataBaseTotalMax } from "../common/common-data";
|
||||
import {
|
||||
DS4AlphabetDataSourceData,
|
||||
DS4ArmorDataSourceData,
|
||||
DS4EquipmentDataSourceData,
|
||||
DS4LanguageDataSourceData,
|
||||
DS4LootDataSourceData,
|
||||
DS4RacialAbilityDataSourceData,
|
||||
DS4ShieldDataSourceData,
|
||||
DS4SpecialCreatureAbilityDataSourceData,
|
||||
DS4SpellDataSourceData,
|
||||
DS4TalentDataSourceData,
|
||||
DS4WeaponDataSourceData,
|
||||
} from "./item-data-source";
|
||||
import type { DS4AlphabetDataProperties } from "./alphabet/alphabet-data-properties";
|
||||
import type { DS4ArmorDataProperties } from "./armor/armor-data-properties";
|
||||
import type { DS4EquipmentDataProperties } from "./equipment/equipment-data-properties";
|
||||
import type { DS4LanguageDataProperties } from "./language/language-data-properties";
|
||||
import type { DS4LootDataProperties } from "./loot/loot-data-properties";
|
||||
import type { DS4RacialAbilityDataProperties } from "./racial-ability/racial-ability-data-properties";
|
||||
import type { DS4ShieldDataProperties } from "./shield/shield-data-properties";
|
||||
import type { DS4SpecialCreatureAbilityDataProperties } from "./special-creature-ability/special-creature-ability-data-properties";
|
||||
import type { DS4SpellDataProperties } from "./spell/spell-data-properties";
|
||||
import type { DS4TalentDataProperties } from "./talent/talent-data-properties";
|
||||
import type { DS4WeaponDataProperties } from "./weapon/weapon-data-properties";
|
||||
|
||||
declare global {
|
||||
interface DataConfig {
|
||||
|
@ -24,107 +21,14 @@ declare global {
|
|||
}
|
||||
|
||||
export type DS4ItemDataProperties =
|
||||
| DS4WeaponDataProperties
|
||||
| DS4ArmorDataProperties
|
||||
| DS4ShieldDataProperties
|
||||
| DS4SpellDataProperties
|
||||
| DS4EquipmentDataProperties
|
||||
| DS4LootDataProperties
|
||||
| DS4TalentDataProperties
|
||||
| DS4RacialAbilityDataProperties
|
||||
| DS4LanguageDataProperties
|
||||
| DS4AlphabetDataProperties
|
||||
| DS4SpecialCreatureAbilityDataProperties;
|
||||
|
||||
export interface DS4WeaponDataProperties {
|
||||
type: "weapon";
|
||||
data: DS4WeaponDataPropertiesData;
|
||||
}
|
||||
|
||||
export interface DS4ArmorDataProperties {
|
||||
type: "armor";
|
||||
data: DS4ArmorDataPropertiesData;
|
||||
}
|
||||
|
||||
export interface DS4ShieldDataProperties {
|
||||
type: "shield";
|
||||
data: DS4ShieldDataPropertiesData;
|
||||
}
|
||||
|
||||
export interface DS4SpellDataProperties {
|
||||
type: "spell";
|
||||
data: DS4SpellDataPropertiesData;
|
||||
}
|
||||
|
||||
export interface DS4EquipmentDataProperties {
|
||||
type: "equipment";
|
||||
data: DS4EquipmentDataPropertiesData;
|
||||
}
|
||||
|
||||
export interface DS4LootDataProperties {
|
||||
type: "loot";
|
||||
data: DS4LootDataPropertiesData;
|
||||
}
|
||||
|
||||
export interface DS4TalentDataProperties {
|
||||
type: "talent";
|
||||
data: DS4TalentDataPropertiesData;
|
||||
}
|
||||
|
||||
export interface DS4RacialAbilityDataProperties {
|
||||
type: "racialAbility";
|
||||
data: DS4RacialAbilityDataPropertiesData;
|
||||
}
|
||||
|
||||
export interface DS4LanguageDataProperties {
|
||||
type: "language";
|
||||
data: DS4LanguageDataPropertiesData;
|
||||
}
|
||||
|
||||
export interface DS4AlphabetDataProperties {
|
||||
type: "alphabet";
|
||||
data: DS4AlphabetDataPropertiesData;
|
||||
}
|
||||
|
||||
export interface DS4SpecialCreatureAbilityDataProperties {
|
||||
type: "specialCreatureAbility";
|
||||
data: DS4SpecialCreatureAbilityDataPropertiesData;
|
||||
}
|
||||
|
||||
// templates
|
||||
|
||||
interface DS4ItemDataPropertiesDataRollable {
|
||||
rollable: boolean;
|
||||
}
|
||||
|
||||
//types
|
||||
|
||||
interface DS4WeaponDataPropertiesData extends DS4WeaponDataSourceData, DS4ItemDataPropertiesDataRollable {}
|
||||
|
||||
interface DS4ArmorDataPropertiesData extends DS4ArmorDataSourceData, DS4ItemDataPropertiesDataRollable {}
|
||||
|
||||
interface DS4ShieldDataPropertiesData extends DS4ShieldDataSourceData, DS4ItemDataPropertiesDataRollable {}
|
||||
|
||||
interface DS4SpellDataPropertiesData extends DS4SpellDataSourceData, DS4ItemDataPropertiesDataRollable {
|
||||
price: number | null;
|
||||
}
|
||||
|
||||
interface DS4EquipmentDataPropertiesData extends DS4EquipmentDataSourceData, DS4ItemDataPropertiesDataRollable {}
|
||||
|
||||
interface DS4LootDataPropertiesData extends DS4LootDataSourceData, DS4ItemDataPropertiesDataRollable {}
|
||||
|
||||
interface DS4TalentDataPropertiesData extends DS4TalentDataSourceData, DS4ItemDataPropertiesDataRollable {
|
||||
rank: ModifiableDataBaseTotalMax<number>;
|
||||
}
|
||||
|
||||
interface DS4RacialAbilityDataPropertiesData
|
||||
extends DS4RacialAbilityDataSourceData,
|
||||
DS4ItemDataPropertiesDataRollable {}
|
||||
|
||||
interface DS4LanguageDataPropertiesData extends DS4LanguageDataSourceData, DS4ItemDataPropertiesDataRollable {}
|
||||
|
||||
interface DS4AlphabetDataPropertiesData extends DS4AlphabetDataSourceData, DS4ItemDataPropertiesDataRollable {}
|
||||
|
||||
interface DS4SpecialCreatureAbilityDataPropertiesData
|
||||
extends DS4SpecialCreatureAbilityDataSourceData,
|
||||
DS4ItemDataPropertiesDataRollable {}
|
||||
| DS4ArmorDataProperties
|
||||
| DS4EquipmentDataProperties
|
||||
| DS4LanguageDataProperties
|
||||
| DS4LootDataProperties
|
||||
| DS4RacialAbilityDataProperties
|
||||
| DS4ShieldDataProperties
|
||||
| DS4SpecialCreatureAbilityDataProperties
|
||||
| DS4SpellDataProperties
|
||||
| DS4TalentDataProperties
|
||||
| DS4WeaponDataProperties;
|
||||
|
|
30
src/item/item-data-source-base.ts
Normal file
30
src/item/item-data-source-base.ts
Normal file
|
@ -0,0 +1,30 @@
|
|||
// SPDX-FileCopyrightText: 2021 Johannes Loher
|
||||
// SPDX-FileCopyrightText: 2021 Oliver Rümpelein
|
||||
// SPDX-FileCopyrightText: 2021 Gesina Schwalbe
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import type { DS4 } from "../config";
|
||||
|
||||
export interface DS4ItemDataSourceDataBase {
|
||||
description: string;
|
||||
}
|
||||
|
||||
export interface DS4ItemDataSourceDataPhysical {
|
||||
quantity: number;
|
||||
price: number;
|
||||
availability: keyof typeof DS4.i18n.itemAvailabilities;
|
||||
storageLocation: string;
|
||||
}
|
||||
|
||||
export function isDS4ItemDataTypePhysical(input: foundry.data.ItemData["data"]): boolean {
|
||||
return "quantity" in input && "price" in input && "availability" in input && "storageLocation" in input;
|
||||
}
|
||||
|
||||
export interface DS4ItemDataSourceDataEquipable {
|
||||
equipped: boolean;
|
||||
}
|
||||
|
||||
export interface DS4ItemDataSourceDataProtective {
|
||||
armorValue: number;
|
||||
}
|
|
@ -1,11 +1,19 @@
|
|||
// SPDX-FileCopyrightText: 2021 Johannes Loher
|
||||
// SPDX-FileCopyrightText: 2021 Oliver Rümpelein
|
||||
// SPDX-FileCopyrightText: 2021 Gesina Schwalbe
|
||||
// SPDX-FileCopyrightText: 2022 Johannes Loher
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import { ModifiableDataBaseMax } from "../common/common-data";
|
||||
import { DS4 } from "../config";
|
||||
import type { DS4 } from "../config";
|
||||
import type { DS4AlphabetDataSource } from "./alphabet/alphabet-data-source";
|
||||
import type { DS4ArmorDataSource } from "./armor/armor-data-source";
|
||||
import type { DS4EquipmentDataSource } from "./equipment/equipment-data-source";
|
||||
import type { DS4LanguageDataSource } from "./language/language-data-source";
|
||||
import type { DS4LootDataSource } from "./loot/loot-data-source";
|
||||
import type { DS4RacialAbilityDataSource } from "./racial-ability/racial-ability-data-source";
|
||||
import type { DS4ShieldDataSource } from "./shield/shield-data-source";
|
||||
import type { DS4SpecialCreatureAbilityDataSource } from "./special-creature-ability/special-creature-ability-data-source";
|
||||
import type { DS4SpellDataSource } from "./spell/spell-data-source";
|
||||
import type { DS4TalentDataSource } from "./talent/talent-data-source";
|
||||
import type { DS4WeaponDataSource } from "./weapon/weapon-data-source";
|
||||
|
||||
declare global {
|
||||
interface SourceConfig {
|
||||
|
@ -16,169 +24,14 @@ declare global {
|
|||
export type ItemType = keyof typeof DS4.i18n.itemTypes;
|
||||
|
||||
export type DS4ItemDataSource =
|
||||
| DS4WeaponDataSource
|
||||
| DS4ArmorDataSource
|
||||
| DS4ShieldDataSource
|
||||
| DS4SpellDataSource
|
||||
| DS4EquipmentDataSource
|
||||
| DS4LootDataSource
|
||||
| DS4TalentDataSource
|
||||
| DS4RacialAbilityDataSource
|
||||
| DS4LanguageDataSource
|
||||
| DS4AlphabetDataSource
|
||||
| DS4SpecialCreatureAbilityDataSource;
|
||||
|
||||
interface DS4WeaponDataSource {
|
||||
type: "weapon";
|
||||
data: DS4WeaponDataSourceData;
|
||||
}
|
||||
|
||||
interface DS4ArmorDataSource {
|
||||
type: "armor";
|
||||
data: DS4ArmorDataSourceData;
|
||||
}
|
||||
|
||||
interface DS4ShieldDataSource {
|
||||
type: "shield";
|
||||
data: DS4ShieldDataSourceData;
|
||||
}
|
||||
|
||||
interface DS4SpellDataSource {
|
||||
type: "spell";
|
||||
data: DS4SpellDataSourceData;
|
||||
}
|
||||
|
||||
interface DS4EquipmentDataSource {
|
||||
type: "equipment";
|
||||
data: DS4EquipmentDataSourceData;
|
||||
}
|
||||
|
||||
interface DS4LootDataSource {
|
||||
type: "loot";
|
||||
data: DS4LootDataSourceData;
|
||||
}
|
||||
|
||||
interface DS4TalentDataSource {
|
||||
type: "talent";
|
||||
data: DS4TalentDataSourceData;
|
||||
}
|
||||
|
||||
interface DS4RacialAbilityDataSource {
|
||||
type: "racialAbility";
|
||||
data: DS4RacialAbilityDataSourceData;
|
||||
}
|
||||
|
||||
interface DS4LanguageDataSource {
|
||||
type: "language";
|
||||
data: DS4LanguageDataSourceData;
|
||||
}
|
||||
|
||||
interface DS4AlphabetDataSource {
|
||||
type: "alphabet";
|
||||
data: DS4AlphabetDataSourceData;
|
||||
}
|
||||
|
||||
interface DS4SpecialCreatureAbilityDataSource {
|
||||
type: "specialCreatureAbility";
|
||||
data: DS4SpecialCreatureAbilityDataSourceData;
|
||||
}
|
||||
|
||||
// templates
|
||||
|
||||
interface DS4ItemDataSourceDataBase {
|
||||
description: string;
|
||||
}
|
||||
|
||||
interface DS4ItemDataSourceDataPhysical {
|
||||
quantity: number;
|
||||
price: number;
|
||||
availability: keyof typeof DS4.i18n.itemAvailabilities;
|
||||
storageLocation: string;
|
||||
}
|
||||
|
||||
export function isDS4ItemDataTypePhysical(input: foundry.data.ItemData["data"]): boolean {
|
||||
return "quantity" in input && "price" in input && "availability" in input && "storageLocation" in input;
|
||||
}
|
||||
|
||||
interface DS4ItemDataSourceDataEquipable {
|
||||
equipped: boolean;
|
||||
}
|
||||
|
||||
interface DS4ItemDataSourceDataProtective {
|
||||
armorValue: number;
|
||||
}
|
||||
|
||||
// types
|
||||
|
||||
export interface DS4WeaponDataSourceData
|
||||
extends DS4ItemDataSourceDataBase,
|
||||
DS4ItemDataSourceDataPhysical,
|
||||
DS4ItemDataSourceDataEquipable {
|
||||
attackType: AttackType;
|
||||
weaponBonus: number;
|
||||
opponentDefense: number;
|
||||
}
|
||||
|
||||
export type AttackType = keyof typeof DS4.i18n.attackTypes;
|
||||
|
||||
export interface DS4ArmorDataSourceData
|
||||
extends DS4ItemDataSourceDataBase,
|
||||
DS4ItemDataSourceDataPhysical,
|
||||
DS4ItemDataSourceDataEquipable,
|
||||
DS4ItemDataSourceDataProtective {
|
||||
armorMaterialType: keyof typeof DS4.i18n.armorMaterialTypes;
|
||||
armorType: keyof typeof DS4.i18n.armorTypes;
|
||||
}
|
||||
|
||||
export interface DS4ShieldDataSourceData
|
||||
extends DS4ItemDataSourceDataBase,
|
||||
DS4ItemDataSourceDataPhysical,
|
||||
DS4ItemDataSourceDataEquipable,
|
||||
DS4ItemDataSourceDataProtective {}
|
||||
|
||||
export type CooldownDuration = keyof typeof DS4.i18n.cooldownDurations;
|
||||
|
||||
export interface DS4SpellDataSourceData extends DS4ItemDataSourceDataBase, DS4ItemDataSourceDataEquipable {
|
||||
spellType: keyof typeof DS4.i18n.spellTypes;
|
||||
bonus: string;
|
||||
spellCategory: keyof typeof DS4.i18n.spellCategories;
|
||||
maxDistance: UnitData<DistanceUnit>;
|
||||
effectRadius: UnitData<DistanceUnit>;
|
||||
duration: UnitData<TemporalUnit>;
|
||||
cooldownDuration: CooldownDuration;
|
||||
minimumLevels: {
|
||||
healer: number | null;
|
||||
wizard: number | null;
|
||||
sorcerer: number | null;
|
||||
};
|
||||
}
|
||||
|
||||
export interface UnitData<UnitType> {
|
||||
value: string;
|
||||
unit: UnitType;
|
||||
}
|
||||
|
||||
type DistanceUnit = keyof typeof DS4.i18n.distanceUnits;
|
||||
|
||||
type TemporalUnit = keyof typeof DS4.i18n.temporalUnits;
|
||||
|
||||
export interface DS4EquipmentDataSourceData
|
||||
extends DS4ItemDataSourceDataBase,
|
||||
DS4ItemDataSourceDataPhysical,
|
||||
DS4ItemDataSourceDataEquipable {}
|
||||
|
||||
export interface DS4LootDataSourceData extends DS4ItemDataSourceDataBase, DS4ItemDataSourceDataPhysical {}
|
||||
|
||||
export interface DS4TalentDataSourceData extends DS4ItemDataSourceDataBase {
|
||||
rank: ModifiableDataBaseMax<number>;
|
||||
}
|
||||
|
||||
export type DS4RacialAbilityDataSourceData = DS4ItemDataSourceDataBase;
|
||||
|
||||
export type DS4LanguageDataSourceData = DS4ItemDataSourceDataBase;
|
||||
|
||||
export type DS4AlphabetDataSourceData = DS4ItemDataSourceDataBase;
|
||||
|
||||
export interface DS4SpecialCreatureAbilityDataSourceData extends DS4ItemDataSourceDataBase {
|
||||
experiencePoints: number;
|
||||
}
|
||||
| DS4ArmorDataSource
|
||||
| DS4EquipmentDataSource
|
||||
| DS4LanguageDataSource
|
||||
| DS4LootDataSource
|
||||
| DS4RacialAbilityDataSource
|
||||
| DS4ShieldDataSource
|
||||
| DS4SpecialCreatureAbilityDataSource
|
||||
| DS4SpellDataSource
|
||||
| DS4TalentDataSource
|
||||
| DS4WeaponDataSource;
|
||||
|
|
|
@ -9,7 +9,7 @@ import { DS4 } from "../config";
|
|||
import { getGame } from "../helpers";
|
||||
import notifications from "../ui/notifications";
|
||||
import { enforce } from "../utils";
|
||||
import { isDS4ItemDataTypePhysical } from "./item-data-source";
|
||||
import { isDS4ItemDataTypePhysical } from "./item-data-source-base";
|
||||
|
||||
/**
|
||||
* The Sheet class for DS4 Items
|
||||
|
|
159
src/item/item.ts
159
src/item/item.ts
|
@ -3,12 +3,9 @@
|
|||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import { DS4 } from "../config";
|
||||
import { getGame } from "../helpers";
|
||||
import { createCheckRoll } from "../rolls/check-factory";
|
||||
import notifications from "../ui/notifications";
|
||||
import { AttackType, ItemType } from "./item-data-source";
|
||||
import { calculateSpellPrice } from "./type-specific-helpers/spell";
|
||||
|
||||
import type { ItemType } from "./item-data-source";
|
||||
|
||||
declare global {
|
||||
interface DocumentClassConfig {
|
||||
|
@ -27,19 +24,8 @@ export class DS4Item extends Item {
|
|||
|
||||
/** @override */
|
||||
prepareDerivedData(): void {
|
||||
if (this.data.type === "talent") {
|
||||
const data = this.data.data;
|
||||
data.rank.total = data.rank.base + data.rank.mod;
|
||||
}
|
||||
if (this.data.type === "weapon" || this.data.type === "spell") {
|
||||
this.data.data.rollable = this.data.data.equipped;
|
||||
} else {
|
||||
this.data.data.rollable = false;
|
||||
}
|
||||
if (this.data.type === "spell") {
|
||||
this.data.data.price = calculateSpellPrice(this.data.data);
|
||||
}
|
||||
}
|
||||
|
||||
isNonEquippedEuipable(): boolean {
|
||||
return "equipped" in this.data.data && !this.data.data.equipped;
|
||||
|
@ -49,9 +35,6 @@ export class DS4Item extends Item {
|
|||
* The number of times that active effect changes originating from this item should be applied.
|
||||
*/
|
||||
get activeEffectFactor(): number | undefined {
|
||||
if (this.data.type === "talent") {
|
||||
return this.data.data.rank.total;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -66,142 +49,8 @@ export class DS4Item extends Item {
|
|||
* Roll a check for an action with this item.
|
||||
* @param options - Additional options to customize the roll
|
||||
*/
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
async roll(options: { speaker?: { token?: TokenDocument; alias?: string } } = {}): Promise<void> {
|
||||
switch (this.data.type) {
|
||||
case "weapon":
|
||||
return this.rollWeapon(options);
|
||||
case "spell":
|
||||
return this.rollSpell(options);
|
||||
default:
|
||||
throw new Error(
|
||||
getGame().i18n.format("DS4.ErrorRollingForItemTypeNotPossible", { type: this.data.type }),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
protected async rollWeapon(options: { speaker?: { token?: TokenDocument; alias?: string } } = {}): Promise<void> {
|
||||
if (!(this.data.type === "weapon")) {
|
||||
throw new Error(
|
||||
getGame().i18n.format("DS4.ErrorWrongItemType", {
|
||||
actualType: this.data.type,
|
||||
expectedType: "weapon",
|
||||
id: this.id,
|
||||
name: this.name,
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
if (!this.data.data.equipped) {
|
||||
return notifications.warn(
|
||||
getGame().i18n.format("DS4.WarningItemMustBeEquippedToBeRolled", {
|
||||
name: this.name,
|
||||
id: this.id,
|
||||
type: this.data.type,
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
if (!this.actor) {
|
||||
throw new Error(getGame().i18n.format("DS4.ErrorCannotRollUnownedItem", { name: this.name, id: this.id }));
|
||||
}
|
||||
|
||||
const ownerDataData = this.actor.data.data;
|
||||
const weaponBonus = this.data.data.weaponBonus;
|
||||
const combatValue = await this.getCombatValueKeyForAttackType(this.data.data.attackType);
|
||||
const checkTargetNumber = ownerDataData.combatValues[combatValue].total + weaponBonus;
|
||||
|
||||
const speaker = ChatMessage.getSpeaker({ actor: this.actor, ...options.speaker });
|
||||
await createCheckRoll(checkTargetNumber, {
|
||||
rollMode: getGame().settings.get("core", "rollMode"),
|
||||
maximumCoupResult: ownerDataData.rolling.maximumCoupResult,
|
||||
minimumFumbleResult: ownerDataData.rolling.minimumFumbleResult,
|
||||
flavor: "DS4.ItemWeaponCheckFlavor",
|
||||
flavorData: { actor: speaker.alias ?? this.actor.name, weapon: this.name },
|
||||
speaker,
|
||||
});
|
||||
}
|
||||
|
||||
protected async rollSpell(options: { speaker?: { token?: TokenDocument; alias?: string } } = {}): Promise<void> {
|
||||
if (!(this.data.type === "spell")) {
|
||||
throw new Error(
|
||||
getGame().i18n.format("DS4.ErrorWrongItemType", {
|
||||
actualType: this.data.type,
|
||||
expectedType: "spell",
|
||||
id: this.id,
|
||||
name: this.name,
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
if (!this.data.data.equipped) {
|
||||
return notifications.warn(
|
||||
getGame().i18n.format("DS4.WarningItemMustBeEquippedToBeRolled", {
|
||||
name: this.name,
|
||||
id: this.id,
|
||||
type: this.data.type,
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
if (!this.actor) {
|
||||
throw new Error(getGame().i18n.format("DS4.ErrorCannotRollUnownedItem", { name: this.name, id: this.id }));
|
||||
}
|
||||
|
||||
const ownerDataData = this.actor.data.data;
|
||||
const spellModifier = Number.isNumeric(this.data.data.bonus) ? parseInt(this.data.data.bonus) : undefined;
|
||||
if (spellModifier === undefined) {
|
||||
notifications.info(
|
||||
getGame().i18n.format("DS4.InfoManuallyEnterSpellModifier", {
|
||||
name: this.name,
|
||||
spellModifier: this.data.data.bonus,
|
||||
}),
|
||||
);
|
||||
}
|
||||
const spellType = this.data.data.spellType;
|
||||
const checkTargetNumber = ownerDataData.combatValues[spellType].total + (spellModifier ?? 0);
|
||||
|
||||
const speaker = ChatMessage.getSpeaker({ actor: this.actor, ...options.speaker });
|
||||
await createCheckRoll(checkTargetNumber, {
|
||||
rollMode: getGame().settings.get("core", "rollMode"),
|
||||
maximumCoupResult: ownerDataData.rolling.maximumCoupResult,
|
||||
minimumFumbleResult: ownerDataData.rolling.minimumFumbleResult,
|
||||
flavor: "DS4.ItemSpellCheckFlavor",
|
||||
flavorData: { actor: speaker.alias ?? this.actor.name, spell: this.name },
|
||||
speaker,
|
||||
});
|
||||
}
|
||||
|
||||
protected async getCombatValueKeyForAttackType(attackType: AttackType): Promise<"meleeAttack" | "rangedAttack"> {
|
||||
if (attackType === "meleeRanged") {
|
||||
const { melee, ranged } = { ...DS4.i18n.attackTypes };
|
||||
const identifier = "attack-type-selection";
|
||||
return Dialog.prompt({
|
||||
title: getGame().i18n.localize("DS4.DialogAttackTypeSelection"),
|
||||
content: await renderTemplate("systems/ds4/templates/dialogs/simple-select-form.hbs", {
|
||||
selects: [
|
||||
{
|
||||
label: getGame().i18n.localize("DS4.AttackType"),
|
||||
identifier,
|
||||
options: { melee, ranged },
|
||||
},
|
||||
],
|
||||
}),
|
||||
label: getGame().i18n.localize("DS4.GenericOkButton"),
|
||||
callback: (html) => {
|
||||
const selectedAttackType = html.find(`#${identifier}`).val();
|
||||
if (selectedAttackType !== "melee" && selectedAttackType !== "ranged") {
|
||||
throw new Error(
|
||||
getGame().i18n.format("DS4.ErrorUnexpectedAttackType", {
|
||||
actualType: selectedAttackType,
|
||||
expectedTypes: "'melee', 'ranged'",
|
||||
}),
|
||||
);
|
||||
}
|
||||
return `${selectedAttackType}Attack` as const;
|
||||
},
|
||||
});
|
||||
} else {
|
||||
return `${attackType}Attack` as const;
|
||||
}
|
||||
throw new Error(getGame().i18n.format("DS4.ErrorRollingForItemTypeNotPossible", { type: this.data.type }));
|
||||
}
|
||||
}
|
||||
|
|
13
src/item/language/language-data-properties.ts
Normal file
13
src/item/language/language-data-properties.ts
Normal file
|
@ -0,0 +1,13 @@
|
|||
// SPDX-FileCopyrightText: 2021 Johannes Loher
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import type { DS4ItemDataPropertiesDataRollable } from "../item-data-properties-base";
|
||||
import type { DS4LanguageDataSourceData } from "./language-data-source";
|
||||
|
||||
export interface DS4LanguageDataProperties {
|
||||
type: "language";
|
||||
data: DS4LanguageDataPropertiesData;
|
||||
}
|
||||
|
||||
interface DS4LanguageDataPropertiesData extends DS4LanguageDataSourceData, DS4ItemDataPropertiesDataRollable {}
|
12
src/item/language/language-data-source.ts
Normal file
12
src/item/language/language-data-source.ts
Normal file
|
@ -0,0 +1,12 @@
|
|||
// SPDX-FileCopyrightText: 2022 Johannes Loher
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import type { DS4ItemDataSourceDataBase } from "../item-data-source-base";
|
||||
|
||||
export interface DS4LanguageDataSource {
|
||||
type: "language";
|
||||
data: DS4LanguageDataSourceData;
|
||||
}
|
||||
|
||||
export type DS4LanguageDataSourceData = DS4ItemDataSourceDataBase;
|
11
src/item/language/language.ts
Normal file
11
src/item/language/language.ts
Normal file
|
@ -0,0 +1,11 @@
|
|||
// SPDX-FileCopyrightText: 2022 Johannes Loher
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import { DS4Item } from "../item";
|
||||
|
||||
export class DS4Language extends DS4Item {}
|
||||
|
||||
export interface DS4Language {
|
||||
data: foundry.data.ItemData & { type: "language"; _source: { type: "language" } };
|
||||
}
|
13
src/item/loot/loot-data-properties.ts
Normal file
13
src/item/loot/loot-data-properties.ts
Normal file
|
@ -0,0 +1,13 @@
|
|||
// SPDX-FileCopyrightText: 2021 Johannes Loher
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import type { DS4ItemDataPropertiesDataRollable } from "../item-data-properties-base";
|
||||
import type { DS4LootDataSourceData } from "./loot-data-source";
|
||||
|
||||
export interface DS4LootDataProperties {
|
||||
type: "loot";
|
||||
data: DS4LootDataPropertiesData;
|
||||
}
|
||||
|
||||
interface DS4LootDataPropertiesData extends DS4LootDataSourceData, DS4ItemDataPropertiesDataRollable {}
|
12
src/item/loot/loot-data-source.ts
Normal file
12
src/item/loot/loot-data-source.ts
Normal file
|
@ -0,0 +1,12 @@
|
|||
// SPDX-FileCopyrightText: 2022 Johannes Loher
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import type { DS4ItemDataSourceDataBase, DS4ItemDataSourceDataPhysical } from "../item-data-source-base";
|
||||
|
||||
export interface DS4LootDataSource {
|
||||
type: "loot";
|
||||
data: DS4LootDataSourceData;
|
||||
}
|
||||
|
||||
export interface DS4LootDataSourceData extends DS4ItemDataSourceDataBase, DS4ItemDataSourceDataPhysical {}
|
11
src/item/loot/loot.ts
Normal file
11
src/item/loot/loot.ts
Normal file
|
@ -0,0 +1,11 @@
|
|||
// SPDX-FileCopyrightText: 2022 Johannes Loher
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import { DS4Item } from "../item";
|
||||
|
||||
export class DS4Loot extends DS4Item {}
|
||||
|
||||
export interface DS4Loot {
|
||||
data: foundry.data.ItemData & { type: "loot"; _source: { type: "loot" } };
|
||||
}
|
50
src/item/proxy.ts
Normal file
50
src/item/proxy.ts
Normal file
|
@ -0,0 +1,50 @@
|
|||
// SPDX-FileCopyrightText: 2022 Johannes Loher
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import { getGame } from "../helpers";
|
||||
import { DS4Alphabet } from "./alphabet/alphabet";
|
||||
import { DS4Armor } from "./armor/armor";
|
||||
import { DS4Equipment } from "./equipment/equipment";
|
||||
import { DS4Item } from "./item";
|
||||
import { DS4Language } from "./language/language";
|
||||
import { DS4Loot } from "./loot/loot";
|
||||
import { DS4RacialAbility } from "./racial-ability/racial-ability";
|
||||
import { DS4Shield } from "./shield/shield";
|
||||
import { DS4SpecialCreatureAbility } from "./special-creature-ability/special-creature-ability";
|
||||
import { DS4Spell } from "./spell/spell";
|
||||
import { DS4Talent } from "./talent/talent";
|
||||
import { DS4Weapon } from "./weapon/weapon";
|
||||
|
||||
const handler = {
|
||||
construct(_: typeof DS4Item, args: ConstructorParameters<typeof DS4Item>) {
|
||||
switch (args[0]?.type) {
|
||||
case "alphabet":
|
||||
return new DS4Alphabet(...args);
|
||||
case "armor":
|
||||
return new DS4Armor(...args);
|
||||
case "equipment":
|
||||
return new DS4Equipment(...args);
|
||||
case "language":
|
||||
return new DS4Language(...args);
|
||||
case "loot":
|
||||
return new DS4Loot(...args);
|
||||
case "racialAbility":
|
||||
return new DS4RacialAbility(...args);
|
||||
case "shield":
|
||||
return new DS4Shield(...args);
|
||||
case "specialCreatureAbility":
|
||||
return new DS4SpecialCreatureAbility(...args);
|
||||
case "spell":
|
||||
return new DS4Spell(...args);
|
||||
case "talent":
|
||||
return new DS4Talent(...args);
|
||||
case "weapon":
|
||||
return new DS4Weapon(...args);
|
||||
default:
|
||||
throw new Error(getGame().i18n.format("DS4.ErrorInvalidItemType", { type: args[0]?.type }));
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
export const DS4ItemProxy: typeof DS4Item = new Proxy(DS4Item, handler);
|
15
src/item/racial-ability/racial-ability-data-properties.ts
Normal file
15
src/item/racial-ability/racial-ability-data-properties.ts
Normal file
|
@ -0,0 +1,15 @@
|
|||
// SPDX-FileCopyrightText: 2021 Johannes Loher
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import type { DS4ItemDataPropertiesDataRollable } from "../item-data-properties-base";
|
||||
import type { DS4RacialAbilityDataSourceData } from "./racial-ability-data-source";
|
||||
|
||||
export interface DS4RacialAbilityDataProperties {
|
||||
type: "racialAbility";
|
||||
data: DS4RacialAbilityDataPropertiesData;
|
||||
}
|
||||
|
||||
interface DS4RacialAbilityDataPropertiesData
|
||||
extends DS4RacialAbilityDataSourceData,
|
||||
DS4ItemDataPropertiesDataRollable {}
|
12
src/item/racial-ability/racial-ability-data-source.ts
Normal file
12
src/item/racial-ability/racial-ability-data-source.ts
Normal file
|
@ -0,0 +1,12 @@
|
|||
// SPDX-FileCopyrightText: 2022 Johannes Loher
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import type { DS4ItemDataSourceDataBase } from "../item-data-source-base";
|
||||
|
||||
export interface DS4RacialAbilityDataSource {
|
||||
type: "racialAbility";
|
||||
data: DS4RacialAbilityDataSourceData;
|
||||
}
|
||||
|
||||
export type DS4RacialAbilityDataSourceData = DS4ItemDataSourceDataBase;
|
11
src/item/racial-ability/racial-ability.ts
Normal file
11
src/item/racial-ability/racial-ability.ts
Normal file
|
@ -0,0 +1,11 @@
|
|||
// SPDX-FileCopyrightText: 2022 Johannes Loher
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import { DS4Item } from "../item";
|
||||
|
||||
export class DS4RacialAbility extends DS4Item {}
|
||||
|
||||
export interface DS4RacialAbility {
|
||||
data: foundry.data.ItemData & { type: "racialAbility"; _source: { type: "racialAbility" } };
|
||||
}
|
13
src/item/shield/shield-data-properties.ts
Normal file
13
src/item/shield/shield-data-properties.ts
Normal file
|
@ -0,0 +1,13 @@
|
|||
// SPDX-FileCopyrightText: 2021 Johannes Loher
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import type { DS4ItemDataPropertiesDataRollable } from "../item-data-properties-base";
|
||||
import type { DS4ShieldDataSourceData } from "./shield-data-source";
|
||||
|
||||
export interface DS4ShieldDataProperties {
|
||||
type: "shield";
|
||||
data: DS4ShieldDataPropertiesData;
|
||||
}
|
||||
|
||||
interface DS4ShieldDataPropertiesData extends DS4ShieldDataSourceData, DS4ItemDataPropertiesDataRollable {}
|
21
src/item/shield/shield-data-source.ts
Normal file
21
src/item/shield/shield-data-source.ts
Normal file
|
@ -0,0 +1,21 @@
|
|||
// SPDX-FileCopyrightText: 2022 Johannes Loher
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import type {
|
||||
DS4ItemDataSourceDataBase,
|
||||
DS4ItemDataSourceDataEquipable,
|
||||
DS4ItemDataSourceDataPhysical,
|
||||
DS4ItemDataSourceDataProtective,
|
||||
} from "../item-data-source-base";
|
||||
|
||||
export interface DS4ShieldDataSource {
|
||||
type: "shield";
|
||||
data: DS4ShieldDataSourceData;
|
||||
}
|
||||
|
||||
export interface DS4ShieldDataSourceData
|
||||
extends DS4ItemDataSourceDataBase,
|
||||
DS4ItemDataSourceDataPhysical,
|
||||
DS4ItemDataSourceDataEquipable,
|
||||
DS4ItemDataSourceDataProtective {}
|
11
src/item/shield/shield.ts
Normal file
11
src/item/shield/shield.ts
Normal file
|
@ -0,0 +1,11 @@
|
|||
// SPDX-FileCopyrightText: 2022 Johannes Loher
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import { DS4Item } from "../item";
|
||||
|
||||
export class DS4Shield extends DS4Item {}
|
||||
|
||||
export interface DS4Shield {
|
||||
data: foundry.data.ItemData & { type: "shield"; _source: { type: "shield" } };
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
// SPDX-FileCopyrightText: 2021 Johannes Loher
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import type { DS4ItemDataPropertiesDataRollable } from "../item-data-properties-base";
|
||||
import type { DS4SpecialCreatureAbilityDataSourceData } from "./special-creature-ability-data-source";
|
||||
|
||||
export interface DS4SpecialCreatureAbilityDataProperties {
|
||||
type: "specialCreatureAbility";
|
||||
data: DS4SpecialCreatureAbilityDataPropertiesData;
|
||||
}
|
||||
|
||||
interface DS4SpecialCreatureAbilityDataPropertiesData
|
||||
extends DS4SpecialCreatureAbilityDataSourceData,
|
||||
DS4ItemDataPropertiesDataRollable {}
|
|
@ -0,0 +1,14 @@
|
|||
// SPDX-FileCopyrightText: 2022 Johannes Loher
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import type { DS4ItemDataSourceDataBase } from "../item-data-source-base";
|
||||
|
||||
export interface DS4SpecialCreatureAbilityDataSource {
|
||||
type: "specialCreatureAbility";
|
||||
data: DS4SpecialCreatureAbilityDataSourceData;
|
||||
}
|
||||
|
||||
export interface DS4SpecialCreatureAbilityDataSourceData extends DS4ItemDataSourceDataBase {
|
||||
experiencePoints: number;
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
// SPDX-FileCopyrightText: 2022 Johannes Loher
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import { DS4Item } from "../item";
|
||||
|
||||
export class DS4SpecialCreatureAbility extends DS4Item {}
|
||||
|
||||
export interface DS4SpecialCreatureAbility {
|
||||
data: foundry.data.ItemData & { type: "specialCreatureAbility"; _source: { type: "specialCreatureAbility" } };
|
||||
}
|
|
@ -2,7 +2,7 @@
|
|||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import { CooldownDuration, DS4SpellDataSourceData } from "../item-data-source";
|
||||
import type { CooldownDuration, DS4SpellDataSourceData } from "./spell-data-source";
|
||||
|
||||
export function calculateSpellPrice(data: DS4SpellDataSourceData): number | null {
|
||||
const spellPriceFactor = calculateSpellPriceFactor(data.cooldownDuration);
|
15
src/item/spell/spell-data-properties.ts
Normal file
15
src/item/spell/spell-data-properties.ts
Normal file
|
@ -0,0 +1,15 @@
|
|||
// SPDX-FileCopyrightText: 2021 Johannes Loher
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import type { DS4ItemDataPropertiesDataRollable } from "../item-data-properties-base";
|
||||
import type { DS4SpellDataSourceData } from "./spell-data-source";
|
||||
|
||||
export interface DS4SpellDataProperties {
|
||||
type: "spell";
|
||||
data: DS4SpellDataPropertiesData;
|
||||
}
|
||||
|
||||
interface DS4SpellDataPropertiesData extends DS4SpellDataSourceData, DS4ItemDataPropertiesDataRollable {
|
||||
price: number | null;
|
||||
}
|
35
src/item/spell/spell-data-source.ts
Normal file
35
src/item/spell/spell-data-source.ts
Normal file
|
@ -0,0 +1,35 @@
|
|||
// SPDX-FileCopyrightText: 2022 Johannes Loher
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import type { DS4 } from "../../config";
|
||||
import type { DS4ItemDataSourceDataBase, DS4ItemDataSourceDataEquipable } from "../item-data-source-base";
|
||||
|
||||
export interface DS4SpellDataSource {
|
||||
type: "spell";
|
||||
data: DS4SpellDataSourceData;
|
||||
}
|
||||
|
||||
export interface DS4SpellDataSourceData extends DS4ItemDataSourceDataBase, DS4ItemDataSourceDataEquipable {
|
||||
spellType: keyof typeof DS4.i18n.spellTypes;
|
||||
bonus: string;
|
||||
spellCategory: keyof typeof DS4.i18n.spellCategories;
|
||||
maxDistance: UnitData<DistanceUnit>;
|
||||
effectRadius: UnitData<DistanceUnit>;
|
||||
duration: UnitData<TemporalUnit>;
|
||||
cooldownDuration: CooldownDuration;
|
||||
minimumLevels: {
|
||||
healer: number | null;
|
||||
wizard: number | null;
|
||||
sorcerer: number | null;
|
||||
};
|
||||
}
|
||||
|
||||
export interface UnitData<UnitType> {
|
||||
value: string;
|
||||
unit: UnitType;
|
||||
}
|
||||
|
||||
type DistanceUnit = keyof typeof DS4.i18n.distanceUnits;
|
||||
type TemporalUnit = keyof typeof DS4.i18n.temporalUnits;
|
||||
export type CooldownDuration = keyof typeof DS4.i18n.cooldownDurations;
|
63
src/item/spell/spell.ts
Normal file
63
src/item/spell/spell.ts
Normal file
|
@ -0,0 +1,63 @@
|
|||
// SPDX-FileCopyrightText: 2022 Johannes Loher
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import { getGame } from "../../helpers";
|
||||
import { createCheckRoll } from "../../rolls/check-factory";
|
||||
import notifications from "../../ui/notifications";
|
||||
import { DS4Item } from "../item";
|
||||
import { calculateSpellPrice } from "./calculate-spell-price";
|
||||
|
||||
export class DS4Spell extends DS4Item {
|
||||
/** @override */
|
||||
prepareDerivedData(): void {
|
||||
this.data.data.rollable = this.data.data.equipped;
|
||||
this.data.data.price = calculateSpellPrice(this.data.data);
|
||||
}
|
||||
|
||||
/** @override */
|
||||
async roll(options: { speaker?: { token?: TokenDocument; alias?: string } } = {}): Promise<void> {
|
||||
const game = getGame();
|
||||
|
||||
if (!this.data.data.equipped) {
|
||||
return notifications.warn(
|
||||
game.i18n.format("DS4.WarningItemMustBeEquippedToBeRolled", {
|
||||
name: this.name,
|
||||
id: this.id,
|
||||
type: this.data.type,
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
if (!this.actor) {
|
||||
throw new Error(game.i18n.format("DS4.ErrorCannotRollUnownedItem", { name: this.name, id: this.id }));
|
||||
}
|
||||
|
||||
const ownerDataData = this.actor.data.data;
|
||||
const spellModifier = Number.isNumeric(this.data.data.bonus) ? parseInt(this.data.data.bonus) : undefined;
|
||||
if (spellModifier === undefined) {
|
||||
notifications.info(
|
||||
game.i18n.format("DS4.InfoManuallyEnterSpellModifier", {
|
||||
name: this.name,
|
||||
spellModifier: this.data.data.bonus,
|
||||
}),
|
||||
);
|
||||
}
|
||||
const spellType = this.data.data.spellType;
|
||||
const checkTargetNumber = ownerDataData.combatValues[spellType].total + (spellModifier ?? 0);
|
||||
|
||||
const speaker = ChatMessage.getSpeaker({ actor: this.actor, ...options.speaker });
|
||||
await createCheckRoll(checkTargetNumber, {
|
||||
rollMode: game.settings.get("core", "rollMode"),
|
||||
maximumCoupResult: ownerDataData.rolling.maximumCoupResult,
|
||||
minimumFumbleResult: ownerDataData.rolling.minimumFumbleResult,
|
||||
flavor: "DS4.ItemSpellCheckFlavor",
|
||||
flavorData: { actor: speaker.alias ?? this.actor.name, spell: this.name },
|
||||
speaker,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export interface DS4Spell {
|
||||
data: foundry.data.ItemData & { type: "spell"; _source: { type: "spell" } };
|
||||
}
|
16
src/item/talent/talent-data-properties.ts
Normal file
16
src/item/talent/talent-data-properties.ts
Normal file
|
@ -0,0 +1,16 @@
|
|||
// SPDX-FileCopyrightText: 2021 Johannes Loher
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import type { ModifiableDataBaseTotalMax } from "../../common/common-data";
|
||||
import type { DS4ItemDataPropertiesDataRollable } from "../item-data-properties-base";
|
||||
import type { DS4TalentDataSourceData } from "./talent-data-source";
|
||||
|
||||
export interface DS4TalentDataProperties {
|
||||
type: "talent";
|
||||
data: DS4TalentDataPropertiesData;
|
||||
}
|
||||
|
||||
interface DS4TalentDataPropertiesData extends DS4TalentDataSourceData, DS4ItemDataPropertiesDataRollable {
|
||||
rank: ModifiableDataBaseTotalMax<number>;
|
||||
}
|
15
src/item/talent/talent-data-source.ts
Normal file
15
src/item/talent/talent-data-source.ts
Normal file
|
@ -0,0 +1,15 @@
|
|||
// SPDX-FileCopyrightText: 2022 Johannes Loher
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import type { ModifiableDataBaseMax } from "../../common/common-data";
|
||||
import type { DS4ItemDataSourceDataBase } from "../item-data-source-base";
|
||||
|
||||
export interface DS4TalentDataSource {
|
||||
type: "talent";
|
||||
data: DS4TalentDataSourceData;
|
||||
}
|
||||
|
||||
export interface DS4TalentDataSourceData extends DS4ItemDataSourceDataBase {
|
||||
rank: ModifiableDataBaseMax<number>;
|
||||
}
|
23
src/item/talent/talent.ts
Normal file
23
src/item/talent/talent.ts
Normal file
|
@ -0,0 +1,23 @@
|
|||
// SPDX-FileCopyrightText: 2022 Johannes Loher
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import { DS4Item } from "../item";
|
||||
|
||||
export class DS4Talent extends DS4Item {
|
||||
/** @override */
|
||||
prepareDerivedData(): void {
|
||||
super.prepareDerivedData();
|
||||
const data = this.data.data;
|
||||
data.rank.total = data.rank.base + data.rank.mod;
|
||||
}
|
||||
|
||||
/** @override */
|
||||
get activeEffectFactor(): number | undefined {
|
||||
return this.data.data.rank.total;
|
||||
}
|
||||
}
|
||||
|
||||
export interface DS4Talent {
|
||||
data: foundry.data.ItemData & { type: "talent"; _source: { type: "talent" } };
|
||||
}
|
13
src/item/weapon/weapon-data-properties.ts
Normal file
13
src/item/weapon/weapon-data-properties.ts
Normal file
|
@ -0,0 +1,13 @@
|
|||
// SPDX-FileCopyrightText: 2022 Johannes Loher
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import type { DS4ItemDataPropertiesDataRollable } from "../item-data-properties-base";
|
||||
import type { DS4WeaponDataSourceData } from "./weapon-data-source";
|
||||
|
||||
interface DS4WeaponDataPropertiesData extends DS4WeaponDataSourceData, DS4ItemDataPropertiesDataRollable {}
|
||||
|
||||
export interface DS4WeaponDataProperties {
|
||||
type: "weapon";
|
||||
data: DS4WeaponDataPropertiesData;
|
||||
}
|
26
src/item/weapon/weapon-data-source.ts
Normal file
26
src/item/weapon/weapon-data-source.ts
Normal file
|
@ -0,0 +1,26 @@
|
|||
// SPDX-FileCopyrightText: 2022 Johannes Loher
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import type { DS4 } from "../../config";
|
||||
import type {
|
||||
DS4ItemDataSourceDataBase,
|
||||
DS4ItemDataSourceDataEquipable,
|
||||
DS4ItemDataSourceDataPhysical,
|
||||
} from "../item-data-source-base";
|
||||
|
||||
export interface DS4WeaponDataSource {
|
||||
type: "weapon";
|
||||
data: DS4WeaponDataSourceData;
|
||||
}
|
||||
|
||||
export interface DS4WeaponDataSourceData
|
||||
extends DS4ItemDataSourceDataBase,
|
||||
DS4ItemDataSourceDataPhysical,
|
||||
DS4ItemDataSourceDataEquipable {
|
||||
attackType: AttackType;
|
||||
weaponBonus: number;
|
||||
opponentDefense: number;
|
||||
}
|
||||
|
||||
export type AttackType = keyof typeof DS4.i18n.attackTypes;
|
89
src/item/weapon/weapon.ts
Normal file
89
src/item/weapon/weapon.ts
Normal file
|
@ -0,0 +1,89 @@
|
|||
// SPDX-FileCopyrightText: 2022 Johannes Loher
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import { DS4 } from "../../config";
|
||||
import { getGame } from "../../helpers";
|
||||
import { createCheckRoll } from "../../rolls/check-factory";
|
||||
import notifications from "../../ui/notifications";
|
||||
import { DS4Item } from "../item";
|
||||
|
||||
import type { AttackType } from "./weapon-data-source";
|
||||
|
||||
export class DS4Weapon extends DS4Item {
|
||||
/** @override */
|
||||
prepareDerivedData(): void {
|
||||
this.data.data.rollable = this.data.data.equipped;
|
||||
}
|
||||
|
||||
/** @override */
|
||||
async roll(options: { speaker?: { token?: TokenDocument; alias?: string } } = {}): Promise<void> {
|
||||
const game = getGame();
|
||||
if (!this.data.data.equipped) {
|
||||
return notifications.warn(
|
||||
game.i18n.format("DS4.WarningItemMustBeEquippedToBeRolled", {
|
||||
name: this.name,
|
||||
id: this.id,
|
||||
type: this.data.type,
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
if (!this.actor) {
|
||||
throw new Error(game.i18n.format("DS4.ErrorCannotRollUnownedItem", { name: this.name, id: this.id }));
|
||||
}
|
||||
|
||||
const ownerDataData = this.actor.data.data;
|
||||
const weaponBonus = this.data.data.weaponBonus;
|
||||
const combatValue = await this.getCombatValueKeyForAttackType(this.data.data.attackType);
|
||||
const checkTargetNumber = ownerDataData.combatValues[combatValue].total + weaponBonus;
|
||||
|
||||
const speaker = ChatMessage.getSpeaker({ actor: this.actor, ...options.speaker });
|
||||
await createCheckRoll(checkTargetNumber, {
|
||||
rollMode: getGame().settings.get("core", "rollMode"),
|
||||
maximumCoupResult: ownerDataData.rolling.maximumCoupResult,
|
||||
minimumFumbleResult: ownerDataData.rolling.minimumFumbleResult,
|
||||
flavor: "DS4.ItemWeaponCheckFlavor",
|
||||
flavorData: { actor: speaker.alias ?? this.actor.name, weapon: this.name },
|
||||
speaker,
|
||||
});
|
||||
}
|
||||
|
||||
private async getCombatValueKeyForAttackType(attackType: AttackType): Promise<"meleeAttack" | "rangedAttack"> {
|
||||
if (attackType === "meleeRanged") {
|
||||
const { melee, ranged } = { ...DS4.i18n.attackTypes };
|
||||
const identifier = "attack-type-selection";
|
||||
return Dialog.prompt({
|
||||
title: getGame().i18n.localize("DS4.DialogAttackTypeSelection"),
|
||||
content: await renderTemplate("systems/ds4/templates/dialogs/simple-select-form.hbs", {
|
||||
selects: [
|
||||
{
|
||||
label: getGame().i18n.localize("DS4.AttackType"),
|
||||
identifier,
|
||||
options: { melee, ranged },
|
||||
},
|
||||
],
|
||||
}),
|
||||
label: getGame().i18n.localize("DS4.GenericOkButton"),
|
||||
callback: (html) => {
|
||||
const selectedAttackType = html.find(`#${identifier}`).val();
|
||||
if (selectedAttackType !== "melee" && selectedAttackType !== "ranged") {
|
||||
throw new Error(
|
||||
getGame().i18n.format("DS4.ErrorUnexpectedAttackType", {
|
||||
actualType: selectedAttackType,
|
||||
expectedTypes: "'melee', 'ranged'",
|
||||
}),
|
||||
);
|
||||
}
|
||||
return `${selectedAttackType}Attack` as const;
|
||||
},
|
||||
});
|
||||
} else {
|
||||
return `${attackType}Attack` as const;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export interface DS4Weapon {
|
||||
data: foundry.data.ItemData & { type: "weapon"; _source: { type: "weapon" } };
|
||||
}
|
|
@ -2,9 +2,10 @@
|
|||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import { DS4Actor } from "../actor/actor";
|
||||
import { getCanvas, getGame } from "../helpers";
|
||||
|
||||
import type { DS4Actor } from "../actor/actor";
|
||||
|
||||
/**
|
||||
* Gets the currently active actor and token based on how {@link ChatMessage}
|
||||
* determines the current speaker.
|
||||
|
|
|
@ -2,12 +2,12 @@
|
|||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import { Check } from "../actor/actor-data-properties";
|
||||
import { DS4 } from "../config";
|
||||
import { getGame } from "../helpers";
|
||||
import notifications from "../ui/notifications";
|
||||
import { getActiveActorAndToken } from "./helpers";
|
||||
|
||||
import type { Check } from "../actor/actor-data-properties-base";
|
||||
/**
|
||||
* Creates a macro from a check drop.
|
||||
* Get an existing roll check macro if one exists, otherwise create a new one.
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import { CooldownDuration } from "../item/item-data-source";
|
||||
import {
|
||||
getActorUpdateDataGetter,
|
||||
getCompendiumMigrator,
|
||||
|
@ -45,10 +44,10 @@ function getItemUpdateData(itemData: Partial<foundry.data.ItemData["_source"]>)
|
|||
return updateData;
|
||||
}
|
||||
|
||||
function migrateCooldownDuration(cooldownDurationValue?: string, cooldownDurationUnit?: string) {
|
||||
function migrateCooldownDuration(cooldownDurationValue = "", cooldownDurationUnit = "") {
|
||||
if (Number.isNumeric(cooldownDurationValue)) {
|
||||
const value = Number.fromString(cooldownDurationValue!);
|
||||
const rounds = getRounds(cooldownDurationUnit ?? "", value);
|
||||
const value = Number.fromString(cooldownDurationValue);
|
||||
const rounds = getRounds(cooldownDurationUnit, value);
|
||||
|
||||
if (rounds * secondsPerRound > secondsPerDay) {
|
||||
return "d20d";
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import { DS4Actor } from "./actor/actor";
|
||||
import { DS4ActorProxy } from "./actor/proxy";
|
||||
import { getGame } from "./helpers";
|
||||
|
||||
let fallbackData: foundry.data.ActorData["data"] | undefined = undefined;
|
||||
|
@ -13,7 +13,7 @@ function getFallbackData() {
|
|||
for (const type of getGame().system.template.Actor?.types ?? []) {
|
||||
foundry.utils.mergeObject(
|
||||
fallbackData,
|
||||
new DS4Actor({ type: type as foundry.data.ActorData["type"], name: "temporary" }).data.data,
|
||||
new DS4ActorProxy({ type: type as foundry.data.ActorData["type"], name: "temporary" }).data.data,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,7 +8,8 @@
|
|||
"forceConsistentCasingInFileNames": true,
|
||||
"strict": true,
|
||||
"noUncheckedIndexedAccess": true,
|
||||
"resolveJsonModule": true
|
||||
"resolveJsonModule": true,
|
||||
"importsNotUsedAsValues": "error"
|
||||
},
|
||||
"include": ["src"]
|
||||
}
|
||||
|
|
10
yarn.lock
10
yarn.lock
|
@ -892,9 +892,9 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@league-of-foundry-developers/foundry-vtt-types@npm:9.249.2":
|
||||
version: 9.249.2
|
||||
resolution: "@league-of-foundry-developers/foundry-vtt-types@npm:9.249.2"
|
||||
"@league-of-foundry-developers/foundry-vtt-types@npm:9.249.3":
|
||||
version: 9.249.3
|
||||
resolution: "@league-of-foundry-developers/foundry-vtt-types@npm:9.249.3"
|
||||
dependencies:
|
||||
"@types/jquery": ~3.5.9
|
||||
"@types/simple-peer": ~9.11.1
|
||||
|
@ -903,7 +903,7 @@ __metadata:
|
|||
pixi.js: 5.3.11
|
||||
socket.io-client: 4.3.2
|
||||
tinymce: 5.10.1
|
||||
checksum: 31e5a7909a9928d34f60c9bd01a615502647331cea1b8f4af2c6f3ed461a1e90efd27a0801527a3eb0d6080f0bc51f62cc38e3658c85afad43522d99e8fd39a6
|
||||
checksum: 13bbcafd57637a59f44ee136e5edd78b1fedb3f0327027bd2bae8971f2eed6ad5ad84755cebc32e4b08f788e0bf5c08dd06cbe4709ae89746198658ebb511451
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
@ -3262,7 +3262,7 @@ __metadata:
|
|||
"@commitlint/cli": 16.2.1
|
||||
"@commitlint/config-conventional": 16.2.1
|
||||
"@guanghechen/rollup-plugin-copy": 1.8.6
|
||||
"@league-of-foundry-developers/foundry-vtt-types": 9.249.2
|
||||
"@league-of-foundry-developers/foundry-vtt-types": 9.249.3
|
||||
"@rollup/plugin-typescript": 8.3.0
|
||||
"@seald-io/nedb": 2.2.1
|
||||
"@types/fs-extra": 9.0.13
|
||||
|
|
Loading…
Reference in a new issue