Files
Foundry-VTT-Docker/resources/app/client-esm/canvas/sources/point-light-source.mjs

90 lines
3.2 KiB
JavaScript
Raw Normal View History

2025-01-04 00:34:03 +01:00
import BaseLightSource from "./base-light-source.mjs";
import PointEffectSourceMixin from "./point-effect-source.mjs";
/**
* A specialized subclass of the BaseLightSource which renders a source of light as a point-based effect.
* @extends {BaseLightSource}
* @mixes {PointEffectSourceMixin}
*/
export default class PointLightSource extends PointEffectSourceMixin(BaseLightSource) {
/** @override */
static effectsCollection = "lightSources";
/* -------------------------------------------- */
/* Source Suppression Management */
/* -------------------------------------------- */
/**
* Update darkness suppression according to darkness sources collection.
*/
#updateDarknessSuppression() {
this.suppression.darkness = canvas.effects.testInsideDarkness({x: this.x, y: this.y}, this.elevation);
}
/* -------------------------------------------- */
/* Light Source Initialization */
/* -------------------------------------------- */
/** @inheritDoc */
_initialize(data) {
super._initialize(data);
Object.assign(this.data, {
radius: Math.max(this.data.dim ?? 0, this.data.bright ?? 0)
});
}
/* -------------------------------------------- */
/** @inheritDoc */
_createShapes() {
this.#updateDarknessSuppression();
super._createShapes();
}
/* -------------------------------------------- */
/** @inheritDoc */
_configure(changes) {
this.ratio = Math.clamp(Math.abs(this.data.bright) / this.data.radius, 0, 1);
super._configure(changes);
}
/* -------------------------------------------- */
/** @inheritDoc */
_getPolygonConfiguration() {
return Object.assign(super._getPolygonConfiguration(), {useThreshold: true, includeDarkness: true});
}
/* -------------------------------------------- */
/* Visibility Testing */
/* -------------------------------------------- */
/**
* Test whether this LightSource provides visibility to see a certain target object.
* @param {object} config The visibility test configuration
* @param {CanvasVisibilityTest[]} config.tests The sequence of tests to perform
* @param {PlaceableObject} config.object The target object being tested
* @returns {boolean} Is the target object visible to this source?
*/
testVisibility({tests, object}={}) {
if ( !(this.data.vision && this._canDetectObject(object)) ) return false;
return tests.some(test => this.shape.contains(test.point.x, test.point.y));
}
/* -------------------------------------------- */
/**
* Can this LightSource theoretically detect a certain object based on its properties?
* This check should not consider the relative positions of either object, only their state.
* @param {PlaceableObject} target The target object being tested
* @returns {boolean} Can the target object theoretically be detected by this vision source?
*/
_canDetectObject(target) {
const tgt = target?.document;
const isInvisible = ((tgt instanceof TokenDocument) && tgt.hasStatusEffect(CONFIG.specialStatusEffects.INVISIBLE));
return !isInvisible;
}
}