525 lines
20 KiB
JavaScript
525 lines
20 KiB
JavaScript
|
|
/**
|
||
|
|
* The collection of data schema and document definitions for primary documents which are shared between the both the
|
||
|
|
* client and the server.
|
||
|
|
* @namespace data
|
||
|
|
*/
|
||
|
|
|
||
|
|
import {DataModel} from "../abstract/module.mjs";
|
||
|
|
import * as fields from "./fields.mjs";
|
||
|
|
import * as documents from "../documents/_module.mjs";
|
||
|
|
import {logCompatibilityWarning} from "../utils/logging.mjs";
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @typedef {import("./fields.mjs").DataFieldOptions} DataFieldOptions
|
||
|
|
* @typedef {import("./fields.mjs").FilePathFieldOptions} FilePathFieldOptions
|
||
|
|
*/
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @typedef {Object} LightAnimationData
|
||
|
|
* @property {string} type The animation type which is applied
|
||
|
|
* @property {number} speed The speed of the animation, a number between 0 and 10
|
||
|
|
* @property {number} intensity The intensity of the animation, a number between 1 and 10
|
||
|
|
* @property {boolean} reverse Reverse the direction of animation.
|
||
|
|
*/
|
||
|
|
|
||
|
|
/**
|
||
|
|
* A reusable document structure for the internal data used to render the appearance of a light source.
|
||
|
|
* This is re-used by both the AmbientLightData and TokenData classes.
|
||
|
|
* @extends DataModel
|
||
|
|
* @memberof data
|
||
|
|
*
|
||
|
|
* @property {boolean} negative Is this light source a negative source? (i.e. darkness source)
|
||
|
|
* @property {number} alpha An opacity for the emitted light, if any
|
||
|
|
* @property {number} angle The angle of emission for this point source
|
||
|
|
* @property {number} bright The allowed radius of bright vision or illumination
|
||
|
|
* @property {number} color A tint color for the emitted light, if any
|
||
|
|
* @property {number} coloration The coloration technique applied in the shader
|
||
|
|
* @property {number} contrast The amount of contrast this light applies to the background texture
|
||
|
|
* @property {number} dim The allowed radius of dim vision or illumination
|
||
|
|
* @property {number} attenuation Fade the difference between bright, dim, and dark gradually?
|
||
|
|
* @property {number} luminosity The luminosity applied in the shader
|
||
|
|
* @property {number} saturation The amount of color saturation this light applies to the background texture
|
||
|
|
* @property {number} shadows The depth of shadows this light applies to the background texture
|
||
|
|
* @property {LightAnimationData} animation An animation configuration for the source
|
||
|
|
* @property {{min: number, max: number}} darkness A darkness range (min and max) for which the source should be active
|
||
|
|
*/
|
||
|
|
class LightData extends DataModel {
|
||
|
|
static defineSchema() {
|
||
|
|
return {
|
||
|
|
negative: new fields.BooleanField(),
|
||
|
|
priority: new fields.NumberField({required: true, nullable: false, integer: true, initial: 0, min: 0}),
|
||
|
|
alpha: new fields.AlphaField({initial: 0.5}),
|
||
|
|
angle: new fields.AngleField({initial: 360, normalize: false}),
|
||
|
|
bright: new fields.NumberField({required: true, nullable: false, initial: 0, min: 0, step: 0.01}),
|
||
|
|
color: new fields.ColorField({}),
|
||
|
|
coloration: new fields.NumberField({required: true, integer: true, initial: 1}),
|
||
|
|
dim: new fields.NumberField({required: true, nullable: false, initial: 0, min: 0, step: 0.01}),
|
||
|
|
attenuation: new fields.AlphaField({initial: 0.5}),
|
||
|
|
luminosity: new fields.NumberField({required: true, nullable: false, initial: 0.5, min: 0, max: 1}),
|
||
|
|
saturation: new fields.NumberField({required: true, nullable: false, initial: 0, min: -1, max: 1}),
|
||
|
|
contrast: new fields.NumberField({required: true, nullable: false, initial: 0, min: -1, max: 1}),
|
||
|
|
shadows: new fields.NumberField({required: true, nullable: false, initial: 0, min: 0, max: 1}),
|
||
|
|
animation: new fields.SchemaField({
|
||
|
|
type: new fields.StringField({nullable: true, blank: false, initial: null}),
|
||
|
|
speed: new fields.NumberField({required: true, nullable: false, integer: true, initial: 5, min: 0, max: 10,
|
||
|
|
validationError: "Light animation speed must be an integer between 0 and 10"}),
|
||
|
|
intensity: new fields.NumberField({required: true, nullable: false, integer: true, initial: 5, min: 1, max: 10,
|
||
|
|
validationError: "Light animation intensity must be an integer between 1 and 10"}),
|
||
|
|
reverse: new fields.BooleanField()
|
||
|
|
}),
|
||
|
|
darkness: new fields.SchemaField({
|
||
|
|
min: new fields.AlphaField({initial: 0}),
|
||
|
|
max: new fields.AlphaField({initial: 1})
|
||
|
|
}, {
|
||
|
|
validate: d => (d.min ?? 0) <= (d.max ?? 1),
|
||
|
|
validationError: "darkness.max may not be less than darkness.min"
|
||
|
|
})
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/** @override */
|
||
|
|
static LOCALIZATION_PREFIXES = ["LIGHT"];
|
||
|
|
|
||
|
|
/* -------------------------------------------- */
|
||
|
|
/* Deprecations and Compatibility */
|
||
|
|
/* -------------------------------------------- */
|
||
|
|
|
||
|
|
/** @inheritDoc */
|
||
|
|
static migrateData(data) {
|
||
|
|
/**
|
||
|
|
* Migration of negative luminosity
|
||
|
|
* @deprecated since v12
|
||
|
|
*/
|
||
|
|
const luminosity = data.luminosity;
|
||
|
|
if ( luminosity < 0) {
|
||
|
|
data.luminosity = 1 - luminosity;
|
||
|
|
data.negative = true;
|
||
|
|
}
|
||
|
|
return super.migrateData(data);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/* ---------------------------------------- */
|
||
|
|
|
||
|
|
/**
|
||
|
|
* A data model intended to be used as an inner EmbeddedDataField which defines a geometric shape.
|
||
|
|
* @extends DataModel
|
||
|
|
* @memberof data
|
||
|
|
*
|
||
|
|
* @property {string} type The type of shape, a value in ShapeData.TYPES.
|
||
|
|
* For rectangles, the x/y coordinates are the top-left corner.
|
||
|
|
* For circles, the x/y coordinates are the center of the circle.
|
||
|
|
* For polygons, the x/y coordinates are the first point of the polygon.
|
||
|
|
* @property {number} [width] For rectangles, the pixel width of the shape.
|
||
|
|
* @property {number} [height] For rectangles, the pixel width of the shape.
|
||
|
|
* @property {number} [radius] For circles, the pixel radius of the shape.
|
||
|
|
* @property {number[]} [points] For polygons, the array of polygon coordinates which comprise the shape.
|
||
|
|
*/
|
||
|
|
class ShapeData extends DataModel {
|
||
|
|
static defineSchema() {
|
||
|
|
return {
|
||
|
|
type: new fields.StringField({required: true, blank: false, choices: Object.values(this.TYPES), initial: "r"}),
|
||
|
|
width: new fields.NumberField({required: false, integer: true, min: 0}),
|
||
|
|
height: new fields.NumberField({required: false, integer: true, min: 0}),
|
||
|
|
radius: new fields.NumberField({required: false, integer: true, positive: true}),
|
||
|
|
points: new fields.ArrayField(new fields.NumberField({nullable: false}))
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* The primitive shape types which are supported
|
||
|
|
* @enum {string}
|
||
|
|
*/
|
||
|
|
static TYPES = {
|
||
|
|
RECTANGLE: "r",
|
||
|
|
CIRCLE: "c",
|
||
|
|
ELLIPSE: "e",
|
||
|
|
POLYGON: "p"
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/* ---------------------------------------- */
|
||
|
|
|
||
|
|
/**
|
||
|
|
* A data model intended to be used as an inner EmbeddedDataField which defines a geometric shape.
|
||
|
|
* @extends DataModel
|
||
|
|
* @memberof data
|
||
|
|
* @abstract
|
||
|
|
*
|
||
|
|
* @property {string} type The type of shape, a value in BaseShapeData.TYPES.
|
||
|
|
* @property {{bottom: number|null, top: number|null}} [elevation] The bottom and top elevation of the shape.
|
||
|
|
* A value of null means -/+Infinity.
|
||
|
|
* @property {boolean} [hole=false] Is this shape a hole?
|
||
|
|
*/
|
||
|
|
class BaseShapeData extends DataModel {
|
||
|
|
|
||
|
|
/**
|
||
|
|
* The possible shape types.
|
||
|
|
* @type {Readonly<{
|
||
|
|
* rectangle: RectangleShapeData,
|
||
|
|
* circle: CircleShapeData,
|
||
|
|
* ellipse: EllipseShapeData,
|
||
|
|
* polygon: PolygonShapeData
|
||
|
|
* }>}
|
||
|
|
*/
|
||
|
|
static get TYPES() {
|
||
|
|
return BaseShapeData.#TYPES ??= Object.freeze({
|
||
|
|
[RectangleShapeData.TYPE]: RectangleShapeData,
|
||
|
|
[CircleShapeData.TYPE]: CircleShapeData,
|
||
|
|
[EllipseShapeData.TYPE]: EllipseShapeData,
|
||
|
|
[PolygonShapeData.TYPE]: PolygonShapeData
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
static #TYPES;
|
||
|
|
|
||
|
|
/* -------------------------------------------- */
|
||
|
|
|
||
|
|
/**
|
||
|
|
* The type of this shape.
|
||
|
|
* @type {string}
|
||
|
|
*/
|
||
|
|
static TYPE = "";
|
||
|
|
|
||
|
|
/* -------------------------------------------- */
|
||
|
|
|
||
|
|
/** @override */
|
||
|
|
static defineSchema() {
|
||
|
|
return {
|
||
|
|
type: new fields.StringField({required: true, blank: false, initial: this.TYPE,
|
||
|
|
validate: value => value === this.TYPE, validationError: `must be equal to "${this.TYPE}"`}),
|
||
|
|
hole: new fields.BooleanField()
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/* -------------------------------------------- */
|
||
|
|
|
||
|
|
/**
|
||
|
|
* The data model for a rectangular shape.
|
||
|
|
* @extends DataModel
|
||
|
|
* @memberof data
|
||
|
|
*
|
||
|
|
* @property {number} x The top-left x-coordinate in pixels before rotation.
|
||
|
|
* @property {number} y The top-left y-coordinate in pixels before rotation.
|
||
|
|
* @property {number} width The width of the rectangle in pixels.
|
||
|
|
* @property {number} height The height of the rectangle in pixels.
|
||
|
|
* @property {number} [rotation=0] The rotation around the center of the rectangle in degrees.
|
||
|
|
*/
|
||
|
|
class RectangleShapeData extends BaseShapeData {
|
||
|
|
|
||
|
|
static {
|
||
|
|
Object.defineProperty(this, "TYPE", {value: "rectangle"});
|
||
|
|
}
|
||
|
|
|
||
|
|
/** @inheritdoc */
|
||
|
|
static defineSchema() {
|
||
|
|
return Object.assign(super.defineSchema(), {
|
||
|
|
x: new fields.NumberField({required: true, nullable: false, initial: undefined}),
|
||
|
|
y: new fields.NumberField({required: true, nullable: false, initial: undefined}),
|
||
|
|
width: new fields.NumberField({required: true, nullable: false, initial: undefined, positive: true}),
|
||
|
|
height: new fields.NumberField({required: true, nullable: false, initial: undefined, positive: true}),
|
||
|
|
rotation: new fields.AngleField()
|
||
|
|
});
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/* -------------------------------------------- */
|
||
|
|
|
||
|
|
/**
|
||
|
|
* The data model for a circle shape.
|
||
|
|
* @extends DataModel
|
||
|
|
* @memberof data
|
||
|
|
*
|
||
|
|
* @property {number} x The x-coordinate of the center point in pixels.
|
||
|
|
* @property {number} y The y-coordinate of the center point in pixels.
|
||
|
|
* @property {number} radius The radius of the circle in pixels.
|
||
|
|
*/
|
||
|
|
class CircleShapeData extends BaseShapeData {
|
||
|
|
|
||
|
|
static {
|
||
|
|
Object.defineProperty(this, "TYPE", {value: "circle"});
|
||
|
|
}
|
||
|
|
|
||
|
|
/** @inheritdoc */
|
||
|
|
static defineSchema() {
|
||
|
|
return Object.assign(super.defineSchema(), {
|
||
|
|
x: new fields.NumberField({required: true, nullable: false, initial: undefined}),
|
||
|
|
y: new fields.NumberField({required: true, nullable: false, initial: undefined}),
|
||
|
|
radius: new fields.NumberField({required: true, nullable: false, initial: undefined, positive: true})
|
||
|
|
});
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/* -------------------------------------------- */
|
||
|
|
|
||
|
|
/**
|
||
|
|
* The data model for an ellipse shape.
|
||
|
|
* @extends DataModel
|
||
|
|
* @memberof data
|
||
|
|
*
|
||
|
|
* @property {number} x The x-coordinate of the center point in pixels.
|
||
|
|
* @property {number} y The y-coordinate of the center point in pixels.
|
||
|
|
* @property {number} radiusX The x-radius of the circle in pixels.
|
||
|
|
* @property {number} radiusY The y-radius of the circle in pixels.
|
||
|
|
* @property {number} [rotation=0] The rotation around the center of the rectangle in degrees.
|
||
|
|
*/
|
||
|
|
class EllipseShapeData extends BaseShapeData {
|
||
|
|
|
||
|
|
static {
|
||
|
|
Object.defineProperty(this, "TYPE", {value: "ellipse"});
|
||
|
|
}
|
||
|
|
|
||
|
|
/** @inheritdoc */
|
||
|
|
static defineSchema() {
|
||
|
|
return Object.assign(super.defineSchema(), {
|
||
|
|
x: new fields.NumberField({required: true, nullable: false, initial: undefined}),
|
||
|
|
y: new fields.NumberField({required: true, nullable: false, initial: undefined}),
|
||
|
|
radiusX: new fields.NumberField({required: true, nullable: false, initial: undefined, positive: true}),
|
||
|
|
radiusY: new fields.NumberField({required: true, nullable: false, initial: undefined, positive: true}),
|
||
|
|
rotation: new fields.AngleField()
|
||
|
|
});
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/* -------------------------------------------- */
|
||
|
|
|
||
|
|
/**
|
||
|
|
* The data model for a polygon shape.
|
||
|
|
* @extends DataModel
|
||
|
|
* @memberof data
|
||
|
|
*
|
||
|
|
* @property {number[]} points The points of the polygon ([x0, y0, x1, y1, ...]).
|
||
|
|
* The polygon must not be self-intersecting.
|
||
|
|
*/
|
||
|
|
class PolygonShapeData extends BaseShapeData {
|
||
|
|
|
||
|
|
static {
|
||
|
|
Object.defineProperty(this, "TYPE", {value: "polygon"});
|
||
|
|
}
|
||
|
|
|
||
|
|
/** @inheritdoc */
|
||
|
|
static defineSchema() {
|
||
|
|
return Object.assign(super.defineSchema(), {
|
||
|
|
points: new fields.ArrayField(new fields.NumberField({required: true, nullable: false, initial: undefined}),
|
||
|
|
{validate: value => {
|
||
|
|
if ( value.length % 2 !== 0 ) throw new Error("must have an even length");
|
||
|
|
if ( value.length < 6 ) throw new Error("must have at least 3 points");
|
||
|
|
}}),
|
||
|
|
});
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/* ---------------------------------------- */
|
||
|
|
|
||
|
|
/**
|
||
|
|
* A {@link fields.SchemaField} subclass used to represent texture data.
|
||
|
|
* @property {string|null} src The URL of the texture source.
|
||
|
|
* @property {number} [anchorX=0] The X coordinate of the texture anchor.
|
||
|
|
* @property {number} [anchorY=0] The Y coordinate of the texture anchor.
|
||
|
|
* @property {number} [scaleX=1] The scale of the texture in the X dimension.
|
||
|
|
* @property {number} [scaleY=1] The scale of the texture in the Y dimension.
|
||
|
|
* @property {number} [offsetX=0] The X offset of the texture with (0,0) in the top left.
|
||
|
|
* @property {number} [offsetY=0] The Y offset of the texture with (0,0) in the top left.
|
||
|
|
* @property {number} [rotation=0] An angle of rotation by which this texture is rotated around its center.
|
||
|
|
* @property {string} [tint="#ffffff"] The tint applied to the texture.
|
||
|
|
* @property {number} [alphaThreshold=0] Only pixels with an alpha value at or above this value are consider solid
|
||
|
|
* w.r.t. to occlusion testing and light/weather blocking.
|
||
|
|
*/
|
||
|
|
class TextureData extends fields.SchemaField {
|
||
|
|
/**
|
||
|
|
* @param {DataFieldOptions} options Options which are forwarded to the SchemaField constructor
|
||
|
|
* @param {FilePathFieldOptions} srcOptions Additional options for the src field
|
||
|
|
*/
|
||
|
|
constructor(options={}, {categories=["IMAGE", "VIDEO"], initial={}, wildcard=false, label=""}={}) {
|
||
|
|
/** @deprecated since v12 */
|
||
|
|
if ( typeof initial === "string" ) {
|
||
|
|
const msg = "Passing the initial value of the src field as a string is deprecated. Pass {src} instead.";
|
||
|
|
logCompatibilityWarning(msg, {since: 12, until: 14});
|
||
|
|
initial = {src: initial};
|
||
|
|
}
|
||
|
|
super({
|
||
|
|
src: new fields.FilePathField({categories, initial: initial.src ?? null, label, wildcard}),
|
||
|
|
anchorX: new fields.NumberField({nullable: false, initial: initial.anchorX ?? 0}),
|
||
|
|
anchorY: new fields.NumberField({nullable: false, initial: initial.anchorY ?? 0}),
|
||
|
|
offsetX: new fields.NumberField({nullable: false, integer: true, initial: initial.offsetX ?? 0}),
|
||
|
|
offsetY: new fields.NumberField({nullable: false, integer: true, initial: initial.offsetY ?? 0}),
|
||
|
|
fit: new fields.StringField({initial: initial.fit ?? "fill", choices: CONST.TEXTURE_DATA_FIT_MODES}),
|
||
|
|
scaleX: new fields.NumberField({nullable: false, initial: initial.scaleX ?? 1}),
|
||
|
|
scaleY: new fields.NumberField({nullable: false, initial: initial.scaleY ?? 1}),
|
||
|
|
rotation: new fields.AngleField({initial: initial.rotation ?? 0}),
|
||
|
|
tint: new fields.ColorField({nullable: false, initial: initial.tint ?? "#ffffff"}),
|
||
|
|
alphaThreshold: new fields.AlphaField({nullable: false, initial: initial.alphaThreshold ?? 0})
|
||
|
|
}, options);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/* ---------------------------------------- */
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Extend the base TokenData to define a PrototypeToken which exists within a parent Actor.
|
||
|
|
* @extends abstract.DataModel
|
||
|
|
* @memberof data
|
||
|
|
* @property {boolean} randomImg Does the prototype token use a random wildcard image?
|
||
|
|
* @alias {PrototypeToken}
|
||
|
|
*/
|
||
|
|
class PrototypeToken extends DataModel {
|
||
|
|
constructor(data={}, options={}) {
|
||
|
|
super(data, options);
|
||
|
|
Object.defineProperty(this, "apps", {value: {}});
|
||
|
|
}
|
||
|
|
|
||
|
|
/** @override */
|
||
|
|
static defineSchema() {
|
||
|
|
const schema = documents.BaseToken.defineSchema();
|
||
|
|
const excluded = ["_id", "actorId", "delta", "x", "y", "elevation", "sort", "hidden", "locked", "_regions"];
|
||
|
|
for ( let x of excluded ) {
|
||
|
|
delete schema[x];
|
||
|
|
}
|
||
|
|
schema.name.textSearch = schema.name.options.textSearch = false;
|
||
|
|
schema.randomImg = new fields.BooleanField();
|
||
|
|
PrototypeToken.#applyDefaultTokenSettings(schema);
|
||
|
|
return schema;
|
||
|
|
}
|
||
|
|
|
||
|
|
/** @override */
|
||
|
|
static LOCALIZATION_PREFIXES = ["TOKEN"];
|
||
|
|
|
||
|
|
/**
|
||
|
|
* The Actor which owns this Prototype Token
|
||
|
|
* @type {documents.BaseActor}
|
||
|
|
*/
|
||
|
|
get actor() {
|
||
|
|
return this.parent;
|
||
|
|
}
|
||
|
|
|
||
|
|
/** @inheritdoc */
|
||
|
|
toObject(source=true) {
|
||
|
|
const data = super.toObject(source);
|
||
|
|
data["actorId"] = this.document?.id;
|
||
|
|
return data;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @see ClientDocument.database
|
||
|
|
* @ignore
|
||
|
|
*/
|
||
|
|
static get database() {
|
||
|
|
return globalThis.CONFIG.DatabaseBackend;
|
||
|
|
}
|
||
|
|
|
||
|
|
/* -------------------------------------------- */
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Apply configured default token settings to the schema.
|
||
|
|
* @param {DataSchema} [schema] The schema to apply the settings to.
|
||
|
|
*/
|
||
|
|
static #applyDefaultTokenSettings(schema) {
|
||
|
|
if ( typeof DefaultTokenConfig === "undefined" ) return;
|
||
|
|
const settings = foundry.utils.flattenObject(game.settings.get("core", DefaultTokenConfig.SETTING) ?? {});
|
||
|
|
for ( const [k, v] of Object.entries(settings) ) {
|
||
|
|
const path = k.split(".");
|
||
|
|
let field = schema[path.shift()];
|
||
|
|
if ( path.length ) field = field._getField(path);
|
||
|
|
if ( field ) field.initial = v;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/* -------------------------------------------- */
|
||
|
|
/* Document Compatibility Methods */
|
||
|
|
/* -------------------------------------------- */
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @see abstract.Document#update
|
||
|
|
* @ignore
|
||
|
|
*/
|
||
|
|
update(data, options) {
|
||
|
|
return this.actor.update({prototypeToken: data}, options);
|
||
|
|
}
|
||
|
|
|
||
|
|
/* -------------------------------------------- */
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @see abstract.Document#getFlag
|
||
|
|
* @ignore
|
||
|
|
*/
|
||
|
|
getFlag(...args) {
|
||
|
|
return foundry.abstract.Document.prototype.getFlag.call(this, ...args);
|
||
|
|
}
|
||
|
|
|
||
|
|
/* -------------------------------------------- */
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @see abstract.Document#getFlag
|
||
|
|
* @ignore
|
||
|
|
*/
|
||
|
|
setFlag(...args) {
|
||
|
|
return foundry.abstract.Document.prototype.setFlag.call(this, ...args);
|
||
|
|
}
|
||
|
|
|
||
|
|
/* -------------------------------------------- */
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @see abstract.Document#unsetFlag
|
||
|
|
* @ignore
|
||
|
|
*/
|
||
|
|
async unsetFlag(...args) {
|
||
|
|
return foundry.abstract.Document.prototype.unsetFlag.call(this, ...args);
|
||
|
|
}
|
||
|
|
|
||
|
|
/* -------------------------------------------- */
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @see abstract.Document#testUserPermission
|
||
|
|
* @ignore
|
||
|
|
*/
|
||
|
|
testUserPermission(user, permission, {exact=false}={}) {
|
||
|
|
return this.actor.testUserPermission(user, permission, {exact});
|
||
|
|
}
|
||
|
|
|
||
|
|
/* -------------------------------------------- */
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @see documents.BaseActor#isOwner
|
||
|
|
* @ignore
|
||
|
|
*/
|
||
|
|
get isOwner() {
|
||
|
|
return this.actor.isOwner;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/* -------------------------------------------- */
|
||
|
|
|
||
|
|
/**
|
||
|
|
* A minimal data model used to represent a tombstone entry inside an EmbeddedCollectionDelta.
|
||
|
|
* @see {EmbeddedCollectionDelta}
|
||
|
|
* @extends DataModel
|
||
|
|
* @memberof data
|
||
|
|
*
|
||
|
|
* @property {string} _id The _id of the base Document that this tombstone represents.
|
||
|
|
* @property {boolean} _tombstone A property that identifies this entry as a tombstone.
|
||
|
|
*/
|
||
|
|
class TombstoneData extends DataModel {
|
||
|
|
/** @override */
|
||
|
|
static defineSchema() {
|
||
|
|
return {
|
||
|
|
_id: new fields.DocumentIdField(),
|
||
|
|
_tombstone: new fields.BooleanField({initial: true, validate: v => v === true, validationError: "must be true"})
|
||
|
|
};
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// Exports need to be at the bottom so that class names appear correctly in JSDoc
|
||
|
|
export {
|
||
|
|
LightData,
|
||
|
|
PrototypeToken,
|
||
|
|
ShapeData,
|
||
|
|
BaseShapeData,
|
||
|
|
RectangleShapeData,
|
||
|
|
CircleShapeData,
|
||
|
|
EllipseShapeData,
|
||
|
|
PolygonShapeData,
|
||
|
|
TextureData,
|
||
|
|
TombstoneData
|
||
|
|
}
|