UNPKG

fvtt-types

Version:
1,544 lines (1,296 loc) 76.1 kB
import type { AnyArray, AnyObject, DeepReadonly, InexactPartial, InterfaceToObject, Merge, NullishProps } from "#utils"; import type { documents } from "#client/client.d.mts"; import type Document from "#common/abstract/document.d.mts"; import type { DataSchema, SchemaField } from "#common/data/fields.d.mts"; import type { ActorDeltaField } from "#common/documents/token.d.mts"; import type BaseToken from "#common/documents/token.d.mts"; import type { LightData, TextureData } from "#common/data/data.mjs"; import type { VisionMode } from "#client/canvas/perception/_module.d.mts"; import type DataModel from "#common/abstract/data.mjs"; import type { TerrainData } from "#client/data/terrain-data.mjs"; import fields = foundry.data.fields; import Token = foundry.canvas.placeables.Token; declare namespace TokenDocument { /** * The document's name. */ type Name = "Token"; /** * The context used to create a `Token`. */ interface ConstructionContext extends Document.ConstructionContext<Parent> {} /** * The documents embedded within `TokenDocument`. */ type Hierarchy = Readonly<Document.HierarchyOf<Schema>>; /** * The implementation of the `TokenDocument` document instance configured through `CONFIG.Token.documentClass` in Foundry and * {@linkcode DocumentClassConfig} or {@link ConfiguredTokenDocument | `fvtt-types/configuration/ConfiguredTokenDocument`} in fvtt-types. */ type Implementation = Document.ImplementationFor<Name>; /** * The implementation of the `TokenDocument` document configured through `CONFIG.Token.documentClass` in Foundry and * {@linkcode DocumentClassConfig} in fvtt-types. */ type ImplementationClass = Document.ImplementationClassFor<Name>; /** * A document's metadata is special information about the document ranging anywhere from its name, * whether it's indexed, or to the permissions a user has over it. */ interface Metadata extends Merge< Document.Metadata.Default, Readonly<{ name: "Token"; collection: "tokens"; label: string; labelPlural: string; isEmbedded: true; embedded: TokenDocument.Metadata.Embedded; permissions: TokenDocument.Metadata.Permissions; schemaVersion: string; }> > {} namespace Metadata { /** * The embedded metadata */ interface Embedded { ActorDelta: "delta"; } /** * The permissions for whether a certain user can create, update, or delete this document. */ interface Permissions { create: "TOKEN_CREATE"; update( user: User.Internal.Implementation, doc: TokenDocument.Implementation, data: BaseToken.UpdateData, ): boolean; delete: "TOKEN_DELETE"; } } /** * A document's parent is something that can contain it. * For example an `Item` can be contained by an `Actor` which makes `Actor` one of its possible parents. */ type Parent = Scene.Implementation | null; /** * A document's direct descendants are documents that are contained directly within its schema. * This is a union of all such instances, or never if the document doesn't have any descendants. */ type DirectDescendant = ActorDelta.Stored; /** * A document's direct descendants are documents that are contained directly within its schema. * This is a union of all such classes, or never if the document doesn't have any descendants. */ type DirectDescendantClass = ActorDelta.ImplementationClass; /** * A document's descendants are any documents that are contained within, either within its schema * or its descendant's schemas. * This is a union of all such instances, or never if the document doesn't have any descendants. */ type Descendant = DirectDescendant | ActorDelta.Descendant; /** * A document's descendants are any child documents, grandchild documents, etc. * This is a union of all classes, or never if the document doesn't have any descendants. */ type DescendantClass = DirectDescendantClass | ActorDelta.DescendantClass; /** * Types of `CompendiumCollection` this document might be contained in. * Note that `this.pack` will always return a string; this is the type for `game.packs.get(this.pack)` * * Will be `never` if cannot be contained in a `CompendiumCollection`. */ type Pack = never; /** * An embedded document is a document contained in another. * For example an `Item` can be contained by an `Actor` which means `Item` can be embedded in `Actor`. * * If this is `never` it is because there are no embeddable documents (or there's a bug!). */ type Embedded = Document.ImplementationFor<Embedded.Name>; namespace Embedded { /** * An embedded document is a document contained in another. * For example an `Item` can be contained by an `Actor` which means `Item` can be embedded in `Actor`. * * If this is `never` it is because there are no embeddable documents (or there's a bug!). */ type Name = keyof Metadata.Embedded; /** * Gets the collection name for an embedded document. */ type CollectionNameOf<CollectionName extends Embedded.CollectionName> = Document.Embedded.CollectionNameFor< Metadata.Embedded, CollectionName >; /** * Gets the collection document for an embedded document. */ type DocumentFor<CollectionName extends Embedded.CollectionName> = Document.Embedded.DocumentFor< Metadata.Embedded, CollectionName >; /** * Gets the collection for an embedded document. */ type CollectionFor<CollectionName extends Embedded.CollectionName> = Document.Embedded.CollectionFor< TokenDocument.Implementation, Metadata.Embedded, CollectionName >; /** * A valid name to refer to a collection embedded in this document. For example an `Actor` * has the key `"items"` which contains `Item` instance which would make both `"Item" | "Items"` * valid keys (amongst others). */ type CollectionName = Document.Embedded.CollectionName<Metadata.Embedded>; } /** * The name of the world or embedded collection this document can find itself in. * For example an `Item` is always going to be inside a collection with a key of `items`. * This is a fixed string per document type and is primarily useful for {@link ClientDocumentMixin | `Descendant Document Events`}. */ type ParentCollectionName = Metadata["collection"]; /** * The world collection that contains this document type. Will be `never` if none exists. */ type CollectionClass = never; /** * The world collection that contains this document type. Will be `never` if none exists. */ type Collection = never; /** * An instance of `TokenDocument` that comes from the database but failed validation meaning that * its `system` and `_source` could theoretically be anything. */ type Invalid = Document.Internal.Invalid<Implementation>; /** * An instance of `TokenDocument` that comes from the database. */ type Stored = Document.Internal.Stored<TokenDocument.Implementation>; /** * The data put in {@link TokenDocument._source | `TokenDocument#_source`}. This data is what was * persisted to the database and therefore it must be valid JSON. * * For example a {@link fields.SetField | `SetField`} is persisted to the database as an array * but initialized as a {@linkcode Set}. */ interface Source extends fields.SchemaField.SourceData<Schema> {} /** * The data necessary to create a document. Used in places like {@linkcode TokenDocument.create} * and {@link TokenDocument | `new TokenDocument(...)`}. * * For example a {@link fields.SetField | `SetField`} can accept any {@linkcode Iterable} * with the right values. This means you can pass a `Set` instance, an array of values, * a generator, or any other iterable. */ interface CreateData extends fields.SchemaField.CreateData<Schema> {} /** * The data after a {@link foundry.abstract.Document | `Document`} has been initialized, for example * {@link TokenDocument.name | `TokenDocument#name`}. * * This is data transformed from {@linkcode TokenDocument.Source} and turned into more * convenient runtime data structures. For example a {@link fields.SetField | `SetField`} is * persisted to the database as an array of values but at runtime it is a `Set` instance. */ interface InitializedData extends fields.SchemaField.InitializedData<Schema> {} /** * The data used to update a document, for example {@link TokenDocument.update | `TokenDocument#update`}. * It is a distinct type from {@link TokenDocument.CreateData | `DeepPartial<TokenDocument.CreateData>`} because * it has different rules for `null` and `undefined`. */ interface UpdateData extends fields.SchemaField.UpdateData<Schema> {} /** * Schema definition shared by {@link foundry.data.PrototypeToken | `PrototypeToken`}. * Foundry technically implements this through deletion, but it's easier for us to do by extension as there are field * option overrides (e.g `textSearch` on `name`) that cause type issues otherwise. */ interface SharedProtoSchema extends DataSchema { // `name` omitted here because, while it is not in the list of omitted fields for `PrototypeToken`, it's `textSearch: true` in the base schema, but overridden to `false` in `PrototypeToken` /** * The display mode of the Token nameplate, from CONST.TOKEN_DISPLAY_MODES * @defaultValue `CONST.TOKEN_DISPLAY_MODES.NONE` */ displayName: fields.NumberField< { required: true; initial: typeof CONST.TOKEN_DISPLAY_MODES.NONE; choices: CONST.TOKEN_DISPLAY_MODES[]; validationError: "must be a value in CONST.TOKEN_DISPLAY_MODES"; }, // FIXME: Without these overrides, the branded type from `choices` is not respected, and the field types as `number` CONST.TOKEN_DISPLAY_MODES | null | undefined, CONST.TOKEN_DISPLAY_MODES, CONST.TOKEN_DISPLAY_MODES >; /** * Does this Token uniquely represent a singular Actor, or is it one of many? * @defaultValue `false` */ actorLink: fields.BooleanField; randomImg: fields.BooleanField; appendNumber: fields.BooleanField; prependAdjective: fields.BooleanField; /** * The width of the Token in grid units * @defaultValue `1` */ width: fields.NumberField<{ nullable: false; positive: true; initial: 1; step: 0.5 }>; /** * The height of the Token in grid units * @defaultValue `1` */ height: fields.NumberField<{ nullable: false; positive: true; initial: 1; step: 0.5 }>; /** * The token's texture on the canvas. */ texture: TextureData<{ initial: { src: () => typeof BaseToken.DEFAULT_ICON; anchorX: 0.5; anchorY: 0.5; fit: "contain"; alphaThreshold: 0.75; }; wildcard: true; }>; /** * Prevent the Token image from visually rotating? * @defaultValue `false` */ lockRotation: fields.BooleanField; /** * The rotation of the Token in degrees, from 0 to 360. A value of 0 represents a southward-facing Token. * @defaultValue `0` */ rotation: fields.AngleField; /** * The opacity of the token image * @defaultValue `1` */ alpha: fields.AlphaField; /** * A displayed Token disposition from CONST.TOKEN_DISPOSITIONS * @defaultValue `CONST.TOKEN_DISPOSITIONS.HOSTILE` (`-1`) */ disposition: fields.NumberField< { required: true; choices: CONST.TOKEN_DISPOSITIONS[]; initial: typeof CONST.TOKEN_DISPOSITIONS.HOSTILE; validationError: "must be a value in CONST.TOKEN_DISPOSITIONS"; }, // FIXME: Without these overrides, the branded type from `choices` is not respected, and the field types as `number` CONST.TOKEN_DISPOSITIONS | null | undefined, CONST.TOKEN_DISPOSITIONS, CONST.TOKEN_DISPOSITIONS >; /** * The display mode of Token resource bars, from CONST.TOKEN_DISPLAY_MODES * @defaultValue `CONST.TOKEN_DISPLAY_MODES.NONE` */ displayBars: fields.NumberField< { required: true; choices: CONST.TOKEN_DISPLAY_MODES[]; initial: typeof CONST.TOKEN_DISPLAY_MODES.NONE; validationError: "must be a value in CONST.TOKEN_DISPLAY_MODES"; }, // FIXME: Without these overrides, the branded type from `choices` is not respected, and the field types as `number` CONST.TOKEN_DISPLAY_MODES | null | undefined, CONST.TOKEN_DISPLAY_MODES, CONST.TOKEN_DISPLAY_MODES >; /** * The configuration of the Token's primary resource bar * @defaultValue see property */ bar1: fields.SchemaField<{ /** * The attribute path within the Token's Actor data which should be displayed * @defaultValue `game?.system.primaryTokenAttribute || null` */ attribute: fields.StringField<{ required: true; nullable: true; blank: false; initial: () => string | null; }>; }>; /** * The configuration of the Token's secondary resource bar * @defaultValue see property */ bar2: fields.SchemaField<{ /** * The attribute path within the Token's Actor data which should be displayed * @defaultValue `game?.system.secondaryTokenAttribute || null` */ attribute: fields.StringField<{ required: true; nullable: true; blank: false; initial: () => string | null; }>; }>; /** * Configuration of the light source that this Token emits * @defaultValue see {@linkcode LightData} */ light: fields.EmbeddedDataField<typeof LightData>; /** * Configuration of sight and vision properties for the Token * @defaultValue see properties * @privateRemarks Foundry has this split out into its own `@typedef TokenSightData`, but it's never * referenced outside `@typedef TokenData`, so no need for a separate interface */ sight: fields.SchemaField<{ /** * Should vision computation and rendering be active for this Token? * @defaultValue `true`, when the token's sight range is greater than 0 */ enabled: fields.BooleanField<{ initial: (data: unknown) => boolean }>; /** * How far in distance units the Token can see without the aid of a light source * @defaultValue `0` */ range: fields.NumberField<{ required: true; nullable: true; min: 0; step: 0.01; initial: 0 }>; /** * An angle at which the Token can see relative to their direction of facing * @defaultValue `360` */ angle: fields.AngleField<{ initial: 360; normalize: false }>; /** * The vision mode which is used to render the appearance of the visible area * @defaultValue `"basic"` */ visionMode: fields.StringField<{ required: true; blank: false; initial: "basic"; }>; /** * A special color which applies a hue to the visible area * @defaultValue `null` */ color: fields.ColorField; /** * A degree of attenuation which gradually fades the edges of the visible area * @defaultValue `0.1` */ attenuation: fields.AlphaField<{ initial: 0.1; }>; /** * An advanced customization for the perceived brightness of the visible area * @defaultValue `0` */ brightness: fields.NumberField<{ required: true; nullable: false; initial: 0; min: -1; max: 1; }>; /** * An advanced customization of color saturation within the visible area * @defaultValue `0` */ saturation: fields.NumberField<{ required: true; nullable: false; initial: 0; min: -1; max: 1; }>; /** * An advanced customization for contrast within the visible area * @defaultValue `0` */ contrast: fields.NumberField<{ required: true; nullable: false; initial: 0; min: -1; max: 1; }>; }>; /** * An array of detection modes which are available to this Token * @defaultValue `[]` * @remarks The validation function is a `BaseToken.#validateDetectionModes` reference, which throws if there's a duplicate mode ID */ detectionModes: fields.ArrayField< fields.SchemaField<DetectionModeSchema>, { validate: () => void; } >; /** * @defaultValue see properties */ occludable: fields.SchemaField<{ /** * @defaultValue `0` */ radius: fields.NumberField<{ required: true; nullable: false; min: 0; step: 0.01; initial: 0 }>; }>; /** * @defaultValue see properties */ ring: fields.SchemaField<{ /** * @defaultValue `false` */ enabled: fields.BooleanField; /** * @defaultValue see properties */ colors: fields.SchemaField<{ /** * @defaultValue `null` */ ring: fields.ColorField; /** * @defaultValue `null` */ background: fields.ColorField; }>; /** * @defaultValue `1` */ effects: fields.NumberField<{ required: true; initial: 1; min: 0; max: 0x7fffff; integer: true }>; /** * @defaultValue see properties */ subject: fields.SchemaField<{ /** * @defaultValue `1` */ scale: fields.NumberField<{ required: true; nullable: false; initial: 1; min: 0.5 }>; /** * @defaultValue `null` */ texture: fields.FilePathField<{ categories: ["IMAGE"] }>; }>; }>; turnMarker: fields.SchemaField<{ mode: fields.NumberField< { required: true; choices: CONST.TOKEN_TURN_MARKER_MODES[]; initial: typeof CONST.TOKEN_TURN_MARKER_MODES.DEFAULT; validationError: "must be a value in CONST.TOKEN_TURN_MARKER_MODES"; }, // FIXME: Without these overrides, the branded type from `choices` is not respected, and the field types as `number` CONST.TOKEN_TURN_MARKER_MODES | null | undefined, CONST.TOKEN_TURN_MARKER_MODES, CONST.TOKEN_TURN_MARKER_MODES >; animation: fields.StringField<{ required: true; blank: false; nullable: true }>; src: fields.FilePathField<{ categories: ["IMAGE", "VIDEO"] }>; disposition: fields.BooleanField; }>; movementAction: fields.StringField<{ required: true; blank: false; nullable: true; initial: null; choices: typeof CONFIG.Token.movement.actions; }>; /** * An object of optional key/value flags * @defaultValue `{}` */ flags: fields.DocumentFlagsField<Name, InterfaceToObject<CoreFlags>>; } interface DetectionModeSchema extends DataSchema { /** * The id of the detection mode, a key from CONFIG.Canvas.detectionModes * @defaultValue `""` */ id: fields.StringField; /** * Whether or not this detection mode is presently enabled * @defaultValue `true` */ enabled: fields.BooleanField<{ initial: true }>; /** * The maximum range in distance units at which this mode can detect targets * @defaultValue `null` */ range: fields.NumberField<{ required: true; min: 0; step: 0.01 }>; } interface DetectionModeData extends SchemaField.InitializedData<DetectionModeSchema> {} interface MeasuredMovementWaypointSchema extends DataSchema { /** * The top-left x-coordinate in pixels (integer). * @defaultValue `undefined` */ x: fields.NumberField<{ required: true; nullable: false; integer: true; initial: undefined }>; /** * The top-left y-coordinate in pixels (integer). * @defaultValue `undefined` */ y: fields.NumberField<{ required: true; nullable: false; integer: true; initial: undefined }>; /** * The elevation in grid units. * @defaultValue `undefined` */ elevation: fields.NumberField<{ required: true; nullable: false; initial: undefined }>; /** * The width in grid spaces (positive). * @defaultValue `undefined` */ width: fields.NumberField<{ required: true; nullable: false; positive: true; initial: undefined }>; /** * The height in grid spaces (positive). * @defaultValue `undefined` */ height: fields.NumberField<{ required: true; nullable: false; positive: true; initial: undefined }>; /** * The shape type (see {@linkcode CONST.TOKEN_SHAPES}). * @defaultValue `undefined` */ shape: fields.NumberField< { required: true; initial: undefined; choices: CONST.TOKEN_SHAPES[]; }, // FIXME: Without these overrides, the branded type from `choices` is not respected, and the field types as `number` CONST.TOKEN_SHAPES | null | undefined, CONST.TOKEN_SHAPES, CONST.TOKEN_SHAPES >; /** * The movement action from the previous to this waypoint. * @defaultValue `undefined` */ action: fields.StringField<{ required: true; blank: false; initial: undefined }>; /** * The terrain data from the previous to this waypoint. * @defaultValue `undefined` * @remarks Not technically a union, but dependent on whether `CONFIG.Token.movement?.TerrainData` exists */ terrain: | fields.EmbeddedDataField<typeof TerrainData, { nullable: true; initial: undefined }> | fields.ObjectField<{ nullable: true; initial: undefined }>; /** * Was this waypoint snapped to the grid? * @defaultValue `undefined` */ snapped: fields.BooleanField<{ initial: undefined }>; /** * Was this waypoint explicitly placed by the user? * @defaultValue `undefined` */ explicit: fields.BooleanField<{ initial: undefined }>; /** * Is this waypoint a checkpoint? * @defaultValue `undefined` */ checkpoint: fields.BooleanField<{ initial: undefined }>; /** * Is this waypoint intermediate? * @defaultValue `undefined` */ intermediate: fields.BooleanField<{ initial: undefined }>; /** * The ID of the user that moved the token to from the previous to this waypoint. * @defaultValue `undefined` */ userId: fields.ForeignDocumentField< typeof documents.BaseUser, { idOnly: true; required: true; initial: undefined } >; /** * The ID of the movement from the previous to this waypoint. * @defaultValue `undefined` */ movementId: fields.StringField<{ required: true; blank: false; initial: undefined; validate: (value: string) => void; }>; /** * The movement cost from the previous to this waypoint (nonnegative). * @defaultValue `undefined` */ cost: fields.NumberField<{ required: true; nullable: false; min: 0; initial: undefined }>; } interface MeasuredMovementWaypoint extends SchemaField.InitializedData<MeasuredMovementWaypointSchema> {} interface GetCompleteMovementPathWaypoint extends InexactPartial<Omit<MeasuredMovementWaypoint, "userId" | "movementId" | "cost">> {} interface CompleteMovementWaypoint extends Omit<MeasuredMovementWaypoint, "userId" | "movementId" | "cost"> {} /** * The schema for {@linkcode TokenDocument}. This is the source of truth for how an TokenDocument document * must be structured. * * Foundry uses this schema to validate the structure of the {@linkcode TokenDocument}. For example * a {@link fields.StringField | `StringField`} will enforce that the value is a string. More * complex fields like {@link fields.SetField | `SetField`} goes through various conversions * starting as an array in the database, initialized as a set, and allows updates with any * iterable. */ interface Schema extends SharedProtoSchema { /** * The Token _id which uniquely identifies it within its parent Scene * @defaultValue `null` */ _id: fields.DocumentIdField; /** * The name used to describe the Token * @defaultValue `""` */ name: fields.StringField<{ required: true; blank: true; textSearch: true }>; /** * The _id of an Actor document which this Token represents * @defaultValue `null` */ actorId: fields.ForeignDocumentField<typeof documents.BaseActor, { idOnly: true }>; /** * The ActorDelta embedded document which stores the differences between this * token and the base actor it represents. */ delta: ActorDeltaField<typeof documents.BaseActorDelta>; /** * The shape of the Token * @defaultValue `CONST.TOKEN_SHAPES.RECTANGLE_1` */ shape: fields.NumberField<{ initial: typeof CONST.TOKEN_SHAPES.RECTANGLE_1; choices: CONST.TOKEN_SHAPES[] }>; /** * The x-coordinate of the top-left corner of the Token * @defaultValue `0` */ x: fields.NumberField<{ required: true; integer: true; nullable: false; initial: 0 }>; /** * The y-coordinate of the top-left corner of the Token * @defaultValue `0` */ y: fields.NumberField<{ required: true; integer: true; nullable: false; initial: 0 }>; /** * The vertical elevation of the Token, in distance units * @defaultValue `0` */ elevation: fields.NumberField<{ required: true; nullable: false; initial: 0 }>; /** * The z-index of this token relative to other siblings * @defaultValue `0` */ sort: fields.NumberField<{ required: true; integer: true; nullable: false; initial: 0 }>; /** * Is the Token currently locked? A locked token cannot be moved or rotated via * standard keyboard or mouse interaction. * @defaultValue `false` */ locked: fields.BooleanField; /** * Is the Token currently hidden from player view? * @defaultValue `false` */ hidden: fields.BooleanField; /** * @remarks Foundry marked `@internal` */ _movementHistory: fields.ArrayField<fields.SchemaField<MeasuredMovementWaypointSchema>>; /** * @remarks Foundry marked `@internal` */ _regions: fields.ArrayField<fields.ForeignDocumentField<typeof documents.BaseRegion, { idOnly: true }>>; } namespace Database { /** Options passed along in Get operations for TokenDocuments */ interface Get extends foundry.abstract.types.DatabaseGetOperation<TokenDocument.Parent> {} /** Options passed along in Create operations for TokenDocuments */ interface Create<Temporary extends boolean | undefined = boolean | undefined> extends foundry.abstract.types.DatabaseCreateOperation< TokenDocument.CreateData, TokenDocument.Parent, Temporary > {} /** Options passed along in Delete operations for TokenDocuments */ interface Delete extends foundry.abstract.types.DatabaseDeleteOperation<TokenDocument.Parent> {} /** Options passed along in Update operations for TokenDocuments */ interface Update extends foundry.abstract.types.DatabaseUpdateOperation<TokenDocument.UpdateData, TokenDocument.Parent> { previousActorId?: string | null; animate?: boolean; _priorRegions?: Record<string, string[]>; _priorPosition?: Record<string, { x: number; y: number; elevation: number }>; teleport?: boolean; forced?: boolean; // TODO: Type this accurately when going over the Token placeable animation: AnyObject; } /** Operation for {@linkcode TokenDocument.createDocuments} */ interface CreateDocumentsOperation<Temporary extends boolean | undefined> extends Document.Database.CreateOperation<TokenDocument.Database.Create<Temporary>> {} /** Operation for {@linkcode TokenDocument.updateDocuments} */ interface UpdateDocumentsOperation extends Document.Database.UpdateDocumentsOperation<TokenDocument.Database.Update> {} /** Operation for {@linkcode TokenDocument.deleteDocuments} */ interface DeleteDocumentsOperation extends Document.Database.DeleteDocumentsOperation<TokenDocument.Database.Delete> {} /** Operation for {@linkcode TokenDocument.create} */ interface CreateOperation<Temporary extends boolean | undefined> extends Document.Database.CreateOperation<TokenDocument.Database.Create<Temporary>> {} /** Operation for {@link TokenDocument.update | `TokenDocument#update`} */ interface UpdateOperation extends Document.Database.UpdateOperation<Update> {} interface DeleteOperation extends Document.Database.DeleteOperation<Delete> {} /** Options for {@linkcode TokenDocument.get} */ interface GetOptions extends Document.Database.GetOptions {} /** Options for {@link TokenDocument._preCreate | `TokenDocument#_preCreate`} */ interface PreCreateOptions extends Document.Database.PreCreateOptions<Create> {} /** Options for {@link TokenDocument._onCreate | `TokenDocument#_onCreate`} */ interface OnCreateOptions extends Document.Database.CreateOptions<Create> {} /** Operation for {@linkcode TokenDocument._preCreateOperation} */ interface PreCreateOperation extends Document.Database.PreCreateOperationStatic<TokenDocument.Database.Create> {} /** Operation for {@link TokenDocument._onCreateOperation | `TokenDocument#_onCreateOperation`} */ interface OnCreateOperation extends TokenDocument.Database.Create {} /** Options for {@link TokenDocument._preUpdate | `TokenDocument#_preUpdate`} */ interface PreUpdateOptions extends Document.Database.PreUpdateOptions<Update> {} /** Options for {@link TokenDocument._onUpdate | `TokenDocument#_onUpdate`} */ interface OnUpdateOptions extends Document.Database.UpdateOptions<Update> {} /** Operation for {@linkcode TokenDocument._preUpdateOperation} */ interface PreUpdateOperation extends TokenDocument.Database.Update {} /** Operation for {@link TokenDocument._onUpdateOperation | `TokenDocument._preUpdateOperation`} */ interface OnUpdateOperation extends TokenDocument.Database.Update {} /** Options for {@link TokenDocument._preDelete | `TokenDocument#_preDelete`} */ interface PreDeleteOptions extends Document.Database.PreDeleteOperationInstance<Delete> {} /** Options for {@link TokenDocument._onDelete | `TokenDocument#_onDelete`} */ interface OnDeleteOptions extends Document.Database.DeleteOptions<Delete> {} /** Options for {@link TokenDocument._preDeleteOperation | `TokenDocument#_preDeleteOperation`} */ interface PreDeleteOperation extends TokenDocument.Database.Delete {} /** Options for {@link TokenDocument._onDeleteOperation | `TokenDocument#_onDeleteOperation`} */ interface OnDeleteOperation extends TokenDocument.Database.Delete {} /** Context for {@linkcode TokenDocument._onDeleteOperation} */ interface OnDeleteDocumentsContext extends Document.ModificationContext<TokenDocument.Parent> {} /** Context for {@linkcode TokenDocument._onCreateDocuments} */ interface OnCreateDocumentsContext extends Document.ModificationContext<TokenDocument.Parent> {} /** Context for {@linkcode TokenDocument._onUpdateDocuments} */ interface OnUpdateDocumentsContext extends Document.ModificationContext<TokenDocument.Parent> {} /** * Options for {@link TokenDocument._preCreateDescendantDocuments | `TokenDocument#_preCreateDescendantDocuments`} * and {@link TokenDocument._onCreateDescendantDocuments | `TokenDocument#_onCreateDescendantDocuments`} */ interface CreateOptions extends Document.Database.CreateOptions<TokenDocument.Database.Create> {} /** * Options for {@link TokenDocument._preUpdateDescendantDocuments | `TokenDocument#_preUpdateDescendantDocuments`} * and {@link TokenDocument._onUpdateDescendantDocuments | `TokenDocument#_onUpdateDescendantDocuments`} */ interface UpdateOptions extends Document.Database.UpdateOptions<TokenDocument.Database.Update> {} /** * Options for {@link TokenDocument._preDeleteDescendantDocuments | `TokenDocument#_preDeleteDescendantDocuments`} * and {@link TokenDocument._onDeleteDescendantDocuments | `TokenDocument#_onDeleteDescendantDocuments`} */ interface DeleteOptions extends Document.Database.DeleteOptions<TokenDocument.Database.Delete> {} /** * Create options for {@linkcode TokenDocument.createDialog}. */ interface DialogCreateOptions extends InexactPartial<Create> {} } /** * If `Temporary` is true then `Token.Implementation`, otherwise `Token.Stored`. */ type TemporaryIf<Temporary extends boolean | undefined> = true extends Temporary ? TokenDocument.Implementation : TokenDocument.Stored; /** * The flags that are available for this document in the form `{ [scope: string]: { [key: string]: unknown } }`. */ interface Flags extends Document.Internal.ConfiguredFlagsForName<Name>, CoreFlags {} namespace Flags { /** * The valid scopes for the flags on this document e.g. `"core"` or `"dnd5e"`. */ type Scope = Document.Internal.FlagKeyOf<Flags>; /** * The valid keys for a certain scope for example if the scope is "core" then a valid key may be `"sheetLock"` or `"viewMode"`. */ type Key<Scope extends Flags.Scope> = Document.Internal.FlagKeyOf<Document.Internal.FlagGetKey<Flags, Scope>>; /** * Gets the type of a particular flag given a `Scope` and a `Key`. */ type Get<Scope extends Flags.Scope, Key extends Flags.Key<Scope>> = Document.Internal.GetFlag<Flags, Scope, Key>; } interface CoreFlags { core?: { /** @remarks If provided, will be used for any light animations emanating from this token */ animationSeed?: number; /** @remarks If true, and texture.src is a video, it will jump to a random timestamp every time the token is drawn */ randomizeVideo?: boolean; }; } interface DropData extends Document.Internal.DropData<Name> {} interface DropDataOptions extends Document.DropDataOptions {} interface DefaultNameContext extends Document.DefaultNameContext<Name, NonNullable<Parent>> {} interface CreateDialogData extends Document.CreateDialogData<CreateData> {} interface CreateDialogOptions extends Document.CreateDialogOptions<Name> {} type PreCreateDescendantDocumentsArgs = | Document.PreCreateDescendantDocumentsArgs< TokenDocument.Stored, TokenDocument.DirectDescendant, TokenDocument.Metadata.Embedded > | ActorDelta.PreCreateDescendantDocumentsArgs; type OnCreateDescendantDocumentsArgs = | Document.OnCreateDescendantDocumentsArgs< TokenDocument.Stored, TokenDocument.DirectDescendant, TokenDocument.Metadata.Embedded > | ActorDelta.OnCreateDescendantDocumentsArgs; type PreUpdateDescendantDocumentsArgs = | Document.PreUpdateDescendantDocumentsArgs< TokenDocument.Stored, TokenDocument.DirectDescendant, TokenDocument.Metadata.Embedded > | ActorDelta.PreUpdateDescendantDocumentsArgs; type OnUpdateDescendantDocumentsArgs = | Document.OnUpdateDescendantDocumentsArgs< TokenDocument.Stored, TokenDocument.DirectDescendant, TokenDocument.Metadata.Embedded > | ActorDelta.OnUpdateDescendantDocumentsArgs; type PreDeleteDescendantDocumentsArgs = | Document.PreDeleteDescendantDocumentsArgs< TokenDocument.Stored, TokenDocument.DirectDescendant, TokenDocument.Metadata.Embedded > | ActorDelta.PreDeleteDescendantDocumentsArgs; type OnDeleteDescendantDocumentsArgs = | Document.OnDeleteDescendantDocumentsArgs< TokenDocument.Stored, TokenDocument.DirectDescendant, TokenDocument.Metadata.Embedded > | ActorDelta.OnDeleteDescendantDocumentsArgs; // The getBarAttribute monkeypatch is simply inside the data model definition at `src/foundry/common/data/data.d.mts` interface PseudoActorCollection extends foundry.utils.Collection<Actor.Implementation> { documentClass: Actor.ImplementationClass; } /** @internal */ type _GetBarAttributeOptions = NullishProps<{ /** * An alternative attribute path to get instead of the default one * @defaultValue `this[barName]?.attribute` * @remarks If the above default returns falsey, the {@link TokenDocument.getBarAttribute | `TokenDocument#getBarAttribute`} * call returns `null` */ alternative: string; }>; interface GetBarAttributeOptions extends _GetBarAttributeOptions {} interface SingleAttributeBar { type: "value"; attribute: string; value: number; editable: boolean; } interface ObjectAttributeBar { type: "bar"; attribute: string; value: number; max: number; editable: boolean; } type GetBarAttributeReturn = SingleAttributeBar | ObjectAttributeBar | null; /** @internal */ type _CreateCombatantsOptions = NullishProps<{ /** * A specific Combat instance which should be modified. If undefined, * the current active combat will be modified if one exists. Otherwise, a new * Combat encounter will be created if the requesting user is a Gamemaster. * @defaultValue `game.combats.viewed` */ combat: Combat.Implementation; }>; interface CreateCombatantsOptions extends _CreateCombatantsOptions {} interface DeleteCombatantsOptions extends _CreateCombatantsOptions {} type TrackedAttributesSubject = | DataModel.Any | DataModel.AnyConstructor | SchemaField.Any | Actor.SubType | AnyObject | AnyArray; interface TrackedAttributesDescription { /** A list of property path arrays to attributes with both a value and a max property. */ bar: string[][]; /** A list of property path arrays to attributes that have only a value property. */ value: string[][]; } interface TrackedAttributesChoice { group: string; value: string; label: string; } interface ToggleCombatantOptions extends InexactPartial<TokenDocument.CreateCombatantsOptions> { /** * Require this token to be an active Combatant or to be removed. * Otherwise, the current combat state of the Token is toggled. */ active: boolean; } type GetEmbeddedCollectionName = Embedded.CollectionName | "Actor" | "Item" | "ActiveEffect"; type GetEmbeddedCollectionResult<Name extends GetEmbeddedCollectionName> = | (Name extends Document.Type ? globalThis.Collection<Document.ImplementationFor<Name>> : never) | (Name extends Embedded.CollectionName ? Embedded.CollectionFor<Name> : never); type MovementState = "completed" | "paused" | "pending" | "stopped"; type MovementMethod = "api" | "config" | "dragging" | "keyboard" | "paste" | "undo"; interface Position { /** * The top-left x-coordinate in pixels (integer). */ x: number; /** * The top-left y-coordinate in pixels (integer). */ y: number; /** * The elevation in grid units. */ elevation: number; /** * The width in grid spaces (positive). */ width: number; /** * The height in grid spaces (positive). */ height: number; /** * The shape type (see {@link CONST.TOKEN_SHAPES}). */ shape: CONST.TOKEN_SHAPES; } interface Dimensions extends Pick<Position, "width" | "height" | "shape"> {} interface PartialDimensions extends InexactPartial<Dimensions> {} interface ShapelessDimensions extends Omit<Dimensions, "shape"> {} interface Dimensions2D extends InexactPartial<foundry.canvas.Canvas.Point & Dimensions> {} interface Dimensions3D extends InexactPartial<foundry.canvas.Canvas.ElevatedPoint & Dimensions> {} interface ResizeOptions extends InexactPartial<Omit<TokenDocument.Database.UpdateOperation, "updates">> {} interface MovementWaypoint extends Omit<MeasuredMovementWaypoint, "terrain" | "intermediate" | "userId" | "movementId" | "cost"> {} interface MovementSegmentData extends Pick<MeasuredMovementWaypoint, "width" | "height" | "shape" | "action" | "terrain"> { actionConfig: CONFIG.Token.MovementActionConfig; teleport: boolean; } interface MovementSectionData { /** * The waypoints of the movement path */ waypoints: TokenDocument.MeasuredMovementWaypoint[]; /** * The distance of the movement path */ distance: number; /** * The cost of the movement path */ cost: number; /** * The number of spaces moved along the path */ spaces: number; /** * The number of diagonals moved along the path */ diagonals: number; } interface MovementHistoryData { /** * The recorded waypoints of the movement path */ recorded: TokenDocument.MovementSectionData; /** * The unrecorded waypoints of the movement path */ unrecorded: TokenDocument.MovementSectionData; /** * The distance of the combined movement path */ distance: number; /** * The cost of the combined movement path */ cost: number; /** * The number spaces of moved along the combined path */ space: number; /** * The number of diagonals moved along the combined path */ diagonals: number; } interface MovementContinuationHandle { /** * The movement ID */ movementId: string; /** * The continuation promise */ continuePromise: Promise<boolean> | undefined; } interface MovementContinuationState { handles: Map<string | symbol, TokenDocument.MovementContinuationHandle>; callbacks: Array<(continued: boolean) => void>; pending: Set<string>; } interface MovementContinuationData { /** * The movement ID */ movementId: string; /** * The number of continuations */ continueCounter: number; /** * Was continued? */ continued: boolean; /** * The continuation promise */ continuePromise: Promise<boolean> | null; /** * The promise to wait for before continuing movement */ waitPromise: Promise<void>; /** * Resolve function of the wait promise */ resolveWaitPromise: (() => void) | undefined; /** * The promise that resolves after the update workflow */ postWorkflowPromise: Promise<void>; /** * The movement continuation states */ states: { [movementId: string]: TokenDocument.MovementContinuationState; }; } interface ConstrainOptions extends Omit<Token.ConstrainMovementPathOptions, "preview" | "history"> {} interface MovementData { /** * The ID of the movement */ id: string; /** * The chain of prior movement IDs that this movement is a continuation of */ chain: string[]; /** * The origin of movement */ origin: TokenDocument.Position; /** * The destination of movement */ destination: TokenDocument.Position; /** * The waypoints and measurements of the passed path */ passed: TokenDocument.MovementSectionData; /** * The waypoints and measurements of the pending path */ pending: TokenDocument.MovementSectionData; /** * The waypoints and measurements of the history path */ history: TokenDocument.MovementHistoryData; /** * Was the movement constrained? */ constrained: boolean; /** * Was the movement recorded in the movement history? */ recorded: boolean; /** * The method of movement */ method: TokenDocument.MovementMethod; /** * The options to constrain movement */ constrainOptions: ConstrainOptions; /** * Automatically rotate the token in the direction of movement? */ autoRotate: boolean; /** * Show the ruler during the movement animation of the token? */ showRuler: boolean; /** * The user that moved the token */ user: User.Implementation; /** * The state of the movement */ state: TokenDocument.MovementState; /** * The update options of the movement operation */ updateOptions: Database.UpdateOperation; } interface MoveOptions extends Database.UpdateOperation { method: MovementMethod; autoRotate: boolean; showRuler: boolean; constrainOptions: ConstrainOptions; } interface MovementCostFunction extends Omit<foundry.grid.BaseGrid.MeasurePathCostFunction3D, "segment"> { segment: MovementSegmentData; } interface MovementCostAggregatorResult { from: foundry.grid.BaseGrid.Offset3D; to: foundry.grid.BaseGrid.Offset3D; cost: number; } /** Returns the aggregated cost */ type MovementCostAggregator = ( /** * The results of the cost function calls. * The array may be sorted but otherwise not mutated * @remarks marked by foundry as readonly */ results: MovementCostAggregatorResult[], /** The distance between the grid spaces. */ distance: number, /** * The properties of the segment * @remarks marked by foundry as readonly */ segment: MovementSegmentData, ) => number; interface MeasureMovementPathOptions extends InexactPartial<{ /** * The function that returns the cost for a given move between grid spaces * (default is the distance travelled along the direct path) */ cost: MovementCostFunction; /** * The cost aggregator. * @defaultValue `CONFIG.Token.movement.costAggregator` */ aggregator: MovementCostAggregator; }> {} interface MovementOperation extends Omit<MovementData, "user" | "state" | "updateOptions"> {} /** * The hexagonal offsets of a Token. */ interface HexagonalOffsetsData { /** * The occupied offsets in an even grid in the 0th row/column */ even: foundry.grid.BaseGrid.Offset2D[]; /** * The occupied offsets in an odd grid in the 0th row/column */ odd: foundry.grid.BaseGrid.Offset2D[]; /** * The anchor in normalized coordiantes */ anchor: foundry.canvas.Canvas.Point; } interface PreMovementOptions extends DeepReadonly<Omit<MovementOperation, "autoRotate" | "showRuler">>, Pick<MovementOperation, "autoRotate" | "showRuler"> {} interface SegmentizeMovementWaypoint extends InexactPartial< Pick< MeasuredMovementWaypoint, "x" | "y" | "elevation" | "width" | "height" | "shape" | "action" | "terrain" | "snapped" > > {} /** * The arguments to construct the document. * * @deprecated Writing the signature directly has helped reduce circularities and therefore is * now recommended. */ // eslint-disable-next-line @typescript-eslint/no-deprecated type ConstructorArgs = Document.ConstructorParameters<CreateData, Parent>; /** * @deprecated Replaced by {@linkcode Token.ConstrainMovementPathOptions}. */ type ConstrainMovementPathOptions = Token.ConstrainMovementPathOptions; } /** * The client-side Token document which extends the common BaseToken model. * * @see {@linkcode Scene} The Scene document type which contains Token embedded documents * @see {@linkcode TokenConfig} The Token configuration application */ declare class TokenDocument extends BaseToken.Internal.CanvasDocument { /** * @param data - Initial data from which to construct the `TokenDocument` * @param context - Construction context options */ // Note(LukeAbby): Optional as there are currently no required properties on `CreateData`. constructor(data?: TokenDocument.CreateData, context?: TokenDocument.ConstructionContext); /** * The current movement data of this Token document. */ get movement(): DeepReadonly<TokenDocument.MovementData>; /** * The movement continuation state of this Token document. * @internal * @defaultValue * ```js * { * movementId: "", * continueCounter: 0, * continued: false, * continuePromise: Promise.resolve(false), * waitPromise: Promise.resolve(), * resolveWaitPromise: undefined, * postWorkflowPromise: Promise.resolve(), * states: {} * } * ``` */ protected _movementContinuation: TokenDocument.MovementContinuationData; /** * A singleton collection which holds a reference to the synthetic token actor by its base actor's ID. * @remarks Initialized by an IIFE that makes a base-model {@linkcode Collection} and adds a `documentClass` property to it */ actors: TokenDocument.PseudoActorCollection; /** * A lazily evaluated reference to the Actor this Token modifies. * If actorLink is true, then the document is the primary Actor document. * Otherwise the Actor document is a synthetic (ephemeral) document constructed using the Token's ActorDelta. */ get actor(): Actor.Implementation | null; /** * A reference to the base, World-level Actor this token represents. */ get baseActor(): Actor.Implementation | null; /** * An indicator for whether or not the current User has full control over this Token document. */ get isOwner(): boolean; /** * A convenient reference for whether this TokenDocument is linked to the Actor it represents, or is a synthetic copy */ get isLinked(): boolean; /** * Does this TokenDocument have the SECRET disposition