Initial commit
This commit is contained in:
commit
32ae12c6bd
38 changed files with 16736 additions and 0 deletions
13
.editorconfig
Normal file
13
.editorconfig
Normal file
|
@ -0,0 +1,13 @@
|
|||
# SPDX-FileCopyrightText: 2021 Johannes Loher
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
root = true
|
||||
|
||||
[*]
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
5
.eslintignore
Normal file
5
.eslintignore
Normal file
|
@ -0,0 +1,5 @@
|
|||
# SPDX-FileCopyrightText: 2021 Johannes Loher
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
dist
|
36
.eslintrc.js
Normal file
36
.eslintrc.js
Normal file
|
@ -0,0 +1,36 @@
|
|||
// SPDX-FileCopyrightText: 2021 Johannes Loher
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
module.exports = {
|
||||
parserOptions: {
|
||||
ecmaVersion: 2020,
|
||||
sourceType: 'module',
|
||||
},
|
||||
|
||||
env: {
|
||||
browser: true,
|
||||
es2020: true,
|
||||
},
|
||||
|
||||
extends: ['eslint:recommended', '@typhonjs-fvtt/eslint-config-foundry.js/0.7.9', 'plugin:prettier/recommended'],
|
||||
|
||||
plugins: [],
|
||||
|
||||
globals: {
|
||||
foundry: false,
|
||||
},
|
||||
|
||||
rules: {
|
||||
// Specify any specific ESLint rules.
|
||||
},
|
||||
|
||||
overrides: [
|
||||
{
|
||||
files: ['./*.js'],
|
||||
env: {
|
||||
node: true,
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
32
.gitignore
vendored
Normal file
32
.gitignore
vendored
Normal file
|
@ -0,0 +1,32 @@
|
|||
# SPDX-FileCopyrightText: 2021 Johannes Loher
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
# IDE
|
||||
.idea/
|
||||
.vs/
|
||||
|
||||
# Node Modules
|
||||
node_modules/
|
||||
npm-debug.log
|
||||
|
||||
# yarn2
|
||||
.yarn/*
|
||||
!.yarn/patches
|
||||
!.yarn/releases
|
||||
!.yarn/plugins
|
||||
!.yarn/sdks
|
||||
!.yarn/versions
|
||||
.pnp.*
|
||||
|
||||
# Local configuration
|
||||
foundryconfig.json
|
||||
|
||||
# Distribution files
|
||||
dist
|
||||
|
||||
# ESLint
|
||||
.eslintcache
|
||||
|
||||
# Junit results
|
||||
junit.xml
|
90
.gitlab-ci.yml
Normal file
90
.gitlab-ci.yml
Normal file
|
@ -0,0 +1,90 @@
|
|||
# SPDX-FileCopyrightText: 2021 Johannes Loher
|
||||
# SPDX-FileCopyrightText: 2021 Oliver Rümpelein
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
image: node:lts
|
||||
|
||||
stages:
|
||||
- test
|
||||
- build
|
||||
- release
|
||||
|
||||
before_script:
|
||||
- yarn install --immutable
|
||||
|
||||
cache: &global_cache
|
||||
paths:
|
||||
- .yarn/cache
|
||||
|
||||
lint:
|
||||
stage: test
|
||||
script:
|
||||
- yarn lint
|
||||
cache:
|
||||
<<: *global_cache
|
||||
|
||||
reuse:
|
||||
stage: test
|
||||
image:
|
||||
name: fsfe/reuse:latest
|
||||
entrypoint: [""]
|
||||
before_script: []
|
||||
script:
|
||||
- reuse lint
|
||||
|
||||
build:
|
||||
stage: build
|
||||
script:
|
||||
- yarn build
|
||||
- mv dist darkness-dependent-vision
|
||||
cache:
|
||||
<<: *global_cache
|
||||
artifacts:
|
||||
paths:
|
||||
- darkness-dependent-vision
|
||||
expire_in: 1 week
|
||||
|
||||
.release-template: &release-template
|
||||
stage: release
|
||||
before_script:
|
||||
- yarn install
|
||||
- apt update
|
||||
- apt install --yes jq
|
||||
- REPOSITORY_URL=$(echo "${CI_REPOSITORY_URL}" | sed -e "s|gitlab-ci-token:.*@|${RELEASE_TOKEN}:${RELEASE_TOKEN_SECRET}@|g")
|
||||
- git remote set-url origin $REPOSITORY_URL
|
||||
- git config user.name $GITLAB_USER_LOGIN
|
||||
- git config user.email $GITLAB_USER_EMAIL
|
||||
- git branch -D ci-processing || true
|
||||
- git checkout -b ci-processing
|
||||
cache:
|
||||
<<: *global_cache
|
||||
script: |
|
||||
yarn bump-version --release=${RELEASE_TYPE}
|
||||
RELEASE_VERSION=$(jq -r '.version' < package.json)
|
||||
git add package.json src/module.json
|
||||
git --no-pager diff
|
||||
git commit -m "release version ${RELEASE_VERSION}"
|
||||
git tag -f latest
|
||||
git tag -f ${RELEASE_VERSION}
|
||||
git push origin ci-processing:${CI_BUILD_REF_NAME}
|
||||
git push origin latest -f
|
||||
git push origin ${RELEASE_VERSION}
|
||||
only:
|
||||
- master
|
||||
when: manual
|
||||
|
||||
release-patch:
|
||||
variables:
|
||||
RELEASE_TYPE: patch
|
||||
<<: *release-template
|
||||
|
||||
release-minor:
|
||||
variables:
|
||||
RELEASE_TYPE: minor
|
||||
<<: *release-template
|
||||
|
||||
release-major:
|
||||
variables:
|
||||
RELEASE_TYPE: major
|
||||
<<: *release-template
|
1
.husky/.gitignore
vendored
Normal file
1
.husky/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
_
|
3
.husky/.gitignore.license
Normal file
3
.husky/.gitignore.license
Normal file
|
@ -0,0 +1,3 @@
|
|||
SPDX-FileCopyrightText: 2021 Johannes Loher
|
||||
|
||||
SPDX-License-Identifier: MIT
|
4
.husky/pre-commit
Executable file
4
.husky/pre-commit
Executable file
|
@ -0,0 +1,4 @@
|
|||
#!/bin/sh
|
||||
. "$(dirname "$0")/_/husky.sh"
|
||||
|
||||
yarn run lint-staged
|
3
.husky/pre-commit.license
Normal file
3
.husky/pre-commit.license
Normal file
|
@ -0,0 +1,3 @@
|
|||
SPDX-FileCopyrightText: 2021 Johannes Loher
|
||||
|
||||
SPDX-License-Identifier: MIT
|
1
.nvmrc
Normal file
1
.nvmrc
Normal file
|
@ -0,0 +1 @@
|
|||
lts/*
|
3
.nvmrc.license
Normal file
3
.nvmrc.license
Normal file
|
@ -0,0 +1,3 @@
|
|||
SPDX-FileCopyrightText: 2021 Johannes Loher
|
||||
|
||||
SPDX-License-Identifier: MIT
|
6
.prettierignore
Normal file
6
.prettierignore
Normal file
|
@ -0,0 +1,6 @@
|
|||
# SPDX-FileCopyrightText: 2021 Johannes Loher
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
dist
|
||||
package-lock.json
|
11
.prettierrc.js
Normal file
11
.prettierrc.js
Normal file
|
@ -0,0 +1,11 @@
|
|||
// SPDX-FileCopyrightText: 2021 Johannes Loher
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
module.exports = {
|
||||
semi: true,
|
||||
trailingComma: 'all',
|
||||
singleQuote: true,
|
||||
printWidth: 120,
|
||||
tabWidth: 2,
|
||||
};
|
8
.reuse/dep5
Normal file
8
.reuse/dep5
Normal file
|
@ -0,0 +1,8 @@
|
|||
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
|
||||
Upstream-Name: darkness-dependent-vision
|
||||
Upstream-Contact: Johannes Loher <johannes.loher@fg4f.de>
|
||||
Source: https://git.f3l.de/ghost/darkness-dependent-vision
|
||||
|
||||
Files: .yarn/**
|
||||
Copyright: Copyright (c) 2016-present, Yarn Contributors. All rights reserved.
|
||||
License: BSD-2-Clause
|
77
.yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs
vendored
Normal file
77
.yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs
vendored
Normal file
File diff suppressed because one or more lines are too long
55
.yarn/releases/yarn-2.4.2.cjs
vendored
Executable file
55
.yarn/releases/yarn-2.4.2.cjs
vendored
Executable file
File diff suppressed because one or more lines are too long
9
.yarnrc.yml
Normal file
9
.yarnrc.yml
Normal file
|
@ -0,0 +1,9 @@
|
|||
# SPDX-FileCopyrightText: 2021 Johannes Loher
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
plugins:
|
||||
- path: .yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs
|
||||
spec: "@yarnpkg/plugin-interactive-tools"
|
||||
|
||||
yarnPath: .yarn/releases/yarn-2.4.2.cjs
|
9
LICENSES/BSD-2-Clause.txt
Normal file
9
LICENSES/BSD-2-Clause.txt
Normal file
|
@ -0,0 +1,9 @@
|
|||
Copyright (c) <year> <owner> All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
9
LICENSES/MIT.txt
Normal file
9
LICENSES/MIT.txt
Normal file
|
@ -0,0 +1,9 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) <year> <copyright holders>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
92
README.md
Normal file
92
README.md
Normal file
|
@ -0,0 +1,92 @@
|
|||
<!--
|
||||
SPDX-FileCopyrightText: 2021 Johannes Loher
|
||||
|
||||
SPDX-License-Identifier: MIT
|
||||
-->
|
||||
|
||||
# Darkness Dependent Vision
|
||||
|
||||
A module for [Foundry Virtual Tabletop] that provides the ability to make the
|
||||
dim and bright vision of tokens depend on the scene's darkness level.
|
||||
|
||||
## Installation
|
||||
|
||||
To install and use the Darkness Dependent Vision module for Foundry Virtual
|
||||
Tabletop, simply paste the following URL into the **Install Module** dialog on
|
||||
the Setup menu of the application.
|
||||
|
||||
https://git.f3l.de/ghost/darkness-dependent-vision/-/raw/latest/src/module.json?inline=false
|
||||
|
||||
## Development
|
||||
|
||||
### Prerequisites
|
||||
|
||||
In order to build this module, recent versions of `node` and `yarn` are
|
||||
required. Most likely using `npm` also works but only `yarn` is officially
|
||||
supported. We recommend using the latest lts version of `node`, which is
|
||||
`v14.17.1` at the time of writing. If you use `nvm` to manage your `node`
|
||||
versions, you can simply run
|
||||
|
||||
```
|
||||
nvm install
|
||||
```
|
||||
|
||||
in the project's root directory.
|
||||
|
||||
You also need to install the the project's dependencies. To do so, run
|
||||
|
||||
```
|
||||
yarn install
|
||||
```
|
||||
|
||||
### Building
|
||||
|
||||
You can build the project by running
|
||||
|
||||
```
|
||||
yarn build
|
||||
```
|
||||
|
||||
Alternatively, you can run
|
||||
|
||||
```
|
||||
yarn build:watch
|
||||
```
|
||||
|
||||
to watch for changes and automatically build as necessary.
|
||||
|
||||
### Linking the built project to Foundry VTT
|
||||
|
||||
In order to provide a fluent development experience, it is recommended to link
|
||||
the built module to your local Foundry VTT installation's data folder. In
|
||||
order to do so, first add a file called `foundryconfig.json` to the project root
|
||||
with the following content:
|
||||
|
||||
```
|
||||
{
|
||||
"dataPath": "/absolute/path/to/your/FoundryVTT/Data"
|
||||
}
|
||||
```
|
||||
|
||||
(if you are using Windows, make sure to use `\` as a path separator instead of
|
||||
`/`)
|
||||
|
||||
Then run
|
||||
|
||||
```
|
||||
yarn link-project
|
||||
```
|
||||
|
||||
On Windows, creating symlinks requires administrator privileges so unfortunately
|
||||
you need to run the above command in an administrator terminal for it to work.
|
||||
|
||||
## Licensing
|
||||
|
||||
This project is being developed under the terms of the
|
||||
[LIMITED LICENSE AGREEMENT FOR MODULE DEVELOPMENT] for Foundry Virtual Tabletop.
|
||||
|
||||
This project is licensed under [MIT]. To get more detailed information about the
|
||||
individual copyright holders, check the individual files.
|
||||
|
||||
[Foundry Virtual Tabletop]: http://foundryvtt.com
|
||||
[MIT]: LICENSES/MIT.txt
|
222
gulpfile.js
Normal file
222
gulpfile.js
Normal file
|
@ -0,0 +1,222 @@
|
|||
// SPDX-FileCopyrightText: 2021 Johannes Loher
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
const { rollup } = require('rollup');
|
||||
const argv = require('yargs').argv;
|
||||
const chalk = require('chalk');
|
||||
const fs = require('fs-extra');
|
||||
const gulp = require('gulp');
|
||||
const path = require('path');
|
||||
const rollupConfig = require('./rollup.config');
|
||||
const semver = require('semver');
|
||||
|
||||
/********************/
|
||||
/* CONFIGURATION */
|
||||
/********************/
|
||||
|
||||
const name = path.basename(path.resolve('.'));
|
||||
const sourceDirectory = './src';
|
||||
const distDirectory = './dist';
|
||||
const stylesDirectory = `${sourceDirectory}/styles`;
|
||||
const stylesExtension = 'css';
|
||||
const sourceFileExtension = 'js';
|
||||
const staticFiles = ['assets', 'fonts', 'lang', 'packs', 'templates', 'module.json'];
|
||||
const getDownloadURL = (version) =>
|
||||
`https://git.f3l.de/ghost/darkness-dependent-vision/-/jobs/artifacts/${version}/download?job=build`;
|
||||
|
||||
/********************/
|
||||
/* BUILD */
|
||||
/********************/
|
||||
|
||||
/**
|
||||
* Build the distributable JavaScript code
|
||||
*/
|
||||
async function buildCode() {
|
||||
const build = await rollup({ input: rollupConfig.input, plugins: rollupConfig.plugins });
|
||||
return build.write(rollupConfig.output);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build style sheets
|
||||
*/
|
||||
function buildStyles() {
|
||||
return gulp.src(`${stylesDirectory}/${name}.${stylesExtension}`).pipe(gulp.dest(`${distDirectory}/styles`));
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy static files
|
||||
*/
|
||||
async function copyFiles() {
|
||||
for (const file of staticFiles) {
|
||||
if (fs.existsSync(`${sourceDirectory}/${file}`)) {
|
||||
await fs.copy(`${sourceDirectory}/${file}`, `${distDirectory}/${file}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Watch for changes for each build step
|
||||
*/
|
||||
function buildWatch() {
|
||||
gulp.watch(`${sourceDirectory}/**/*.${sourceFileExtension}`, { ignoreInitial: false }, buildCode);
|
||||
gulp.watch(`${stylesDirectory}/**/*.${stylesExtension}`, { ignoreInitial: false }, buildStyles);
|
||||
gulp.watch(
|
||||
staticFiles.map((file) => `${sourceDirectory}/${file}`),
|
||||
{ ignoreInitial: false },
|
||||
copyFiles,
|
||||
);
|
||||
}
|
||||
|
||||
/********************/
|
||||
/* CLEAN */
|
||||
/********************/
|
||||
|
||||
/**
|
||||
* Remove built files from `dist` folder while ignoring source files
|
||||
*/
|
||||
async function clean() {
|
||||
const files = [...staticFiles, 'module'];
|
||||
|
||||
if (fs.existsSync(`${stylesDirectory}/${name}.${stylesExtension}`)) {
|
||||
files.push('styles');
|
||||
}
|
||||
|
||||
console.log(' ', chalk.yellow('Files to clean:'));
|
||||
console.log(' ', chalk.blueBright(files.join('\n ')));
|
||||
|
||||
for (const filePath of files) {
|
||||
await fs.remove(`${distDirectory}/${filePath}`);
|
||||
}
|
||||
}
|
||||
|
||||
/********************/
|
||||
/* LINK */
|
||||
/********************/
|
||||
|
||||
/**
|
||||
* Get the data path of Foundry VTT based on what is configured in `foundryconfig.json`
|
||||
*/
|
||||
function getDataPath() {
|
||||
const config = fs.readJSONSync('foundryconfig.json');
|
||||
|
||||
if (config?.dataPath) {
|
||||
if (!fs.existsSync(path.resolve(config.dataPath))) {
|
||||
throw new Error('User Data path invalid, no Data directory found');
|
||||
}
|
||||
|
||||
return path.resolve(config.dataPath);
|
||||
} else {
|
||||
throw new Error('No User Data path defined in foundryconfig.json');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Link build to User Data folder
|
||||
*/
|
||||
async function linkUserData() {
|
||||
let destinationDirectory;
|
||||
if (fs.existsSync(path.resolve(sourceDirectory, 'module.json'))) {
|
||||
destinationDirectory = 'modules';
|
||||
} else {
|
||||
throw new Error(`Could not find ${chalk.blueBright('module.json')}`);
|
||||
}
|
||||
|
||||
const linkDirectory = path.resolve(getDataPath(), destinationDirectory, name);
|
||||
|
||||
if (argv.clean || argv.c) {
|
||||
console.log(chalk.yellow(`Removing build in ${chalk.blueBright(linkDirectory)}.`));
|
||||
|
||||
await fs.remove(linkDirectory);
|
||||
} else if (!fs.existsSync(linkDirectory)) {
|
||||
console.log(chalk.green(`Linking dist to ${chalk.blueBright(linkDirectory)}.`));
|
||||
await fs.ensureDir(path.resolve(linkDirectory, '..'));
|
||||
await fs.symlink(path.resolve(distDirectory), linkDirectory);
|
||||
}
|
||||
}
|
||||
|
||||
/********************/
|
||||
/* VERSIONING */
|
||||
/********************/
|
||||
|
||||
/**
|
||||
* Get the contents of the manifest file as object.
|
||||
*/
|
||||
function getManifest() {
|
||||
const manifestPath = `${sourceDirectory}/module.json`;
|
||||
|
||||
if (fs.existsSync(manifestPath)) {
|
||||
return {
|
||||
file: fs.readJSONSync(manifestPath),
|
||||
name: 'module.json',
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the target version based on on the current version and the argument passed as release.
|
||||
*/
|
||||
function getTargetVersion(currentVersion, release) {
|
||||
if (['major', 'premajor', 'minor', 'preminor', 'patch', 'prepatch', 'prerelease'].includes(release)) {
|
||||
return semver.inc(currentVersion, release);
|
||||
} else {
|
||||
return semver.valid(release);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update version and download URL.
|
||||
*/
|
||||
function bumpVersion(cb) {
|
||||
const packageJson = fs.readJSONSync('package.json');
|
||||
const packageLockJson = fs.existsSync('package-lock.json') ? fs.readJSONSync('package-lock.json') : undefined;
|
||||
const manifest = getManifest();
|
||||
|
||||
if (!manifest) cb(Error(chalk.red('Manifest JSON not found')));
|
||||
|
||||
try {
|
||||
const release = argv.release || argv.r;
|
||||
|
||||
const currentVersion = packageJson.version;
|
||||
|
||||
if (!release) {
|
||||
return cb(Error('Missing release type'));
|
||||
}
|
||||
|
||||
const targetVersion = getTargetVersion(currentVersion, release);
|
||||
|
||||
if (!targetVersion) {
|
||||
return cb(new Error(chalk.red('Error: Incorrect version arguments')));
|
||||
}
|
||||
|
||||
if (targetVersion === currentVersion) {
|
||||
return cb(new Error(chalk.red('Error: Target version is identical to current version')));
|
||||
}
|
||||
|
||||
console.log(`Updating version number to '${targetVersion}'`);
|
||||
|
||||
packageJson.version = targetVersion;
|
||||
fs.writeJSONSync('package.json', packageJson, { spaces: 2 });
|
||||
|
||||
if (packageLockJson) {
|
||||
packageLockJson.version = targetVersion;
|
||||
fs.writeJSONSync('package-lock.json', packageLockJson, { spaces: 2 });
|
||||
}
|
||||
|
||||
manifest.file.version = targetVersion;
|
||||
manifest.file.download = getDownloadURL(targetVersion);
|
||||
fs.writeJSONSync(`${sourceDirectory}/${manifest.name}`, manifest.file, { spaces: 2 });
|
||||
|
||||
return cb();
|
||||
} catch (err) {
|
||||
cb(err);
|
||||
}
|
||||
}
|
||||
|
||||
const execBuild = gulp.parallel(buildCode, buildStyles, copyFiles);
|
||||
|
||||
exports.build = gulp.series(clean, execBuild);
|
||||
exports.watch = buildWatch;
|
||||
exports.clean = clean;
|
||||
exports.link = linkUserData;
|
||||
exports.bumpVersion = bumpVersion;
|
10646
package-lock.json
generated
Normal file
10646
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load diff
3
package-lock.json.license
Normal file
3
package-lock.json.license
Normal file
|
@ -0,0 +1,3 @@
|
|||
SPDX-FileCopyrightText: 2021 Johannes Loher
|
||||
|
||||
SPDX-License-Identifier: MIT
|
52
package.json
Normal file
52
package.json
Normal file
|
@ -0,0 +1,52 @@
|
|||
{
|
||||
"private": true,
|
||||
"name": "darkness-dependent-vision",
|
||||
"version": "0.0.1",
|
||||
"description": "A module for Foundry Virtual Tabletop that provides the ability to make the dim and bright vision of tokens depend on the scene's darkness level.",
|
||||
"license": "MIT",
|
||||
"homepage": "https://git.f3l.de/ghost/darkness-dependent-vision",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://git.f3l.de/ghost/darkness-dependent-vision"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://git.f3l.de/ghost/darkness-dependent-vision/-/issues"
|
||||
},
|
||||
"contributors": [
|
||||
{
|
||||
"name": "Johannes Loher",
|
||||
"email": "johannes.loher@fg4f.de"
|
||||
}
|
||||
],
|
||||
"scripts": {
|
||||
"build": "gulp build",
|
||||
"build:watch": "gulp watch",
|
||||
"link-project": "gulp link",
|
||||
"clean": "gulp clean",
|
||||
"clean:link": "gulp link --clean",
|
||||
"bump-version": "gulp bumpVersion",
|
||||
"lint": "eslint --ext .js .",
|
||||
"lint:fix": "eslint --ext .js --fix .",
|
||||
"format": "prettier --write \"./**/*.(js|json|css)\"",
|
||||
"postinstall": "husky install"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@typhonjs-fvtt/eslint-config-foundry.js": "^0.8.0",
|
||||
"chalk": "^4.1.1",
|
||||
"eslint": "^7.29.0",
|
||||
"eslint-config-prettier": "^8.3.0",
|
||||
"eslint-plugin-prettier": "^3.4.0",
|
||||
"fs-extra": "^10.0.0",
|
||||
"gulp": "^4.0.2",
|
||||
"husky": "^6.0.0",
|
||||
"lint-staged": "^11.0.0",
|
||||
"prettier": "^2.3.2",
|
||||
"rollup": "^2.52.3",
|
||||
"semver": "^7.3.5",
|
||||
"yargs": "^17.0.1"
|
||||
},
|
||||
"lint-staged": {
|
||||
"*.(js)": "eslint --fix",
|
||||
"*.(json|css)": "prettier --write"
|
||||
}
|
||||
}
|
3
package.json.license
Normal file
3
package.json.license
Normal file
|
@ -0,0 +1,3 @@
|
|||
SPDX-FileCopyrightText: 2021 Johannes Loher
|
||||
|
||||
SPDX-License-Identifier: MIT
|
12
rollup.config.js
Normal file
12
rollup.config.js
Normal file
|
@ -0,0 +1,12 @@
|
|||
// SPDX-FileCopyrightText: 2021 Johannes Loher
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
module.exports = {
|
||||
input: 'src/module/darkness-dependent-vision.js',
|
||||
output: {
|
||||
dir: 'dist/module',
|
||||
format: 'es',
|
||||
sourcemap: true,
|
||||
},
|
||||
};
|
3
src/lang/en.json
Normal file
3
src/lang/en.json
Normal file
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"DDV.ErrorFailedToOverride": "Failed to override {target}, some things might not work correctly."
|
||||
}
|
3
src/lang/en.json.license
Normal file
3
src/lang/en.json.license
Normal file
|
@ -0,0 +1,3 @@
|
|||
SPDX-FileCopyrightText: 2021 Johannes Loher
|
||||
|
||||
SPDX-License-Identifier: MIT
|
34
src/module.json
Normal file
34
src/module.json
Normal file
|
@ -0,0 +1,34 @@
|
|||
{
|
||||
"name": "darkness-dependent-vision",
|
||||
"title": "Darkness Dependent Vision",
|
||||
"description": "A module for Foundry Virtual Tabletop that provides the ability to make the dim and bright vision of tokens depend on the scene's darkness level.",
|
||||
"version": "0.0.1",
|
||||
"author": "Johannes Loher",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Johannes Loher",
|
||||
"email": "johannes.loher@fg4f.de"
|
||||
}
|
||||
],
|
||||
"minimumCoreVersion": "0.8.8",
|
||||
"compatibleCoreVersion": "0.8.8",
|
||||
"scripts": [],
|
||||
"esmodules": ["module/darkness-dependent-vision.js"],
|
||||
"styles": ["styles/darkness-dependent-vision.css"],
|
||||
"languages": [
|
||||
{
|
||||
"lang": "en",
|
||||
"name": "English",
|
||||
"path": "lang/en.json"
|
||||
}
|
||||
],
|
||||
"socket": false,
|
||||
"url": "https://git.f3l.de/ghost/darkness-dependent-vision",
|
||||
"manifest": "https://git.f3l.de/ghost/darkness-dependent-vision/-/raw/latest/src/module.json?inline=false",
|
||||
"download": "https://git.f3l.de/ghost/darkness-dependent-vision/-/jobs/artifacts/0.0.1/download?job=build",
|
||||
"license": "MIT",
|
||||
"readme": "https://git.f3l.de/ghost/darkness-dependent-vision/-/blob/master/README.md",
|
||||
"bugs": "https://git.f3l.de/ghost/darkness-dependent-vision/-/issues",
|
||||
"changelog": "https://git.f3l.de/ghost/darkness-dependent-vision/-/releases",
|
||||
"library": false
|
||||
}
|
3
src/module.json.license
Normal file
3
src/module.json.license
Normal file
|
@ -0,0 +1,3 @@
|
|||
SPDX-FileCopyrightText: 2021 Johannes Loher
|
||||
|
||||
SPDX-License-Identifier: MIT
|
164
src/module/darkness-dependent-vision.js
Normal file
164
src/module/darkness-dependent-vision.js
Normal file
|
@ -0,0 +1,164 @@
|
|||
// SPDX-FileCopyrightText: 2021 Johannes Loher
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
'use strict';
|
||||
|
||||
import logger from './logger';
|
||||
import { libWrapper } from './shims/libWrapperShim';
|
||||
import notifications from './notifications';
|
||||
|
||||
const packageName = 'darkness-dependent-vision';
|
||||
|
||||
Hooks.once('init', async () => {
|
||||
logger.info(`Initializing ${packageName}`);
|
||||
|
||||
try {
|
||||
libWrapper.register('darkness-dependent-vision', 'Token.prototype.dimRadius', getDimRadius, 'OVERRIDE');
|
||||
} catch (e) {
|
||||
notifications.warn(game.i18n.format('DDV.ErrorFailedToOverride', { target: 'Token.prototype.dimRadius' }), {
|
||||
log: true,
|
||||
});
|
||||
}
|
||||
|
||||
try {
|
||||
libWrapper.register('darkness-dependent-vision', 'Token.prototype.brightRadius', getBrightRadius, 'OVERRIDE');
|
||||
} catch (e) {
|
||||
notifications.warn(game.i18n.format('DDV.ErrorFailedToOverride', { target: 'Token.prototype.brightRadius' }), {
|
||||
log: true,
|
||||
});
|
||||
}
|
||||
|
||||
libWrapper.register('darkness-dependent-vision', 'Token.prototype.updateSource', updateSource, 'WRAPPER');
|
||||
});
|
||||
|
||||
/**
|
||||
* Does this {@link Token} have dim vision, considering the darkness level of
|
||||
* its containing {@link Scene}?
|
||||
*/
|
||||
function hasDimVision() {
|
||||
const dimVisionDarknessLowerBound = this.document.getFlag(packageName, 'dimVisionDarknessLowerBound') ?? -1;
|
||||
const dimVisionDarknessUpperBound = this.document.getFlag(packageName, 'dimVisionDarknessUpperBound') ?? 2;
|
||||
return (
|
||||
this.document.parent.data.darkness >= dimVisionDarknessLowerBound &&
|
||||
this.document.parent.data.darkness < dimVisionDarknessUpperBound
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Does this {@link Token} have bright vision, considering the darkness level of
|
||||
* its containing {@link Scene}?
|
||||
*/
|
||||
function hasBrightVision() {
|
||||
const brightVisionDarknessLowerBound = this.document.getFlag(packageName, 'brightVisionDarknessLowerBound') ?? -1;
|
||||
const brightVisionDarknessUpperBound = this.document.getFlag(packageName, 'brightVisionDarknessUpperBound') ?? 2;
|
||||
return (
|
||||
this.document.parent.data.darkness >= brightVisionDarknessLowerBound &&
|
||||
this.document.parent.data.darkness < brightVisionDarknessUpperBound
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Translate the token's sight distance in units into a radius in pixels.
|
||||
* @return {number} The sight radius in pixels
|
||||
*/
|
||||
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
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {({defer, deleted, noUpdateFog}?: {defer?: boolean, deleted?: boolean, noUpdateFog?: boolean}) => void} UpdateSourceFunction
|
||||
*/
|
||||
|
||||
/**
|
||||
* Update the light and vision source objects associated with this Token
|
||||
* @param {UpdateSourceFunction} wrapped The function that is wrapped by this function and needs to be called next in the chain
|
||||
* @param {boolean} [defer] Defer refreshing the SightLayer to manually call that refresh later.
|
||||
* @param {boolean} [deleted] Indicate that this light source has been deleted.
|
||||
* @param {boolean} [noUpdateFog] Never update the Fog exploration progress for this update.
|
||||
*/
|
||||
function updateSource(wrapped, { defer = false, deleted = false, noUpdateFog = false } = {}) {
|
||||
wrapped({ defer, deleted, noUpdateFog });
|
||||
|
||||
// Prepare some common data
|
||||
const origin = this.getSightOrigin();
|
||||
const sourceId = this.sourceId;
|
||||
const d = canvas.dimensions;
|
||||
|
||||
// Update vision source
|
||||
const isVisionSource = this._isVisionSource();
|
||||
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);
|
||||
if (!defer) {
|
||||
this.vision.drawLight();
|
||||
canvas.sight.refresh({ noUpdateFog });
|
||||
}
|
||||
} else {
|
||||
canvas.sight.sources.delete(sourceId);
|
||||
if (isVisionSource && !defer) canvas.sight.refresh();
|
||||
}
|
||||
}
|
||||
|
||||
Hooks.on('updateScene', (scene, change) => {
|
||||
if (change.darkness != null) {
|
||||
scene.getEmbeddedCollection('Token').forEach((tokenDocument) => tokenDocument.object.updateSource());
|
||||
}
|
||||
});
|
||||
|
||||
Hooks.on('updateToken', (token, change) => {
|
||||
const shouldUpdateSource = [
|
||||
'dimVisionDarknessLowerBound',
|
||||
'dimVisionDarknessUpperBound',
|
||||
'brightVisionDarknessLowerBound',
|
||||
'brightVisionDarknessUpperBound',
|
||||
].some((flagKey) => `flags.darkness-dependent-vision.${flagKey}` in foundry.utils.flattenObject(change));
|
||||
if (shouldUpdateSource) {
|
||||
token.object.updateSource();
|
||||
}
|
||||
});
|
35
src/module/logger.js
Normal file
35
src/module/logger.js
Normal file
|
@ -0,0 +1,35 @@
|
|||
// SPDX-FileCopyrightText: 2021 Johannes Loher
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
'use strict';
|
||||
|
||||
const loggingContext = 'DDV';
|
||||
const loggingSeparator = '|';
|
||||
|
||||
/**
|
||||
* @typedef {'debug' | 'info' | 'warning' | 'error'} LogLevel
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {(...args: unknown[]) => void} LoggingFunction
|
||||
*/
|
||||
|
||||
/**
|
||||
* @param {LogLevel} [type = 'info'] - The log level of the requested logger
|
||||
* @returns {LoggingFunction}
|
||||
*/
|
||||
function getLoggingFunction(type = 'info') {
|
||||
const log = { debug: console.debug, info: console.info, warning: console.warn, error: console.error }[type];
|
||||
return (...data) => log(loggingContext, loggingSeparator, ...data);
|
||||
}
|
||||
|
||||
const logger = Object.freeze({
|
||||
debug: getLoggingFunction('debug'),
|
||||
info: getLoggingFunction('info'),
|
||||
warn: getLoggingFunction('warn'),
|
||||
error: getLoggingFunction('error'),
|
||||
getLoggingFunction,
|
||||
});
|
||||
|
||||
export default logger;
|
46
src/module/notifications.js
Normal file
46
src/module/notifications.js
Normal file
|
@ -0,0 +1,46 @@
|
|||
// SPDX-FileCopyrightText: 2021 Johannes Loher
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
'use strict';
|
||||
|
||||
import logger from './logger';
|
||||
|
||||
const notificationPrefix = 'Darkness Dependent Vision:';
|
||||
|
||||
/**
|
||||
* @typedef {"info" | "warn" | "error"} NotificationType
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {(message: string, {permanent, log}?: {permanent?: boolean, log?: boolean}) => void} NotificationFunction
|
||||
*/
|
||||
|
||||
/**
|
||||
* @param {NotificationType} type The type of the notification function to get
|
||||
* @returns {NotificationFunction} A function that can be called to send a notification to the user
|
||||
*/
|
||||
function getNotificationFunction(type) {
|
||||
return (message, { permanent = false, log = false } = {}) => {
|
||||
ui.notifications[type](`${notificationPrefix} ${message}`, { permanent });
|
||||
if (log) {
|
||||
logger[type](message);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
const notifications = {
|
||||
info: getNotificationFunction('info'),
|
||||
warn: getNotificationFunction('warn'),
|
||||
error: getNotificationFunction('error'),
|
||||
notify: (message, type, { permanent = false, log = false } = {}) => {
|
||||
ui.notifications.notify(`${notificationPrefix} ${message}`, type, { permanent });
|
||||
if (log) {
|
||||
logger.getLoggingFunction(type)(message);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
Object.freeze(notifications);
|
||||
|
||||
export default notifications;
|
138
src/module/shims/libWrapperShim.js
Normal file
138
src/module/shims/libWrapperShim.js
Normal file
|
@ -0,0 +1,138 @@
|
|||
// Copyright © 2021 fvtt-lib-wrapper Rui Pinheiro
|
||||
// 2021 Johannes Loher
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
'use strict';
|
||||
|
||||
// A shim for the libWrapper library
|
||||
export let libWrapper = undefined;
|
||||
|
||||
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 register(package_id, target, fn, type = 'MIXED', { chain = undefined } = {}) {
|
||||
const is_setter = target.endsWith('#set');
|
||||
target = !is_setter ? target : target.slice(0, -4);
|
||||
const split = target.split('.');
|
||||
const fn_name = split.pop();
|
||||
const root_nm = split.splice(0, 1)[0];
|
||||
const _eval = eval; // The browser doesn't expose all global variables (e.g. 'Game') inside globalThis, but it does to an eval. We copy it to a variable to have it run in global scope.
|
||||
const 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 `libWrapper Shim: '${target}' does not exist, could not be found, or has a non-configurable descriptor.`;
|
||||
|
||||
let original = null;
|
||||
const wrapper =
|
||||
chain ?? type != 'OVERRIDE'
|
||||
? function () {
|
||||
return fn.call(this, original.bind(this), ...arguments);
|
||||
}
|
||||
: function () {
|
||||
return fn.apply(this, arguments);
|
||||
};
|
||||
|
||||
if (!is_setter) {
|
||||
if (descriptor.value) {
|
||||
original = descriptor.value;
|
||||
descriptor.value = wrapper;
|
||||
} else {
|
||||
original = descriptor.get;
|
||||
descriptor.get = wrapper;
|
||||
}
|
||||
} else {
|
||||
if (!descriptor.set) throw `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:
|
||||
// Whether to warn GM that the fallback is being used
|
||||
const WARN_FALLBACK = true;
|
||||
|
||||
// Set up the ready hook that shows the "libWrapper not installed" warning dialog
|
||||
if (WARN_FALLBACK) {
|
||||
//************** 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);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
0
src/styles/darkness-dependent-vision.css
Normal file
0
src/styles/darkness-dependent-vision.css
Normal file
3
src/styles/darkness-dependent-vision.css.license
Normal file
3
src/styles/darkness-dependent-vision.css.license
Normal file
|
@ -0,0 +1,3 @@
|
|||
SPDX-FileCopyrightText: 2021 Johannes Loher
|
||||
|
||||
SPDX-License-Identifier: MIT
|
3
yarn.lock.license
Normal file
3
yarn.lock.license
Normal file
|
@ -0,0 +1,3 @@
|
|||
SPDX-FileCopyrightText: 2021 Johannes Loher
|
||||
|
||||
SPDX-License-Identifier: MIT
|
Loading…
Reference in a new issue