Compare commits
1 commit
master
...
replace-li
Author | SHA1 | Date | |
---|---|---|---|
5b2b29ae4c |
6 changed files with 131 additions and 296 deletions
|
@ -17,13 +17,6 @@ the Setup menu of the application.
|
||||||
|
|
||||||
https://git.f3l.de/ghost/darkness-dependent-vision/-/raw/latest/src/module.json?inline=false
|
https://git.f3l.de/ghost/darkness-dependent-vision/-/raw/latest/src/module.json?inline=false
|
||||||
|
|
||||||
### libWrapper
|
|
||||||
|
|
||||||
This module uses the [libWrapper] library for wrapping core methods. It is only
|
|
||||||
a soft dependency (a shim is provided) but it is highly recommended to install
|
|
||||||
libWrapper as a module for the best experience and compatibility with other
|
|
||||||
modules.
|
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
In order to configure the darkness range in which a token has dim and bright
|
In order to configure the darkness range in which a token has dim and bright
|
||||||
|
@ -116,7 +109,6 @@ specified either inside the source file or by an accompanying `.license` file,
|
||||||
but for some files, the licenses are specified in [.reuse/dep5].
|
but for some files, the licenses are specified in [.reuse/dep5].
|
||||||
|
|
||||||
[Foundry Virtual Tabletop]: http://foundryvtt.com
|
[Foundry Virtual Tabletop]: http://foundryvtt.com
|
||||||
[libWrapper]: https://github.com/ruipin/fvtt-lib-wrapper
|
|
||||||
[LIMITED LICENSE AGREEMENT FOR MODULE DEVELOPMENT]: https://foundryvtt.com/article/license/
|
[LIMITED LICENSE AGREEMENT FOR MODULE DEVELOPMENT]: https://foundryvtt.com/article/license/
|
||||||
[REUSE]: https://reuse.software/
|
[REUSE]: https://reuse.software/
|
||||||
[.reuse/dep5]: .reuse/dep5
|
[.reuse/dep5]: .reuse/dep5
|
||||||
|
|
|
@ -5,9 +5,8 @@
|
||||||
import { packageName } from '../config';
|
import { packageName } from '../config';
|
||||||
import registerHandlebarsPartials from '../handlebars-partials';
|
import registerHandlebarsPartials from '../handlebars-partials';
|
||||||
import logger from '../logger';
|
import logger from '../logger';
|
||||||
|
import { registerMixins } from '../mixins/index.js';
|
||||||
import registerSettings from '../setiings';
|
import registerSettings from '../setiings';
|
||||||
import { libWrapper } from '../shims/libWrapperShim';
|
|
||||||
import { getBrightRadius, getDimRadius, updateVisionSource } from '../wrappers/token';
|
|
||||||
|
|
||||||
export default function registerForInitHook() {
|
export default function registerForInitHook() {
|
||||||
Hooks.on('init', onInit);
|
Hooks.on('init', onInit);
|
||||||
|
@ -16,27 +15,7 @@ export default function registerForInitHook() {
|
||||||
async function onInit() {
|
async function onInit() {
|
||||||
logger.info(`Initializing ${packageName}`);
|
logger.info(`Initializing ${packageName}`);
|
||||||
|
|
||||||
const dimRadiusTarget = 'Token.prototype.dimRadius';
|
registerMixins();
|
||||||
try {
|
|
||||||
libWrapper.register(packageName, dimRadiusTarget, getDimRadius, 'OVERRIDE');
|
|
||||||
} catch (e) {
|
|
||||||
logger.warn(`Failed to override ${dimRadiusTarget}, some things might not work correctly:`, e);
|
|
||||||
}
|
|
||||||
|
|
||||||
const brightRadiusTarget = 'Token.prototype.brightRadius';
|
|
||||||
try {
|
|
||||||
libWrapper.register(packageName, brightRadiusTarget, getBrightRadius, 'OVERRIDE');
|
|
||||||
} catch (e) {
|
|
||||||
logger.warn(`Failed to override ${brightRadiusTarget}, some things might not work correctly:`, e);
|
|
||||||
}
|
|
||||||
|
|
||||||
const updateVisionSourceTarget = 'Token.prototype.updateVisionSource';
|
|
||||||
try {
|
|
||||||
libWrapper.register(packageName, updateVisionSourceTarget, updateVisionSource, 'OVERRIDE');
|
|
||||||
} catch (e) {
|
|
||||||
logger.warn(`Failed to override ${updateVisionSourceTarget}, some things might not work correctly:`, e);
|
|
||||||
}
|
|
||||||
|
|
||||||
registerSettings();
|
registerSettings();
|
||||||
await registerHandlebarsPartials();
|
await registerHandlebarsPartials();
|
||||||
}
|
}
|
||||||
|
|
5
src/mixins/index.js
Normal file
5
src/mixins/index.js
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
import { registerTokenMixin } from './token';
|
||||||
|
|
||||||
|
export function registerMixins() {
|
||||||
|
registerTokenMixin();
|
||||||
|
}
|
124
src/mixins/token.js
Normal file
124
src/mixins/token.js
Normal file
|
@ -0,0 +1,124 @@
|
||||||
|
// SPDX-FileCopyrightText: 2021 Johannes Loher
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
import { packageName } from '../config';
|
||||||
|
|
||||||
|
export function registerTokenMixin() {
|
||||||
|
CONFIG.Token.objectClass = TokenMixin(CONFIG.Token.objectClass);
|
||||||
|
}
|
||||||
|
|
||||||
|
function TokenMixin(BaseToken) {
|
||||||
|
return class extends BaseToken {
|
||||||
|
/**
|
||||||
|
* Translate the token's sight distance in units into a radius in pixels.
|
||||||
|
* @return {number} The sight radius in pixels
|
||||||
|
* @override
|
||||||
|
*/
|
||||||
|
get dimRadius() {
|
||||||
|
const dimSight = this._dimVision;
|
||||||
|
let r = Math.abs(this.data.dimLight) > Math.abs(dimSight) ? this.data.dimLight : dimSight;
|
||||||
|
return this.getLightRadius(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Does this {@link Token} have dim vision, considering the darkness level of
|
||||||
|
* its containing {@link Scene}?
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
get _hasDimVision() {
|
||||||
|
const dimVisionDarknessMin = this.document.getFlag(packageName, 'dimVisionDarknessMin') ?? 0;
|
||||||
|
const dimVisionDarknessMax = this.document.getFlag(packageName, 'dimVisionDarknessMax') ?? 1;
|
||||||
|
const darkness = this.document.parent.data.darkness;
|
||||||
|
return dimVisionDarknessMin <= darkness && darkness <= dimVisionDarknessMax;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get this {@link Token}'s dim vision distance of in grid units, considering
|
||||||
|
* the darkness level of its containing {@link Scene}.
|
||||||
|
*
|
||||||
|
* @returns {number} The the number of grid units that this {@link Token} has
|
||||||
|
* dim vision
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
get _dimVision() {
|
||||||
|
return this._hasDimVision ? this.data.dimSight : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Translate the token's bright light distance in units into a radius in pixels.
|
||||||
|
* @return {number} The bright radius in pixels
|
||||||
|
* @override
|
||||||
|
*/
|
||||||
|
get brightRadius() {
|
||||||
|
const brightSight = this._brightVision;
|
||||||
|
let r = Math.abs(this.data.brightLight) > Math.abs(brightSight) ? this.data.brightLight : brightSight;
|
||||||
|
return this.getLightRadius(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Does this {@link Token} have bright vision, considering the darkness level of
|
||||||
|
* its containing {@link Scene}?
|
||||||
|
* @override
|
||||||
|
*/
|
||||||
|
get _hasBrightVision() {
|
||||||
|
const brightVisionDarknessMin = this.document.getFlag(packageName, 'brightVisionDarknessMin') ?? 0;
|
||||||
|
const brightVisionDarknessMax = this.document.getFlag(packageName, 'brightVisionDarknessMax') ?? 1;
|
||||||
|
const darkness = this.document.parent.data.darkness;
|
||||||
|
return brightVisionDarknessMin <= darkness && darkness <= brightVisionDarknessMax;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get this {@link Token}'s bright vision distance in grid units, considering
|
||||||
|
* the darkness level of its containing {@link Scene}.
|
||||||
|
*
|
||||||
|
* @returns {number} The the number of grid units that this {@link Token} has
|
||||||
|
* bright vision
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
get _brightVision() {
|
||||||
|
return this._hasBrightVision ? this.data.brightSight : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update an Token vision source associated for this token.
|
||||||
|
* @param {boolean} [defer] Defer refreshing the LightingLayer to manually call that refresh later.
|
||||||
|
* @param {boolean} [deleted] Indicate that this vision source has been deleted.
|
||||||
|
* @param {boolean} [skipUpdateFog] Never update the Fog exploration progress for this update.
|
||||||
|
* @override
|
||||||
|
*/
|
||||||
|
updateVisionSource({ defer = false, deleted = false, skipUpdateFog = false } = {}) {
|
||||||
|
// Prepare data
|
||||||
|
const origin = this.getSightOrigin();
|
||||||
|
const sourceId = this.sourceId;
|
||||||
|
const d = canvas.dimensions;
|
||||||
|
const isVisionSource = this._isVisionSource();
|
||||||
|
|
||||||
|
// Initialize vision source
|
||||||
|
if (isVisionSource && !deleted) {
|
||||||
|
const dimSight = this._dimVision;
|
||||||
|
const brightSight = this._brightVision;
|
||||||
|
let dim = Math.min(this.getLightRadius(dimSight), d.maxR);
|
||||||
|
const bright = Math.min(this.getLightRadius(brightSight), d.maxR);
|
||||||
|
this.vision.initialize({
|
||||||
|
x: origin.x,
|
||||||
|
y: origin.y,
|
||||||
|
dim: dim,
|
||||||
|
bright: bright,
|
||||||
|
angle: this.data.sightAngle,
|
||||||
|
rotation: this.data.rotation,
|
||||||
|
});
|
||||||
|
canvas.sight.sources.set(sourceId, this.vision);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove vision source
|
||||||
|
else canvas.sight.sources.delete(sourceId);
|
||||||
|
|
||||||
|
// Schedule a perception update
|
||||||
|
if (!defer && (isVisionSource || deleted))
|
||||||
|
canvas.perception.schedule({
|
||||||
|
sight: { refresh: true, skipUpdateFog },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
|
@ -1,156 +0,0 @@
|
||||||
// SPDX-License-Identifier: MIT
|
|
||||||
// Copyright © 2021 fvtt-lib-wrapper Rui Pinheiro
|
|
||||||
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
// A shim for the libWrapper library
|
|
||||||
export let libWrapper = undefined;
|
|
||||||
|
|
||||||
export const VERSIONS = [1, 12, 1];
|
|
||||||
export const TGT_SPLIT_RE = new RegExp('([^.[]+|\\[(\'([^\'\\\\]|\\\\.)+?\'|"([^"\\\\]|\\\\.)+?")\\])', 'g');
|
|
||||||
export const TGT_CLEANUP_RE = new RegExp('(^\\[\'|\'\\]$|^\\["|"\\]$)', 'g');
|
|
||||||
|
|
||||||
// Main shim code
|
|
||||||
Hooks.once('init', () => {
|
|
||||||
// Check if the real module is already loaded - if so, use it
|
|
||||||
if (globalThis.libWrapper && !(globalThis.libWrapper.is_fallback ?? true)) {
|
|
||||||
libWrapper = globalThis.libWrapper;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fallback implementation
|
|
||||||
libWrapper = class {
|
|
||||||
static get is_fallback() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static get WRAPPER() {
|
|
||||||
return 'WRAPPER';
|
|
||||||
}
|
|
||||||
static get MIXED() {
|
|
||||||
return 'MIXED';
|
|
||||||
}
|
|
||||||
static get OVERRIDE() {
|
|
||||||
return 'OVERRIDE';
|
|
||||||
}
|
|
||||||
|
|
||||||
static register(package_id, target, fn, type = 'MIXED', { chain = undefined, bind = [] } = {}) {
|
|
||||||
const is_setter = target.endsWith('#set');
|
|
||||||
target = !is_setter ? target : target.slice(0, -4);
|
|
||||||
const split = target.match(TGT_SPLIT_RE).map((x) => x.replace(/\\(.)/g, '$1').replace(TGT_CLEANUP_RE, ''));
|
|
||||||
const root_nm = split.splice(0, 1)[0];
|
|
||||||
|
|
||||||
let obj, fn_name;
|
|
||||||
if (split.length == 0) {
|
|
||||||
obj = globalThis;
|
|
||||||
fn_name = root_nm;
|
|
||||||
} else {
|
|
||||||
const _eval = eval;
|
|
||||||
fn_name = split.pop();
|
|
||||||
obj = split.reduce((x, y) => x[y], globalThis[root_nm] ?? _eval(root_nm));
|
|
||||||
}
|
|
||||||
|
|
||||||
let iObj = obj;
|
|
||||||
let descriptor = null;
|
|
||||||
while (iObj) {
|
|
||||||
descriptor = Object.getOwnPropertyDescriptor(iObj, fn_name);
|
|
||||||
if (descriptor) break;
|
|
||||||
iObj = Object.getPrototypeOf(iObj);
|
|
||||||
}
|
|
||||||
if (!descriptor || descriptor?.configurable === false)
|
|
||||||
throw new Error(
|
|
||||||
`libWrapper Shim: '${target}' does not exist, could not be found, or has a non-configurable descriptor.`,
|
|
||||||
);
|
|
||||||
|
|
||||||
let original = null;
|
|
||||||
const wrapper =
|
|
||||||
chain ?? (type.toUpperCase?.() != 'OVERRIDE' && type != 3)
|
|
||||||
? function (...args) {
|
|
||||||
return fn.call(this, original.bind(this), ...bind, ...args);
|
|
||||||
}
|
|
||||||
: function (...args) {
|
|
||||||
return fn.call(this, ...bind, ...args);
|
|
||||||
};
|
|
||||||
if (!is_setter) {
|
|
||||||
if (descriptor.value) {
|
|
||||||
original = descriptor.value;
|
|
||||||
descriptor.value = wrapper;
|
|
||||||
} else {
|
|
||||||
original = descriptor.get;
|
|
||||||
descriptor.get = wrapper;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (!descriptor.set) throw new Error(`libWrapper Shim: '${target}' does not have a setter`);
|
|
||||||
original = descriptor.set;
|
|
||||||
descriptor.set = wrapper;
|
|
||||||
}
|
|
||||||
|
|
||||||
descriptor.configurable = true;
|
|
||||||
Object.defineProperty(obj, fn_name, descriptor);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
//************** USER CUSTOMIZABLE:
|
|
||||||
// Set up the ready hook that shows the "libWrapper not installed" warning dialog. Remove if undesired.
|
|
||||||
{
|
|
||||||
//************** USER CUSTOMIZABLE:
|
|
||||||
// Package ID & Package Title - by default attempts to auto-detect, but you might want to hardcode your package ID and title here to avoid potential auto-detect issues
|
|
||||||
const [PACKAGE_ID, PACKAGE_TITLE] = (() => {
|
|
||||||
const match = (import.meta?.url ?? Error().stack)?.match(/\/(worlds|systems|modules)\/(.+)(?=\/)/i);
|
|
||||||
if (match?.length !== 3) return [null, null];
|
|
||||||
const dirs = match[2].split('/');
|
|
||||||
if (match[1] === 'worlds')
|
|
||||||
return dirs.find((n) => n && game.world.id === n) ? [game.world.id, game.world.title] : [null, null];
|
|
||||||
if (match[1] === 'systems')
|
|
||||||
return dirs.find((n) => n && game.system.id === n) ? [game.system.id, game.system.data.title] : [null, null];
|
|
||||||
const id = dirs.find((n) => n && game.modules.has(n));
|
|
||||||
return [id, game.modules.get(id)?.data?.title];
|
|
||||||
})();
|
|
||||||
|
|
||||||
if (!PACKAGE_ID || !PACKAGE_TITLE) {
|
|
||||||
console.error(
|
|
||||||
'libWrapper Shim: Could not auto-detect package ID and/or title. The libWrapper fallback warning dialog will be disabled.',
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Hooks.once('ready', () => {
|
|
||||||
//************** USER CUSTOMIZABLE:
|
|
||||||
// Title and message for the dialog shown when the real libWrapper is not installed.
|
|
||||||
const FALLBACK_MESSAGE_TITLE = PACKAGE_TITLE;
|
|
||||||
const FALLBACK_MESSAGE = `
|
|
||||||
<p><b>'${PACKAGE_TITLE}' depends on the 'libWrapper' module, which is not present.</b></p>
|
|
||||||
<p>A fallback implementation will be used, which increases the chance of compatibility issues with other modules.</p>
|
|
||||||
<small><p>'libWrapper' is a library which provides package developers with a simple way to modify core Foundry VTT code, while reducing the likelihood of conflict with other packages.</p>
|
|
||||||
<p>You can install it from the "Add-on Modules" tab in the <a href="javascript:game.shutDown()">Foundry VTT Setup</a>, from the <a href="https://foundryvtt.com/packages/lib-wrapper">Foundry VTT package repository</a>, or from <a href="https://github.com/ruipin/fvtt-lib-wrapper/">libWrapper's Github page</a>.</p></small>
|
|
||||||
`;
|
|
||||||
|
|
||||||
// Settings key used for the "Don't remind me again" setting
|
|
||||||
const DONT_REMIND_AGAIN_KEY = 'libwrapper-dont-remind-again';
|
|
||||||
|
|
||||||
// Dialog code
|
|
||||||
console.warn(`${PACKAGE_TITLE}: libWrapper not present, using fallback implementation.`);
|
|
||||||
game.settings.register(PACKAGE_ID, DONT_REMIND_AGAIN_KEY, {
|
|
||||||
name: '',
|
|
||||||
default: false,
|
|
||||||
type: Boolean,
|
|
||||||
scope: 'world',
|
|
||||||
config: false,
|
|
||||||
});
|
|
||||||
if (game.user.isGM && !game.settings.get(PACKAGE_ID, DONT_REMIND_AGAIN_KEY)) {
|
|
||||||
new Dialog({
|
|
||||||
title: FALLBACK_MESSAGE_TITLE,
|
|
||||||
content: FALLBACK_MESSAGE,
|
|
||||||
buttons: {
|
|
||||||
ok: { icon: '<i class="fas fa-check"></i>', label: 'Understood' },
|
|
||||||
dont_remind: {
|
|
||||||
icon: '<i class="fas fa-times"></i>',
|
|
||||||
label: "Don't remind me again",
|
|
||||||
callback: () => game.settings.set(PACKAGE_ID, DONT_REMIND_AGAIN_KEY, true),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}).render(true);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
|
@ -1,109 +0,0 @@
|
||||||
// SPDX-FileCopyrightText: 2021 Johannes Loher
|
|
||||||
//
|
|
||||||
// SPDX-License-Identifier: MIT
|
|
||||||
|
|
||||||
import { packageName } from '../config';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Translate the token's sight distance in units into a radius in pixels.
|
|
||||||
* @return {number} The sight radius in pixels
|
|
||||||
*/
|
|
||||||
export function getDimRadius() {
|
|
||||||
const dimSight = getDimVision.call(this);
|
|
||||||
let r = Math.abs(this.data.dimLight) > Math.abs(dimSight) ? this.data.dimLight : dimSight;
|
|
||||||
return this.getLightRadius(r);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Translate the token's bright light distance in units into a radius in pixels.
|
|
||||||
* @return {number} The bright radius in pixels
|
|
||||||
*/
|
|
||||||
export function getBrightRadius() {
|
|
||||||
const brightSight = getBrightVision.call(this);
|
|
||||||
let r = Math.abs(this.data.brightLight) > Math.abs(brightSight) ? this.data.brightLight : brightSight;
|
|
||||||
return this.getLightRadius(r);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Update an Token vision source associated for this token.
|
|
||||||
* @param {boolean} [defer] Defer refreshing the LightingLayer to manually call that refresh later.
|
|
||||||
* @param {boolean} [deleted] Indicate that this vision source has been deleted.
|
|
||||||
* @param {boolean} [skipUpdateFog] Never update the Fog exploration progress for this update.
|
|
||||||
*/
|
|
||||||
export function updateVisionSource({ defer = false, deleted = false, skipUpdateFog = false } = {}) {
|
|
||||||
// Prepare data
|
|
||||||
const origin = this.getSightOrigin();
|
|
||||||
const sourceId = this.sourceId;
|
|
||||||
const d = canvas.dimensions;
|
|
||||||
const isVisionSource = this._isVisionSource();
|
|
||||||
|
|
||||||
// Initialize vision source
|
|
||||||
if (isVisionSource && !deleted) {
|
|
||||||
const dimSight = getDimVision.call(this);
|
|
||||||
const brightSight = getBrightVision.call(this);
|
|
||||||
let dim = Math.min(this.getLightRadius(dimSight), d.maxR);
|
|
||||||
const bright = Math.min(this.getLightRadius(brightSight), d.maxR);
|
|
||||||
this.vision.initialize({
|
|
||||||
x: origin.x,
|
|
||||||
y: origin.y,
|
|
||||||
dim: dim,
|
|
||||||
bright: bright,
|
|
||||||
angle: this.data.sightAngle,
|
|
||||||
rotation: this.data.rotation,
|
|
||||||
});
|
|
||||||
canvas.sight.sources.set(sourceId, this.vision);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove vision source
|
|
||||||
else canvas.sight.sources.delete(sourceId);
|
|
||||||
|
|
||||||
// Schedule a perception update
|
|
||||||
if (!defer && (isVisionSource || deleted))
|
|
||||||
canvas.perception.schedule({
|
|
||||||
sight: { refresh: true, skipUpdateFog },
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Does this {@link Token} have dim vision, considering the darkness level of
|
|
||||||
* its containing {@link Scene}?
|
|
||||||
*/
|
|
||||||
function hasDimVision() {
|
|
||||||
const dimVisionDarknessMin = this.document.getFlag(packageName, 'dimVisionDarknessMin') ?? 0;
|
|
||||||
const dimVisionDarknessMax = this.document.getFlag(packageName, 'dimVisionDarknessMax') ?? 1;
|
|
||||||
const darkness = this.document.parent.data.darkness;
|
|
||||||
return dimVisionDarknessMin <= darkness && darkness <= dimVisionDarknessMax;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Does this {@link Token} have bright vision, considering the darkness level of
|
|
||||||
* its containing {@link Scene}?
|
|
||||||
*/
|
|
||||||
function hasBrightVision() {
|
|
||||||
const brightVisionDarknessMin = this.document.getFlag(packageName, 'brightVisionDarknessMin') ?? 0;
|
|
||||||
const brightVisionDarknessMax = this.document.getFlag(packageName, 'brightVisionDarknessMax') ?? 1;
|
|
||||||
const darkness = this.document.parent.data.darkness;
|
|
||||||
return brightVisionDarknessMin <= darkness && darkness <= brightVisionDarknessMax;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get this {@link Token}'s dim vision distance of in grid units, considering
|
|
||||||
* the darkness level of its containing {@link Scene}.
|
|
||||||
*
|
|
||||||
* @returns {number} The the number of grid units that this {@link Token} has
|
|
||||||
* dim vision
|
|
||||||
*/
|
|
||||||
function getDimVision() {
|
|
||||||
return hasDimVision.call(this) ? this.data.dimSight : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get this {@link Token}'s bright vision distance in grid units, considering
|
|
||||||
* the darkness level of its containing {@link Scene}.
|
|
||||||
*
|
|
||||||
* @returns {number} The the number of grid units that this {@link Token} has
|
|
||||||
* bright vision
|
|
||||||
*/
|
|
||||||
function getBrightVision() {
|
|
||||||
return hasBrightVision.call(this) ? this.data.brightSight : 0;
|
|
||||||
}
|
|
Loading…
Reference in a new issue