forked from foundryvtt/pf2e
-
Notifications
You must be signed in to change notification settings - Fork 0
/
token-image.ts
85 lines (73 loc) · 2.9 KB
/
token-image.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
import type { AlphaField, ColorField, NumberField } from "types/foundry/common/data/fields.d.ts";
import { isBracketedValue } from "../helpers.ts";
import { RuleElementPF2e } from "./base.ts";
import { ModelPropsFromRESchema, ResolvableValueField, RuleElementSchema } from "./data.ts";
/**
* Change the image representing an actor's token
* @category RuleElement
*/
class TokenImageRuleElement extends RuleElementPF2e<TokenImageRuleSchema> {
static override defineSchema(): TokenImageRuleSchema {
const fields = foundry.data.fields;
return {
...super.defineSchema(),
value: new ResolvableValueField({
required: true,
nullable: false,
initial: undefined,
label: "TOKEN.ImagePath",
validate: (v) => typeof v === "string" || isBracketedValue(v),
}),
scale: new fields.NumberField({
required: false,
nullable: true,
positive: true,
initial: null,
label: "Scale",
}),
tint: new fields.ColorField({ label: "TOKEN.TintColor" }),
alpha: new fields.AlphaField({
label: "PF2E.RuleEditor.General.Opacity",
required: false,
nullable: true,
initial: null,
}),
};
}
override afterPrepareData(): void {
const src = this.resolveValue(this.value);
if (!this.#srcIsValid(src)) return this.failValidation("Missing or invalid value field");
if (!this.test()) return;
const texture: { src: VideoFilePath; scaleX?: number; scaleY?: number; tint?: Color } = { src };
if (this.scale) {
texture.scaleX = this.scale;
texture.scaleY = this.scale;
}
if (this.tint) {
texture.tint = this.tint;
}
if (this.alpha) {
this.actor.synthetics.tokenOverrides.alpha = this.alpha;
}
this.actor.synthetics.tokenOverrides.texture = texture;
}
#srcIsValid(src: unknown): src is VideoFilePath {
if (typeof src !== "string") return false;
const extension = /(?<=\.)[a-z0-9]{3,4}$/i.exec(src)?.at(0);
return !!extension && (extension in CONST.IMAGE_FILE_EXTENSIONS || extension in CONST.VIDEO_FILE_EXTENSIONS);
}
}
interface TokenImageRuleElement
extends RuleElementPF2e<TokenImageRuleSchema>,
ModelPropsFromRESchema<TokenImageRuleSchema> {}
type TokenImageRuleSchema = RuleElementSchema & {
/** An image or video path */
value: ResolvableValueField<true, false, false>;
/** An optional scale adjustment */
scale: NumberField<number, number, false, true, true>;
/** An optional tint adjustment */
tint: ColorField;
/** An optional alpha adjustment */
alpha: AlphaField<false, true, true>;
};
export { TokenImageRuleElement };