137 lines
5.0 KiB
JavaScript
137 lines
5.0 KiB
JavaScript
import RegionBehaviorType from "./base.mjs";
|
|
import {REGION_EVENTS} from "../../../common/constants.mjs";
|
|
import RegionMesh from "../../canvas/regions/mesh.mjs";
|
|
import * as fields from "../../../common/data/fields.mjs";
|
|
|
|
/**
|
|
* The data model for a behavior that allows to suppress weather effects within the Region
|
|
*/
|
|
export default class AdjustDarknessLevelRegionBehaviorType extends RegionBehaviorType {
|
|
|
|
/** @override */
|
|
static LOCALIZATION_PREFIXES = ["BEHAVIOR.TYPES.adjustDarknessLevel", "BEHAVIOR.TYPES.base"];
|
|
|
|
/* ---------------------------------------- */
|
|
|
|
/**
|
|
* Darkness level behavior modes.
|
|
* @enum {number}
|
|
*/
|
|
static get MODES() {
|
|
return AdjustDarknessLevelRegionBehaviorType.#MODES;
|
|
}
|
|
|
|
static #MODES = Object.freeze({
|
|
/**
|
|
* Override the darkness level with the modifier.
|
|
*/
|
|
OVERRIDE: 0,
|
|
|
|
/**
|
|
* Brighten the darkness level: `darknessLevel * (1 - modifier)`
|
|
*/
|
|
BRIGHTEN: 1,
|
|
|
|
/**
|
|
* Darken the darkness level: `1 - (1 - darknessLevel) * (1 - modifier)`.
|
|
*/
|
|
DARKEN: 2
|
|
});
|
|
|
|
/* ---------------------------------------- */
|
|
|
|
/** @override */
|
|
static defineSchema() {
|
|
return {
|
|
mode: new fields.NumberField({required: true, blank: false, choices: Object.fromEntries(Object.entries(this.MODES)
|
|
.map(([key, value]) => [value, `BEHAVIOR.TYPES.adjustDarknessLevel.MODES.${key}.label`])),
|
|
initial: this.MODES.OVERRIDE, validationError: "must be a value in AdjustDarknessLevelRegionBehaviorType.MODES"}),
|
|
modifier: new fields.AlphaField({initial: 0, step: 0.01})
|
|
};
|
|
}
|
|
|
|
/* ---------------------------------------- */
|
|
|
|
/**
|
|
* Called when the status of the weather behavior is changed.
|
|
* @param {RegionEvent} event
|
|
* @this {AdjustDarknessLevelRegionBehaviorType}
|
|
*/
|
|
static async #onBehaviorStatus(event) {
|
|
|
|
// Create mesh
|
|
if ( event.data.viewed === true ) {
|
|
// Create darkness level mesh
|
|
const dlMesh = new RegionMesh(this.region.object, AdjustDarknessLevelRegionShader);
|
|
if ( canvas.performance.mode > CONST.CANVAS_PERFORMANCE_MODES.LOW ) {
|
|
dlMesh._blurFilter = canvas.createBlurFilter(8, 2);
|
|
dlMesh.filters = [dlMesh._blurFilter];
|
|
}
|
|
|
|
// Create illumination mesh
|
|
const illMesh = new RegionMesh(this.region.object, IlluminationDarknessLevelRegionShader);
|
|
|
|
// Common properties
|
|
illMesh.name = dlMesh.name = this.behavior.uuid;
|
|
illMesh.shader.mode = dlMesh.shader.mode = this.mode;
|
|
illMesh.shader.modifier = dlMesh.shader.modifier = this.modifier;
|
|
|
|
// Adding the mesh to their respective containers
|
|
canvas.effects.illumination.darknessLevelMeshes.addChild(dlMesh);
|
|
canvas.visibility.vision.light.global.meshes.addChild(illMesh);
|
|
|
|
// Invalidate darkness level container and refresh vision if global light is enabled
|
|
canvas.effects.illumination.invalidateDarknessLevelContainer(true);
|
|
canvas.perception.update({refreshLighting: true, refreshVision: canvas.environment.globalLightSource.active});
|
|
}
|
|
|
|
// Destroy mesh
|
|
else if ( event.data.viewed === false ) {
|
|
const dlMesh = canvas.effects.illumination.darknessLevelMeshes.getChildByName(this.behavior.uuid);
|
|
if ( dlMesh._blurFilter ) canvas.blurFilters.delete(dlMesh._blurFilter);
|
|
dlMesh.destroy();
|
|
const ilMesh = canvas.visibility.vision.light.global.meshes.getChildByName(this.behavior.uuid);
|
|
ilMesh.destroy();
|
|
canvas.effects.illumination.invalidateDarknessLevelContainer(true);
|
|
canvas.perception.update({refreshLighting: true, refreshVision: canvas.environment.globalLightSource.active});
|
|
}
|
|
}
|
|
|
|
/* ---------------------------------------- */
|
|
|
|
/**
|
|
* Called when the boundary of an event has changed.
|
|
* @param {RegionEvent} event
|
|
* @this {AdjustDarknessLevelRegionBehaviorType}
|
|
*/
|
|
static async #onRegionBoundary(event) {
|
|
if ( !this.behavior.viewed ) return;
|
|
canvas.effects.illumination.invalidateDarknessLevelContainer(true);
|
|
canvas.perception.update({refreshLighting: true, refreshVision: canvas.environment.globalLightSource.active});
|
|
}
|
|
|
|
/* ---------------------------------------- */
|
|
|
|
/** @override */
|
|
static events = {
|
|
[REGION_EVENTS.BEHAVIOR_STATUS]: this.#onBehaviorStatus,
|
|
[REGION_EVENTS.REGION_BOUNDARY]: this.#onRegionBoundary
|
|
};
|
|
|
|
/* ---------------------------------------- */
|
|
|
|
/** @inheritDoc */
|
|
_onUpdate(changed, options, userId) {
|
|
super._onUpdate(changed, options, userId);
|
|
if ( !("system" in changed) || !this.behavior.viewed ) return;
|
|
const dlMesh = canvas.effects.illumination.darknessLevelMeshes.getChildByName(this.behavior.uuid);
|
|
dlMesh.shader.mode = this.mode;
|
|
dlMesh.shader.modifier = this.modifier;
|
|
const ilMesh = canvas.visibility.vision.light.global.meshes.getChildByName(this.behavior.uuid);
|
|
ilMesh.shader.mode = this.mode;
|
|
ilMesh.shader.modifier = this.modifier;
|
|
canvas.effects.illumination.invalidateDarknessLevelContainer(true);
|
|
canvas.perception.update({refreshLighting: true, refreshVision: canvas.environment.globalLightSource.active});
|
|
}
|
|
}
|