Files
2025-01-04 00:34:03 +01:00

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});
}
}