diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..28e442a --- /dev/null +++ b/.editorconfig @@ -0,0 +1,11 @@ +root = true + +[*] +indent_style = space +indent_size = 4 +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true +[*.yml] +indent_size = 2 diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000..7807f51 --- /dev/null +++ b/.eslintignore @@ -0,0 +1,18 @@ +gulpfile.js +.eslintrc.js +.prettierrc.js +jsconfig.json +/.pnp.js +/.yarn/ + +.github/ +dist/ +docs/ +external/ +src/languages/ +src/assets/ +src/lang/ +src/scripts/ +src/styles/ +src/templates/ +src/**/*.svelte \ No newline at end of file diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 0000000..40d6cef --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,344 @@ +{ + "env": { + "browser": true, + "es6": true, + "node": true, + "jquery": true + }, + "extends": [ + "eslint:recommended", + "plugin:@typescript-eslint/recommended", + "prettier" + ], + "parser": "@babel/eslint-parser", + "parserOptions": { + "requireConfigFile": false, + "ecmaVersion": 2018, + "sourceType": "module" + }, + "ignorePatterns": [ + "dist/" + ], + "rules": { + "prettier/prettier": "error", + "no-console": "off", + "no-plusplus": [ + "error", + { + "allowForLoopAfterthoughts": true + } + ], + "array-bracket-spacing": ["warn", "never"], + "array-callback-return": "warn", + "arrow-spacing": "warn", + "comma-dangle": ["warn", "always-multiline"], + "comma-style": "warn", + "computed-property-spacing": "warn", + "constructor-super": "error", + "default-param-last": "warn", + "dot-location": ["warn", "property"], + "eol-last": ["error", "always"], + "eqeqeq": "error", + "func-call-spacing": "warn", + "func-names": ["warn", "never"], + "getter-return": "warn", + "lines-between-class-members": "warn", + "new-parens": ["warn", "always"], + "no-alert": "warn", + "no-array-constructor": "warn", + "no-class-assign": "warn", + "no-compare-neg-zero": "warn", + "no-cond-assign": "warn", + "no-const-assign": "error", + "no-constant-condition": "warn", + "no-constructor-return": "warn", + "no-delete-var": "warn", + "no-dupe-args": "warn", + "no-dupe-class-members": "warn", + "no-dupe-keys": "warn", + "no-duplicate-case": "warn", + "no-duplicate-imports": ["warn", {"includeExports": true}], + "no-empty": ["warn", {"allowEmptyCatch": true}], + "no-empty-character-class": "warn", + "no-empty-pattern": "warn", + "no-func-assign": "warn", + "no-global-assign": "warn", + "no-implicit-coercion": ["warn", {"allow": ["!!"]}], + "no-implied-eval": "warn", + "no-import-assign": "warn", + "no-invalid-regexp": "warn", + "no-irregular-whitespace": "warn", + "no-iterator": "warn", + "no-lone-blocks": "warn", + "no-lonely-if": "off", + "no-loop-func": "warn", + "no-misleading-character-class": "warn", + "no-mixed-operators": "warn", + "no-multi-str": "warn", + "no-multiple-empty-lines": "warn", + "no-new-func": "warn", + "no-new-object": "warn", + "no-new-symbol": "warn", + "no-new-wrappers": "warn", + "no-nonoctal-decimal-escape": "warn", + "no-obj-calls": "warn", + "no-octal": "warn", + "no-octal-escape": "warn", + "no-promise-executor-return": "warn", + "no-proto": "warn", + "no-regex-spaces": "warn", + "no-script-url": "warn", + "no-self-assign": "warn", + "no-self-compare": "warn", + "no-setter-return": "warn", + "no-sequences": "warn", + "no-template-curly-in-string": "warn", + "no-this-before-super": "error", + "no-unexpected-multiline": "warn", + "no-unmodified-loop-condition": "warn", + "no-unneeded-ternary": "warn", + "no-unreachable": "warn", + "no-unreachable-loop": "warn", + "no-unsafe-negation": ["warn", {"enforceForOrderingRelations": true}], + "no-unsafe-optional-chaining": ["warn", {"disallowArithmeticOperators": true}], + "no-unused-expressions": [ + "error", + { + "allowShortCircuit": true + } + ], + "no-useless-backreference": "warn", + "no-useless-call": "warn", + "no-useless-catch": "warn", + "no-useless-computed-key": ["warn", {"enforceForClassMembers": true}], + "no-useless-concat": "warn", + "no-useless-constructor": "warn", + "no-useless-rename": "warn", + "no-useless-return": "warn", + "no-var": "warn", + "no-void": "warn", + "no-whitespace-before-property": "warn", + "prefer-numeric-literals": "warn", + "prefer-object-spread": "warn", + "prefer-regex-literals": "warn", + "prefer-spread": "warn", + "rest-spread-spacing": ["warn", "never"], + "semi-spacing": "warn", + "semi-style": ["warn", "last"], + "space-unary-ops": ["warn", {"words": true, "nonwords": false}], + "switch-colon-spacing": "warn", + "symbol-description": "warn", + "template-curly-spacing": ["warn", "never"], + "unicode-bom": ["warn", "never"], + "use-isnan": ["warn", {"enforceForSwitchCase": true, "enforceForIndexOf": true}], + "valid-typeof": ["warn", {"requireStringLiterals": true}], + "wrap-iife": ["warn", "inside"], + + "arrow-parens": ["warn", "as-needed", {"requireForBlockBody": false}], + "capitalized-comments": ["warn", "always", { + "ignoreConsecutiveComments": true, + "ignorePattern": "noinspection" + }], + "comma-spacing": "warn", + "dot-notation": "warn", + "indent": ["warn", 4, {"SwitchCase": 1}], + "key-spacing": "warn", + "keyword-spacing": ["warn", {"overrides": {"catch": {"before": true, "after": false}}}], + "max-len": ["warn", { + "code": 120, + "ignoreTrailingComments": true, + "ignoreUrls": true, + "ignoreStrings": true, + "ignoreTemplateLiterals": true + }], + "no-extra-boolean-cast": ["warn", {"enforceForLogicalOperands": true}], + "no-extra-semi": "warn", + "no-multi-spaces": ["warn", {"ignoreEOLComments": true}], + "no-tabs": "warn", + "no-throw-literal": "error", + "no-trailing-spaces": "warn", + "no-useless-escape": "warn", + "nonblock-statement-body-position": ["warn", "beside"], + "one-var": ["warn", "never"], + "operator-linebreak": ["warn", "before", { + "overrides": {"=": "after", "+=": "after", "-=": "after"} + }], + "prefer-template": "warn", + "quote-props": ["warn", "as-needed", {"keywords": false}], + "quotes": ["warn", "double", {"avoidEscape": true, "allowTemplateLiterals": false}], + "semi": "warn", + "space-before-blocks": ["warn", "always"], + "space-before-function-paren": ["warn", { + "anonymous": "never", + "named": "never", + "asyncArrow": "always" + }], + "spaced-comment": [ + "error", + "always", + { + "markers": [ + "/" + ] + } + ], + "@typescript-eslint/ban-ts-comment": "error", + "@typescript-eslint/ban-types": "off", + "@typescript-eslint/explicit-module-boundary-types": "off", + "@typescript-eslint/lines-between-class-members": [ + "error", + "always", + { + "exceptAfterSingleLine": true + } + ], + "@typescript-eslint/prefer-namespace-keyword": "off", + "@typescript-eslint/no-empty-function": "off", + "@typescript-eslint/no-explicit-any": "error", + "@typescript-eslint/no-namespace": [ + "error", + { + "allowDeclarations": true + } + ], + "@typescript-eslint/no-non-null-assertion": "off", + "@typescript-eslint/no-unsafe-declaration-merging": "off", + "@typescript-eslint/no-unused-vars": "off", + "@typescript-eslint/array-type": [ + "error", + { + "default": "array" + } + ], + "jsdoc/check-access": "warn", + "jsdoc/check-alignment": "warn", + "jsdoc/check-examples": "off", + "jsdoc/check-indentation": "off", + "jsdoc/check-line-alignment": "off", + "jsdoc/check-param-names": "warn", + "jsdoc/check-property-names": "warn", + "jsdoc/check-syntax": "off", + "jsdoc/check-tag-names": ["warn", { "definedTags": ["category"] }], + "jsdoc/check-types": "warn", + "jsdoc/check-values": "warn", + "jsdoc/empty-tags": "warn", + "jsdoc/implements-on-classes": "warn", + "jsdoc/match-description": "off", + "jsdoc/newline-after-description": "off", + "jsdoc/no-bad-blocks": "warn", + "jsdoc/no-defaults": "off", + "jsdoc/no-types": "off", + "jsdoc/no-undefined-types": "off", + "jsdoc/require-description": "warn", + "jsdoc/require-description-complete-sentence": "off", + "jsdoc/require-example": "off", + "jsdoc/require-file-overview": "off", + "jsdoc/require-hyphen-before-param-description": ["warn", "never"], + "jsdoc/require-jsdoc": "warn", + "jsdoc/require-param": "warn", + "jsdoc/require-param-description": "off", + "jsdoc/require-param-name": "warn", + "jsdoc/require-param-type": "warn", + "jsdoc/require-property": "warn", + "jsdoc/require-property-description": "off", + "jsdoc/require-property-name": "warn", + "jsdoc/require-property-type": "warn", + "jsdoc/require-returns": "off", + "jsdoc/require-returns-check": "warn", + "jsdoc/require-returns-description": "off", + "jsdoc/require-returns-type": "warn", + "jsdoc/require-throws": "off", + "jsdoc/require-yields": "warn", + "jsdoc/require-yields-check": "warn", + "jsdoc/valid-types": "off" + }, + "plugins": [ + "jsdoc", + "prettier", + "@typescript-eslint" + ], + "settings": { + "jsdoc": { + "preferredTypes": { + ".<>": "<>", + "object": "Object", + "Object": "object" + }, + "mode": "typescript", + "tagNamePreference": { + "augments": "extends" + } + } + }, + "overrides": [ + { + "files": "tests/**/*", + "rules": { + "global-require": "off" + } + } + ], + "globals": { + "globalThis": true, + "canvas": true, + "Hooks": true, + "game": true, + "Handlebars": true, + "Babele": true, + "foundry": true, + "CONFIG": true, + "libWrapper": true, + "socketlib": true, + "DatabaseBackend": true, + "Actor": true, + "Adventure": true, + "Cards": true, + "ChatMessage": true, + "Combat": true, + "Dice": true, + "FogExploration": true, + "Folder": true, + "Item": true, + "JournalEntry": true, + "Macro": true, + "Playlist": true, + "RollTable": true, + "Scene": true, + "Setting": true, + "User": true, + "Canvas": true, + "canvasTextStyle": true, + "weatherEffects": true, + "controlIcons": true, + "fontDefinitions": true, + "_fontFamilies": true, + "defaultFontFamily": true, + "statusEffects": true, + "specialStatusEffects": true, + "sounds": true, + "supportedLanguages": true, + "i18n": true, + "time": true, + "ActiveEffect": true, + "ActorDelta": true, + "Card": true, + "TableResult": true, + "JournalEntryPage": true, + "PlaylistSound": true, + "AmbientLight": true, + "AmbientSound": true, + "Combatant": true, + "Drawing": true, + "MeasuredTemplate": true, + "Note": true, + "Tile": true, + "Token": true, + "Wall": true, + "TinyMCE": true, + "TextEditor": true, + "WebRTC": true, + "ui": true, + "DND5E": true + } +} + diff --git a/.gitattributes b/.gitattributes index ef35ab7..815a562 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1 +1,7 @@ -tokenmagic/packs/** binary \ No newline at end of file +.github export-ignore +FUNDING.yml export-ignore + +.gitattributes export-ignore +README.md export-ignore +preview.jpg export-ignore +patchnotes.md export-ignore diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index d8ed97e..0cc8d45 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -1,44 +1,44 @@ ---- -name: Bug report -about: Create a report to help us improve -title: "[BUG]" -labels: bug -assignees: '' - ---- - -**Module Version:** v0.0.0 - -**Before open any issue** - -1) Enable the module setting _"Enable debugging"_ -2) Click F12 go to the _console_ tab -3) make the test you want and replicate the error -4) Go to the tab console open on point 2) and just right click and click 'Save as' and 'Save' or send a screenshot of the exception on the console. -5) Attach the text file on the github issue with all the logs related tot he module, or send a screenshot of the messages on the console. - -**Describe the bug** -A clear and concise description of what the bug is. - -**To Reproduce** -Steps to reproduce the behavior: -1. Go to '...' -2. Click on '....' -3. Scroll down to '....' -4. See error - -**Expected behavior** -A clear and concise description of what you expected to happen. - -**Screenshots** -If applicable, add screenshots to help explain your problem. - -**Browser:** - - - -**Foundry Version:** - -**Game System:** - -**Additional context** -Add any other context (like other modules installed) about the problem here. +--- +name: Bug report +about: Create a report to help us improve +title: "[BUG]" +labels: bug +assignees: '' + +--- + +**Module Version:** v0.0.0 + +**Before open any issue** + +1) Enable the module setting _"Enable debugging"_ +2) Click F12 go to the _console_ tab +3) make the test you want and replicate the error +4) Go to the tab console open on point 2) and just right click and click 'Save as' and 'Save' or send a screenshot of the exception on the console. +5) Attach the text file on the github issue with all the logs related tot he module, or send a screenshot of the messages on the console. + +**Describe the bug** +A clear and concise description of what the bug is. + +**To Reproduce** +Steps to reproduce the behavior: +1. Go to '...' +2. Click on '....' +3. Scroll down to '....' +4. See error + +**Expected behavior** +A clear and concise description of what you expected to happen. + +**Screenshots** +If applicable, add screenshots to help explain your problem. + +**Browser:** + - + +**Foundry Version:** + +**Game System:** + +**Additional context** +Add any other context (like other modules installed) about the problem here. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index 809b7b0..017320a 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -1,10 +1,10 @@ ---- -name: Feature request -about: Suggest an idea for this project -title: '' -labels: enhancement -assignees: '' - ---- - - +--- +name: Feature request +about: Suggest an idea for this project +title: '' +labels: enhancement +assignees: '' + +--- + + diff --git a/.github/ISSUE_TEMPLATE/styling.md b/.github/ISSUE_TEMPLATE/styling.md index 914837c..43706ab 100644 --- a/.github/ISSUE_TEMPLATE/styling.md +++ b/.github/ISSUE_TEMPLATE/styling.md @@ -1,10 +1,10 @@ ---- -name: Styling -about: Request a change or bug related to styles -title: '' -labels: styling -assignees: '' - ---- - - +--- +name: Styling +about: Request a change or bug related to styles +title: '' +labels: styling +assignees: '' + +--- + + diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 0000000..5059d99 --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,133 @@ +name: Release Creation + +on: + release: + types: [ published ] + +jobs: + build: + runs-on: ubuntu-latest + permissions: + contents: write + steps: + - uses: actions/checkout@v2 + + # Substitute the Manifest and Download URLs in the module.json + + - name: Substitute Manifest and Download Links For Versioned Ones + id: sub_release_manifest_version + uses: microsoft/variable-substitution@v1 + with: + files: 'src/module.json' + env: + version: ${{github.event.release.tag_name}} + url: https://github.com/${{github.repository}} + manifest: https://github.com/${{github.repository}}/releases/latest/download/module.json + download: https://github.com/${{github.repository}}/releases/download/${{github.event.release.tag_name}}/module.zip + + # for a FULL RELEASE + # - name: Substitute Manifest and Download Links For Versioned Ones + # if: "!github.event.release.prerelease" + # id: sub_release_manifest_version + # uses: microsoft/variable-substitution@v1 + # with: + # files: 'module.json' + # env: + # version: ${{github.event.release.tag_name}} + # url: https://github.com/${{github.repository}} + # manifest: https://github.com/${{github.repository}}/releases/latest/download/module.json + # download: https://github.com/${{github.repository}}/releases/download/${{github.event.release.tag_name}}/module.zip + + # Substitute the Manifest and Download URLs in the module.json + # for a PRE RELEASE. Manifest pointing to live module.json on branch, + # which is updated after tag. + # - name: Substitute Manifest and Download Links For Versioned Ones + # if: "github.event.release.prerelease" + # id: sub_prerelease_manifest_version + # uses: microsoft/variable-substitution@v1 + # with: + # files: 'module.json' + # env: + # version: ${{github.event.release.tag_name}} + # url: https://github.com/${{github.repository}} + # manifest: https://raw.githubusercontent.com/${{github.repository}}/next/module.json + # download: https://github.com/${{github.repository}}/releases/download/${{github.event.release.tag_name}}/module.zip + + # Install packages. + - run: npm install + + # Build distribution. + - run: npm run build + + - run: mkdir package + + - run: mv -v ./dist/* ./package/ + + # Create a zip file with all files required by the module to add to the release + #- run: zip -r ./module.zip module.json LICENSE module.js module.js.map style.css templates/ languages/ packs/ assets/ + # - run: zip -r ./package/module.zip ./package/* + + # && ensures that zip only runs if the directory was correctly changed, + # and the parentheses run everything in a subshell, so the current directory + # is restored at the end. Using OLDPWD avoids having to calculate the relative path to package.zip. + # https://unix.stackexchange.com/questions/385405/zip-all-files-and-subfolder-in-directory-without-parent-directory + - run: (cd package && zip -r "$OLDPWD/module.zip" .) + + - name: Update Release with Files + id: create_version_release + uses: ncipollo/release-action@v1 + with: + allowUpdates: true # Set this to false if you want to prevent updating existing releases + name: ${{ github.event.release.name }} + draft: false + prerelease: false + token: ${{ secrets.GITHUB_TOKEN }} + artifacts: './src/module.json, ./module.zip' + tag: ${{ github.event.release.tag_name }} + body: ${{ github.event.release.body }} + + # Create a release for this specific version + # - name: Update Release with Files + # if: "!github.event.release.prerelease" + # id: create_version_release + # uses: ncipollo/release-action@v1 + # with: + # allowUpdates: true # Set this to false if you want to prevent updating existing releases + # name: ${{ github.event.release.name }} + # draft: false + # prerelease: false + # token: ${{ secrets.GITHUB_TOKEN }} + # artifacts: './module.json, ./module.zip' + # tag: ${{ github.event.release.tag_name }} + # body: ${{ github.event.release.body }} + + # OR create a pre-release for this specific version + # - name: Update Release with Files + # if: "github.event.release.prerelease" + # id: create_version_prerelease + # uses: ncipollo/release-action@v1 + # with: + # allowUpdates: true # Set this to false if you want to prevent updating existing releases + # name: ${{ github.event.release.name }} + # draft: false + # prerelease: true + # token: ${{ secrets.GITHUB_TOKEN }} + # artifacts: './module.json, ./module.zip' + # tag: ${{ github.event.release.tag_name }} + # body: ${{ github.event.release.body }} + + #update next branch + # - name: Prepare repository + # if: "github.event.release.prerelease" + # run: | + # git config --global user.name '${{github.actor}}' + # git config --global user.email '${{github.actor}}@users.noreply.github.com' + # git add module.json + # git stash + # git clean -f + # git remote set-url origin "https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/$GITHUB_REPOSITORY" + # git fetch origin "next" + # git switch -c "next" "origin/next" + # git checkout stash module.json + # git commit -m "${{github.event.release.tag_name}} manifest" + # git push -f diff --git a/.gitignore b/.gitignore index 36b0783..c76b57d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,10 +1,126 @@ -# IDE -.vs/ -.vscode/ -.idea/ -# Module -tokenmagic.zip -tokenmagic/fx/assets/particles/ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +lerna-debug.log* + +# Diagnostic reports (https://nodejs.org/api/report.html) +report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage +*.lcov + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ +jspm_packages/ + +# Snowpack dependency directory (https://snowpack.dev/) +web_modules/ + +# TypeScript cache +*.tsbuildinfo + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Microbundle cache +.rpt2_cache/ +.rts2_cache_cjs/ +.rts2_cache_es/ +.rts2_cache_umd/ + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variables file +.env +.env.test + +# parcel-bundler cache (https://parceljs.org/) +.cache +.parcel-cache + +# Next.js build output +.next +out + +# Nuxt.js build / generate output +.nuxt + +# Gatsby files +.cache/ +# Comment in the public line in if your project uses Gatsby and not Next.js +# https://nextjs.org/blog/next-9-1#public-directory-support +# public + +# vuepress build output +.vuepress/dist + +# Serverless directories +.serverless/ + +# FuseBox cache +.fusebox/ + +# DynamoDB Local files +.dynamodb/ + +# TernJS port file +.tern-port + +# Stores VSCode versions used for testing VSCode extensions +.vscode-test + +# yarn v2 +.yarn/cache +.yarn/unplugged +.yarn/build-state.yml +.yarn/install-state.gz +.pnp.* + +# Foundry foundry.js -dist/* -tokenmagic/packs/* \ No newline at end of file +/dist +/package +/.vite-cache +/package-lock.json +/package-lock.json +/wiki/backups/FoundryVTT-ItemPiles_2024-03-03 + +src/module.zip diff --git a/.husky/.gitignore b/.husky/.gitignore new file mode 100644 index 0000000..31354ec --- /dev/null +++ b/.husky/.gitignore @@ -0,0 +1 @@ +_ diff --git a/.husky/pre-commit b/.husky/pre-commit new file mode 100644 index 0000000..36af219 --- /dev/null +++ b/.husky/pre-commit @@ -0,0 +1,4 @@ +#!/bin/sh +. "$(dirname "$0")/_/husky.sh" + +npx lint-staged diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..befa2ca --- /dev/null +++ b/.prettierignore @@ -0,0 +1,9 @@ +/dist +/package-lock.json +/.pnp.js +/.yarn/ +/.vscode/ +/.idea +.vite-cache/** +**/*.md +/src/packs \ No newline at end of file diff --git a/.prettierrc b/.prettierrc deleted file mode 100644 index 655730a..0000000 --- a/.prettierrc +++ /dev/null @@ -1,5 +0,0 @@ -{ - "printWidth": 120, - "useTabs": true, - "singleQuote": true -} diff --git a/.prettierrc.json b/.prettierrc.json new file mode 100644 index 0000000..60bf782 --- /dev/null +++ b/.prettierrc.json @@ -0,0 +1,40 @@ +{ + "printWidth": 120, + "tabWidth": 4, + "overrides": [ + { + "files": [ + "*.scss", + "*.css" + ], + "options": { + "requirePragma": false, + "parser": "scss" + } + }, + { + "files": [ + "*.yml" + ], + "options": { + "tabWidth": 2 + } + }, + { + "files": "*.html", + "options": { + "requirePragma": false, + "parser": "html", + "htmlWhitespaceSensitivity": "ignore" + } + }, + { + "files": "*.hbs", + "options": { + "requirePragma": false, + "parser": "angular", + "htmlWhitespaceSensitivity": "ignore" + } + } + ] +} diff --git a/CHANGELOG.md b/CHANGELOG.md index aac3969..af6d82f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,13 +1,3 @@ -# Token Magic FX - Update v0.6.5.0 - -- Source files have been bundled to reduce number of requests -- New filter added under `TokenMagic Portfolio` - - `45 - Star Mask (spriteMask)` - - Uses the provided image's alpha component to mask the target -- New GUI added under `TokenMagic Portfolio - - `00 - D - TMFX GUI - Toggle Presets` - - Allows searching for and toggling of presets on currently selected placeables - # Token Magic FX - Update v0.6.4.1 - fixed v11 compatibility warnings diff --git a/README.md b/README.md index 41ddc3b..81969eb 100644 --- a/README.md +++ b/README.md @@ -1,17 +1,20 @@ -![Latest Release Download Count](https://img.shields.io/github/downloads/Feu-Secret/tokenmagic/latest/tokenmagic.zip?color=2b82fc&label=DOWNLOADS&style=for-the-badge) -[![Forge Installs](https://img.shields.io/badge/dynamic/json?label=Forge%20Installs&query=package.installs&suffix=%25&url=https%3A%2F%2Fforge-vtt.com%2Fapi%2Fbazaar%2Fpackage%2Ftokenmagic&colorB=006400&style=for-the-badge)](https://forge-vtt.com/bazaar#package=tokenmagic) +![Latest Release Download Count](https://img.shields.io/github/downloads/Feu-Secret/tokenmagic/latest/tokenmagic.zip?color=2b82fc&label=DOWNLOADS&style=for-the-badge) +[![Forge Installs](https://img.shields.io/badge/dynamic/json?label=Forge%20Installs&query=package.installs&suffix=%25&url=https%3A%2F%2Fforge-vtt.com%2Fapi%2Fbazaar%2Fpackage%2Ftokenmagic&colorB=006400&style=for-the-badge)](https://forge-vtt.com/bazaar#package=tokenmagic) ![Foundry Core Compatible Version](https://img.shields.io/badge/dynamic/json.svg?url=https%3A%2F%2Fraw.githubusercontent.com%2Fp4535992%2Ftokenmagic%2Fmaster%2Ftokenmagic%2Fmodule.json&label=Foundry%20Version&query=$.compatibility.verified&colorB=orange&style=for-the-badge) ![Latest Version](https://img.shields.io/badge/dynamic/json.svg?url=https%3A%2F%2Fraw.githubusercontent.com%2FFeu-Secret%2Ftokenmagic%2Fmaster%2Ftokenmagic%2Fmodule.json&label=Latest%20Release&prefix=v&query=$.version&colorB=red&style=for-the-badge) [![Foundry Hub Endorsements](https://img.shields.io/endpoint?logoColor=white&url=https%3A%2F%2Fwww.foundryvtt-hub.com%2Fwp-json%2Fhubapi%2Fv1%2Fpackage%2Ftokenmagic%2Fshield%2Fendorsements&style=for-the-badge)](https://www.foundryvtt-hub.com/package/tokenmagic/) ![GitHub all releases](https://img.shields.io/github/downloads/Feu-Secret/tokenmagic/total?style=for-the-badge) -*If you want to support more modules of this kind, I invite you to go and support the original author to [ko-fi](https://ko-fi.com/K3K24XAWE) , or with [paypal](https://www.paypal.me/silentFire "Paypal")* +## If you want to support more modules of this kind, I invite you to go and support the original author [![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/K3K24XAWE) , or [my paypal](https://www.paypal.me/silentFire "Paypal") + +## or these contributors: + +- **[Aedif](https://github.com/Aedif/):** [![alt-text](https://img.shields.io/badge/-Patreon-%23ff424d?style=for-the-badge)](https://patreon.com/Aedif) -[![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/K3K24XAWE) # Token Magic FX -Token Magic is a module for Foundry VTT that allows you to add graphic effects to tokens, tiles, drawings and templates. These FX can be animated. +Token Magic is a module for Foundry VTT that allows you to add graphic effects to tokens, tiles, drawings and templates. These FX can be animated. This beta version is partly used via macros, except for automatic templates and measurement templates. A graphical interface will be added later. But do not panic, Token Magic comes with a compendium of macros for each effect, easily modifiable to suit your needs. I advise you to go there and play with the values. @@ -63,19 +66,19 @@ Token Magic is adding four options : - A Token Magic effect (you can create your own by adding presets in the template library) - And a tint applied to texture and special effect -![Templates Ex](images/templates-ex.png) +![Templates Ex](wiki/images/templates-ex.png) ### Automatic Templates You can configure automatic templates in the module option panel. You also have options to disable automatic templates and the display of the grid. -![Template Settings](images/template-settings.png) +![Template Settings](wiki/images/template-settings.png) In the template settings, you have a tab that display to automatic templates settings by categories, and another for spells and items overrides. -![Template Settings Base](images/template-settings-base.png) +![Template Settings Base](wiki/images/template-settings-base.png) -![Template Settings Overrides](images/template-settings-overrides.png) +![Template Settings Overrides](wiki/images/template-settings-overrides.png) Automatic template settings are linked to a world. You can import and export the settings with the following code : @@ -155,7 +158,7 @@ Each filter is identified by a `filterId`, you can specify it. Otherwise, a rand `Padding` is a property applicable to all filters. It allows you to increase the size of the container so that the effects do not spill over an invisible part. Padding is applied on all sides. In the module option, you can decide to use the default additive padding (three filters with a padding of 40 would make a padding of 120), use a maximum padding (one filter with a padding of 10 and a filter with a padding of 20 give a padding of 20). You can also assign a minimum padding value that will be assigned each time you create an effect. You want to apply filters to all selected tokens or tiles in the UI ? Use : -`TokenMagic.addFiltersOnSelected()` +`TokenMagic.addFiltersOnSelected()` You want to apply the filters to a placeable passed in parameter (token, tile, drawing, template) ? Use : `TokenMagic.addFilters(, )` @@ -192,12 +195,12 @@ let params = padding: 10, animated: { - color: + color: { - active: true, - loopDuration: 3000, - animType: "colorOscillation", - val1:0x003000, + active: true, + loopDuration: 3000, + animType: "colorOscillation", + val1:0x003000, val2:0x00FF00 } } @@ -212,9 +215,9 @@ let params = outerStrength: 6, animated: { - color: + color: { - val1:0x300030, + val1:0x300030, val2:0xFF3000 } } @@ -296,7 +299,7 @@ TokenMagic.hasFilterId(,) ... if (TokenMagic.hasFilterId(myToken,"mySuperShadow_01")) { console.log("myToken has my customized super shadow 1 filter."); -} +} ... ``` Here are one in two functions, to add or update filter(s) on a specific placeable, selected tokens, drawings or tiles, or targeted tokens. If a filter applied on an object has a filterType and a filterId identical to those found in the parameters, the values are updated with the new ones. Otherwise a new filter is created. @@ -310,7 +313,7 @@ You can automatically destroy or disable filters with the following properties : - `autoDisable` : When this property is set to `true` the filter is automatically disabled when each animation become inactive (number of loops reached). - `autoDestroy` : The same as autoDisable, but the filter is destroyed. - Note : if you set `loops` with `Infinity` (default value if the property is not present), you will never trigger the autoDestroy or autoDisable. But you can prepare your filter with an auto keyword and then, later, update the `loops` properties with finite values to start the countdown. - + ```javascript // autoDestroy example let params = @@ -322,12 +325,12 @@ let params = padding: 10, animated: { - color: + color: { - active: true, + active: true, loopDuration: 3000, loops: 5, - animType: "colorOscillation", + animType: "colorOscillation", val1:0x003000, val2:0x00FF00 } @@ -352,7 +355,7 @@ animated : wantInteger: // used for random generation speed: // used with « move » animType chaosFactor: // used to create chaos - syncShift: // used to alter synchronicity + syncShift: // used to alter synchronicity } <,…> } @@ -378,8 +381,8 @@ The same as cosOscillation, but with a chaos factor. The oscillation is freaky. **Keywords:** `"colorOscillation"` `"syncColorOscillation"` **Mandatory properties:** `active` `loopDuration` `val1` `val2` **Optional properties:** `loops` `syncShift` -Same as cosOscillation or syncCosOscillation, but specific to colors. -The transition is correctly applied to each component of the RGB value. +Same as cosOscillation or syncCosOscillation, but specific to colors. +The transition is correctly applied to each component of the RGB value. Instead, you can use a cosOscillation, but the transition is not very nice (for colors). **Keywords:** `"halfCosOscillation"` @@ -406,12 +409,12 @@ generate a random number per frame, between val1 and val2. You need Integers? Us **Keywords:** `"randomNumberPerLoop"` **Mandatory properties:** `active` `loopDuration` `val1` `val2` -**Optional properties:** `wantInteger` `loops` +**Optional properties:** `wantInteger` `loops` generate a random number at the end of a complete loop, between val1 and val2. You need Integers? Use `wantInteger: true` **Keywords:** `"randomColorPerLoop"` **Mandatory properties:** `active` `loopDuration` -**Optional properties:** `loops` +**Optional properties:** `loops` generate a random color per complete loop. **Keywords:** `"move"` @@ -476,51 +479,51 @@ randomized : You can control the ordering of the filters with the `zOrder` property. If you want to work with this new property, you must activate the option in the module option panel. The `zOrder` allows the filters to be applied on a Placeable in a specific order: from the smallest `zOrder` to the highest. -A concrete example: you have applied an aura to a token, then you apply a mirror image, the aura will also be processed by the mirror image, which is probably not the desired effect. +A concrete example: you have applied an aura to a token, then you apply a mirror image, the aura will also be processed by the mirror image, which is probably not the desired effect. By assigning a `zOrder` to your effects, you can determine that the mirror image should apply before the aura. You will find below a table with the filters and their default `zOrder`. The default `zOrder` can be overriden in the parameters of the filters. | Filter | default zOrder | Image | |---|---|--------------------------------------------------------------------------------------------------| -| Splash (splash) | 5 | | -| Remove Shadow (zapshadow) | 10 | | -| Pixelate (pixel) | 20 | | -| Adjustment (adjustment) | 30 | | -| Bloom (xbloom) | 40 | | -| Outline (outline) | 50 | | -| Old Film (oldfilm) | 60 | | -| Glow (glow) | 70 | | -| Gleaming Glow (xglow) | 80 | | -| Bevel (bevel) | 90 | | -| Mirror Images (images) | 100 | | -| Drop Shadow (shadow) | 110 | | -| Rays (ray) | 120 | | -| XRays (xray) | 130 | | -| BulgePinch (bulgepinch) | 140 | | -| Fire (fire) | 150 | | -| Electric (electric) | 160 | | -| Flood (flood) | 170 | | -| Liquid (liquid) | 180 | | -| Fog (fog) | 190 | | -| Smoke (smoke) | 200 | | -| Fumes (fumes) | 210 | | -| Shockwave (shockwave) | 220 | | -| XFog (xfog) | 230 | | -| Twist (twist) | 240 | | -| Solar Ripples (ripples) | 250 | | -| Spiderweb (web) | 260 | | -| Globes (globes) | 270 | | -| Waves (wave) | 280 | | -| Blur (blur) | 290 | | -| Zoom Blur (zoomblur) | 300 | | -| Ascii (ascii) | 310 | | -| Dot Shade (dot) | 320 | | -| CRT Monitor (crt) | 330 | | -| RGB Split (rgbSplit) | 340 | | -| Transform (transform) | 1000 | | -| Force Field (field) | 2000 | | -| Distortion (distortion) | 4000 | | +| Splash (splash) | 5 | | +| Remove Shadow (zapshadow) | 10 | | +| Pixelate (pixel) | 20 | | +| Adjustment (adjustment) | 30 | | +| Bloom (xbloom) | 40 | | +| Outline (outline) | 50 | | +| Old Film (oldfilm) | 60 | | +| Glow (glow) | 70 | | +| Gleaming Glow (xglow) | 80 | | +| Bevel (bevel) | 90 | | +| Mirror Images (images) | 100 | | +| Drop Shadow (shadow) | 110 | | +| Rays (ray) | 120 | | +| XRays (xray) | 130 | | +| BulgePinch (bulgepinch) | 140 | | +| Fire (fire) | 150 | | +| Electric (electric) | 160 | | +| Flood (flood) | 170 | | +| Liquid (liquid) | 180 | | +| Fog (fog) | 190 | | +| Smoke (smoke) | 200 | | +| Fumes (fumes) | 210 | | +| Shockwave (shockwave) | 220 | | +| XFog (xfog) | 230 | | +| Twist (twist) | 240 | | +| Solar Ripples (ripples) | 250 | | +| Spiderweb (web) | 260 | | +| Globes (globes) | 270 | | +| Waves (wave) | 280 | | +| Blur (blur) | 290 | | +| Zoom Blur (zoomblur) | 300 | | +| Ascii (ascii) | 310 | | +| Dot Shade (dot) | 320 | | +| CRT Monitor (crt) | 330 | | +| RGB Split (rgbSplit) | 340 | | +| Transform (transform) | 1000 | | +| Force Field (field) | 2000 | | +| Distortion (distortion) | 4000 | | You can store your custom effects in a Token Magic library. TMFX comes with two libraries: A main library with all the presets common to drawings, tokens and tiles, and one specific to measured templates. @@ -741,7 +744,7 @@ You have access to TMFX specific prototype functions in class PlaceableObject (T .TMFXhasFilterType() .TMFXhasFilterId() -// Example 1 +// Example 1 let glowFunc = async function() { const tokens = canvas.tokens.placeables; @@ -765,6 +768,89 @@ let glowFunc = async function() { glowFunc(); ``` +## Api + +TODO + +# Build + +## Install all packages + +```bash +npm install +``` + +### dev + +`dev` will let you develop you own code with hot reloading on the browser + +```bash +npm run dev +``` + +### build + +`build` will build and set up a symlink between `dist` and your `dataPath`. + +```bash +npm run build +``` + +### build:watch + +`build:watch` will build and watch for changes, rebuilding automatically. + +```bash +npm run build:watch +``` + +### prettier-format + +`prettier-format` launch the prettier plugin based on the configuration [here](./.prettierrc) + +```bash +npm run-script prettier-format +``` + +### lint + +`lint` launch the eslint process based on the configuration [here](./.eslintrc.json) + +```bash +npm run-script lint +``` + +### lint:fix + +`lint:fix` launch the eslint process with the fix argument + +```bash +npm run-script lint:fix +``` + +### build:json + +`build:json` unpack LevelDB pack on `src/packs` to the json db sources in `src/packs/_source`very useful for backup your items and manually fix some hard issue with some text editor + +```bash +npm run-script build:json +``` + +### build:clean + +`build:clean` clean packs json sources in `src/packs/_source`. NOTE: usually this command is launched after the command `build:json` and after make some modifications on the json source files with some text editor, but before the `build:db` + +```bash +npm run-script build:clean +``` + +### build:db + +`build:db` packs the json db sources in `src/packs/_source` to LevelDB pack on `src/packs` with the new jsons. NOTE: usually this command is launched after the command `build:json` and after make some modifications on the json source files with some text editor + +```bash +npm run-script build:db +``` ## Issues @@ -774,11 +860,11 @@ Any issues, bugs, or feature requests are always welcome to be reported directly If you want to use TokenMagic in your modules, know that you are welcome. I await your feedback and I will listen to your needs. ### Contributions -Contributors are welcome: UI specialists and GLSL shader programmers would be appreciated, and anyone wishing to get involved in this project. +Contributors are welcome: UI specialists and GLSL shader programmers would be appreciated, and anyone wishing to get involved in this project. Contact me on Github or Discord, or make a Super Surprise PR! ### Important notes -TokenMagic is in beta version, this means that bugs and other unwanted effects will occur from time to time. +TokenMagic is in beta version, this means that bugs and other unwanted effects will occur from time to time. You can help me to track them by posting issues in Github and taking care to give me all the information I need to reproduce them. Thank you ! ### Acknowledgements @@ -790,7 +876,7 @@ You can help me to track them by posting issues in Github and taking care to giv - **JosephSeraph** for the [art](https://opengameart.org/content/js-actor-witch) used in the macro images (edited under [CC license](https://creativecommons.org/licenses/by/3.0/)) - **Lozalojo, zimm44, drdwing, zeteticl** for providing translations for the community. - **The whole community** for its kindness. -- **The Forgotten**, sorry for forgetting about you, you don't deserve it! +- **The Forgotten**, sorry for forgetting about you, you don't deserve it! ### An advice *The wise man knows how to `await`.* @@ -804,4 +890,3 @@ My most sincere thanks. *Discord : SecretFire#4843* - diff --git a/package.json b/package.json index 89d9e12..be79801 100644 --- a/package.json +++ b/package.json @@ -1,20 +1,78 @@ { "name": "tokenmagic", - "version": "1.0.0", + "title": "Token Magic FX", + "description": "

Add special effects and animations on your tokens, tiles, drawings and templates.

", + "version": "0.6.4.1", + "main": "module.js", + "license": "SEE LICENSE IN LICENSE", "private": true, "type": "module", - "source:": "tokenmagic/module/tokenmagic.js", - "main": "tokenmagic/module/tokenmagicBundle.js", - "targets": { - "main": { - "optimize": true - } + "author": "", + "contributors": [], + "imports": { + "#runtime/*": "@typhonjs-fvtt/runtime/*", + "#standard/*": "@typhonjs-fvtt/svelte-standard/*" + }, + "dependencies": { + "@fortawesome/fontawesome-svg-core": "^6.5.1", + "@fortawesome/free-solid-svg-icons": "^6.5.1", + "@fortawesome/react-fontawesome": "^0.2.0", + "@rollup/plugin-node-resolve": "^15.2.3", + "@typhonjs-fvtt/runtime": "^0.1.2", + "@typhonjs-fvtt/svelte-standard": "^0.1.0", + "moment": "^2.30.1", + "svelte": "^4.2.12", + "svelte-select": "^5.8.3", + "svelte-virtual-scroll-list": "^1.3.0" }, "devDependencies": { - "parcel": "latest" + "@babel/eslint-parser": "^7.23.10", + "@foundryvtt/foundryvtt-cli": "^1.0.2", + "@rollup/plugin-node-resolve": "^15.2.3", + "@typescript-eslint/eslint-plugin": "^7.1.1", + "@typhonjs-config/eslint-config": "^0.6.3", + "@typhonjs-fvtt/eslint-config-foundry.js": "^0.8.0", + "eslint": "^8.57.0", + "eslint-config-prettier": "^9.1.0", + "eslint-plugin-jsdoc": "^46.10.1", + "eslint-plugin-prettier": "^5.1.3", + "fancy-log": "^2.0.0", + "husky": "^8.0.3", + "jquery": "^3.7.1", + "jsdoc": "^4.0.2", + "less": "^4.2.0", + "less-watch-compiler": "^1.16.3", + "lint-staged": "^13.3.0", + "prettier": "^3.2.5", + "rollup": "^3.29.4", + "sass": "^1.71.1", + "svelte-dnd-action": "^0.9.40", + "svelte-preprocess": "^5.1.3", + "vite": "^4.5.3", + "vite-plugin-clean": "^1.0.0", + "vite-plugin-run": "^0.5.1", + "vite-plugin-static-copy": "^0.17.0", + "yargs": "^17.7.2" }, + "browserslist": [ + ">5%", + "not IE 11" + ], "scripts": { - "build": "npx parcel build tokenmagic/module/tokenmagic.js", - "watch": "npx parcel watch tokenmagic/module/tokenmagic.js" + "build": "node ./utils/clean.mjs && vite build", + "build:watch": "node ./utils/clean.mjs && vite build --watch --mode development", + "build:watchWithDb": "node ./utils/clean.mjs && npm run build:db && vite build --watch --mode development", + "dev": "vite serve", + "build:clean": "node ./utils/packs.mjs package clean", + "build:db": "node ./utils/packs.mjs package pack", + "build:json": "node ./utils/packs.mjs package unpack", + "eslint": "eslint .", + "prepare": "husky install", + "prettier-format": "prettier --config .prettierrc.json --write \"./src/**/*.{js,mjs,json,scss,css}\"", + "lint": "eslint --ext .js ./src", + "lint:fix": "eslint --ext .js ./src --fix" + }, + "lint-staged": { + "*.{js,css}": "prettier --write" } } diff --git a/src/fx/Anime.js b/src/fx/Anime.js new file mode 100644 index 0000000..80e926d --- /dev/null +++ b/src/fx/Anime.js @@ -0,0 +1,560 @@ +import { isAnimationDisabled } from "../module.js"; + +export class Anime { + constructor(puppet) { + const self = this; + this.puppet = puppet; + this.animated = null; + this.animeId = randomID(); + + // Time/synchronization related variables + this.frameTime = {}; + this.elapsedTime = {}; + this.loopElapsedTime = {}; + this.loops = {}; + this.internalLoops = {}; + this.ping = {}; + this.pauseBetweenElapsedTime = {}; + this.pauseBetween = {}; + this.shutdown = {}; + + if (!(this.puppet == null)) { + if ( + this.puppet.hasOwnProperty("animated") && + !(this.puppet.animated == null) && + typeof this.puppet.animated === "object" && + Object.keys(this.puppet.animated).length > 0 + ) { + this.initAnimatedInternals(this.puppet.animated); + this.animated = this.puppet.animated; // easy access to the puppet's animodes + } + Anime.addAnimation(self); // ready to tick + } + } + + static rgbToValue(r, g, b) { + return (r << 16) | (g << 8) | b; + } + + static valueToRgb(bin) { + const r = bin >> 16; + const g = (bin >> 8) & 0xff; + const b = bin & 0xff; + return [r, g, b]; + } + + static oscillation(elapsed, loopDuration, syncShift, val1, val2, func, isSync, xpi = Anime.twoPi) { + return ( + ((val1 - val2) * + (func( + xpi * (isSync ? Anime.getSynchronizedTime(loopDuration, syncShift) : elapsed / loopDuration + syncShift) + ) + + 1)) / + 2 + + val2 + ); + } + + static colOscillation(elapsed, loopDuration, syncShift, val1, val2, isSync, xpi = Anime.twoPi) { + const rgbValue1 = Anime.valueToRgb(val1); + const rgbValue2 = Anime.valueToRgb(val2); + + return Anime.rgbToValue( + Math.floor( + Anime.oscillation(elapsed, loopDuration, syncShift, rgbValue1[0], rgbValue2[0], Math.cos, isSync, xpi) + ), + Math.floor( + Anime.oscillation(elapsed, loopDuration, syncShift, rgbValue1[1], rgbValue2[1], Math.cos, isSync, xpi) + ), + Math.floor(Anime.oscillation(elapsed, loopDuration, syncShift, rgbValue1[2], rgbValue2[2], Math.cos, isSync, xpi)) + ); + } + + static getSynchronizedTime(loopDuration, syncShift) { + return Anime._lastTime / loopDuration + syncShift; + } + + static getSynchronizedRotation(loopDuration, syncShift) { + return (360 * ((Anime._lastTime + syncShift) % loopDuration)) / loopDuration; + } + + static getPuppetsByParams(params) { + let puppetArray = []; + Anime._animeMap.forEach((anime, id) => { + if ( + anime.puppet.placeableId === params.placeableId && + anime.puppet.filterId === params.filterId && + (!anime.puppet.hasOwnProperty("filterInternalId") || anime.puppet.filterInternalId === params.filterInternalId) + ) { + puppetArray.push(anime.puppet); + } + }); + return puppetArray; + } + + static addAnimation(anime) { + Anime._animeMap.set(anime.animeId, anime); + Anime._resumeAnimation(); + } + + static removeAnimation(placeableId) { + Anime._animeMap.forEach((anime, id) => { + if (anime.puppet.placeableId === placeableId) { + Anime._animeMap.delete(id); + } + }); + if (Anime._animeMap.size === 0) { + Anime._suspendAnimation(); + } + } + + static removeAnimationByFilterId(placeableId, filterId) { + Anime._animeMap.forEach((anime, id) => { + if (anime.puppet.placeableId === placeableId && anime.puppet.filterId === filterId) { + Anime._animeMap.delete(id); + } + }); + if (Anime._animeMap.size === 0) { + Anime._suspendAnimation(); + } + } + + static resetAnimation() { + Anime._animeMap = new Map(); + Anime._suspended = true; + } + + static tick() { + Anime._lastTime = canvas.app.ticker.lastTime; + Anime._frameTime = Anime._lastTime - Anime._prevTime; + + for (const [id, anime] of Anime._animeMap) { + if (anime.puppet.enabled) { + if (anime.puppet.hasOwnProperty("preComputation") && anime.puppet.placeableImg != null) { + anime.puppet.preComputation(); + } + if (anime.puppet.hasOwnProperty("animated") && !(anime.puppet.animated == null)) { + anime.animate(Anime._frameTime); + } + } + } + + Anime._prevTime = Anime._lastTime; + } + + static _suspendAnimation() { + if (Anime._activated && !Anime._suspended && !isAnimationDisabled()) { + Anime._detachFromTicker(); + } + Anime._suspended = true; + } + + static _resumeAnimation() { + if (Anime._activated && Anime._suspended && !isAnimationDisabled()) { + Anime._attachToTicker(); + } + Anime._suspended = false; + } + + static activateAnimation() { + if (!Anime._activated && !Anime._suspended && !isAnimationDisabled()) { + Anime._attachToTicker(); + } + Anime._activated = true; + } + + static deactivateAnimation() { + if (Anime._activated && !Anime._suspended && !isAnimationDisabled()) { + Anime._detachFromTicker(); + } + Anime._activated = false; + } + + static _attachToTicker() { + canvas.app.ticker.add(Anime.tick, this, PIXI.UPDATE_PRIORITY.LOW + 1); + Anime._lastTime = canvas.app.ticker.lastTime; + Anime._prevTime = Anime._lastTime; + } + + static _detachFromTicker() { + canvas.app.ticker.remove(Anime.tick, this); + Anime._lastTime = 0; + Anime._prevTime = 0; + } + + static getAnimeMap() { + return Anime._animeMap; + } + + initAnimatedInternals(animated) { + Object.keys(animated).forEach((effect) => { + // Internals init + this.initInternals(effect); + }); + } + + initInternals(effect) { + this.elapsedTime[effect] = 0; + this.loopElapsedTime[effect] = 0; + this.pauseBetweenElapsedTime[effect] = 0; + this.loops[effect] = 0; + this.internalLoops[effect] = 0; + this.frameTime[effect] = 0; + this.pauseBetween[effect] = false; + this.ping[effect] = false; + this.shutdown[effect] = false; + } + + hasInternals(effect) { + return this.elapsedTime.hasOwnProperty(effect); + } + + animate(frameTime) { + for (const effect of Object.keys(this.puppet.animated)) { + if (this.animated[effect].active && this.cycleCheck(effect, frameTime)) { + if (this[this.animated[effect].animType] != null) { + this[this.animated[effect].animType](effect); + } + if (this.shutdown[effect]) { + this.animated[effect].active = false; + this.shutdown[effect] = false; + + // persists the value of an effect which is terminated. + this.persistTerminatedEffect(effect); + } else { + this.loopElapsedTime[effect] += frameTime; + this.elapsedTime[effect] += frameTime; + } + } + } + this.autoDisableCheck(); + } + + cycleCheck(effect, frameTime) { + this.frameTime[effect] = frameTime; + + if (this.isPauseBetweenLoop(effect, frameTime)) { + return false; + } + + if (this.loopElapsedTime[effect] > this.animated[effect].loopDuration) { + this.loopElapsedTime[effect] -= this.animated[effect].loopDuration; + this.ping[effect] = true; + + if (this.animated[effect].loops !== Infinity) { + this.loops[effect]++; + this.internalLoops[effect]++; + } + + if (this.loops[effect] >= this.animated[effect].loops) { + // correction to stop exactly on the target value when the last loop end. + this.elapsedTime[effect] = this.internalLoops[effect] * this.animated[effect].loopDuration; + this.loops[effect] = 0; + this.loopElapsedTime[effect] = 0; + this.shutdown[effect] = true; + } else if (this.animated[effect].pauseBetweenDuration > 0) { + this.elapsedTime[effect] = this.animated[effect].loopDuration; + this.pauseBetween[effect] = true; + } + } + return true; + } + + async persistTerminatedEffect(effect) { + if (!(this.puppet.filterOwner === game.data.userId)) { + return; + } + + let animeInfo; + let doInit = true; + let flag = this.puppet.targetPlaceable.document.getFlag("tokenmagic", "animeInfo"); + + if (flag) { + // fastest than array.find + for (const animeinfo of flag.values()) { + if ( + animeinfo.tmFilterId === this.puppet.filterId && + animeinfo.tmFilterInternalId === this.puppet.filterInternalId && + animeinfo.tmFilterEffect === effect + ) { + if (animeinfo && animeinfo instanceof Object) { + animeinfo.tmFilterEffectValue = this.puppet[effect]; + doInit = false; + break; + } + } + } + } + + if (doInit) { + animeInfo = [ + { + tmFilterId: this.puppet.filterId, + tmFilterInternalId: this.puppet.filterInternalId, + tmFilterEffect: effect, + tmFilterEffectValue: this.puppet[effect], + }, + ]; + + if (flag) flag = flag.concat(animeInfo); + else flag = animeInfo; + } + + flag = duplicate(flag); + await this.puppet.targetPlaceable._TMFXsetAnimeFlag(flag); + } + + autoDisableCheck() { + if (!(this.puppet.autoDisable || this.puppet.autoDestroy)) { + return; + } + if (!(this.puppet.filterOwner === game.data.userId)) { + return; + } + if (this.puppet.enabled === false && !this.puppet.autoDestroy) { + return; + } + + if (Object.values(this.animated).every((animeEffect) => animeEffect.active === false)) { + this.disableOrDestroy(); + } + } + + async disableOrDestroy() { + if (this.puppet == null) return; + const placeable = this.puppet.targetPlaceable; + if (placeable == null) return; + + if (this.puppet.autoDestroy) { + await window.TokenMagic.deleteFilters(placeable, this.puppet.filterId); + } else { + let params = {}; + params.filterType = this.puppet.filterType; + params.filterId = this.puppet.filterId; + params.enabled = false; + await window.TokenMagic.updateFiltersByPlaceable(placeable, [params]); + } + } + + isPauseBetweenLoop(effect, frametime) { + if (this.pauseBetween[effect] && this.animated[effect].pauseBetweenDuration > 0) { + this.pauseBetweenElapsedTime[effect] += frametime; + if (this.pauseBetweenElapsedTime[effect] < this.animated[effect].pauseBetweenDuration) { + return true; + } else { + this.pauseBetweenElapsedTime[effect] = 0; + return (this.pauseBetween[effect] = false); + } + } + return false; + } + + pauseBetweenCheck(effect, frametime) { + if (this.pauseStart[effect] && this.animated[effect].pauseStartDuration > 0) { + this.pauseStartElapsedTime[effect] += frametime; + if (this.pauseStartElapsedTime[effect] < this.animated[effect].pauseStartDuration) { + return false; + } else { + this.pauseStart[effect] = false; + return true; + } + } + } + + moveToward(effect) { + this.puppet[effect] = + ((this.animated[effect].val1 - this.animated[effect].val2) / this.animated[effect].loopDuration) * + this.elapsedTime[effect]; + } + + colorOscillation(effect) { + this.puppet[effect] = Anime.colOscillation( + this.elapsedTime[effect], + this.animated[effect].loopDuration, + this.animated[effect].syncShift, + this.animated[effect].val1, + this.animated[effect].val2, + false + ); + } + + halfColorOscillation(effect) { + this.puppet[effect] = Anime.colOscillation( + this.elapsedTime[effect], + this.animated[effect].loopDuration, + this.animated[effect].syncShift, + this.animated[effect].val1, + this.animated[effect].val2, + false, + Math.PI + ); + } + + syncColorOscillation(effect) { + this.puppet[effect] = Anime.colOscillation( + this.elapsedTime[effect], + this.animated[effect].loopDuration, + this.animated[effect].syncShift, + this.animated[effect].val1, + this.animated[effect].val2, + true + ); + } + + cosOscillation(effect) { + this.puppet[effect] = Anime.oscillation( + this.elapsedTime[effect], + this.animated[effect].loopDuration, + this.animated[effect].syncShift, + this.animated[effect].val1, + this.animated[effect].val2, + Math.cos, + false + ); + } + + halfCosOscillation(effect) { + this.puppet[effect] = Anime.oscillation( + this.elapsedTime[effect], + this.animated[effect].loopDuration, + this.animated[effect].syncShift, + this.animated[effect].val1, + this.animated[effect].val2, + Math.cos, + false, + Math.PI + ); + } + + sinOscillation(effect) { + this.puppet[effect] = Anime.oscillation( + this.elapsedTime[effect], + this.animated[effect].loopDuration, + this.animated[effect].syncShift, + this.animated[effect].val1, + this.animated[effect].val2, + Math.sin, + false + ); + } + + halfSinOscillation(effect) { + this.puppet[effect] = Anime.oscillation( + this.elapsedTime[effect], + this.animated[effect].loopDuration, + this.animated[effect].syncShift, + this.animated[effect].val1, + this.animated[effect].val2, + Math.sin, + false, + Math.PI + ); + } + + chaoticOscillation(effect) { + this.puppet[effect] = Anime.oscillation( + this.elapsedTime[effect], + this.animated[effect].loopDuration, + this.animated[effect].syncShift + Math.random() * this.animated[effect].chaosFactor, + this.animated[effect].val1, + this.animated[effect].val2, + Math.cos, + false + ); + } + + syncCosOscillation(effect) { + this.puppet[effect] = Anime.oscillation( + this.elapsedTime[effect], + this.animated[effect].loopDuration, + this.animated[effect].syncShift, + this.animated[effect].val1, + this.animated[effect].val2, + Math.cos, + true + ); + } + + syncSinOscillation(effect) { + this.puppet[effect] = Anime.oscillation( + this.elapsedTime[effect], + this.animated[effect].loopDuration, + this.animated[effect].syncShift, + this.animated[effect].val1, + this.animated[effect].val2, + Math.sin, + true + ); + } + + syncChaoticOscillation(effect) { + this.puppet[effect] = Anime.oscillation( + this.elapsedTime[effect], + this.animated[effect].loopDuration, + this.animated[effect].syncShift + Math.random() * this.animated[effect].chaosFactor, + this.animated[effect].val1, + this.animated[effect].val2, + Math.cos, + true + ); + } + + rotation(effect) { + const computedRotation = (360 * this.elapsedTime[effect]) / this.animated[effect].loopDuration; + this.puppet[effect] = this.animated[effect].clockWise ? computedRotation : 360 - computedRotation; + } + + syncRotation(effect) { + const computedRotation = Anime.getSynchronizedRotation( + this.animated[effect].loopDuration, + this.animated[effect].syncShift + ); + this.puppet[effect] = this.animated[effect].clockWise ? computedRotation : 360 - computedRotation; + } + + randomNumber(effect) { + const randomNumber = + Math.random() * (this.animated[effect].val2 - this.animated[effect].val1) + this.animated[effect].val1; + if (this.animated[effect].wantInteger) { + this.puppet[effect] = Math.floor(randomNumber); + } else { + this.puppet[effect] = randomNumber; + } + } + + randomNumberPerLoop(effect) { + if (this._ringing(effect)) { + this.randomNumber(effect); + } + } + + randomColor(effect) { + this.puppet[effect] = Math.floor(Math.random() * 16777215); + } + + randomColorPerLoop(effect) { + if (this._ringing(effect)) { + this.randomColor(effect); + } + } + + move(effect) { + this.puppet[effect] += this.animated[effect].speed * this.frameTime[effect]; + } + + _ringing(effect) { + if (this.ping[effect]) { + this.ping[effect] = false; + return true; + } + return false; + } +} + +Anime._lastTime = 0; +Anime._prevTime = 0; +Anime._frameTime = 0; +Anime._animeMap = new Map(); +Anime.twoPi = Math.PI * 2; +Anime._activated = false; +Anime._suspended = true; diff --git a/tokenmagic/fx/assets/box.webp b/src/fx/assets/box.webp similarity index 100% rename from tokenmagic/fx/assets/box.webp rename to src/fx/assets/box.webp diff --git a/tokenmagic/fx/assets/distortion-1.png b/src/fx/assets/distortion-1.png similarity index 100% rename from tokenmagic/fx/assets/distortion-1.png rename to src/fx/assets/distortion-1.png diff --git a/tokenmagic/fx/assets/dots-1.png b/src/fx/assets/dots-1.png similarity index 100% rename from tokenmagic/fx/assets/dots-1.png rename to src/fx/assets/dots-1.png diff --git a/tokenmagic/fx/assets/extrusion-1.png b/src/fx/assets/extrusion-1.png similarity index 100% rename from tokenmagic/fx/assets/extrusion-1.png rename to src/fx/assets/extrusion-1.png diff --git a/tokenmagic/fx/assets/gem-1.png b/src/fx/assets/gem-1.png similarity index 100% rename from tokenmagic/fx/assets/gem-1.png rename to src/fx/assets/gem-1.png diff --git a/tokenmagic/fx/assets/gem-2.png b/src/fx/assets/gem-2.png similarity index 100% rename from tokenmagic/fx/assets/gem-2.png rename to src/fx/assets/gem-2.png diff --git a/tokenmagic/fx/assets/hexa-1.png b/src/fx/assets/hexa-1.png similarity index 100% rename from tokenmagic/fx/assets/hexa-1.png rename to src/fx/assets/hexa-1.png diff --git a/tokenmagic/fx/assets/noise-1.png b/src/fx/assets/noise-1.png similarity index 100% rename from tokenmagic/fx/assets/noise-1.png rename to src/fx/assets/noise-1.png diff --git a/tokenmagic/fx/assets/noise-2.jpg b/src/fx/assets/noise-2.jpg similarity index 100% rename from tokenmagic/fx/assets/noise-2.jpg rename to src/fx/assets/noise-2.jpg diff --git a/tokenmagic/fx/assets/noise-3.jpg b/src/fx/assets/noise-3.jpg similarity index 100% rename from tokenmagic/fx/assets/noise-3.jpg rename to src/fx/assets/noise-3.jpg diff --git a/tokenmagic/fx/assets/noise.jpg b/src/fx/assets/noise.jpg similarity index 100% rename from tokenmagic/fx/assets/noise.jpg rename to src/fx/assets/noise.jpg diff --git a/tokenmagic/fx/assets/noise.png b/src/fx/assets/noise.png similarity index 100% rename from tokenmagic/fx/assets/noise.png rename to src/fx/assets/noise.png diff --git a/tokenmagic/fx/assets/pentagram.png b/src/fx/assets/pentagram.png similarity index 100% rename from tokenmagic/fx/assets/pentagram.png rename to src/fx/assets/pentagram.png diff --git a/tokenmagic/fx/assets/star.webp b/src/fx/assets/star.webp similarity index 100% rename from tokenmagic/fx/assets/star.webp rename to src/fx/assets/star.webp diff --git a/tokenmagic/fx/assets/symbols-1.png b/src/fx/assets/symbols-1.png similarity index 100% rename from tokenmagic/fx/assets/symbols-1.png rename to src/fx/assets/symbols-1.png diff --git a/tokenmagic/fx/assets/templates/black-tone-pure.png b/src/fx/assets/templates/black-tone-pure.png similarity index 100% rename from tokenmagic/fx/assets/templates/black-tone-pure.png rename to src/fx/assets/templates/black-tone-pure.png diff --git a/tokenmagic/fx/assets/templates/black-tone-strong-opacity.png b/src/fx/assets/templates/black-tone-strong-opacity.png similarity index 100% rename from tokenmagic/fx/assets/templates/black-tone-strong-opacity.png rename to src/fx/assets/templates/black-tone-strong-opacity.png diff --git a/tokenmagic/fx/assets/templates/black-tone-vstrong-opacity.png b/src/fx/assets/templates/black-tone-vstrong-opacity.png similarity index 100% rename from tokenmagic/fx/assets/templates/black-tone-vstrong-opacity.png rename to src/fx/assets/templates/black-tone-vstrong-opacity.png diff --git a/tokenmagic/fx/assets/templates/white-tone-strong-opacity.png b/src/fx/assets/templates/white-tone-strong-opacity.png similarity index 100% rename from tokenmagic/fx/assets/templates/white-tone-strong-opacity.png rename to src/fx/assets/templates/white-tone-strong-opacity.png diff --git a/tokenmagic/fx/assets/videos/IounStoneGreaterAbsorption.webm b/src/fx/assets/videos/IounStoneGreaterAbsorption.webm similarity index 100% rename from tokenmagic/fx/assets/videos/IounStoneGreaterAbsorption.webm rename to src/fx/assets/videos/IounStoneGreaterAbsorption.webm diff --git a/tokenmagic/fx/assets/waves-1.png b/src/fx/assets/waves-1.png similarity index 100% rename from tokenmagic/fx/assets/waves-1.png rename to src/fx/assets/waves-1.png diff --git a/tokenmagic/fx/assets/waves-2.png b/src/fx/assets/waves-2.png similarity index 100% rename from tokenmagic/fx/assets/waves-2.png rename to src/fx/assets/waves-2.png diff --git a/tokenmagic/fx/assets/waves-3.png b/src/fx/assets/waves-3.png similarity index 100% rename from tokenmagic/fx/assets/waves-3.png rename to src/fx/assets/waves-3.png diff --git a/src/fx/filters/CustomFilter.js b/src/fx/filters/CustomFilter.js new file mode 100644 index 0000000..3c62ac7 --- /dev/null +++ b/src/fx/filters/CustomFilter.js @@ -0,0 +1,73 @@ +const _tempRect = new PIXI.Rectangle(); + +export class CustomFilter extends PIXI.Filter { + constructor(...args) { + super(...args); + + if (!this.uniforms.filterMatrix || !this.uniforms.filterMatrixInverse) + this.uniforms.filterMatrix = new PIXI.Matrix(); + + if (!this.uniforms.filterMatrixInverse) this.uniforms.filterMatrixInverse = new PIXI.Matrix(); + } + + apply(filterManager, input, output, clear) { + const filterMatrix = this.uniforms.filterMatrix; + + if (filterMatrix) { + const { sourceFrame, destinationFrame, target } = filterManager.activeState; + + filterMatrix.set(destinationFrame.width, 0, 0, destinationFrame.height, sourceFrame.x, sourceFrame.y); + + const worldTransform = PIXI.Matrix.TEMP_MATRIX; + + const localBounds = target.getLocalBounds(_tempRect); + + if (this.sticky) { + worldTransform.copyFrom(target.transform.worldTransform); + worldTransform.invert(); + + const rotation = target.transform.rotation; + const sin = Math.sin(rotation); + const cos = Math.cos(rotation); + const scaleX = Math.hypot( + cos * worldTransform.a + sin * worldTransform.c, + cos * worldTransform.b + sin * worldTransform.d + ); + const scaleY = Math.hypot( + -sin * worldTransform.a + cos * worldTransform.c, + -sin * worldTransform.b + cos * worldTransform.d + ); + + localBounds.pad(scaleX * this.boundsPadding.x, scaleY * this.boundsPadding.y); + } else { + const transform = target.transform; + worldTransform.a = transform.scale.x; + worldTransform.b = 0; + worldTransform.c = 0; + worldTransform.d = transform.scale.y; + worldTransform.tx = transform.position.x - transform.pivot.x * transform.scale.x; + worldTransform.ty = transform.position.y - transform.pivot.y * transform.scale.y; + worldTransform.prepend(target.parent.transform.worldTransform); + worldTransform.invert(); + + const scaleX = Math.hypot(worldTransform.a, worldTransform.b); + const scaleY = Math.hypot(worldTransform.c, worldTransform.d); + + localBounds.pad(scaleX * this.boundsPadding.x, scaleY * this.boundsPadding.y); + } + + filterMatrix.prepend(worldTransform); + filterMatrix.translate(-localBounds.x, -localBounds.y); + filterMatrix.scale(1.0 / localBounds.width, 1.0 / localBounds.height); + + const filterMatrixInverse = this.uniforms.filterMatrixInverse; + + if (filterMatrixInverse) { + filterMatrixInverse.copyFrom(filterMatrix); + filterMatrixInverse.invert(); + } + } + + filterManager.applyFilter(this, input, output, clear); + } +} diff --git a/src/fx/filters/FilterAdjustment.js b/src/fx/filters/FilterAdjustment.js new file mode 100644 index 0000000..c443256 --- /dev/null +++ b/src/fx/filters/FilterAdjustment.js @@ -0,0 +1,24 @@ +import { Anime } from "../Anime.js"; +import "./proto/FilterProto.js"; + +export class FilterAdjustment extends PIXI.filters.AdjustmentFilter { + constructor(params) { + super(); + this.enabled = false; + this.gamma = 1; + this.saturation = 1; + this.contrast = 1; + this.brightness = 1; + this.red = 1; + this.green = 1; + this.blue = 1; + this.alpha = 1; + this.zOrder = 30; + this.animating = {}; + this.setTMParams(params); + if (!this.dummy) { + this.anime = new Anime(this); + this.normalizeTMParams(); + } + } +} diff --git a/src/fx/filters/FilterAdvancedBloom.js b/src/fx/filters/FilterAdvancedBloom.js new file mode 100644 index 0000000..276f54b --- /dev/null +++ b/src/fx/filters/FilterAdvancedBloom.js @@ -0,0 +1,23 @@ +import { Anime } from "../Anime.js"; +import "./proto/FilterProto.js"; + +export class FilterXBloom extends PIXI.filters.AdvancedBloomFilter { + constructor(params) { + super(); + + this.enabled = false; + this.threshold = 0.5; + this.bloomScale = 1.0; + this.brightness = 1.0; + this.blur = 4.0; + this.quality = 4.0; + this.zOrder = 40; + + this.animated = {}; + this.setTMParams(params); + if (!this.dummy) { + this.anime = new Anime(this); + this.normalizeTMParams(); + } + } +} diff --git a/src/fx/filters/FilterAscii.js b/src/fx/filters/FilterAscii.js new file mode 100644 index 0000000..ce94905 --- /dev/null +++ b/src/fx/filters/FilterAscii.js @@ -0,0 +1,16 @@ +import { Anime } from "../Anime.js"; +import "./proto/FilterProto.js"; + +export class FilterAscii extends PIXI.filters.AsciiFilter { + constructor(params) { + super(); + this.size = 8; + this.zOrder = 310; + this.animated = {}; + this.setTMParams(params); + if (!this.dummy) { + this.anime = new Anime(this); + this.normalizeTMParams(); + } + } +} diff --git a/src/fx/filters/FilterBevel.js b/src/fx/filters/FilterBevel.js new file mode 100644 index 0000000..39b1897 --- /dev/null +++ b/src/fx/filters/FilterBevel.js @@ -0,0 +1,25 @@ +import { Anime } from "../Anime.js"; +import "./proto/FilterProto.js"; + +export class FilterBevel extends PIXI.filters.BevelFilter { + constructor(params) { + super(); + this.blendMode = PIXI.BLEND_MODES.NORMAL; + this.padding = 10; + this.enabled = false; + this.rotation = 0; + this.thickness = 5; + this.lightColor = 0xffffff; + this.lightAlpha = 0.95; + this.shadowColor = 0x000000; + this.shadowAlpha = 0.95; + this.zOrder = 90; + this.quality = 1; + this.animated = {}; + this.setTMParams(params); + if (!this.dummy) { + this.anime = new Anime(this); + this.normalizeTMParams(); + } + } +} diff --git a/src/fx/filters/FilterBlur.js b/src/fx/filters/FilterBlur.js new file mode 100644 index 0000000..2f63ffb --- /dev/null +++ b/src/fx/filters/FilterBlur.js @@ -0,0 +1,52 @@ +import { Anime } from "../Anime.js"; +import "./proto/FilterProto.js"; +import { FilterBlurEx } from "./FilterBlurEx.js"; + +export class FilterBlur extends FilterBlurEx { + constructor(params) { + super(); + this.enabled = false; + this.blur = 2; + this.quality = 4; + this.zOrder = 290; + this.repeatEdgePixels = false; + this.animated = {}; + this.setTMParams(params); + if (!this.dummy) { + this.anime = new Anime(this); + this.normalizeTMParams(); + } + } + + get blur() { + return this.strengthX; + } + + set blur(value) { + this.strengthX = this.strengthY = value; + } + + get blurX() { + return this.strengthX; + } + + set blurX(value) { + this.strengthX = value; + } + + get blurY() { + return this.strengthY; + } + + set blurY(value) { + this.strengthY = value; + } + + calculatePadding() { + const scale = this.targetPlaceable.worldTransform.a; + this.blurXFilter.blur = scale * this.strengthX; + this.blurYFilter.blur = scale * this.strengthY; + this.updatePadding(); + super.calculatePadding(); + } +} diff --git a/src/fx/filters/FilterBlurEx.js b/src/fx/filters/FilterBlurEx.js new file mode 100644 index 0000000..03414a6 --- /dev/null +++ b/src/fx/filters/FilterBlurEx.js @@ -0,0 +1,311 @@ +import { CustomFilter } from "./CustomFilter.js"; + +export class FilterBlurEx extends CustomFilter { + blurXFilter; + blurYFilter; + + _repeatEdgePixels; + + constructor(strength = 8, quality = 4, resolution = PIXI.settings.FILTER_RESOLUTION, kernelSize = 5) { + super(); + + this.blurXFilter = new BlurFilterPassEx(true, strength, quality, resolution, kernelSize); + this.blurYFilter = new BlurFilterPassEx(false, strength, quality, resolution, kernelSize); + + this.resolution = resolution; + this.quality = quality; + this.blur = strength; + + this.repeatEdgePixels = false; + } + + apply(filterManager, input, output, clearMode) { + const xStrength = Math.abs(this.blurXFilter.strength); + const yStrength = Math.abs(this.blurYFilter.strength); + + if (xStrength && yStrength) { + const renderTarget = filterManager.getFilterTexture(); + + this.blurXFilter.apply(filterManager, input, renderTarget, PIXI.CLEAR_MODES.CLEAR); + this.blurYFilter.apply(filterManager, renderTarget, output, clearMode); + + filterManager.returnFilterTexture(renderTarget); + } else if (yStrength) { + this.blurYFilter.apply(filterManager, input, output, clearMode); + } else { + this.blurXFilter.apply(filterManager, input, output, clearMode); + } + } + + updatePadding() { + if (this._repeatEdgePixels) { + this.padding = 0; + } else { + this.padding = Math.max(Math.abs(this.blurXFilter.strength), Math.abs(this.blurYFilter.strength)) * 2; + } + } + + get blur() { + return this.blurXFilter.blur; + } + + set blur(value) { + this.blurXFilter.blur = this.blurYFilter.blur = value; + this.updatePadding(); + } + + get quality() { + return this.blurXFilter.quality; + } + + set quality(value) { + this.blurXFilter.quality = this.blurYFilter.quality = value; + } + + get blurX() { + return this.blurXFilter.blur; + } + + set blurX(value) { + this.blurXFilter.blur = value; + this.updatePadding(); + } + + get blurY() { + return this.blurYFilter.blur; + } + + set blurY(value) { + this.blurYFilter.blur = value; + this.updatePadding(); + } + + get blendMode() { + return this.blurYFilter.blendMode; + } + + set blendMode(value) { + this.blurYFilter.blendMode = value; + } + + get repeatEdgePixels() { + return this._repeatEdgePixels; + } + + set repeatEdgePixels(value) { + this._repeatEdgePixels = value; + this.updatePadding(); + } +} + +export class BlurFilterPassEx extends CustomFilter { + horizontal; + strength; + passes; + _quality; + + constructor(horizontal, strength = 8, quality = 4, resolution = PIXI.settings.FILTER_RESOLUTION, kernelSize = 5) { + const vertSrc = generateBlurVertSource(kernelSize, horizontal); + const fragSrc = generateBlurFragSource(kernelSize); + + super( + // vertex shader + vertSrc, + // fragment shader + fragSrc + ); + + this.horizontal = horizontal; + + this.resolution = resolution; + + this._quality = 0; + + this.quality = quality; + + this.blur = strength; + } + + apply(filterManager, input, output, clearMode) { + if (output) { + if (this.horizontal) { + this.uniforms.strength = (1 / output.width) * (output.width / input.width); + } else { + this.uniforms.strength = (1 / output.height) * (output.height / input.height); + } + } else { + if (this.horizontal) { + this.uniforms.strength = (1 / filterManager.renderer.width) * (filterManager.renderer.width / input.width); + } else { + this.uniforms.strength = (1 / filterManager.renderer.height) * (filterManager.renderer.height / input.height); + } + } + + // screen space! + this.uniforms.strength *= this.strength; + this.uniforms.strength /= this.passes; + + if (this.passes === 1) { + filterManager.applyFilter(this, input, output, clearMode); + } else { + const renderTarget = filterManager.getFilterTexture(); + const renderer = filterManager.renderer; + + let flip = input; + let flop = renderTarget; + + this.state.blend = false; + filterManager.applyFilter(this, flip, flop, PIXI.CLEAR_MODES.CLEAR); + + for (let i = 1; i < this.passes - 1; i++) { + filterManager.bindAndClear(flip, PIXI.CLEAR_MODES.BLIT); + + this.uniforms.uSampler = flop; + + const temp = flop; + + flop = flip; + flip = temp; + + renderer.shader.bind(this); + renderer.geometry.draw(5); + } + + this.state.blend = true; + filterManager.applyFilter(this, flop, output, clearMode); + filterManager.returnFilterTexture(renderTarget); + } + } + + get blur() { + return this.strength; + } + + set blur(value) { + this.padding = 1 + Math.abs(value) * 2; + this.strength = value; + } + + get quality() { + return this._quality; + } + + set quality(value) { + this._quality = value; + this.passes = value; + } +} + +const GAUSSIAN_VALUES = { + 5: [0.153388, 0.221461, 0.250301], + 7: [0.071303, 0.131514, 0.189879, 0.214607], + 9: [0.028532, 0.067234, 0.124009, 0.179044, 0.20236], + 11: [0.0093, 0.028002, 0.065984, 0.121703, 0.175713, 0.198596], + 13: [0.002406, 0.009255, 0.027867, 0.065666, 0.121117, 0.174868, 0.197641], + 15: [0.000489, 0.002403, 0.009246, 0.02784, 0.065602, 0.120999, 0.174697, 0.197448], +}; + +const fragTemplate = [ + "varying vec2 vBlurTexCoords[%size%];", + "uniform sampler2D uSampler;", + + "void main(void)", + "{", + " gl_FragColor = vec4(0.0);", + " %blur%", + "}", +].join("\n"); + +export function generateBlurFragSource(kernelSize) { + const kernel = GAUSSIAN_VALUES[kernelSize]; + const halfLength = kernel.length; + + let fragSource = fragTemplate; + + let blurLoop = ""; + const template = "gl_FragColor += texture2D(uSampler, vBlurTexCoords[%index%]) * %value%;"; + let value; + + for (let i = 0; i < kernelSize; i++) { + let blur = template.replace("%index%", i.toString()); + + value = i; + + if (i >= halfLength) { + value = kernelSize - i - 1; + } + + blur = blur.replace("%value%", kernel[value].toString()); + + blurLoop += blur; + blurLoop += "\n"; + } + + fragSource = fragSource.replace("%blur%", blurLoop); + fragSource = fragSource.replace("%size%", kernelSize.toString()); + + return fragSource; +} + +const vertTemplate = ` + attribute vec2 aVertexPosition; + uniform mat3 projectionMatrix; + uniform float strength; + varying vec2 vBlurTexCoords[%size%]; + uniform vec4 inputSize; + uniform vec4 outputFrame; + vec4 filterVertexPosition( void ) + { + vec2 position = aVertexPosition * max(outputFrame.zw, vec2(0.)) + outputFrame.xy; + return vec4((projectionMatrix * vec3(position, 1.0)).xy, 0.0, 1.0); + } + vec2 filterTextureCoord( void ) + { + return aVertexPosition * (outputFrame.zw * inputSize.zw); + } + void main(void) + { + gl_Position = filterVertexPosition(); + vec2 textureCoord = filterTextureCoord(); + %blur% + }`; + +export function generateBlurVertSource(kernelSize, x) { + const halfLength = Math.ceil(kernelSize / 2); + + let vertSource = vertTemplate; + + let blurLoop = ""; + let template; + + if (x) { + template = "vBlurTexCoords[%index%] = textureCoord + vec2(%sampleIndex% * strength, 0.0);"; + } else { + template = "vBlurTexCoords[%index%] = textureCoord + vec2(0.0, %sampleIndex% * strength);"; + } + + for (let i = 0; i < kernelSize; i++) { + let blur = template.replace("%index%", i.toString()); + + blur = blur.replace("%sampleIndex%", `${i - (halfLength - 1)}.0`); + + blurLoop += blur; + blurLoop += "\n"; + } + + vertSource = vertSource.replace("%blur%", blurLoop); + vertSource = vertSource.replace("%size%", kernelSize.toString()); + + return vertSource; +} + +export function getMaxKernelSize(gl) { + const maxVaryings = PIXI.gl.getParameter(PIXI.gl.MAX_VARYING_VECTORS); + let kernelSize = 15; + + while (kernelSize > maxVaryings) { + kernelSize -= 2; + } + + return kernelSize; +} diff --git a/src/fx/filters/FilterBulgePinch.js b/src/fx/filters/FilterBulgePinch.js new file mode 100644 index 0000000..09f90aa --- /dev/null +++ b/src/fx/filters/FilterBulgePinch.js @@ -0,0 +1,31 @@ +import { Anime } from "../Anime.js"; +import "./proto/FilterProto.js"; + +export class FilterBulgePinch extends PIXI.filters.BulgePinchFilter { + constructor(params) { + super(); + + this.strength = 0; + this.radiusPercent = 100; + this.zOrder = 140; + this.autoFit = false; + + this.animated = {}; + this.setTMParams(params); + if (!this.dummy) { + this.anime = new Anime(this); + this.normalizeTMParams(); + } + + // Anchor point + this.center = [0.5, 0.5]; + } + + handleTransform() { + this.radius = + (Math.max(this.placeableImg.width, this.placeableImg.height) * + this.targetPlaceable.worldTransform.a * + this.radiusPercent) / + 200; + } +} diff --git a/src/fx/filters/FilterCRT.js b/src/fx/filters/FilterCRT.js new file mode 100644 index 0000000..2e81ad2 --- /dev/null +++ b/src/fx/filters/FilterCRT.js @@ -0,0 +1,23 @@ +import { Anime } from "../Anime.js"; +import "./proto/FilterProto.js"; + +export class FilterCRT extends PIXI.filters.CRTFilter { + constructor(params) { + super(); + this.curvature = 1.0; + this.lineWidth = 1.0; + this.lineContrast = 0.25; + this.verticalLine = false; + this.noise = 0.08; + this.noiseSize = 1.0; + this.seed = 0; + this.vignetting = 0; + this.zOrder = 320; + this.animated = {}; + this.setTMParams(params); + if (!this.dummy) { + this.anime = new Anime(this); + this.normalizeTMParams(); + } + } +} diff --git a/src/fx/filters/FilterDDTint.js b/src/fx/filters/FilterDDTint.js new file mode 100644 index 0000000..cdd39ea --- /dev/null +++ b/src/fx/filters/FilterDDTint.js @@ -0,0 +1,27 @@ +import { customVertex2D } from "../glsl/vertexshaders/customvertex2D.js"; +import { CustomFilter } from "./CustomFilter.js"; +import { Anime } from "../Anime.js"; +import "./proto/FilterProto.js"; +import { ddTint } from "../glsl/fragmentshaders/ddtint.js"; + +export class FilterDDTint extends CustomFilter { + constructor(params) { + super(customVertex2D, ddTint); + this.tint = [1, 0, 0]; + this.zOrder = 100; + this.animating = {}; + this.setTMParams(params); + if (!this.dummy) { + this.anime = new Anime(this); + this.normalizeTMParams(); + } + } + + get tint() { + return this.uniforms.tint; + } + + set tint(value) { + this.uniforms.tint = value; + } +} diff --git a/src/fx/filters/FilterDistortion.js b/src/fx/filters/FilterDistortion.js new file mode 100644 index 0000000..b09d212 --- /dev/null +++ b/src/fx/filters/FilterDistortion.js @@ -0,0 +1,146 @@ +import { Anime } from "../Anime.js"; +import "./proto/FilterProto.js"; +import { fixPath } from "../../module.js"; + +export class FilterDistortion extends PIXI.filters.DisplacementFilter { + constructor(params) { + // Loading distortion sprite + var displacementSpriteMask; + var spriteMaskPath; + spriteMaskPath = params.hasOwnProperty("maskPath") + ? fixPath(params.maskPath) + : "modules/tokenmagic/fx/assets/distortion-1.png"; + displacementSpriteMask = PIXI.Sprite.from(spriteMaskPath); + super(displacementSpriteMask); + + // Configuring distortion sprite + this.sprite = displacementSpriteMask; + this.wrapMode = PIXI.WRAP_MODES.REPEAT; + this.position = new PIXI.Point(); + this.skew = new PIXI.Point(); + this.pivot = new PIXI.Point(); + this.anchorSet = 0.5; + this.transition = null; + this.padding = 15; // conf + this.enabled = false; + this.maskSpriteX = 0; + this.maskSpriteY = 0; + this.maskSpriteScaleX = 4; + this.maskSpriteScaleY = 4; + this.maskSpriteSkewX = 0; + this.maskSpriteSkewY = 0; + this.maskSpriteRotation = 0; + this.zOrder = 4000; + this.sticky = true; + + this.animated = {}; + this.setTMParams(params); + this.maskPath = spriteMaskPath; + if (!this.dummy) { + this.anime = new Anime(this); + this.normalizeTMParams(); + this.sprite.anchor.set(this.anchorSet); + this.sprite.texture.baseTexture.wrapMode = this.wrapMode; + } + } + + set maskSpriteX(value) { + this.position.x = value; + } + + set maskSpriteY(value) { + this.position.y = value; + } + + get maskSpriteX() { + return this.position.x; + } + + get maskSpriteY() { + return this.position.y; + } + + set maskSpriteScaleX(value) { + this.scale.x = value; + } + + set maskSpriteScaleY(value) { + this.scale.y = value; + } + + get maskSpriteScaleX() { + return this.scale.x; + } + + get maskSpriteScaleY() { + return this.scale.y; + } + + set maskSpriteRotation(value) { + this.rotation = value; + } + + get maskSpriteRotation() { + return this.rotation; + } + + set maskSpriteSkewX(value) { + this.skew.x = value; + } + + get maskSpriteSkewX() { + return this.skew.x; + } + + set maskSpriteSkewY(value) { + this.skew.y = value; + } + + get maskSpriteSkewY() { + return this.skew.y; + } + + set maskSpritePivotX(value) { + this.pivot.x = value; + } + + get maskSpritePivotX() { + return this.pivot.x; + } + + set maskSpritePivotY(value) { + this.pivot.y = value; + } + + get maskSpritePivotY() { + return this.pivot.y; + } + + handleTransform() { + this.sprite.position.x = this.targetPlaceable.x + this.placeableImg.x + this.position.x; + this.sprite.position.y = this.targetPlaceable.y + this.placeableImg.y + this.position.y; + this.sprite.skew.x = this.skew.x; + this.sprite.skew.x = this.skew.y; + this.sprite.rotation = this.rotation; + this.sprite.pivot.x = this.pivot.x; + this.sprite.pivot.y = this.pivot.y; + + if (this.sticky) this.sprite.rotation += this.placeableImg.rotation; + + this.sprite.transform.updateTransform(canvas.stage.transform); + } + + apply(filterManager, input, output, clear) { + this.uniforms.filterMatrix = filterManager.calculateSpriteMatrix(this.maskMatrix, this.maskSprite); + this.uniforms.scale.x = this.scale.x; + this.uniforms.scale.y = this.scale.y; + + const wt = this.maskSprite.worldTransform; + this.uniforms.rotation[0] = wt.a; + this.uniforms.rotation[1] = wt.b; + this.uniforms.rotation[2] = wt.c; + this.uniforms.rotation[3] = wt.d; + + filterManager.applyFilter(this, input, output, clear); + } +} diff --git a/src/fx/filters/FilterDot.js b/src/fx/filters/FilterDot.js new file mode 100644 index 0000000..8d55bae --- /dev/null +++ b/src/fx/filters/FilterDot.js @@ -0,0 +1,18 @@ +import { Anime } from "../Anime.js"; +import "./proto/FilterProto.js"; + +export class FilterDot extends PIXI.filters.DotFilter { + constructor(params) { + super(); + this.scale = 1; + this.angle = 5; + this.grayscale = true; + this.zOrder = 330; + this.animated = {}; + this.setTMParams(params); + if (!this.dummy) { + this.anime = new Anime(this); + this.normalizeTMParams(); + } + } +} diff --git a/src/fx/filters/FilterDropShadow.js b/src/fx/filters/FilterDropShadow.js new file mode 100644 index 0000000..2e96f0b --- /dev/null +++ b/src/fx/filters/FilterDropShadow.js @@ -0,0 +1,29 @@ +import { Anime } from "../Anime.js"; +import "./proto/FilterProto.js"; +import { FilterDropShadowEx } from "./FilterDropShadowEx.js"; + +export class FilterDropShadow extends FilterDropShadowEx { + constructor(params) { + super(); + this.enabled = false; + this.rotation = 45; + this.distance = 5; + this.color = 0x000000; + this.alpha = 0.5; + this.shadowOnly = false; + this.blur = 2; + this.quality = 3; + this.padding = 10; + this.zOrder = 110; + this.animated = {}; + this.resolution = game.settings.get("core", "pixelRatioResolutionScaling") + ? window.devicePixelRatio + : PIXI.settings.FILTER_RESOLUTION; + this.setTMParams(params); + if (!this.dummy) { + this.anime = new Anime(this); + this.normalizeTMParams(); + } + this.autoFit = false; + } +} diff --git a/src/fx/filters/FilterDropShadowEx.js b/src/fx/filters/FilterDropShadowEx.js new file mode 100644 index 0000000..c80bbaf --- /dev/null +++ b/src/fx/filters/FilterDropShadowEx.js @@ -0,0 +1,146 @@ +import { CustomFilter } from "./CustomFilter.js"; +import { dropShadow } from "../glsl/fragmentshaders/dropshadow.js"; +import { customVertex2D } from "../glsl/vertexshaders/customvertex2D.js"; +import "./proto/FilterProto.js"; + +export class FilterDropShadowEx extends CustomFilter { + shadowOnly; + angle = 45; + + _distance = 5; + _resolution = PIXI.settings.FILTER_RESOLUTION; + _tintFilter; + _blurFilter; + + constructor(options = {}) { + super(); + + const opt = options ? { ...FilterDropShadowEx.defaults, ...options } : FilterDropShadowEx.defaults; + + const { kernels, blur, quality, resolution } = opt; + + this._tintFilter = new PIXI.Filter(customVertex2D, dropShadow); + this._tintFilter.uniforms.color = new Float32Array(4); + this._tintFilter.uniforms.shift = new PIXI.Point(); + this._tintFilter.resolution = resolution; + this._blurFilter = kernels + ? new PIXI.filters.KawaseBlurFilter(kernels) + : new PIXI.filters.KawaseBlurFilter(blur, quality); + + this._pixelSize = 1.0; + this.resolution = resolution; + + const { shadowOnly, rotation, distance, alpha, color } = opt; + + this.shadowOnly = shadowOnly; + this.rotation = rotation; + this.distance = distance; + this.alpha = alpha; + this.color = color; + } + + apply(filterManager, input, output, clear) { + this._updateShiftAndScale(); + const target = filterManager.getFilterTexture(); + + this._tintFilter.apply(filterManager, input, target, 1); + this._blurFilter.apply(filterManager, target, output, clear); + + if (this.shadowOnly !== true) { + filterManager.applyFilter(this, input, output, 0); + } + + filterManager.returnFilterTexture(target); + } + + _updateShiftAndScale() { + const scale = this.targetPlaceable?.worldTransform.a ?? 1.0; + this._tintFilter.uniforms.shift.set( + this.distance * Math.cos(this.angle) * scale, + this.distance * Math.sin(this.angle) * scale + ); + this._pixelSize = Math.max(1.0, 1.0 * scale); + } + + get resolution() { + return this._resolution; + } + set resolution(value) { + this._resolution = value; + + if (this._tintFilter) { + this._tintFilter.resolution = value; + } + if (this._blurFilter) { + this._blurFilter.resolution = value; + } + } + + get distance() { + return this._distance; + } + set distance(value) { + this._distance = value; + } + + get rotation() { + return this.angle / PIXI.DEG_TO_RAD; + } + set rotation(value) { + this.angle = value * PIXI.DEG_TO_RAD; + } + + get alpha() { + return this._tintFilter.uniforms.alpha; + } + set alpha(value) { + this._tintFilter.uniforms.alpha = value; + } + + get color() { + return PIXI.utils.rgb2hex(this._tintFilter.uniforms.color); + } + set color(value) { + new PIXI.Color(value).toRgbArray(this._tintFilter.uniforms.color); + } + + get kernels() { + return this._blurFilter.kernels; + } + set kernels(value) { + this._blurFilter.kernels = value; + } + + get blur() { + return this._blurFilter.blur; + } + set blur(value) { + this._blurFilter.blur = value; + } + + get quality() { + return this._blurFilter.quality; + } + set quality(value) { + this._blurFilter.quality = value; + } + + get _pixelSize() { + return this._blurFilter.pixelSize; + } + set _pixelSize(value) { + this._blurFilter.pixelSize = value; + } +} + +FilterDropShadowEx.defaults = { + rotation: 45, + distance: 5, + color: 0x000000, + alpha: 0.5, + shadowOnly: false, + kernels: null, + blur: 2, + quality: 3, + resolution: PIXI.settings.FILTER_RESOLUTION, +}; diff --git a/src/fx/filters/FilterElectric.js b/src/fx/filters/FilterElectric.js new file mode 100644 index 0000000..bd43773 --- /dev/null +++ b/src/fx/filters/FilterElectric.js @@ -0,0 +1,70 @@ +import { zapElectricity } from "../glsl/fragmentshaders/electricity.js"; +import { customVertex2D } from "../glsl/vertexshaders/customvertex2D.js"; +import { CustomFilter } from "./CustomFilter.js"; +import { Anime } from "../Anime.js"; +import "./proto/FilterProto.js"; + +export class FilterElectric extends CustomFilter { + constructor(params) { + let { time, blend, color } = Object.assign({}, FilterElectric.defaults, params); + + var shaderFragment; + if (params.hasOwnProperty("intensity") && typeof params.intensity === "number") { + var intensityVal = Math.floor(params.intensity); + shaderFragment = zapElectricity.replace("#define INTENSITY 5", "#define INTENSITY " + intensityVal); + } else { + shaderFragment = zapElectricity; + } + + super(customVertex2D, shaderFragment); + + this.uniforms.color = new Float32Array([1.0, 1.0, 1.0, 1.0]); + this.uniforms.blend = 2; + + Object.assign(this, { + time, + blend, + color, + }); + + this.zOrder = 160; + this.animated = {}; + this.setTMParams(params); + if (!this.dummy) { + this.anime = new Anime(this); + this.normalizeTMParams(); + } + + this.quality = 0.5; + } + + get time() { + return this.uniforms.time; + } + + set time(value) { + this.uniforms.time = value; + } + + get color() { + return PIXI.utils.rgb2hex(this.uniforms.color); + } + + set color(value) { + new PIXI.Color(value).toRgbArray(this.uniforms.color); + } + + get blend() { + return this.uniforms.blend; + } + + set blend(value) { + this.uniforms.blend = Math.floor(value); + } +} + +FilterElectric.defaults = { + time: 0.0, + blend: 1, + color: 0xffffff, +}; diff --git a/src/fx/filters/FilterFire.js b/src/fx/filters/FilterFire.js new file mode 100644 index 0000000..047ac2f --- /dev/null +++ b/src/fx/filters/FilterFire.js @@ -0,0 +1,127 @@ +import { burnFire } from "../glsl/fragmentshaders/fire.js"; +import { customVertex2D } from "../glsl/vertexshaders/customvertex2D.js"; +import { CustomFilter } from "./CustomFilter.js"; +import { Anime } from "../Anime.js"; +import "./proto/FilterProto.js"; + +export class FilterFire extends CustomFilter { + constructor(params) { + let { time, color, amplitude, intensity, fireBlend, blend, anchorX, anchorY, alphaDiscard } = Object.assign( + {}, + FilterFire.defaults, + params + ); + + // using specific vertex shader and fragment shader + super(customVertex2D, burnFire); + + this.uniforms.color = new Float32Array([1.0, 1.0, 1.0]); + this.uniforms.anchor = new Float32Array([1.0, 1.0]); + + Object.assign(this, { + time, + color, + amplitude, + intensity, + fireBlend, + blend, + anchorX, + anchorY, + alphaDiscard, + }); + + this.zOrder = 150; + this.animated = {}; + this.setTMParams(params); + if (!this.dummy) { + this.anime = new Anime(this); + this.normalizeTMParams(); + } + } + + get time() { + return this.uniforms.time; + } + + set time(value) { + this.uniforms.time = value; + } + + get color() { + return PIXI.utils.rgb2hex(this.uniforms.color); + } + + set color(value) { + new PIXI.Color(value).toRgbArray(this.uniforms.color); + } + + get amplitude() { + return this.uniforms.amplitude; + } + + set amplitude(value) { + this.uniforms.amplitude = value; + } + + get intensity() { + return this.uniforms.intensity; + } + + set intensity(value) { + this.uniforms.intensity = value; + } + + get fireBlend() { + return this.uniforms.fireBlend; + } + + set fireBlend(value) { + this.uniforms.fireBlend = Math.floor(value); + } + + get blend() { + return this.uniforms.blend; + } + + set blend(value) { + this.uniforms.blend = Math.floor(value); + } + + get anchorX() { + return this.uniforms.anchor[0]; + } + + set anchorX(value) { + this.uniforms.anchor[0] = value; + } + + get anchorY() { + return this.uniforms.anchor[1]; + } + + set anchorY(value) { + this.uniforms.anchor[1] = value; + } + + get alphaDiscard() { + return this.uniforms.alphaDiscard; + } + + set alphaDiscard(value) { + if (!(value == null) && typeof value === "boolean") { + this.uniforms.alphaDiscard = value; + } + } +} + +FilterFire.defaults = { + time: 0, + color: 0xffffff, + amplitude: 1, + intensity: 1, + fireBlend: 1, + blend: 2, + anchorX: 1, + anchorY: 1, + alphaDiscard: false, +}; diff --git a/src/fx/filters/FilterFlood.js b/src/fx/filters/FilterFlood.js new file mode 100644 index 0000000..014cf49 --- /dev/null +++ b/src/fx/filters/FilterFlood.js @@ -0,0 +1,115 @@ +import { seaFlood } from "../glsl/fragmentshaders/flood.js"; +import { customVertex2D } from "../glsl/vertexshaders/customvertex2D.js"; +import { CustomFilter } from "./CustomFilter.js"; +import { Anime } from "../Anime.js"; +import "./proto/FilterProto.js"; + +export class FilterFlood extends CustomFilter { + constructor(params) { + let { time, scale, glint, billowy, color, shiftX, shiftY, tintIntensity } = Object.assign( + {}, + FilterFlood.defaults, + params + ); + + // using specific vertex shader and fragment shader + super(customVertex2D, seaFlood); + + this.uniforms.waterColor = new Float32Array([0.0, 0.18, 0.54]); + this.uniforms.shift = new Float32Array([0.0, 0.0]); + + Object.assign(this, { + time, + scale, + glint, + billowy, + color, + shiftX, + shiftY, + tintIntensity, + }); + + this.zOrder = 170; + this.animated = {}; + this.setTMParams(params); + if (!this.dummy) { + this.anime = new Anime(this); + this.normalizeTMParams(); + } + } + + get time() { + return this.uniforms.time; + } + + set time(value) { + this.uniforms.time = value; + } + + get color() { + return PIXI.utils.rgb2hex(this.uniforms.waterColor); + } + + set color(value) { + new PIXI.Color(value).toRgbArray(this.uniforms.waterColor); + } + + get scale() { + return this.uniforms.scale; + } + + set scale(value) { + this.uniforms.scale = value; + } + + get glint() { + return this.uniforms.glint; + } + + set glint(value) { + this.uniforms.glint = value; + } + + get billowy() { + return this.uniforms.billowy; + } + + set billowy(value) { + this.uniforms.billowy = value; + } + + get tintIntensity() { + return this.uniforms.tintIntensity; + } + + set tintIntensity(value) { + this.uniforms.tintIntensity = value; + } + + get shiftX() { + return this.uniforms.shift[0]; + } + + set shiftX(value) { + this.uniforms.shift[0] = value; + } + + get shiftY() { + this.uniforms.shift[1]; + } + + set shiftY(value) { + this.uniforms.shift[1] = value; + } +} + +FilterFlood.defaults = { + time: 0, + glint: 0.5, + scale: 70, + billowy: 0.5, + color: 0x0020a9, + shiftX: 0, + shiftY: 0, + tintIntensity: 0.2, +}; diff --git a/src/fx/filters/FilterFog.js b/src/fx/filters/FilterFog.js new file mode 100644 index 0000000..78a33ea --- /dev/null +++ b/src/fx/filters/FilterFog.js @@ -0,0 +1,80 @@ +import { innerFog } from "../glsl/fragmentshaders/fog.js"; +import { customVertex2D } from "../glsl/vertexshaders/customvertex2D.js"; +import { CustomFilter } from "./CustomFilter.js"; +import { Anime } from "../Anime.js"; + +export class FilterFog extends CustomFilter { + constructor(params) { + let { time, color, density, dimX, dimY } = Object.assign({}, FilterFog.defaults, params); + + // specific vertex and fragment shaders + super(customVertex2D, innerFog); + + this.uniforms.color = new Float32Array([1.0, 0.4, 0.1, 0.55]); + this.uniforms.dimensions = new Float32Array([1.0, 1.0]); + + Object.assign(this, { + time, + color, + density, + dimX, + dimY, + }); + + this.zOrder = 190; + this.animated = {}; + this.setTMParams(params); + if (!this.dummy) { + this.anime = new Anime(this); + this.normalizeTMParams(); + } + } + + get time() { + return this.uniforms.time; + } + + set time(value) { + this.uniforms.time = value; + } + + get color() { + return PIXI.utils.rgb2hex(this.uniforms.color); + } + + set color(value) { + new PIXI.Color(value).toRgbArray(this.uniforms.color); + } + + get density() { + return this.uniforms.density; + } + + set density(value) { + this.uniforms.density = value; + } + + get dimX() { + return this.uniforms.dimensions[0]; + } + + set dimX(value) { + this.uniforms.dimensions[0] = value; + } + + get dimY() { + return this.uniforms.dimensions[1]; + } + + set dimY(value) { + this.uniforms.dimensions[1] = value; + } +} + +FilterFog.defaults = { + time: 0.0, + color: 0xffffff, + density: 0.5, + dimX: 1.0, + dimY: 1.0, +}; diff --git a/src/fx/filters/FilterForceField.js b/src/fx/filters/FilterForceField.js new file mode 100644 index 0000000..4741578 --- /dev/null +++ b/src/fx/filters/FilterForceField.js @@ -0,0 +1,201 @@ +import { forceField } from "../glsl/fragmentshaders/forcefield.js"; +import { customVertex2D } from "../glsl/vertexshaders/customvertex2D.js"; +import { CustomFilter } from "./CustomFilter.js"; +import { Anime } from "../Anime.js"; +import "./proto/FilterProto.js"; + +export class FilterForceField extends CustomFilter { + constructor(params) { + let { + time, + color, + lightAlpha, + blend, + shieldType, + posLightX, + posLightY, + lightSize, + scale, + intensity, + radius, + hideRadius, + chromatic, + discardThreshold, + alphaDiscard, + } = Object.assign({}, FilterForceField.defaults, params); + + // using specific vertex shader and fragment shader + super(customVertex2D, forceField); + + this.uniforms.color = new Float32Array([1.0, 1.0, 1.0]); + this.uniforms.posLight = new Float32Array([1.0, 1.0]); + + Object.assign(this, { + time, + color, + lightAlpha, + blend, + shieldType, + posLightX, + posLightY, + lightSize, + scale, + intensity, + radius, + hideRadius, + chromatic, + discardThreshold, + alphaDiscard, + }); + + this.zOrder = 2000; + this.animated = {}; + this.setTMParams(params); + if (!this.dummy) { + this.anime = new Anime(this); + this.normalizeTMParams(); + } + } + + get time() { + return this.uniforms.time; + } + + set time(value) { + this.uniforms.time = value; + } + + get color() { + return PIXI.utils.rgb2hex(this.uniforms.color); + } + + set color(value) { + new PIXI.Color(value).toRgbArray(this.uniforms.color); + } + + get blend() { + return this.uniforms.blend; + } + + set blend(value) { + this.uniforms.blend = Math.floor(value); + } + + get lightAlpha() { + return this.uniforms.lightColorAlpha; + } + + set lightAlpha(value) { + this.uniforms.lightColorAlpha = value; + } + + get shieldType() { + return this.uniforms.shieldType; + } + + set shieldType(value) { + this.uniforms.shieldType = Math.floor(value); + } + + get posLightX() { + return this.uniforms.posLight[0]; + } + + set posLightX(value) { + this.uniforms.posLight[0] = value; + } + + get posLightY() { + return this.uniforms.posLight[1]; + } + + set posLightY(value) { + this.uniforms.posLight[1] = value; + } + + get lightSize() { + return this.uniforms.lightSize; + } + + set lightSize(value) { + this.uniforms.lightSize = value; + } + + get scale() { + return this.uniforms.scale; + } + + set scale(value) { + this.uniforms.scale = value; + } + + get intensity() { + return this.uniforms.intensity; + } + + set intensity(value) { + this.uniforms.intensity = value; + } + + get radius() { + return this.uniforms.radius; + } + + set radius(value) { + this.uniforms.radius = value; + } + + get hideRadius() { + return this.uniforms.hideRadius; + } + + set hideRadius(value) { + this.uniforms.hideRadius = value; + } + + get discardThreshold() { + return this.uniforms.discardThreshold; + } + + set discardThreshold(value) { + this.uniforms.discardThreshold = value; + } + + get alphaDiscard() { + return this.uniforms.alphaDiscard; + } + + set alphaDiscard(value) { + if (!(value == null) && typeof value === "boolean") { + this.uniforms.alphaDiscard = value; + } + } + + get chromatic() { + return this.uniforms.chromatic; + } + + set chromatic(value) { + if (!(value == null) && typeof value === "boolean") { + this.uniforms.chromatic = value; + } + } +} + +FilterForceField.defaults = { + time: 0, + color: 0xbbbbbb, + lightAlpha: 1.0, + blend: 2, + shieldType: 1, + posLightX: 0.65, + posLightY: 0.25, + lightSize: 0.483, + scale: 1, + intensity: 1, + radius: 1, + hideRadius: 0, + chromatic: false, + discardThreshold: 0.25, + alphaDiscard: false, +}; diff --git a/src/fx/filters/FilterFumes.js b/src/fx/filters/FilterFumes.js new file mode 100644 index 0000000..e047810 --- /dev/null +++ b/src/fx/filters/FilterFumes.js @@ -0,0 +1,81 @@ +import { fumes } from "../glsl/fragmentshaders/fumes.js"; +import { customVertex2D } from "../glsl/vertexshaders/customvertex2D.js"; +import { CustomFilter } from "./CustomFilter.js"; +import { Anime } from "../Anime.js"; +import "./proto/FilterProto.js"; + +export class FilterFumes extends CustomFilter { + constructor(params) { + let { time, color, blend, dimX, dimY } = Object.assign({}, FilterFumes.defaults, params); + + // using specific vertex shader and fragment shader + super(customVertex2D, fumes); + + this.uniforms.color = new Float32Array([1.0, 1.0, 1.0]); + this.uniforms.dimensions = new Float32Array([1.0, 1.0]); + + Object.assign(this, { + time, + color, + blend, + dimX, + dimY, + }); + + this.zOrder = 210; + this.animated = {}; + this.setTMParams(params); + if (!this.dummy) { + this.anime = new Anime(this); + this.normalizeTMParams(); + } + } + + get time() { + return this.uniforms.time; + } + + set time(value) { + this.uniforms.time = value; + } + + get color() { + return PIXI.utils.rgb2hex(this.uniforms.color); + } + + set color(value) { + new PIXI.Color(value).toRgbArray(this.uniforms.color); + } + + get blend() { + return this.uniforms.blend; + } + + set blend(value) { + this.uniforms.blend = Math.floor(value); + } + + get dimX() { + return this.uniforms.dimensions[0]; + } + + set dimX(value) { + this.uniforms.dimensions[0] = value; + } + + get dimY() { + return this.uniforms.dimensions[1]; + } + + set dimY(value) { + this.uniforms.dimensions[1] = value; + } +} + +FilterFumes.defaults = { + time: 0, + color: 0xffffff, + blend: 2, + dimX: 1, + dimY: 1, +}; diff --git a/src/fx/filters/FilterGleamingGlow.js b/src/fx/filters/FilterGleamingGlow.js new file mode 100644 index 0000000..8a22519 --- /dev/null +++ b/src/fx/filters/FilterGleamingGlow.js @@ -0,0 +1,122 @@ +import { magicGlow } from "../glsl/fragmentshaders/magicglow.js"; +import { customVertex2D } from "../glsl/vertexshaders/customvertex2D.js"; +import { CustomFilter } from "./CustomFilter.js"; +import { Anime } from "../Anime.js"; +import "./proto/FilterProto.js"; + +export class FilterGleamingGlow extends CustomFilter { + constructor(params) { + let { time, color, thickness, scale, auraIntensity, subAuraIntensity, discard, threshold, auraType } = + Object.assign({}, FilterGleamingGlow.defaults, params); + + // using specific vertex shader and fragment shader + super(customVertex2D, magicGlow); + + this.uniforms.color = new Float32Array([1.0, 0.4, 0.1, 1.0]); + this.uniforms.thickness = new Float32Array([0.01, 0.01]); + + Object.assign(this, { + time, + color, + thickness, + scale, + auraIntensity, + subAuraIntensity, + discard, + threshold, + auraType, + }); + + this.zOrder = 80; + this.animated = {}; + this.setTMParams(params); + if (!this.dummy) { + this.anime = new Anime(this); + this.normalizeTMParams(); + } + } + + get time() { + return this.uniforms.time; + } + + set time(value) { + this.uniforms.time = value; + } + + get scale() { + return this.uniforms.scale; + } + + set scale(value) { + this.uniforms.scale = value; + } + + get auraIntensity() { + return this.uniforms.auraIntensity; + } + + set auraIntensity(value) { + this.uniforms.auraIntensity = value; + } + + get subAuraIntensity() { + return this.uniforms.subAuraIntensity; + } + + set subAuraIntensity(value) { + this.uniforms.subAuraIntensity = value; + } + + get threshold() { + return this.uniforms.threshold; + } + + set threshold(value) { + this.uniforms.threshold = value; + } + + get color() { + return PIXI.utils.rgb2hex(this.uniforms.color); + } + + set color(value) { + new PIXI.Color(value).toRgbArray(this.uniforms.color); + } + + get discard() { + return this.uniforms.holes; + } + + set discard(value) { + if (!(value == null) && typeof value === "boolean") { + this.uniforms.holes = value; + } + } + + get auraType() { + return this.uniforms.auraType; + } + + set auraType(value) { + this.uniforms.auraType = Math.floor(value); + } + + apply(filterManager, input, output, clear) { + this.uniforms.thickness[0] = (this.thickness * this.targetPlaceable.worldTransform.a) / input._frame.width; + this.uniforms.thickness[1] = (this.thickness * this.targetPlaceable.worldTransform.a) / input._frame.height; + super.apply(filterManager, input, output, clear); + } +} + +FilterGleamingGlow.defaults = { + time: 0, + color: 0xff8010, + thickness: 5, + scale: 1, + auraIntensity: 1, + subAuraIntensity: 1, + discard: false, + threshold: 0.5, + auraType: 1, +}; diff --git a/src/fx/filters/FilterGlobes.js b/src/fx/filters/FilterGlobes.js new file mode 100644 index 0000000..79d378f --- /dev/null +++ b/src/fx/filters/FilterGlobes.js @@ -0,0 +1,82 @@ +import { globes } from "../glsl/fragmentshaders/globes.js"; +import { customVertex2D } from "../glsl/vertexshaders/customvertex2D.js"; +import { CustomFilter } from "./CustomFilter.js"; +import { Anime } from "../Anime.js"; +import "./proto/FilterProto.js"; + +export class FilterGlobes extends CustomFilter { + constructor(params) { + let { time, color, scale, distortion, alphaDiscard } = Object.assign({}, FilterGlobes.defaults, params); + + // using specific vertex shader and fragment shader + super(customVertex2D, globes); + + this.uniforms.color = new Float32Array([0.75, 0.75, 0.75]); + + Object.assign(this, { + time, + color, + scale, + distortion, + alphaDiscard, + }); + + this.zOrder = 270; + this.animated = {}; + this.setTMParams(params); + if (!this.dummy) { + this.anime = new Anime(this); + this.normalizeTMParams(); + } + } + + get time() { + return this.uniforms.time; + } + + set time(value) { + this.uniforms.time = value; + } + + get color() { + return PIXI.utils.rgb2hex(this.uniforms.color); + } + + set color(value) { + new PIXI.Color(value).toRgbArray(this.uniforms.color); + } + + get scale() { + return this.uniforms.scale; + } + + set scale(value) { + this.uniforms.scale = value; + } + + get distortion() { + return this.uniforms.distortion; + } + + set distortion(value) { + this.uniforms.distortion = value; + } + + get alphaDiscard() { + return this.uniforms.alphaDiscard; + } + + set alphaDiscard(value) { + if (!(value == null) && typeof value === "boolean") { + this.uniforms.alphaDiscard = value; + } + } +} + +FilterGlobes.defaults = { + time: 0.0, + color: 0xaa3050, + scale: 20, + distortion: 0.25, + alphaDiscard: false, +}; diff --git a/src/fx/filters/FilterGlow.js b/src/fx/filters/FilterGlow.js new file mode 100644 index 0000000..d8b3f8e --- /dev/null +++ b/src/fx/filters/FilterGlow.js @@ -0,0 +1,24 @@ +import { Anime } from "../Anime.js"; +import "./proto/FilterProto.js"; + +export class FilterGlow extends PIXI.filters.GlowFilter { + constructor(params) { + super(); + this.padding = 15; + this.enabled = false; + this.innerStrength = 0; + this.outerStrength = 6.5; + this.color = 0x0020ff; + this.quality = 1; + this.alpha = 1; + this.zOrder = 70; + this.animated = {}; + this.setTMParams(params); + // Imposed value. Should not be a shader uniform + this.distance = 10; + if (!this.dummy) { + this.anime = new Anime(this); + this.normalizeTMParams(); + } + } +} diff --git a/src/fx/filters/FilterLiquid.js b/src/fx/filters/FilterLiquid.js new file mode 100644 index 0000000..d7705a5 --- /dev/null +++ b/src/fx/filters/FilterLiquid.js @@ -0,0 +1,108 @@ +import { liquid } from "../glsl/fragmentshaders/liquid.js"; +import { customVertex2D } from "../glsl/vertexshaders/customvertex2D.js"; +import { CustomFilter } from "./CustomFilter.js"; +import { Anime } from "../Anime.js"; +import "./proto/FilterProto.js"; + +export class FilterLiquid extends CustomFilter { + constructor(params) { + let { time, color, scale, intensity, blend, spectral, alphaDiscard } = Object.assign( + {}, + FilterLiquid.defaults, + params + ); + + // using specific vertex shader and fragment shader + super(customVertex2D, liquid); + + this.uniforms.color = new Float32Array([0.1, 0.45, 1.0]); + + Object.assign(this, { + time, + color, + scale, + intensity, + blend, + spectral, + alphaDiscard, + }); + + this.zOrder = 180; + this.animated = {}; + this.setTMParams(params); + if (!this.dummy) { + this.anime = new Anime(this); + this.normalizeTMParams(); + } + } + + get time() { + return this.uniforms.time; + } + + set time(value) { + this.uniforms.time = value; + } + + get scale() { + return this.uniforms.scale; + } + + set scale(value) { + this.uniforms.scale = value; + } + + get color() { + return PIXI.utils.rgb2hex(this.uniforms.color); + } + + set color(value) { + new PIXI.Color(value).toRgbArray(this.uniforms.color); + } + + get intensity() { + return this.uniforms.intensity; + } + + set intensity(value) { + this.uniforms.intensity = value; + } + + get blend() { + return this.uniforms.blend; + } + + set blend(value) { + this.uniforms.blend = Math.floor(value); + } + + get spectral() { + return this.uniforms.spectral; + } + + set spectral(value) { + if (!(value == null) && typeof value === "boolean") { + this.uniforms.spectral = value; + } + } + + get alphaDiscard() { + return this.uniforms.alphaDiscard; + } + + set alphaDiscard(value) { + if (!(value == null) && typeof value === "boolean") { + this.uniforms.alphaDiscard = value; + } + } +} + +FilterLiquid.defaults = { + time: 0.0, + color: 0x0595ff, + scale: 1, + intensity: 5, + blend: 4, + spectral: false, + alphaDiscard: false, +}; diff --git a/src/fx/filters/FilterMirrorImages.js b/src/fx/filters/FilterMirrorImages.js new file mode 100644 index 0000000..3afd07c --- /dev/null +++ b/src/fx/filters/FilterMirrorImages.js @@ -0,0 +1,103 @@ +import { mirrorImages } from "../glsl/fragmentshaders/mirrorimages.js"; +import { customVertex2D } from "../glsl/vertexshaders/customvertex2D.js"; +import { CustomFilter } from "./CustomFilter.js"; +import { Anime } from "../Anime.js"; +import "./proto/FilterProto.js"; + +export class FilterMirrorImages extends CustomFilter { + constructor(params) { + let { time, blend, alphaImg, alphaChr, nbImage, ampX, ampY } = Object.assign( + {}, + FilterMirrorImages.defaults, + params + ); + + // using specific vertex shader and fragment shader + super(customVertex2D, mirrorImages); + + Object.assign(this, { + time, + blend, + alphaImg, + alphaChr, + nbImage, + ampX, + ampY, + }); + + this.zOrder = 100; + this.autoFit = false; + this.animated = {}; + this.setTMParams(params); + if (!this.dummy) { + this.anime = new Anime(this); + this.normalizeTMParams(); + } + } + + get time() { + return this.uniforms.time; + } + + set time(value) { + this.uniforms.time = value; + } + + get alphaImg() { + return this.uniforms.alphaImg; + } + + set alphaImg(value) { + this.uniforms.alphaImg = value; + } + + get alphaChr() { + return this.uniforms.alphaChr; + } + + set alphaChr(value) { + this.uniforms.alphaChr = value; + } + + get nbImage() { + return this.uniforms.nbImage; + } + + set nbImage(value) { + this.uniforms.nbImage = Math.floor(value); + } + + get blend() { + return this.uniforms.blend; + } + + set blend(value) { + this.uniforms.blend = Math.floor(value); + } + + get ampX() { + return this.uniforms.ampX; + } + + set ampX(value) { + this.uniforms.ampX = value; + } + + get ampY() { + return this.uniforms.ampY; + } + + set ampY(value) { + this.uniforms.ampY = value; + } +} + +FilterMirrorImages.defaults = { + time: 0, + blend: 4, + alphaImg: 0.5, + alphaChr: 1.0, + nbImage: 4, + ampX: 0.15, + ampY: 0.15, +}; diff --git a/src/fx/filters/FilterOldFilm.js b/src/fx/filters/FilterOldFilm.js new file mode 100644 index 0000000..d956288 --- /dev/null +++ b/src/fx/filters/FilterOldFilm.js @@ -0,0 +1,21 @@ +import { Anime } from "../Anime.js"; +import "./proto/FilterProto.js"; + +export class FilterOldFilm extends PIXI.filters.OldFilmFilter { + constructor(params) { + super(); + this.enabled = false; + this.vignetting = 0; + this.noise = 0.08; + this.scratch = 0.1; + this.scratchDensity = 0.1; + this.seed = 0; + this.zOrder = 60; + this.animated = {}; + this.setTMParams(params); + if (!this.dummy) { + this.anime = new Anime(this); + this.normalizeTMParams(); + } + } +} diff --git a/src/fx/filters/FilterOutline.js b/src/fx/filters/FilterOutline.js new file mode 100644 index 0000000..7b3c484 --- /dev/null +++ b/src/fx/filters/FilterOutline.js @@ -0,0 +1,21 @@ +import { Anime } from "../Anime.js"; +import "./proto/FilterProto.js"; + +export class FilterOutline extends PIXI.filters.OutlineFilter { + constructor(params) { + super(); + this.blendMode = PIXI.BLEND_MODES.NORMAL; + this.padding = 5; + this.enabled = false; + this.thickness = 3; + this.color = 0x000000; + this.quality = 1; + this.zOrder = 50; + this.animated = {}; + this.setTMParams(params); + if (!this.dummy) { + this.anime = new Anime(this); + this.normalizeTMParams(); + } + } +} diff --git a/src/fx/filters/FilterPixelate.js b/src/fx/filters/FilterPixelate.js new file mode 100644 index 0000000..823bcef --- /dev/null +++ b/src/fx/filters/FilterPixelate.js @@ -0,0 +1,23 @@ +import { Anime } from "../Anime.js"; +import "./proto/FilterProto.js"; + +export class FilterPixelate extends PIXI.filters.PixelateFilter { + constructor(params) { + super(); + this.enabled = false; + this.animated = {}; + this.sizeX = 5; + this.sizeY = 5; + this.zOrder = 20; + this.setTMParams(params); + if (!this.dummy) { + this.anime = new Anime(this); + this.normalizeTMParams(); + } + } + + handleTransform() { + this.size.x = this.sizeX * this.targetPlaceable.worldTransform.a; + this.size.y = this.sizeY * this.targetPlaceable.worldTransform.a; + } +} diff --git a/src/fx/filters/FilterPolymorph.js b/src/fx/filters/FilterPolymorph.js new file mode 100644 index 0000000..ceee146 --- /dev/null +++ b/src/fx/filters/FilterPolymorph.js @@ -0,0 +1,144 @@ +import { polymorph } from "../glsl/fragmentshaders/polymorph.js"; +import { customVertex2DSampler } from "../glsl/vertexshaders/customvertex2DSampler.js"; +import { CustomFilter } from "./CustomFilter.js"; +import { Anime } from "../Anime.js"; +import "./proto/FilterProto.js"; +import { fixPath } from "../../module.js"; + +export class FilterPolymorph extends CustomFilter { + constructor(params) { + let { imagePath, progress, magnify, type } = Object.assign({}, FilterPolymorph.defaults, params); + + const targetSpriteMatrix = new PIXI.Matrix(); + + // using specific vertex shader and fragment shader + super(customVertex2DSampler, polymorph); + + // vertex uniforms + this.uniforms.targetUVMatrix = targetSpriteMatrix; + + // fragment uniforms + this.uniforms.inputClampTarget = new Float32Array([0, 0, 0, 0]); + + // to store sprite matrix from the filter manager (and send to vertex) + this.targetSpriteMatrix = targetSpriteMatrix; + + Object.assign(this, { + imagePath: fixPath(imagePath), + progress, + magnify, + type, + }); + + this.zOrder = 1; + this.autoFit = false; + this.animated = {}; + this.setTMParams(params); + if (!this.dummy) { + this.anime = new Anime(this); + this.normalizeTMParams(); + } + } + + setTMParams(params) { + super.setTMParams(params); + if (!this.dummy && "imagePath" in params) { + this.assignTexture(); + } + } + + get progress() { + return this.uniforms.progress * 100; + } + + set progress(value) { + this.uniforms.progress = Math.min(Math.max(value * 0.01, 0), 1); + } + + get magnify() { + return this.uniforms.magnify; + } + + set magnify(value) { + this.uniforms.magnify = Math.min(Math.max(value, 0.1), 100); + } + + get type() { + return this.uniforms.type; + } + + set type(value) { + this.uniforms.type = Math.floor(value); + } + + get uSamplerTarget() { + return this.uniforms.uSamplerTarget; + } + + set uSamplerTarget(value) { + this.uniforms.uSamplerTarget = value; + } + + _setTargetSpriteSize() { + const sprite = this.targetSprite; + let ratioW = this.placeableImg._texture.baseTexture.realWidth / sprite.texture.baseTexture.realWidth; + sprite.width = sprite.texture.baseTexture.realWidth * ratioW; + sprite.height = sprite.texture.baseTexture.realHeight * ratioW; + sprite.anchor.set(0.5); + } + + assignTexture() { + if (this.hasOwnProperty("imagePath")) { + let tex = PIXI.Texture.from(this.imagePath); + let sprite = new PIXI.Sprite(tex); + + sprite.renderable = false; + this.targetSprite = sprite; + + // We may need to wait for the texture to be loaded before accessing it's width and height + // In such a case register an update listener which should be called when the texture is loaded/becomes valid + if (tex.valid) { + this._setTargetSpriteSize(); + } else { + tex.on("update", () => { + this._setTargetSpriteSize(); + }); + } + + this.uSamplerTarget = sprite._texture; + this.placeableImg.addChild(sprite); + } + } + + // override + apply(filterManager, input, output, clear) { + const targetSprite = this.targetSprite; + const tex = targetSprite._texture; + + if (tex.valid) { + if (!tex.uvMatrix) tex.uvMatrix = new PIXI.TextureMatrix(tex, 0.0); + tex.uvMatrix.update(); + + this.uniforms.uSamplerTarget = tex; + this.uniforms.targetUVMatrix = filterManager + .calculateSpriteMatrix(this.targetSpriteMatrix, targetSprite) + .prepend(tex.uvMatrix.mapCoord); + this.uniforms.inputClampTarget = tex.uvMatrix.uClampFrame; + } + + super.apply(filterManager, input, output, clear); + } + + // override + destroy() { + super.destroy(); + if (this.placeableImg) this.placeableImg.removeChild(this.targetSprite); + this.targetSprite.destroy({ children: true, texture: false, baseTexture: false }); + } +} + +FilterPolymorph.defaults = { + progress: 0, + magnify: 1, + type: 1, +}; diff --git a/src/fx/filters/FilterRGBSplit.js b/src/fx/filters/FilterRGBSplit.js new file mode 100644 index 0000000..78a95c2 --- /dev/null +++ b/src/fx/filters/FilterRGBSplit.js @@ -0,0 +1,66 @@ +import { Anime } from "../Anime.js"; +import "./proto/FilterProto.js"; + +export class FilterRGBSplit extends PIXI.filters.RGBSplitFilter { + constructor(params) { + super(); + this.red = new Float32Array([-10, 0]); + this.green = new Float32Array([0, 10]); + this.blue = new Float32Array([0, 0]); + this.zOrder = 340; + this.animated = {}; + this.setTMParams(params); + if (!this.dummy) { + this.anime = new Anime(this); + this.normalizeTMParams(); + } + } + + get redX() { + return this.uniforms.red[0]; + } + + set redX(value) { + this.uniforms.red[0] = value; + } + + get redY() { + return this.uniforms.red[1]; + } + + set redY(value) { + this.uniforms.red[1] = value; + } + + get greenX() { + return this.uniforms.green[0]; + } + + set greenX(value) { + this.uniforms.green[0] = value; + } + + get greenY() { + return this.uniforms.green[1]; + } + + set greenY(value) { + this.uniforms.green[1] = value; + } + + get blueX() { + return this.uniforms.blue[0]; + } + + set blueX(value) { + this.uniforms.blue[0] = value; + } + + get blueY() { + return this.uniforms.blue[1]; + } + + set blueY(value) { + this.uniforms.blue[1] = value; + } +} diff --git a/src/fx/filters/FilterRays.js b/src/fx/filters/FilterRays.js new file mode 100644 index 0000000..1469c4a --- /dev/null +++ b/src/fx/filters/FilterRays.js @@ -0,0 +1,130 @@ +import { cosmicRayFrag } from "../glsl/fragmentshaders/cosmicray.js"; +import { customVertex2D } from "../glsl/vertexshaders/customvertex2D.js"; +import { CustomFilter } from "./CustomFilter.js"; +import { Anime } from "../Anime.js"; +import "./proto/FilterProto.js"; + +export class FilterRays extends CustomFilter { + constructor(params) { + let { time, color, divisor, alpha, anchorX, anchorY, dimX, dimY, alphaDiscard } = Object.assign( + {}, + FilterRays.defaults, + params + ); + + // using specific vertex shader and fragment shader + super(customVertex2D, cosmicRayFrag); + + this.uniforms.color = new Float32Array([1.0, 0.4, 0.1, 0.55]); + this.uniforms.anchor = new Float32Array([0.5, 0.5]); + this.uniforms.dimensions = new Float32Array([1.0, 1.0]); + + Object.assign(this, { + time, + color, + divisor, + alpha, + anchorX, + anchorY, + dimX, + dimY, + alphaDiscard, + }); + + this.zOrder = 120; + this.animated = {}; + this.setTMParams(params); + if (!this.dummy) { + this.anime = new Anime(this); + this.normalizeTMParams(); + } + } + + get time() { + return this.uniforms.time; + } + + set time(value) { + this.uniforms.time = value; + } + + get color() { + return PIXI.utils.rgb2hex(this.uniforms.color); + } + + set color(value) { + new PIXI.Color(value).toRgbArray(this.uniforms.color); + } + + get divisor() { + return this.uniforms.divisor; + } + + set divisor(value) { + this.uniforms.divisor = value; + } + + get alpha() { + return this.uniforms.color[3]; + } + + set alpha(value) { + if (value >= 0 && value <= 1) { + this.uniforms.color[3] = value; + } + } + + get anchorX() { + return this.uniforms.anchor[0]; + } + + set anchorX(value) { + this.uniforms.anchor[0] = value; + } + + get anchorY() { + return this.uniforms.anchor[1]; + } + + set anchorY(value) { + this.uniforms.anchor[1] = value; + } + + get dimX() { + return this.uniforms.dimensions[0]; + } + + set dimX(value) { + this.uniforms.dimensions[0] = value; + } + + get dimY() { + return this.uniforms.dimensions[1]; + } + + set dimY(value) { + this.uniforms.dimensions[1] = value; + } + + get alphaDiscard() { + return this.uniforms.alphaDiscard; + } + + set alphaDiscard(value) { + if (!(value == null) && typeof value === "boolean") { + this.uniforms.alphaDiscard = value; + } + } +} + +FilterRays.defaults = { + time: 0.0, + color: 0xff8010, + divisor: 16, + alpha: 0.55, + anchorX: 0.5, + anchorY: 0.5, + dimX: 100, + dimY: 100, + alphaDiscard: false, +}; diff --git a/src/fx/filters/FilterRemoveShadow.js b/src/fx/filters/FilterRemoveShadow.js new file mode 100644 index 0000000..7d7e996 --- /dev/null +++ b/src/fx/filters/FilterRemoveShadow.js @@ -0,0 +1,36 @@ +import { removeShadowFrag } from "../glsl/fragmentshaders/removeshadow.js"; +import { CustomFilter } from "./CustomFilter.js"; +import { Anime } from "../Anime.js"; +import "./proto/FilterProto.js"; + +export class FilterRemoveShadow extends CustomFilter { + constructor(params) { + let { alphaTolerance } = Object.assign({}, FilterRemoveShadow.defaults, params); + + // using the default vertex shader and the specific fragment shader + super(undefined, removeShadowFrag); + + Object.assign(this, { + alphaTolerance, + }); + + this.zOrder = 10; + this.animated = {}; + this.setTMParams(params); + if (!this.dummy) { + this.anime = new Anime(this); + this.normalizeTMParams(); + } + } + + get alphaTolerance() { + return this.uniforms.alphaTolerance; + } + set alphaTolerance(value) { + this.uniforms.alphaTolerance = value; + } +} + +FilterRemoveShadow.defaults = { + alphaTolerance: 0.8, +}; diff --git a/src/fx/filters/FilterReplaceColor.js b/src/fx/filters/FilterReplaceColor.js new file mode 100644 index 0000000..679a00e --- /dev/null +++ b/src/fx/filters/FilterReplaceColor.js @@ -0,0 +1,18 @@ +import { Anime } from "../Anime.js"; +import "./proto/FilterProto.js"; + +export class FilterReplaceColor extends PIXI.filters.ColorReplaceFilter { + constructor(params) { + super(); + this.originalColor = [1, 0, 0]; + this.newColor = [0, 1, 0]; + this.epsilon = 0.7; + this.zOrder = 100; + this.animating = {}; + this.setTMParams(params); + if (!this.dummy) { + this.anime = new Anime(this); + this.normalizeTMParams(); + } + } +} diff --git a/src/fx/filters/FilterShockWave.js b/src/fx/filters/FilterShockWave.js new file mode 100644 index 0000000..8f7f04a --- /dev/null +++ b/src/fx/filters/FilterShockWave.js @@ -0,0 +1,29 @@ +import { Anime } from "../Anime.js"; +import "./proto/FilterProto.js"; + +export class FilterShockwave extends PIXI.filters.ShockwaveFilter { + constructor(params) { + super(); + this.enabled = false; + + this.time = 0; + this.amplitude = 5; + this.wavelength = 100; + this.speed = 50.0; + this.brightness = 1.5; + this.radius = 200; + + this.zOrder = 220; + this.animated = {}; + this.setTMParams(params); + if (!this.dummy) { + this.anime = new Anime(this); + this.normalizeTMParams(); + } + } + + handleTransform(state) { + this.center[0] = 0.5 * state.sourceFrame.width; + this.center[1] = 0.5 * state.sourceFrame.height; + } +} diff --git a/src/fx/filters/FilterSmoke.js b/src/fx/filters/FilterSmoke.js new file mode 100644 index 0000000..4d82dff --- /dev/null +++ b/src/fx/filters/FilterSmoke.js @@ -0,0 +1,81 @@ +import { innerSmoke } from "../glsl/fragmentshaders/smoke.js"; +import { customVertex2D } from "../glsl/vertexshaders/customvertex2D.js"; +import { CustomFilter } from "./CustomFilter.js"; +import { Anime } from "../Anime.js"; +import "./proto/FilterProto.js"; + +export class FilterSmoke extends CustomFilter { + constructor(params) { + let { time, color, blend, dimX, dimY } = Object.assign({}, FilterSmoke.defaults, params); + + // using specific vertex shader and fragment shader + super(customVertex2D, innerSmoke); + + this.uniforms.color = new Float32Array([1.0, 1.0, 1.0]); + this.uniforms.scale = new Float32Array([1.0, 1.0]); + + Object.assign(this, { + time, + color, + blend, + dimX, + dimY, + }); + + this.zOrder = 200; + this.animated = {}; + this.setTMParams(params); + if (!this.dummy) { + this.anime = new Anime(this); + this.normalizeTMParams(); + } + } + + get time() { + return this.uniforms.time; + } + + set time(value) { + this.uniforms.time = value; + } + + get color() { + return PIXI.utils.rgb2hex(this.uniforms.color); + } + + set color(value) { + new PIXI.Color(value).toRgbArray(this.uniforms.color); + } + + get blend() { + return this.uniforms.blend; + } + + set blend(value) { + this.uniforms.blend = Math.floor(value); + } + + get dimX() { + return this.uniforms.scale[0]; + } + + set dimX(value) { + this.uniforms.scale[0] = value; + } + + get dimY() { + return this.uniforms.scale[1]; + } + + set dimY(value) { + this.uniforms.scale[1] = value; + } +} + +FilterSmoke.defaults = { + time: 0, + color: 0xffffff, + blend: 13, + dimX: 1, + dimY: 1, +}; diff --git a/src/fx/filters/FilterSolarRipples.js b/src/fx/filters/FilterSolarRipples.js new file mode 100644 index 0000000..218737b --- /dev/null +++ b/src/fx/filters/FilterSolarRipples.js @@ -0,0 +1,90 @@ +import { solarRipples } from "../glsl/fragmentshaders/ripples.js"; +import { customVertex2D } from "../glsl/vertexshaders/customvertex2D.js"; +import { CustomFilter } from "./CustomFilter.js"; +import { Anime } from "../Anime.js"; +import "./proto/FilterProto.js"; + +export class FilterSolarRipples extends CustomFilter { + constructor(params) { + let { time, color, amplitude, intensity, alphaDiscard, _octaves } = Object.assign( + {}, + FilterSolarRipples.defaults, + params + ); + + if (typeof _octaves !== "number") _octaves = FilterSolarRipples.defaults._octave; + let fragment = solarRipples.replace(`#define OCTAVES 3`, `#define OCTAVES ${_octaves}`); + + // using specific vertex shader and fragment shader + super(customVertex2D, fragment); + + this.uniforms.color = new Float32Array([0.75, 0.75, 0.75]); + + Object.assign(this, { + time, + color, + amplitude, + intensity, + alphaDiscard, + }); + + this.zOrder = 250; + this.animated = {}; + this.setTMParams(params); + if (!this.dummy) { + this.anime = new Anime(this); + this.normalizeTMParams(); + } + } + + get time() { + return this.uniforms.time; + } + + set time(value) { + this.uniforms.time = value; + } + + get color() { + return PIXI.utils.rgb2hex(this.uniforms.color); + } + + set color(value) { + new PIXI.Color(value).toRgbArray(this.uniforms.color); + } + + get amplitude() { + return this.uniforms.amplitude; + } + + set amplitude(value) { + this.uniforms.amplitude = value; + } + + get intensity() { + return this.uniforms.intensity; + } + + set intensity(value) { + this.uniforms.intensity = value; + } + + get alphaDiscard() { + return this.uniforms.alphaDiscard; + } + + set alphaDiscard(value) { + if (!(value == null) && typeof value === "boolean") { + this.uniforms.alphaDiscard = value; + } + } +} + +FilterSolarRipples.defaults = { + time: 0.0, + color: 0xbbbbbb, + amplitude: 1, + intensity: 0.001, + alphaDiscard: false, + _octave: 3, +}; diff --git a/src/fx/filters/FilterSpiderWeb.js b/src/fx/filters/FilterSpiderWeb.js new file mode 100644 index 0000000..b91a62b --- /dev/null +++ b/src/fx/filters/FilterSpiderWeb.js @@ -0,0 +1,137 @@ +import { spiderWeb } from "../glsl/fragmentshaders/spiderweb.js"; +import { customVertex2D } from "../glsl/vertexshaders/customvertex2D.js"; +import { CustomFilter } from "./CustomFilter.js"; +import { Anime } from "../Anime.js"; +import "./proto/FilterProto.js"; + +export class FilterSpiderWeb extends CustomFilter { + constructor(params) { + let { time, anchorX, anchorY, color, thickness, div1, div2, tear, amplitude, alphaDiscard } = Object.assign( + {}, + FilterSpiderWeb.defaults, + params + ); + + // using specific vertex shader and fragment shader + super(customVertex2D, spiderWeb); + + this.uniforms.anchor = new Float32Array([0.5, -1.0]); + this.uniforms.color = new Float32Array([0.75, 0.75, 0.75]); + + Object.assign(this, { + time, + anchorX, + anchorY, + color, + thickness, + div1, + div2, + tear, + amplitude, + alphaDiscard, + }); + + this.zOrder = 260; + this.animated = {}; + this.setTMParams(params); + if (!this.dummy) { + this.anime = new Anime(this); + this.normalizeTMParams(); + } + } + + get time() { + return this.uniforms.time; + } + + set time(value) { + this.uniforms.time = value; + } + + get color() { + return PIXI.utils.rgb2hex(this.uniforms.color); + } + + set color(value) { + new PIXI.Color(value).toRgbArray(this.uniforms.color); + } + + get anchorX() { + return this.uniforms.anchor[0]; + } + + set anchorX(value) { + this.uniforms.anchor[0] = 0.5; + } + + get anchorY() { + return this.uniforms.anchor[1]; + } + + set anchorY(value) { + this.uniforms.anchor[1] = 0.5; + } + + get thickness() { + return this.uniforms.thickness; + } + + set thickness(value) { + this.uniforms.thickness = value; + } + + get tear() { + return this.uniforms.tear; + } + + set tear(value) { + this.uniforms.tear = value; + } + + get amplitude() { + return this.uniforms.amplitude; + } + + set amplitude(value) { + this.uniforms.amplitude = value; + } + + get div1() { + return this.uniforms.div1; + } + + set div1(value) { + this.uniforms.div1 = value; + } + + get div2() { + return this.uniforms.div2; + } + + set div2(value) { + this.uniforms.div2 = value; + } + + get alphaDiscard() { + return this.uniforms.alphaDiscard; + } + + set alphaDiscard(value) { + if (!(value == null) && typeof value === "boolean") { + this.uniforms.alphaDiscard = value; + } + } +} + +FilterSpiderWeb.defaults = { + time: 0.0, + anchorX: 0.5, + anchorY: 0.5, + color: 0xbbbbbb, + thickness: 1, + div1: 10, + div2: 10, + tear: 0.54, + amplitude: 0.8, + alphaDiscard: false, +}; diff --git a/src/fx/filters/FilterSplash.js b/src/fx/filters/FilterSplash.js new file mode 100644 index 0000000..7b9745f --- /dev/null +++ b/src/fx/filters/FilterSplash.js @@ -0,0 +1,157 @@ +import { splash } from "../glsl/fragmentshaders/splash.js"; +import { customVertex2D } from "../glsl/vertexshaders/customvertex2D.js"; +import { CustomFilter } from "./CustomFilter.js"; +import { Anime } from "../Anime.js"; +import "./proto/FilterProto.js"; + +export class FilterSplash extends CustomFilter { + constructor(params) { + let { time, seed, spread, splashFactor, color, dimX, dimY, blend, cut, textureAlphaBlend, anchorX, anchorY } = + Object.assign({}, FilterSplash.defaults, params); + + // using specific vertex shader and fragment shader + super(customVertex2D, splash); + + this.uniforms.color = new Float32Array([1.0, 0.05, 0.05]); + this.uniforms.dimensions = new Float32Array([1.0, 1.0]); + this.uniforms.anchor = new Float32Array([0.0, 0.0]); + + Object.assign(this, { + time, + seed, + spread, + splashFactor, + color, + dimX, + dimY, + blend, + cut, + textureAlphaBlend, + anchorX, + anchorY, + }); + + this.zOrder = 5; + this.animated = {}; + this.setTMParams(params); + if (!this.dummy) { + this.anime = new Anime(this); + this.normalizeTMParams(); + } + } + + get time() { + return this.uniforms.time; + } + + set time(value) { + this.uniforms.time = value; + } + + get color() { + return PIXI.utils.rgb2hex(this.uniforms.color); + } + + set color(value) { + new PIXI.Color(value).toRgbArray(this.uniforms.color); + } + + get seed() { + return this.uniforms.seed; + } + + set seed(value) { + this.uniforms.seed = value; + } + + get spread() { + return this.uniforms.spread; + } + + set spread(value) { + this.uniforms.spread = value; + } + + get splashFactor() { + return this.uniforms.splashFactor; + } + + set splashFactor(value) { + this.uniforms.splashFactor = value; + } + + get dimX() { + return this.uniforms.dimensions[0]; + } + + set dimX(value) { + this.uniforms.dimensions[0] = value; + } + + get dimY() { + return this.uniforms.dimensions[1]; + } + + set dimY(value) { + this.uniforms.dimensions[1] = value; + } + + get anchorY() { + return this.uniforms.anchor[1] + 0.5; + } + + set anchorY(value) { + this.uniforms.anchor[1] = value - 0.5; + } + + get anchorX() { + return this.uniforms.anchor[0] + 0.5; + } + + set anchorX(value) { + this.uniforms.anchor[0] = value - 0.5; + } + + get blend() { + return this.uniforms.blend; + } + + set blend(value) { + this.uniforms.blend = Math.floor(value); + } + + get cut() { + return this.uniforms.cut; + } + + set cut(value) { + if (!(value == null) && typeof value === "boolean") { + this.uniforms.cut = value; + } + } + + get textureAlphaBlend() { + return this.uniforms.textureAlphaBlend; + } + + set textureAlphaBlend(value) { + if (!(value == null) && typeof value === "boolean") { + this.uniforms.textureAlphaBlend = value; + } + } +} + +FilterSplash.defaults = { + time: Math.random() * 2000, + color: 0xf00505, + seed: 0.1, + spread: 5, + splashFactor: 2, + dimX: 1, + dimY: 1, + blend: 8, + cut: false, + textureAlphaBlend: false, + anchorX: 0.5, + anchorY: 0.5, +}; diff --git a/src/fx/filters/FilterSprite.js b/src/fx/filters/FilterSprite.js new file mode 100644 index 0000000..66ff5df --- /dev/null +++ b/src/fx/filters/FilterSprite.js @@ -0,0 +1,407 @@ +import { sprite } from "../glsl/fragmentshaders/sprite.js"; +import { customVertex2DSampler } from "../glsl/vertexshaders/customvertex2DSampler.js"; +import { CustomFilter } from "./CustomFilter.js"; +import { Anime } from "../Anime.js"; +import "./proto/FilterProto.js"; +import { fixPath } from "../../module.js"; + +export class FilterSprite extends CustomFilter { + tex = null; + + constructor(params) { + let { + imagePath, + color, + colorize, + inverse, + alpha, + alphaDiscard, + repeat, + top, + rotation, + twRadiusPercent, + twAngle, + twRotation, + bpRadiusPercent, + bpStrength, + scale, + scaleX, + scaleY, + translationX, + translationY, + play, + loop, + maintainAspectRatio, + maintainScale, + } = Object.assign({}, FilterSprite.defaults, params); + + const targetSpriteMatrix = new PIXI.Matrix(); + + // using specific vertex shader and fragment shader + super(customVertex2DSampler, sprite); + + // vertex uniforms + this.uniforms.targetUVMatrix = targetSpriteMatrix; + + // fragment uniforms + this.uniforms.inputClampTarget = new Float32Array([0, 0, 0, 0]); + this.uniforms.color = new Float32Array([0.0, 0.0, 0.0]); + this.uniforms.scale = new Float32Array([1.0, 1.0]); + this.uniforms.translation = new Float32Array([0.0, 0.0]); + + // to store sprite matrix from the filter manager (and send to vertex) + this.targetSpriteMatrix = targetSpriteMatrix; + + Object.assign(this, { + imagePath: fixPath(imagePath), + color, + colorize, + inverse, + alpha, + alphaDiscard, + repeat, + top, + rotation, + twRadiusPercent, + twAngle, + twRotation, + bpRadiusPercent, + bpStrength, + scale, + scaleX, + scaleY, + translationX, + translationY, + play, + loop, + maintainAspectRatio, + maintainScale, + }); + + this.zOrder = 0; + this.autoFit = false; + this.animated = {}; + this.setTMParams(params); + if (!this.dummy) { + this.anime = new Anime(this); + this.normalizeTMParams(); + } + } + + setTMParams(params) { + super.setTMParams(params); + if (!this.dummy && "imagePath" in params) { + this.assignTexture(); + } + } + + _play = true; + _loop = true; + _maintainAspectRatio = false; + _maintainScale = false; + + get play() { + return this._play; + } + + set play(value) { + if (!(value == null) && typeof value === "boolean") { + this._play = value; + this._playVideo(this._play); + } + } + + get loop() { + return this._loop; + } + + set loop(value) { + if (!(value == null) && typeof value === "boolean") { + this._loop = value; + this._playVideo(this._play); + } + } + + get maintainAspectRatio() { + return this._maintainAspectRatio; + } + + set maintainAspectRatio(value) { + if (!(value == null) && typeof value === "boolean") { + this._maintainAspectRatio = value; + } + } + + get maintainScale() { + return this._maintainScale; + } + + set maintainScale(value) { + if (!(value == null) && typeof value === "boolean") { + this._maintainScale = value; + } + } + + get color() { + return PIXI.utils.rgb2hex(this.uniforms.color); + } + + set color(value) { + new PIXI.Color(value).toRgbArray(this.uniforms.color); + } + + get colorize() { + return this.uniforms.colorize; + } + + set colorize(value) { + if (!(value == null) && typeof value === "boolean") { + this.uniforms.colorize = value; + } + } + + get inverse() { + return this.uniforms.inverse; + } + + set inverse(value) { + if (!(value == null) && typeof value === "boolean") { + this.uniforms.inverse = value; + } + } + + get alpha() { + return this.uniforms.alpha; + } + + set alpha(value) { + this.uniforms.alpha = value; + } + + get alphaDiscard() { + return this.uniforms.alphaDiscard; + } + + set alphaDiscard(value) { + if (!(value == null) && typeof value === "boolean") { + this.uniforms.alphaDiscard = value; + } + } + + get repeat() { + return this.uniforms.repeat; + } + + set repeat(value) { + if (!(value == null) && typeof value === "boolean") { + this.uniforms.repeat = value; + } + } + + get top() { + return this.uniforms.top; + } + + set top(value) { + if (!(value == null) && typeof value === "boolean") { + this.uniforms.top = value; + } + } + + get rotation() { + return this.uniforms.rotation; + } + + set rotation(value) { + this.uniforms.rotation = value; + } + + get twRadiusPercent() { + return this.uniforms.twRadius * 200; + } + + set twRadiusPercent(value) { + this.uniforms.twRadius = value / 200; + } + + get twAngle() { + return this.uniforms.twAngle; + } + + set twAngle(value) { + this.uniforms.twAngle = value; + } + + get twRotation() { + return this.uniforms.twAngle * (180 / Math.PI); + } + + set twRotation(value) { + this.uniforms.twAngle = value * (Math.PI / 180); + } + + get bpRadiusPercent() { + return this.uniforms.bpRadius * 200; + } + + set bpRadiusPercent(value) { + this.uniforms.bpRadius = value / 200; + } + + get bpStrength() { + return this.uniforms.bpStrength; + } + + set bpStrength(value) { + this.uniforms.bpStrength = value; + } + + get scale() { + // a little hack (we get only x) + return this.uniforms.scale[0]; + } + + set scale(value) { + this.uniforms.scale[1] = this.uniforms.scale[0] = value; + } + + get scaleX() { + return this.uniforms.scale[0]; + } + + set scaleX(value) { + this.uniforms.scale[0] = value; + } + + get scaleY() { + return this.uniforms.scale[1]; + } + + set scaleY(value) { + this.uniforms.scale[1] = value; + } + + get translationX() { + return this.uniforms.translation[0]; + } + + set translationX(value) { + this.uniforms.translation[0] = value; + } + + get translationY() { + return this.uniforms.translation[1]; + } + + set translationY(value) { + this.uniforms.translation[1] = value; + } + + get uSamplerTarget() { + return this.uniforms.uSamplerTarget; + } + + set uSamplerTarget(value) { + this.uniforms.uSamplerTarget = value; + } + + async _playVideo(value) { + // Play if baseTexture resource is a video + if (this.tex) { + const source = getProperty(this.tex, "baseTexture.resource.source"); + if (source && source.tagName === "VIDEO") { + if (isNaN(source.duration)) { + await new Promise((resolve) => { + source.onloadedmetadata = () => resolve(); + }); + } + if (value) game.video.play(source, { loop: this._loop, volume: 0 }); + else game.video.stop(source); + } + } + } + + assignTexture() { + if (this.hasOwnProperty("imagePath")) { + // Destroy the previous sprite + if (this.targetSprite && !this.targetSprite.destroyed) + this.targetSprite.destroy({ children: true, texture: false, baseTexture: false }); + this.tex = PIXI.Texture.from(this.imagePath); + + let sprite = new PIXI.Sprite(this.tex); + + sprite.renderable = false; + if (this.placeableImg._texture) { + sprite.width = this.placeableImg._texture.baseTexture.realWidth; + sprite.height = this.placeableImg._texture.baseTexture.realHeight; + sprite.anchor.set(0.5); + } else { + sprite.width = this.placeableImg.width; + sprite.height = this.placeableImg.height; + } + + this.targetSprite = sprite; + this.uSamplerTarget = sprite._texture; + this.placeableImg.addChild(sprite); + + this._playVideo(this._play); + } + } + + // override + apply(filterManager, input, output, clear) { + const targetSprite = this.targetSprite; + const tex = targetSprite._texture; + + if (tex.valid) { + if (!tex.uvMatrix) tex.uvMatrix = new PIXI.TextureMatrix(tex, 0.0); + tex.uvMatrix.update(); + + this.uniforms.uSamplerTarget = tex; + if (this.maintainScale) { + let pScale = targetSprite.parent.scale; + targetSprite.scale.set(1 / pScale.x, 1 / pScale.y); + } + + let w = targetSprite.worldTransform; + if (this.maintainAspectRatio) { + let scale = Math.min(w.a, w.d); + w.set(scale, w.b, w.c, scale, w.tx, w.ty); + } + + this.uniforms.targetUVMatrix = filterManager.calculateSpriteMatrix(this.targetSpriteMatrix, targetSprite); + this.uniforms.inputClampTarget = tex.uvMatrix.uClampFrame; + } + + super.apply(filterManager, input, output, clear); + } + + // override + destroy() { + super.destroy(); + if (!this.targetSprite.destroyed) this.targetSprite.destroy({ children: true, texture: false, baseTexture: false }); + } +} + +FilterSprite.defaults = { + color: 0x000000, + colorize: false, + inverse: false, + alpha: 1, + alphaDiscard: false, + repeat: false, + top: false, + rotation: 0.0, + twRadiusPercent: 0, + twAngle: 0, + bpRadiusPercent: 0, + bpStrength: 0, + scaleX: 1, + scaleY: 1, + translationX: 0, + translationY: 0, + play: true, + loop: true, + maintainAspectRatio: false, + maintainScale: false, +}; diff --git a/src/fx/filters/FilterSpriteMask.js b/src/fx/filters/FilterSpriteMask.js new file mode 100644 index 0000000..fccc72b --- /dev/null +++ b/src/fx/filters/FilterSpriteMask.js @@ -0,0 +1,344 @@ +import { spritemask } from "../glsl/fragmentshaders/spritemask.js"; +import { customVertex2DSampler } from "../glsl/vertexshaders/customvertex2DSampler.js"; +import { CustomFilter } from "./CustomFilter.js"; +import { Anime } from "../Anime.js"; +import "./proto/FilterProto.js"; +import { fixPath } from "../../module.js"; + +export class FilterSpriteMask extends CustomFilter { + tex = null; + + constructor(params) { + let { + imagePath, + alpha, + repeat, + rotation, + twRadiusPercent, + twAngle, + twRotation, + bpRadiusPercent, + bpStrength, + scale, + scaleX, + scaleY, + translationX, + translationY, + play, + loop, + maintainAspectRatio, + maintainScale, + } = Object.assign({}, FilterSpriteMask.defaults, params); + + const targetSpriteMatrix = new PIXI.Matrix(); + + // using specific vertex shader and fragment shader + super(customVertex2DSampler, spritemask); + + // vertex uniforms + this.uniforms.targetUVMatrix = targetSpriteMatrix; + + // fragment uniforms + this.uniforms.inputClampTarget = new Float32Array([0, 0, 0, 0]); + this.uniforms.color = new Float32Array([0.0, 0.0, 0.0]); + this.uniforms.scale = new Float32Array([1.0, 1.0]); + this.uniforms.translation = new Float32Array([0.0, 0.0]); + + // to store sprite matrix from the filter manager (and send to vertex) + this.targetSpriteMatrix = targetSpriteMatrix; + + Object.assign(this, { + imagePath: fixPath(imagePath), + alpha, + repeat, + rotation, + twRadiusPercent, + twAngle, + twRotation, + bpRadiusPercent, + bpStrength, + scale, + scaleX, + scaleY, + translationX, + translationY, + play, + loop, + maintainAspectRatio, + maintainScale, + }); + + this.zOrder = 0; + this.autoFit = false; + this.animated = {}; + this.setTMParams(params); + if (!this.dummy) { + this.anime = new Anime(this); + this.normalizeTMParams(); + } + } + + setTMParams(params) { + super.setTMParams(params); + if (!this.dummy && "imagePath" in params) { + this.assignTexture(); + } + } + + _play = true; + _loop = true; + _maintainAspectRatio = false; + _maintainScale = false; + + get play() { + return this._play; + } + + set play(value) { + if (!(value == null) && typeof value === "boolean") { + this._play = value; + this._playVideo(this._play); + } + } + + get loop() { + return this._loop; + } + + set loop(value) { + if (!(value == null) && typeof value === "boolean") { + this._loop = value; + this._playVideo(this._play); + } + } + + get maintainAspectRatio() { + return this._maintainAspectRatio; + } + + set maintainAspectRatio(value) { + if (!(value == null) && typeof value === "boolean") { + this._maintainAspectRatio = value; + } + } + + get maintainScale() { + return this._maintainScale; + } + + set maintainScale(value) { + if (!(value == null) && typeof value === "boolean") { + this._maintainScale = value; + } + } + + get alpha() { + return this.uniforms.alpha; + } + + set alpha(value) { + this.uniforms.alpha = value; + } + + get repeat() { + return this.uniforms.repeat; + } + + set repeat(value) { + if (!(value == null) && typeof value === "boolean") { + this.uniforms.repeat = value; + } + } + + get rotation() { + return this.uniforms.rotation; + } + + set rotation(value) { + this.uniforms.rotation = value; + } + + get twRadiusPercent() { + return this.uniforms.twRadius * 200; + } + + set twRadiusPercent(value) { + this.uniforms.twRadius = value / 200; + } + + get twAngle() { + return this.uniforms.twAngle; + } + + set twAngle(value) { + this.uniforms.twAngle = value; + } + + get twRotation() { + return this.uniforms.twAngle * (180 / Math.PI); + } + + set twRotation(value) { + this.uniforms.twAngle = value * (Math.PI / 180); + } + + get bpRadiusPercent() { + return this.uniforms.bpRadius * 200; + } + + set bpRadiusPercent(value) { + this.uniforms.bpRadius = value / 200; + } + + get bpStrength() { + return this.uniforms.bpStrength; + } + + set bpStrength(value) { + this.uniforms.bpStrength = value; + } + + get scale() { + // a little hack (we get only x) + return this.uniforms.scale[0]; + } + + set scale(value) { + this.uniforms.scale[1] = this.uniforms.scale[0] = value; + } + + get scaleX() { + return this.uniforms.scale[0]; + } + + set scaleX(value) { + this.uniforms.scale[0] = value; + } + + get scaleY() { + return this.uniforms.scale[1]; + } + + set scaleY(value) { + this.uniforms.scale[1] = value; + } + + get translationX() { + return this.uniforms.translation[0]; + } + + set translationX(value) { + this.uniforms.translation[0] = value; + } + + get translationY() { + return this.uniforms.translation[1]; + } + + set translationY(value) { + this.uniforms.translation[1] = value; + } + + get uSamplerTarget() { + return this.uniforms.uSamplerTarget; + } + + set uSamplerTarget(value) { + this.uniforms.uSamplerTarget = value; + } + + async _playVideo(value) { + // Play if baseTexture resource is a video + if (this.tex) { + const source = getProperty(this.tex, "baseTexture.resource.source"); + if (source && source.tagName === "VIDEO") { + if (isNaN(source.duration)) { + await new Promise((resolve) => { + source.onloadedmetadata = () => resolve(); + }); + } + if (value) game.video.play(source, { loop: this._loop, volume: 0 }); + else game.video.stop(source); + } + } + } + + assignTexture() { + if (this.hasOwnProperty("imagePath")) { + // Destroy the previous sprite + if (this.targetSprite && !this.targetSprite.destroyed) + this.targetSprite.destroy({ children: true, texture: false, baseTexture: false }); + this.tex = PIXI.Texture.from(this.imagePath); + + let sprite = new PIXI.Sprite(this.tex); + + sprite.renderable = false; + if (this.placeableImg._texture) { + sprite.width = this.placeableImg._texture.baseTexture.realWidth; + sprite.height = this.placeableImg._texture.baseTexture.realHeight; + sprite.anchor.set(0.5); + } else { + sprite.width = this.placeableImg.width; + sprite.height = this.placeableImg.height; + } + + this.targetSprite = sprite; + this.uSamplerTarget = sprite._texture; + this.placeableImg.addChild(sprite); + + this._playVideo(this._play); + } + } + + // override + apply(filterManager, input, output, clear) { + const targetSprite = this.targetSprite; + const tex = targetSprite._texture; + + if (tex.valid) { + if (!tex.uvMatrix) tex.uvMatrix = new PIXI.TextureMatrix(tex, 0.0); + tex.uvMatrix.update(); + + this.uniforms.uSamplerTarget = tex; + if (this.maintainScale) { + let pScale = targetSprite.parent.scale; + targetSprite.scale.set(1 / pScale.x, 1 / pScale.y); + } + + let w = targetSprite.worldTransform; + if (this.maintainAspectRatio) { + let scale = Math.min(w.a, w.d); + w.set(scale, w.b, w.c, scale, w.tx, w.ty); + } + + this.uniforms.targetUVMatrix = filterManager.calculateSpriteMatrix(this.targetSpriteMatrix, targetSprite); + this.uniforms.inputClampTarget = tex.uvMatrix.uClampFrame; + } + + super.apply(filterManager, input, output, clear); + } + + // override + destroy() { + super.destroy(); + if (!this.targetSprite.destroyed) this.targetSprite.destroy({ children: true, texture: false, baseTexture: false }); + } +} + +FilterSpriteMask.defaults = { + alpha: 1, + repeat: false, + rotation: 0.0, + twRadiusPercent: 0, + twAngle: 0, + bpRadiusPercent: 0, + bpStrength: 0, + scaleX: 1, + scaleY: 1, + translationX: 0, + translationY: 0, + play: true, + loop: true, + maintainAspectRatio: false, + maintainScale: false, +}; diff --git a/src/fx/filters/FilterTransform.js b/src/fx/filters/FilterTransform.js new file mode 100644 index 0000000..8d7ea95 --- /dev/null +++ b/src/fx/filters/FilterTransform.js @@ -0,0 +1,175 @@ +import { matrix } from "../glsl/fragmentshaders/matrix.js"; +import { customVertex2D } from "../glsl/vertexshaders/customvertex2D.js"; +import { CustomFilter } from "./CustomFilter.js"; +import { Anime } from "../Anime.js"; +import "./proto/FilterProto.js"; + +export class FilterTransform extends CustomFilter { + constructor(params) { + let { + rotation, + twRadiusPercent, + twAngle, + twRotation, + bpRadiusPercent, + bpStrength, + scale, + scaleX, + scaleY, + pivotX, + pivotY, + translationX, + translationY, + } = Object.assign({}, FilterTransform.defaults, params); + + super(customVertex2D, matrix); + + this.uniforms.scale = new Float32Array([1.0, 1.0]); + this.uniforms.pivot = new Float32Array([0.5, 0.5]); + this.uniforms.translation = new Float32Array([0.0, 0.0]); + + Object.assign(this, { + rotation, + twRadiusPercent, + twAngle, + twRotation, + bpRadiusPercent, + bpStrength, + scale, + scaleX, + scaleY, + pivotX, + pivotY, + translationX, + translationY, + }); + + this.zOrder = 1000; + this.autoFit = false; + this.animated = {}; + this.setTMParams(params); + if (!this.dummy) { + this.anime = new Anime(this); + this.normalizeTMParams(); + } + } + + get rotation() { + return this.uniforms.rotation; + } + + set rotation(value) { + this.uniforms.rotation = value; + } + + get twRadiusPercent() { + return this.uniforms.twRadius * 200; + } + + set twRadiusPercent(value) { + this.uniforms.twRadius = value / 200; + } + + get twAngle() { + return this.uniforms.twAngle; + } + + set twAngle(value) { + this.uniforms.twAngle = value; + } + + get twRotation() { + return this.uniforms.twAngle * (180 / Math.PI); + } + + set twRotation(value) { + this.uniforms.twAngle = value * (Math.PI / 180); + } + + get bpRadiusPercent() { + return this.uniforms.bpRadius * 200; + } + + set bpRadiusPercent(value) { + this.uniforms.bpRadius = value / 200; + } + + get bpStrength() { + return this.uniforms.bpStrength; + } + + set bpStrength(value) { + this.uniforms.bpStrength = value; + } + + get scale() { + // a little hack (we get only x) + return this.uniforms.scale[0]; + } + + set scale(value) { + this.uniforms.scale[1] = this.uniforms.scale[0] = value; + } + + get scaleX() { + return this.uniforms.scale[0]; + } + + set scaleX(value) { + this.uniforms.scale[0] = value; + } + + get scaleY() { + return this.uniforms.scale[1]; + } + + set scaleY(value) { + this.uniforms.scale[1] = value; + } + + get pivotX() { + return this.uniforms.pivot[0]; + } + + set pivotX(value) { + this.uniforms.pivot[0] = value; + } + + get pivotY() { + return this.uniforms.pivot[1]; + } + + set pivotY(value) { + this.uniforms.pivot[1] = value; + } + + get translationX() { + return this.uniforms.translation[0]; + } + + set translationX(value) { + this.uniforms.translation[0] = value; + } + + get translationY() { + return this.uniforms.translation[1]; + } + + set translationY(value) { + this.uniforms.translation[1] = value; + } +} + +FilterTransform.defaults = { + rotation: 0.0, + twRadiusPercent: 0, + twAngle: 0, + bpRadiusPercent: 0, + bpStrength: 0, + scaleX: 1, + scaleY: 1, + pivotX: 0.5, + pivotY: 0.5, + translationX: 0, + translationY: 0, +}; diff --git a/src/fx/filters/FilterTwist.js b/src/fx/filters/FilterTwist.js new file mode 100644 index 0000000..3dd56bc --- /dev/null +++ b/src/fx/filters/FilterTwist.js @@ -0,0 +1,30 @@ +import { Anime } from "../Anime.js"; +import "./proto/FilterProto.js"; + +export class FilterTwist extends PIXI.filters.TwistFilter { + constructor(params) { + super(); + this.enabled = false; + this.radiusPercent = 50; + this.angle = 4; + this.zOrder = 240; + this.animated = {}; + this.offset = [0, 0]; + this.autoFit = false; + this.setTMParams(params); + if (!this.dummy) { + this.anime = new Anime(this); + this.normalizeTMParams(); + } + } + + handleTransform() { + this.offset[0] = this.placeableImg.worldTransform.tx; + this.offset[1] = this.placeableImg.worldTransform.ty; + this.radius = + (Math.max(this.placeableImg.width, this.placeableImg.height) * + this.targetPlaceable.worldTransform.a * + this.radiusPercent) / + 200; + } +} diff --git a/src/fx/filters/FilterWaves.js b/src/fx/filters/FilterWaves.js new file mode 100644 index 0000000..6b6318c --- /dev/null +++ b/src/fx/filters/FilterWaves.js @@ -0,0 +1,127 @@ +import { magicWaves } from "../glsl/fragmentshaders/waves.js"; +import { customVertex2D } from "../glsl/vertexshaders/customvertex2D.js"; +import { CustomFilter } from "./CustomFilter.js"; +import { Anime } from "../Anime.js"; +import "./proto/FilterProto.js"; + +export class FilterWaves extends CustomFilter { + constructor(params) { + let { time, color, inward, frequency, strength, minIntensity, maxIntensity, anchorX, anchorY } = Object.assign( + {}, + FilterWaves.defaults, + params + ); + + // using specific vertex shader and fragment shader + super(customVertex2D, magicWaves); + + this.uniforms.color = new Float32Array([1.0, 1.0, 1.0]); + this.uniforms.anchor = new Float32Array([0.5, 0.5]); + + Object.assign(this, { + time, + color, + inward, + frequency, + strength, + minIntensity, + maxIntensity, + anchorX, + anchorY, + }); + + this.zOrder = 280; + this.animated = {}; + this.setTMParams(params); + if (!this.dummy) { + this.anime = new Anime(this); + this.normalizeTMParams(); + } + } + + get time() { + return this.uniforms.time; + } + + set time(value) { + this.uniforms.time = value; + } + + get color() { + return PIXI.utils.rgb2hex(this.uniforms.color); + } + + set color(value) { + new PIXI.Color(value).toRgbArray(this.uniforms.color); + } + + get inward() { + return this.uniforms.inward; + } + + set inward(value) { + if (!(value == null) && typeof value === "boolean") { + this.uniforms.inward = value; + } + } + + get anchorX() { + return this.uniforms.anchor[0]; + } + + set anchorX(value) { + this.uniforms.anchor[0] = value; + } + + get anchorY() { + return this.uniforms.anchor[1]; + } + + set anchorY(value) { + this.uniforms.anchor[1] = value; + } + + get frequency() { + return this.uniforms.frequency; + } + + set frequency(value) { + this.uniforms.frequency = value; + } + + get strength() { + return this.uniforms.strength; + } + + set strength(value) { + this.uniforms.strength = value; + } + + get minIntensity() { + return this.uniforms.minIntensity; + } + + set minIntensity(value) { + this.uniforms.minIntensity = value; + } + + get maxIntensity() { + return this.uniforms.maxIntensity; + } + + set maxIntensity(value) { + this.uniforms.maxIntensity = value; + } +} + +FilterWaves.defaults = { + time: 0, + color: 0xffffff, + inward: false, + frequency: 35, + strength: 0.01, + minIntensity: 1.2, + maxIntensity: 3.5, + anchorX: 0.5, + anchorY: 0.5, +}; diff --git a/src/fx/filters/FilterXFire.js b/src/fx/filters/FilterXFire.js new file mode 100644 index 0000000..fa37a20 --- /dev/null +++ b/src/fx/filters/FilterXFire.js @@ -0,0 +1,207 @@ +import { burnXFire } from "../glsl/fragmentshaders/xfire.js"; +import { customVertex2D } from "../glsl/vertexshaders/customvertex2D.js"; +import { CustomFilter } from "./CustomFilter.js"; +import { Anime } from "../Anime.js"; +import "./proto/FilterProto.js"; + +export class FilterXFire extends CustomFilter { + constructor(params) { + let { + time, + color, + color1, + color2, + color3, + color4, + amplitude, + dispersion, + blend, + scaleX, + scaleY, + alphaDiscard, + discardThreshold, + chromatic, + inlay, + } = Object.assign({}, FilterXFire.defaults, params); + + // using specific vertex shader and fragment shader + super(customVertex2D, burnXFire); + + this.uniforms.color = new Float32Array([1.0, 1.0, 1.0]); + this.uniforms.color1 = new Float32Array([1.0, 1.0, 1.0]); + this.uniforms.color2 = new Float32Array([1.0, 1.0, 1.0]); + this.uniforms.color3 = new Float32Array([1.0, 1.0, 1.0]); + this.uniforms.color4 = new Float32Array([1.0, 1.0, 1.0]); + this.uniforms.scale = new Float32Array([1.0, 1.0]); + + Object.assign(this, { + time, + color, + color1, + color2, + color3, + color4, + amplitude, + dispersion, + blend, + scaleX, + scaleY, + alphaDiscard, + discardThreshold, + chromatic, + inlay, + }); + + this.zOrder = 145; + this.animated = {}; + this.setTMParams(params); + if (!this.dummy) { + this.anime = new Anime(this); + this.normalizeTMParams(); + } + } + + get time() { + return this.uniforms.time; + } + + set time(value) { + this.uniforms.time = value; + } + + get color() { + return PIXI.utils.rgb2hex(this.uniforms.color); + } + + set color(value) { + new PIXI.Color(value).toRgbArray(this.uniforms.color); + } + + get color1() { + return PIXI.utils.rgb2hex(this.uniforms.color1); + } + + set color1(value) { + new PIXI.Color(value).toRgbArray(this.uniforms.color1); + } + + get color2() { + return PIXI.utils.rgb2hex(this.uniforms.color2); + } + + set color2(value) { + new PIXI.Color(value).toRgbArray(this.uniforms.color2); + } + + get color3() { + return PIXI.utils.rgb2hex(this.uniforms.color3); + } + + set color3(value) { + new PIXI.Color(value).toRgbArray(this.uniforms.color3); + } + + get color4() { + return PIXI.utils.rgb2hex(this.uniforms.color4); + } + + set color4(value) { + new PIXI.Color(value).toRgbArray(this.uniforms.color4); + } + + get amplitude() { + return this.uniforms.amplitude; + } + + set amplitude(value) { + this.uniforms.amplitude = value; + } + + get dispersion() { + return this.uniforms.dispersion; + } + + set dispersion(value) { + this.uniforms.dispersion = value; + } + + get blend() { + return this.uniforms.blend; + } + + set blend(value) { + this.uniforms.blend = Math.floor(value); + } + + get scaleX() { + return this.uniforms.scale[0]; + } + + set scaleX(value) { + this.uniforms.scale[0] = value; + } + + get scaleY() { + return this.uniforms.scale[1]; + } + + set scaleY(value) { + this.uniforms.scale[1] = value; + } + + get alphaDiscard() { + return this.uniforms.alphaDiscard; + } + + set alphaDiscard(value) { + if (!(value == null) && typeof value === "boolean") { + this.uniforms.alphaDiscard = value; + } + } + + get discardThreshold() { + return this.uniforms.discardThreshold; + } + + set discardThreshold(value) { + this.uniforms.discardThreshold = value; + } + + get chromatic() { + return this.uniforms.chromatic; + } + + set chromatic(value) { + if (!(value == null) && typeof value === "boolean") { + this.uniforms.chromatic = value; + } + } + + get inlay() { + return this.uniforms.inlay; + } + + set inlay(value) { + if (!(value == null) && typeof value === "boolean") { + this.uniforms.inlay = value; + } + } +} + +FilterXFire.defaults = { + time: 0, + color: 0x000000, + color1: 0x250000, + color2: 0xb20000, + color3: 0x330000, + color4: 0xffe500, + amplitude: 1, + dispersion: 0.25, + blend: 2, + scaleX: 1, + scaleY: 1, + discardThreshold: 0.1, + alphaDiscard: false, + chromatic: false, + inlay: false, +}; diff --git a/src/fx/filters/FilterXFog.js b/src/fx/filters/FilterXFog.js new file mode 100644 index 0000000..49b43fd --- /dev/null +++ b/src/fx/filters/FilterXFog.js @@ -0,0 +1,61 @@ +import { xFog } from "../glsl/fragmentshaders/xfog.js"; +import { customVertex2D } from "../glsl/vertexshaders/customvertex2D.js"; +import { CustomFilter } from "./CustomFilter.js"; +import { Anime } from "../Anime.js"; + +export class FilterXFog extends CustomFilter { + constructor(params) { + let { time, color, alphaDiscard } = Object.assign({}, FilterXFog.defaults, params); + + // specific vertex and fragment shaders + super(customVertex2D, xFog); + + this.uniforms.color = new Float32Array([1.0, 0.4, 0.1, 0.55]); + + Object.assign(this, { + time, + color, + alphaDiscard, + }); + + this.zOrder = 230; + this.animated = {}; + this.setTMParams(params); + if (!this.dummy) { + this.anime = new Anime(this); + this.normalizeTMParams(); + } + } + + get time() { + return this.uniforms.time; + } + + set time(value) { + this.uniforms.time = value; + } + + get color() { + return PIXI.utils.rgb2hex(this.uniforms.color); + } + + set color(value) { + new PIXI.Color(value).toRgbArray(this.uniforms.color); + } + + get alphaDiscard() { + return this.uniforms.alphaDiscard; + } + + set alphaDiscard(value) { + if (!(value == null) && typeof value === "boolean") { + this.uniforms.alphaDiscard = value; + } + } +} + +FilterXFog.defaults = { + time: 0.0, + color: 0xffffff, + alphaDiscard: false, +}; diff --git a/src/fx/filters/FilterXRays.js b/src/fx/filters/FilterXRays.js new file mode 100644 index 0000000..c39ef09 --- /dev/null +++ b/src/fx/filters/FilterXRays.js @@ -0,0 +1,126 @@ +import { xRay } from "../glsl/fragmentshaders/xray.js"; +import { customVertex2D } from "../glsl/vertexshaders/customvertex2D.js"; +import { CustomFilter } from "./CustomFilter.js"; +import { Anime } from "../Anime.js"; +import "./proto/FilterProto.js"; + +export class FilterXRays extends CustomFilter { + constructor(params) { + let { time, color, divisor, intensity, blend, anchorX, anchorY, dimX, dimY } = Object.assign( + {}, + FilterXRays.defaults, + params + ); + + // using specific vertex shader and fragment shader + super(customVertex2D, xRay); + + this.uniforms.color = new Float32Array([1.0, 0.4, 0.1]); + this.uniforms.anchor = new Float32Array([0.5, -1.0]); + this.uniforms.dimensions = new Float32Array([1.0, 1.0]); + + Object.assign(this, { + time, + color, + divisor, + intensity, + blend, + anchorX, + anchorY, + dimX, + dimY, + }); + + this.zOrder = 130; + this.animated = {}; + this.setTMParams(params); + if (!this.dummy) { + this.anime = new Anime(this); + this.normalizeTMParams(); + } + } + + get time() { + return this.uniforms.time; + } + + set time(value) { + this.uniforms.time = value; + } + + get color() { + return PIXI.utils.rgb2hex(this.uniforms.color); + } + + set color(value) { + new PIXI.Color(value).toRgbArray(this.uniforms.color); + } + + get divisor() { + return this.uniforms.divisor; + } + + set divisor(value) { + this.uniforms.divisor = value; + } + + get intensity() { + return this.uniforms.intensity; + } + + set intensity(value) { + this.uniforms.intensity = value; + } + + get blend() { + return this.uniforms.blend; + } + + set blend(value) { + this.uniforms.blend = Math.floor(value); + } + + get anchorX() { + return this.uniforms.anchor[0]; + } + + set anchorX(value) { + this.uniforms.anchor[0] = value; + } + + get anchorY() { + return this.uniforms.anchor[1]; + } + + set anchorY(value) { + this.uniforms.anchor[1] = value; + } + + get dimX() { + return this.uniforms.dimensions[0]; + } + + set dimX(value) { + this.uniforms.dimensions[0] = value; + } + + get dimY() { + return this.uniforms.dimensions[1]; + } + + set dimY(value) { + this.uniforms.dimensions[1] = value; + } +} + +FilterXRays.defaults = { + time: 0.0, + color: 0xff8010, + divisor: 40, + intensity: 0.1, + blend: 8, + anchorX: 0.5, + anchorY: -1.0, + dimX: 1, + dimY: 1, +}; diff --git a/src/fx/filters/FilterZoomBlur.js b/src/fx/filters/FilterZoomBlur.js new file mode 100644 index 0000000..deaae8c --- /dev/null +++ b/src/fx/filters/FilterZoomBlur.js @@ -0,0 +1,34 @@ +import { Anime } from "../Anime.js"; +import "./proto/FilterProto.js"; + +export class FilterZoomBlur extends PIXI.filters.ZoomBlurFilter { + constructor(params) { + super(); + this.enabled = false; + this.strength = 0.1; + this.radiusPercent = 50; + this.innerRadiusPercent = 10; + this.zOrder = 300; + this.animated = {}; + this.setTMParams(params); + if (!this.dummy) { + this.anime = new Anime(this); + this.normalizeTMParams(); + } + } + + handleTransform(state) { + this.center[0] = 0.5 * state.sourceFrame.width; + this.center[1] = 0.5 * state.sourceFrame.height; + this.radius = + (Math.max(this.placeableImg.width, this.placeableImg.height) * + this.targetPlaceable.worldTransform.a * + this.radiusPercent) / + 200; + this.innerRadius = + (Math.max(this.placeableImg.width, this.placeableImg.height) * + this.targetPlaceable.worldTransform.a * + this.innerRadiusPercent) / + 200; + } +} diff --git a/src/fx/filters/proto/FilterProto.js b/src/fx/filters/proto/FilterProto.js new file mode 100644 index 0000000..5c63e77 --- /dev/null +++ b/src/fx/filters/proto/FilterProto.js @@ -0,0 +1,177 @@ +import { getPlaceableById, getMinPadding, PlaceableType } from "../../../module.js"; +import "../../../scripts/proto/PlaceableObjectProto.js"; + +PIXI.Filter.prototype.setTMParams = function (params) { + this.autoDisable = false; + this.autoDestroy = false; + this.gridPadding = 0; + this.boundsPadding = new PIXI.Point(0, 0); + this.currentPadding = 0; + this.recalculatePadding = true; + this.dummy = false; + foundry.utils.mergeObject(this, params); + if (!this.dummy) { + this.rawPadding = this.rawPadding ?? this.padding ?? 0; + this.originalPadding = Math.max(this.rawPadding, getMinPadding()); + this.assignPlaceable(); + this.activateTransform(); + Object.defineProperty(this, "padding", { + get: function () { + if (this.recalculatePadding) this.calculatePadding(); + return this.currentPadding; + }, + set: function (padding) { + this.rawPadding = padding; + this.originalPadding = Math.max(padding, getMinPadding()); + }, + }); + } else { + this.apply = function (filterManager, input, output, clear) { + filterManager.applyFilter(this, input, output, clear); + }; + } +}; + +PIXI.Filter.prototype.getPlaceable = function () { + return getPlaceableById(this.placeableId, this.placeableType); +}; + +PIXI.Filter.prototype.getPlaceableType = function () { + return this.placeableType; +}; + +PIXI.Filter.prototype.calculatePadding = function () { + const target = this.placeableImg; + let width; + let height; + + { + const ang = !this.sticky && this.placeableType !== PlaceableType.TOKEN ? target.rotation : 0; + const sin = Math.sin(ang); + const cos = Math.cos(ang); + width = Math.abs(target.width * cos) + Math.abs(target.height * sin); + height = Math.abs(target.width * sin) + Math.abs(target.height * cos); + } + + if (this.gridPadding > 0) { + const gridSize = canvas.dimensions.size; + this.boundsPadding.x = this.boundsPadding.y = (this.gridPadding - 1) * gridSize; + this.boundsPadding.x += (gridSize - 1 - ((width + gridSize - 1) % gridSize)) / 2; + this.boundsPadding.y += (gridSize - 1 - ((height + gridSize - 1) % gridSize)) / 2; + } else { + this.boundsPadding.x = this.boundsPadding.y = this.rawPadding; + } + + { + const ang = this.sticky ? target.rotation : 0; + const sin = Math.sin(ang); + const cos = Math.cos(ang); + this.currentPadding = + Math.max( + Math.abs(this.boundsPadding.x * cos) + Math.abs(this.boundsPadding.y * sin), + Math.abs(this.boundsPadding.x * sin) + Math.abs(this.boundsPadding.y * cos) + ) + + (this.originalPadding - this.rawPadding); + } + + this.boundsPadding.x += (width - target.width) / 2; + this.boundsPadding.y += (height - target.height) / 2; + + const scale = this.targetPlaceable.worldTransform.a; + + this.boundsPadding.x *= scale; + this.boundsPadding.y *= scale; + this.currentPadding *= scale; +}; + +PIXI.Filter.prototype.assignPlaceable = function () { + this.targetPlaceable = this.getPlaceable(); + this.targetPlaceable != null + ? (this.placeableImg = this.targetPlaceable._TMFXgetSprite()) + : (this.placeableImg = null); +}; + +PIXI.Filter.prototype.activateTransform = function () { + this.preComputation = this.filterTransform; + this.filterTransform(); + + const apply = this.apply; + this.apply = function (filterManager, input, output, clear, state) { + if ("handleTransform" in this) { + this.handleTransform(state); + } + return apply.apply(this, arguments); + }; +}; + +PIXI.Filter.prototype.filterTransform = function () { + if (this.hasOwnProperty("zIndex")) { + this.targetPlaceable.zIndex = this.zIndex; + } +}; + +PIXI.Filter.prototype.normalizeTMParams = function () { + if (this.hasOwnProperty("animated") && !(this.animated == null)) { + // Normalize animations properties + Object.keys(this.animated).forEach((effect) => { + if (this.animated[effect].active == null || typeof this.animated[effect].active != "boolean") { + this.animated[effect].active = true; + } + if ( + this.animated[effect].loops == null || + typeof this.animated[effect].loops != "number" || + this.animated[effect].loops <= 0 + ) { + this.animated[effect].loops = Infinity; + } + if ( + this.animated[effect].loopDuration == null || + typeof this.animated[effect].loopDuration != "number" || + this.animated[effect].loopDuration <= 0 + ) { + this.animated[effect].loopDuration = 3000; + } + if (this.animated[effect].clockWise == null || typeof this.animated[effect].clockWise != "boolean") { + this.animated[effect].clockWise = true; + } + if ( + this.animated[effect].pauseBetweenDuration == null || + typeof this.animated[effect].pauseBetweenDuration != "number" || + this.animated[effect].pauseBetweenDuration <= 0 + ) { + this.animated[effect].pauseBetweenDuration = 0; + } + if ( + this.animated[effect].syncShift == null || + typeof this.animated[effect].syncShift != "number" || + this.animated[effect].syncShift < 0 + ) { + this.animated[effect].syncShift = 0; + } + if (this.animated[effect].val1 == null || typeof this.animated[effect].val1 != "number") { + this.animated[effect].val1 = 0; + } + if (this.animated[effect].val2 == null || typeof this.animated[effect].val2 != "number") { + this.animated[effect].val2 = 0; + } + if (this.anime[this.animated[effect].animType] === undefined) { + this.animated[effect].animType = null; + } + if (this.animated[effect].speed == null || typeof this.animated[effect].speed != "number") { + this.animated[effect].speed = 0; + } + if (this.animated[effect].chaosFactor == null || typeof this.animated[effect].chaosFactor != "number") { + this.animated[effect].chaosFactor = 0.25; + } + if (this.animated[effect].wantInteger == null || typeof this.animated[effect].wantInteger != "boolean") { + this.animated[effect].wantInteger = false; + } + + if (!this.anime.hasInternals(effect)) { + this.anime.initInternals(effect); + } + + this.anime.animated = this.animated; + }); + } +}; diff --git a/tokenmagic/fx/glsl/fragmentshaders/cosmicray.js b/src/fx/glsl/fragmentshaders/cosmicray.js similarity index 100% rename from tokenmagic/fx/glsl/fragmentshaders/cosmicray.js rename to src/fx/glsl/fragmentshaders/cosmicray.js diff --git a/tokenmagic/fx/glsl/fragmentshaders/ddtint.js b/src/fx/glsl/fragmentshaders/ddtint.js similarity index 100% rename from tokenmagic/fx/glsl/fragmentshaders/ddtint.js rename to src/fx/glsl/fragmentshaders/ddtint.js diff --git a/tokenmagic/fx/glsl/fragmentshaders/dropshadow.js b/src/fx/glsl/fragmentshaders/dropshadow.js similarity index 100% rename from tokenmagic/fx/glsl/fragmentshaders/dropshadow.js rename to src/fx/glsl/fragmentshaders/dropshadow.js diff --git a/tokenmagic/fx/glsl/fragmentshaders/electricity.js b/src/fx/glsl/fragmentshaders/electricity.js similarity index 100% rename from tokenmagic/fx/glsl/fragmentshaders/electricity.js rename to src/fx/glsl/fragmentshaders/electricity.js diff --git a/tokenmagic/fx/glsl/fragmentshaders/fire.js b/src/fx/glsl/fragmentshaders/fire.js similarity index 100% rename from tokenmagic/fx/glsl/fragmentshaders/fire.js rename to src/fx/glsl/fragmentshaders/fire.js diff --git a/tokenmagic/fx/glsl/fragmentshaders/flood.js b/src/fx/glsl/fragmentshaders/flood.js similarity index 100% rename from tokenmagic/fx/glsl/fragmentshaders/flood.js rename to src/fx/glsl/fragmentshaders/flood.js diff --git a/tokenmagic/fx/glsl/fragmentshaders/fog.js b/src/fx/glsl/fragmentshaders/fog.js similarity index 100% rename from tokenmagic/fx/glsl/fragmentshaders/fog.js rename to src/fx/glsl/fragmentshaders/fog.js diff --git a/tokenmagic/fx/glsl/fragmentshaders/forcefield.js b/src/fx/glsl/fragmentshaders/forcefield.js similarity index 100% rename from tokenmagic/fx/glsl/fragmentshaders/forcefield.js rename to src/fx/glsl/fragmentshaders/forcefield.js diff --git a/tokenmagic/fx/glsl/fragmentshaders/fumes.js b/src/fx/glsl/fragmentshaders/fumes.js similarity index 100% rename from tokenmagic/fx/glsl/fragmentshaders/fumes.js rename to src/fx/glsl/fragmentshaders/fumes.js diff --git a/tokenmagic/fx/glsl/fragmentshaders/globes.js b/src/fx/glsl/fragmentshaders/globes.js similarity index 100% rename from tokenmagic/fx/glsl/fragmentshaders/globes.js rename to src/fx/glsl/fragmentshaders/globes.js diff --git a/tokenmagic/fx/glsl/fragmentshaders/liquid.js b/src/fx/glsl/fragmentshaders/liquid.js similarity index 100% rename from tokenmagic/fx/glsl/fragmentshaders/liquid.js rename to src/fx/glsl/fragmentshaders/liquid.js diff --git a/tokenmagic/fx/glsl/fragmentshaders/magicglow.js b/src/fx/glsl/fragmentshaders/magicglow.js similarity index 100% rename from tokenmagic/fx/glsl/fragmentshaders/magicglow.js rename to src/fx/glsl/fragmentshaders/magicglow.js diff --git a/tokenmagic/fx/glsl/fragmentshaders/matrix.js b/src/fx/glsl/fragmentshaders/matrix.js similarity index 100% rename from tokenmagic/fx/glsl/fragmentshaders/matrix.js rename to src/fx/glsl/fragmentshaders/matrix.js diff --git a/tokenmagic/fx/glsl/fragmentshaders/mirrorimages.js b/src/fx/glsl/fragmentshaders/mirrorimages.js similarity index 100% rename from tokenmagic/fx/glsl/fragmentshaders/mirrorimages.js rename to src/fx/glsl/fragmentshaders/mirrorimages.js diff --git a/tokenmagic/fx/glsl/fragmentshaders/polymorph.js b/src/fx/glsl/fragmentshaders/polymorph.js similarity index 100% rename from tokenmagic/fx/glsl/fragmentshaders/polymorph.js rename to src/fx/glsl/fragmentshaders/polymorph.js diff --git a/tokenmagic/fx/glsl/fragmentshaders/removeshadow.js b/src/fx/glsl/fragmentshaders/removeshadow.js similarity index 100% rename from tokenmagic/fx/glsl/fragmentshaders/removeshadow.js rename to src/fx/glsl/fragmentshaders/removeshadow.js diff --git a/tokenmagic/fx/glsl/fragmentshaders/ripples.js b/src/fx/glsl/fragmentshaders/ripples.js similarity index 100% rename from tokenmagic/fx/glsl/fragmentshaders/ripples.js rename to src/fx/glsl/fragmentshaders/ripples.js diff --git a/tokenmagic/fx/glsl/fragmentshaders/smoke.js b/src/fx/glsl/fragmentshaders/smoke.js similarity index 100% rename from tokenmagic/fx/glsl/fragmentshaders/smoke.js rename to src/fx/glsl/fragmentshaders/smoke.js diff --git a/tokenmagic/fx/glsl/fragmentshaders/spiderweb.js b/src/fx/glsl/fragmentshaders/spiderweb.js similarity index 100% rename from tokenmagic/fx/glsl/fragmentshaders/spiderweb.js rename to src/fx/glsl/fragmentshaders/spiderweb.js diff --git a/tokenmagic/fx/glsl/fragmentshaders/splash.js b/src/fx/glsl/fragmentshaders/splash.js similarity index 100% rename from tokenmagic/fx/glsl/fragmentshaders/splash.js rename to src/fx/glsl/fragmentshaders/splash.js diff --git a/tokenmagic/fx/glsl/fragmentshaders/sprite.js b/src/fx/glsl/fragmentshaders/sprite.js similarity index 100% rename from tokenmagic/fx/glsl/fragmentshaders/sprite.js rename to src/fx/glsl/fragmentshaders/sprite.js diff --git a/tokenmagic/fx/glsl/fragmentshaders/spritemask.js b/src/fx/glsl/fragmentshaders/spritemask.js similarity index 100% rename from tokenmagic/fx/glsl/fragmentshaders/spritemask.js rename to src/fx/glsl/fragmentshaders/spritemask.js diff --git a/tokenmagic/fx/glsl/fragmentshaders/waves.js b/src/fx/glsl/fragmentshaders/waves.js similarity index 100% rename from tokenmagic/fx/glsl/fragmentshaders/waves.js rename to src/fx/glsl/fragmentshaders/waves.js diff --git a/tokenmagic/fx/glsl/fragmentshaders/xfire.js b/src/fx/glsl/fragmentshaders/xfire.js similarity index 100% rename from tokenmagic/fx/glsl/fragmentshaders/xfire.js rename to src/fx/glsl/fragmentshaders/xfire.js diff --git a/tokenmagic/fx/glsl/fragmentshaders/xfog.js b/src/fx/glsl/fragmentshaders/xfog.js similarity index 100% rename from tokenmagic/fx/glsl/fragmentshaders/xfog.js rename to src/fx/glsl/fragmentshaders/xfog.js diff --git a/tokenmagic/fx/glsl/fragmentshaders/xray.js b/src/fx/glsl/fragmentshaders/xray.js similarity index 100% rename from tokenmagic/fx/glsl/fragmentshaders/xray.js rename to src/fx/glsl/fragmentshaders/xray.js diff --git a/tokenmagic/fx/glsl/vertexshaders/customvertex2D.js b/src/fx/glsl/vertexshaders/customvertex2D.js similarity index 100% rename from tokenmagic/fx/glsl/vertexshaders/customvertex2D.js rename to src/fx/glsl/vertexshaders/customvertex2D.js diff --git a/tokenmagic/fx/glsl/vertexshaders/customvertex2DSampler.js b/src/fx/glsl/vertexshaders/customvertex2DSampler.js similarity index 100% rename from tokenmagic/fx/glsl/vertexshaders/customvertex2DSampler.js rename to src/fx/glsl/vertexshaders/customvertex2DSampler.js diff --git a/src/fx/presets/defaultpresets.js b/src/fx/presets/defaultpresets.js new file mode 100644 index 0000000..0f986d8 --- /dev/null +++ b/src/fx/presets/defaultpresets.js @@ -0,0 +1,2677 @@ +export const PresetsLibrary = { + MAIN: "tmfx-main", + TEMPLATE: "tmfx-template", +}; + +export var presets = []; + +let params = [ + { + filterType: "bevel", + filterId: "bevel", + rotation: 0, + thickness: 5, + lightColor: 0xff0000, + lightAlpha: 0.8, + shadowColor: 0x00ff00, + shadowAlpha: 0.5, + animated: { + rotation: { + active: true, + clockWise: true, + loopDuration: 1600, + animType: "syncRotation", + }, + }, + }, +]; + +var presetObject = {}; +presetObject.name = "bevel"; +presetObject.library = PresetsLibrary.MAIN; +presetObject.params = params; +presets.push(presetObject); + +params = [ + { + filterType: "adjustment", + filterId: "adjustment", + saturation: 1.5, + brightness: 1.5, + contrast: 2, + gamma: 2, + red: 4, + green: 0.25, + blue: 0.25, + alpha: 1, + animated: { + alpha: { + active: true, + loopDuration: 5000, + animType: "syncCosOscillation", + val1: 0.15, + val2: 1, + }, + }, + }, +]; + +presetObject = new Object(); +presetObject.name = "adjustment"; +presetObject.library = PresetsLibrary.MAIN; +presetObject.params = params; +presets.push(presetObject); + +params = [ + { + filterType: "shadow", + filterId: "dropshadow", + rotation: 35, + blur: 2, + quality: 5, + distance: 20, + alpha: 0.7, + padding: 10, + shadowOnly: false, + color: 0x000000, + animated: { + blur: { + active: true, + loopDuration: 1500, + animType: "syncCosOscillation", + val1: 2, + val2: 3, + }, + rotation: { + active: true, + loopDuration: 150, + animType: "syncSinOscillation", + val1: 33, + val2: 35, + }, + }, + }, +]; + +presetObject = new Object(); +presetObject.name = "dropshadow"; +presetObject.library = PresetsLibrary.MAIN; +presetObject.params = params; +presets.push(presetObject); + +params = [ + { + filterType: "outline", + filterId: "outline", + padding: 10, + color: 0xee6035, + thickness: 1, + quality: 5, + animated: { + thickness: { + active: true, + loopDuration: 800, + animType: "syncCosOscillation", + val1: 1, + val2: 6, + }, + }, + }, +]; + +presetObject = new Object(); +presetObject.name = "outline"; +presetObject.library = PresetsLibrary.MAIN; +presetObject.params = params; +presets.push(presetObject); + +params = [ + { + filterType: "glow", + filterId: "glow", + outerStrength: 7, + innerStrength: 0, + color: 0x006000, + quality: 0.5, + padding: 10, + animated: { + color: { + active: true, + loopDuration: 3000, + animType: "colorOscillation", + val1: 0x003000, + val2: 0x00ff00, + }, + }, + }, +]; + +presetObject = new Object(); +presetObject.name = "glow"; +presetObject.library = PresetsLibrary.MAIN; +presetObject.params = params; +presets.push(presetObject); + +params = [ + { + filterType: "xbloom", + filterId: "bloom", + threshold: 0.35, + bloomScale: 0, + brightness: 1, + blur: 0.1, + padding: 10, + quality: 15, + blendMode: 0, + animated: { + bloomScale: { + active: true, + loopDuration: 2000, + animType: "syncCosOscillation", + val1: 0, + val2: 2.1, + }, + threshold: { + active: false, + loopDuration: 1000, + animType: "syncCosOscillation", + val1: 0.0, + val2: 1.9, + }, + }, + }, +]; + +presetObject = new Object(); +presetObject.name = "bloom"; +presetObject.library = PresetsLibrary.MAIN; +presetObject.params = params; +presets.push(presetObject); + +params = [ + { + filterType: "distortion", + filterId: "distortion", + maskPath: "modules/tokenmagic/fx/assets/distortion-1.png", + maskSpriteScaleX: 5, + maskSpriteScaleY: 5, + padding: 20, + animated: { + maskSpriteX: { active: true, speed: 0.05, animType: "move" }, + maskSpriteY: { active: true, speed: 0.07, animType: "move" }, + }, + }, +]; + +presetObject = new Object(); +presetObject.name = "distortion"; +presetObject.library = PresetsLibrary.MAIN; +presetObject.params = params; +presets.push(presetObject); + +params = [ + { + filterType: "oldfilm", + filterId: "oldfilm", + sepia: 0.6, + noise: 0.2, + noiseSize: 1.0, + scratch: 0.8, + scratchDensity: 0.5, + scratchWidth: 1.2, + vignetting: 0.9, + vignettingAlpha: 0.6, + vignettingBlur: 0.2, + animated: { + seed: { + active: true, + animType: "randomNumber", + val1: 0, + val2: 1, + }, + vignetting: { + active: true, + animType: "syncCosOscillation", + loopDuration: 2000, + val1: 0.2, + val2: 0.4, + }, + }, + }, + { + filterType: "outline", + filterId: "oldfilm", + color: 0x000000, + thickness: 0, + }, +]; + +presetObject = new Object(); +presetObject.name = "oldfilm"; +presetObject.library = PresetsLibrary.MAIN; +presetObject.params = params; +presets.push(presetObject); + +params = [ + { + filterType: "twist", + filterId: "twist", + radiusPercent: 120, + angle: 0, + animated: { + angle: { + active: true, + animType: "sinOscillation", + loopDuration: 10000, + val1: -0.6 * Math.PI, + val2: +0.6 * Math.PI, + }, + }, + }, +]; + +presetObject = new Object(); +presetObject.name = "twist"; +presetObject.library = PresetsLibrary.MAIN; +presetObject.params = params; +presets.push(presetObject); + +params = [ + { + filterType: "bulgepinch", + filterId: "bulge", + padding: 150, + strength: 0, + zIndex: 2, + radiusPercent: 200, + animated: { + strength: { + active: true, + animType: "cosOscillation", + loopDuration: 2000, + val1: 0, + val2: 0.45, + }, + }, + }, +]; + +presetObject = new Object(); +presetObject.name = "bulge"; +presetObject.library = PresetsLibrary.MAIN; +presetObject.params = params; +presets.push(presetObject); + +params = [ + { + filterType: "blur", + filterId: "blur", + padding: 10, + quality: 4.0, + blur: 0, + blurX: 0, + blurY: 0, + animated: { + blurX: { + active: true, + animType: "syncCosOscillation", + loopDuration: 500, + val1: 0, + val2: 6, + }, + blurY: { + active: true, + animType: "syncCosOscillation", + loopDuration: 750, + val1: 0, + val2: 6, + }, + }, + }, +]; + +presetObject = new Object(); +presetObject.name = "blur"; +presetObject.library = PresetsLibrary.MAIN; +presetObject.params = params; +presets.push(presetObject); + +params = [ + { + filterType: "zoomblur", + filterId: "zoomblur", + strength: 0.15, + innerRadiusPercent: 65, + radiusPercent: 100, + padding: 30, + animated: { + innerRadiusPercent: { + active: true, + animType: "sinOscillation", + loopDuration: 500, + val1: 65, + val2: 75, + }, + }, + }, +]; + +presetObject = new Object(); +presetObject.name = "zoomblur"; +presetObject.library = PresetsLibrary.MAIN; +presetObject.params = params; +presets.push(presetObject); + +params = [ + { + filterType: "shockwave", + filterId: "shockwave", + time: 0, + amplitude: 8, + wavelength: 75, + radius: 500, + brightness: 1.5, + speed: 25, + padding: 0, + animated: { + time: { + animType: "cosOscillation", + active: true, + loopDuration: 1800, + val1: 0, + val2: 10, + }, + }, + }, +]; + +presetObject = new Object(); +presetObject.name = "shockwave"; +presetObject.library = PresetsLibrary.MAIN; +presetObject.params = params; +presets.push(presetObject); + +params = [ + { + filterType: "zapshadow", + filterId: "zapshadow", + alphaTolerance: 0.45, + }, +]; + +presetObject = new Object(); +presetObject.name = "zapshadow"; +presetObject.library = PresetsLibrary.MAIN; +presetObject.params = params; +presets.push(presetObject); + +params = [ + { + filterType: "ray", + filterId: "rays", + time: 0, + color: 0xcf8000, + alpha: 0.5, + divisor: 32, + anchorX: 0, + anchorY: 0, + animated: { + time: { + active: true, + speed: 0.0005, + animType: "move", + }, + }, + }, +]; + +presetObject = new Object(); +presetObject.name = "rays"; +presetObject.library = PresetsLibrary.MAIN; +presetObject.params = params; +presets.push(presetObject); + +params = [ + { + filterType: "fog", + filterId: "fog", + color: 0x000000, + density: 0.65, + time: 0, + dimX: 1, + dimY: 1, + animated: { + time: { + active: true, + speed: 2.2, + animType: "move", + }, + }, + }, +]; + +presetObject = new Object(); +presetObject.name = "fog"; +presetObject.library = PresetsLibrary.MAIN; +presetObject.params = params; +presets.push(presetObject); + +params = [ + { + filterType: "fumes", + filterId: "fumes", + color: 0x808080, + time: 0, + blend: 8, + animated: { + time: { + active: true, + speed: 0.001, + animType: "move", + }, + }, + }, +]; + +presetObject = new Object(); +presetObject.name = "fumes"; +presetObject.library = PresetsLibrary.MAIN; +presetObject.params = params; +presets.push(presetObject); + +params = [ + { + filterType: "electric", + filterId: "electric", + color: 0xffffff, + time: 0, + blend: 1, + intensity: 5, + animated: { + time: { + active: true, + speed: 0.002, + animType: "move", + }, + }, + }, +]; + +presetObject = new Object(); +presetObject.name = "electric"; +presetObject.library = PresetsLibrary.MAIN; +presetObject.params = params; +presets.push(presetObject); + +params = [ + { + filterType: "fire", + filterId: "fire", + intensity: 1, + color: 0xffffff, + amplitude: 1, + time: 0, + blend: 2, + fireBlend: 1, + animated: { + time: { + active: true, + speed: -0.0024, + animType: "move", + }, + intensity: { + active: true, + loopDuration: 15000, + val1: 0.8, + val2: 2, + animType: "syncCosOscillation", + }, + amplitude: { + active: true, + loopDuration: 4400, + val1: 1, + val2: 1.4, + animType: "syncCosOscillation", + }, + }, + }, +]; + +presetObject = new Object(); +presetObject.name = "fire"; +presetObject.library = PresetsLibrary.MAIN; +presetObject.params = params; +presets.push(presetObject); + +params = [ + { + filterType: "wave", + filterId: "waves", + time: 0, + anchorX: 0.5, + anchorY: 0.5, + strength: 0.015, + frequency: 120, + color: 0xffffff, + maxIntensity: 2.5, + minIntensity: 0.9, + padding: 10, + animated: { + time: { + active: true, + speed: 0.0085, + animType: "move", + }, + anchorX: { + active: false, + val1: 0.15, + val2: 0.85, + animType: "syncChaoticOscillation", + loopDuration: 20000, + }, + anchorY: { + active: false, + val1: 0.15, + val2: 0.85, + animType: "syncSinOscillation", + loopDuration: 20000, + }, + }, + }, +]; + +presetObject = new Object(); +presetObject.name = "waves"; +presetObject.library = PresetsLibrary.MAIN; +presetObject.params = params; +presets.push(presetObject); + +params = [ + { + filterType: "flood", + filterId: "flood", + time: 0, + color: 0x0020bb, + billowy: 0.43, + tintIntensity: 0.72, + glint: 0.31, + scale: 70, + padding: 10, + animated: { + time: { + active: true, + speed: 0.0006, + animType: "move", + }, + }, + }, +]; + +presetObject = new Object(); +presetObject.name = "flood"; +presetObject.library = PresetsLibrary.MAIN; +presetObject.params = params; +presets.push(presetObject); + +params = [ + { + filterType: "smoke", + filterId: "smoke", + color: 0x5099dd, + time: 0, + blend: 2, + dimX: 0.1, + dimY: 1, + animated: { + time: { + active: true, + speed: 0.009, + animType: "move", + }, + }, + }, +]; + +presetObject = new Object(); +presetObject.name = "smoke"; +presetObject.library = PresetsLibrary.MAIN; +presetObject.params = params; +presets.push(presetObject); + +params = [ + { + filterType: "images", + filterId: "images", + time: 0, + nbImage: 4, + alphaImg: 1.0, + alphaChr: 0.0, + blend: 4, + ampX: 0.1, + ampY: 0.1, + animated: { + time: { + active: true, + speed: 0.001, + animType: "move", + }, + }, + }, +]; + +presetObject = new Object(); +presetObject.name = "images"; +presetObject.library = PresetsLibrary.MAIN; +presetObject.params = params; +presets.push(presetObject); + +params = [ + { + filterType: "images", + filterId: "chaos-images", + time: 0, + nbImage: 4, + alphaImg: 1.0, + alphaChr: 0.0, + blend: 4, + ampX: 0.1, + ampY: 0.1, + padding: 80, + animated: { + time: { + active: true, + speed: 0.001, + animType: "move", + }, + ampX: { + active: true, + val1: 0.0, + val2: 0.3, + chaosFactor: 0.03, + animType: "syncChaoticOscillation", + loopDuration: 2000, + }, + ampY: { + active: true, + val1: 0.0, + val2: 0.3, + chaosFactor: 0.04, + animType: "syncChaoticOscillation", + loopDuration: 1650, + }, + alphaChr: { + active: true, + animType: "randomNumberPerLoop", + val1: 0.0, + val2: 1, + loopDuration: 250, + }, + alphaImg: { + active: true, + animType: "randomNumberPerLoop", + val1: 0.8, + val2: 1, + loopDuration: 250, + }, + nbImage: { + active: true, + val1: 1, + val2: 9, + animType: "syncSinOscillation", + loopDuration: 1400, + }, + }, + }, +]; + +presetObject = new Object(); +presetObject.name = "chaos-images"; +presetObject.library = PresetsLibrary.MAIN; +presetObject.params = params; +presets.push(presetObject); + +params = [ + { + filterType: "images", + filterId: "spectral-images", + time: 0, + blend: 4, + nbImage: 4, + padding: 100, + alphaImg: 0.5, + alphaChr: 0.0, + ampX: 0.1, + ampY: 0.1, + animated: { + time: { + speed: 0.001, + animType: "move", + }, + ampX: { + val1: 0, + val2: 0.22, + animType: "syncCosOscillation", + loopDuration: 2500, + }, + ampY: { + val1: 0, + val2: 0.24, + animType: "syncCosOscillation", + loopDuration: 2500, + pauseBetweenDuration: 2500, + }, + alphaChr: { + val1: 1, + val2: 0, + animType: "syncCosOscillation", + loopDuration: 2500, + }, + alphaImg: { + val1: 0.2, + val2: 0.8, + animType: "syncSinOscillation", + loopDuration: 2500, + }, + }, + }, +]; + +presetObject = new Object(); +presetObject.name = "spectral-images"; +presetObject.library = PresetsLibrary.MAIN; +presetObject.params = params; +presets.push(presetObject); + +params = [ + { + filterType: "field", + filterId: "hexa-field", + shieldType: 2, + gridPadding: 1.5, + color: 0xcc00cc, + time: 0, + blend: 3, + intensity: 1, + lightAlpha: 0.5, + lightSize: 0.5, + scale: 1, + radius: 1, + chromatic: false, + animated: { + time: { + active: true, + speed: 0.0015, + animType: "move", + }, + }, + }, +]; + +presetObject = new Object(); +presetObject.name = "hexa-field"; +presetObject.library = PresetsLibrary.MAIN; +presetObject.params = params; +presets.push(presetObject); + +params = [ + { + filterType: "field", + filterId: "fire-field", + shieldType: 1, + gridPadding: 2, + color: 0xe58550, + time: 0, + blend: 2, + intensity: 1.15, + lightAlpha: 2, + lightSize: 0.7, + scale: 1, + radius: 1, + chromatic: false, + animated: { + time: { + active: true, + speed: 0.0015, + animType: "move", + }, + }, + }, +]; + +presetObject = new Object(); +presetObject.name = "fire-field"; +presetObject.library = PresetsLibrary.MAIN; +presetObject.params = params; +presets.push(presetObject); + +params = [ + { + filterType: "field", + filterId: "smoke-field", + shieldType: 3, + gridPadding: 1.5, + color: 0x60cc70, + time: 0, + blend: 2, + intensity: 0.9, + lightAlpha: 1, + lightSize: 0.7, + scale: 1, + radius: 1, + chromatic: false, + animated: { + time: { + active: true, + speed: 0.0015, + animType: "move", + }, + }, + }, +]; + +presetObject = new Object(); +presetObject.name = "smoke-field"; +presetObject.library = PresetsLibrary.MAIN; +presetObject.params = params; +presets.push(presetObject); + +params = [ + { + filterType: "field", + filterId: "earth-field", + shieldType: 4, + gridPadding: 2, + color: 0xbb9070, + time: 0, + blend: 1, + intensity: 1.25, + lightAlpha: 1, + lightSize: 0.7, + scale: 1, + radius: 1, + chromatic: false, + animated: { + time: { + active: true, + speed: 0.0015, + animType: "move", + }, + }, + }, +]; + +presetObject = new Object(); +presetObject.name = "earth-field"; +presetObject.library = PresetsLibrary.MAIN; +presetObject.params = params; +presets.push(presetObject); + +params = [ + { + filterType: "field", + filterId: "earth-field-top", + shieldType: 5, + gridPadding: 3, + color: 0xaaaaaa, + time: 0, + blend: 5, + intensity: 1.9, + lightAlpha: 1, + lightSize: 0.7, + scale: 1, + radius: 1, + zIndex: 5, + chromatic: true, + animated: { + time: { + active: true, + speed: 0.0015, + animType: "move", + }, + }, + }, +]; + +presetObject = new Object(); +presetObject.name = "earth-field-top"; +presetObject.library = PresetsLibrary.MAIN; +presetObject.params = params; +presets.push(presetObject); + +params = [ + { + filterType: "field", + filterId: "air-field", + shieldType: 6, + gridPadding: 1.2, + color: 0x7090aa, + time: 0, + blend: 14, + intensity: 1, + lightAlpha: 1, + lightSize: 0.7, + scale: 1, + radius: 1, + chromatic: false, + animated: { + time: { + active: true, + speed: 0.0015, + animType: "move", + }, + }, + }, +]; + +presetObject = new Object(); +presetObject.name = "air-field"; +presetObject.library = PresetsLibrary.MAIN; +presetObject.params = params; +presets.push(presetObject); + +params = [ + { + filterType: "field", + filterId: "magic-field", + shieldType: 7, + gridPadding: 1, + color: 0xffffff, + time: 0, + blend: 10, + intensity: 0.8, + lightAlpha: 1, + lightSize: 0.45, + scale: 1, + radius: 1, + chromatic: false, + animated: { + time: { + active: true, + speed: 0.0015, + animType: "move", + }, + }, + }, +]; + +presetObject = new Object(); +presetObject.name = "magic-field"; +presetObject.library = PresetsLibrary.MAIN; +presetObject.params = params; +presets.push(presetObject); + +params = [ + { + filterType: "field", + filterId: "chromatic-field", + shieldType: 8, + gridPadding: 2, + color: 0xaaaaaa, + time: 0, + blend: 0, + intensity: 1, + lightAlpha: 0, + lightSize: 0, + scale: 1, + radius: 1, + chromatic: true, + animated: { + time: { + active: true, + speed: 0.0045, + animType: "move", + }, + }, + }, +]; + +presetObject = new Object(); +presetObject.name = "chromatic-field"; +presetObject.library = PresetsLibrary.MAIN; +presetObject.params = params; +presets.push(presetObject); + +params = [ + { + filterType: "field", + filterId: "water-field", + shieldType: 9, + gridPadding: 1.2, + color: 0x20bbee, + time: 0, + blend: 4, + intensity: 1, + lightAlpha: 0.7, + lightSize: 0.5, + scale: 0.6, + radius: 1, + chromatic: false, + animated: { + time: { + active: true, + speed: 0.0015, + animType: "move", + }, + }, + }, +]; + +presetObject = new Object(); +presetObject.name = "water-field"; +presetObject.library = PresetsLibrary.MAIN; +presetObject.params = params; +presets.push(presetObject); + +params = [ + { + filterType: "field", + filterId: "evil-field", + shieldType: 9, + gridPadding: 2, + color: 0xff3010, + time: 0, + blend: 5, + intensity: 1, + lightAlpha: 4, + lightSize: 0.8, + scale: 0.5, + radius: 1, + chromatic: false, + animated: { + time: { + active: true, + speed: 0.0012, + animType: "move", + }, + lightSize: { + val1: 0.4, + val2: 1.5, + animType: "syncCosOscillation", + loopDuration: 5000, + }, + }, + }, +]; + +presetObject = new Object(); +presetObject.name = "evil-field"; +presetObject.library = PresetsLibrary.MAIN; +presetObject.params = params; +presets.push(presetObject); + +params = [ + { + filterType: "field", + filterId: "grid-field", + shieldType: 11, + gridPadding: 2, + color: 0x00cccc, + time: 0, + blend: 2, + intensity: 1, + lightAlpha: 1, + lightSize: 0.3, + scale: 0.5, + radius: 1, + chromatic: false, + animated: { + time: { + active: true, + speed: 0.0009, + animType: "move", + }, + }, + }, +]; + +presetObject = new Object(); +presetObject.name = "grid-field"; +presetObject.library = PresetsLibrary.MAIN; +presetObject.params = params; +presets.push(presetObject); + +params = [ + { + filterType: "field", + filterId: "warp-field", + shieldType: 12, + gridPadding: 2, + color: 0xffffff, + time: 0, + blend: 2, + intensity: 1, + lightAlpha: 0.8, + lightSize: 0.5, + scale: 0.9, + radius: 1, + chromatic: false, + animated: { + time: { + active: true, + speed: 0.0009, + animType: "move", + }, + }, + }, +]; + +presetObject = new Object(); +presetObject.name = "warp-field"; +presetObject.library = PresetsLibrary.MAIN; +presetObject.params = params; +presets.push(presetObject); + +params = [ + { + filterType: "field", + filterId: "color-field", + shieldType: 13, + gridPadding: 2, + color: 0x00cc00, + time: 0, + blend: 14, + intensity: 1, + lightAlpha: 0, + lightSize: 0, + scale: 1, + radius: 1, + chromatic: false, + animated: { + time: { + active: true, + speed: 0.0009, + animType: "move", + }, + }, + }, +]; + +presetObject = new Object(); +presetObject.name = "color-field"; +presetObject.library = PresetsLibrary.MAIN; +presetObject.params = params; +presets.push(presetObject); + +params = [ + { + filterType: "xray", + filterId: "sunburst", + time: 0, + color: 0xffbb00, + blend: 9, + dimX: 1, + dimY: 1, + anchorX: 0, + anchorY: 0, + divisor: 36, + intensity: 4, + animated: { + time: { + active: true, + speed: 0.0012, + animType: "move", + }, + anchorX: { + animType: "syncCosOscillation", + loopDuration: 6000, + val1: 0.4, + val2: 0.6, + }, + }, + }, +]; + +presetObject = new Object(); +presetObject.name = "sunburst"; +presetObject.library = PresetsLibrary.MAIN; +presetObject.params = params; +presets.push(presetObject); + +params = [ + { + filterType: "xray", + filterId: "clover", + time: 0, + color: 0x00ff00, + blend: 9, + dimX: 0.05, + dimY: 0.05, + anchorX: 0.5, + anchorY: 0.5, + divisor: 4, + intensity: 1, + animated: { + time: { + active: true, + speed: 0.0012, + animType: "move", + }, + anchorX: { + animType: "syncCosOscillation", + loopDuration: 6000, + val1: 0.4, + val2: 0.6, + }, + anchorY: { + animType: "syncSinOscillation", + loopDuration: 6000, + val1: 0.4, + val2: 0.6, + }, + }, + }, +]; + +presetObject = new Object(); +presetObject.name = "clover"; +presetObject.library = PresetsLibrary.MAIN; +presetObject.params = params; +presets.push(presetObject); + +params = [ + { + filterType: "xray", + filterId: "scan", + time: 0, + color: 0xffffff, + blend: 5, + dimX: 20, + dimY: 20, + anchorX: 0.5, + anchorY: 0, + divisor: 8, + intensity: 1, + animated: { + time: { + active: true, + speed: 0.0005, + animType: "move", + }, + }, + }, +]; + +presetObject = new Object(); +presetObject.name = "scan"; +presetObject.library = PresetsLibrary.MAIN; +presetObject.params = params; +presets.push(presetObject); + +params = [ + { + filterType: "xray", + filterId: "blue-rays", + time: 0, + color: 0x1030ff, + blend: 9, + dimX: 1, + dimY: 1, + anchorX: 0, + anchorY: 0, + divisor: 24, + intensity: 1, + animated: { + time: { + active: true, + speed: 0.0002, + animType: "move", + }, + anchorX: { + animType: "syncCosOscillation", + loopDuration: 18000, + val1: 0.05, + val2: 0.95, + }, + anchorY: { + animType: "syncSinOscillation", + loopDuration: 18000, + val1: 0.05, + val2: 0.95, + }, + }, + }, +]; + +presetObject = new Object(); +presetObject.name = "blue-rays"; +presetObject.library = PresetsLibrary.MAIN; +presetObject.params = params; +presets.push(presetObject); + +params = [ + { + filterType: "liquid", + filterId: "spectral-body", + color: 0x20aaee, + time: 0, + blend: 8, + intensity: 4, + spectral: true, + scale: 0.9, + animated: { + time: { + active: true, + speed: 0.001, + animType: "move", + }, + color: { + active: true, + loopDuration: 6000, + animType: "colorOscillation", + val1: 0xffffff, + val2: 0x00aaff, + }, + }, + }, +]; + +presetObject = new Object(); +presetObject.name = "spectral-body"; +presetObject.library = PresetsLibrary.MAIN; +presetObject.params = params; +presets.push(presetObject); + +params = [ + { + filterType: "liquid", + filterId: "mantle-of-madness", + color: 0x0090ff, + time: 0, + blend: 5, + intensity: 0.0001, + spectral: false, + scale: 7, + animated: { + time: { + active: true, + speed: 0.0015, + animType: "move", + }, + intensity: { + active: true, + animType: "syncCosOscillation", + loopDuration: 30000, + val1: 0.0001, + val2: 4, + }, + scale: { + active: true, + animType: "syncCosOscillation", + loopDuration: 30000, + val1: 7, + val2: 1, + }, + }, + }, +]; + +presetObject = new Object(); +presetObject.name = "mantle-of-madness"; +presetObject.library = PresetsLibrary.MAIN; +presetObject.params = params; +presets.push(presetObject); + +params = [ + { + filterType: "wave", + filterId: "drift-in-plans", + time: 0, + anchorX: 0.5, + anchorY: 0.5, + strength: 0.035, + frequency: 80, + color: 0xffffff, + maxIntensity: 1.5, + minIntensity: 0.5, + padding: 10, + animated: { + time: { + active: true, + speed: 0.0085, + animType: "move", + }, + anchorX: { + active: true, + val1: 0.35, + val2: 0.65, + animType: "syncCosOscillation", + loopDuration: 10000, + }, + anchorY: { + active: true, + val1: 0.35, + val2: 0.65, + animType: "syncSinOscillation", + loopDuration: 10000, + }, + }, + }, + { + filterType: "liquid", + filterId: "drift-in-plans", + color: 0xff0000, + time: 0, + blend: 6, + intensity: 5, + spectral: false, + scale: 2.5, + animated: { + time: { + active: true, + speed: 0.0018, + animType: "move", + }, + color: { + active: true, + loopDuration: 9000, + animType: "colorOscillation", + val1: 0xff0000, + val2: 0xffffff, + }, + }, + }, +]; + +presetObject = new Object(); +presetObject.name = "drift-in-plans"; +presetObject.library = PresetsLibrary.MAIN; +presetObject.params = params; +presets.push(presetObject); + +params = [ + { + filterType: "zapshadow", + filterId: "fire-aura", + alphaTolerance: 0.5, + }, + { + filterType: "xglow", + filterId: "fire-aura", + auraType: 2, + color: 0x903010, + thickness: 9.8, + scale: 4, + time: 0, + auraIntensity: 2, + subAuraIntensity: 1.5, + threshold: 0.4, + discard: true, + animated: { + time: { + active: true, + speed: 0.0027, + animType: "move", + }, + thickness: { + active: true, + loopDuration: 3000, + animType: "cosOscillation", + val1: 2, + val2: 5, + }, + }, + }, +]; + +presetObject = new Object(); +presetObject.name = "fire-aura"; +presetObject.library = PresetsLibrary.MAIN; +presetObject.params = params; +presets.push(presetObject); + +params = [ + { + filterType: "zapshadow", + filterId: "glacial-aura", + alphaTolerance: 0.5, + }, + { + filterType: "xglow", + filterId: "glacial-aura", + auraType: 1, + color: 0x5099dd, + thickness: 4.5, + scale: 3, + time: 0, + auraIntensity: 0.8, + subAuraIntensity: 0.25, + threshold: 0.5, + discard: false, + animated: { + time: { + active: true, + speed: 0.0018, + animType: "move", + }, + thickness: { + val1: 2, + val2: 4.7, + animType: "cosOscillation", + loopDuration: 3000, + }, + subAuraIntensity: { + val1: 0.45, + val2: 0.65, + animType: "cosOscillation", + loopDuration: 6000, + }, + auraIntensity: { + val1: 0.9, + val2: 2.2, + animType: "cosOscillation", + loopDuration: 3000, + }, + }, + }, +]; + +presetObject = new Object(); +presetObject.name = "glacial-aura"; +presetObject.library = PresetsLibrary.MAIN; +presetObject.params = params; +presets.push(presetObject); + +params = [ + { + filterType: "zapshadow", + filterId: "anti-aura", + alphaTolerance: 0.5, + }, + { + filterType: "xglow", + filterId: "anti-aura", + auraType: 2, + color: 0x050505, + thickness: 2.7, + scale: 7, + time: 0, + auraIntensity: 5, + subAuraIntensity: 2, + threshold: 0.08, + discard: false, + animated: { + time: { + active: true, + speed: 0.0012, + animType: "move", + }, + auraIntensity: { + active: true, + loopDuration: 3000, + animType: "syncCosOscillation", + val1: 5, + val2: 0, + }, + subAuraIntensity: { + active: true, + loopDuration: 3000, + animType: "syncCosOscillation", + val1: 2, + val2: 0, + }, + color: { + active: true, + loopDuration: 6000, + animType: "syncColorOscillation", + val1: 0x050505, + val2: 0x200000, + }, + threshold: { + active: true, + loopDuration: 1500, + animType: "syncCosOscillation", + val1: 0.02, + val2: 0.5, + }, + }, + }, +]; + +presetObject = new Object(); +presetObject.name = "anti-aura"; +presetObject.library = PresetsLibrary.MAIN; +presetObject.params = params; +presets.push(presetObject); + +params = [ + { + filterType: "fire", + filterId: "pure-fire-aura", + intensity: 1, + color: 0xffffff, + amplitude: 1, + time: 0, + blend: 2, + fireBlend: 1, + animated: { + time: { + active: true, + speed: -0.0024, + animType: "move", + }, + intensity: { + active: true, + loopDuration: 15000, + val1: 0.8, + val2: 2, + animType: "syncCosOscillation", + }, + amplitude: { + active: true, + loopDuration: 4400, + val1: 1, + val2: 1.4, + animType: "syncCosOscillation", + }, + }, + }, + { + filterType: "zapshadow", + filterId: "pure-fire-aura", + alphaTolerance: 0.5, + }, + { + filterType: "xglow", + filterId: "pure-fire-aura", + auraType: 2, + color: 0x903010, + thickness: 9.8, + scale: 4, + time: 0, + auraIntensity: 2, + subAuraIntensity: 1.5, + threshold: 0.4, + discard: true, + animated: { + time: { + active: true, + speed: 0.0027, + animType: "move", + }, + thickness: { + active: true, + loopDuration: 3000, + animType: "cosOscillation", + val1: 2, + val2: 5, + }, + }, + }, +]; + +presetObject = new Object(); +presetObject.name = "pure-fire-aura"; +presetObject.library = PresetsLibrary.MAIN; +presetObject.params = params; +presets.push(presetObject); + +params = [ + { + filterType: "zapshadow", + filterId: "pure-fire-aura-2", + alphaTolerance: 0.5, + }, + { + filterType: "xglow", + filterId: "pure-fire-aura-2", + auraType: 2, + color: 0x903010, + thickness: 9.8, + scale: 4, + time: 0, + auraIntensity: 1, + subAuraIntensity: 0.3, + threshold: 0.5, + discard: true, + animated: { + time: { + active: true, + speed: 0.0027, + animType: "move", + }, + thickness: { + active: true, + loopDuration: 3000, + animType: "cosOscillation", + val1: 2, + val2: 3.6, + }, + }, + }, + { + filterType: "fire", + filterId: "pure-fire-aura-2", + intensity: 1, + color: 0xffffff, + amplitude: 1, + time: 0, + blend: 2, + fireBlend: 1, + animated: { + time: { + active: true, + speed: -0.0024, + animType: "move", + }, + intensity: { + active: true, + loopDuration: 15000, + val1: 0.8, + val2: 3, + animType: "syncCosOscillation", + }, + amplitude: { + active: true, + loopDuration: 4400, + val1: 1, + val2: 1.6, + animType: "syncCosOscillation", + }, + }, + }, +]; + +presetObject = new Object(); +presetObject.name = "pure-fire-aura-2"; +presetObject.library = PresetsLibrary.MAIN; +presetObject.params = params; +presets.push(presetObject); + +params = [ + { + filterType: "zapshadow", + filterId: "pure-ice-aura", + alphaTolerance: 0.5, + }, + { + filterType: "xglow", + filterId: "pure-ice-aura", + auraType: 1, + color: 0x5099dd, + thickness: 4.5, + scale: 10, + time: 0, + auraIntensity: 0.25, + subAuraIntensity: 1, + threshold: 0.5, + discard: false, + animated: { + time: { + active: true, + speed: 0.0018, + animType: "move", + }, + thickness: { + val1: 2, + val2: 3.3, + animType: "cosOscillation", + loopDuration: 3000, + }, + subAuraIntensity: { + val1: 0.45, + val2: 0.65, + animType: "cosOscillation", + loopDuration: 6000, + }, + auraIntensity: { + val1: 0.9, + val2: 2.2, + animType: "cosOscillation", + loopDuration: 3000, + }, + }, + }, + { + filterType: "smoke", + filterId: "pure-ice-aura", + color: 0x80ccff, + time: 0, + blend: 2, + dimX: 0.3, + dimY: 1, + animated: { + time: { + active: true, + speed: -0.006, + animType: "move", + }, + dimX: { + val1: 0.4, + val2: 0.2, + animType: "cosOscillation", + loopDuration: 3000, + }, + }, + }, +]; + +presetObject = new Object(); +presetObject.name = "pure-ice-aura"; +presetObject.library = PresetsLibrary.MAIN; +presetObject.params = params; +presets.push(presetObject); + +params = [ + { + filterType: "pixel", + filterId: "pixelate", + sizeX: 2.5, + sizeY: 2.5, + }, +]; + +presetObject = new Object(); +presetObject.name = "pixelate"; +presetObject.library = PresetsLibrary.MAIN; +presetObject.params = params; +presets.push(presetObject); + +export var templatePresets = []; + +// white : **electric , **waves, ***xrays, **liquid (normal), (clover) +// black : **liquid (protoplasm), **smoke, **rays, outline, **fumes, **fog, **flood, **fire +// no texture : **glow, **bulge, **blur, **bloom + +params = [ + { + filterType: "flood", + filterId: "Watery Surface", + time: 0, + color: 0x0020bb, + billowy: 0.43, + tintIntensity: 0.72, + glint: 0.31, + scale: 70, + padding: 10, + animated: { + time: { + active: true, + speed: 0.0006, + animType: "move", + }, + }, + }, +]; + +presetObject = {}; +presetObject.name = "Watery Surface"; +presetObject.library = PresetsLibrary.TEMPLATE; +presetObject.defaultTexture = "modules/tokenmagic/fx/assets/templates/black-tone-strong-opacity.png"; +presetObject.params = params; +templatePresets.push(presetObject); + +params = [ + { + filterType: "liquid", + filterId: "Protoplasm", + color: 0x20aaee, + time: 0, + blend: 8, + intensity: 4, + spectral: true, + scale: 1.4, + animated: { + time: { + active: true, + speed: 0.001, + animType: "move", + }, + }, + }, +]; + +presetObject = {}; +presetObject.name = "Protoplasm"; +presetObject.library = PresetsLibrary.TEMPLATE; +presetObject.defaultTexture = "modules/tokenmagic/fx/assets/templates/black-tone-strong-opacity.png"; +presetObject.params = params; +templatePresets.push(presetObject); + +params = [ + { + filterType: "liquid", + filterId: "Watery Surface 2", + color: 0x20aaee, + time: 0, + blend: 8, + intensity: 4, + spectral: false, + scale: 1.4, + animated: { + time: { + active: true, + speed: 0.001, + animType: "move", + }, + }, + }, +]; + +presetObject = {}; +presetObject.name = "Watery Surface 2"; +presetObject.library = PresetsLibrary.TEMPLATE; +presetObject.defaultTexture = "modules/tokenmagic/fx/assets/templates/white-tone-strong-opacity.png"; +presetObject.params = params; +templatePresets.push(presetObject); + +params = [ + { + filterType: "smoke", + filterId: "Smoky Area", + color: 0xaaaaaa, + time: 0, + blend: 2, + dimX: 1, + dimY: 1, + animated: { + time: { + active: true, + speed: 0.002, + animType: "move", + }, + }, + }, +]; + +presetObject = {}; +presetObject.name = "Smoky Area"; +presetObject.library = PresetsLibrary.TEMPLATE; +presetObject.defaultTexture = "modules/tokenmagic/fx/assets/templates/black-tone-strong-opacity.png"; +presetObject.params = params; +templatePresets.push(presetObject); + +params = [ + { + filterType: "electric", + filterId: "Shock", + color: 0xffffff, + time: 0, + blend: 1, + intensity: 5, + animated: { + time: { + active: true, + speed: 0.002, + animType: "move", + }, + }, + }, +]; + +presetObject = {}; +presetObject.name = "Shock"; +presetObject.library = PresetsLibrary.TEMPLATE; +presetObject.defaultTexture = "modules/tokenmagic/fx/assets/templates/white-tone-strong-opacity.png"; +presetObject.params = params; +templatePresets.push(presetObject); + +params = [ + { + filterType: "xray", + filterId: "Annihilating Rays", + time: 0, + color: 0xffbb00, + blend: 9, + dimX: 1, + dimY: 1, + anchorX: 0, + anchorY: 0, + divisor: 6, + intensity: 4, + animated: { + time: { + active: true, + speed: 0.0012, + animType: "move", + }, + }, + }, +]; + +presetObject = {}; +presetObject.name = "Annihilating Rays"; +presetObject.library = PresetsLibrary.TEMPLATE; +presetObject.defaultTexture = "modules/tokenmagic/fx/assets/templates/white-tone-strong-opacity.png"; +presetObject.params = params; +templatePresets.push(presetObject); + +params = [ + { + filterType: "ray", + filterId: "Classic Rays", + time: 0, + color: 0xcf8000, + alpha: 0.5, + divisor: 32, + anchorX: 0, + anchorY: 0, + animated: { + time: { + active: true, + speed: 0.0005, + animType: "move", + }, + }, + }, +]; + +presetObject = {}; +presetObject.name = "Classic Rays"; +presetObject.library = PresetsLibrary.TEMPLATE; +presetObject.defaultTexture = "modules/tokenmagic/fx/assets/templates/black-tone-strong-opacity.png"; +presetObject.params = params; +templatePresets.push(presetObject); + +params = [ + { + filterType: "fumes", + filterId: "Smoke Filaments", + color: 0x808080, + time: 0, + blend: 8, + animated: { + time: { + active: true, + speed: 0.001, + animType: "move", + }, + }, + }, +]; + +presetObject = {}; +presetObject.name = "Smoke Filaments"; +presetObject.library = PresetsLibrary.TEMPLATE; +presetObject.defaultTexture = "modules/tokenmagic/fx/assets/templates/black-tone-strong-opacity.png"; +presetObject.params = params; +templatePresets.push(presetObject); + +params = [ + { + filterType: "fire", + filterId: "Flames", + intensity: 1.5, + color: 0xffffff, + amplitude: 1.3, + time: 0, + blend: 2, + fireBlend: 1, + animated: { + time: { + active: true, + speed: -0.0016, + animType: "move", + }, + }, + }, +]; + +presetObject = {}; +presetObject.name = "Flames"; +presetObject.library = PresetsLibrary.TEMPLATE; +presetObject.defaultTexture = "modules/tokenmagic/fx/assets/templates/black-tone-strong-opacity.png"; +presetObject.params = params; +templatePresets.push(presetObject); + +params = [ + { + filterType: "xfog", + filterId: "Thick Fog", + autoFit: false, + color: 0x3090ff, + time: 0, + animated: { + time: { + active: true, + speed: 0.0006, + animType: "move", + }, + }, + }, +]; + +presetObject = {}; +presetObject.name = "Thick Fog"; +presetObject.library = PresetsLibrary.TEMPLATE; +presetObject.defaultTexture = "modules/tokenmagic/fx/assets/templates/black-tone-vstrong-opacity.png"; +presetObject.params = params; +templatePresets.push(presetObject); + +params = [ + { + filterType: "glow", + filterId: "Glowing Outline", + outerStrength: 5.5, + innerStrength: 0, + color: 0x006000, + quality: 0.5, + padding: 10, + animated: { + outerStrength: { + active: true, + loopDuration: 3000, + animType: "syncCosOscillation", + val1: 5.5, + val2: 1.5, + }, + }, + }, +]; + +presetObject = {}; +presetObject.name = "Glowing Outline"; +presetObject.library = PresetsLibrary.TEMPLATE; +presetObject.params = params; +templatePresets.push(presetObject); + +params = [ + { + filterType: "wave", + filterId: "Waves", + time: 0, + anchorX: 0.5, + anchorY: 0.5, + strength: 0.015, + frequency: 120, + color: 0xffffff, + maxIntensity: 2.5, + minIntensity: 0.9, + padding: 10, + animated: { + time: { + active: true, + speed: 0.0085, + animType: "move", + }, + }, + }, +]; + +presetObject = {}; +presetObject.name = "Waves"; +presetObject.library = PresetsLibrary.TEMPLATE; +presetObject.defaultTexture = "modules/tokenmagic/fx/assets/templates/white-tone-strong-opacity.png"; +presetObject.params = params; +templatePresets.push(presetObject); + +params = [ + { + filterType: "wave", + filterId: "Waves 2", + time: 0, + anchorX: 0.5, + anchorY: 0.5, + strength: 0.014, + frequency: 400, + color: 0xffffff, + maxIntensity: 2.4, + minIntensity: 0.8, + padding: 10, + animated: { + time: { + active: true, + speed: 0.0385, + animType: "move", + }, + }, + }, +]; + +presetObject = {}; +presetObject.name = "Waves 2"; +presetObject.library = PresetsLibrary.TEMPLATE; +presetObject.defaultTexture = "modules/tokenmagic/fx/assets/templates/white-tone-strong-opacity.png"; +presetObject.params = params; +templatePresets.push(presetObject); + +params = [ + { + filterType: "wave", + filterId: "Waves 3", + time: 0, + anchorX: 0.5, + anchorY: 0.5, + strength: 0.017, + frequency: 35, + color: 0xffffff, + maxIntensity: 2.6, + minIntensity: 0.9, + padding: 20, + animated: { + time: { + active: true, + speed: 0.0085, + animType: "move", + }, + }, + }, +]; + +presetObject = {}; +presetObject.name = "Waves 3"; +presetObject.library = PresetsLibrary.TEMPLATE; +presetObject.defaultTexture = "modules/tokenmagic/fx/assets/templates/white-tone-strong-opacity.png"; +presetObject.params = params; +templatePresets.push(presetObject); + +params = [ + { + filterType: "xglow", + filterId: "Zone : Fire", + auraType: 1, + color: 0x903010, + scale: 1.5, + time: 0, + auraIntensity: 1.8, + subAuraIntensity: 0.25, + threshold: 0.6, + discard: false, + animated: { + time: { + active: true, + speed: 0.0027, + animType: "move", + }, + thickness: { + active: true, + loopDuration: 3000, + animType: "cosOscillation", + val1: 2, + val2: 5, + }, + }, + }, + { + filterType: "fire", + filterId: "Zone : Fire", + intensity: 1.5, + color: 0xffffff, + amplitude: 1, + time: 0, + blend: 2, + fireBlend: 1, + animated: { + time: { + active: true, + speed: -0.0015, + animType: "move", + }, + }, + }, +]; + +presetObject = {}; +presetObject.name = "Zone : Fire"; +presetObject.library = PresetsLibrary.TEMPLATE; +presetObject.defaultTexture = "modules/tokenmagic/fx/assets/templates/black-tone-strong-opacity.png"; +presetObject.params = params; +templatePresets.push(presetObject); + +params = [ + { + filterType: "xglow", + filterId: "Zone : Electricity", + auraType: 2, + color: 0x303030, + scale: 1.5, + time: 0, + auraIntensity: 1, + subAuraIntensity: 0.9, + threshold: 0, + discard: true, + animated: { + time: { + active: true, + speed: 0.0027, + animType: "move", + }, + thickness: { + active: true, + loopDuration: 3000, + animType: "cosOscillation", + val1: 1, + val2: 2, + }, + }, + }, + { + filterType: "electric", + filterId: "Zone : Electricity", + color: 0xffffff, + time: 0, + blend: 1, + intensity: 5, + animated: { + time: { + active: true, + speed: 0.002, + animType: "move", + }, + }, + }, +]; + +presetObject = {}; +presetObject.name = "Zone : Electricity"; +presetObject.library = PresetsLibrary.TEMPLATE; +presetObject.defaultTexture = "modules/tokenmagic/fx/assets/templates/white-tone-strong-opacity.png"; +presetObject.params = params; +templatePresets.push(presetObject); + +params = [ + { + filterType: "xglow", + filterId: "Zone : Blizzard", + auraType: 1, + color: 0x5099dd, + thickness: 4.5, + scale: 5, + time: 0, + auraIntensity: 0.25, + subAuraIntensity: 1, + threshold: 0.5, + discard: false, + animated: { + time: { + active: true, + speed: 0.0018, + animType: "move", + }, + thickness: { + val1: 2, + val2: 3.3, + animType: "cosOscillation", + loopDuration: 3000, + }, + subAuraIntensity: { + val1: 0.05, + val2: 0.1, + animType: "cosOscillation", + loopDuration: 6000, + }, + auraIntensity: { + val1: 0.9, + val2: 2.2, + animType: "cosOscillation", + loopDuration: 3000, + }, + }, + }, + { + filterType: "smoke", + filterId: "Zone : Blizzard", + color: 0x80ccff, + time: 0, + blend: 2, + dimY: 1, + animated: { + time: { + active: true, + speed: -0.005, + animType: "move", + }, + dimX: { + val1: 0.4, + val2: 0.2, + animType: "cosOscillation", + loopDuration: 3000, + }, + }, + }, +]; + +presetObject = {}; +presetObject.name = "Zone : Blizzard"; +presetObject.library = PresetsLibrary.TEMPLATE; +presetObject.defaultTexture = "modules/tokenmagic/fx/assets/templates/black-tone-strong-opacity.png"; +presetObject.params = params; +templatePresets.push(presetObject); + +params = [ + { + filterType: "bulgepinch", + filterId: "Bulging Out", + padding: 150, + strength: 0, + radiusPercent: 200, + animated: { + strength: { + active: true, + animType: "cosOscillation", + loopDuration: 2000, + val1: 0, + val2: 0.45, + }, + }, + }, +]; + +presetObject = {}; +presetObject.name = "Bulging Out"; +presetObject.library = PresetsLibrary.TEMPLATE; +presetObject.params = params; +templatePresets.push(presetObject); + +params = [ + { + filterType: "blur", + filterId: "Blurred Texture", + padding: 25, + quality: 4.0, + blur: 0, + blurX: 0, + blurY: 0, + animated: { + blurX: { + active: true, + animType: "syncCosOscillation", + loopDuration: 500, + val1: 0, + val2: 6, + }, + blurY: { + active: true, + animType: "syncCosOscillation", + loopDuration: 750, + val1: 0, + val2: 6, + }, + }, + }, +]; + +presetObject = {}; +presetObject.name = "Blurred Texture"; +presetObject.library = PresetsLibrary.TEMPLATE; +presetObject.params = params; +templatePresets.push(presetObject); + +params = [ + { + filterType: "xbloom", + filterId: "Bloomed Texture", + threshold: 0.35, + bloomScale: 0, + brightness: 1, + blur: 0.1, + padding: 10, + quality: 15, + blendMode: 0, + animated: { + bloomScale: { + active: true, + loopDuration: 2000, + animType: "syncCosOscillation", + val1: 0, + val2: 2.1, + }, + threshold: { + active: false, + loopDuration: 1000, + animType: "syncCosOscillation", + val1: 0.0, + val2: 1.9, + }, + }, + }, +]; + +presetObject = {}; +presetObject.name = "Bloomed Texture"; +presetObject.library = PresetsLibrary.TEMPLATE; +presetObject.params = params; +templatePresets.push(presetObject); + +params = [ + { + filterType: "liquid", + filterId: "Wild Magic", + color: 0xff0000, + time: 0, + blend: 6, + intensity: 5, + spectral: false, + scale: 2.5, + animated: { + time: { + active: true, + speed: 0.0018, + animType: "move", + }, + }, + }, + { + filterType: "wave", + filterId: "Wild Magic", + time: 0, + anchorX: 0.5, + anchorY: 0.5, + strength: 0.014, + frequency: 10, + color: 0xffffff, + maxIntensity: 1.3, + minIntensity: 0.6, + padding: 10, + animated: { + time: { + active: true, + speed: 0.0065, + animType: "move", + }, + }, + }, +]; + +presetObject = {}; +presetObject.name = "Wild Magic"; +presetObject.library = PresetsLibrary.TEMPLATE; +presetObject.defaultTexture = "modules/tokenmagic/fx/assets/templates/black-tone-strong-opacity.png"; +presetObject.params = params; +templatePresets.push(presetObject); + +params = [ + { + filterType: "web", + filterId: "Spider Web 1", + anchorX: 0.5, + anchorY: 0.5, + color: 0xffffff, + thickness: 2, + div2: 5, + time: 98.8, + animated: { + time: { + active: true, + loopDuration: 5000, + animType: "cosOscillation", + val1: 98.8, + val2: 99.7, + }, + }, + }, +]; + +presetObject = {}; +presetObject.name = "Spider Web 1"; +presetObject.library = PresetsLibrary.TEMPLATE; +presetObject.defaultTexture = "modules/tokenmagic/fx/assets/templates/black-tone-strong-opacity.png"; +presetObject.params = params; +templatePresets.push(presetObject); + +params = [ + { + filterType: "web", + filterId: "Spider Web 2", + anchorX: 0.5, + anchorY: 0.5, + color: 0xcccccc, + animated: { + time: { + active: true, + speed: 0.0005, + animType: "move", + }, + }, + }, + { + filterType: "liquid", + filterId: "Spider Web 2", + color: 0xff0000, + time: 0, + blend: 4, + intensity: 8, + spectral: false, + scale: 0.2, + animated: { + time: { + active: true, + speed: 0.0005, + animType: "move", + }, + }, + }, +]; + +presetObject = {}; +presetObject.name = "Spider Web 2"; +presetObject.library = PresetsLibrary.TEMPLATE; +presetObject.defaultTexture = "modules/tokenmagic/fx/assets/templates/black-tone-strong-opacity.png"; +presetObject.params = params; +templatePresets.push(presetObject); + +params = [ + { + filterType: "web", + filterId: "Spider Web 3", + anchorX: 0.5, + anchorY: 0.5, + color: 0xcccccc, + time: 100, + }, + { + filterType: "liquid", + filterId: "Spider Web 3", + color: 0xff0000, + time: 0, + blend: 1, + intensity: 4, + spectral: true, + scale: 0.2, + animated: { + time: { + active: true, + speed: 0.0005, + animType: "move", + }, + }, + }, +]; + +presetObject = {}; +presetObject.name = "Spider Web 3"; +presetObject.library = PresetsLibrary.TEMPLATE; +presetObject.defaultTexture = "modules/tokenmagic/fx/assets/templates/black-tone-strong-opacity.png"; +presetObject.params = params; +templatePresets.push(presetObject); + +export var allPresets = presets.concat(templatePresets); diff --git a/tokenmagic/gui/icons/simple-gui-macro.svg b/src/gui/icons/simple-gui-macro.svg similarity index 100% rename from tokenmagic/gui/icons/simple-gui-macro.svg rename to src/gui/icons/simple-gui-macro.svg diff --git a/tokenmagic/gui/macros/SImpleGUIMacro.js b/src/gui/macros/SImpleGUIMacro.js similarity index 54% rename from tokenmagic/gui/macros/SImpleGUIMacro.js rename to src/gui/macros/SImpleGUIMacro.js index c4d2c19..a18e434 100644 --- a/tokenmagic/gui/macros/SImpleGUIMacro.js +++ b/src/gui/macros/SImpleGUIMacro.js @@ -3,10 +3,10 @@ // You can create your own compendium, and put any effects in it // Just change MyCompendium below with your custom compendium -const MyCompendium = 'TokenMagic Book of Fire'; +const MyCompendium = "TokenMagic Book of Fire"; // ------------------------ -const macroVersion = 'v0.2.1'; +const macroVersion = "v0.2.1"; /* Simple GUI - Token Magic Author : brunocalado @@ -19,17 +19,17 @@ Icon: let filterType; (async () => { - let msgtoken = ``; - if (canvas.tokens.controlled != 0 || canvas.background.controlled[0]) { - filterType = 'selected'; - } else if (game.user.targets.size != 0) { - filterType = 'targeted'; - } else { - ui.notifications.error('Select something!'); - return; - } - - let template = `\n \n
\n
    \n ${await loadMacroButton()}\n
\n \n
\n \n \n\n \n `;\n\n new Dialog({\n title: `TMFX GUI - ${macroVersion}`,\n content: template,\n buttons: {\n yes: {\n icon: \"\",\n label: \"Apply\",\n callback: () => {}\n },\n clear: {\n icon: \"\",\n label: \"Clear\",\n callback: async (html) => {\n removeOnSelected(html);\n }\n }\n },\n default: \"yes\",\n close: html => {\n }\n }, { id: 'tokenmagic-quickpreview' }).render(true);\n //} ).render(true); \n})()\n\n// ==============================\n// Main\n// ==============================\n\n\n// ==============================\n// Common Functions \n// ==============================\nasync function removeOnSelected() {\n await TokenMagic.deleteFilters(_token);\n await TokenMagic.deleteFiltersOnSelected(); // Delete all filters on the selected tokens/tiles\n}\n\nasync function loadMacroButton() {\n const list_compendium = await game.packs.filter(p => p.metadata.type == 'Macro');\n const inside = await list_compendium.filter(p => p.metadata.label == MyCompendium)[0].index.contents;\n let msg = ``;\n let tmp;\n let counter = 1;\n\n inside.map((el) => {\n tmp = el.name.split(' ').join('');\n msg += `
  • `;\n counter += 1;\n });\n\n return msg;\n}\n\nasync function loadMacros(filterType) {\n const pack = await game.packs.find(p => p.metadata.label == MyCompendium);\n const index = await pack.getIndex({fields: [\"name\", \"img\", \"command\"]});\n const inside = index.contents;\n let msg = ``;\n let tmp;\n let counter = 1;\n\n inside.map((el) => {\n let macro = el.command;\n if (filterType == 'selected') {\n macro = macro.replace(\"OnTargeted\", \"OnSelected\");\n } else {\n macro = macro.replace(\"OnSelected\", \"OnTargeted\");\n }\n tmp = el.name.split(' ').join('');\n msg += `async function effect${counter}() {`;\n msg += `await removeOnSelected();`;\n msg += `${macro}`;\n msg += `}`;\n counter += 1;\n });\n return msg;\n}\n\nfunction removeAll() {\n const clean = `async function removeOnSelected() {await TokenMagic.deleteFilters(_token);await TokenMagic.deleteFiltersOnSelected()}`;\n return clean;\n}", + "folder": null, + "sort": 9000000, + "flags": {}, + "ownership": { + "default": 0 + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!iQbTZfjc0y3vHYTB" +} diff --git a/src/packs/_source/tmMacros/00-d-tmfx-gui-toggle-presets.json b/src/packs/_source/tmMacros/00-d-tmfx-gui-toggle-presets.json new file mode 100644 index 0000000..ebee5e0 --- /dev/null +++ b/src/packs/_source/tmMacros/00-d-tmfx-gui-toggle-presets.json @@ -0,0 +1,24 @@ +{ + "name": "00 - D - TMFX GUI - Toggle Presets", + "type": "script", + "scope": "global", + "author": "cDfy4cFieNjb5vsL", + "img": "icons/svg/book.svg", + "command": "// Search for and toggle presets on all selected placeables\n\nfunction togglePresetOnSelected(presetName) {\n const controlled = [...canvas.templates.controlled, ...canvas.tokens.controlled, ...canvas.drawings.controlled];\n for(const placeable of controlled) {\n if(TokenMagic.hasFilterId(placeable, presetName)) {\n TokenMagic.deleteFilters(placeable, presetName);\n } else {\n const preset = TokenMagic.getPreset(presetName);\n if(preset) {\n TokenMagic.addUpdateFilters(placeable, preset);\n }\n }\n }\n}\n\nlet content = ``;\n\nlet list = '
      '\nTokenMagic.getPresets().forEach(p => list += `
    • ${p.name}
    • `)\nlist += '
    ';\n\ncontent += list;\n \nlet styles = `\n\n`;\n\ncontent = styles + content;\n \n new Dialog({\n title: `TMFX GUI - Toggle Presets`,\n content,\n render: (html) => {\n // Filtering\n html.find('.search').on('input', () => {\n const filter = html.find('.search').val().trim().toLowerCase()\n html.find('.preset-list li').each(function () {\n const li = $(this);\n if(li.find('a').text().toLowerCase().includes(filter)) {\n li.show();\n } else {\n li.hide();\n }\n });\n });\n // Toggling\n html.find('.preset-list li').on('click', (event) => {\n const presetName = $(event.target).closest('li').find('a').text();\n togglePresetOnSelected(presetName);\n });\n // Deleting\n html.find('.delete').on('click', ()=> {\n TokenMagic.deleteFiltersOnSelected();\n });\n } ,\n buttons: {\n close: {\n icon: \"\",\n label: \"Close\",\n callback: () => {}\n },\n },\n default: \"close\",\n close: html => {\n }\n }, { id: 'tokenmagic-toggle-preset' }).render(true);", + "folder": null, + "ownership": { + "default": 0 + }, + "flags": {}, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": 1695323062735, + "modifiedTime": 1695399597925, + "lastModifiedBy": "packsbuilder0000" + }, + "_id": "y1VbGayfVRU7eqGi", + "sort": 0, + "_key": "!macros!y1VbGayfVRU7eqGi" +} diff --git a/src/packs/_source/tmMacros/01-bevel.json b/src/packs/_source/tmMacros/01-bevel.json new file mode 100644 index 0000000..bde5e81 --- /dev/null +++ b/src/packs/_source/tmMacros/01-bevel.json @@ -0,0 +1,24 @@ +{ + "_id": "GvYp56Thtf3n9RYy", + "name": "01 - Bevel", + "type": "script", + "author": "Njc5YzFjZDI5NjZl", + "img": "modules/tokenmagic/gui/macros/images/01%20-%20Bevel.webp", + "scope": "global", + "command": "let params = \n[{\n filterType: \"bevel\",\n filterId: \"myBevel\",\n rotation: 0,\n thickness: 5,\n lightColor: 0xFF0000,\n lightAlpha: 0.8,\n shadowColor: 0x00FF00,\n shadowAlpha: 0.5,\n animated :\n {\n rotation: \n { \n active: true,\n clockWise: true, \n loopDuration: 1600, \n animType: \"syncRotation\"\n }\n }\n}];\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 3600000, + "flags": {}, + "ownership": { + "default": 0 + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!GvYp56Thtf3n9RYy" +} diff --git a/src/packs/_source/tmMacros/02-adjustment.json b/src/packs/_source/tmMacros/02-adjustment.json new file mode 100644 index 0000000..e90805c --- /dev/null +++ b/src/packs/_source/tmMacros/02-adjustment.json @@ -0,0 +1,24 @@ +{ + "_id": "VWTz2fKfSb6WK7Mo", + "name": "02 - Adjustment", + "type": "script", + "author": "Njc5YzFjZDI5NjZl", + "img": "modules/tokenmagic/gui/macros/images/02%20-%20Adjustment.webp", + "scope": "global", + "command": "let params =\n[{\n filterType: \"adjustment\",\n filterId: \"myAdjust\",\n saturation: 1,\n brightness: 1,\n contrast: 1,\n gamma: 1,\n red: 0.2,\n green: 0.2,\n blue: 0.2,\n alpha: 1,\n animated:\n {\n alpha: \n { \n active: true, \n loopDuration: 2000, \n animType: \"syncCosOscillation\",\n val1: 0.35,\n val2: 0.75 }\n }\n}];\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 6500000, + "flags": {}, + "ownership": { + "default": 0 + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!VWTz2fKfSb6WK7Mo" +} diff --git a/src/packs/_source/tmMacros/03-drop-shadow.json b/src/packs/_source/tmMacros/03-drop-shadow.json new file mode 100644 index 0000000..a8d2731 --- /dev/null +++ b/src/packs/_source/tmMacros/03-drop-shadow.json @@ -0,0 +1,24 @@ +{ + "_id": "hayiRem3LXoEP3tL", + "name": "03 - Drop Shadow", + "type": "script", + "author": "Njc5YzFjZDI5NjZl", + "img": "modules/tokenmagic/gui/macros/images/03%20-%20Drop%20Shadow.webp", + "scope": "global", + "command": "let params =\n[{\n filterType: \"shadow\",\n filterId: \"myShadow\",\n rotation: 35,\n blur: 2,\n quality: 5,\n distance: 20,\n alpha: 0.7,\n padding: 10,\n shadowOnly: false,\n color: 0x000000,\n zOrder: 6000,\n animated:\n {\n blur: \n { \n active: true, \n loopDuration: 500, \n animType: \"syncCosOscillation\", \n val1: 2, \n val2: 4\n },\n rotation:\n {\n active: true,\n loopDuration: 100,\n animType: \"syncSinOscillation\",\n val1: 33,\n val2: 37\n }\n }\n}];\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 8900000, + "flags": {}, + "ownership": { + "default": 0 + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!hayiRem3LXoEP3tL" +} diff --git a/src/packs/_source/tmMacros/04-outline.json b/src/packs/_source/tmMacros/04-outline.json new file mode 100644 index 0000000..a886da5 --- /dev/null +++ b/src/packs/_source/tmMacros/04-outline.json @@ -0,0 +1,31 @@ +{ + "_id": "b5Enw7tEwfjDNHuY", + "name": "04 - Outline", + "type": "script", + "author": "Njc5YzFjZDI5NjZl", + "img": "modules/tokenmagic/gui/macros/images/04%20-%20Outline.webp", + "scope": "global", + "command": "let params = \n[{\n filterType: \"outline\",\n filterId: \"myOutline\",\n padding: 10,\n color: 0xEE6035,\n thickness: 1,\n quality: 5,\n zOrder: 9,\n animated :\n {\n thickness: \n { \n active: true,\n loopDuration: 800,\n animType: \"syncCosOscillation\",\n val1: 1, \n val2: 6\n }\n }\n}];\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 7400000, + "flags": { + "combat-utility-belt": { + "macroTrigger": "" + }, + "furnace": { + "runAsGM": false + } + }, + "ownership": { + "default": 0 + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!b5Enw7tEwfjDNHuY" +} diff --git a/src/packs/_source/tmMacros/05-glow.json b/src/packs/_source/tmMacros/05-glow.json new file mode 100644 index 0000000..f140190 --- /dev/null +++ b/src/packs/_source/tmMacros/05-glow.json @@ -0,0 +1,28 @@ +{ + "_id": "g7O4u4dTaWcnajW7", + "name": "05 - Glow", + "type": "script", + "author": "Njc5YzFjZDI5NjZl", + "img": "modules/tokenmagic/gui/macros/images/05%20-%20Glow.webp", + "scope": "global", + "command": "let params =\n[{\n filterType: \"glow\",\n filterId: \"superSpookyGlow\",\n outerStrength: 4,\n innerStrength: 0,\n color: 0x5099DD,\n quality: 0.5,\n padding: 10,\n animated:\n {\n color: \n {\n active: true, \n loopDuration: 3000, \n animType: \"colorOscillation\", \n val1:0x5099DD, \n val2:0x90EEFF\n }\n }\n}];\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 8600000, + "flags": { + "furnace": { + "runAsGM": false + } + }, + "ownership": { + "default": 0 + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!g7O4u4dTaWcnajW7" +} diff --git a/src/packs/_source/tmMacros/06-bloom.json b/src/packs/_source/tmMacros/06-bloom.json new file mode 100644 index 0000000..e91ab6b --- /dev/null +++ b/src/packs/_source/tmMacros/06-bloom.json @@ -0,0 +1,24 @@ +{ + "_id": "cCEOQFsJvjhSTbbM", + "name": "06 - Bloom", + "type": "script", + "author": "Njc5YzFjZDI5NjZl", + "img": "modules/tokenmagic/gui/macros/images/06%20-%20Bloom.webp", + "scope": "global", + "command": "let params = \n[{\n filterType: \"xbloom\",\n filterId: \"letsShine\",\n threshold: 0.35,\n bloomScale: 0,\n brightness: 1,\n blur: 0.1,\n padding: 10,\n quality: 15,\n blendMode: 0,\n animated:\n {\n bloomScale: \n { \n active: true, \n loopDuration: 2000, \n animType: \"syncCosOscillation\", \n val1: 0, \n val2: 2.1\n },\n threshold: \n { \n active: false, \n loopDuration: 1000, \n animType: \"syncCosOscillation\", \n val1: 0.00, \n val2: 1.90\n }\n }\n}];\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 7600000, + "flags": {}, + "ownership": { + "default": 0 + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!cCEOQFsJvjhSTbbM" +} diff --git a/src/packs/_source/tmMacros/07-distortion.json b/src/packs/_source/tmMacros/07-distortion.json new file mode 100644 index 0000000..a0e1562 --- /dev/null +++ b/src/packs/_source/tmMacros/07-distortion.json @@ -0,0 +1,24 @@ +{ + "_id": "yHYwADWdYDAMTuCR", + "name": "07 - Distortion", + "type": "script", + "author": "Njc5YzFjZDI5NjZl", + "img": "modules/tokenmagic/gui/macros/images/07%20-%20Distortion.webp", + "scope": "global", + "command": "// you can change the mask of the filter\n// the mask must have a power of 2 h and w (512x512, 128x128, ...) \n// the distortion applies on black and white and shades of grey\n// after testing the first version of this macro try this :\n// -> maskPath: \"modules/tokenmagic/fx/assets/waves-2.png\"\n\nlet params =\n[{\n filterType: \"distortion\",\n filterId: \"myDistortion\",\n maskPath: \"modules/tokenmagic/fx/assets/distortion-1.png\",\n maskSpriteScaleX: 5,\n maskSpriteScaleY: 5,\n padding: 20,\n animated:\n {\n maskSpriteX: { active: true, speed: 0.05, animType: \"move\" },\n maskSpriteY: { active: true, speed: 0.07, animType: \"move\" }\n }\n}];\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 11400000, + "flags": {}, + "ownership": { + "default": 0 + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!yHYwADWdYDAMTuCR" +} diff --git a/src/packs/_source/tmMacros/08-old-film.json b/src/packs/_source/tmMacros/08-old-film.json new file mode 100644 index 0000000..6ccc413 --- /dev/null +++ b/src/packs/_source/tmMacros/08-old-film.json @@ -0,0 +1,24 @@ +{ + "_id": "lH53KTce3zYEFXos", + "name": "08 - Old film", + "type": "script", + "author": "Njc5YzFjZDI5NjZl", + "img": "modules/tokenmagic/gui/macros/images/08%20-%20Old%20film.webp", + "scope": "global", + "command": "// special : the OldFilm filter need an Outline filter to be contained (or else, it will affect all the container)\nlet params =\n[{\n filterType: \"oldfilm\",\n filterId: \"myOldfilm\",\n sepia: 0.6,\n noise: 0.2,\n noiseSize: 1.0,\n scratch: 0.8,\n scratchDensity: 0.5,\n scratchWidth: 1.2,\n vignetting: 0.9,\n vignettingAlpha: 0.6,\n vignettingBlur: 0.2,\n animated:\n {\n seed: \n { \n active: true, \n animType: \"randomNumber\", \n val1: 0, \n val2: 1 \n },\n vignetting: \n { \n active: true, \n animType: \"syncCosOscillation\" , \n loopDuration: 2000, \n val1: 0.2, \n val2: 0.4 }\n }\n},\n{\n filterType: \"outline\",\n filterId: \"oldfilmOutline\",\n color: 0x000000,\n thickness: 0,\n zOrder: 61\n}];\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 9500000, + "flags": {}, + "ownership": { + "default": 0 + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!lH53KTce3zYEFXos" +} diff --git a/src/packs/_source/tmMacros/09-t01-twist-transform.json b/src/packs/_source/tmMacros/09-t01-twist-transform.json new file mode 100644 index 0000000..f440a09 --- /dev/null +++ b/src/packs/_source/tmMacros/09-t01-twist-transform.json @@ -0,0 +1,24 @@ +{ + "_id": "OWgJD9lvBlDzXALz", + "name": "09 - T01 - Twist (transform)", + "type": "script", + "author": "Njc5YzFjZDI5NjZl", + "img": "modules/tokenmagic/gui/macros/images/09%20-%20T01%20-%20Twist%20%28transform%29.webp", + "scope": "global", + "command": "let params =\n [{\n filterType: \"transform\",\n filterId: \"myTwistTransform\",\n twRadiusPercent: 70,\n padding: 10,\n animated:\n {\n twRotation:\n {\n animType: \"sinOscillation\",\n val1: -90,\n val2: +90,\n loopDuration: 5000,\n }\n }\n }];\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 4800000, + "flags": {}, + "ownership": { + "default": 0 + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!OWgJD9lvBlDzXALz" +} diff --git a/src/packs/_source/tmMacros/09-t02-moo-man-dance-transform.json b/src/packs/_source/tmMacros/09-t02-moo-man-dance-transform.json new file mode 100644 index 0000000..3bf1701 --- /dev/null +++ b/src/packs/_source/tmMacros/09-t02-moo-man-dance-transform.json @@ -0,0 +1,24 @@ +{ + "_id": "jFdKzkYqcKOmeQPW", + "name": "09 - T02 - Moo Man Dance (transform)", + "type": "script", + "author": "Njc5YzFjZDI5NjZl", + "img": "modules/tokenmagic/gui/macros/images/09%20-%20T02%20-%20Moo%20Man%20Dance%20%28transform%29.webp", + "scope": "global", + "command": "let params =\n [{\n filterType: \"transform\",\n filterId: \"theMooManDance\",\n twRadiusPercent: 70,\n bpRadiusPercent: 90,\n padding: 50,\n animated:\n {\n twRotation:\n {\n animType: \"sinOscillation\",\n val1: -90,\n val2: +90,\n loopDuration: 1000,\n },\n bpStrength:\n {\n animType: \"cosOscillation\",\n val1: 0,\n val2: 0.55,\n loopDuration: 1000,\n },\n translationX:\n {\n animType: \"sinOscillation\",\n val1: -0.125,\n val2: +0.125,\n loopDuration: 1400,\n },\n translationY:\n {\n animType: \"cosOscillation\",\n val1: -0.125,\n val2: +0.125,\n loopDuration: 1400,\n },\n rotation:\n {\n animType: \"cosOscillation\",\n val1: 90,\n val2: -90,\n loopDuration: 4200,\n }, \n }\n }];\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 9100000, + "flags": {}, + "ownership": { + "default": 0 + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!jFdKzkYqcKOmeQPW" +} diff --git a/src/packs/_source/tmMacros/10-t01-bulge-transform.json b/src/packs/_source/tmMacros/10-t01-bulge-transform.json new file mode 100644 index 0000000..15dd203 --- /dev/null +++ b/src/packs/_source/tmMacros/10-t01-bulge-transform.json @@ -0,0 +1,24 @@ +{ + "_id": "FBQzhLveCvFKOvJ7", + "name": "10 - T01 - Bulge (transform)", + "type": "script", + "author": "Njc5YzFjZDI5NjZl", + "img": "modules/tokenmagic/gui/macros/images/10%20-%20T01%20-%20Bulge%20%28transform%29.webp", + "scope": "global", + "command": "let params =\n [{\n filterType: \"transform\",\n filterId: \"myBulgeTransform\",\n bpRadiusPercent: 70,\n padding: 100,\n animated:\n {\n bpStrength:\n {\n animType: \"cosOscillation\",\n val1: 0,\n val2: 0.65,\n loopDuration: 3500,\n }\n }\n }];\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 3200000, + "flags": {}, + "ownership": { + "default": 0 + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!FBQzhLveCvFKOvJ7" +} diff --git a/src/packs/_source/tmMacros/10-t02-pinch-transform.json b/src/packs/_source/tmMacros/10-t02-pinch-transform.json new file mode 100644 index 0000000..488ab60 --- /dev/null +++ b/src/packs/_source/tmMacros/10-t02-pinch-transform.json @@ -0,0 +1,24 @@ +{ + "_id": "wT26Z1cjH4pFmtFO", + "name": "10 - T02 - Pinch (transform)", + "type": "script", + "author": "Njc5YzFjZDI5NjZl", + "img": "modules/tokenmagic/gui/macros/images/10%20-%20T02%20-%20Pinch%20%28transform%29.webp", + "scope": "global", + "command": "let params =\n [{\n filterType: \"transform\",\n filterId: \"myPinchTransform\",\n bpRadiusPercent: 70,\n padding: 100,\n animated:\n {\n bpStrength:\n {\n animType: \"cosOscillation\",\n val1: 0,\n val2: -0.65,\n loopDuration: 3500,\n }\n }\n }];\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 11100000, + "flags": {}, + "ownership": { + "default": 0 + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!wT26Z1cjH4pFmtFO" +} diff --git a/src/packs/_source/tmMacros/11-blur.json b/src/packs/_source/tmMacros/11-blur.json new file mode 100644 index 0000000..185f71b --- /dev/null +++ b/src/packs/_source/tmMacros/11-blur.json @@ -0,0 +1,24 @@ +{ + "_id": "CdFhWPKBMb5wj7cM", + "name": "11 - Blur", + "type": "script", + "author": "Njc5YzFjZDI5NjZl", + "img": "modules/tokenmagic/gui/macros/images/11%20-%20Blur.webp", + "scope": "global", + "command": "let params =\n[{\n filterType: \"blur\",\n filterId: \"myBlur\",\n padding: 10,\n quality: 4.0,\n blur: 0,\n blurX: 0,\n blurY: 0,\n animated:\n {\n blurX: \n { \n active: true, \n animType: \"syncCosOscillation\", \n loopDuration: 500, \n val1: 0, \n val2: 6\n },\n blurY: \n { \n active: true, \n animType: \"syncCosOscillation\", \n loopDuration: 750, \n val1: 0, \n val2: 6}\n }\n}];\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 2400000, + "flags": {}, + "ownership": { + "default": 0 + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!CdFhWPKBMb5wj7cM" +} diff --git a/src/packs/_source/tmMacros/12-zoom-blur.json b/src/packs/_source/tmMacros/12-zoom-blur.json new file mode 100644 index 0000000..3e55954 --- /dev/null +++ b/src/packs/_source/tmMacros/12-zoom-blur.json @@ -0,0 +1,24 @@ +{ + "_id": "t2MjFs4cVUCYsbMr", + "name": "12 - Zoom Blur", + "type": "script", + "author": "Njc5YzFjZDI5NjZl", + "img": "modules/tokenmagic/gui/macros/images/12%20-%20Zoom%20Blur.webp", + "scope": "global", + "command": "let params =\n[{\n filterType: \"zoomblur\",\n filterId: \"myZoomBlur\",\n strength: 0.15,\n innerRadiusPercent: 65,\n radiusPercent: 100,\n padding: 30,\n animated:\n {\n innerRadiusPercent: \n { \n active: true, \n animType: \"sinOscillation\", \n loopDuration: 500, \n val1: 65, \n val2: 75\n }\n }\n}];\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 10400000, + "flags": {}, + "ownership": { + "default": 0 + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!t2MjFs4cVUCYsbMr" +} diff --git a/src/packs/_source/tmMacros/13-shockwave-wave.json b/src/packs/_source/tmMacros/13-shockwave-wave.json new file mode 100644 index 0000000..9bc618d --- /dev/null +++ b/src/packs/_source/tmMacros/13-shockwave-wave.json @@ -0,0 +1,28 @@ +{ + "_id": "r3JzTibAUnlpgPsD", + "name": "13 - Shockwave (wave)", + "type": "script", + "author": "Njc5YzFjZDI5NjZl", + "img": "modules/tokenmagic/gui/macros/images/13%20-%20Shockwave%20%28wave%29.webp", + "scope": "global", + "command": "// Below, you can turn on the anchor animation.\nlet params =\n[{\n filterType: \"wave\",\n filterId: \"myShockwave\",\n time: 0,\n strength: 0.03,\n frequency: 15,\n maxIntensity: 4.0,\n minIntensity: 0.5,\n padding:25,\n animated :\n {\n time : \n { \n active: true, \n speed: 0.0180,\n animType: \"move\",\n }\n }\n}];\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 9900000, + "flags": { + "furnace": { + "runAsGM": false + } + }, + "ownership": { + "default": 0 + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!r3JzTibAUnlpgPsD" +} diff --git a/src/packs/_source/tmMacros/14-remove-shadow.json b/src/packs/_source/tmMacros/14-remove-shadow.json new file mode 100644 index 0000000..3ab4ccc --- /dev/null +++ b/src/packs/_source/tmMacros/14-remove-shadow.json @@ -0,0 +1,24 @@ +{ + "_id": "H3rF4XGEf76ZylwP", + "name": "14 - Remove Shadow", + "type": "script", + "author": "Njc5YzFjZDI5NjZl", + "img": "modules/tokenmagic/gui/macros/images/14%20-%20Remove%20Shadow.webp", + "scope": "global", + "command": "// this simple filter remove pixels with a certain amount of alpha\n// it can be useful to remove shadows before using glow or outline filters.\n\nlet params =\n[{\n filterType: \"zapshadow\",\n filterId: \"myZap\",\n alphaTolerance: 0.45,\n rank: 2\n}];\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 3700000, + "flags": {}, + "ownership": { + "default": 0 + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!H3rF4XGEf76ZylwP" +} diff --git a/src/packs/_source/tmMacros/15-cosmic-ray.json b/src/packs/_source/tmMacros/15-cosmic-ray.json new file mode 100644 index 0000000..0f5dc3b --- /dev/null +++ b/src/packs/_source/tmMacros/15-cosmic-ray.json @@ -0,0 +1,24 @@ +{ + "_id": "37aHASDQzFvbqmJG", + "name": "15 - Cosmic Ray", + "type": "script", + "author": "Njc5YzFjZDI5NjZl", + "img": "modules/tokenmagic/gui/macros/images/15%20-%20Cosmic%20Ray.webp", + "scope": "global", + "command": "let params =\n[{\n filterType: \"ray\",\n filterId : \"myRay\",\n time: 0,\n color: 0xCF8000,\n alpha: 0.5,\n divisor: 32,\n anchorX: 0,\n anchorY: 0,\n animated :\n {\n time : \n { \n active: true, \n speed: 0.0005, \n animType: \"move\" \n }\n }\n}];\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 600000, + "flags": {}, + "ownership": { + "default": 0 + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!37aHASDQzFvbqmJG" +} diff --git a/src/packs/_source/tmMacros/16-inner-fog.json b/src/packs/_source/tmMacros/16-inner-fog.json new file mode 100644 index 0000000..d372374 --- /dev/null +++ b/src/packs/_source/tmMacros/16-inner-fog.json @@ -0,0 +1,28 @@ +{ + "_id": "Edw0KaZiBtWEG86g", + "name": "16 - Inner Fog", + "type": "script", + "author": "Njc5YzFjZDI5NjZl", + "img": "modules/tokenmagic/gui/macros/images/16%20-%20Inner%20Fog.webp", + "scope": "global", + "command": "let params =\n[{\n filterType: \"fog\",\n filterId: \"myFog\",\n color: 0x000000,\n density: 0.65,\n time: 0,\n dimX: 1,\n dimY: 1,\n animated :\n {\n time : \n { \n active: true, \n speed: 2.2, \n animType: \"move\" \n }\n }\n}];\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 2900000, + "flags": { + "furnace": { + "runAsGM": false + } + }, + "ownership": { + "default": 0 + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!Edw0KaZiBtWEG86g" +} diff --git a/src/packs/_source/tmMacros/17-fumes.json b/src/packs/_source/tmMacros/17-fumes.json new file mode 100644 index 0000000..107bc25 --- /dev/null +++ b/src/packs/_source/tmMacros/17-fumes.json @@ -0,0 +1,28 @@ +{ + "_id": "ebWbFeiJP8UZG4Fd", + "name": "17 - Fumes", + "type": "script", + "author": "Njc5YzFjZDI5NjZl", + "img": "modules/tokenmagic/gui/macros/images/17%20-%20Fumes.webp", + "scope": "global", + "command": "let params =\n[{\n filterType: \"fumes\",\n filterId: \"myFumes\",\n color: 0x808080,\n time: 0,\n blend: 8,\n animated :\n {\n time : \n { \n active: true, \n speed: 0.001, \n animType: \"move\" \n }\n }\n}];\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 8200000, + "flags": { + "furnace": { + "runAsGM": false + } + }, + "ownership": { + "default": 0 + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!ebWbFeiJP8UZG4Fd" +} diff --git a/src/packs/_source/tmMacros/18-electric.json b/src/packs/_source/tmMacros/18-electric.json new file mode 100644 index 0000000..9e65b4a --- /dev/null +++ b/src/packs/_source/tmMacros/18-electric.json @@ -0,0 +1,28 @@ +{ + "_id": "YJjeB7N0L1rGfZD2", + "name": "18 - Electric", + "type": "script", + "author": "Njc5YzFjZDI5NjZl", + "img": "modules/tokenmagic/gui/macros/images/18%20-%20Electric.webp", + "scope": "global", + "command": "// Because the shader is dynamically compiled,\n// intensity is a one time init and can't be updated.\n// you must delete the filters to \"change\" it.\nlet params =\n[{\n filterType: \"electric\",\n filterId: \"myElectric\",\n color: 0xFFFFFF,\n time: 0,\n blend: 1,\n intensity: 5,\n animated :\n {\n time : \n { \n active: true, \n speed: 0.0020, \n animType: \"move\" \n }\n }\n}];\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 7000000, + "flags": { + "furnace": { + "runAsGM": false + } + }, + "ownership": { + "default": 0 + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!YJjeB7N0L1rGfZD2" +} diff --git a/src/packs/_source/tmMacros/19-t01-fire.json b/src/packs/_source/tmMacros/19-t01-fire.json new file mode 100644 index 0000000..9d8dd10 --- /dev/null +++ b/src/packs/_source/tmMacros/19-t01-fire.json @@ -0,0 +1,24 @@ +{ + "_id": "F47j6ivhmXxeYVmY", + "name": "19 - T01 - Fire", + "type": "script", + "author": "Njc5YzFjZDI5NjZl", + "img": "modules/tokenmagic/gui/macros/images/19%20-%20T01%20-%20Fire.webp", + "scope": "global", + "command": "let params =\n[{\n filterType: \"fire\",\n filterId: \"myFire\",\n intensity: 1,\n color: 0xFFFFFF,\n amplitude: 1,\n time: 0,\n blend: 2,\n fireBlend : 1,\n animated :\n {\n time : \n { \n active: true, \n speed: -0.0024, \n animType: \"move\" \n },\n intensity:\n {\n active:true,\n loopDuration: 15000,\n val1: 0.8,\n val2: 2,\n animType: \"syncCosOscillation\"\n },\n amplitude:\n {\n active:true,\n loopDuration: 4400,\n val1: 1,\n val2: 1.4,\n animType: \"syncCosOscillation\"\n }\n \n }\n}];\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 3100000, + "flags": {}, + "ownership": { + "default": 0 + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!F47j6ivhmXxeYVmY" +} diff --git a/src/packs/_source/tmMacros/19-t02-devouring-fire.json b/src/packs/_source/tmMacros/19-t02-devouring-fire.json new file mode 100644 index 0000000..3f1a65d --- /dev/null +++ b/src/packs/_source/tmMacros/19-t02-devouring-fire.json @@ -0,0 +1,24 @@ +{ + "_id": "Gec6BaJMehMO7p7v", + "name": "19 - T02 - Devouring Fire", + "type": "script", + "author": "Njc5YzFjZDI5NjZl", + "img": "modules/tokenmagic/gui/macros/images/19%20-%20T02%20-%20Devouring%20Fire.webp", + "scope": "global", + "command": "let params =\n[{\n filterType: \"fire\",\n filterId: \"myFire\",\n intensity: 3,\n color: 0xFFFFFF,\n amplitude: 2,\n time: 0,\n blend: 10,\n fireBlend : 1,\n alphaDiscard: true,\n zOrder: 50,\n animated :\n {\n time : \n { \n active: true, \n speed: -0.0024, \n animType: \"move\" \n }\n }\n},{\n filterType: \"glow\",\n filterId: \"glowripples\",\n outerStrength: 4,\n innerStrength: 2,\n color: 0xAA6500,\n quality: 0.5,\n padding: 10,\n zOrder: 100,\n}];\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 3500000, + "flags": {}, + "ownership": { + "default": 0 + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!Gec6BaJMehMO7p7v" +} diff --git a/src/packs/_source/tmMacros/20-waves.json b/src/packs/_source/tmMacros/20-waves.json new file mode 100644 index 0000000..f302359 --- /dev/null +++ b/src/packs/_source/tmMacros/20-waves.json @@ -0,0 +1,24 @@ +{ + "_id": "DoXvYWKPRcTpHbPG", + "name": "20 - Waves", + "type": "script", + "author": "Njc5YzFjZDI5NjZl", + "img": "modules/tokenmagic/gui/macros/images/20%20-%20Waves.webp", + "scope": "global", + "command": "// Below, you can turn on the anchor animation.\nlet params =\n[{\n filterType: \"wave\",\n filterId: \"myWaves\",\n time: 0,\n anchorX: 0.5,\n anchorY: 0.5,\n strength: 0.015,\n frequency: 120,\n color: 0xFFFFFF,\n maxIntensity: 2.5,\n minIntensity: 0.9,\n padding:10,\n animated :\n {\n time : \n { \n active: true, \n speed: 0.0085, \n animType: \"move\" \n },\n anchorX :\n {\n active: false,\n val1: 0.15,\n val2: 0.85,\n animType: \"syncChaoticOscillation\",\n loopDuration: 20000\n },\n anchorY :\n {\n active: false,\n val1: 0.15,\n val2: 0.85,\n animType: \"syncSinOscillation\",\n loopDuration: 20000\n }\n }\n}];\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 2800000, + "flags": {}, + "ownership": { + "default": 0 + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!DoXvYWKPRcTpHbPG" +} diff --git a/src/packs/_source/tmMacros/21-flood.json b/src/packs/_source/tmMacros/21-flood.json new file mode 100644 index 0000000..ffb9443 --- /dev/null +++ b/src/packs/_source/tmMacros/21-flood.json @@ -0,0 +1,24 @@ +{ + "_id": "zCCp4x0EResFji7O", + "name": "21 - Flood", + "type": "script", + "author": "Njc5YzFjZDI5NjZl", + "img": "modules/tokenmagic/gui/macros/images/21%20-%20Flood.webp", + "scope": "global", + "command": "let params =\n[{\n filterType: \"flood\",\n filterId: \"myFlood\",\n time: 0,\n color: 0x0020BB,\n billowy: 0.43,\n tintIntensity: 0.72,\n glint: 0.31,\n scale: 70,\n padding: 10,\n animated :\n {\n time : \n { \n active: true, \n speed: 0.0006, \n animType: \"move\"\n }\n }\n}];\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 11800000, + "flags": {}, + "ownership": { + "default": 0 + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!zCCp4x0EResFji7O" +} diff --git a/src/packs/_source/tmMacros/22-smoke.json b/src/packs/_source/tmMacros/22-smoke.json new file mode 100644 index 0000000..d9c5045 --- /dev/null +++ b/src/packs/_source/tmMacros/22-smoke.json @@ -0,0 +1,24 @@ +{ + "_id": "2zRNjnw7Ps26h5xz", + "name": "22 - Smoke", + "type": "script", + "author": "Njc5YzFjZDI5NjZl", + "img": "modules/tokenmagic/gui/macros/images/22%20-%20Smoke.webp", + "scope": "global", + "command": "let params =\n[{\n filterType: \"smoke\",\n filterId: \"mySmoke\",\n color: 0x50FFAA,\n time: 0,\n blend: 2,\n dimX: 1,\n dimY: 1,\n animated :\n {\n time : \n { \n active: true, \n speed: 0.0015, \n animType: \"move\"\n }\n }\n}];\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 400000, + "flags": {}, + "ownership": { + "default": 0 + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!2zRNjnw7Ps26h5xz" +} diff --git a/src/packs/_source/tmMacros/23-t01-mirror-images.json b/src/packs/_source/tmMacros/23-t01-mirror-images.json new file mode 100644 index 0000000..6eb8fb8 --- /dev/null +++ b/src/packs/_source/tmMacros/23-t01-mirror-images.json @@ -0,0 +1,24 @@ +{ + "_id": "Ac6lTCiwnycb2Hbw", + "name": "23 - T01 - Mirror Images", + "type": "script", + "author": "Njc5YzFjZDI5NjZl", + "img": "modules/tokenmagic/gui/macros/images/23%20-%20T01%20-%20Mirror%20Images.webp", + "scope": "global", + "command": "let params =\n[{\n filterType: \"images\",\n filterId: \"myMirrorImages\",\n time: 0,\n nbImage: 4,\n alphaImg: 1.0,\n alphaChr: 0.0,\n blend: 4,\n ampX: 0.10,\n ampY: 0.10,\n zOrder: 20,\n animated :\n {\n time: \n { \n active: true, \n speed: 0.0010, \n animType: \"move\" \n }\n }\n}];\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 1800000, + "flags": {}, + "ownership": { + "default": 0 + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!Ac6lTCiwnycb2Hbw" +} diff --git a/src/packs/_source/tmMacros/23-t02-chaotic-images.json b/src/packs/_source/tmMacros/23-t02-chaotic-images.json new file mode 100644 index 0000000..d000901 --- /dev/null +++ b/src/packs/_source/tmMacros/23-t02-chaotic-images.json @@ -0,0 +1,24 @@ +{ + "_id": "ycesEG9gnQecVsDM", + "name": "23 - T02 - Chaotic Images", + "type": "script", + "author": "Njc5YzFjZDI5NjZl", + "img": "modules/tokenmagic/gui/macros/images/23%20-%20T02%20-%20Chaotic%20Images.webp", + "scope": "global", + "command": "// This is an extreme example...\nlet params =\n[{\n filterType: \"images\",\n filterId: \"myChaoticImages\",\n time: 0,\n nbImage: 4,\n alphaImg: 1.0,\n alphaChr: 0.0,\n blend: 4,\n ampX: 0.10,\n ampY: 0.10,\n padding: 80,\n zOrder: 20,\n animated :\n {\n time: \n { \n active: true, \n speed: 0.0010, \n animType: \"move\" \n },\n ampX:\n {\n active: true,\n val1: 0.00,\n val2: 0.30,\n chaosFactor: 0.03,\n animType: \"syncChaoticOscillation\",\n loopDuration: 2000\n },\n ampY:\n {\n active: true,\n val1: 0.00,\n val2: 0.30,\n chaosFactor: 0.04,\n animType: \"syncChaoticOscillation\",\n loopDuration: 1650\n },\n alphaChr: \n { \n active: true, \n animType: \"randomNumberPerLoop\", \n val1: 0.0, \n val2: 1,\n loopDuration: 250\n },\n alphaImg: \n { \n active: true, \n animType: \"randomNumberPerLoop\", \n val1: 0.8, \n val2: 1,\n loopDuration: 250\n },\n nbImage:\n {\n active: true,\n val1: 1,\n val2: 9,\n animType: \"syncSinOscillation\",\n loopDuration: 1400\n }\n }\n}];\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 11600000, + "flags": {}, + "ownership": { + "default": 0 + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!ycesEG9gnQecVsDM" +} diff --git a/src/packs/_source/tmMacros/23-t03-spectral-images.json b/src/packs/_source/tmMacros/23-t03-spectral-images.json new file mode 100644 index 0000000..4b18f5a --- /dev/null +++ b/src/packs/_source/tmMacros/23-t03-spectral-images.json @@ -0,0 +1,24 @@ +{ + "_id": "UEsyHtvWqlOGbUAG", + "name": "23 - T03 - Spectral Images", + "type": "script", + "author": "Njc5YzFjZDI5NjZl", + "img": "modules/tokenmagic/gui/macros/images/23%20-%20T03%20-%20Spectral%20Images.webp", + "scope": "global", + "command": "// Another extreme example...\nlet params =\n[{\n filterType: \"images\",\n filterId: \"mySpectralImages\",\n time: 0, \n blend: 4,\n nbImage: 4, \n padding: 0,\n alphaImg: 0.5, \n alphaChr: 0.0,\n ampX: 0.10, \n ampY: 0.10,\n zOrder: 20,\n animated :\n {\n time: \n { \n speed: 0.0010, \n animType: \"move\" \n },\n ampX:\n {\n val1: 0, val2: 0.22,\n animType: \"syncCosOscillation\",\n loopDuration: 2500\n },\n ampY:\n {\n val1: 0, val2: 0.28,\n animType: \"syncCosOscillation\",\n loopDuration: 2500,\n },\n alphaChr: \n {\n val1: 1, val2: 0,\n animType: \"syncCosOscillation\",\n loopDuration: 2500\n },\n alphaImg: \n {\n val1: 0.2, val2: 0.8,\n animType: \"syncSinOscillation\",\n loopDuration: 2500\n }\n }\n}];\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 6100000, + "flags": {}, + "ownership": { + "default": 0 + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!UEsyHtvWqlOGbUAG" +} diff --git a/src/packs/_source/tmMacros/24-t01-hexa-force-field-2.json b/src/packs/_source/tmMacros/24-t01-hexa-force-field-2.json new file mode 100644 index 0000000..2f25747 --- /dev/null +++ b/src/packs/_source/tmMacros/24-t01-hexa-force-field-2.json @@ -0,0 +1,24 @@ +{ + "_id": "cqKydeDi9ay4PKdf", + "name": "24 - T01 - Hexa Force Field 2", + "type": "script", + "author": "Njc5YzFjZDI5NjZl", + "img": "modules/tokenmagic/gui/macros/images/24%20-%20T01%20-%20Hexa%20Force%20Field%202.webp", + "scope": "global", + "command": "let params =\n[{\n filterType: \"field\",\n filterId: \"myHexaField\",\n shieldType: 2,\n gridPadding: 2,\n color: 0x00CCDD,\n time: 0,\n blend: 2,\n intensity: 0.95,\n lightAlpha: 0,\n lightSize: 0,\n scale: 0.75,\n radius: 1,\n chromatic: false,\n alphaDiscard: true,\n zOrder: 5000,\n animated :\n {\n time : \n { \n active: true, \n speed: 0.0015, \n animType: \"move\" \n }\n }\n}];\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 7800000, + "flags": {}, + "ownership": { + "default": 0 + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!cqKydeDi9ay4PKdf" +} diff --git a/src/packs/_source/tmMacros/24-t01-hexa-force-field-3-scintillating.json b/src/packs/_source/tmMacros/24-t01-hexa-force-field-3-scintillating.json new file mode 100644 index 0000000..d3bb46f --- /dev/null +++ b/src/packs/_source/tmMacros/24-t01-hexa-force-field-3-scintillating.json @@ -0,0 +1,24 @@ +{ + "_id": "HfaGElkKX6xXf3zV", + "name": "24 - T01 - Hexa Force Field 3 - Scintillating", + "type": "script", + "author": "Njc5YzFjZDI5NjZl", + "img": "modules/tokenmagic/gui/macros/images/24%20-%20T01%20-%20Hexa%20Force%20Field%203%20-%20Scintillating.webp", + "scope": "global", + "command": "let params =\n[{\n filterType: \"field\",\n filterId: \"myHexaField\",\n shieldType: 2,\n gridPadding: 2,\n color: 0x00CCDD,\n time: 0,\n blend: 2,\n intensity: 1,\n lightAlpha: 0,\n lightSize: 0,\n scale: 2,\n radius: 0.98,\n chromatic: false,\n discardThreshold: 0.13,\n alphaDiscard: true,\n animated :\n {\n time : \n { \n active: true, \n speed: 0.0015, \n animType: \"move\" \n }\n }\n},\n{\n filterType: \"xglow\",\n filterId: \"myBurningAura\",\n auraType: 2,\n color: 0x500050,\n scale: 1.,\n time: 0,\n auraIntensity: 1,\n subAuraIntensity: 0,\n threshold: 0,\n discard: false,\n zOrder: 3000,\n animated:\n {\n time : \n { \n active: true,\n speed: 0.0027, \n animType: \"move\" \n },\n thickness:\n {\n active: true,\n loopDuration: 6000, \n animType: \"cosOscillation\", \n val1:2, \n val2:4\n }\n }\n}];\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 3800000, + "flags": {}, + "ownership": { + "default": 0 + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!HfaGElkKX6xXf3zV" +} diff --git a/src/packs/_source/tmMacros/24-t01-hexa-force-field.json b/src/packs/_source/tmMacros/24-t01-hexa-force-field.json new file mode 100644 index 0000000..8a7e8c4 --- /dev/null +++ b/src/packs/_source/tmMacros/24-t01-hexa-force-field.json @@ -0,0 +1,24 @@ +{ + "_id": "sbP8KX50YRYtxVyB", + "name": "24 - T01 - Hexa Force Field", + "type": "script", + "author": "Njc5YzFjZDI5NjZl", + "img": "modules/tokenmagic/gui/macros/images/24%20-%20T01%20-%20Hexa%20Force%20Field.webp", + "scope": "global", + "command": "let params =\n[{\n filterType: \"field\",\n filterId: \"myHexaField\",\n shieldType: 2,\n gridPadding: 2,\n color: 0xCC00CC,\n time: 0,\n blend: 3,\n intensity: 1,\n lightAlpha: 0.5,\n lightSize: 0.5,\n scale: 0.5,\n radius: 1,\n chromatic: false,\n alphaDiscard: true,\n zOrder: 5000,\n animated :\n {\n time : \n { \n active: true, \n speed: 0.0015, \n animType: \"move\" \n }\n }\n}];\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 10200000, + "flags": {}, + "ownership": { + "default": 0 + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!sbP8KX50YRYtxVyB" +} diff --git a/src/packs/_source/tmMacros/24-t02-fire-shield-2.json b/src/packs/_source/tmMacros/24-t02-fire-shield-2.json new file mode 100644 index 0000000..ee12778 --- /dev/null +++ b/src/packs/_source/tmMacros/24-t02-fire-shield-2.json @@ -0,0 +1,24 @@ +{ + "_id": "WdxUWiUJALQVSO81", + "name": "24 - T02 - Fire Shield 2", + "type": "script", + "author": "Njc5YzFjZDI5NjZl", + "img": "modules/tokenmagic/gui/macros/images/24%20-%20T02%20-%20Fire%20Shield%202.webp", + "scope": "global", + "command": "let params =\n[{\n filterType: \"field\",\n filterId: \"myFireField\",\n shieldType: 1,\n gridPadding: 2,\n color: 0xE58550,\n time: 0,\n blend: 2,\n intensity: 1.2,\n lightAlpha: 1,\n lightSize: 0.7,\n scale: 1,\n radius: 1,\n chromatic: false,\n discardThreshold: 0.5,\n alphaDiscard: true,\n animated :\n {\n time : \n { \n active: true, \n speed: 0.0015, \n animType: \"move\" \n }\n }\n}];\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 6700000, + "flags": {}, + "ownership": { + "default": 0 + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!WdxUWiUJALQVSO81" +} diff --git a/src/packs/_source/tmMacros/24-t02-fire-shield-3-ring.json b/src/packs/_source/tmMacros/24-t02-fire-shield-3-ring.json new file mode 100644 index 0000000..e05675d --- /dev/null +++ b/src/packs/_source/tmMacros/24-t02-fire-shield-3-ring.json @@ -0,0 +1,24 @@ +{ + "_id": "Uw5icMEGsNrCToeV", + "name": "24 - T02 - Fire Shield 3 - Ring", + "type": "script", + "author": "Njc5YzFjZDI5NjZl", + "img": "modules/tokenmagic/gui/macros/images/24%20-%20T02%20-%20Fire%20Shield%203%20-%20Ring.webp", + "scope": "global", + "command": "let params =\n[{\n filterType: \"zapshadow\",\n filterId: \"myZap\",\n alphaTolerance: 0.45\n},{\n filterType: \"field\",\n filterId: \"myFireField\",\n shieldType: 1,\n gridPadding: 1.1,\n color: 0xE58550,\n time: 0,\n blend: 2,\n intensity: 1.2,\n lightAlpha: 1,\n lightSize: 0.7,\n scale: 1,\n radius: 1,\n chromatic: false,\n discardThreshold: 0.9,\n hideRadius: 0.95,\n alphaDiscard: true,\n animated :\n {\n time : \n { \n active: true, \n speed: 0.0015, \n animType: \"move\" \n }\n }\n},{\n filterType: \"xglow\",\n filterId: \"myBurningAura\",\n auraType: 2,\n color: 0x903010,\n thickness: 9.8,\n scale: 4.,\n time: 0,\n auraIntensity: 2,\n subAuraIntensity: 1.5,\n threshold: 0.40,\n discard: true,\n zOrder: 3000,\n animated:\n {\n time : \n { \n active: true,\n speed: 0.0027, \n animType: \"move\" \n },\n thickness:\n {\n active: true,\n loopDuration: 3000, \n animType: \"cosOscillation\", \n val1:2, \n val2:5\n }\n }\n}];\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 6400000, + "flags": {}, + "ownership": { + "default": 0 + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!Uw5icMEGsNrCToeV" +} diff --git a/src/packs/_source/tmMacros/24-t02-fire-shield-4-lava-zone.json b/src/packs/_source/tmMacros/24-t02-fire-shield-4-lava-zone.json new file mode 100644 index 0000000..459d157 --- /dev/null +++ b/src/packs/_source/tmMacros/24-t02-fire-shield-4-lava-zone.json @@ -0,0 +1,24 @@ +{ + "_id": "kyQD90fSuNLDI4Y0", + "name": "24 - T02 - Fire Shield 4 - Lava Zone", + "type": "script", + "author": "Njc5YzFjZDI5NjZl", + "img": "modules/tokenmagic/gui/macros/images/24%20-%20T02%20-%20Fire%20Shield%204%20-%20Lava%20Zone.webp", + "scope": "global", + "command": "let params =\n[{\n filterType: \"zapshadow\",\n filterId: \"myZap\",\n alphaTolerance: 0.45\n},{\n filterType: \"field\",\n filterId: \"myLavaRing\",\n shieldType: 6,\n gridPadding: 1.25,\n color: 0xFFAA00,\n time: 0,\n blend: 14,\n intensity: 1,\n lightAlpha: 0,\n lightSize: 0.7,\n scale: 1,\n radius: 1,\n chromatic: false,\n discardThreshold: 0.30,\n hideRadius: 0.95,\n alphaDiscard: true,\n animated :\n {\n time : \n { \n active: true, \n speed: 0.0015, \n animType: \"move\" \n },\n radius: \n {\n active: true, \n loopDuration: 6000, \n animType: \"cosOscillation\", \n val1:1, \n val2:0.8\n },\n hideRadius: \n {\n active: true, \n loopDuration: 3000, \n animType: \"cosOscillation\", \n val1:0.75, \n val2:0.4\n }\n }\n},{\n filterType: \"xglow\",\n filterId: \"myBurningAura\",\n auraType: 2,\n color: 0xFF5000,\n thickness: 9.8,\n scale: 1.,\n time: 0,\n auraIntensity: 2,\n subAuraIntensity: 1,\n threshold: 0.30,\n discard: true,\n zOrder: 3000,\n animated:\n {\n time : \n { \n active: true,\n speed: 0.0027, \n animType: \"move\" \n },\n thickness:\n {\n active: true,\n loopDuration: 600, \n animType: \"cosOscillation\", \n val1:4, \n val2:8\n }\n }\n}];\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 9400000, + "flags": {}, + "ownership": { + "default": 0 + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!kyQD90fSuNLDI4Y0" +} diff --git a/src/packs/_source/tmMacros/24-t02-fire-shield.json b/src/packs/_source/tmMacros/24-t02-fire-shield.json new file mode 100644 index 0000000..6018b46 --- /dev/null +++ b/src/packs/_source/tmMacros/24-t02-fire-shield.json @@ -0,0 +1,24 @@ +{ + "_id": "IA3ofbRDpi3Rjgcy", + "name": "24 - T02 - Fire Shield", + "type": "script", + "author": "Njc5YzFjZDI5NjZl", + "img": "modules/tokenmagic/gui/macros/images/24%20-%20T02%20-%20Fire%20Shield.webp", + "scope": "global", + "command": "let params =\n[{\n filterType: \"field\",\n filterId: \"myFireField\",\n shieldType: 1,\n gridPadding: 2,\n color: 0xE58550,\n time: 0,\n blend: 2,\n intensity: 1.2,\n lightAlpha: 1,\n lightSize: 0.7,\n scale: 1,\n radius: 1,\n chromatic: false,\n zOrder: 512,\n animated :\n {\n time : \n { \n active: true, \n speed: 0.0015, \n animType: \"move\" \n }\n }\n}];\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 4000000, + "flags": {}, + "ownership": { + "default": 0 + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!IA3ofbRDpi3Rjgcy" +} diff --git a/src/packs/_source/tmMacros/24-t03-poisoned-smoke.json b/src/packs/_source/tmMacros/24-t03-poisoned-smoke.json new file mode 100644 index 0000000..7b4c0ee --- /dev/null +++ b/src/packs/_source/tmMacros/24-t03-poisoned-smoke.json @@ -0,0 +1,24 @@ +{ + "_id": "SSY0fjib0PgJaKEK", + "name": "24 - T03 - Poisoned Smoke", + "type": "script", + "author": "Njc5YzFjZDI5NjZl", + "img": "modules/tokenmagic/gui/macros/images/24%20-%20T03%20-%20Poisoned%20Smoke.webp", + "scope": "global", + "command": "let params =\n[{\n filterType: \"field\",\n filterId: \"mySmokeField\",\n shieldType: 3,\n gridPadding: 1,\n color: 0x60CC70,\n time: 0,\n blend: 0,\n intensity: 0.9,\n lightAlpha: 1,\n lightSize: 0.7,\n scale: 1,\n radius: 1,\n chromatic: false,\n zOrder: 512,\n animated :\n {\n time : \n { \n active: true, \n speed: 0.0015, \n animType: \"move\" \n }\n }\n}];\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 5400000, + "flags": {}, + "ownership": { + "default": 0 + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!SSY0fjib0PgJaKEK" +} diff --git a/src/packs/_source/tmMacros/24-t04-shell-earth.json b/src/packs/_source/tmMacros/24-t04-shell-earth.json new file mode 100644 index 0000000..993003c --- /dev/null +++ b/src/packs/_source/tmMacros/24-t04-shell-earth.json @@ -0,0 +1,24 @@ +{ + "_id": "359Mw23cvaEDevkP", + "name": "24 - T04 - Shell - Earth", + "type": "script", + "author": "Njc5YzFjZDI5NjZl", + "img": "modules/tokenmagic/gui/macros/images/24%20-%20T04%20-%20Shell%20-%20Earth.webp", + "scope": "global", + "command": "let params =\n[{\n filterType: \"field\",\n filterId: \"myEarthField\",\n shieldType: 4,\n gridPadding: 2,\n color: 0xBB9070,\n time: 0,\n blend: 1,\n intensity: 1.25,\n lightAlpha: 1,\n lightSize: 0.7,\n scale: 1,\n radius: 1,\n chromatic: false,\n animated :\n {\n time : \n { \n active: true, \n speed: 0.0015, \n animType: \"move\" \n }\n }\n}];\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 500000, + "flags": {}, + "ownership": { + "default": 0 + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!359Mw23cvaEDevkP" +} diff --git a/src/packs/_source/tmMacros/24-t04-shell-moving-ice-disc.json b/src/packs/_source/tmMacros/24-t04-shell-moving-ice-disc.json new file mode 100644 index 0000000..af2ff6c --- /dev/null +++ b/src/packs/_source/tmMacros/24-t04-shell-moving-ice-disc.json @@ -0,0 +1,24 @@ +{ + "_id": "tZZaP7yvqdNnqF2L", + "name": "24 - T04 - Shell - Moving Ice Disc", + "type": "script", + "author": "Njc5YzFjZDI5NjZl", + "img": "modules/tokenmagic/gui/macros/images/24%20-%20T04%20-%20Shell%20-%20Moving%20Ice%20Disc.webp", + "scope": "global", + "command": "let params =\n[{\n filterType: \"field\",\n filterId: \"myIceField\",\n shieldType: 14,\n gridPadding: 1.25,\n color: 0x409090,\n time: 0,\n blend: 9,\n intensity: 1,\n lightAlpha: 2,\n lightSize: 1,\n scale: 1,\n radius: 0.97,\n chromatic: false,\n discardThreshold: 0.2,\n alphaDiscard: true,\n animated :\n {\n posLightX:\n {\n active: true,\n val1: 0.25,\n val2: 0.75,\n animType: \"syncCosOscillation\",\n loopDuration: 5000\n },\n posLightY:\n {\n active: true,\n val1: 0.25,\n val2: 0.75,\n animType: \"syncSinOscillation\",\n loopDuration: 5000\n },\n lightSize:\n {\n active: true,\n val1: 0.95,\n val2: 1.05,\n animType: \"sinOscillation\",\n loopDuration: 900\n }\n }\n},{\n filterType: \"xglow\",\n filterId: \"myIceField\",\n auraType: 1,\n color: 0x5099DD,\n thickness: 4.5,\n scale: 1,\n time: 0,\n auraIntensity: 0.25,\n subAuraIntensity: 0.25,\n threshold: 0.1,\n discard: false,\n zOrder: 3000,\n animated:\n {\n time:\n {\n active: true,\n speed: 0.0018,\n animType: \"move\"\n },\n thickness:\n {\n val1: 2, val2: 2.5,\n animType: \"cosOscillation\",\n loopDuration: 3000\n },\n subAuraIntensity:\n {\n val1: 0.45, val2: 0.65,\n animType: \"cosOscillation\",\n loopDuration: 6000\n },\n auraIntensity:\n {\n val1: 0.9, val2: 2.2,\n animType: \"cosOscillation\",\n loopDuration: 3000\n }\n }\n }];\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 10500000, + "flags": {}, + "ownership": { + "default": 0 + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!tZZaP7yvqdNnqF2L" +} diff --git a/src/packs/_source/tmMacros/24-t05-mega-chroma-shell-on-top.json b/src/packs/_source/tmMacros/24-t05-mega-chroma-shell-on-top.json new file mode 100644 index 0000000..6a1a176 --- /dev/null +++ b/src/packs/_source/tmMacros/24-t05-mega-chroma-shell-on-top.json @@ -0,0 +1,24 @@ +{ + "_id": "LrfXNjrImAWK5Hb2", + "name": "24 - T05 - Mega - Chroma Shell (on top)", + "type": "script", + "author": "Njc5YzFjZDI5NjZl", + "img": "modules/tokenmagic/gui/macros/images/24%20-%20T05%20-%20Mega%20-%20Chroma%20Shell%20%28on%20top%29.webp", + "scope": "global", + "command": "let params =\n[{\n filterType: \"field\",\n filterId: \"myEarthFieldTop\",\n shieldType: 5,\n gridPadding: 3,\n color: 0xAAAAAA,\n time: 0,\n blend: 5,\n intensity: 1.9,\n lightAlpha: 1,\n lightSize: 0.7,\n scale: 1,\n radius: 1,\n zIndex: 5,\n chromatic: true,\n zOrder: 512,\n animated :\n {\n time : \n { \n active: true, \n speed: 0.0015, \n animType: \"move\" \n }\n }\n}];\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 4700000, + "flags": {}, + "ownership": { + "default": 0 + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!LrfXNjrImAWK5Hb2" +} diff --git a/src/packs/_source/tmMacros/24-t05-mega-ice-shell-on-top.json b/src/packs/_source/tmMacros/24-t05-mega-ice-shell-on-top.json new file mode 100644 index 0000000..a06d776 --- /dev/null +++ b/src/packs/_source/tmMacros/24-t05-mega-ice-shell-on-top.json @@ -0,0 +1,24 @@ +{ + "_id": "QHFSZ2GTB3gdDijZ", + "name": "24 - T05 - Mega - Ice Shell (on top)", + "type": "script", + "author": "Njc5YzFjZDI5NjZl", + "img": "modules/tokenmagic/gui/macros/images/24%20-%20T05%20-%20Mega%20-%20Ice%20Shell%20%28on%20top%29.webp", + "scope": "global", + "command": "let params =\n[{\n filterType: \"field\",\n filterId: \"myEarthFieldTop\",\n shieldType: 5,\n gridPadding: 3,\n color: 0x00DDFF,\n time: 0,\n blend: 5,\n intensity: 1.9,\n lightAlpha: 0,\n lightSize: 0,\n scale: 1,\n radius: 1,\n zIndex: 5,\n discardThreshold: 0.09,\n alphaDiscard: true,\n animated :\n {\n time : \n { \n active: true, \n speed: 0.0015, \n animType: \"move\" \n }\n }\n},\n {\n filterType: \"xglow\",\n filterId: \"myEarthFieldTopGlow\",\n auraType: 1,\n color: 0x5099DD,\n thickness: 4.5,\n scale: 1,\n time: 0,\n auraIntensity: 0.25,\n subAuraIntensity: 1,\n threshold: 0.5,\n discard: false,\n zOrder: 3000,\n animated:\n {\n time:\n {\n active: true,\n speed: 0.0018,\n animType: \"move\"\n },\n thickness:\n {\n val1: 2, val2: 2.5,\n animType: \"cosOscillation\",\n loopDuration: 3000\n },\n subAuraIntensity:\n {\n val1: 0.45, val2: 0.65,\n animType: \"cosOscillation\",\n loopDuration: 6000\n },\n auraIntensity:\n {\n val1: 0.9, val2: 2.2,\n animType: \"cosOscillation\",\n loopDuration: 3000\n }\n }\n }];\n\nTokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 5000000, + "flags": {}, + "ownership": { + "default": 0 + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!QHFSZ2GTB3gdDijZ" +} diff --git a/src/packs/_source/tmMacros/24-t06-air-bubble-2.json b/src/packs/_source/tmMacros/24-t06-air-bubble-2.json new file mode 100644 index 0000000..b21e581 --- /dev/null +++ b/src/packs/_source/tmMacros/24-t06-air-bubble-2.json @@ -0,0 +1,24 @@ +{ + "_id": "etT28F5qKw6PpXq5", + "name": "24 - T06 - Air Bubble 2", + "type": "script", + "author": "Njc5YzFjZDI5NjZl", + "img": "modules/tokenmagic/gui/macros/images/24%20-%20T06%20-%20Air%20Bubble%202.webp", + "scope": "global", + "command": "let params =\n[{\n filterType: \"field\",\n filterId: \"myAirField\",\n shieldType: 6,\n gridPadding: 1.2,\n color: 0x7090AA,\n time: 0,\n blend: 2,\n intensity: 1,\n lightAlpha: 0,\n lightSize: 0,\n scale: 1,\n radius: 1,\n chromatic: false,\n discardThreshold: 0.1,\n alphaDiscard: true,\n animated :\n {\n time : \n { \n active: true, \n speed: 0.0015, \n animType: \"move\" \n }\n }\n}];\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 8300000, + "flags": {}, + "ownership": { + "default": 0 + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!etT28F5qKw6PpXq5" +} diff --git a/src/packs/_source/tmMacros/24-t06-air-bubble.json b/src/packs/_source/tmMacros/24-t06-air-bubble.json new file mode 100644 index 0000000..8f1278c --- /dev/null +++ b/src/packs/_source/tmMacros/24-t06-air-bubble.json @@ -0,0 +1,24 @@ +{ + "_id": "6Do4AOxfbtCG8R4j", + "name": "24 - T06 - Air Bubble", + "type": "script", + "author": "Njc5YzFjZDI5NjZl", + "img": "modules/tokenmagic/gui/macros/images/24%20-%20T06%20-%20Air%20Bubble.webp", + "scope": "global", + "command": "let params =\n[{\n filterType: \"field\",\n filterId: \"myAirField\",\n shieldType: 6,\n gridPadding: 1.2,\n color: 0x7090AA,\n time: 0,\n blend: 1,\n intensity: 1,\n lightAlpha: 1,\n lightSize: 0.7,\n scale: 1,\n radius: 1,\n chromatic: false,\n zOrder: 512,\n animated :\n {\n time : \n { \n active: true, \n speed: 0.0015, \n animType: \"move\" \n }\n }\n}];\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 1100000, + "flags": {}, + "ownership": { + "default": 0 + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!6Do4AOxfbtCG8R4j" +} diff --git a/src/packs/_source/tmMacros/24-t07-mage-armor-2.json b/src/packs/_source/tmMacros/24-t07-mage-armor-2.json new file mode 100644 index 0000000..6789a5f --- /dev/null +++ b/src/packs/_source/tmMacros/24-t07-mage-armor-2.json @@ -0,0 +1,24 @@ +{ + "_id": "Ii7MvSDFFEKMavuM", + "name": "24 - T07 - Mage Armor 2", + "type": "script", + "author": "Njc5YzFjZDI5NjZl", + "img": "modules/tokenmagic/gui/macros/images/24%20-%20T07%20-%20Mage%20Armor%202.webp", + "scope": "global", + "command": "let params =\n[{\n filterType: \"field\",\n filterId: \"myMageField\",\n shieldType: 7,\n gridPadding: 1,\n color: 0xEEFFFF,\n time: 0,\n blend: 4,\n intensity: 0.8,\n lightAlpha: 0,\n lightSize: 0,\n scale: 1,\n radius: 1,\n chromatic: false,\n discardThreshold: 0.25,\n alphaDiscard: true,\n animated :\n {\n time : \n { \n active: true, \n speed: 0.003, \n animType: \"move\" \n }\n }\n}];\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 4300000, + "flags": {}, + "ownership": { + "default": 0 + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!Ii7MvSDFFEKMavuM" +} diff --git a/src/packs/_source/tmMacros/24-t07-mage-armor.json b/src/packs/_source/tmMacros/24-t07-mage-armor.json new file mode 100644 index 0000000..4f94284 --- /dev/null +++ b/src/packs/_source/tmMacros/24-t07-mage-armor.json @@ -0,0 +1,24 @@ +{ + "_id": "6ZIpqLC3agLw2Vgx", + "name": "24 - T07 - Mage Armor", + "type": "script", + "author": "Njc5YzFjZDI5NjZl", + "img": "modules/tokenmagic/gui/macros/images/24%20-%20T07%20-%20Mage%20Armor.webp", + "scope": "global", + "command": "let params =\n[{\n filterType: \"field\",\n filterId: \"myMageField\",\n shieldType: 7,\n gridPadding: 1.,\n color: 0xFFFFFF,\n time: 0,\n blend: 4,\n intensity: 0.8,\n lightAlpha: 1,\n lightSize: 0.45,\n scale: 1,\n radius: 1,\n chromatic: false,\n animated :\n {\n time : \n { \n active: true, \n speed: 0.0015, \n animType: \"move\" \n }\n }\n}];\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 1200000, + "flags": {}, + "ownership": { + "default": 0 + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!6ZIpqLC3agLw2Vgx" +} diff --git a/src/packs/_source/tmMacros/24-t08-chromatic-bubble-2.json b/src/packs/_source/tmMacros/24-t08-chromatic-bubble-2.json new file mode 100644 index 0000000..71ca8c1 --- /dev/null +++ b/src/packs/_source/tmMacros/24-t08-chromatic-bubble-2.json @@ -0,0 +1,28 @@ +{ + "_id": "EzV1RAvmD9azXoNe", + "name": "24 - T08 - Chromatic Bubble 2", + "type": "script", + "author": "Njc5YzFjZDI5NjZl", + "img": "modules/tokenmagic/gui/macros/images/24%20-%20T08%20-%20Chromatic%20Bubble%202.webp", + "scope": "global", + "command": "let params =\n[{\n filterType: \"field\",\n filterId: \"myChromaField\",\n shieldType: 8,\n gridPadding: 1,\n color: 0xAAAAAA,\n time: 0,\n blend: 2,\n intensity: 1,\n lightAlpha: 0,\n lightSize: 0,\n scale: 1,\n radius: 1,\n chromatic: true,\n discardThreshold: 0.3,\n alphaDiscard: true,\n animated :\n {\n time : \n { \n active: true, \n speed: 0.0045, \n animType: \"move\" \n }\n }\n}];\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 3000000, + "flags": { + "furnace": { + "runAsGM": false + } + }, + "ownership": { + "default": 0 + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!EzV1RAvmD9azXoNe" +} diff --git a/src/packs/_source/tmMacros/24-t08-chromatic-bubble.json b/src/packs/_source/tmMacros/24-t08-chromatic-bubble.json new file mode 100644 index 0000000..228aef5 --- /dev/null +++ b/src/packs/_source/tmMacros/24-t08-chromatic-bubble.json @@ -0,0 +1,28 @@ +{ + "_id": "f74nx1SMT5m8RRn8", + "name": "24 - T08 - Chromatic Bubble", + "type": "script", + "author": "Njc5YzFjZDI5NjZl", + "img": "modules/tokenmagic/gui/macros/images/24%20-%20T08%20-%20Chromatic%20Bubble.webp", + "scope": "global", + "command": "let params =\n[{\n filterType: \"field\",\n filterId: \"myChromaField\",\n shieldType: 8,\n gridPadding: 2,\n color: 0xAAAAAA,\n time: 0,\n blend: 2,\n intensity: 1,\n lightAlpha: 0,\n lightSize: 0,\n scale: 1,\n radius: 1,\n chromatic: true,\n zOrder: 512,\n animated :\n {\n time : \n { \n active: true, \n speed: 0.0045, \n animType: \"move\" \n }\n }\n}];\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 8400000, + "flags": { + "furnace": { + "runAsGM": false + } + }, + "ownership": { + "default": 0 + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!f74nx1SMT5m8RRn8" +} diff --git a/src/packs/_source/tmMacros/24-t09-water-defense-2-ring.json b/src/packs/_source/tmMacros/24-t09-water-defense-2-ring.json new file mode 100644 index 0000000..effe887 --- /dev/null +++ b/src/packs/_source/tmMacros/24-t09-water-defense-2-ring.json @@ -0,0 +1,24 @@ +{ + "_id": "CPMuEoGlADZ4OfXv", + "name": "24 - T09 - Water Defense 2 - Ring", + "type": "script", + "author": "Njc5YzFjZDI5NjZl", + "img": "modules/tokenmagic/gui/macros/images/24%20-%20T09%20-%20Water%20Defense%202%20-%20Ring.webp", + "scope": "global", + "command": "let params =\n[{\n filterType: \"field\",\n filterId: \"myWaterField\",\n shieldType: 9,\n gridPadding: 1.2,\n color: 0x20BBEE,\n time: 0,\n blend: 4,\n intensity: 1,\n lightAlpha: 0.7,\n lightSize: 0.5,\n scale: 0.6,\n radius: 1,\n chromatic: false,\n hideRadius: 0.8,\n animated :\n {\n time : \n { \n active: true, \n speed: 0.0015, \n animType: \"move\" \n },\n radius: \n {\n active: true, \n loopDuration: 6000, \n animType: \"cosOscillation\", \n val1:1, \n val2:0.8\n },\n hideRadius: \n {\n active: true, \n loopDuration: 3000, \n animType: \"cosOscillation\", \n val1:0.6, \n val2:0\n }\n }\n},{\n filterType: \"liquid\",\n filterId: \"myDriftLiquid\",\n color: 0x002040,\n time: 0,\n blend: 4,\n intensity: 4,\n spectral: false,\n scale: 1.5,\n zOrder: 3000,\n animated :\n {\n time : \n { \n active: true, \n speed: 0.0018, \n animType: \"move\" \n }\n }\n}];\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 2200000, + "flags": {}, + "ownership": { + "default": 0 + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!CPMuEoGlADZ4OfXv" +} diff --git a/src/packs/_source/tmMacros/24-t09-water-defense.json b/src/packs/_source/tmMacros/24-t09-water-defense.json new file mode 100644 index 0000000..0b21e20 --- /dev/null +++ b/src/packs/_source/tmMacros/24-t09-water-defense.json @@ -0,0 +1,24 @@ +{ + "_id": "aoqr6qPxif62zWLo", + "name": "24 - T09 - Water Defense", + "type": "script", + "author": "Njc5YzFjZDI5NjZl", + "img": "modules/tokenmagic/gui/macros/images/24%20-%20T09%20-%20Water%20Defense.webp", + "scope": "global", + "command": "let params =\n[{\n filterType: \"field\",\n filterId: \"myWaterField\",\n shieldType: 9,\n gridPadding: 1.2,\n color: 0x20BBEE,\n time: 0,\n blend: 4,\n intensity: 1,\n lightAlpha: 0.7,\n lightSize: 0.5,\n scale: 0.6,\n radius: 1,\n chromatic: false,\n animated :\n {\n time : \n { \n active: true, \n speed: 0.0015, \n animType: \"move\" \n }\n }\n}];\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 7300000, + "flags": {}, + "ownership": { + "default": 0 + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!aoqr6qPxif62zWLo" +} diff --git a/src/packs/_source/tmMacros/24-t10-evil-aura.json b/src/packs/_source/tmMacros/24-t10-evil-aura.json new file mode 100644 index 0000000..b790036 --- /dev/null +++ b/src/packs/_source/tmMacros/24-t10-evil-aura.json @@ -0,0 +1,24 @@ +{ + "_id": "4Ywsytul1no7EwKb", + "name": "24 - T10 - Evil Aura", + "type": "script", + "author": "Njc5YzFjZDI5NjZl", + "img": "modules/tokenmagic/gui/macros/images/24%20-%20T10%20-%20Evil%20Aura.webp", + "scope": "global", + "command": "let params =\n[{\n filterType: \"field\",\n filterId: \"myEvilField\",\n shieldType: 10,\n gridPadding: 1,\n color: 0xFF3010,\n time: 0,\n blend: 5,\n intensity: 1,\n lightAlpha: 4,\n lightSize: 0.8,\n scale: 0.5,\n radius: 1,\n chromatic: false,\n zOrder: 512,\n animated :\n {\n time : \n { \n active: true, \n speed: 0.0012, \n animType: \"move\" \n },\n lightSize: \n {\n val1: 0.4, val2: 1.5,\n animType: \"syncCosOscillation\",\n loopDuration: 5000\n }\n }\n}];\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 700000, + "flags": {}, + "ownership": { + "default": 0 + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!4Ywsytul1no7EwKb" +} diff --git a/src/packs/_source/tmMacros/24-t11-grid-force-field-2-chromatic.json b/src/packs/_source/tmMacros/24-t11-grid-force-field-2-chromatic.json new file mode 100644 index 0000000..e5233ab --- /dev/null +++ b/src/packs/_source/tmMacros/24-t11-grid-force-field-2-chromatic.json @@ -0,0 +1,24 @@ +{ + "_id": "fZd9j5Y4p49Vwys0", + "name": "24 - T11 - Grid Force Field 2 - Chromatic", + "type": "script", + "author": "Njc5YzFjZDI5NjZl", + "img": "modules/tokenmagic/gui/macros/images/24%20-%20T11%20-%20Grid%20Force%20Field%202%20-%20Chromatic.webp", + "scope": "global", + "command": "let params =\n[{\n filterType: \"field\",\n filterId: \"myGridField\",\n shieldType: 11,\n gridPadding: 2,\n color: 0xC1C1C1,\n time: 0,\n blend: 2,\n intensity: 1,\n lightAlpha: 0,\n lightSize: 0.3,\n scale: 0.5,\n radius: 1,\n chromatic: true,\n alphaDiscard: true,\n discardThreshold: 0.3,\n zOrder: 512,\n animated :\n {\n time : \n { \n active: true, \n speed: 0.0009, \n animType: \"move\" \n }\n }\n}];\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 8500000, + "flags": {}, + "ownership": { + "default": 0 + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!fZd9j5Y4p49Vwys0" +} diff --git a/src/packs/_source/tmMacros/24-t11-grid-force-field.json b/src/packs/_source/tmMacros/24-t11-grid-force-field.json new file mode 100644 index 0000000..ea5f81f --- /dev/null +++ b/src/packs/_source/tmMacros/24-t11-grid-force-field.json @@ -0,0 +1,24 @@ +{ + "_id": "VuMHH9LMD51MNJzZ", + "name": "24 - T11 - Grid Force Field", + "type": "script", + "author": "Njc5YzFjZDI5NjZl", + "img": "modules/tokenmagic/gui/macros/images/24%20-%20T11%20-%20Grid%20Force%20Field.webp", + "scope": "global", + "command": "let params =\n[{\n filterType: \"field\",\n filterId: \"myGridField\",\n shieldType: 11,\n gridPadding: 2,\n color: 0x00CCCC,\n time: 0,\n blend: 2,\n intensity: 1,\n lightAlpha: 1,\n lightSize: 0.3,\n scale: 0.5,\n radius: 1,\n chromatic: false,\n zOrder: 512,\n animated :\n {\n time : \n { \n active: true, \n speed: 0.0009, \n animType: \"move\" \n }\n }\n}];\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 6600000, + "flags": {}, + "ownership": { + "default": 0 + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!VuMHH9LMD51MNJzZ" +} diff --git a/src/packs/_source/tmMacros/24-t12-warp-time-aura-2.json b/src/packs/_source/tmMacros/24-t12-warp-time-aura-2.json new file mode 100644 index 0000000..ff1ae38 --- /dev/null +++ b/src/packs/_source/tmMacros/24-t12-warp-time-aura-2.json @@ -0,0 +1,28 @@ +{ + "_id": "7078QmgtTEjnbAv0", + "name": "24 - T12 - Warp Time Aura 2", + "type": "script", + "author": "Njc5YzFjZDI5NjZl", + "img": "modules/tokenmagic/gui/macros/images/24%20-%20T12%20-%20Warp%20Time%20Aura%202.webp", + "scope": "global", + "command": "let params =\n[{\n filterType: \"field\",\n filterId: \"myMageField\",\n shieldType: 7,\n gridPadding: 2,\n color: 0xFFFFFF,\n time: 0,\n blend: 4,\n intensity: 0.8,\n lightAlpha: 1,\n lightSize: 0.45,\n scale: 1,\n radius: 1,\n chromatic: true,\n animated :\n {\n time : \n { \n active: true, \n speed: 0.0080, \n animType: \"move\" \n }\n }\n},{\n filterType: \"field\",\n filterId: \"myWarpField\",\n shieldType: 12,\n gridPadding: 2,\n color: 0xFFFFFF,\n time: 0,\n blend: 2,\n intensity: 1,\n lightAlpha: 0,\n lightSize: 0,\n scale: 0.7,\n radius: 1,\n chromatic: false,\n alphaDiscard: true,\n discardThreshold: 0.1,\n animated :\n {\n time : \n { \n active: true, \n speed: 0.0009, \n animType: \"move\" \n }\n }\n}];\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 1300000, + "flags": { + "furnace": { + "runAsGM": false + } + }, + "ownership": { + "default": 0 + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!7078QmgtTEjnbAv0" +} diff --git a/src/packs/_source/tmMacros/24-t12-warp-time-aura.json b/src/packs/_source/tmMacros/24-t12-warp-time-aura.json new file mode 100644 index 0000000..aaa5c73 --- /dev/null +++ b/src/packs/_source/tmMacros/24-t12-warp-time-aura.json @@ -0,0 +1,28 @@ +{ + "_id": "2IOkNL2J1jETUvSP", + "name": "24 - T12 - Warp Time Aura", + "type": "script", + "author": "Njc5YzFjZDI5NjZl", + "img": "modules/tokenmagic/gui/macros/images/24%20-%20T12%20-%20Warp%20Time%20Aura.webp", + "scope": "global", + "command": "let params =\n[{\n filterType: \"field\",\n filterId: \"myWarpField\",\n shieldType: 12,\n gridPadding: 2,\n color: 0xFFFFFF,\n time: 0,\n blend: 2,\n intensity: 1.5,\n lightAlpha: 0.8,\n lightSize: 0.5,\n scale: 0.7,\n radius: 1,\n chromatic: false,\n animated :\n {\n time : \n { \n active: true, \n speed: 0.0009, \n animType: \"move\" \n }\n }\n}];\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 200000, + "flags": { + "furnace": { + "runAsGM": false + } + }, + "ownership": { + "default": 0 + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!2IOkNL2J1jETUvSP" +} diff --git a/src/packs/_source/tmMacros/24-t13-simple-color.json b/src/packs/_source/tmMacros/24-t13-simple-color.json new file mode 100644 index 0000000..639188d --- /dev/null +++ b/src/packs/_source/tmMacros/24-t13-simple-color.json @@ -0,0 +1,24 @@ +{ + "_id": "GHbWoqQWjeUjcStr", + "name": "24 - T13 - Simple Color", + "type": "script", + "author": "Njc5YzFjZDI5NjZl", + "img": "modules/tokenmagic/gui/macros/images/24%20-%20T13%20-%20Simple%20Color.webp", + "scope": "global", + "command": "let params =\n[{\n filterType: \"field\",\n filterId: \"mySimpleField\",\n shieldType: 13,\n gridPadding: 2,\n alpha: 0.25,\n color: 0xCCCC00,\n time: 0,\n blend: 14,\n intensity: 1.10,\n lightSize: 0,\n scale: 1,\n radius: 1,\n chromatic: false,\n}];\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 3300000, + "flags": {}, + "ownership": { + "default": 0 + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!GHbWoqQWjeUjcStr" +} diff --git a/src/packs/_source/tmMacros/25-t01-sunburst-rays-xray.json b/src/packs/_source/tmMacros/25-t01-sunburst-rays-xray.json new file mode 100644 index 0000000..78666ba --- /dev/null +++ b/src/packs/_source/tmMacros/25-t01-sunburst-rays-xray.json @@ -0,0 +1,24 @@ +{ + "_id": "IEl6F5dtFcYBZDDZ", + "name": "25 - T01 - Sunburst Rays (xray)", + "type": "script", + "author": "Njc5YzFjZDI5NjZl", + "img": "modules/tokenmagic/gui/macros/images/25%20-%20T01%20-%20Sunburst%20Rays%20%28xray%29.webp", + "scope": "global", + "command": "let params =\n[{\n filterType: \"xray\",\n filterId: \"mySunburstRays\",\n time: 0,\n color: 0xFFBB00,\n blend: 9,\n dimX: 1,\n dimY: 1,\n anchorX: 0,\n anchorY: 0,\n divisor: 36,\n intensity: 4,\n animated :\n {\n time : \n { \n active: true, \n speed: 0.0012, \n animType: \"move\" \n },\n anchorX:\n {\n animType: \"syncCosOscillation\",\n loopDuration : 6000,\n val1: 0.40,\n val2: 0.60\n }\n }\n}];\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 4100000, + "flags": {}, + "ownership": { + "default": 0 + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!IEl6F5dtFcYBZDDZ" +} diff --git a/src/packs/_source/tmMacros/25-t02-lucky-clover-xray.json b/src/packs/_source/tmMacros/25-t02-lucky-clover-xray.json new file mode 100644 index 0000000..d00b164 --- /dev/null +++ b/src/packs/_source/tmMacros/25-t02-lucky-clover-xray.json @@ -0,0 +1,24 @@ +{ + "_id": "YPOoPH63FqcEoVTk", + "name": "25 - T02 - Lucky Clover (xray)", + "type": "script", + "author": "Njc5YzFjZDI5NjZl", + "img": "modules/tokenmagic/gui/macros/images/25%20-%20T02%20-%20Lucky%20Clover%20%28xray%29.webp", + "scope": "global", + "command": "let params =\n[{\n filterType: \"xray\",\n filterId: \"myLuckyRays\",\n time: 0,\n color: 0x00FF00,\n blend: 9,\n dimX: 0.05,\n dimY: 0.05,\n anchorX: 0.5,\n anchorY: 0.5,\n divisor: 4,\n intensity: 1,\n animated :\n {\n time : \n { \n active: true, \n speed: 0.0012, \n animType: \"move\" \n },\n anchorX:\n {\n animType: \"syncCosOscillation\",\n loopDuration : 6000,\n val1: 0.40,\n val2: 0.60\n },\n anchorY:\n {\n animType: \"syncSinOscillation\",\n loopDuration : 6000,\n val1: 0.40,\n val2: 0.60\n }\n }\n}];\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 7100000, + "flags": {}, + "ownership": { + "default": 0 + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!YPOoPH63FqcEoVTk" +} diff --git a/src/packs/_source/tmMacros/25-t03-x-ray-scan-xray.json b/src/packs/_source/tmMacros/25-t03-x-ray-scan-xray.json new file mode 100644 index 0000000..3bad48c --- /dev/null +++ b/src/packs/_source/tmMacros/25-t03-x-ray-scan-xray.json @@ -0,0 +1,24 @@ +{ + "_id": "hFZvMSE5VMCUiYNE", + "name": "25 - T03 - X-ray Scan (xray)", + "type": "script", + "author": "Njc5YzFjZDI5NjZl", + "img": "modules/tokenmagic/gui/macros/images/25%20-%20T03%20-%20X-ray%20Scan%20%28xray%29.webp", + "scope": "global", + "command": "let params =\n[{\n filterType: \"xray\",\n filterId: \"myXrayScan\",\n time: 0,\n color: 0xFFFFFF,\n blend: 5,\n dimX: 20,\n dimY: 20,\n anchorX: 0.5,\n anchorY: 0,\n divisor: 8,\n intensity: 1,\n animated :\n {\n time : \n { \n active: true, \n speed: 0.00038, \n animType: \"move\" \n }\n }\n}];\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 8800000, + "flags": {}, + "ownership": { + "default": 0 + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!hFZvMSE5VMCUiYNE" +} diff --git a/src/packs/_source/tmMacros/25-t04-blue-rays-xray.json b/src/packs/_source/tmMacros/25-t04-blue-rays-xray.json new file mode 100644 index 0000000..4a4f457 --- /dev/null +++ b/src/packs/_source/tmMacros/25-t04-blue-rays-xray.json @@ -0,0 +1,28 @@ +{ + "_id": "SpHEaIwubKpbwzvV", + "name": "25 - T04 - Blue Rays ! (xray)", + "type": "script", + "author": "Njc5YzFjZDI5NjZl", + "img": "modules/tokenmagic/gui/macros/images/25%20-%20T04%20-%20Blue%20Rays%20%21%20%28xray%29.webp", + "scope": "global", + "command": "let params =\n[{\n filterType: \"xray\",\n filterId: \"myBlueRay\",\n time: 0,\n color: 0x1030FF,\n blend: 9,\n dimX: 1,\n dimY: 1,\n anchorX: 0,\n anchorY: 0,\n divisor: 24,\n intensity: 1,\n animated :\n {\n time : \n { \n active: true, \n speed: 0.0002, \n animType: \"move\" \n },\n anchorX:\n {\n animType: \"syncCosOscillation\",\n loopDuration : 18000,\n val1: 0.05,\n val2: 0.95\n },\n anchorY:\n {\n animType: \"syncSinOscillation\",\n loopDuration : 18000,\n val1: 0.05,\n val2: 0.95\n }\n }\n}];\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 5500000, + "flags": { + "furnace": { + "runAsGM": false + } + }, + "ownership": { + "default": 0 + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!SpHEaIwubKpbwzvV" +} diff --git a/src/packs/_source/tmMacros/26-t01-spectral-body-liquid.json b/src/packs/_source/tmMacros/26-t01-spectral-body-liquid.json new file mode 100644 index 0000000..4cc7bbf --- /dev/null +++ b/src/packs/_source/tmMacros/26-t01-spectral-body-liquid.json @@ -0,0 +1,24 @@ +{ + "_id": "SpvVIO1eHYG96TGX", + "name": "26 - T01 - Spectral Body (liquid)", + "type": "script", + "author": "Njc5YzFjZDI5NjZl", + "img": "modules/tokenmagic/gui/macros/images/26%20-%20T01%20-%20Spectral%20Body%20%28liquid%29.webp", + "scope": "global", + "command": "let params =\n[{\n filterType: \"liquid\",\n filterId: \"mySpectralBody\",\n color: 0x20AAEE,\n time: 0,\n blend: 8,\n intensity: 4,\n spectral: true,\n scale: 0.9,\n animated :\n {\n time : \n { \n active: true, \n speed: 0.0010, \n animType: \"move\" \n },\n color: \n {\n active: true, \n loopDuration: 6000, \n animType: \"colorOscillation\", \n val1:0xFFFFFF, \n val2:0x00AAFF\n }\n }\n}];\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 5600000, + "flags": {}, + "ownership": { + "default": 0 + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!SpvVIO1eHYG96TGX" +} diff --git a/src/packs/_source/tmMacros/26-t02-mantle-of-madness-liquid.json b/src/packs/_source/tmMacros/26-t02-mantle-of-madness-liquid.json new file mode 100644 index 0000000..ceab073 --- /dev/null +++ b/src/packs/_source/tmMacros/26-t02-mantle-of-madness-liquid.json @@ -0,0 +1,24 @@ +{ + "_id": "8nsxKDYhS1Wcc139", + "name": "26 - T02 - Mantle of Madness (liquid)", + "type": "script", + "author": "Njc5YzFjZDI5NjZl", + "img": "modules/tokenmagic/gui/macros/images/26%20-%20T02%20-%20Mantle%20of%20Madness%20%28liquid%29.webp", + "scope": "global", + "command": "let params =\n[{\n filterType: \"liquid\",\n filterId: \"myMantle\",\n color: 0x0090FF,\n time: 0,\n blend: 5,\n intensity: 0.0001,\n spectral: false,\n scale: 7,\n animated :\n {\n time : \n { \n active: true, \n speed: 0.0015, \n animType: \"move\" \n },\n intensity : \n { \n active: true, \n animType: \"syncCosOscillation\",\n loopDuration: 30000,\n val1: 0.0001, \n val2: 4 \n },\n scale: \n { \n active: true, \n animType: \"syncCosOscillation\",\n loopDuration: 30000,\n val1: 7, \n val2: 1 \n }\n }\n}];\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 1500000, + "flags": {}, + "ownership": { + "default": 0 + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!8nsxKDYhS1Wcc139" +} diff --git a/src/packs/_source/tmMacros/26-t03-drift-in-plans-liquid-waves.json b/src/packs/_source/tmMacros/26-t03-drift-in-plans-liquid-waves.json new file mode 100644 index 0000000..caaae6c --- /dev/null +++ b/src/packs/_source/tmMacros/26-t03-drift-in-plans-liquid-waves.json @@ -0,0 +1,28 @@ +{ + "_id": "T953GJB235BbrCll", + "name": "26 - T03 - Drift in Plans (liquid+waves)", + "type": "script", + "author": "Njc5YzFjZDI5NjZl", + "img": "modules/tokenmagic/gui/macros/images/26%20-%20T03%20-%20Drift%20in%20Plans%20%28liquid%2Bwaves%29.webp", + "scope": "global", + "command": "let params =\n[{\n filterType: \"wave\",\n filterId: \"myDriftWaves\",\n time: 0,\n anchorX: 0.5,\n anchorY: 0.5,\n strength: 0.035,\n frequency: 20,\n color: 0xFFFFFF,\n maxIntensity: 1.5,\n minIntensity: 0.5,\n padding:10,\n animated :\n {\n time : \n { \n active: true, \n speed: 0.0085, \n animType: \"move\" \n },\n anchorX :\n {\n active: true,\n val1: 0.35,\n val2: 0.65,\n animType: \"syncCosOscillation\",\n loopDuration: 10000\n },\n anchorY :\n {\n active: true,\n val1: 0.35,\n val2: 0.65,\n animType: \"syncSinOscillation\",\n loopDuration: 10000\n }\n }\n},\n{\n filterType: \"liquid\",\n filterId: \"myDriftLiquid\",\n color: 0xFF0000,\n time: 0,\n blend: 6,\n intensity: 5,\n spectral: false,\n scale: 2.5,\n animated :\n {\n time : \n { \n active: true, \n speed: 0.0018, \n animType: \"move\" \n },\n color: \n {\n active: true, \n loopDuration: 9000, \n animType: \"colorOscillation\", \n val1:0xFF0000, \n val2:0xFFFFFF\n }\n }\n}];\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 5800000, + "flags": { + "furnace": { + "runAsGM": false + } + }, + "ownership": { + "default": 0 + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!T953GJB235BbrCll" +} diff --git a/src/packs/_source/tmMacros/27-t01-burning-aura-xglow.json b/src/packs/_source/tmMacros/27-t01-burning-aura-xglow.json new file mode 100644 index 0000000..cb600b3 --- /dev/null +++ b/src/packs/_source/tmMacros/27-t01-burning-aura-xglow.json @@ -0,0 +1,24 @@ +{ + "_id": "cOaB7NxSQ5jNDd5g", + "name": "27 - T01 - Burning Aura (xglow)", + "type": "script", + "author": "Njc5YzFjZDI5NjZl", + "img": "modules/tokenmagic/gui/macros/images/27%20-%20T01%20-%20Burning%20Aura%20%28xglow%29.webp", + "scope": "global", + "command": "let params =\n[{\n filterType: \"zapshadow\",\n filterId: \"myZapShadow\",\n alphaTolerance: 0.50\n},\n{\n filterType: \"xglow\",\n filterId: \"myBurningAura\",\n auraType: 2,\n color: 0x903010,\n thickness: 9.8,\n scale: 1.,\n time: 0,\n auraIntensity: 2,\n subAuraIntensity: 1.5,\n threshold: 0.40,\n discard: true,\n animated:\n {\n time : \n { \n active: true,\n speed: 0.0027, \n animType: \"move\" \n },\n thickness:\n {\n active: true,\n loopDuration: 3000, \n animType: \"cosOscillation\", \n val1:2, \n val2:5\n }\n }\n}];\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 7700000, + "flags": {}, + "ownership": { + "default": 0 + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!cOaB7NxSQ5jNDd5g" +} diff --git a/src/packs/_source/tmMacros/27-t02-glacial-aura-xglow.json b/src/packs/_source/tmMacros/27-t02-glacial-aura-xglow.json new file mode 100644 index 0000000..99a81f8 --- /dev/null +++ b/src/packs/_source/tmMacros/27-t02-glacial-aura-xglow.json @@ -0,0 +1,24 @@ +{ + "_id": "wdbgHdNcBwBETc1y", + "name": "27 - T02 - Glacial Aura (xglow)", + "type": "script", + "author": "Njc5YzFjZDI5NjZl", + "img": "modules/tokenmagic/gui/macros/images/27%20-%20T02%20-%20Glacial%20Aura%20%28xglow%29.webp", + "scope": "global", + "command": "let params =\n[{\n filterType: \"zapshadow\",\n filterId: \"myGlacialZapShadow\",\n alphaTolerance: 0.50\n},\n{\n filterType: \"xglow\",\n filterId: \"myGlacialAura\",\n auraType: 1,\n color: 0x5099DD,\n thickness: 4.5,\n scale: 3,\n time: 0,\n auraIntensity: 0.8,\n subAuraIntensity: 0.25,\n threshold: 0.5,\n discard: false,\n animated:\n {\n time : \n { \n active: true,\n speed: 0.0018, \n animType: \"move\" \n },\n thickness: \n {\n val1: 2, val2: 4.7,\n animType: \"cosOscillation\",\n loopDuration: 3000\n },\n subAuraIntensity: \n {\n val1: 0.45, val2: 0.65,\n animType: \"cosOscillation\",\n loopDuration: 6000\n },\n auraIntensity: \n {\n val1: 0.9, val2: 2.2,\n animType: \"cosOscillation\",\n loopDuration: 3000\n }\n }\n}];\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 11200000, + "flags": {}, + "ownership": { + "default": 0 + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!wdbgHdNcBwBETc1y" +} diff --git a/src/packs/_source/tmMacros/27-t03-ugly-villains-aura-xglow.json b/src/packs/_source/tmMacros/27-t03-ugly-villains-aura-xglow.json new file mode 100644 index 0000000..bad7edc --- /dev/null +++ b/src/packs/_source/tmMacros/27-t03-ugly-villains-aura-xglow.json @@ -0,0 +1,24 @@ +{ + "_id": "ydY1XOCO4yIhunkj", + "name": "27 - T03 - Ugly Villains Aura (xglow)", + "type": "script", + "author": "Njc5YzFjZDI5NjZl", + "img": "modules/tokenmagic/gui/macros/images/27%20-%20T03%20-%20Ugly%20Villains%20Aura%20%28xglow%29.webp", + "scope": "global", + "command": "let params =\n[{\n filterType: \"zapshadow\",\n filterId: \"myUglyZapShadow\",\n alphaTolerance: 0.50\n},\n{\n filterType: \"xglow\",\n filterId: \"myUglyGlow\",\n auraType: 2,\n color: 0x050505,\n thickness: 2.7,\n scale: 7,\n time: 0,\n auraIntensity: 5,\n subAuraIntensity: 2,\n threshold: 0.08,\n discard: false,\n animated:\n {\n time : \n { \n active: true,\n speed: 0.0012, \n animType: \"move\" \n },\n auraIntensity:\n {\n active: true,\n loopDuration: 3000, \n animType: \"syncCosOscillation\", \n val1:5, \n val2:0\n },\n subAuraIntensity:\n {\n active: true,\n loopDuration: 3000, \n animType: \"syncCosOscillation\", \n val1:2, \n val2:0\n },\n color:\n {\n active: true,\n loopDuration: 6000, \n animType: \"syncColorOscillation\", \n val1:0x050505, \n val2:0x200000\n },\n threshold:\n {\n active: true,\n loopDuration: 1500, \n animType: \"syncCosOscillation\", \n val1:0.02, \n val2:0.50\n }\n }\n}];\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 11700000, + "flags": {}, + "ownership": { + "default": 0 + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!ydY1XOCO4yIhunkj" +} diff --git a/src/packs/_source/tmMacros/27-t04-pure-fire-xglow-fire.json b/src/packs/_source/tmMacros/27-t04-pure-fire-xglow-fire.json new file mode 100644 index 0000000..d8a88ff --- /dev/null +++ b/src/packs/_source/tmMacros/27-t04-pure-fire-xglow-fire.json @@ -0,0 +1,28 @@ +{ + "_id": "eJQSmnIitUUQMKDS", + "name": "27 - T04 - Pure Fire (xglow+fire)", + "type": "script", + "author": "Njc5YzFjZDI5NjZl", + "img": "modules/tokenmagic/gui/macros/images/27%20-%20T04%20-%20Pure%20Fire%20%28xglow%2Bfire%29.webp", + "scope": "global", + "command": "let params =\n[{\n filterType: \"fire\",\n filterId: \"myPureFire\",\n intensity: 1,\n color: 0xFFFFFF,\n amplitude: 1,\n time: 0,\n blend: 2,\n fireBlend : 1,\n animated :\n {\n time : \n { \n active: true, \n speed: -0.0024, \n animType: \"move\" \n },\n intensity:\n {\n active:true,\n loopDuration: 15000,\n val1: 0.8,\n val2: 2,\n animType: \"syncCosOscillation\"\n },\n amplitude:\n {\n active:true,\n loopDuration: 4400,\n val1: 1,\n val2: 1.4,\n animType: \"syncCosOscillation\"\n }\n \n }\n},\n{\n filterType: \"zapshadow\",\n filterId: \"myPureFireShadow\",\n alphaTolerance: 0.50\n},\n{\n filterType: \"xglow\",\n filterId: \"myPureFireAura\",\n auraType: 2,\n color: 0x903010,\n thickness: 9.8,\n scale: 4.,\n time: 0,\n auraIntensity: 2,\n subAuraIntensity: 1.5,\n threshold: 0.40,\n discard: true,\n animated:\n {\n time : \n { \n active: true,\n speed: 0.0027, \n animType: \"move\" \n },\n thickness:\n {\n active: true,\n loopDuration: 3000, \n animType: \"cosOscillation\", \n val1:2, \n val2:5\n }\n }\n}];\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 8000000, + "flags": { + "furnace": { + "runAsGM": false + } + }, + "ownership": { + "default": 0 + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!eJQSmnIitUUQMKDS" +} diff --git a/src/packs/_source/tmMacros/27-t05-pure-fire-v2-xglow-fire.json b/src/packs/_source/tmMacros/27-t05-pure-fire-v2-xglow-fire.json new file mode 100644 index 0000000..edf05f5 --- /dev/null +++ b/src/packs/_source/tmMacros/27-t05-pure-fire-v2-xglow-fire.json @@ -0,0 +1,24 @@ +{ + "_id": "wRWqUK0wliNZSsgl", + "name": "27 - T05 - Pure Fire v2 (xglow+fire)", + "type": "script", + "author": "Njc5YzFjZDI5NjZl", + "img": "modules/tokenmagic/gui/macros/images/27%20-%20T05%20-%20Pure%20Fire%20v2%20%28xglow%2Bfire%29.webp", + "scope": "global", + "command": "// In this version, the glow is blending with the fire\n// This is to show that the order of the filters is important\nlet params =\n[{\n filterType: \"zapshadow\",\n filterId: \"myPureFireShadow\",\n alphaTolerance: 0.50\n},\n{\n filterType: \"xglow\",\n filterId: \"myPureFireAura\",\n auraType: 2,\n color: 0x903010,\n thickness: 9.8,\n scale: 3.,\n time: 0,\n auraIntensity: 1,\n subAuraIntensity: 0.3,\n threshold: 0.25,\n discard: true,\n animated:\n {\n time : \n { \n active: true,\n speed: 0.0027, \n animType: \"move\" \n },\n thickness:\n {\n active: true,\n loopDuration: 3000, \n animType: \"cosOscillation\", \n val1:2, \n val2:3.6\n }\n }\n},\n{\n filterType: \"fire\",\n filterId: \"myPureFire\",\n intensity: 1,\n color: 0xFFFFFF,\n amplitude: 1,\n time: 0,\n blend: 2,\n fireBlend : 1,\n animated :\n {\n time : \n { \n active: true, \n speed: -0.0024, \n animType: \"move\" \n },\n intensity:\n {\n active:true,\n loopDuration: 15000,\n val1: 0.8,\n val2: 3,\n animType: \"syncCosOscillation\"\n },\n amplitude:\n {\n active:true,\n loopDuration: 4400,\n val1: 1,\n val2: 1.6,\n animType: \"syncCosOscillation\"\n }\n \n }\n}];\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 11000000, + "flags": {}, + "ownership": { + "default": 0 + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!wRWqUK0wliNZSsgl" +} diff --git a/src/packs/_source/tmMacros/27-t06-pure-ice-xglow-smoke.json b/src/packs/_source/tmMacros/27-t06-pure-ice-xglow-smoke.json new file mode 100644 index 0000000..b4b14e4 --- /dev/null +++ b/src/packs/_source/tmMacros/27-t06-pure-ice-xglow-smoke.json @@ -0,0 +1,24 @@ +{ + "_id": "QkPSIfIOf72oD49L", + "name": "27 - T06 - Pure Ice (xglow+smoke)", + "type": "script", + "author": "Njc5YzFjZDI5NjZl", + "img": "modules/tokenmagic/gui/macros/images/27%20-%20T06%20-%20Pure%20Ice%20%28xglow%2Bsmoke%29.webp", + "scope": "global", + "command": "let params =\n [{\n filterType: \"zapshadow\",\n filterId: \"myPureIceZapShadow\",\n alphaTolerance: 0.50\n },\n {\n filterType: \"xglow\",\n filterId: \"myPureIceAura\",\n auraType: 1,\n color: 0x5099DD,\n thickness: 4.5,\n scale: 10,\n time: 0,\n auraIntensity: 0.25,\n subAuraIntensity: 1,\n threshold: 0.5,\n discard: false,\n animated:\n {\n time:\n {\n active: true,\n speed: 0.0018,\n animType: \"move\"\n },\n thickness:\n {\n val1: 2, val2: 2.5,\n animType: \"cosOscillation\",\n loopDuration: 3000\n },\n subAuraIntensity:\n {\n val1: 0.45, val2: 0.65,\n animType: \"cosOscillation\",\n loopDuration: 6000\n },\n auraIntensity:\n {\n val1: 0.9, val2: 2.2,\n animType: \"cosOscillation\",\n loopDuration: 3000\n }\n }\n },\n {\n filterType: \"smoke\",\n filterId: \"myPureIceSmoke\",\n color: 0x80CCFF,\n time: 0,\n blend: 2,\n dimX: 0.3,\n dimY: 1,\n animated:\n {\n time:\n {\n active: true,\n speed: -0.006,\n animType: \"move\"\n },\n dimX:\n {\n val1: 0.4, val2: 0.2,\n animType: \"cosOscillation\",\n loopDuration: 3000\n }\n }\n }];\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 5100000, + "flags": {}, + "ownership": { + "default": 0 + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!QkPSIfIOf72oD49L" +} diff --git a/src/packs/_source/tmMacros/28-glory-to-pixels.json b/src/packs/_source/tmMacros/28-glory-to-pixels.json new file mode 100644 index 0000000..ce86918 --- /dev/null +++ b/src/packs/_source/tmMacros/28-glory-to-pixels.json @@ -0,0 +1,24 @@ +{ + "_id": "8KIRbHAgs6SCs8mT", + "name": "28 - Glory to Pixels", + "type": "script", + "author": "Njc5YzFjZDI5NjZl", + "img": "modules/tokenmagic/gui/macros/images/28%20-%20Glory%20to%20Pixels.webp", + "scope": "global", + "command": "let params = \n[{\n filterType: \"pixel\",\n filterId: \"pixelate\",\n sizeX: 2.5,\n sizeY: 2.5\n}]\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 1400000, + "flags": {}, + "ownership": { + "default": 0 + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!8KIRbHAgs6SCs8mT" +} diff --git a/src/packs/_source/tmMacros/29-t01-foul-fog-xfog.json b/src/packs/_source/tmMacros/29-t01-foul-fog-xfog.json new file mode 100644 index 0000000..7a59a2b --- /dev/null +++ b/src/packs/_source/tmMacros/29-t01-foul-fog-xfog.json @@ -0,0 +1,24 @@ +{ + "_id": "T1cSEVif6eETPeQw", + "name": "29 - T01 - Foul Fog (xfog)", + "type": "script", + "author": "Njc5YzFjZDI5NjZl", + "img": "modules/tokenmagic/gui/macros/images/29%20-%20T01%20-%20Foul%20Fog%20%28xfog%29.webp", + "scope": "global", + "command": "let params = \n[{\n filterType: \"xfog\",\n filterId: \"foulfog\",\n color: 0xFFFFFF,\n time: 0,\n animated:\n {\n time:\n {\n active: true,\n speed: 0.0005,\n animType: \"move\"\n }\n }\n}]\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 5700000, + "flags": {}, + "ownership": { + "default": 0 + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!T1cSEVif6eETPeQw" +} diff --git a/src/packs/_source/tmMacros/29-t02-phase-spider-web-xfog-web.json b/src/packs/_source/tmMacros/29-t02-phase-spider-web-xfog-web.json new file mode 100644 index 0000000..4f1663c --- /dev/null +++ b/src/packs/_source/tmMacros/29-t02-phase-spider-web-xfog-web.json @@ -0,0 +1,24 @@ +{ + "_id": "ki2AEmXzUJkGpU65", + "name": "29 - T02 - Phase Spider Web (xfog+web)", + "type": "script", + "author": "Njc5YzFjZDI5NjZl", + "img": "modules/tokenmagic/gui/macros/images/29%20-%20T02%20-%20Phase%20Spider%20Web%20%28xfog%2Bweb%29.webp", + "scope": "global", + "command": "let params = \n[{\n filterType: \"web\",\n filterId: \"phaseweb\",\n time: 0,\n animated:\n {\n time:\n {\n active: true,\n speed: 0.0005,\n animType: \"move\"\n }\n }\n},\n{\n filterType: \"xfog\",\n filterId: \"phaseweb\",\n color: 0x30FF30,\n time: 0,\n animated:\n {\n time:\n {\n active: true,\n speed: 0.0005,\n animType: \"move\"\n }\n }\n}]\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 9300000, + "flags": {}, + "ownership": { + "default": 0 + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!ki2AEmXzUJkGpU65" +} diff --git a/src/packs/_source/tmMacros/30-t01-simple-web-web.json b/src/packs/_source/tmMacros/30-t01-simple-web-web.json new file mode 100644 index 0000000..94d638c --- /dev/null +++ b/src/packs/_source/tmMacros/30-t01-simple-web-web.json @@ -0,0 +1,24 @@ +{ + "_id": "9gvCwVdvis3NABbI", + "name": "30 - T01 - Simple Web (web)", + "type": "script", + "author": "Njc5YzFjZDI5NjZl", + "img": "modules/tokenmagic/gui/macros/images/30%20-%20T01%20-%20Simple%20Web%20%28web%29.webp", + "scope": "global", + "command": "let params = \n[{\n filterType: \"web\",\n filterId: \"simpleweb\",\n time: 100,\n div1: 20,\n div2: 10,\n animated :\n {\n time : \n { \n active: true, \n speed: 0.0005, \n animType: \"move\" \n }\n }\n}]\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 1700000, + "flags": {}, + "ownership": { + "default": 0 + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!9gvCwVdvis3NABbI" +} diff --git a/src/packs/_source/tmMacros/30-t02-infernal-web-field-web.json b/src/packs/_source/tmMacros/30-t02-infernal-web-field-web.json new file mode 100644 index 0000000..7184bf6 --- /dev/null +++ b/src/packs/_source/tmMacros/30-t02-infernal-web-field-web.json @@ -0,0 +1,24 @@ +{ + "_id": "D2su0oqd2SLY0uZ7", + "name": "30 - T02 - Infernal Web (field+web)", + "type": "script", + "author": "Njc5YzFjZDI5NjZl", + "img": "modules/tokenmagic/gui/macros/images/30%20-%20T02%20-%20Infernal%20Web%20%28field%2Bweb%29.webp", + "scope": "global", + "command": "let params = \n[{\n filterType: \"field\",\n filterId: \"infernalWeb\",\n shieldType: 1,\n gridPadding: 1.5,\n color: 0xCC2050,\n time: 0,\n blend: 3,\n intensity: 1,\n lightAlpha: 1,\n lightSize: 0.8,\n scale: 1,\n radius: 1,\n chromatic: false,\n zOrder: 512,\n animated :\n {\n time : \n { \n active: true, \n speed: 0.0012, \n animType: \"move\" \n },\n lightSize: \n {\n val1: 0.4, val2: 1.5,\n animType: \"syncCosOscillation\",\n loopDuration: 5000\n }\n }\n}\n,{\n filterType: \"web\",\n filterId: \"infernalWeb\",\n time: 100,\n div1: 16,\n div2: 8,\n tear: 0.45,\n amplitude: 0.8,\n thickness: 2,\n color: 0xAA3030,\n zOrder: 1024,\n animated :\n {\n time : \n { \n active: true, \n speed: 0.0005, \n animType: \"move\" \n }\n }\n}]\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 2600000, + "flags": {}, + "ownership": { + "default": 0 + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!D2su0oqd2SLY0uZ7" +} diff --git a/src/packs/_source/tmMacros/31-t01-glowing-globes-globes.json b/src/packs/_source/tmMacros/31-t01-glowing-globes-globes.json new file mode 100644 index 0000000..782d8e6 --- /dev/null +++ b/src/packs/_source/tmMacros/31-t01-glowing-globes-globes.json @@ -0,0 +1,24 @@ +{ + "_id": "BV1FdyFefneHRoEx", + "name": "31 - T01 - Glowing Globes (globes)", + "type": "script", + "author": "Njc5YzFjZDI5NjZl", + "img": "modules/tokenmagic/gui/macros/images/31%20-%20T01%20-%20Glowing%20Globes%20%28globes%29.webp", + "scope": "global", + "command": "let params = \n[{\n filterType: \"globes\",\n filterId: \"glowingGlobes\",\n time: 0,\n color: 0x5099DD,\n distortion: 0.4,\n scale: 80,\n alphaDiscard: false,\n zOrder: 1,\n animated :\n {\n time : \n { \n active: true, \n speed: 0.0005, \n animType: \"move\" \n }\n }\n}]\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 2100000, + "flags": {}, + "ownership": { + "default": 0 + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!BV1FdyFefneHRoEx" +} diff --git a/src/packs/_source/tmMacros/31-t02-fairy-outline-globes-glow.json b/src/packs/_source/tmMacros/31-t02-fairy-outline-globes-glow.json new file mode 100644 index 0000000..c70b6cf --- /dev/null +++ b/src/packs/_source/tmMacros/31-t02-fairy-outline-globes-glow.json @@ -0,0 +1,24 @@ +{ + "_id": "URg5jbccjFontPwQ", + "name": "31 - T02 - Fairy Outline (globes+glow)", + "type": "script", + "author": "Njc5YzFjZDI5NjZl", + "img": "modules/tokenmagic/gui/macros/images/31%20-%20T02%20-%20Fairy%20Outline%20%28globes%2Bglow%29.webp", + "scope": "global", + "command": "// works better with non-round forms\nlet params = \n[{\n filterType: \"globes\",\n filterId: \"glowingGlobes\",\n time: 0,\n color: 0x3080EE,\n distortion: 0.9,\n scale: 320,\n alphaDiscard: true,\n zOrder: 1,\n animated :\n {\n time : \n { \n active: true, \n speed: 0.0015, \n animType: \"move\" \n }\n }\n},\n{\n filterType: \"glow\",\n filterId: \"superSpookyGlow\",\n outerStrength: 4,\n innerStrength: 0,\n color: 0xFF3000,\n quality: 0.5,\n padding: 10,\n animated:\n {\n color: \n {\n active: true, \n loopDuration: 3000, \n animType: \"colorOscillation\", \n val1:0xFF3000, \n val2:0x30FF00\n }\n }\n}]\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 6300000, + "flags": {}, + "ownership": { + "default": 0 + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!URg5jbccjFontPwQ" +} diff --git a/src/packs/_source/tmMacros/32-t01-solar-ripples-ripples.json b/src/packs/_source/tmMacros/32-t01-solar-ripples-ripples.json new file mode 100644 index 0000000..8d8b8a3 --- /dev/null +++ b/src/packs/_source/tmMacros/32-t01-solar-ripples-ripples.json @@ -0,0 +1,24 @@ +{ + "_id": "qMZ03TZJuNYwudlg", + "name": "32 - T01 - Solar Ripples (ripples)", + "type": "script", + "author": "Njc5YzFjZDI5NjZl", + "img": "modules/tokenmagic/gui/macros/images/32%20-%20T01%20-%20Solar%20Ripples%20%28ripples%29.webp", + "scope": "global", + "command": "let params = \n[{\n filterType: \"ripples\",\n filterId: \"SolarRipples\",\n color: 0xCC9000,\n time: 0,\n alphaDiscard: false,\n animated :\n {\n time : \n { \n active: true, \n speed: 0.0009, \n animType: \"move\" \n }\n }\n}]\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 9800000, + "flags": {}, + "ownership": { + "default": 0 + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!qMZ03TZJuNYwudlg" +} diff --git a/src/packs/_source/tmMacros/32-t02-devoured-by-the-bewitched-flames-ripples-glow.json b/src/packs/_source/tmMacros/32-t02-devoured-by-the-bewitched-flames-ripples-glow.json new file mode 100644 index 0000000..d221403 --- /dev/null +++ b/src/packs/_source/tmMacros/32-t02-devoured-by-the-bewitched-flames-ripples-glow.json @@ -0,0 +1,24 @@ +{ + "_id": "v9CPcenfjU6hH5mO", + "name": "32 - T02 - Devoured by the Bewitched Flames (ripples+glow)", + "type": "script", + "author": "Njc5YzFjZDI5NjZl", + "img": "modules/tokenmagic/gui/macros/images/32%20-%20T02%20-%20Devoured%20by%20the%20Bewitched%20Flames%20%28ripples%2Bglow%29.webp", + "scope": "global", + "command": "let params = \n[{\n filterType: \"ripples\",\n filterId: \"SolarRipples\",\n color: 0x508000,\n time: 0,\n alphaDiscard: true,\n zOrder:50,\n animated :\n {\n time : \n { \n active: true, \n speed: 0.0009, \n animType: \"move\" \n }\n }\n},\n{\n filterType: \"glow\",\n filterId: \"glowripples\",\n outerStrength: 2,\n innerStrength: 1,\n color: 0xFF3000,\n quality: 0.5,\n padding: 10,\n zOrder: 100,\n animated:\n {\n color: \n {\n active: true, \n loopDuration: 3000, \n animType: \"colorOscillation\", \n val1:0xFF3000, \n val2:0x30FF00\n }\n }\n}]\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 10800000, + "flags": {}, + "ownership": { + "default": 0 + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!v9CPcenfjU6hH5mO" +} diff --git a/src/packs/_source/tmMacros/33-t01-evade-stance-transform.json b/src/packs/_source/tmMacros/33-t01-evade-stance-transform.json new file mode 100644 index 0000000..5569e4e --- /dev/null +++ b/src/packs/_source/tmMacros/33-t01-evade-stance-transform.json @@ -0,0 +1,28 @@ +{ + "_id": "0U6lS2hR1uMm7iFI", + "name": "33 - T01 - Evade Stance (transform)", + "type": "script", + "author": "Njc5YzFjZDI5NjZl", + "img": "modules/tokenmagic/gui/macros/images/33%20-%20T01%20-%20Evade%20Stance%20%28transform%29.webp", + "scope": "global", + "command": "let params =\n [{\n filterType: \"transform\",\n filterId: \"dodgeStance\",\n padding: 50,\n animated:\n {\n translationX:\n {\n animType: \"sinOscillation\",\n val1: -0.125,\n val2: +0.125,\n loopDuration: 1400,\n },\n translationY:\n {\n animType: \"cosOscillation\",\n val1: -0.035,\n val2: +0.035,\n loopDuration: 1400,\n }\n }\n }];\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 100000, + "flags": { + "furnace": { + "runAsGM": false + } + }, + "ownership": { + "default": 0 + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!0U6lS2hR1uMm7iFI" +} diff --git a/src/packs/_source/tmMacros/33-t02-saving-roll-transform.json b/src/packs/_source/tmMacros/33-t02-saving-roll-transform.json new file mode 100644 index 0000000..49c4c48 --- /dev/null +++ b/src/packs/_source/tmMacros/33-t02-saving-roll-transform.json @@ -0,0 +1,28 @@ +{ + "_id": "Rcfdd8fQYH3Ripm1", + "name": "33 - T02 - Saving Roll (transform)", + "type": "script", + "author": "Njc5YzFjZDI5NjZl", + "img": "modules/tokenmagic/gui/macros/images/33%20-%20T02%20-%20Saving%20Roll%20%28transform%29.webp", + "scope": "global", + "command": "let params =\n [{\n filterType: \"transform\",\n filterId: \"savingRoll\",\n autoDestroy: true,\n padding: 80,\n pivotX: 0.5,\n pivotY: 0.55,\n animated:\n {\n translationX:\n {\n animType: \"sinOscillation\",\n val1: -0.220,\n val2: +0.220,\n loops: 1,\n loopDuration: 1250\n },\n rotation:\n {\n animType: \"sinOscillation\",\n val1: -360,\n val2: +360,\n loops: 1,\n loopDuration: 1250,\n },\n scaleY:\n {\n animType: \"cosOscillation\",\n val1: 1,\n val2: 1.3,\n loops: 2,\n loopDuration: 625,\n },\n scaleX:\n {\n animType: \"cosOscillation\",\n val1: 1,\n val2: 1.4,\n loops: 2,\n loopDuration: 625,\n }\n }\n }];\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 5300000, + "flags": { + "furnace": { + "runAsGM": false + } + }, + "ownership": { + "default": 0 + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!Rcfdd8fQYH3Ripm1" +} diff --git a/src/packs/_source/tmMacros/33-t03-dodge-jump-transform.json b/src/packs/_source/tmMacros/33-t03-dodge-jump-transform.json new file mode 100644 index 0000000..fac43e7 --- /dev/null +++ b/src/packs/_source/tmMacros/33-t03-dodge-jump-transform.json @@ -0,0 +1,28 @@ +{ + "_id": "snidZpTtUrrRZpiF", + "name": "33 - T03 - Dodge Jump (transform)", + "type": "script", + "author": "Njc5YzFjZDI5NjZl", + "img": "modules/tokenmagic/gui/macros/images/33%20-%20T03%20-%20Dodge%20Jump%20%28transform%29.webp", + "scope": "global", + "command": "let params =\n [{\n filterType: \"transform\",\n filterId: \"jumpedDodge\",\n autoDestroy: true,\n padding: 80,\n animated:\n {\n translationY:\n {\n animType: \"cosOscillation\",\n val1: 0,\n val2: -0.225,\n loops: 1,\n loopDuration: 900\n },\n scaleY:\n {\n animType: \"cosOscillation\",\n val1: 1,\n val2: 0.65,\n loops: 2,\n loopDuration: 450,\n },\n scaleX:\n {\n animType: \"cosOscillation\",\n val1: 1,\n val2: 0.65,\n loops: 2,\n loopDuration: 450,\n }\n }\n }];\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 10300000, + "flags": { + "furnace": { + "runAsGM": false + } + }, + "ownership": { + "default": 0 + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!snidZpTtUrrRZpiF" +} diff --git a/src/packs/_source/tmMacros/33-t04-some-real-nuts-here-transform.json b/src/packs/_source/tmMacros/33-t04-some-real-nuts-here-transform.json new file mode 100644 index 0000000..36c4fd2 --- /dev/null +++ b/src/packs/_source/tmMacros/33-t04-some-real-nuts-here-transform.json @@ -0,0 +1,28 @@ +{ + "_id": "PHe9kakKlPKpARvm", + "name": "33 - T04 - Some Real Nuts Here! (transform)", + "type": "script", + "author": "Njc5YzFjZDI5NjZl", + "img": "modules/tokenmagic/gui/macros/images/33%20-%20T04%20-%20Some%20Real%20Nuts%20Here%21%20%28transform%29.webp", + "scope": "global", + "command": "let params =\n [{\n filterType: \"transform\",\n filterId: \"myTransform\",\n padding: 200,\n animated:\n {\n rotation:\n {\n clockWise: true,\n loopDuration: 700,\n animType: \"syncRotation\"\n },\n translationX:\n {\n animType: \"sinOscillation\",\n val1: -0.25,\n val2: +0.25\n },\n translationY:\n {\n animType: \"sinOscillation\",\n val1: -0.125,\n val2: +0.125,\n loopDuration: 1500\n },\n scaleX:\n {\n animType: \"sinOscillation\",\n val1: 0.5,\n val2: 2.6,\n loopDuration: 1200\n },\n scaleY:\n {\n animType: \"sinOscillation\",\n val1: 0.5,\n val2: 2.6,\n loopDuration: 1200\n }\n }\n }];\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 4900000, + "flags": { + "furnace": { + "runAsGM": false + } + }, + "ownership": { + "default": 0 + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!PHe9kakKlPKpARvm" +} diff --git a/src/packs/_source/tmMacros/34-t01-wound-repeatable-splash.json b/src/packs/_source/tmMacros/34-t01-wound-repeatable-splash.json new file mode 100644 index 0000000..6f20cb2 --- /dev/null +++ b/src/packs/_source/tmMacros/34-t01-wound-repeatable-splash.json @@ -0,0 +1,24 @@ +{ + "_id": "XzB3cj1TLsx7qABY", + "name": "34 - T01 - Wound - Repeatable (splash)", + "type": "script", + "author": "Njc5YzFjZDI5NjZl", + "img": "modules/tokenmagic/gui/macros/images/34%20-%20T01%20-%20Wound%20-%20Repeatable%20%28splash%29.webp", + "scope": "global", + "command": "let params =\n [{\n filterType: \"splash\",\n filterId: \"mySplash\",\n rank:5,\n color: 0x990505,\n padding: 80,\n time: Math.random()*1000,\n seed: Math.random(),\n splashFactor: 1,\n spread: 0.4,\n blend: 1,\n dimX: 1,\n dimY: 1,\n cut: false,\n textureAlphaBlend: true,\n anchorX: 0.32+(Math.random()*0.36),\n anchorY: 0.32+(Math.random()*0.36)\n }];\n\nawait TokenMagic.addFiltersOnSelected(params);", + "folder": null, + "sort": 6900000, + "flags": {}, + "ownership": { + "default": 0 + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!XzB3cj1TLsx7qABY" +} diff --git a/src/packs/_source/tmMacros/34-t02-dead-splash.json b/src/packs/_source/tmMacros/34-t02-dead-splash.json new file mode 100644 index 0000000..ce34c95 --- /dev/null +++ b/src/packs/_source/tmMacros/34-t02-dead-splash.json @@ -0,0 +1,24 @@ +{ + "_id": "WyiMXpscxVhgE1zy", + "name": "34 - T02 - Dead (splash)", + "type": "script", + "author": "Njc5YzFjZDI5NjZl", + "img": "modules/tokenmagic/gui/macros/images/34%20-%20T02%20-%20Dead%20%28splash%29.webp", + "scope": "global", + "command": "let params =\n [{\n filterType: \"splash\",\n filterId: \"mySplash\",\n color: 0x900505,\n padding: 30,\n time: Math.random()*1000,\n seed: Math.random()/100,\n splashFactor: 2,\n spread: 7,\n blend: 1,\n dimX: 1,\n dimY: 1,\n cut: true,\n textureAlphaBlend: false\n }];\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 6800000, + "flags": {}, + "ownership": { + "default": 0 + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!WyiMXpscxVhgE1zy" +} diff --git a/src/packs/_source/tmMacros/34-t03-blood-bath-splash.json b/src/packs/_source/tmMacros/34-t03-blood-bath-splash.json new file mode 100644 index 0000000..a751dd9 --- /dev/null +++ b/src/packs/_source/tmMacros/34-t03-blood-bath-splash.json @@ -0,0 +1,24 @@ +{ + "_id": "CRwxsDAsfCkXXTOa", + "name": "34 - T03 - Blood Bath (splash)", + "type": "script", + "author": "Njc5YzFjZDI5NjZl", + "img": "modules/tokenmagic/gui/macros/images/34%20-%20T03%20-%20Blood%20Bath%20%28splash%29.webp", + "scope": "global", + "command": "let params =\n [{\n filterType: \"splash\",\n filterId: \"mySplash\",\n color: 0xFF0505,\n padding: 80,\n time: 0,\n seed: 0.10,\n splashFactor: 2.25,\n spread: 7,\n blend: 7,\n dimX: 1,\n dimY: 1,\n alphaBlending: false,\n alphaDiscard: true,\n cut: true,\n animated :\n {\n time : \n { \n active: true, \n speed: 0.0009, \n animType: \"move\" \n }\n }\n }];\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 2300000, + "flags": {}, + "ownership": { + "default": 0 + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!CRwxsDAsfCkXXTOa" +} diff --git a/src/packs/_source/tmMacros/35-t01-fire-v2-xfire.json b/src/packs/_source/tmMacros/35-t01-fire-v2-xfire.json new file mode 100644 index 0000000..bd3dc88 --- /dev/null +++ b/src/packs/_source/tmMacros/35-t01-fire-v2-xfire.json @@ -0,0 +1,24 @@ +{ + "_id": "URV08yIJk4cBTppj", + "name": "35 - T01 - Fire v2 (xfire)", + "type": "script", + "author": "Njc5YzFjZDI5NjZl", + "img": "modules/tokenmagic/gui/macros/images/35%20-%20T01%20-%20Fire%20v2%20%28xfire%29.webp", + "scope": "global", + "command": "let params =\n[{\n filterType: \"xfire\",\n filterId: \"myFireV2XFire\",\n time: 0,\n blend: 1,\n amplitude: 1,\n dispersion: 0,\n chromatic: false,\n scaleX: 1.5,\n scaleY: 1,\n inlay: false,\n animated :\n {\n time : \n { \n active: true, \n speed: -0.0015, \n animType: \"move\" \n }\n }\n}];\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 6200000, + "flags": {}, + "ownership": { + "default": 0 + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!URV08yIJk4cBTppj" +} diff --git a/src/packs/_source/tmMacros/35-t02-chromatic-fire-xfire.json b/src/packs/_source/tmMacros/35-t02-chromatic-fire-xfire.json new file mode 100644 index 0000000..35c4e4c --- /dev/null +++ b/src/packs/_source/tmMacros/35-t02-chromatic-fire-xfire.json @@ -0,0 +1,24 @@ +{ + "_id": "9FRCMHBW6OsUXDwz", + "name": "35 - T02 - Chromatic Fire (xfire)", + "type": "script", + "author": "Njc5YzFjZDI5NjZl", + "img": "modules/tokenmagic/gui/macros/images/35%20-%20T02%20-%20Chromatic%20Fire%20%28xfire%29.webp", + "scope": "global", + "command": "let params =\n[{\n filterType: \"xfire\",\n filterId: \"myChromaticXFire\",\n time: 0,\n blend: 2,\n amplitude: 1.1,\n dispersion: 0,\n chromatic: true,\n scaleX: 1,\n scaleY: 1,\n inlay: false,\n animated :\n {\n time : \n { \n active: true, \n speed: -0.0015, \n animType: \"move\" \n }\n }\n}];\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 1600000, + "flags": {}, + "ownership": { + "default": 0 + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!9FRCMHBW6OsUXDwz" +} diff --git a/src/packs/_source/tmMacros/35-t03-sparks-xfire.json b/src/packs/_source/tmMacros/35-t03-sparks-xfire.json new file mode 100644 index 0000000..f453530 --- /dev/null +++ b/src/packs/_source/tmMacros/35-t03-sparks-xfire.json @@ -0,0 +1,24 @@ +{ + "_id": "GKxtep2eo55zKl1Z", + "name": "35 - T03 - Sparks (xfire)", + "type": "script", + "author": "Njc5YzFjZDI5NjZl", + "img": "modules/tokenmagic/gui/macros/images/35%20-%20T03%20-%20Sparks%20%28xfire%29.webp", + "scope": "global", + "command": "let params =\n[{\n filterType: \"xfire\",\n filterId: \"mySparksXFire\",\n time: 0,\n blend: 2,\n amplitude: 0.7,\n dispersion: 0,\n chromatic: false,\n scaleX: 2,\n scaleY: 2,\n inlay: false,\n animated :\n {\n time : \n { \n active: true, \n speed: -0.0015, \n animType: \"move\" \n }\n }\n}];\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 3400000, + "flags": {}, + "ownership": { + "default": 0 + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!GKxtep2eo55zKl1Z" +} diff --git a/src/packs/_source/tmMacros/35-t04-cold-fire-xfire.json b/src/packs/_source/tmMacros/35-t04-cold-fire-xfire.json new file mode 100644 index 0000000..0df80ca --- /dev/null +++ b/src/packs/_source/tmMacros/35-t04-cold-fire-xfire.json @@ -0,0 +1,24 @@ +{ + "_id": "hC63QbO6aATjatSA", + "name": "35 - T04 - Cold Fire (xfire)", + "type": "script", + "author": "Njc5YzFjZDI5NjZl", + "img": "modules/tokenmagic/gui/macros/images/35%20-%20T04%20-%20Cold%20Fire%20%28xfire%29.webp", + "scope": "global", + "command": "let params =\n[{\n filterType: \"xfire\",\n filterId: \"myColdXFire\",\n time: 0,\n color: 0xBBDDEE,\n blend: 1,\n amplitude: 1,\n dispersion: 0,\n chromatic: false,\n scaleX: 1,\n scaleY: 1,\n inlay: false,\n animated :\n {\n time : \n { \n active: true, \n speed: -0.0015, \n animType: \"move\" \n }\n }\n}];\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 8700000, + "flags": {}, + "ownership": { + "default": 0 + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!hC63QbO6aATjatSA" +} diff --git a/src/packs/_source/tmMacros/35-t05-black-fire-xfire.json b/src/packs/_source/tmMacros/35-t05-black-fire-xfire.json new file mode 100644 index 0000000..dd0b7e3 --- /dev/null +++ b/src/packs/_source/tmMacros/35-t05-black-fire-xfire.json @@ -0,0 +1,24 @@ +{ + "_id": "Zvg3xCOOPTtPH1MY", + "name": "35 - T05 - Black Fire (xfire)", + "type": "script", + "author": "Njc5YzFjZDI5NjZl", + "img": "modules/tokenmagic/gui/macros/images/35%20-%20T05%20-%20Black%20Fire%20%28xfire%29.webp", + "scope": "global", + "command": "let params =\n[{\n filterType: \"xfire\",\n filterId: \"myBlackXFire\",\n time: 0,\n color: 0x707070,\n blend: 11,\n amplitude: 1,\n dispersion: 2.2,\n chromatic: false,\n scaleX: 2.5,\n scaleY: 2,\n inlay: false,\n animated :\n {\n time : \n { \n active: true, \n speed: -0.0015, \n animType: \"move\" \n }\n }\n}];\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 7200000, + "flags": {}, + "ownership": { + "default": 0 + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!Zvg3xCOOPTtPH1MY" +} diff --git a/src/packs/_source/tmMacros/35-t06-custom-color-fire-xfire.json b/src/packs/_source/tmMacros/35-t06-custom-color-fire-xfire.json new file mode 100644 index 0000000..94b31dc --- /dev/null +++ b/src/packs/_source/tmMacros/35-t06-custom-color-fire-xfire.json @@ -0,0 +1,24 @@ +{ + "_id": "llpMoa9rOjeCzWf3", + "name": "35 - T06 - Custom Color Fire (xfire)", + "type": "script", + "author": "Njc5YzFjZDI5NjZl", + "img": "modules/tokenmagic/gui/macros/images/35%20-%20T06%20-%20Custom%20Color%20Fire%20%28xfire%29.webp", + "scope": "global", + "command": "// example with color fine tuning\nlet params =\n[{\n filterType: \"xfire\",\n filterId: \"myCustomXFire\",\n time: 0,\n color1: 0x00DD20,\n color2: 0x009090,\n color3: 0x001020,\n color4: 0x00CCFF,\n blend: 1,\n amplitude: 1,\n dispersion: 0,\n chromatic: false,\n scaleX: 1,\n scaleY: 1,\n inlay: false,\n animated :\n {\n time : \n { \n active: true, \n speed: -0.0015, \n animType: \"move\" \n }\n }\n}];\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 9700000, + "flags": {}, + "ownership": { + "default": 0 + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!llpMoa9rOjeCzWf3" +} diff --git a/src/packs/_source/tmMacros/35-t07-superfrost-xfire.json b/src/packs/_source/tmMacros/35-t07-superfrost-xfire.json new file mode 100644 index 0000000..d551570 --- /dev/null +++ b/src/packs/_source/tmMacros/35-t07-superfrost-xfire.json @@ -0,0 +1,24 @@ +{ + "_id": "TUyzBYb350Gcn5rE", + "name": "35 - T07 - SuperFrost (xfire)", + "type": "script", + "author": "Njc5YzFjZDI5NjZl", + "img": "modules/tokenmagic/gui/macros/images/35%20-%20T07%20-%20SuperFrost%20%28xfire%29.webp", + "scope": "global", + "command": "let params =\n[{\n filterType: \"xfire\",\n filterId: \"mySuperFrost\",\n color: 0xACC5C5,\n time: 0,\n blend: 5,\n amplitude: 1,\n dispersion: 0,\n chromatic: false,\n scaleX: 1,\n scaleY: 1,\n inlay: true,\n animated :\n {\n time : \n { \n active: true, \n speed: -0.0020, \n animType: \"move\" \n } \n }\n}];\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 5900000, + "flags": {}, + "ownership": { + "default": 0 + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!TUyzBYb350Gcn5rE" +} diff --git a/src/packs/_source/tmMacros/35-t08-animated-superfrost-xfire-xglow.json b/src/packs/_source/tmMacros/35-t08-animated-superfrost-xfire-xglow.json new file mode 100644 index 0000000..02d5b40 --- /dev/null +++ b/src/packs/_source/tmMacros/35-t08-animated-superfrost-xfire-xglow.json @@ -0,0 +1,24 @@ +{ + "_id": "TktbnfMR7IIWewbg", + "name": "35 - T08 - Animated SuperFrost (xfire+xglow)", + "type": "script", + "author": "Njc5YzFjZDI5NjZl", + "img": "modules/tokenmagic/gui/macros/images/35%20-%20T08%20-%20Animated%20SuperFrost%20%28xfire%2Bxglow%29.webp", + "scope": "global", + "command": "let params =\n [{\n filterType: \"zapshadow\",\n filterId: \"myAnimSuperFrost\",\n alphaTolerance: 0.50\n },\n {\n filterType: \"xfire\",\n filterId: \"myAnimSuperFrost\",\n color: 0xACC5C5,\n time: 0,\n blend: 5,\n amplitude: 1,\n dispersion: 0,\n chromatic: false,\n scaleX: 1,\n scaleY: 1,\n inlay: true,\n animated:\n {\n time:\n {\n active: true,\n speed: -0.0020,\n animType: \"move\"\n },\n dispersion:\n {\n animType: \"cosOscillation\",\n val1: 0.25,\n val2: 0.55,\n loopDuration: 3000\n }\n }\n },\n {\n filterType: \"xglow\",\n filterId: \"myAnimSuperFrost\",\n auraType: 1,\n color: 0x6090AA,\n thickness: 4.5,\n scale: 10,\n time: 0,\n auraIntensity: 0.25,\n subAuraIntensity: 1,\n threshold: 0.5,\n discard: false,\n animated:\n {\n time:\n {\n active: true,\n speed: 0.0018,\n animType: \"move\"\n },\n thickness:\n {\n val1: 2, val2: 2.5,\n animType: \"cosOscillation\",\n loopDuration: 3000\n },\n subAuraIntensity:\n {\n val1: 0.45, val2: 0.65,\n animType: \"cosOscillation\",\n loopDuration: 6000\n },\n auraIntensity:\n {\n val1: 0.9, val2: 1.1,\n animType: \"cosOscillation\",\n loopDuration: 3000\n }\n }\n }];\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 6000000, + "flags": {}, + "ownership": { + "default": 0 + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!TktbnfMR7IIWewbg" +} diff --git a/src/packs/_source/tmMacros/35-t09-superheat-xfire.json b/src/packs/_source/tmMacros/35-t09-superheat-xfire.json new file mode 100644 index 0000000..95b725b --- /dev/null +++ b/src/packs/_source/tmMacros/35-t09-superheat-xfire.json @@ -0,0 +1,24 @@ +{ + "_id": "2l4UxekocRzIzaPE", + "name": "35 - T09 - SuperHeat (xfire)", + "type": "script", + "author": "Njc5YzFjZDI5NjZl", + "img": "modules/tokenmagic/gui/macros/images/35%20-%20T09%20-%20SuperHeat%20%28xfire%29.webp", + "scope": "global", + "command": "let params =\n[{\n filterType: \"xfire\",\n filterId: \"mySuperHeat\",\n time: 0,\n blend: 5,\n amplitude: 0.25,\n dispersion: -1,\n chromatic: false,\n scaleX: 1,\n scaleY: 1,\n inlay: true,\n animated :\n {\n time : \n { \n active: true, \n speed: -0.0090, \n animType: \"move\" \n }\n }\n}];\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 300000, + "flags": {}, + "ownership": { + "default": 0 + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!2l4UxekocRzIzaPE" +} diff --git a/src/packs/_source/tmMacros/35-t10-animated-superheat-xfire-liquid-wave.json b/src/packs/_source/tmMacros/35-t10-animated-superheat-xfire-liquid-wave.json new file mode 100644 index 0000000..26972b4 --- /dev/null +++ b/src/packs/_source/tmMacros/35-t10-animated-superheat-xfire-liquid-wave.json @@ -0,0 +1,24 @@ +{ + "_id": "eBGBaCFsLO8b3lMb", + "name": "35 - T10 - Animated SuperHeat (xfire+liquid+wave)", + "type": "script", + "author": "Njc5YzFjZDI5NjZl", + "img": "modules/tokenmagic/gui/macros/images/35%20-%20T10%20-%20Animated%20SuperHeat%20%28xfire%2Bliquid%2Bwave%29.webp", + "scope": "global", + "command": "let params =\n[{\n filterType: \"xfire\",\n filterId: \"myAnimSuperHeat\",\n time: 0,\n blend: 5,\n amplitude: 0.5,\n dispersion: -1,\n chromatic: false,\n scaleX: 1,\n scaleY: 1,\n inlay: true,\n animated :\n {\n time : \n { \n active: true, \n speed: -0.0090, \n animType: \"move\" \n }\n }\n},\n{\n filterType: \"liquid\",\n filterId: \"myAnimSuperHeat\",\n color: 0xBB9500,\n time: 0,\n blend: 8,\n intensity: 1,\n spectral: false,\n scale: 0.25,\n animated :\n {\n time : \n { \n active: true, \n speed: 0.0010, \n animType: \"move\" \n }\n }\n},\n{\n filterType: \"wave\",\n filterId: \"myAnimSuperHeat\",\n time: 0,\n anchorX: 0.5,\n anchorY: 0.5,\n strength: 0.005,\n frequency: 60,\n color: 0xFFFFFF,\n maxIntensity: 2.0,\n minIntensity: 1.0,\n padding:10,\n animated :\n {\n time : \n { \n active: true, \n speed: 0.0100, \n animType: \"move\" \n }\n }\n}];\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 7900000, + "flags": {}, + "ownership": { + "default": 0 + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!eBGBaCFsLO8b3lMb" +} diff --git a/src/packs/_source/tmMacros/36-t01-turn-into-mystery-man-polymorph.json b/src/packs/_source/tmMacros/36-t01-turn-into-mystery-man-polymorph.json new file mode 100644 index 0000000..d22c154 --- /dev/null +++ b/src/packs/_source/tmMacros/36-t01-turn-into-mystery-man-polymorph.json @@ -0,0 +1,24 @@ +{ + "_id": "lZefFMIYs8WYRpdZ", + "name": "36 - T01 - Turn into Mystery Man (polymorph)", + "type": "script", + "flags": {}, + "scope": "global", + "command": "// This macro contains a small tutorial : how to work with non-infinite loops and halfCosOscillation animType\n\n// Click once to transform your token and again to revert to the original shape (thank to halfCosOscillation)\n\n// There is 9 types of metamorphose\n// 1 - Simple transition\n// 2 - Dreamy\n// 3 - Twist\n// 4 - Water drop\n// 5 - TV Noise\n// 6 - Morphing\n// 7 - Take off/Put on you disguise!\n// 8 - Wind\n// 9 - Hologram\n\n// change the type here\nlet transitionType = 4;\n\n// change the target image here\nlet targetImagePath = \"icons/svg/mystery-man.svg\";\n\n// declare filter id (think to change the id for personal macros)\n// each filterId should be unique to a player or gm to prevent collisions\n// example : \"brutusChthulhuPolymorph\"\nlet polymorphFilterId = \"myPolymorph\";\n\n// we put our code into an async function that will be called later\nlet polymorphFunc = async function () {\n\n for (const token of canvas.tokens.controlled) {\n let params;\n \n // Is the filter already activated on the placeable ? \n if (token.TMFXhasFilterId(polymorphFilterId)) {\n \n // Yes. So we update the type in the general section and loops + active in the progress animated section, to activate the animation for just one loop.\n // \"type\" to allow you to change the animation type\n // \"active\" to say at Token Magic : \"Hey filter! It's time to work again!\"\n // \"loops\" so that Token Magic can know how many loops it needs to schedule for the animation.\n // Each animation loop decreases \"loops\" by one. When \"loops\" reach 0, \"active\" becomes \"false\" and the animation will be dormant again.\n // Thank to the halfCosOscillation, a loop brings the value of the property from val1 to val2. A second loop is needed to bring val2 to val1. This is useful for monitoring progress with back and forth movements.\n params =\n [{\n filterType: \"polymorph\",\n filterId: polymorphFilterId,\n type: transitionType,\n animated:\n {\n progress:\n {\n active: true,\n loops: 1\n }\n }\n }];\n\n } else {\n\n // No. So we create the entirety of the filter\n params =\n [{\n filterType: \"polymorph\",\n filterId: polymorphFilterId,\n type: transitionType,\n padding: 70,\n magnify: 1,\n imagePath: targetImagePath,\n animated:\n {\n progress:\n {\n active: true,\n animType: \"halfCosOscillation\",\n val1: 0,\n val2: 100,\n loops: 1,\n loopDuration: 1000\n }\n }\n }];\n }\n\n // all functions that add, update or delete filters are asynchronous\n // if you are in a loop AND/OR you chain these functions, it is MANDATORY to await them\n // otherwise, data persistence may not works.\n // this is the reason why we use an async function (we cant use await in a non-async function)\n // avoid awaiting in a forEach loop, use \"for\" or \"for/of\" loop.\n await token.TMFXaddUpdateFilters(params);\n }\n\n};\n\n// polymorph async function call\npolymorphFunc();", + "author": "Njc5YzFjZDI5NjZl", + "img": "modules/tokenmagic/gui/macros/images/36%20-%20T01%20-%20Turn%20into%20Mystery%20Man%20%28polymorph%29.webp", + "ownership": { + "default": 0 + }, + "folder": null, + "sort": 9600000, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!lZefFMIYs8WYRpdZ" +} diff --git a/src/packs/_source/tmMacros/37-t01-ioun-stone-sprite.json b/src/packs/_source/tmMacros/37-t01-ioun-stone-sprite.json new file mode 100644 index 0000000..af947fa --- /dev/null +++ b/src/packs/_source/tmMacros/37-t01-ioun-stone-sprite.json @@ -0,0 +1,24 @@ +{ + "_id": "vd2sFikounQpg6nh", + "name": "37 - T01 - Ioun Stone (sprite)", + "type": "script", + "author": "f8mJy0XxrFT8Pzt3", + "img": "modules/tokenmagic/gui/macros/images/37%20-%20T01%20-%20Ioun%20Stone%20%28sprite%29.webp", + "scope": "global", + "command": "let params =\n[{\n filterType: \"sprite\",\n filterId: \"mySprite\",\n imagePath: \"modules/tokenmagic/fx/assets/gem-2.png\",\n gridPadding: 1,\n scaleX: 0.20,\n scaleY: 0.20,\n colorize: true,\n color: 0xFFBB00,\n inverse: false,\n top: true,\n animated:\n {\n rotation: \n { \n active: true,\n clockWise: false, \n loopDuration: 2000, \n animType: \"syncRotation\"\n },\n translationX:\n {\n active: true,\n animType: \"cosOscillation\",\n val1: 2.0,\n val2: -2.0,\n loopDuration: 4000,\n },\n translationY:\n {\n active: true,\n animType: \"sinOscillation\",\n val1: 2.0,\n val2: -2.0,\n loopDuration: 4000,\n },\n color:\n {\n active: true,\n animType: \"colorOscillation\",\n val1: 0xFFFF00,\n val2: 0x00FFFF,\n loopDuration: 4000,\n }\n }\n}];\n\nawait TokenMagic.addFiltersOnSelected(params);", + "folder": null, + "sort": 10900000, + "flags": {}, + "ownership": { + "default": 0 + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!vd2sFikounQpg6nh" +} diff --git a/src/packs/_source/tmMacros/37-t02-pentagram-sprite.json b/src/packs/_source/tmMacros/37-t02-pentagram-sprite.json new file mode 100644 index 0000000..fcc3f6c --- /dev/null +++ b/src/packs/_source/tmMacros/37-t02-pentagram-sprite.json @@ -0,0 +1,24 @@ +{ + "_id": "sIy0tlSrWhG7m15h", + "name": "37 - T02 - Pentagram (sprite)", + "type": "script", + "author": "f8mJy0XxrFT8Pzt3", + "img": "modules/tokenmagic/gui/macros/images/37%20-%20T02%20-%20Pentagram%20%28sprite%29.webp", + "scope": "global", + "command": "let params =\n[{\n filterType: \"sprite\",\n filterId: \"myPentagram\",\n imagePath: \"modules/tokenmagic/fx/assets/pentagram.png\",\n gridPadding: 2,\n scaleX: 3,\n scaleY: 3,\n colorize: true,\n color: 0xFF0000,\n inverse: true,\n top: false,\n animated:\n {\n rotation: \n { \n active: true,\n clockWise: false, \n loopDuration: 4000, \n animType: \"syncRotation\"\n }\n }\n}];\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 10000000, + "flags": {}, + "ownership": { + "default": 0 + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!sIy0tlSrWhG7m15h" +} diff --git a/src/packs/_source/tmMacros/37-t03-fire-pentagram-sprite-xglow.json b/src/packs/_source/tmMacros/37-t03-fire-pentagram-sprite-xglow.json new file mode 100644 index 0000000..3f19ede --- /dev/null +++ b/src/packs/_source/tmMacros/37-t03-fire-pentagram-sprite-xglow.json @@ -0,0 +1,24 @@ +{ + "_id": "4cniAQdp0uQ4vE3G", + "name": "37 - T03 - Fire Pentagram (sprite+xglow)", + "type": "script", + "author": "f8mJy0XxrFT8Pzt3", + "img": "modules/tokenmagic/gui/macros/images/37%20-%20T03%20-%20Fire%20Pentagram%20%28sprite%2Bxglow%29.webp", + "scope": "global", + "command": "let params =\n[{\n filterType: \"sprite\",\n filterId: \"myFirePentagram\",\n imagePath: \"modules/tokenmagic/fx/assets/pentagram.png\",\n gridPadding: 2,\n scaleX: 3,\n scaleY: 3,\n colorize: true,\n color: 0x000000,\n inverse: true,\n top: false,\n animated:\n {\n rotation: \n { \n active: true,\n clockWise: false, \n loopDuration: 4000, \n animType: \"syncRotation\"\n }\n }\n},\n{\n filterType: \"zapshadow\",\n filterId: \"myFirePentagram\",\n alphaTolerance: 0.50\n},\n{\n filterType: \"xglow\",\n filterId: \"myFirePentagram\",\n auraType: 2,\n color: 0x903010,\n thickness: 9.8,\n scale: 1.,\n time: 0,\n auraIntensity: 2,\n subAuraIntensity: 1.5,\n threshold: 0.40,\n discard: true,\n animated:\n {\n time : \n { \n active: true,\n speed: 0.0027, \n animType: \"move\" \n },\n thickness:\n {\n active: true,\n loopDuration: 3000, \n animType: \"cosOscillation\", \n val1:2, \n val2:5\n }\n }\n}];\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 900000, + "flags": {}, + "ownership": { + "default": 0 + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!4cniAQdp0uQ4vE3G" +} diff --git a/src/packs/_source/tmMacros/38-replace-color.json b/src/packs/_source/tmMacros/38-replace-color.json new file mode 100644 index 0000000..3666b6a --- /dev/null +++ b/src/packs/_source/tmMacros/38-replace-color.json @@ -0,0 +1,28 @@ +{ + "name": "38 - Replace Color", + "type": "script", + "author": "SyH1ydCe6TgtPGAR", + "img": "icons/magic/time/arrows-circling-pink.webp", + "scope": "global", + "command": "async function applyFilter() {\n\tlet params = [\n\t\t{\n\t\t\tfilterType: 'replaceColor',\n\t\t\tfilterId: 'ReplaceColor',\n\t\t\toriginalColor: PIXI.utils.hex2rgb(originalColor),\n\t\t\tnewColor: PIXI.utils.hex2rgb(newColor),\n\t\t\tepsilon,\n\t\t},\n\t];\n\n\tawait TokenMagic.addUpdateFiltersOnSelected(params);\n}\n\nlet originalColor = 0xff0000;\nlet newColor = 0x00ff00;\nlet epsilon = 0.7;\n\nconst filter = TokenMagic.getControlledPlaceables()[0].children.find((child) => child.filters?.[0]?.filterId === 'ReplaceColor')?.filters[0];\nif (filter) {\n\toriginalColor = PIXI.utils.rgb2hex(filter.uniforms.originalColor);\n\tnewColor = PIXI.utils.rgb2hex(filter.uniforms.newColor);\n\tepsilon = filter.uniforms.epsilon;\n}\n\nconst originalColorString = PIXI.utils.hex2string(originalColor);\nconst newColorString = PIXI.utils.hex2string(newColor);\n\nnew Dialog(\n\t{\n\t\ttitle: 'Replace Color',\n\t\tcontent: `\n
    \n

    Select the parameters you wish to change

    \n
    \n \n
    \n \n \n \n
    \n
    \n \n \n \n
    \n
    \n \n \n ${epsilon}\n \n
    \n
    \n `,\n\t\tbuttons: {\n\t\t\tsave: {\n\t\t\t\ticon: ``,\n\t\t\t\tlabel: 'Set',\n\t\t\t\tcallback: async (html) => applyFilter(),\n\t\t\t},\n\t\t\tcancel: {\n\t\t\t\ticon: ``,\n\t\t\t\tlabel: 'Cancel',\n\t\t\t\tcallback: async (html) => {\n\t\t\t\t\tif (!filter) TokenMagic.deleteFiltersOnSelected();\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\tdefault: 'yes',\n\t\trender: (html) => {\n\t\t\tfunction updateFilterParams() {\n\t\t\t\toriginalColor = PIXI.utils.string2hex(html.querySelector('#originalColorText').value);\n\t\t\t\tnewColor = PIXI.utils.string2hex(html.querySelector('#replacementColorText').value);\n\t\t\t\tepsilon = +html.querySelector('input[name=tolerance]').value;\n\n\t\t\t\tapplyFilter();\n\t\t\t}\n\n\t\t\tconst oldColor = html.querySelector('input[name=originalColor]');\n\t\t\tconst oldColorBar = html.querySelector('#originalColorText');\n\t\t\tconst replacementColor = html.querySelector('input[name=replacementColor]');\n\t\t\tconst replacementColorBar = html.querySelector('#replacementColorText');\n\t\t\tconst tolerance = html.querySelector('input[name=tolerance]');\n\t\t\tconst toleranceSpan = html.querySelector('#toleranceSpan');\n\n\t\t\toldColor.addEventListener('change', (ev) => (oldColorBar.value = ev.target.value));\n\t\t\toldColorBar.addEventListener('change', (ev) => (oldColor.value = ev.target.value));\n\t\t\treplacementColor.addEventListener('change', (ev) => (replacementColorBar.value = ev.target.value));\n\t\t\treplacementColorBar.addEventListener('change', (ev) => (replacementColor.value = ev.target.value));\n\t\t\ttolerance.addEventListener('change', (ev) => (toleranceSpan.textContent = ev.target.value));\n\t\t\thtml.addEventListener('change', () => updateFilterParams());\n\n\t\t\tapplyFilter();\n\t\t},\n\t},\n\t{ jQuery: false }\n).render(true);", + "folder": null, + "sort": 11900000, + "flags": { + "furnace": { + "runAsGM": false + } + }, + "_id": "zLsUrLWfdJn7BjTw", + "ownership": { + "default": 0 + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!zLsUrLWfdJn7BjTw" +} diff --git a/src/packs/_source/tmMacros/39-dungeondraft-tint.json b/src/packs/_source/tmMacros/39-dungeondraft-tint.json new file mode 100644 index 0000000..5f8baf9 --- /dev/null +++ b/src/packs/_source/tmMacros/39-dungeondraft-tint.json @@ -0,0 +1,24 @@ +{ + "name": "39 - DungeonDraft Tint", + "type": "script", + "author": "SyH1ydCe6TgtPGAR", + "img": "icons/magic/light/hand-sparks-smoke-green.webp", + "scope": "global", + "command": "async function applyFilter() {\n\tlet params = [\n\t\t{\n\t\t\tfilterType: 'ddTint',\n\t\t\tfilterId: 'DDTint',\n\t\t\ttint: PIXI.utils.hex2rgb(color),\n\t\t},\n\t];\n\n\tawait TokenMagic.addUpdateFiltersOnSelected(params);\n}\n\nlet color = 0xff0000;\n\nconst filter = TokenMagic.getControlledPlaceables()[0].children.find((child) => child.filters?.[0]?.filterId === 'DDTint')?.filters[0];\nif (filter) color = PIXI.utils.rgb2hex(filter.uniforms.tint);\n\nconst colorString = PIXI.utils.hex2string(color);\n\nnew Dialog(\n\t{\n\t\ttitle: 'Dungeondraft Tint',\n\t\tcontent: `\n
    \n
    \n \n \n \n
    \n
    \n `,\n\t\tbuttons: {\n\t\t\tsave: {\n\t\t\t\ticon: ``,\n\t\t\t\tlabel: 'Set',\n\t\t\t\tcallback: async (html) => applyFilter(),\n\t\t\t},\n\t\t\tcancel: {\n\t\t\t\ticon: ``,\n\t\t\t\tlabel: 'Cancel',\n\t\t\t\tcallback: async (html) => {\n\t\t\t\t\tif (!filter) TokenMagic.deleteFiltersOnSelected();\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\tdefault: 'save',\n\t\trender: (html) => {\n\t\t\tfunction updateFilterParams() {\n\t\t\t\tcolor = PIXI.utils.string2hex(html.querySelector('#colorText').value);\n\n\t\t\t\tapplyFilter();\n\t\t\t}\n\n\t\t\tconst oldColor = html.querySelector('input[name=color]');\n\t\t\tconst oldColorBar = html.querySelector('#colorText');\n\n\t\t\toldColor.addEventListener('change', (ev) => (oldColorBar.value = ev.target.value));\n\t\t\toldColorBar.addEventListener('change', (ev) => (oldColor.value = ev.target.value));\n\t\t\thtml.addEventListener('change', () => updateFilterParams());\n\n\t\t\tapplyFilter();\n\t\t},\n\t},\n\t{ jQuery: false }\n).render(true);", + "folder": null, + "sort": 11500000, + "flags": {}, + "_id": "ySVgJ0j9REhxaF5O", + "ownership": { + "default": 0 + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!ySVgJ0j9REhxaF5O" +} diff --git a/src/packs/_source/tmMacros/40-ascii-ascii.json b/src/packs/_source/tmMacros/40-ascii-ascii.json new file mode 100644 index 0000000..bf0d2de --- /dev/null +++ b/src/packs/_source/tmMacros/40-ascii-ascii.json @@ -0,0 +1,30 @@ +{ + "name": "40 - Ascii (ascii)", + "type": "script", + "author": "UTH9wXZFkTza6igr", + "img": "modules/tokenmagic/gui/macros/images/40%20-%20Ascii.webp", + "scope": "global", + "command": "let params =\n[{\n filterType: \"ascii\",\n filterId: \"myAscii\",\n size: 8\n}];\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "flags": { + "advanced-macros": { + "runAsGM": false, + "runForEveryone": false, + "runForSpecificUser": "" + } + }, + "ownership": { + "default": 0 + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": 1669130213391, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "folder": null, + "sort": 7500000, + "_id": "bt4FUt1RboVkjk2W", + "_key": "!macros!bt4FUt1RboVkjk2W" +} diff --git a/src/packs/_source/tmMacros/41-dot-shade-dot.json b/src/packs/_source/tmMacros/41-dot-shade-dot.json new file mode 100644 index 0000000..829547b --- /dev/null +++ b/src/packs/_source/tmMacros/41-dot-shade-dot.json @@ -0,0 +1,24 @@ +{ + "name": "41 - Dot Shade (dot)", + "type": "script", + "scope": "global", + "author": "UTH9wXZFkTza6igr", + "img": "modules/tokenmagic/gui/macros/images/41%20-%20Dot.webp", + "command": "let params =\n[{\n filterType: \"dot\",\n filterId: \"myDot\",\n scale: 1,\n angle: 5,\n grayscale: true,\n}];\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "ownership": { + "default": 0 + }, + "flags": {}, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": 1673706034119, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "folder": null, + "sort": 2500000, + "_id": "D2d0BpOjnTSbzeOt", + "_key": "!macros!D2d0BpOjnTSbzeOt" +} diff --git a/src/packs/_source/tmMacros/42-crt-monitor-crt.json b/src/packs/_source/tmMacros/42-crt-monitor-crt.json new file mode 100644 index 0000000..2374fe1 --- /dev/null +++ b/src/packs/_source/tmMacros/42-crt-monitor-crt.json @@ -0,0 +1,24 @@ +{ + "name": "42 - CRT Monitor (crt)", + "type": "script", + "scope": "global", + "author": "UTH9wXZFkTza6igr", + "img": "modules/tokenmagic/gui/macros/images/42%20-%20CRT.webp", + "command": "let params = [\n {\n filterType: \"crt\",\n filterId: \"myCRT\",\n curvature: 4,\n lineWidth: 5,\n lineContrast: 0.25,\n verticalLine: false,\n noise: 0.3,\n noiseSize: 1,\n vignetting: 0,\n vignettingAlpha: 1,\n vignettingBlur: 0.3,\n animated: {\n seed: {\n active: true,\n animType: \"randomNumber\",\n val1: 0,\n val2: 1\n },\n time: {\n active: true,\n speed: -0.01,\n animType: \"move\"\n },\n vignetting: {\n active: false,\n animType: \"syncCosOscillation\",\n loopDuration: 2000,\n val1: 0.1,\n val2: 0.2\n }\n },\n enabled: true\n },\n {\n filterType: \"outline\",\n filterId: \"crtOutline\",\n color: 0,\n thickness: 0,\n zOrder: 321,\n enabled: true\n }\n];\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "ownership": { + "default": 0 + }, + "flags": {}, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": 1673706658449, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "folder": null, + "sort": 4500000, + "_id": "JZzR087czwBFJOFC", + "_key": "!macros!JZzR087czwBFJOFC" +} diff --git a/src/packs/_source/tmMacros/43-rgb-split-rgbsplit.json b/src/packs/_source/tmMacros/43-rgb-split-rgbsplit.json new file mode 100644 index 0000000..4a32460 --- /dev/null +++ b/src/packs/_source/tmMacros/43-rgb-split-rgbsplit.json @@ -0,0 +1,24 @@ +{ + "name": "43 - RGB Split (rgbSplit)", + "type": "script", + "scope": "global", + "author": "UTH9wXZFkTza6igr", + "img": "modules/tokenmagic/gui/macros/images/43%20-%20RGB%20Split.webp", + "command": "let params = [\n {\n filterType: \"rgbSplit\",\n filterId: \"myRGBSplit\",\n redX: -10,\n redY: 0,\n greenX: 0,\n greenY: 10,\n blueX: 0,\n blueY: 0,\n enabled: true\n }\n];\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "ownership": { + "default": 0 + }, + "flags": {}, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": 1673711141092, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "folder": null, + "sort": 1000000, + "_id": "5tUn35zYzB7m8sLN", + "_key": "!macros!5tUn35zYzB7m8sLN" +} diff --git a/src/packs/_source/tmMacros/44-criss-cross-overlay-sprite.json b/src/packs/_source/tmMacros/44-criss-cross-overlay-sprite.json new file mode 100644 index 0000000..7eb8a1e --- /dev/null +++ b/src/packs/_source/tmMacros/44-criss-cross-overlay-sprite.json @@ -0,0 +1,24 @@ +{ + "name": "44 - Criss-Cross Overlay (sprite)", + "type": "script", + "scope": "global", + "author": "UTH9wXZFkTza6igr", + "img": "modules/tokenmagic/gui/macros/images/44%20-%20Criss%20Cross%20Overlay%20(sprite).webp", + "command": "let params = [\n {\n filterType: \"sprite\",\n filterId: \"crissCrossBox\",\n imagePath: \"modules/tokenmagic/fx/assets/box.webp\",\n repeat: true,\n alphaDiscard: true,\n colorize: true,\n color: 0x0000FF,\n inverse: true,\n gridPadding: 1,\n maintainAspectRatio: false,\n maintainScale: false,\n scaleX: 0.16,\n scaleY: 0.16,\n translationX: 0,\n translationY: 0,\n rotation: 45,\n alpha: 0.75,\n top: true,\n animated: {\n rotation: {\n active: false,\n clockWise: false,\n loopDuration: 30000,\n animType: \"syncRotation\"\n }\n },\n }\n];\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "ownership": { + "default": 0 + }, + "flags": {}, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": 1673888263584, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "folder": null, + "sort": 4400000, + "_id": "Izk5Ewj7YLcPO75x", + "_key": "!macros!Izk5Ewj7YLcPO75x" +} diff --git a/src/packs/_source/tmMacros/45-star-mask-spritemask.json b/src/packs/_source/tmMacros/45-star-mask-spritemask.json new file mode 100644 index 0000000..dd4ad59 --- /dev/null +++ b/src/packs/_source/tmMacros/45-star-mask-spritemask.json @@ -0,0 +1,24 @@ +{ + "name": "45 - Star Mask (spriteMask)", + "type": "script", + "scope": "global", + "author": "cDfy4cFieNjb5vsL", + "img": "modules/tokenmagic/gui/macros/images/45%20-%20Star%20Mask%20(spriteMask).webp", + "command": "let params = [\n {\n \"filterType\": \"spriteMask\",\n \"filterId\": \"starMask\",\n \"imagePath\": \"modules/tokenmagic/fx/assets/star.webp\",\n \"repeat\": false,\n \"gridPadding\": 1,\n \"maintainAspectRatio\": false,\n \"maintainScale\": false,\n \"scaleX\": 1,\n \"scaleY\": 1,\n \"translationX\": 0,\n \"translationY\": 0,\n \"rotation\": 0,\n \"alpha\": 1,\n \"rank\": 10000,\n \"enabled\": true\n }\n];\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "ownership": { + "default": 0 + }, + "flags": {}, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": 1694556128271, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_id": "8Lb6g8Tm1navvZbM", + "sort": 10600000, + "_key": "!macros!8Lb6g8Tm1navvZbM" +} diff --git a/src/packs/_source/tmMacros/a-multi-filters-example.json b/src/packs/_source/tmMacros/a-multi-filters-example.json new file mode 100644 index 0000000..f2fe6c8 --- /dev/null +++ b/src/packs/_source/tmMacros/a-multi-filters-example.json @@ -0,0 +1,24 @@ +{ + "_id": "tvDGSwbeQ97HNS8v", + "name": "A - Multi-Filters Example", + "type": "script", + "author": "Njc5YzFjZDI5NjZl", + "img": "modules/tokenmagic/gui/macros/images/A%20-%20Multi-Filters%20Example.webp", + "scope": "global", + "command": "let params =\n[{\n filterType: \"fog\",\n color: 0x00FF50,\n density: 0.20,\n time: 0,\n animated :\n {\n time : \n { \n active: true, \n speed: 1.2, \n animType: \"move\" \n }\n }\n},\n{\n filterType: \"ray\",\n time: 0,\n color: 0x00DE50,\n alpha: 0.25,\n divisor: 32,\n anchorY: 0,\n animated :\n {\n time : \n { \n active: true, \n speed: 0.0005, \n animType: \"move\" \n }\n }\n},\n{\n filterType: \"glow\",\n distance: 10,\n outerStrength: 8,\n innerStrength: 0,\n color: 0x003000,\n quality: 0.5,\n padding: 10,\n animated:\n {\n color: \n {\n active: true, \n loopDuration: 3000, \n animType: \"colorOscillation\", \n val1:0x003000, \n val2:0x00EF00\n }\n }\n}\n];\n\nawait TokenMagic.addFiltersOnSelected(params);", + "folder": null, + "sort": 10700000, + "flags": {}, + "ownership": { + "default": 0 + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!tvDGSwbeQ97HNS8v" +} diff --git a/src/packs/_source/tmMacros/b-multi-filters-example.json b/src/packs/_source/tmMacros/b-multi-filters-example.json new file mode 100644 index 0000000..1aff8b2 --- /dev/null +++ b/src/packs/_source/tmMacros/b-multi-filters-example.json @@ -0,0 +1,24 @@ +{ + "_id": "eJnsq5g4Pldh8Z6Q", + "name": "B - Multi-Filters Example", + "type": "script", + "author": "Njc5YzFjZDI5NjZl", + "img": "modules/tokenmagic/gui/macros/images/B%20-%20Multi-Filters%20Example.webp", + "scope": "global", + "command": "let params =\n[{\n filterType: \"distortion\",\n maskPath: \"modules/tokenmagic/fx/assets/waves-2.png\",\n maskSpriteScaleX: 7,\n maskSpriteScaleY: 7,\n padding: 50,\n animated:\n {\n maskSpriteX: { active: true, speed: 0.05, animType: \"move\" },\n maskSpriteY: { active: true, speed: 0.07, animType: \"move\" }\n }\n},\n{\n filterType: \"ray\",\n time: 0,\n color: 0xEF9000,\n alpha: 0.25,\n divisor: 32,\n anchorY: 1,\n animated :\n {\n time : \n { \n active: true, \n speed: 0.0005, \n animType: \"move\" \n }\n }\n},\n{\n filterType: \"glow\",\n distance: 10,\n outerStrength: 8,\n innerStrength: 0,\n color: 0xB03000,\n quality: 0.5,\n animated:\n {\n color: \n {\n active: true, \n loopDuration: 3000, \n animType: \"colorOscillation\", \n val1:0xB03000, \n val2:0xFFD010\n }\n }\n}\n];\n\nawait TokenMagic.addFiltersOnSelected(params);", + "folder": null, + "sort": 8100000, + "flags": {}, + "ownership": { + "default": 0 + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!eJnsq5g4Pldh8Z6Q" +} diff --git a/src/packs/_source/tmMacros/c-electric-multi-filters.json b/src/packs/_source/tmMacros/c-electric-multi-filters.json new file mode 100644 index 0000000..334b22d --- /dev/null +++ b/src/packs/_source/tmMacros/c-electric-multi-filters.json @@ -0,0 +1,24 @@ +{ + "_id": "Ia0tPcllVQq96yXF", + "name": "C - Electric Multi-Filters", + "type": "script", + "author": "Njc5YzFjZDI5NjZl", + "img": "modules/tokenmagic/gui/macros/images/C%20-%20Electric%20Multi-Filters.webp", + "scope": "global", + "command": "// works better with tokens or tiles with no shadows\nlet params =\n[{\n filterType: \"shadow\",\n blur: 2,\n quality: 5,\n distance: 0,\n alpha: 1.,\n padding: 100,\n color: 0xFFFFFF,\n animated:\n {\n blur: \n { \n active: true, \n loopDuration: 500, \n animType: \"syncCosOscillation\", \n val1: 2, \n val2: 4\n },\n }\n},\n{\n filterType: \"electric\",\n color: 0xFFFFFF,\n time: 0,\n blend: 2,\n intensity: 5,\n animated :\n {\n time : \n { \n active: true, \n speed: 0.0020, \n animType: \"move\" \n }\n }\n}];\n\nawait TokenMagic.addFiltersOnSelected(params);", + "folder": null, + "sort": 4200000, + "flags": {}, + "ownership": { + "default": 0 + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!Ia0tPcllVQq96yXF" +} diff --git a/src/packs/_source/tmMacros/d-auto-destroy-example.json b/src/packs/_source/tmMacros/d-auto-destroy-example.json new file mode 100644 index 0000000..274a646 --- /dev/null +++ b/src/packs/_source/tmMacros/d-auto-destroy-example.json @@ -0,0 +1,24 @@ +{ + "_id": "HjzhkTFUng8sxWkH", + "name": "D - Auto-Destroy Example", + "type": "script", + "author": "Njc5YzFjZDI5NjZl", + "img": "modules/tokenmagic/gui/macros/images/D%20-%20Auto-Destroy%20Example.webp", + "scope": "global", + "command": "let params = \n[{\n filterType: \"bevel\",\n autoDestroy: true,\n rotation: 0,\n thickness: 5,\n lightColor: 0x00FF00,\n lightAlpha: 0.7,\n shadowColor: 0xFF0000,\n shadowAlpha: 0.4,\n animated :\n {\n rotation: \n { \n active: true,\n clockWise: true, \n loopDuration: 1000,\n loops: 5,\n animType: \"rotation\"\n }\n }\n}];\n\nawait TokenMagic.addFiltersOnSelected(params);", + "folder": null, + "sort": 3900000, + "flags": {}, + "ownership": { + "default": 0 + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!HjzhkTFUng8sxWkH" +} diff --git a/src/packs/_source/tmMacros/e-click-click-click-and-click.json b/src/packs/_source/tmMacros/e-click-click-click-and-click.json new file mode 100644 index 0000000..e9d2bc9 --- /dev/null +++ b/src/packs/_source/tmMacros/e-click-click-click-and-click.json @@ -0,0 +1,24 @@ +{ + "_id": "BGz9j7xPy0H2QlBf", + "name": "E - Click, click, click and click !", + "type": "script", + "author": "Njc5YzFjZDI5NjZl", + "img": "modules/tokenmagic/gui/macros/images/E%20-%20Click%2C%20click%2C%20click%20and%20click%20%21.webp", + "scope": "global", + "command": "let glowFunc = async function() {\n\n const myTokens = canvas.tokens.placeables;\n\n for (const myToken of myTokens ){\n if (myToken.TMFXhasFilterId(\"funnyAlternateGlow\")) {\n await myToken.TMFXdeleteFilters(\"funnyAlternateGlow\");\n } else {\n let params =\n [{\n filterType: \"glow\",\n filterId: \"funnyAlternateGlow\",\n color: Math.floor(Math.random() * 16777215),\n animated: null\n }];\n await myToken.TMFXaddUpdateFilters(params);\n }\n }\n};\n\nglowFunc();", + "folder": null, + "sort": 2000000, + "flags": {}, + "ownership": { + "default": 0 + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!BGz9j7xPy0H2QlBf" +} diff --git a/src/packs/_source/tmMacros/f-03-export-fx-presets.json b/src/packs/_source/tmMacros/f-03-export-fx-presets.json new file mode 100644 index 0000000..d8c0189 --- /dev/null +++ b/src/packs/_source/tmMacros/f-03-export-fx-presets.json @@ -0,0 +1,24 @@ +{ + "_id": "Ku4jBl972O7hHczs", + "name": "F - 03 - Export FX Presets", + "type": "script", + "flags": {}, + "scope": "global", + "command": "TokenMagic.exportPresetLibrary();", + "author": "Njc5YzFjZDI5NjZl", + "img": "icons/svg/dice-target.svg", + "ownership": { + "default": 0 + }, + "folder": null, + "sort": 4600000, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!Ku4jBl972O7hHczs" +} diff --git a/src/packs/_source/tmMacros/f-04-import-fx-presets-local.json b/src/packs/_source/tmMacros/f-04-import-fx-presets-local.json new file mode 100644 index 0000000..e9e0666 --- /dev/null +++ b/src/packs/_source/tmMacros/f-04-import-fx-presets-local.json @@ -0,0 +1,24 @@ +{ + "_id": "QzFJd7hkaYesE7Ud", + "name": "F - 04 - Import FX Presets (local)", + "type": "script", + "flags": {}, + "scope": "global", + "command": "// Open the console (F12) to check the state of the import\r\n// You can configure in the module option panel the \"overwrite mode on import\"\r\n\r\nTokenMagic.importPresetLibrary();", + "author": "Njc5YzFjZDI5NjZl", + "img": "icons/svg/dice-target.svg", + "ownership": { + "default": 0 + }, + "folder": null, + "sort": 5200000, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!QzFJd7hkaYesE7Ud" +} diff --git a/src/packs/_source/tmMacros/f-05-import-fx-presets-url.json b/src/packs/_source/tmMacros/f-05-import-fx-presets-url.json new file mode 100644 index 0000000..9eeb5f0 --- /dev/null +++ b/src/packs/_source/tmMacros/f-05-import-fx-presets-url.json @@ -0,0 +1,24 @@ +{ + "_id": "sZmVZvLEYmlEC1bK", + "name": "F - 05 - Import FX Presets (URL)", + "type": "script", + "flags": {}, + "scope": "global", + "command": "// Replace the dummy url with a valid url that points to a Token Magic FX presets file (json)\r\n// Open the console (F12) to check the state of the import\r\n// You can configure in the module option panel the \"overwrite mode on import\"\r\n\r\n// TokenMagic.importPresetLibraryFromURL(\"https://presets-to-import-url\");\r\n\r\nui.notifications.warn(\"Open this macro and read the instructions.\");", + "author": "Njc5YzFjZDI5NjZl", + "img": "icons/svg/dice-target.svg", + "ownership": { + "default": 0 + }, + "folder": null, + "sort": 10100000, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!sZmVZvLEYmlEC1bK" +} diff --git a/src/packs/_source/tmMacros/f-06-export-template-settings.json b/src/packs/_source/tmMacros/f-06-export-template-settings.json new file mode 100644 index 0000000..bbe5212 --- /dev/null +++ b/src/packs/_source/tmMacros/f-06-export-template-settings.json @@ -0,0 +1,24 @@ +{ + "name": "F - 06 - Export Template Settings", + "type": "script", + "author": "jkj278HJluWLWiGt", + "img": "icons/svg/dice-target.svg", + "scope": "global", + "command": "TokenMagic.exportTemplateSettings();", + "folder": null, + "sort": 9200000, + "flags": {}, + "_id": "jMhvaRGK3hAufND8", + "ownership": { + "default": 0 + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!jMhvaRGK3hAufND8" +} diff --git a/src/packs/_source/tmMacros/f-07-import-template-settings-local.json b/src/packs/_source/tmMacros/f-07-import-template-settings-local.json new file mode 100644 index 0000000..d7ea33d --- /dev/null +++ b/src/packs/_source/tmMacros/f-07-import-template-settings-local.json @@ -0,0 +1,24 @@ +{ + "name": "F - 07 - Import Template Settings (local)", + "type": "script", + "author": "jkj278HJluWLWiGt", + "img": "icons/svg/dice-target.svg", + "scope": "global", + "command": "// Open the console (F12) to check the state of the import\n\nTokenMagic.importTemplateSettings();", + "folder": null, + "sort": 11300000, + "flags": {}, + "_id": "xlBIisESJPU1nSxw", + "ownership": { + "default": 0 + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": null, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "_key": "!macros!xlBIisESJPU1nSxw" +} diff --git a/src/packs/_source/tmMacros/g-randomization-example.json b/src/packs/_source/tmMacros/g-randomization-example.json new file mode 100644 index 0000000..5998634 --- /dev/null +++ b/src/packs/_source/tmMacros/g-randomization-example.json @@ -0,0 +1,29 @@ +{ + "name": "G - Randomization Example", + "type": "script", + "author": "UTH9wXZFkTza6igr", + "img": "modules/tokenmagic/gui/macros/images/G%20-%20Randomization%20Example.webp", + "scope": "global", + "command": "// This sprite filter contains randomized 'imagePath', 'scaleX', 'scaleY', 'rotation' and 'alpha' parameters.\n// - 'imagePath' sources a random path from the provided array\n// - The rest of params will generate a random value using ranges:\n// - 'val1' and 'val2' define the range for the randomized value\n// - 'step' defines the increment, step of 0.1 for example with range 0 to 1 would produce 0.1, 0.4, 0.2, 0.9, etc. \n// while a step of 10 with a range of 50 to 400 would produce 70, 50, 340, 200, etc.\n// - 'link' provides a way to set another parameter to the same randomized value, which is useful when for example setting scale which consists of two components x and y\n\nlet params = [\n {\n filterType: \"sprite\",\n filterId: \"randomOverlay\",\n repeat: true,\n alphaDiscard: true,\n inverse: true,\n gridPadding: 1,\n translationX: 0,\n translationY: 0,\n top: true,\n randomized: {\n imagePath: [\n \"modules/tokenmagic/fx/assets/distortion-1.png\",\n \"modules/tokenmagic/fx/assets/dots-1.png\",\n \"modules/tokenmagic/fx/assets/extrusion-1.png\",\n \"modules/tokenmagic/fx/assets/noise-2.jpg\",\n \"modules/tokenmagic/fx/assets/symbols-1.png\",\n \"modules/tokenmagic/fx/assets/waves-1.png\",\n ],\n scaleX: { val1: 0.1, val2: 0.6, step: 0.01, link: 'scaleY' },\n rotation: { val1: 0, val2: 360, step: 1 },\n alpha: { val1: 0.5, val2: 1.0, step: 0.1 }\n },\n }\n];\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "ownership": { + "default": 0 + }, + "flags": { + "scene-packer": { + "hash": "8e77b72fb122ec185881742084f1a3ebf7ee7ed7", + "sourceId": "Macro.oiRoT64pfS1mVnXH" + } + }, + "_stats": { + "systemId": "dnd5e", + "systemVersion": "2.3.1", + "coreVersion": "11.308", + "createdTime": 1676649619562, + "modifiedTime": 1695296911423, + "lastModifiedBy": "packsbuilder0000" + }, + "folder": null, + "sort": 800000, + "_id": "4aMgnzj0WHUx054m", + "_key": "!macros!4aMgnzj0WHUx054m" +} diff --git a/src/packs/_source/tmSampleCompendium/19-t01-fire.json b/src/packs/_source/tmSampleCompendium/19-t01-fire.json new file mode 100644 index 0000000..de516d8 --- /dev/null +++ b/src/packs/_source/tmSampleCompendium/19-t01-fire.json @@ -0,0 +1,17 @@ +{ + "_id": "EdOz5OYVcgHEhraW", + "name": "19 - T01 - Fire", + "type": "script", + "author": "f8mJy0XxrFT8Pzt3", + "img": "modules/tokenmagic/gui/macros/images/19%20-%20T01%20-%20Fire.webp", + "scope": "global", + "command": "let params =\n[{\n filterType: \"fire\",\n filterId: \"myFire\",\n intensity: 1,\n color: 0xFFFFFF,\n amplitude: 1,\n time: 0,\n blend: 2,\n fireBlend : 1,\n animated :\n {\n time : \n { \n active: true, \n speed: -0.0024, \n animType: \"move\" \n },\n intensity:\n {\n active:true,\n loopDuration: 15000,\n val1: 0.8,\n val2: 2,\n animType: \"syncCosOscillation\"\n },\n amplitude:\n {\n active:true,\n loopDuration: 4400,\n val1: 1,\n val2: 1.4,\n animType: \"syncCosOscillation\"\n }\n \n }\n}];\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 0, + "permission": { + "default": 0, + "f8mJy0XxrFT8Pzt3": 3 + }, + "flags": {}, + "_key": "!macros!EdOz5OYVcgHEhraW" +} diff --git a/src/packs/_source/tmSampleCompendium/19-t02-devouring-fire.json b/src/packs/_source/tmSampleCompendium/19-t02-devouring-fire.json new file mode 100644 index 0000000..820a9bb --- /dev/null +++ b/src/packs/_source/tmSampleCompendium/19-t02-devouring-fire.json @@ -0,0 +1,17 @@ +{ + "_id": "c5S9Ew0kvgMZU0Bg", + "name": "19 - T02 - Devouring Fire", + "type": "script", + "author": "f8mJy0XxrFT8Pzt3", + "img": "modules/tokenmagic/gui/macros/images/19%20-%20T02%20-%20Devouring%20Fire.webp", + "scope": "global", + "command": "let params =\n[{\n filterType: \"fire\",\n filterId: \"myFire\",\n intensity: 3,\n color: 0xFFFFFF,\n amplitude: 2,\n time: 0,\n blend: 10,\n fireBlend : 1,\n alphaDiscard: true,\n zOrder: 50,\n animated :\n {\n time : \n { \n active: true, \n speed: -0.0024, \n animType: \"move\" \n }\n }\n},{\n filterType: \"glow\",\n filterId: \"glowripples\",\n outerStrength: 4,\n innerStrength: 2,\n color: 0xAA6500,\n quality: 0.5,\n padding: 10,\n zOrder: 100,\n}];\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 0, + "permission": { + "default": 0, + "f8mJy0XxrFT8Pzt3": 3 + }, + "flags": {}, + "_key": "!macros!c5S9Ew0kvgMZU0Bg" +} diff --git a/src/packs/_source/tmSampleCompendium/24-t02-fire-shield-2.json b/src/packs/_source/tmSampleCompendium/24-t02-fire-shield-2.json new file mode 100644 index 0000000..47b3523 --- /dev/null +++ b/src/packs/_source/tmSampleCompendium/24-t02-fire-shield-2.json @@ -0,0 +1,17 @@ +{ + "_id": "nij9Xlo2wbJWM5fV", + "name": "24 - T02 - Fire Shield 2", + "type": "script", + "author": "f8mJy0XxrFT8Pzt3", + "img": "modules/tokenmagic/gui/macros/images/24%20-%20T02%20-%20Fire%20Shield%202.webp", + "scope": "global", + "command": "let params =\n[{\n filterType: \"field\",\n filterId: \"myFireField\",\n shieldType: 1,\n gridPadding: 2,\n color: 0xE58550,\n time: 0,\n blend: 2,\n intensity: 1.2,\n lightAlpha: 1,\n lightSize: 0.7,\n scale: 1,\n radius: 1,\n chromatic: false,\n discardThreshold: 0.5,\n alphaDiscard: true,\n animated :\n {\n time : \n { \n active: true, \n speed: 0.0015, \n animType: \"move\" \n }\n }\n}];\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 0, + "permission": { + "default": 0, + "f8mJy0XxrFT8Pzt3": 3 + }, + "flags": {}, + "_key": "!macros!nij9Xlo2wbJWM5fV" +} diff --git a/src/packs/_source/tmSampleCompendium/24-t02-fire-shield-3-ring.json b/src/packs/_source/tmSampleCompendium/24-t02-fire-shield-3-ring.json new file mode 100644 index 0000000..3a20130 --- /dev/null +++ b/src/packs/_source/tmSampleCompendium/24-t02-fire-shield-3-ring.json @@ -0,0 +1,17 @@ +{ + "_id": "Wu2N6ToVJUKVKTvj", + "name": "24 - T02 - Fire Shield 3 - Ring", + "type": "script", + "author": "f8mJy0XxrFT8Pzt3", + "img": "modules/tokenmagic/gui/macros/images/24%20-%20T02%20-%20Fire%20Shield%203%20-%20Ring.webp", + "scope": "global", + "command": "let params =\n[{\n filterType: \"zapshadow\",\n filterId: \"myZap\",\n alphaTolerance: 0.45\n},{\n filterType: \"field\",\n filterId: \"myFireField\",\n shieldType: 1,\n gridPadding: 1.1,\n color: 0xE58550,\n time: 0,\n blend: 2,\n intensity: 1.2,\n lightAlpha: 1,\n lightSize: 0.7,\n scale: 1,\n radius: 1,\n chromatic: false,\n discardThreshold: 0.9,\n hideRadius: 0.95,\n alphaDiscard: true,\n animated :\n {\n time : \n { \n active: true, \n speed: 0.0015, \n animType: \"move\" \n }\n }\n},{\n filterType: \"xglow\",\n filterId: \"myBurningAura\",\n auraType: 2,\n color: 0x903010,\n thickness: 9.8,\n scale: 4.,\n time: 0,\n auraIntensity: 2,\n subAuraIntensity: 1.5,\n threshold: 0.40,\n discard: true,\n zOrder: 3000,\n animated:\n {\n time : \n { \n active: true,\n speed: 0.0027, \n animType: \"move\" \n },\n thickness:\n {\n active: true,\n loopDuration: 3000, \n animType: \"cosOscillation\", \n val1:2, \n val2:5\n }\n }\n}];\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 0, + "permission": { + "default": 0, + "f8mJy0XxrFT8Pzt3": 3 + }, + "flags": {}, + "_key": "!macros!Wu2N6ToVJUKVKTvj" +} diff --git a/src/packs/_source/tmSampleCompendium/24-t02-fire-shield-4-lava-zone.json b/src/packs/_source/tmSampleCompendium/24-t02-fire-shield-4-lava-zone.json new file mode 100644 index 0000000..1c071f7 --- /dev/null +++ b/src/packs/_source/tmSampleCompendium/24-t02-fire-shield-4-lava-zone.json @@ -0,0 +1,17 @@ +{ + "_id": "Nnty2Oba51s6pLYd", + "name": "24 - T02 - Fire Shield 4 - Lava Zone", + "type": "script", + "author": "f8mJy0XxrFT8Pzt3", + "img": "modules/tokenmagic/gui/macros/images/24%20-%20T02%20-%20Fire%20Shield%204%20-%20Lava%20Zone.webp", + "scope": "global", + "command": "let params =\n[{\n filterType: \"zapshadow\",\n filterId: \"myZap\",\n alphaTolerance: 0.45\n},{\n filterType: \"field\",\n filterId: \"myLavaRing\",\n shieldType: 6,\n gridPadding: 1.25,\n color: 0xFFAA00,\n time: 0,\n blend: 14,\n intensity: 1,\n lightAlpha: 0,\n lightSize: 0.7,\n scale: 1,\n radius: 1,\n chromatic: false,\n discardThreshold: 0.30,\n hideRadius: 0.95,\n alphaDiscard: true,\n animated :\n {\n time : \n { \n active: true, \n speed: 0.0015, \n animType: \"move\" \n },\n radius: \n {\n active: true, \n loopDuration: 6000, \n animType: \"cosOscillation\", \n val1:1, \n val2:0.8\n },\n hideRadius: \n {\n active: true, \n loopDuration: 3000, \n animType: \"cosOscillation\", \n val1:0.75, \n val2:0.4\n }\n }\n},{\n filterType: \"xglow\",\n filterId: \"myBurningAura\",\n auraType: 2,\n color: 0xFF5000,\n thickness: 9.8,\n scale: 1.,\n time: 0,\n auraIntensity: 2,\n subAuraIntensity: 1,\n threshold: 0.30,\n discard: true,\n zOrder: 3000,\n animated:\n {\n time : \n { \n active: true,\n speed: 0.0027, \n animType: \"move\" \n },\n thickness:\n {\n active: true,\n loopDuration: 600, \n animType: \"cosOscillation\", \n val1:4, \n val2:8\n }\n }\n}];\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 0, + "permission": { + "default": 0, + "f8mJy0XxrFT8Pzt3": 3 + }, + "flags": {}, + "_key": "!macros!Nnty2Oba51s6pLYd" +} diff --git a/src/packs/_source/tmSampleCompendium/24-t02-fire-shield.json b/src/packs/_source/tmSampleCompendium/24-t02-fire-shield.json new file mode 100644 index 0000000..63fde1d --- /dev/null +++ b/src/packs/_source/tmSampleCompendium/24-t02-fire-shield.json @@ -0,0 +1,17 @@ +{ + "_id": "WcwNyVbYeHm24XgI", + "name": "24 - T02 - Fire Shield", + "type": "script", + "author": "f8mJy0XxrFT8Pzt3", + "img": "modules/tokenmagic/gui/macros/images/24%20-%20T02%20-%20Fire%20Shield.webp", + "scope": "global", + "command": "let params =\n[{\n filterType: \"field\",\n filterId: \"myFireField\",\n shieldType: 1,\n gridPadding: 2,\n color: 0xE58550,\n time: 0,\n blend: 2,\n intensity: 1.2,\n lightAlpha: 1,\n lightSize: 0.7,\n scale: 1,\n radius: 1,\n chromatic: false,\n zOrder: 512,\n animated :\n {\n time : \n { \n active: true, \n speed: 0.0015, \n animType: \"move\" \n }\n }\n}];\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 0, + "permission": { + "default": 0, + "f8mJy0XxrFT8Pzt3": 3 + }, + "flags": {}, + "_key": "!macros!WcwNyVbYeHm24XgI" +} diff --git a/src/packs/_source/tmSampleCompendium/27-t01-burning-aura-xglow.json b/src/packs/_source/tmSampleCompendium/27-t01-burning-aura-xglow.json new file mode 100644 index 0000000..da4343a --- /dev/null +++ b/src/packs/_source/tmSampleCompendium/27-t01-burning-aura-xglow.json @@ -0,0 +1,17 @@ +{ + "_id": "ygP4EwZGwIChqLwG", + "name": "27 - T01 - Burning Aura (xglow)", + "type": "script", + "author": "f8mJy0XxrFT8Pzt3", + "img": "modules/tokenmagic/gui/macros/images/27%20-%20T01%20-%20Burning%20Aura%20%28xglow%29.webp", + "scope": "global", + "command": "let params =\n[{\n filterType: \"zapshadow\",\n filterId: \"myZapShadow\",\n alphaTolerance: 0.50\n},\n{\n filterType: \"xglow\",\n filterId: \"myBurningAura\",\n auraType: 2,\n color: 0x903010,\n thickness: 9.8,\n scale: 4.,\n time: 0,\n auraIntensity: 2,\n subAuraIntensity: 1.5,\n threshold: 0.40,\n discard: true,\n animated:\n {\n time : \n { \n active: true,\n speed: 0.0027, \n animType: \"move\" \n },\n thickness:\n {\n active: true,\n loopDuration: 3000, \n animType: \"cosOscillation\", \n val1:2, \n val2:5\n }\n }\n}];\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 0, + "permission": { + "default": 0, + "f8mJy0XxrFT8Pzt3": 3 + }, + "flags": {}, + "_key": "!macros!ygP4EwZGwIChqLwG" +} diff --git a/src/packs/_source/tmSampleCompendium/27-t04-pure-fire-xglow-fire.json b/src/packs/_source/tmSampleCompendium/27-t04-pure-fire-xglow-fire.json new file mode 100644 index 0000000..76d8dd6 --- /dev/null +++ b/src/packs/_source/tmSampleCompendium/27-t04-pure-fire-xglow-fire.json @@ -0,0 +1,21 @@ +{ + "_id": "AvE297PJ7nRJiyb9", + "name": "27 - T04 - Pure Fire (xglow+fire)", + "type": "script", + "author": "f8mJy0XxrFT8Pzt3", + "img": "modules/tokenmagic/gui/macros/images/27%20-%20T04%20-%20Pure%20Fire%20%28xglow%2Bfire%29.webp", + "scope": "global", + "command": "let params =\n[{\n filterType: \"fire\",\n filterId: \"myPureFire\",\n intensity: 1,\n color: 0xFFFFFF,\n amplitude: 1,\n time: 0,\n blend: 2,\n fireBlend : 1,\n animated :\n {\n time : \n { \n active: true, \n speed: -0.0024, \n animType: \"move\" \n },\n intensity:\n {\n active:true,\n loopDuration: 15000,\n val1: 0.8,\n val2: 2,\n animType: \"syncCosOscillation\"\n },\n amplitude:\n {\n active:true,\n loopDuration: 4400,\n val1: 1,\n val2: 1.4,\n animType: \"syncCosOscillation\"\n }\n \n }\n},\n{\n filterType: \"zapshadow\",\n filterId: \"myPureFireShadow\",\n alphaTolerance: 0.50\n},\n{\n filterType: \"xglow\",\n filterId: \"myPureFireAura\",\n auraType: 2,\n color: 0x903010,\n thickness: 9.8,\n scale: 4.,\n time: 0,\n auraIntensity: 2,\n subAuraIntensity: 1.5,\n threshold: 0.40,\n discard: true,\n animated:\n {\n time : \n { \n active: true,\n speed: 0.0027, \n animType: \"move\" \n },\n thickness:\n {\n active: true,\n loopDuration: 3000, \n animType: \"cosOscillation\", \n val1:2, \n val2:5\n }\n }\n}];\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 0, + "permission": { + "default": 0, + "f8mJy0XxrFT8Pzt3": 3 + }, + "flags": { + "furnace": { + "runAsGM": false + } + }, + "_key": "!macros!AvE297PJ7nRJiyb9" +} diff --git a/src/packs/_source/tmSampleCompendium/27-t05-pure-fire-v2-xglow-fire.json b/src/packs/_source/tmSampleCompendium/27-t05-pure-fire-v2-xglow-fire.json new file mode 100644 index 0000000..6cfd6ed --- /dev/null +++ b/src/packs/_source/tmSampleCompendium/27-t05-pure-fire-v2-xglow-fire.json @@ -0,0 +1,17 @@ +{ + "_id": "uFJIpXbBGRl1NY83", + "name": "27 - T05 - Pure Fire v2 (xglow+fire)", + "type": "script", + "author": "f8mJy0XxrFT8Pzt3", + "img": "modules/tokenmagic/gui/macros/images/27%20-%20T05%20-%20Pure%20Fire%20v2%20%28xglow%2Bfire%29.webp", + "scope": "global", + "command": "// In this version, the glow is blending with the fire\n// This is to show that the order of the filters is important\nlet params =\n[{\n filterType: \"zapshadow\",\n filterId: \"myPureFireShadow\",\n alphaTolerance: 0.50\n},\n{\n filterType: \"xglow\",\n filterId: \"myPureFireAura\",\n auraType: 2,\n color: 0x903010,\n thickness: 9.8,\n scale: 3.,\n time: 0,\n auraIntensity: 1,\n subAuraIntensity: 0.3,\n threshold: 0.25,\n discard: true,\n animated:\n {\n time : \n { \n active: true,\n speed: 0.0027, \n animType: \"move\" \n },\n thickness:\n {\n active: true,\n loopDuration: 3000, \n animType: \"cosOscillation\", \n val1:2, \n val2:3.6\n }\n }\n},\n{\n filterType: \"fire\",\n filterId: \"myPureFire\",\n intensity: 1,\n color: 0xFFFFFF,\n amplitude: 1,\n time: 0,\n blend: 2,\n fireBlend : 1,\n animated :\n {\n time : \n { \n active: true, \n speed: -0.0024, \n animType: \"move\" \n },\n intensity:\n {\n active:true,\n loopDuration: 15000,\n val1: 0.8,\n val2: 3,\n animType: \"syncCosOscillation\"\n },\n amplitude:\n {\n active:true,\n loopDuration: 4400,\n val1: 1,\n val2: 1.6,\n animType: \"syncCosOscillation\"\n }\n \n }\n}];\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 0, + "permission": { + "default": 0, + "f8mJy0XxrFT8Pzt3": 3 + }, + "flags": {}, + "_key": "!macros!uFJIpXbBGRl1NY83" +} diff --git a/src/packs/_source/tmSampleCompendium/32-t01-solar-ripples-ripples.json b/src/packs/_source/tmSampleCompendium/32-t01-solar-ripples-ripples.json new file mode 100644 index 0000000..9a88400 --- /dev/null +++ b/src/packs/_source/tmSampleCompendium/32-t01-solar-ripples-ripples.json @@ -0,0 +1,17 @@ +{ + "_id": "A1qb9Vho5PFpPwOr", + "name": "32 - T01 - Solar Ripples (ripples)", + "type": "script", + "author": "f8mJy0XxrFT8Pzt3", + "img": "modules/tokenmagic/gui/macros/images/32%20-%20T01%20-%20Solar%20Ripples%20%28ripples%29.webp", + "scope": "global", + "command": "let params = \n[{\n filterType: \"ripples\",\n filterId: \"SolarRipples\",\n color: 0xCC9000,\n time: 0,\n alphaDiscard: false,\n animated :\n {\n time : \n { \n active: true, \n speed: 0.0009, \n animType: \"move\" \n }\n }\n}]\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 0, + "permission": { + "default": 0, + "f8mJy0XxrFT8Pzt3": 3 + }, + "flags": {}, + "_key": "!macros!A1qb9Vho5PFpPwOr" +} diff --git a/src/packs/_source/tmSampleCompendium/35-t01-fire-v2-xfire.json b/src/packs/_source/tmSampleCompendium/35-t01-fire-v2-xfire.json new file mode 100644 index 0000000..eec90dd --- /dev/null +++ b/src/packs/_source/tmSampleCompendium/35-t01-fire-v2-xfire.json @@ -0,0 +1,17 @@ +{ + "_id": "9qImMNihwv8V9Qho", + "name": "35 - T01 - Fire v2 (xfire)", + "type": "script", + "author": "f8mJy0XxrFT8Pzt3", + "img": "modules/tokenmagic/gui/macros/images/35%20-%20T01%20-%20Fire%20v2%20%28xfire%29.webp", + "scope": "global", + "command": "let params =\n[{\n filterType: \"xfire\",\n filterId: \"myFireV2XFire\",\n time: 0,\n blend: 1,\n amplitude: 1,\n dispersion: 0,\n chromatic: false,\n scaleX: 1.5,\n scaleY: 1,\n inlay: false,\n animated :\n {\n time : \n { \n active: true, \n speed: -0.0015, \n animType: \"move\" \n }\n }\n}];\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 0, + "permission": { + "default": 0, + "f8mJy0XxrFT8Pzt3": 3 + }, + "flags": {}, + "_key": "!macros!9qImMNihwv8V9Qho" +} diff --git a/src/packs/_source/tmSampleCompendium/35-t02-chromatic-fire-xfire.json b/src/packs/_source/tmSampleCompendium/35-t02-chromatic-fire-xfire.json new file mode 100644 index 0000000..cf00dc5 --- /dev/null +++ b/src/packs/_source/tmSampleCompendium/35-t02-chromatic-fire-xfire.json @@ -0,0 +1,17 @@ +{ + "_id": "rzC68R0rMzIlzKw1", + "name": "35 - T02 - Chromatic Fire (xfire)", + "type": "script", + "author": "f8mJy0XxrFT8Pzt3", + "img": "modules/tokenmagic/gui/macros/images/35%20-%20T02%20-%20Chromatic%20Fire%20%28xfire%29.webp", + "scope": "global", + "command": "let params =\n[{\n filterType: \"xfire\",\n filterId: \"myChromaticXFire\",\n time: 0,\n blend: 2,\n amplitude: 1.1,\n dispersion: 0,\n chromatic: true,\n scaleX: 1,\n scaleY: 1,\n inlay: false,\n animated :\n {\n time : \n { \n active: true, \n speed: -0.0015, \n animType: \"move\" \n }\n }\n}];\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 0, + "permission": { + "default": 0, + "f8mJy0XxrFT8Pzt3": 3 + }, + "flags": {}, + "_key": "!macros!rzC68R0rMzIlzKw1" +} diff --git a/src/packs/_source/tmSampleCompendium/35-t04-cold-fire-xfire.json b/src/packs/_source/tmSampleCompendium/35-t04-cold-fire-xfire.json new file mode 100644 index 0000000..4ddea46 --- /dev/null +++ b/src/packs/_source/tmSampleCompendium/35-t04-cold-fire-xfire.json @@ -0,0 +1,17 @@ +{ + "_id": "8aHbX9wGc5ih56Gx", + "name": "35 - T04 - Cold Fire (xfire)", + "type": "script", + "author": "f8mJy0XxrFT8Pzt3", + "img": "modules/tokenmagic/gui/macros/images/35%20-%20T04%20-%20Cold%20Fire%20%28xfire%29.webp", + "scope": "global", + "command": "let params =\n[{\n filterType: \"xfire\",\n filterId: \"myColdXFire\",\n time: 0,\n color: 0xBBDDEE,\n blend: 1,\n amplitude: 1,\n dispersion: 0,\n chromatic: false,\n scaleX: 1,\n scaleY: 1,\n inlay: false,\n animated :\n {\n time : \n { \n active: true, \n speed: -0.0015, \n animType: \"move\" \n }\n }\n}];\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 0, + "permission": { + "default": 0, + "f8mJy0XxrFT8Pzt3": 3 + }, + "flags": {}, + "_key": "!macros!8aHbX9wGc5ih56Gx" +} diff --git a/src/packs/_source/tmSampleCompendium/35-t05-black-fire-xfire.json b/src/packs/_source/tmSampleCompendium/35-t05-black-fire-xfire.json new file mode 100644 index 0000000..e0ebfde --- /dev/null +++ b/src/packs/_source/tmSampleCompendium/35-t05-black-fire-xfire.json @@ -0,0 +1,17 @@ +{ + "_id": "HsMz9DNe78RVAI9y", + "name": "35 - T05 - Black Fire (xfire)", + "type": "script", + "author": "f8mJy0XxrFT8Pzt3", + "img": "modules/tokenmagic/gui/macros/images/35%20-%20T05%20-%20Black%20Fire%20%28xfire%29.webp", + "scope": "global", + "command": "let params =\n[{\n filterType: \"xfire\",\n filterId: \"myBlackXFire\",\n time: 0,\n color: 0x707070,\n blend: 11,\n amplitude: 1,\n dispersion: 2.2,\n chromatic: false,\n scaleX: 2.5,\n scaleY: 2,\n inlay: false,\n animated :\n {\n time : \n { \n active: true, \n speed: -0.0015, \n animType: \"move\" \n }\n }\n}];\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 0, + "permission": { + "default": 0, + "f8mJy0XxrFT8Pzt3": 3 + }, + "flags": {}, + "_key": "!macros!HsMz9DNe78RVAI9y" +} diff --git a/src/packs/_source/tmSampleCompendium/35-t09-superheat-xfire.json b/src/packs/_source/tmSampleCompendium/35-t09-superheat-xfire.json new file mode 100644 index 0000000..08f8511 --- /dev/null +++ b/src/packs/_source/tmSampleCompendium/35-t09-superheat-xfire.json @@ -0,0 +1,17 @@ +{ + "_id": "bRUq2B72Idhb4uVR", + "name": "35 - T09 - SuperHeat (xfire)", + "type": "script", + "author": "f8mJy0XxrFT8Pzt3", + "img": "modules/tokenmagic/gui/macros/images/35%20-%20T09%20-%20SuperHeat%20%28xfire%29.webp", + "scope": "global", + "command": "let params =\n[{\n filterType: \"xfire\",\n filterId: \"mySuperHeat\",\n time: 0,\n blend: 5,\n amplitude: 0.25,\n dispersion: -1,\n chromatic: false,\n scaleX: 1,\n scaleY: 1,\n inlay: true,\n animated :\n {\n time : \n { \n active: true, \n speed: -0.0090, \n animType: \"move\" \n }\n }\n}];\n\nawait TokenMagic.addUpdateFiltersOnSelected(params);", + "folder": null, + "sort": 0, + "permission": { + "default": 0, + "f8mJy0XxrFT8Pzt3": 3 + }, + "flags": {}, + "_key": "!macros!bRUq2B72Idhb4uVR" +} diff --git a/tokenmagic/packs/token-magic-portfolio/000202.ldb b/src/packs/tmMacros/000202.ldb similarity index 100% rename from tokenmagic/packs/token-magic-portfolio/000202.ldb rename to src/packs/tmMacros/000202.ldb diff --git a/src/packs/tmMacros/CURRENT b/src/packs/tmMacros/CURRENT new file mode 100644 index 0000000..45d010a --- /dev/null +++ b/src/packs/tmMacros/CURRENT @@ -0,0 +1 @@ +MANIFEST-000393 diff --git a/tokenmagic/packs/token-magic-book-of-fire/LOCK b/src/packs/tmMacros/LOCK similarity index 100% rename from tokenmagic/packs/token-magic-book-of-fire/LOCK rename to src/packs/tmMacros/LOCK diff --git a/src/packs/tmMacros/LOG b/src/packs/tmMacros/LOG new file mode 100644 index 0000000..3dac3bb --- /dev/null +++ b/src/packs/tmMacros/LOG @@ -0,0 +1,3 @@ +2024/05/13-17:42:02.236 8ba0 Recovering log #392 +2024/05/13-17:42:02.241 8ba0 Delete type=0 #392 +2024/05/13-17:42:02.241 8ba0 Delete type=3 #391 diff --git a/src/packs/tmMacros/LOG.old b/src/packs/tmMacros/LOG.old new file mode 100644 index 0000000..8878027 --- /dev/null +++ b/src/packs/tmMacros/LOG.old @@ -0,0 +1,3 @@ +2024/05/13-17:42:02.221 8ba0 Recovering log #389 +2024/05/13-17:42:02.226 8ba0 Delete type=0 #389 +2024/05/13-17:42:02.226 8ba0 Delete type=3 #387 diff --git a/tokenmagic/packs/token-magic-portfolio/MANIFEST-000387 b/src/packs/tmMacros/MANIFEST-000393 similarity index 71% rename from tokenmagic/packs/token-magic-portfolio/MANIFEST-000387 rename to src/packs/tmMacros/MANIFEST-000393 index ad178b1..8ce7a29 100644 Binary files a/tokenmagic/packs/token-magic-portfolio/MANIFEST-000387 and b/src/packs/tmMacros/MANIFEST-000393 differ diff --git a/tokenmagic/packs/token-magic-book-of-fire/000017.ldb b/src/packs/tmSampleCompendium/000017.ldb similarity index 100% rename from tokenmagic/packs/token-magic-book-of-fire/000017.ldb rename to src/packs/tmSampleCompendium/000017.ldb diff --git a/src/packs/tmSampleCompendium/CURRENT b/src/packs/tmSampleCompendium/CURRENT new file mode 100644 index 0000000..d8c433b --- /dev/null +++ b/src/packs/tmSampleCompendium/CURRENT @@ -0,0 +1 @@ +MANIFEST-000390 diff --git a/tokenmagic/packs/token-magic-portfolio/LOCK b/src/packs/tmSampleCompendium/LOCK similarity index 100% rename from tokenmagic/packs/token-magic-portfolio/LOCK rename to src/packs/tmSampleCompendium/LOCK diff --git a/src/packs/tmSampleCompendium/LOG b/src/packs/tmSampleCompendium/LOG new file mode 100644 index 0000000..b5ca90b --- /dev/null +++ b/src/packs/tmSampleCompendium/LOG @@ -0,0 +1,3 @@ +2024/05/13-17:42:02.391 8ba0 Recovering log #389 +2024/05/13-17:42:02.395 8ba0 Delete type=0 #389 +2024/05/13-17:42:02.395 8ba0 Delete type=3 #388 diff --git a/src/packs/tmSampleCompendium/LOG.old b/src/packs/tmSampleCompendium/LOG.old new file mode 100644 index 0000000..088f85c --- /dev/null +++ b/src/packs/tmSampleCompendium/LOG.old @@ -0,0 +1,3 @@ +2024/05/13-17:42:02.381 8ba0 Recovering log #386 +2024/05/13-17:42:02.386 8ba0 Delete type=0 #386 +2024/05/13-17:42:02.386 8ba0 Delete type=3 #384 diff --git a/tokenmagic/packs/token-magic-book-of-fire/MANIFEST-000384 b/src/packs/tmSampleCompendium/MANIFEST-000390 similarity index 73% rename from tokenmagic/packs/token-magic-book-of-fire/MANIFEST-000384 rename to src/packs/tmSampleCompendium/MANIFEST-000390 index bf28e9a..b79aa14 100644 Binary files a/tokenmagic/packs/token-magic-book-of-fire/MANIFEST-000384 and b/src/packs/tmSampleCompendium/MANIFEST-000390 differ diff --git a/src/scripts/autoTemplate/TheWitcherTRPG.js b/src/scripts/autoTemplate/TheWitcherTRPG.js new file mode 100644 index 0000000..216f675 --- /dev/null +++ b/src/scripts/autoTemplate/TheWitcherTRPG.js @@ -0,0 +1,151 @@ +import { defaultOpacity, emptyPreset } from "../constants.js"; + +export class AutoTemplateTheWitcherTRPG { + static get defaultConfiguration() { + const defaultConfig = { + categories: {}, + overrides: { + 0: { + target: "Игни", + opacity: 0.5, + tint: "#00a80b", + preset: "Flames", + texture: null, + }, + }, + }; + + Object.keys(CONFIG.witcher.meleeSkills).forEach((meleeSkillType) => { + if (defaultConfig.categories[meleeSkillType] == undefined) { + const config = { opacity: defaultOpacity, tint: null }; + switch (meleeSkillType.toLowerCase()) { + case "brawling": + config.tint = "#2d8000"; + config.opacity = 0.6; + break; + case "melee": + config.tint = "#47b3ff"; + break; + case "small blades": + config.tint = "#502673"; + break; + case "staff/spear": + config.tint = "#00a80b"; + break; + case "swordsmanship": + config.tint = "#8000ff"; + break; + case "athletics": + config.tint = "#0060ff"; + break; + default: + break; + } + defaultConfig.categories[meleeSkillType] = config; + } + Object.keys(CONFIG.MeasuredTemplate.types).forEach((tplType) => { + const config = { preset: emptyPreset, texture: null }; + switch (meleeSkillType.toLowerCase()) { + case "acid": + config.preset = "slashing"; + break; + case "cold": + config.preset = "bludgeoning"; + break; + case "fire": + config.preset = "piercing"; + break; + case "force": + config.preset = "elemental"; + break; + default: + break; + } + defaultConfig.categories[meleeSkillType][tplType] = config; + }); + }); + + return defaultConfig; + } + + constructor() { + this._enabled = false; + } + + get enabled() { + return this._enabled; + } + + configure(enabled = false) { + if (game.system.id !== "TheWitcherTRPG") return; + this._enabled = enabled; + } + + getData() { + return { + hasAutoTemplates: true, + meleeSkills: CONFIG.witcher.meleeSkills, + templateTypes: CONFIG.MeasuredTemplate.types, + }; + } + + preCreateMeasuredTemplate(template) { + let hasPreset = template.hasOwnProperty("tmfxPreset"); + if (hasPreset) { + return template; + } + const settings = game.settings.get("tokenmagic", "autoTemplateSettings"); + let updated = settings.overrides ? fromOverrides(Object.values(settings.overrides), template) : false; + if (!updated) { + fromCategories(settings.categories, template); + } + } +} + +function fromConfig(config, templateData) { + const o = { tokenmagic: { options: {} } }; + if (config.preset && config.preset !== "" && config.preset !== emptyPreset) { + o.tokenmagic.options.tmfxPreset = config.preset; + } + if (config.texture && config.texture !== "") { + o.tokenmagic.options.tmfxTexture = config.texture; + } + if (config.tint && config.tint !== "") { + o.tokenmagic.options.tmfxTint = config.tint; + } + o.tokenmagic.options.tmfxTextureAlpha = config.opacity; + mergeObject(templateData, { "flags.tokenmagic": o.tokenmagic }); +} + +function fromOverrides(overrides = [], templateData) { + const name = templateData.flags.witcher?.origin?.name; + let config = overrides.find((el) => el.target.toLowerCase() === name?.toLowerCase()); + if (!config) { + return false; + } + fromConfig(config, templateData); + return true; +} + +function fromCategories(categories = {}, templateData) { + const traits = templateData.flags.witcher?.origin?.traits ?? []; + + let config, dmgSettings; + for (const trait of traits) { + dmgSettings = categories[trait] || {}; + config = dmgSettings[templateData.t]; + + if (config && config.preset !== emptyPreset) { + break; + } + } + + if (!config) { + return false; + } + + fromConfig(mergeObject(config, { opacity: dmgSettings.opacity, tint: dmgSettings.tint }, true, true), templateData); + return true; +} + +export const witcherTemplates = new AutoTemplateTheWitcherTRPG(); diff --git a/src/scripts/autoTemplate/dnd5e.js b/src/scripts/autoTemplate/dnd5e.js new file mode 100644 index 0000000..f16fd6e --- /dev/null +++ b/src/scripts/autoTemplate/dnd5e.js @@ -0,0 +1,206 @@ +import { defaultOpacity, emptyPreset } from "../constants.js"; + +export class AutoTemplateDND5E { + static get defaultConfiguration() { + const defaultConfig = { + categories: {}, + overrides: { + 0: { + target: "Stinking Cloud", + opacity: 0.5, + tint: "#00a80b", + preset: "Smoky Area", + texture: null, + }, + 1: { + target: "Web", + opacity: 0.5, + tint: "#808080", + preset: "Spider Web 2", + texture: null, + }, + }, + }; + + Object.keys(CONFIG.DND5E.damageTypes).forEach((dmgType) => { + if (defaultConfig.categories[dmgType] == undefined) { + const config = { opacity: defaultOpacity, tint: null }; + switch (dmgType.toLowerCase()) { + case "acid": + config.tint = "#2d8000"; + config.opacity = 0.6; + break; + case "cold": + config.tint = "#47b3ff"; + break; + case "necrotic": + config.tint = "#502673"; + break; + case "poison": + config.tint = "#00a80b"; + break; + case "psychic": + config.tint = "#8000ff"; + break; + case "thunder": + config.tint = "#0060ff"; + break; + default: + break; + } + defaultConfig.categories[dmgType] = config; + } + Object.keys(CONFIG.MeasuredTemplate.types).forEach((tplType) => { + const config = { preset: emptyPreset, texture: null }; + switch (dmgType.toLowerCase()) { + case "acid": + config.preset = "Watery Surface 2"; + break; + case "cold": + config.preset = "Thick Fog"; + break; + case "fire": + config.preset = "Flames"; + break; + case "force": + config.preset = "Waves 3"; + break; + case "lightning": + config.preset = "Shock"; + break; + case "necrotic": + config.preset = "Smoke Filaments"; + break; + case "poison": + config.preset = "Smoky Area"; + break; + case "psychic": + config.preset = "Classic Rays"; + break; + case "radiant": + config.preset = "Annihilating Rays"; + break; + case "thunder": + config.preset = "Waves"; + break; + default: + break; + } + defaultConfig.categories[dmgType][tplType] = config; + }); + }); + + return defaultConfig; + } + + constructor() { + this._enabled = false; + } + + get enabled() { + return this._enabled; + } + + configure(enabled = false) { + if (game.system.id !== "dnd5e") return; + + if (!enabled) { + if (this._enabled) { + if (game.modules.get("lib-wrapper")?.active) { + libWrapper.unregister("tokenmagic", "game.dnd5e.canvas.AbilityTemplate.fromItem"); + } else { + window.location.reload(); + } + } + } else { + if (!this._enabled) { + if (game.modules.get("lib-wrapper")?.active) { + libWrapper.register("tokenmagic", "game.dnd5e.canvas.AbilityTemplate.fromItem", fromItem, "WRAPPER"); + } else { + const origFromItem = game.dnd5e.canvas.AbilityTemplate.fromItem; + game.dnd5e.canvas.AbilityTemplate.fromItem = function () { + return fromItem.call(this, origFromItem.bind(this), ...arguments); + }; + } + } + } + + this._enabled = enabled; + } + + getData() { + return { + hasAutoTemplates: true, + dmgTypes: CONFIG.DND5E.damageTypes, + templateTypes: CONFIG.MeasuredTemplate.types, + }; + } +} + +function fromConfig(config, template) { + const o = { tokenmagic: { options: {} } }; + if (config.preset && config.preset !== "" && config.preset !== emptyPreset) { + o.tokenmagic.options.tmfxPreset = config.preset; + } + if (config.texture && config.texture !== "") { + o.tokenmagic.options.tmfxTexture = config.texture; + } + if (config.tint && config.tint !== "") { + o.tokenmagic.options.tmfxTint = config.tint; + } + o.tokenmagic.options.tmfxTextureAlpha = config.opacity; + template.document.updateSource({ flags: { tokenmagic: o.tokenmagic } }); +} + +function fromOverrides(overrides = [], item, template) { + let config = overrides.find((el) => el.target.toLowerCase() === item.name.toLowerCase()); + if (!config) { + return false; + } + fromConfig(config, template); + return true; +} + +function fromCategories(categories = {}, item, template) { + if (!item.hasDamage) { + return false; + } + + let config, dmgSettings; + + // some items/spells have multiple damage types + // this loop looks over all the types until it finds one with a valid fx preset + for (const [_, dmgType] of item.data.data.damage.parts) { + dmgSettings = categories[dmgType] || {}; + config = dmgSettings[template.data.t]; + + if (config && config.preset !== emptyPreset) { + break; + } + } + if (!config) { + return false; + } + fromConfig(mergeObject(config, { opacity: dmgSettings.opacity, tint: dmgSettings.tint }, true, true), template); + return true; +} + +function fromItem(wrapped, ...args) { + const [item] = args; + const template = wrapped(...args); + if (!template) { + return template; + } + let hasPreset = template.hasOwnProperty("tmfxPreset"); + if (hasPreset) { + return template; + } + const settings = game.settings.get("tokenmagic", "autoTemplateSettings"); + let updated = settings.overrides ? fromOverrides(Object.values(settings.overrides), item, template) : false; + if (!updated) { + fromCategories(settings.categories, item, template); + } + return template; +} + +export const dnd5eTemplates = new AutoTemplateDND5E(); diff --git a/src/scripts/autoTemplate/pf2e.js b/src/scripts/autoTemplate/pf2e.js new file mode 100644 index 0000000..6aaafe5 --- /dev/null +++ b/src/scripts/autoTemplate/pf2e.js @@ -0,0 +1,206 @@ +import { defaultOpacity, emptyPreset } from "../constants.js"; + +export class AutoTemplatePF2E { + static get defaultConfiguration() { + const defaultConfig = { + categories: {}, + overrides: { + 0: { + target: "Stinking Cloud", + opacity: 0.5, + tint: "#00a80b", + preset: "Smoky Area", + texture: null, + }, + 1: { + target: "Sanguine Mist", + opacity: 0.6, + tint: "#c41212", + preset: "Smoky Area", + }, + 2: { + target: "Web", + opacity: 0.5, + tint: "#808080", + preset: "Spider Web 2", + texture: null, + }, + 3: { + target: "Incendiary Aura", + opacity: 0.2, + tint: "#b12910", + preset: "Smoke Filaments", + texture: null, + }, + }, + }; + + Object.keys(CONFIG.PF2E.damageTraits).forEach((dmgType) => { + if (defaultConfig.categories[dmgType] == undefined) { + const config = { opacity: defaultOpacity, tint: null }; + switch (dmgType.toLowerCase()) { + case "acid": + config.tint = "#2d8000"; + config.opacity = 0.6; + break; + case "cold": + config.tint = "#47b3ff"; + break; + case "electricity": + break; + case "fire": + break; + case "force": + break; + case "mental": + config.tint = "#8000ff"; + break; + case "negative": + config.tint = "#502673"; + break; + case "poison": + config.tint = "#00a80b"; + break; + case "positive": + break; + case "sonic": + config.tint = "#0060ff"; + break; + default: + break; + } + defaultConfig.categories[dmgType] = config; + } + Object.keys(CONFIG.MeasuredTemplate.types).forEach((tplType) => { + const config = { preset: emptyPreset, texture: null }; + switch (dmgType.toLowerCase()) { + case "acid": + config.preset = "Watery Surface 2"; + break; + case "cold": + config.preset = "Thick Fog"; + break; + case "electricity": + config.preset = "Shock"; + break; + case "fire": + config.preset = "Flames"; + break; + case "force": + config.preset = "Waves 3"; + break; + case "mental": + config.preset = "Classic Rays"; + break; + case "negative": + config.preset = "Smoke Filaments"; + break; + case "poison": + config.preset = "Smoky Area"; + break; + case "positive": + config.preset = "Annihilating Rays"; + break; + case "sonic": + config.preset = "Waves"; + break; + default: + break; + } + defaultConfig.categories[dmgType][tplType] = config; + }); + }); + + return defaultConfig; + } + + constructor() { + this._enabled = false; + } + + configure(enabled = false) { + if (game.system.id !== "pf2e") return; + this._enabled = enabled; + } + + get enabled() { + return this._enabled; + } + + set enabled(value) {} + + getData() { + return { + hasAutoTemplates: true, + dmgTypes: CONFIG.PF2E.damageTraits, + templateTypes: CONFIG.MeasuredTemplate.types, + }; + } + + preCreateMeasuredTemplate(template) { + let hasPreset = template.hasOwnProperty("tmfxPreset"); + if (hasPreset) { + return template; + } + + const origin = template.flags?.pf2e?.origin; + const settings = game.settings.get("tokenmagic", "autoTemplateSettings"); + let updated = settings.overrides ? fromOverrides(Object.values(settings.overrides), origin, template) : false; + if (!updated) { + fromCategories(settings.categories, origin, template); + } + return template; + } +} + +function fromConfig(config, template) { + const o = { tokenmagic: { options: {} } }; + if (config.preset && config.preset !== "" && config.preset !== emptyPreset) { + o.tokenmagic.options.tmfxPreset = config.preset; + } + if (config.texture && config.texture !== "") { + o.tokenmagic.options.tmfxTexture = config.texture; + } + if (config.tint && config.tint !== "") { + o.tokenmagic.options.tmfxTint = config.tint; + } + o.tokenmagic.options.tmfxTextureAlpha = config.opacity; + template.updateSource({ flags: { tokenmagic: o.tokenmagic } }); +} + +function fromOverrides(overrides = [], origin, template) { + const { name, slug } = origin; + + let config = overrides.find((el) => el.target.toLowerCase() === name?.toLowerCase()); + if (!config) { + return false; + } + fromConfig(config, template); + return true; +} + +function fromCategories(categories = {}, origin, template) { + if (!origin.traits?.length) { + return false; + } + + let config, dmgSettings; + + // some templates may have multiple traits + // this loop looks over all of them until it finds one with a valid fx preset + for (const trait of origin.traits) { + dmgSettings = categories[trait.toLowerCase()] || {}; + config = dmgSettings[template.t]; + + if (config && config.preset !== emptyPreset) { + break; + } + } + if (!config) { + return false; + } + fromConfig(mergeObject(config, { opacity: dmgSettings.opacity, tint: dmgSettings.tint }, true, true), template); + return true; +} + +export const pf2eTemplates = new AutoTemplatePF2E(); diff --git a/tokenmagic/module/constants.js b/src/scripts/constants.js similarity index 66% rename from tokenmagic/module/constants.js rename to src/scripts/constants.js index d02c828..3b0b480 100644 --- a/tokenmagic/module/constants.js +++ b/src/scripts/constants.js @@ -1,3 +1,3 @@ export const defaultOpacity = 0.5; -export const emptyPreset = 'NOFX'; +export const emptyPreset = "NOFX"; export const autoMinRank = 10000; diff --git a/src/scripts/migration/migration.js b/src/scripts/migration/migration.js new file mode 100644 index 0000000..89cae6e --- /dev/null +++ b/src/scripts/migration/migration.js @@ -0,0 +1,176 @@ +import { TokenMagic, isTheOne, log, warn, error } from "../../module.js"; +import { PresetsLibrary, templatePresets } from "../../fx/presets/defaultpresets.js"; + +const Magic = TokenMagic(); + +// TODO create a generic function to import JSON by version + +export const DataVersion = { + ARCHAIC: "", + V030: "0.3.0", + V040: "0.4.0", + V040b: "0.4.0b", + V041: "0.4.1", + V043: "0.4.3", +}; + +// migration function - will evolve constantly +export async function tmfxDataMigration() { + if (isTheOne()) { + var dataVersionNow; + try { + dataVersionNow = game.settings.get("tokenmagic", "migration"); + } catch (e) { + dataVersionNow = DataVersion.ARCHAIC; + } + if (dataVersionNow < DataVersion.V030) { + await updatePresetsV030(); + } + if (dataVersionNow < DataVersion.V040) { + await updatePresetsV040(); + } + if (dataVersionNow < DataVersion.V040b) { + await updatePresetsV040b(); + } + if (dataVersionNow < DataVersion.V041) { + await updatePresetsV041(); + } + if (dataVersionNow < DataVersion.V043) { + await updatePresetsV043(); + } + } +} + +// migrating to the new presets data +async function updatePresetsV030() { + var presets = game.settings.get("tokenmagic", "presets"); + + if (!(presets == null)) { + log(`Migration 0.3.0 - Launching presets data migration...`); + + let foundTemplateLibrary = false; + + for (const preset of presets) { + if (!preset.hasOwnProperty("library")) { + preset.library = PresetsLibrary.MAIN; + log(`Migration 0.3.0 - Adding ${preset.name} to ${PresetsLibrary.MAIN}`); + } else if (preset.library === PresetsLibrary.TEMPLATE && !foundTemplateLibrary) { + foundTemplateLibrary = true; + log(`Migration 0.3.0 - Found template presets. Templates will not be added.`); + } + } + + if (!foundTemplateLibrary) log(`Migration 0.3.0 - Merging templates presets.`); + + let newPresets = foundTemplateLibrary ? presets : presets.concat(templatePresets); + + try { + await game.settings.set("tokenmagic", "presets", newPresets); + await game.settings.set("tokenmagic", "migration", DataVersion.V030); + log(`Migration 0.3.0 - Migration successful!`); + } catch (e) { + error(`Migration 0.3.0 - Migration failed.`); + error(e); + } + } +} + +async function updatePresetsV040() { + var presets = game.settings.get("tokenmagic", "presets"); + + if (!(presets == null)) { + log(`Migration 0.4.0 - Launching presets data migration...`); + + // Adding zOrder for the template presets only + // Does not break visuals + for (const preset of presets) { + if (preset.library === PresetsLibrary.TEMPLATE) { + log(`Migration 0.4.0 - Checking template preset ${preset.name}...`); + let zOrder = 1; + for (const filter of preset.params) { + if (!filter.hasOwnProperty("zOrder")) { + filter.zOrder = zOrder; + log(`Migration 0.4.0 - Updating ${filter.filterType} in ${preset.name}...`); + zOrder++; + } + } + } + } + + try { + await game.settings.set("tokenmagic", "presets", presets); + log(`Migration 0.4.0 - Importing new template presets...`); + await Magic.importPresetLibraryFromPath("modules/tokenmagic/import/TMFX-update-presets-v040.json", { + overwrite: false, + }); + await game.settings.set("tokenmagic", "migration", DataVersion.V040); + log(`Migration 0.4.0 - Migration successful!`); + } catch (e) { + error(`Migration 0.4.0 - Migration failed.`); + error(e); + } + } +} + +async function updatePresetsV040b() { + var presets = game.settings.get("tokenmagic", "presets"); + + if (!(presets == null)) { + log(`Migration 0.4.0b - Launching presets data migration...`); + + try { + await game.settings.set("tokenmagic", "presets", presets); + log(`Migration 0.4.0b - updating template presets...`); + await Magic.importPresetLibraryFromPath("modules/tokenmagic/import/TMFX-update-presets-v040b.json", { + overwrite: true, + }); + await game.settings.set("tokenmagic", "migration", DataVersion.V040b); + log(`Migration 0.4.0b - Migration successful!`); + } catch (e) { + error(`Migration 0.4.0b - Migration failed.`); + error(e); + } + } +} + +async function updatePresetsV041() { + var presets = game.settings.get("tokenmagic", "presets"); + + if (!(presets == null)) { + log(`Migration 0.4.1 - Launching presets data migration...`); + + try { + await game.settings.set("tokenmagic", "presets", presets); + log(`Migration 0.4.1 - updating template presets...`); + await Magic.importPresetLibraryFromPath("modules/tokenmagic/import/TMFX-update-presets-v041.json", { + overwrite: true, + }); + await game.settings.set("tokenmagic", "migration", DataVersion.V041); + log(`Migration 0.4.1 - Migration successful!`); + } catch (e) { + error(`Migration 0.4.1 - Migration failed.`); + error(e); + } + } +} + +async function updatePresetsV043() { + var presets = game.settings.get("tokenmagic", "presets"); + + if (!(presets == null)) { + log(`Migration 0.4.3 - Launching presets data migration...`); + + try { + await game.settings.set("tokenmagic", "presets", presets); + log(`Migration 0.4.3 - updating template presets...`); + await Magic.importPresetLibraryFromPath("modules/tokenmagic/import/TMFX-update-presets-v043.json", { + overwrite: true, + }); + await game.settings.set("tokenmagic", "migration", DataVersion.V043); + log(`Migration 0.4.3 - Migration successful!`); + } catch (e) { + error(`Migration 0.4.3 - Migration failed.`); + error(e); + } + } +} diff --git a/src/scripts/proto/PlaceableObjectProto.js b/src/scripts/proto/PlaceableObjectProto.js new file mode 100644 index 0000000..5023a04 --- /dev/null +++ b/src/scripts/proto/PlaceableObjectProto.js @@ -0,0 +1,171 @@ +import { PlaceableType, Magic, broadcast, SocketAction, mustBroadCast, isZOrderConfig } from "../../module.js"; +import { emptyPreset, autoMinRank } from "../constants.js"; + +export var gMaxRank = autoMinRank; + +PlaceableObject.prototype.TMFXaddFilters = async function (paramsArray, replace = false) { + await Magic.addFilters(this, paramsArray, replace); +}; + +PlaceableObject.prototype.TMFXupdateFilters = async function (paramsArray) { + await Magic.updateFiltersByPlaceable(this, paramsArray); +}; + +PlaceableObject.prototype.TMFXaddUpdateFilters = async function (paramsArray) { + await Magic.addUpdateFilters(this, paramsArray); +}; + +PlaceableObject.prototype.TMFXdeleteFilters = async function (filterId = null) { + await Magic.deleteFilters(this, filterId); +}; + +PlaceableObject.prototype.TMFXhasFilterType = function (filterType) { + return Magic.hasFilterType(this, filterType); +}; + +PlaceableObject.prototype.TMFXhasFilterId = function (filterId) { + return Magic.hasFilterId(this, filterId); +}; + +PlaceableObject.prototype._TMFXsetFlag = async function (flag) { + if (mustBroadCast()) broadcast(this, flag, SocketAction.SET_FLAG); + else await this.document.setFlag("tokenmagic", "filters", flag); +}; + +PlaceableObject.prototype._TMFXsetAnimeFlag = async function (flag) { + if (mustBroadCast()) broadcast(this, flag, SocketAction.SET_ANIME_FLAG); + else await this.document.setFlag("tokenmagic", "animeInfo", flag); +}; + +PlaceableObject.prototype._TMFXunsetFlag = async function () { + if (mustBroadCast()) broadcast(this, null, SocketAction.SET_FLAG); + else await this.document.unsetFlag("tokenmagic", "filters"); +}; + +PlaceableObject.prototype._TMFXunsetAnimeFlag = async function () { + if (mustBroadCast()) broadcast(this, null, SocketAction.SET_ANIME_FLAG); + else await this.document.unsetFlag("tokenmagic", "animeInfo"); +}; + +PlaceableObject.prototype._TMFXgetSprite = function () { + const type = this._TMFXgetPlaceableType(); + switch (type) { + case PlaceableType.TOKEN: + return this.mesh; + case PlaceableType.TILE: + return this.mesh ?? this.bg; + case PlaceableType.TEMPLATE: + return this.template; + case PlaceableType.DRAWING: + return this.hasText ? this.text : this.shape; + default: + return null; + } +}; + +PlaceableObject.prototype._TMFXgetPlaceablePadding = function () { + // get the placeable padding, by taking into account all filters and options + let accPadding = 0; + const filters = this._TMFXgetSprite().filters; + if (filters instanceof Array) { + for (const filter of filters) { + if (!filter.enabled) continue; + if (canvas.app.renderer.filter.useMaxPadding) { + accPadding = Math.max(accPadding, filter.padding); + } else { + accPadding += filter.padding; + } + } + } + return accPadding; +}; + +PlaceableObject.prototype._TMFXcheckSprite = function () { + const type = this._TMFXgetPlaceableType(); + switch (type) { + case PlaceableType.TOKEN: + case PlaceableType.TILE: + return !(this.mesh == null); + case PlaceableType.TEMPLATE: + return !(this.template == null); + case PlaceableType.DRAWING: + return !(this.shape == null); + default: + return null; + } +}; + +PlaceableObject.prototype._TMFXgetMaxFilterRank = function () { + const sprite = this._TMFXgetSprite(); + if (sprite == null) { + return gMaxRank++; + } + if (sprite.filters == null) { + return gMaxRank++; + } else { + let maxRank = Math.max(...sprite.filters.map((f) => f.rank), autoMinRank); + gMaxRank = Math.max(maxRank, gMaxRank) + 1; + return gMaxRank; + } +}; + +PlaceableObject.prototype._TMFXsetRawFilters = function (filters) { + function insertFilter(filters) { + function filterZOrderCompare(a, b) { + if (a.zOrder < b.zOrder) return -1; + if (a.zOrder > b.zOrder) return 1; + return 0; + } + + function filterRankCompare(a, b) { + if (a.rank < b.rank) return -1; + if (a.rank > b.rank) return 1; + return 0; + } + + if (!isZOrder) { + if (!filters.hasOwnProperty("rank")) { + let maxRank = Math.max(...sprite.filters.map((f) => f.rank), autoMinRank); + filters.rank = maxRank + 1; + } + } + + sprite.filters.push(filters); + isZOrder ? sprite.filters.sort(filterZOrderCompare) : sprite.filters.sort(filterRankCompare); + } + + function addFilter(filters) { + if (!isZOrder && !filters.hasOwnProperty("rank")) { + filters.rank = autoMinRank; + } + sprite.filters = [filters]; + } + + const isZOrder = isZOrderConfig(); + const sprite = this._TMFXgetSprite(); + if (sprite == null) { + return false; + } + + if (filters == null) { + sprite.filters = null; + } else { + sprite.filters == null ? addFilter(filters) : insertFilter(filters); + } + + return true; +}; + +PlaceableObject.prototype._TMFXunsetRawFilters = function () { + return this._TMFXsetRawFilters(null); +}; + +PlaceableObject.prototype._TMFXgetPlaceableType = function () { + if ( + [PlaceableType.TOKEN, PlaceableType.TEMPLATE, PlaceableType.TILE, PlaceableType.DRAWING].includes( + this.constructor.embeddedName + ) + ) + return this.constructor.embeddedName; + return PlaceableType.NOT_SUPPORTED; +}; diff --git a/src/scripts/settings.js b/src/scripts/settings.js new file mode 100644 index 0000000..360448d --- /dev/null +++ b/src/scripts/settings.js @@ -0,0 +1,613 @@ +import { presets as defaultPresets, PresetsLibrary } from "../fx/presets/defaultpresets.js"; +import { DataVersion } from "./migration/migration.js"; +import { TokenMagic, isVideoDisabled, fixPath } from "../module.js"; +import { dnd5eTemplates } from "./autoTemplate/dnd5e.js"; +import { pf2eTemplates } from "./autoTemplate/pf2e.js"; +import { witcherTemplates } from "./autoTemplate/TheWitcherTRPG.js"; +import { defaultOpacity, emptyPreset } from "./constants.js"; + +const Magic = TokenMagic(); + +export class TokenMagicSettings extends FormApplication { + constructor(object = {}, options) { + super(object, options); + } + + /** @override */ + static get defaultOptions() { + return { + ...super.defaultOptions, + template: "modules/tokenmagic/templates/settings/settings.html", + height: "auto", + title: game.i18n.localize("TMFX.settings.autoTemplateSettings.dialog.title"), + width: 600, + classes: ["tokenmagic", "settings"], + tabs: [ + { + navSelector: ".tabs", + contentSelector: "form", + initial: "name", + }, + ], + submitOnClose: false, + }; + } + + static init() { + const menuAutoTemplateSettings = { + key: "autoTemplateSettings", + config: { + name: game.i18n.localize("TMFX.settings.autoTemplateSettings.button.name"), + label: game.i18n.localize("TMFX.settings.autoTemplateSettings.button.label"), + hint: game.i18n.localize("TMFX.settings.autoTemplateSettings.button.hint"), + type: TokenMagicSettings, + restricted: true, + }, + }; + + const settingAutoTemplateSettings = { + key: "autoTemplateSettings", + config: { + name: game.i18n.localize("TMFX.settings.autoTemplateSettings.name"), + hint: game.i18n.localize("TMFX.settings.autoTemplateSettings.hint"), + scope: "world", + config: false, + default: {}, + type: Object, + }, + }; + + const templates = this.getSystemTemplates(); + let hasAutoTemplates = !!templates; + if (templates) { + game.settings.registerMenu("tokenmagic", menuAutoTemplateSettings.key, menuAutoTemplateSettings.config); + game.settings.register( + "tokenmagic", + settingAutoTemplateSettings.key, + mergeObject( + settingAutoTemplateSettings.config, + { + default: templates.constructor.defaultConfiguration, + }, + true, + true + ) + ); + } + + game.settings.register("tokenmagic", "autoTemplateEnabled", { + name: game.i18n.localize("TMFX.settings.autoTemplateEnabled.name"), + hint: game.i18n.localize("TMFX.settings.autoTemplateEnabled.hint"), + scope: "world", + config: hasAutoTemplates, + default: hasAutoTemplates, + type: Boolean, + onChange: (value) => TokenMagicSettings.configureAutoTemplate(value), + }); + + game.settings.register("tokenmagic", "defaultTemplateOnHover", { + name: game.i18n.localize("TMFX.settings.defaultTemplateOnHover.name"), + hint: game.i18n.localize("TMFX.settings.defaultTemplateOnHover.hint"), + scope: "world", + config: true, + default: hasAutoTemplates, + type: Boolean, + onChange: () => window.location.reload(), + }); + + game.settings.register("tokenmagic", "autohideTemplateElements", { + name: game.i18n.localize("TMFX.settings.autohideTemplateElements.name"), + hint: game.i18n.localize("TMFX.settings.autohideTemplateElements.hint"), + scope: "world", + config: true, + default: true, + type: Boolean, + onChange: () => window.location.reload(), + }); + + game.settings.register("tokenmagic", "useAdditivePadding", { + name: game.i18n.localize("TMFX.settings.useMaxPadding.name"), + hint: game.i18n.localize("TMFX.settings.useMaxPadding.hint"), + scope: "world", + config: true, + default: false, + type: Boolean, + }); + + game.settings.register("tokenmagic", "minPadding", { + name: game.i18n.localize("TMFX.settings.minPadding.name"), + hint: game.i18n.localize("TMFX.settings.minPadding.hint"), + scope: "world", + config: true, + default: 50, + type: Number, + }); + + game.settings.register("tokenmagic", "fxPlayerPermission", { + name: game.i18n.localize("TMFX.settings.fxPlayerPermission.name"), + hint: game.i18n.localize("TMFX.settings.fxPlayerPermission.hint"), + scope: "world", + config: true, + default: false, + type: Boolean, + }); + + game.settings.register("tokenmagic", "importOverwrite", { + name: game.i18n.localize("TMFX.settings.importOverwrite.name"), + hint: game.i18n.localize("TMFX.settings.importOverwrite.hint"), + scope: "world", + config: true, + default: false, + type: Boolean, + }); + + game.settings.register("tokenmagic", "useZOrder", { + name: game.i18n.localize("TMFX.settings.useZOrder.name"), + hint: game.i18n.localize("TMFX.settings.useZOrder.hint"), + scope: "world", + config: true, + default: false, + type: Boolean, + }); + + game.settings.register("tokenmagic", "disableAnimations", { + name: game.i18n.localize("TMFX.settings.disableAnimations.name"), + hint: game.i18n.localize("TMFX.settings.disableAnimations.hint"), + scope: "client", + config: true, + default: false, + type: Boolean, + onChange: () => window.location.reload(), + }); + + game.settings.register("tokenmagic", "disableCaching", { + name: game.i18n.localize("TMFX.settings.disableCaching.name"), + hint: game.i18n.localize("TMFX.settings.disableCaching.hint"), + scope: "client", + config: true, + default: true, + type: Boolean, + }); + + game.settings.register("tokenmagic", "disableVideo", { + name: game.i18n.localize("TMFX.settings.disableVideo.name"), + hint: game.i18n.localize("TMFX.settings.disableVideo.hint"), + scope: "world", + config: true, + default: false, + type: Boolean, + onChange: () => window.location.reload(), + }); + + game.settings.register("tokenmagic", "presets", { + name: "Token Magic FX presets", + hint: "Token Magic FX presets", + scope: "world", + config: false, + default: defaultPresets, + type: Object, + }); + + game.settings.register("tokenmagic", "migration", { + name: "TMFX Data Version", + hint: "TMFX Data Version", + scope: "world", + config: false, + default: DataVersion.ARCHAIC, + type: String, + }); + + loadTemplates([ + "modules/tokenmagic/templates/settings/settings.html", + "modules/tokenmagic/templates/settings/dnd5e/categories.html", + "modules/tokenmagic/templates/settings/dnd5e/overrides.html", + "modules/tokenmagic/templates/settings/pf2e/categories.html", + "modules/tokenmagic/templates/settings/pf2e/overrides.html", + "modules/tokenmagic/templates/settings/TheWitcherTRPG/categories.html", + "modules/tokenmagic/templates/settings/TheWitcherTRPG/overrides.html", + ]); + } + + static configureAutoTemplate(enabled = false) { + this.getSystemTemplates()?.configure(enabled); + } + + static getSystemTemplates() { + switch (game.system.id) { + case "dnd5e": + return dnd5eTemplates; + case "pf2e": + return pf2eTemplates; + case "TheWitcherTRPG": + return witcherTemplates; + default: + return null; + } + } + + getSettingsData() { + let settingsData = { + autoTemplateEnable: game.settings.get("tokenmagic", "autoTemplateEnabled"), + }; + if (TokenMagicSettings.getSystemTemplates()) { + settingsData["autoTemplateSettings"] = game.settings.get("tokenmagic", "autoTemplateSettings"); + } + return settingsData; + } + + /** @override */ + getData() { + let data = super.getData(); + data.hasAutoTemplates = false; + data.emptyPreset = emptyPreset; + const templates = TokenMagicSettings.getSystemTemplates(); + if (templates) { + mergeObject(data, templates.getData()); + } + + data.presets = Magic.getPresets(PresetsLibrary.TEMPLATE).sort(function (a, b) { + if (a.name < b.name) return -1; + if (a.name > b.name) return 1; + return 0; + }); + data.system = { id: game.system.id, title: game.system.title }; + data.settings = this.getSettingsData(); + data.submitText = game.i18n.localize("TMFX.save"); + return data; + } + + /** @override */ + async _updateObject(_, formData) { + const data = expandObject(formData); + for (let [key, value] of Object.entries(data)) { + if (key === "autoTemplateSettings" && value.overrides) { + const compacted = {}; + Object.values(value.overrides).forEach((val, idx) => (compacted[idx] = val)); + value.overrides = compacted; + } + await game.settings.set("tokenmagic", key, value); + } + } + + /** @override */ + activateListeners(html) { + super.activateListeners(html); + + html.find("button.add-override").click(this._onAddOverride.bind(this)); + html.find("button.remove-override").click(this._onRemoveOverride.bind(this)); + } + + async _onAddOverride(event) { + event.preventDefault(); + let idx = 0; + const entries = event.target.closest("div.tab").querySelectorAll("div.override-entry"); + const last = entries[entries.length - 1]; + if (last) { + idx = last.dataset.idx + 1; + } + let updateData = {}; + updateData[`autoTemplateSettings.overrides.${idx}.target`] = ""; + updateData[`autoTemplateSettings.overrides.${idx}.opacity`] = defaultOpacity; + updateData[`autoTemplateSettings.overrides.${idx}.tint`] = null; + updateData[`autoTemplateSettings.overrides.${idx}.preset`] = emptyPreset; + updateData[`autoTemplateSettings.overrides.${idx}.texture`] = null; + await this._onSubmit(event, { updateData: updateData, preventClose: true }); + this.render(); + } + + async _onRemoveOverride(event) { + event.preventDefault(); + let idx = event.target.dataset.idx; + const el = event.target.closest(`div[data-idx="${idx}"]`); + if (!el) { + return true; + } + el.remove(); + await this._onSubmit(event, { preventClose: true }); + this.render(); + } +} + +Hooks.once("init", () => { + // Extracted from https://github.com/leapfrogtechnology/just-handlebars-helpers/ + Handlebars.registerHelper("concat", function (...params) { + // Ignore the object appended by handlebars. + if (typeof params[params.length - 1] === "object") { + params.pop(); + } + + return params.join(""); + }); + TokenMagicSettings.init(); + TokenMagicSettings.configureAutoTemplate(game.settings.get("tokenmagic", "autoTemplateEnabled")); + + const wmtdUpdate = async function (wrapped, ...args) { + const [document] = args; + let preset, hasPresetData; + + const tex = document.texture ?? ""; + const hasTexture = !!document.texture; + const opt = document.flags?.tokenmagic?.options ?? null; + if (!opt) { + preset = document["flags.tokenmagic.templateData.preset"]; + } + hasPresetData = !!preset; + + //const hasOpt = data["flags.tokenmagic"]?.options ?? null; + + if (hasTexture) { + document.texture = fixPath(document.texture); + } + + if (opt == null) { + if (hasPresetData && preset !== emptyPreset) { + let defaultTexture = Magic._getPresetTemplateDefaultTexture(preset); + if (!(defaultTexture == null)) { + if (tex === "" || tex.startsWith("modules/tokenmagic/fx/assets/templates/")) + document.texture = defaultTexture; + } + } else if ( + hasTexture && + tex.startsWith("modules/tokenmagic/fx/assets/templates/") && + hasPresetData && + preset === emptyPreset + ) { + document.texture = ""; + } + } + + return await wrapped(...args); + }; + + const wmtDraw = async function (wrapped, ...args) { + if (this.document.texture) { + this.document.texture = fixPath(this.document.texture); + } + const retVal = await wrapped(...args); + this.template.alpha = this.document.getFlag("tokenmagic", "templateData")?.opacity ?? 1; + return retVal; + }; + + let wmtApplyRenderFlags; + let wmtApplyRenderFlagsType; + + let wmtRefreshTemplate; + let wmtRefreshTemplateType; + + if (!isVideoDisabled()) { + const toRadians = Math.toRadians; + + wmtApplyRenderFlagsType = "WRAPPER"; + + wmtApplyRenderFlags = function (wrapped, ...args) { + const [flags] = args; + if (flags?.refreshShape) flags.refreshShape = this.template && !this.template._destroyed; + return wrapped(...args); + }; + + /* ------------------------------------------------------------------------------------ */ + + wmtRefreshTemplateType = "OVERRIDE"; + + /** + * + * @return {wmtRefreshTemplate} + */ + wmtRefreshTemplate = function () { + const t = this.template.clear(); + if (!this.isVisible) return; + + // Draw the Template outline + t.lineStyle(this._borderThickness, this.borderColor, 0.75).beginFill(0x000000, 0.0); + + // Fill Color or Texture + if (this.texture) { + let mat = PIXI.Matrix.IDENTITY; + // rectangle + if (this.shape.width && this.shape.height) + mat.scale(this.shape.width / this.texture.width, this.shape.height / this.texture.height); + else if (this.shape.radius) { + mat.scale((this.shape.radius * 2) / this.texture.height, (this.shape.radius * 2) / this.texture.width); + // Circle center is texture start... + mat.translate(-this.shape.radius, -this.shape.radius); + } else if (this.document.t === "ray") { + const d = canvas.dimensions, + height = (this.document.width * d.size) / d.distance, + width = (this.document.distance * d.size) / d.distance; + mat.scale(width / this.texture.width, height / this.texture.height); + mat.translate(0, -height * 0.5); + + mat.rotate(toRadians(this.document.direction)); + } else { + // cone + const d = canvas.dimensions; + + // Extract and prepare data + let { direction, distance, angle } = this.document; + distance *= d.size / d.distance; + direction = Math.toRadians(direction); + const width = (this.document.distance * d.size) / d.distance; + + const angles = [angle / -2, angle / 2]; + distance = distance / Math.cos(Math.toRadians(angle / 2)); + + // Get the cone shape as a polygon + const rays = angles.map((a) => Ray.fromAngle(0, 0, direction + Math.toRadians(a), distance + 1)); + const height = Math.sqrt( + (rays[0].B.x - rays[1].B.x) * (rays[0].B.x - rays[1].B.x) + + (rays[0].B.y - rays[1].B.y) * (rays[0].B.y - rays[1].B.y) + ); + mat.scale(width / this.texture.width, height / this.texture.height); + mat.translate(0, -height / 2); + mat.rotate(toRadians(this.document.direction)); + } + + t.beginTextureFill({ + texture: this.texture, + matrix: mat, + alpha: 1.0, + }); + const source = getProperty(this.texture, "baseTexture.resource.source"); + if (source && source.tagName === "VIDEO") { + source.loop = true; + source.muted = true; + game.video.play(source); + } + } else t.beginFill(0x000000, 0.0); + + // Draw the shape + t.drawShape(this.shape); + + // Draw origin and destination points + t.lineStyle(this._borderThickness, 0x000000) + .beginFill(0x000000, 0.5) + .drawCircle(0, 0, 6) + .drawCircle(this.ray.dx, this.ray.dy, 6); + + // Update visibility + this.controlIcon.visible = !!this.layer.active; + this.controlIcon.border.visible = !!this.hover; + const alpha = this.document.getFlag("tokenmagic", "templateData")?.opacity ?? 1; + t.alpha = this.hover ? alpha / 1.25 : alpha; + + return this; + }; + + /* ------------------------------------------------------------------------------------ */ + } + + if (game.settings.get("tokenmagic", "autohideTemplateElements")) { + /** + * + * @param wrapped + * @param args + * @return {*} + */ + const autohideTemplateElements = function (wrapped, ...args) { + // Save texture and border thickness + const texture = this.texture; + const borderThickness = this._borderThickness; + + // Hide template texture while moving + if (this._original || this.parent === canvas.templates.preview) { + this.texture = null; + } + + // Show border outline only on hover if the template is textured + if (this.texture && this.texture !== "" && !this._hover) { + this._borderThickness = 0; + } + + const retVal = wrapped(...args); + + // Restore texture and border thickness + this.texture = texture; + this._borderThickness = borderThickness; + + { + // Show the origin/destination points and ruler text only on hover or while creating but not while moving + const template = this._original ?? this; + const show = !this._original && (this._hover || this.parent === canvas.templates.preview); + + if (!show && template.template?.geometry) { + // Hide origin and destination points, i.e., hide everything except the template shape + for (const document of template.template.geometry.graphicsData) { + if (document.shape !== template.shape) { + document.fillStyle.visible = false; + document.lineStyle.visible = false; + } + } + template.template.geometry.invalidate(); + } + + if (template.ruler) template.ruler.renderable = show; + if (template.controlIcon) template.controlIcon.renderable = template.owner; + if (template.handle) template.handle.renderable = template.owner; + } + return retVal; + }; + + /* ------------------------------------------------------------------------------------ */ + + if (wmtApplyRenderFlags) { + const _wmtApplyRenderFlags = wmtApplyRenderFlags; + wmtApplyRenderFlags = function () { + return autohideTemplateElements.call(this, _wmtApplyRenderFlags.bind(this), ...arguments); + }; + } else { + wmtApplyRenderFlagsType = "WRAPPER"; + wmtApplyRenderFlags = autohideTemplateElements; + } + } + + if (game.settings.get("tokenmagic", "defaultTemplateOnHover")) { + Hooks.on("canvasReady", () => { + canvas.stage.on("mousemove", (event) => { + const { x: mx, y: my } = event.data.getLocalPosition(canvas.templates); + for (const template of canvas.templates.placeables) { + const hl = canvas.grid.getHighlightLayer(`MeasuredTemplate.${template.id}`); + const opacity = template.document.getFlag("tokenmagic", "templateData")?.opacity ?? 1; + if (template.texture && template.texture !== "") { + const { x: cx, y: cy } = template.center; + const mouseover = template.shape?.contains(mx - cx, my - cy); + hl.renderable = mouseover; + template.template.alpha = (mouseover ? 0.5 : 1.0) * opacity; + } else { + hl.renderable = true; + template.template.alpha = opacity; + } + } + }); + }); + } + + if (game.modules.get("lib-wrapper")?.active) { + libWrapper.register("tokenmagic", "MeasuredTemplateDocument.prototype.update", wmtdUpdate, "WRAPPER"); + libWrapper.register("tokenmagic", "MeasuredTemplate.prototype._draw", wmtDraw, "WRAPPER"); + if (wmtApplyRenderFlags) + libWrapper.register( + "tokenmagic", + "MeasuredTemplate.prototype._applyRenderFlags", + wmtApplyRenderFlags, + wmtApplyRenderFlagsType + ); + if (wmtRefreshTemplate) + libWrapper.register( + "tokenmagic", + "MeasuredTemplate.prototype._refreshTemplate", + wmtRefreshTemplate, + wmtRefreshTemplateType + ); + } else { + const cmtdUpdate = MeasuredTemplateDocument.prototype.update; + MeasuredTemplateDocument.prototype.update = function () { + return wmtdUpdate.call(this, cmtdUpdate.bind(this), ...arguments); + }; + const cmtDraw = MeasuredTemplate.prototype._draw; + MeasuredTemplate.prototype._draw = function () { + return wmtDraw.call(this, cmtDraw.bind(this), ...arguments); + }; + + if (wmtApplyRenderFlags) { + if (wmtApplyRenderFlagsType && wmtApplyRenderFlagsType !== "OVERRIDE") { + const cmtApplyRenderFlags = MeasuredTemplate.prototype._applyRenderFlags; + MeasuredTemplate.prototype._applyRenderFlags = function () { + return wmtApplyRenderFlags.call(this, cmtApplyRenderFlags.bind(this), ...arguments); + }; + } else { + MeasuredTemplate.prototype._applyRenderFlags = wmtApplyRenderFlags; + } + } + + if (wmtRefreshTemplate) { + if (wmtRefreshTemplateType && wmtRefreshTemplateType !== "OVERRIDE") { + const cmtRefreshTemplate = MeasuredTemplate.prototype._refreshTemplate; + MeasuredTemplate.prototype._refreshTemplate = function () { + return wmtRefreshTemplate.call(this, cmtRefreshTemplate.bind(this), ...arguments); + }; + } else { + MeasuredTemplate.prototype._refreshTemplate = wmtRefreshTemplate; + } + } + } +}); diff --git a/src/styles/tokenmagic.css b/src/styles/tokenmagic.css new file mode 100644 index 0000000..ec3b23d --- /dev/null +++ b/src/styles/tokenmagic.css @@ -0,0 +1,30 @@ +.tokenmagic.settings nav.tabs { + flex: 0 0 32px; + line-height: 32px; + font-size: 16px; + border-bottom: 1px solid #000; +} + +.tokenmagic.settings section.content { + border-top: 1px solid #b5b3a4; +} + +.tokenmagic.settings section.content .settings-list { + max-height: calc(100vh - 150px); + overflow-y: auto; + padding-right: 0.5em; +} + +.tokenmagic.settings div.override-entry { + padding: 0.5em 0; + border-top: 1px solid #b5b3a4; +} + +.tokenmagic.settings div.remove-override-wrapper { + flex: 0; + margin-left: 0.5em; +} + +.tokenmagic.settings footer.add-override-wrapper { + margin-bottom: 0.5em; +} diff --git a/tokenmagic/templates/settings/TheWitcherTRPG/categories.html b/src/templates/settings/TheWitcherTRPG/categories.html similarity index 100% rename from tokenmagic/templates/settings/TheWitcherTRPG/categories.html rename to src/templates/settings/TheWitcherTRPG/categories.html diff --git a/tokenmagic/templates/settings/TheWitcherTRPG/overrides.html b/src/templates/settings/TheWitcherTRPG/overrides.html similarity index 100% rename from tokenmagic/templates/settings/TheWitcherTRPG/overrides.html rename to src/templates/settings/TheWitcherTRPG/overrides.html diff --git a/tokenmagic/templates/settings/dnd5e/categories.html b/src/templates/settings/dnd5e/categories.html similarity index 100% rename from tokenmagic/templates/settings/dnd5e/categories.html rename to src/templates/settings/dnd5e/categories.html diff --git a/tokenmagic/templates/settings/dnd5e/overrides.html b/src/templates/settings/dnd5e/overrides.html similarity index 100% rename from tokenmagic/templates/settings/dnd5e/overrides.html rename to src/templates/settings/dnd5e/overrides.html diff --git a/tokenmagic/templates/settings/pf2e/categories.html b/src/templates/settings/pf2e/categories.html similarity index 100% rename from tokenmagic/templates/settings/pf2e/categories.html rename to src/templates/settings/pf2e/categories.html diff --git a/tokenmagic/templates/settings/pf2e/overrides.html b/src/templates/settings/pf2e/overrides.html similarity index 100% rename from tokenmagic/templates/settings/pf2e/overrides.html rename to src/templates/settings/pf2e/overrides.html diff --git a/tokenmagic/templates/settings/settings.html b/src/templates/settings/settings.html similarity index 100% rename from tokenmagic/templates/settings/settings.html rename to src/templates/settings/settings.html diff --git a/tokenmagic/fx/Anime.js b/tokenmagic/fx/Anime.js deleted file mode 100644 index 35fee9f..0000000 --- a/tokenmagic/fx/Anime.js +++ /dev/null @@ -1,560 +0,0 @@ -import { isAnimationDisabled } from '../module/tokenmagic.js'; - -export class Anime { - constructor(puppet) { - const self = this; - this.puppet = puppet; - this.animated = null; - this.animeId = randomID(); - - // Time/synchronization related variables - this.frameTime = {}; - this.elapsedTime = {}; - this.loopElapsedTime = {}; - this.loops = {}; - this.internalLoops = {}; - this.ping = {}; - this.pauseBetweenElapsedTime = {}; - this.pauseBetween = {}; - this.shutdown = {}; - - if (!(this.puppet == null)) { - if ( - this.puppet.hasOwnProperty('animated') && - !(this.puppet.animated == null) && - typeof this.puppet.animated === 'object' && - Object.keys(this.puppet.animated).length > 0 - ) { - this.initAnimatedInternals(this.puppet.animated); - this.animated = this.puppet.animated; // easy access to the puppet's animodes - } - Anime.addAnimation(self); // ready to tick - } - } - - static rgbToValue(r, g, b) { - return (r << 16) | (g << 8) | b; - } - - static valueToRgb(bin) { - const r = bin >> 16; - const g = (bin >> 8) & 0xff; - const b = bin & 0xff; - return [r, g, b]; - } - - static oscillation(elapsed, loopDuration, syncShift, val1, val2, func, isSync, xpi = Anime.twoPi) { - return ( - ((val1 - val2) * - (func( - xpi * (isSync ? Anime.getSynchronizedTime(loopDuration, syncShift) : elapsed / loopDuration + syncShift) - ) + - 1)) / - 2 + - val2 - ); - } - - static colOscillation(elapsed, loopDuration, syncShift, val1, val2, isSync, xpi = Anime.twoPi) { - const rgbValue1 = Anime.valueToRgb(val1); - const rgbValue2 = Anime.valueToRgb(val2); - - return Anime.rgbToValue( - Math.floor( - Anime.oscillation(elapsed, loopDuration, syncShift, rgbValue1[0], rgbValue2[0], Math.cos, isSync, xpi) - ), - Math.floor( - Anime.oscillation(elapsed, loopDuration, syncShift, rgbValue1[1], rgbValue2[1], Math.cos, isSync, xpi) - ), - Math.floor(Anime.oscillation(elapsed, loopDuration, syncShift, rgbValue1[2], rgbValue2[2], Math.cos, isSync, xpi)) - ); - } - - static getSynchronizedTime(loopDuration, syncShift) { - return Anime._lastTime / loopDuration + syncShift; - } - - static getSynchronizedRotation(loopDuration, syncShift) { - return (360 * ((Anime._lastTime + syncShift) % loopDuration)) / loopDuration; - } - - static getPuppetsByParams(params) { - let puppetArray = []; - Anime._animeMap.forEach((anime, id) => { - if ( - anime.puppet.placeableId === params.placeableId && - anime.puppet.filterId === params.filterId && - (!anime.puppet.hasOwnProperty('filterInternalId') || anime.puppet.filterInternalId === params.filterInternalId) - ) { - puppetArray.push(anime.puppet); - } - }); - return puppetArray; - } - - static addAnimation(anime) { - Anime._animeMap.set(anime.animeId, anime); - Anime._resumeAnimation(); - } - - static removeAnimation(placeableId) { - Anime._animeMap.forEach((anime, id) => { - if (anime.puppet.placeableId === placeableId) { - Anime._animeMap.delete(id); - } - }); - if (Anime._animeMap.size === 0) { - Anime._suspendAnimation(); - } - } - - static removeAnimationByFilterId(placeableId, filterId) { - Anime._animeMap.forEach((anime, id) => { - if (anime.puppet.placeableId === placeableId && anime.puppet.filterId === filterId) { - Anime._animeMap.delete(id); - } - }); - if (Anime._animeMap.size === 0) { - Anime._suspendAnimation(); - } - } - - static resetAnimation() { - Anime._animeMap = new Map(); - Anime._suspended = true; - } - - static tick() { - Anime._lastTime = canvas.app.ticker.lastTime; - Anime._frameTime = Anime._lastTime - Anime._prevTime; - - for (const [id, anime] of Anime._animeMap) { - if (anime.puppet.enabled) { - if (anime.puppet.hasOwnProperty('preComputation') && anime.puppet.placeableImg != null) { - anime.puppet.preComputation(); - } - if (anime.puppet.hasOwnProperty('animated') && !(anime.puppet.animated == null)) { - anime.animate(Anime._frameTime); - } - } - } - - Anime._prevTime = Anime._lastTime; - } - - static _suspendAnimation() { - if (Anime._activated && !Anime._suspended && !isAnimationDisabled()) { - Anime._detachFromTicker(); - } - Anime._suspended = true; - } - - static _resumeAnimation() { - if (Anime._activated && Anime._suspended && !isAnimationDisabled()) { - Anime._attachToTicker(); - } - Anime._suspended = false; - } - - static activateAnimation() { - if (!Anime._activated && !Anime._suspended && !isAnimationDisabled()) { - Anime._attachToTicker(); - } - Anime._activated = true; - } - - static deactivateAnimation() { - if (Anime._activated && !Anime._suspended && !isAnimationDisabled()) { - Anime._detachFromTicker(); - } - Anime._activated = false; - } - - static _attachToTicker() { - canvas.app.ticker.add(Anime.tick, this, PIXI.UPDATE_PRIORITY.LOW + 1); - Anime._lastTime = canvas.app.ticker.lastTime; - Anime._prevTime = Anime._lastTime; - } - - static _detachFromTicker() { - canvas.app.ticker.remove(Anime.tick, this); - Anime._lastTime = 0; - Anime._prevTime = 0; - } - - static getAnimeMap() { - return Anime._animeMap; - } - - initAnimatedInternals(animated) { - Object.keys(animated).forEach((effect) => { - // Internals init - this.initInternals(effect); - }); - } - - initInternals(effect) { - this.elapsedTime[effect] = 0; - this.loopElapsedTime[effect] = 0; - this.pauseBetweenElapsedTime[effect] = 0; - this.loops[effect] = 0; - this.internalLoops[effect] = 0; - this.frameTime[effect] = 0; - this.pauseBetween[effect] = false; - this.ping[effect] = false; - this.shutdown[effect] = false; - } - - hasInternals(effect) { - return this.elapsedTime.hasOwnProperty(effect); - } - - animate(frameTime) { - for (const effect of Object.keys(this.puppet.animated)) { - if (this.animated[effect].active && this.cycleCheck(effect, frameTime)) { - if (this[this.animated[effect].animType] != null) { - this[this.animated[effect].animType](effect); - } - if (this.shutdown[effect]) { - this.animated[effect].active = false; - this.shutdown[effect] = false; - - // persists the value of an effect which is terminated. - this.persistTerminatedEffect(effect); - } else { - this.loopElapsedTime[effect] += frameTime; - this.elapsedTime[effect] += frameTime; - } - } - } - this.autoDisableCheck(); - } - - cycleCheck(effect, frameTime) { - this.frameTime[effect] = frameTime; - - if (this.isPauseBetweenLoop(effect, frameTime)) { - return false; - } - - if (this.loopElapsedTime[effect] > this.animated[effect].loopDuration) { - this.loopElapsedTime[effect] -= this.animated[effect].loopDuration; - this.ping[effect] = true; - - if (this.animated[effect].loops !== Infinity) { - this.loops[effect]++; - this.internalLoops[effect]++; - } - - if (this.loops[effect] >= this.animated[effect].loops) { - // correction to stop exactly on the target value when the last loop end. - this.elapsedTime[effect] = this.internalLoops[effect] * this.animated[effect].loopDuration; - this.loops[effect] = 0; - this.loopElapsedTime[effect] = 0; - this.shutdown[effect] = true; - } else if (this.animated[effect].pauseBetweenDuration > 0) { - this.elapsedTime[effect] = this.animated[effect].loopDuration; - this.pauseBetween[effect] = true; - } - } - return true; - } - - async persistTerminatedEffect(effect) { - if (!(this.puppet.filterOwner === game.data.userId)) { - return; - } - - let animeInfo; - let doInit = true; - let flag = this.puppet.targetPlaceable.document.getFlag('tokenmagic', 'animeInfo'); - - if (flag) { - // fastest than array.find - for (const animeinfo of flag.values()) { - if ( - animeinfo.tmFilterId === this.puppet.filterId && - animeinfo.tmFilterInternalId === this.puppet.filterInternalId && - animeinfo.tmFilterEffect === effect - ) { - if (animeinfo && animeinfo instanceof Object) { - animeinfo.tmFilterEffectValue = this.puppet[effect]; - doInit = false; - break; - } - } - } - } - - if (doInit) { - animeInfo = [ - { - tmFilterId: this.puppet.filterId, - tmFilterInternalId: this.puppet.filterInternalId, - tmFilterEffect: effect, - tmFilterEffectValue: this.puppet[effect], - }, - ]; - - if (flag) flag = flag.concat(animeInfo); - else flag = animeInfo; - } - - flag = duplicate(flag); - await this.puppet.targetPlaceable._TMFXsetAnimeFlag(flag); - } - - autoDisableCheck() { - if (!(this.puppet.autoDisable || this.puppet.autoDestroy)) { - return; - } - if (!(this.puppet.filterOwner === game.data.userId)) { - return; - } - if (this.puppet.enabled === false && !this.puppet.autoDestroy) { - return; - } - - if (Object.values(this.animated).every((animeEffect) => animeEffect.active === false)) { - this.disableOrDestroy(); - } - } - - async disableOrDestroy() { - if (this.puppet == null) return; - const placeable = this.puppet.targetPlaceable; - if (placeable == null) return; - - if (this.puppet.autoDestroy) { - await window.TokenMagic.deleteFilters(placeable, this.puppet.filterId); - } else { - let params = {}; - params.filterType = this.puppet.filterType; - params.filterId = this.puppet.filterId; - params.enabled = false; - await window.TokenMagic.updateFiltersByPlaceable(placeable, [params]); - } - } - - isPauseBetweenLoop(effect, frametime) { - if (this.pauseBetween[effect] && this.animated[effect].pauseBetweenDuration > 0) { - this.pauseBetweenElapsedTime[effect] += frametime; - if (this.pauseBetweenElapsedTime[effect] < this.animated[effect].pauseBetweenDuration) { - return true; - } else { - this.pauseBetweenElapsedTime[effect] = 0; - return (this.pauseBetween[effect] = false); - } - } - return false; - } - - pauseBetweenCheck(effect, frametime) { - if (this.pauseStart[effect] && this.animated[effect].pauseStartDuration > 0) { - this.pauseStartElapsedTime[effect] += frametime; - if (this.pauseStartElapsedTime[effect] < this.animated[effect].pauseStartDuration) { - return false; - } else { - this.pauseStart[effect] = false; - return true; - } - } - } - - moveToward(effect) { - this.puppet[effect] = - ((this.animated[effect].val1 - this.animated[effect].val2) / this.animated[effect].loopDuration) * - this.elapsedTime[effect]; - } - - colorOscillation(effect) { - this.puppet[effect] = Anime.colOscillation( - this.elapsedTime[effect], - this.animated[effect].loopDuration, - this.animated[effect].syncShift, - this.animated[effect].val1, - this.animated[effect].val2, - false - ); - } - - halfColorOscillation(effect) { - this.puppet[effect] = Anime.colOscillation( - this.elapsedTime[effect], - this.animated[effect].loopDuration, - this.animated[effect].syncShift, - this.animated[effect].val1, - this.animated[effect].val2, - false, - Math.PI - ); - } - - syncColorOscillation(effect) { - this.puppet[effect] = Anime.colOscillation( - this.elapsedTime[effect], - this.animated[effect].loopDuration, - this.animated[effect].syncShift, - this.animated[effect].val1, - this.animated[effect].val2, - true - ); - } - - cosOscillation(effect) { - this.puppet[effect] = Anime.oscillation( - this.elapsedTime[effect], - this.animated[effect].loopDuration, - this.animated[effect].syncShift, - this.animated[effect].val1, - this.animated[effect].val2, - Math.cos, - false - ); - } - - halfCosOscillation(effect) { - this.puppet[effect] = Anime.oscillation( - this.elapsedTime[effect], - this.animated[effect].loopDuration, - this.animated[effect].syncShift, - this.animated[effect].val1, - this.animated[effect].val2, - Math.cos, - false, - Math.PI - ); - } - - sinOscillation(effect) { - this.puppet[effect] = Anime.oscillation( - this.elapsedTime[effect], - this.animated[effect].loopDuration, - this.animated[effect].syncShift, - this.animated[effect].val1, - this.animated[effect].val2, - Math.sin, - false - ); - } - - halfSinOscillation(effect) { - this.puppet[effect] = Anime.oscillation( - this.elapsedTime[effect], - this.animated[effect].loopDuration, - this.animated[effect].syncShift, - this.animated[effect].val1, - this.animated[effect].val2, - Math.sin, - false, - Math.PI - ); - } - - chaoticOscillation(effect) { - this.puppet[effect] = Anime.oscillation( - this.elapsedTime[effect], - this.animated[effect].loopDuration, - this.animated[effect].syncShift + Math.random() * this.animated[effect].chaosFactor, - this.animated[effect].val1, - this.animated[effect].val2, - Math.cos, - false - ); - } - - syncCosOscillation(effect) { - this.puppet[effect] = Anime.oscillation( - this.elapsedTime[effect], - this.animated[effect].loopDuration, - this.animated[effect].syncShift, - this.animated[effect].val1, - this.animated[effect].val2, - Math.cos, - true - ); - } - - syncSinOscillation(effect) { - this.puppet[effect] = Anime.oscillation( - this.elapsedTime[effect], - this.animated[effect].loopDuration, - this.animated[effect].syncShift, - this.animated[effect].val1, - this.animated[effect].val2, - Math.sin, - true - ); - } - - syncChaoticOscillation(effect) { - this.puppet[effect] = Anime.oscillation( - this.elapsedTime[effect], - this.animated[effect].loopDuration, - this.animated[effect].syncShift + Math.random() * this.animated[effect].chaosFactor, - this.animated[effect].val1, - this.animated[effect].val2, - Math.cos, - true - ); - } - - rotation(effect) { - const computedRotation = (360 * this.elapsedTime[effect]) / this.animated[effect].loopDuration; - this.puppet[effect] = this.animated[effect].clockWise ? computedRotation : 360 - computedRotation; - } - - syncRotation(effect) { - const computedRotation = Anime.getSynchronizedRotation( - this.animated[effect].loopDuration, - this.animated[effect].syncShift - ); - this.puppet[effect] = this.animated[effect].clockWise ? computedRotation : 360 - computedRotation; - } - - randomNumber(effect) { - const randomNumber = - Math.random() * (this.animated[effect].val2 - this.animated[effect].val1) + this.animated[effect].val1; - if (this.animated[effect].wantInteger) { - this.puppet[effect] = Math.floor(randomNumber); - } else { - this.puppet[effect] = randomNumber; - } - } - - randomNumberPerLoop(effect) { - if (this._ringing(effect)) { - this.randomNumber(effect); - } - } - - randomColor(effect) { - this.puppet[effect] = Math.floor(Math.random() * 16777215); - } - - randomColorPerLoop(effect) { - if (this._ringing(effect)) { - this.randomColor(effect); - } - } - - move(effect) { - this.puppet[effect] += this.animated[effect].speed * this.frameTime[effect]; - } - - _ringing(effect) { - if (this.ping[effect]) { - this.ping[effect] = false; - return true; - } - return false; - } -} - -Anime._lastTime = 0; -Anime._prevTime = 0; -Anime._frameTime = 0; -Anime._animeMap = new Map(); -Anime.twoPi = Math.PI * 2; -Anime._activated = false; -Anime._suspended = true; diff --git a/tokenmagic/fx/filters/CustomFilter.js b/tokenmagic/fx/filters/CustomFilter.js deleted file mode 100644 index a32393c..0000000 --- a/tokenmagic/fx/filters/CustomFilter.js +++ /dev/null @@ -1,73 +0,0 @@ -const _tempRect = new PIXI.Rectangle(); - -export class CustomFilter extends PIXI.Filter { - constructor(...args) { - super(...args); - - if (!this.uniforms.filterMatrix || !this.uniforms.filterMatrixInverse) - this.uniforms.filterMatrix = new PIXI.Matrix(); - - if (!this.uniforms.filterMatrixInverse) this.uniforms.filterMatrixInverse = new PIXI.Matrix(); - } - - apply(filterManager, input, output, clear) { - const filterMatrix = this.uniforms.filterMatrix; - - if (filterMatrix) { - const { sourceFrame, destinationFrame, target } = filterManager.activeState; - - filterMatrix.set(destinationFrame.width, 0, 0, destinationFrame.height, sourceFrame.x, sourceFrame.y); - - const worldTransform = PIXI.Matrix.TEMP_MATRIX; - - const localBounds = target.getLocalBounds(_tempRect); - - if (this.sticky) { - worldTransform.copyFrom(target.transform.worldTransform); - worldTransform.invert(); - - const rotation = target.transform.rotation; - const sin = Math.sin(rotation); - const cos = Math.cos(rotation); - const scaleX = Math.hypot( - cos * worldTransform.a + sin * worldTransform.c, - cos * worldTransform.b + sin * worldTransform.d - ); - const scaleY = Math.hypot( - -sin * worldTransform.a + cos * worldTransform.c, - -sin * worldTransform.b + cos * worldTransform.d - ); - - localBounds.pad(scaleX * this.boundsPadding.x, scaleY * this.boundsPadding.y); - } else { - const transform = target.transform; - worldTransform.a = transform.scale.x; - worldTransform.b = 0; - worldTransform.c = 0; - worldTransform.d = transform.scale.y; - worldTransform.tx = transform.position.x - transform.pivot.x * transform.scale.x; - worldTransform.ty = transform.position.y - transform.pivot.y * transform.scale.y; - worldTransform.prepend(target.parent.transform.worldTransform); - worldTransform.invert(); - - const scaleX = Math.hypot(worldTransform.a, worldTransform.b); - const scaleY = Math.hypot(worldTransform.c, worldTransform.d); - - localBounds.pad(scaleX * this.boundsPadding.x, scaleY * this.boundsPadding.y); - } - - filterMatrix.prepend(worldTransform); - filterMatrix.translate(-localBounds.x, -localBounds.y); - filterMatrix.scale(1.0 / localBounds.width, 1.0 / localBounds.height); - - const filterMatrixInverse = this.uniforms.filterMatrixInverse; - - if (filterMatrixInverse) { - filterMatrixInverse.copyFrom(filterMatrix); - filterMatrixInverse.invert(); - } - } - - filterManager.applyFilter(this, input, output, clear); - } -} diff --git a/tokenmagic/fx/filters/FilterAdjustment.js b/tokenmagic/fx/filters/FilterAdjustment.js deleted file mode 100644 index 7de882c..0000000 --- a/tokenmagic/fx/filters/FilterAdjustment.js +++ /dev/null @@ -1,24 +0,0 @@ -import { Anime } from '../Anime.js'; -import './proto/FilterProto.js'; - -export class FilterAdjustment extends PIXI.filters.AdjustmentFilter { - constructor(params) { - super(); - this.enabled = false; - this.gamma = 1; - this.saturation = 1; - this.contrast = 1; - this.brightness = 1; - this.red = 1; - this.green = 1; - this.blue = 1; - this.alpha = 1; - this.zOrder = 30; - this.animating = {}; - this.setTMParams(params); - if (!this.dummy) { - this.anime = new Anime(this); - this.normalizeTMParams(); - } - } -} diff --git a/tokenmagic/fx/filters/FilterAdvancedBloom.js b/tokenmagic/fx/filters/FilterAdvancedBloom.js deleted file mode 100644 index 7b62732..0000000 --- a/tokenmagic/fx/filters/FilterAdvancedBloom.js +++ /dev/null @@ -1,23 +0,0 @@ -import { Anime } from '../Anime.js'; -import './proto/FilterProto.js'; - -export class FilterXBloom extends PIXI.filters.AdvancedBloomFilter { - constructor(params) { - super(); - - this.enabled = false; - this.threshold = 0.5; - this.bloomScale = 1.0; - this.brightness = 1.0; - this.blur = 4.0; - this.quality = 4.0; - this.zOrder = 40; - - this.animated = {}; - this.setTMParams(params); - if (!this.dummy) { - this.anime = new Anime(this); - this.normalizeTMParams(); - } - } -} diff --git a/tokenmagic/fx/filters/FilterAscii.js b/tokenmagic/fx/filters/FilterAscii.js deleted file mode 100644 index bdfd622..0000000 --- a/tokenmagic/fx/filters/FilterAscii.js +++ /dev/null @@ -1,16 +0,0 @@ -import { Anime } from '../Anime.js'; -import './proto/FilterProto.js'; - -export class FilterAscii extends PIXI.filters.AsciiFilter { - constructor(params) { - super(); - this.size = 8; - this.zOrder = 310; - this.animated = {}; - this.setTMParams(params); - if (!this.dummy) { - this.anime = new Anime(this); - this.normalizeTMParams(); - } - } -} diff --git a/tokenmagic/fx/filters/FilterBevel.js b/tokenmagic/fx/filters/FilterBevel.js deleted file mode 100644 index e3e60ab..0000000 --- a/tokenmagic/fx/filters/FilterBevel.js +++ /dev/null @@ -1,25 +0,0 @@ -import { Anime } from '../Anime.js'; -import './proto/FilterProto.js'; - -export class FilterBevel extends PIXI.filters.BevelFilter { - constructor(params) { - super(); - this.blendMode = PIXI.BLEND_MODES.NORMAL; - this.padding = 10; - this.enabled = false; - this.rotation = 0; - this.thickness = 5; - this.lightColor = 0xffffff; - this.lightAlpha = 0.95; - this.shadowColor = 0x000000; - this.shadowAlpha = 0.95; - this.zOrder = 90; - this.quality = 1; - this.animated = {}; - this.setTMParams(params); - if (!this.dummy) { - this.anime = new Anime(this); - this.normalizeTMParams(); - } - } -} diff --git a/tokenmagic/fx/filters/FilterBlur.js b/tokenmagic/fx/filters/FilterBlur.js deleted file mode 100644 index bef398f..0000000 --- a/tokenmagic/fx/filters/FilterBlur.js +++ /dev/null @@ -1,52 +0,0 @@ -import { Anime } from '../Anime.js'; -import './proto/FilterProto.js'; -import { FilterBlurEx } from './FilterBlurEx.js'; - -export class FilterBlur extends FilterBlurEx { - constructor(params) { - super(); - this.enabled = false; - this.blur = 2; - this.quality = 4; - this.zOrder = 290; - this.repeatEdgePixels = false; - this.animated = {}; - this.setTMParams(params); - if (!this.dummy) { - this.anime = new Anime(this); - this.normalizeTMParams(); - } - } - - get blur() { - return this.strengthX; - } - - set blur(value) { - this.strengthX = this.strengthY = value; - } - - get blurX() { - return this.strengthX; - } - - set blurX(value) { - this.strengthX = value; - } - - get blurY() { - return this.strengthY; - } - - set blurY(value) { - this.strengthY = value; - } - - calculatePadding() { - const scale = this.targetPlaceable.worldTransform.a; - this.blurXFilter.blur = scale * this.strengthX; - this.blurYFilter.blur = scale * this.strengthY; - this.updatePadding(); - super.calculatePadding(); - } -} diff --git a/tokenmagic/fx/filters/FilterBlurEx.js b/tokenmagic/fx/filters/FilterBlurEx.js deleted file mode 100644 index 341c69d..0000000 --- a/tokenmagic/fx/filters/FilterBlurEx.js +++ /dev/null @@ -1,311 +0,0 @@ -import { CustomFilter } from './CustomFilter.js'; - -export class FilterBlurEx extends CustomFilter { - blurXFilter; - blurYFilter; - - _repeatEdgePixels; - - constructor(strength = 8, quality = 4, resolution = PIXI.settings.FILTER_RESOLUTION, kernelSize = 5) { - super(); - - this.blurXFilter = new BlurFilterPassEx(true, strength, quality, resolution, kernelSize); - this.blurYFilter = new BlurFilterPassEx(false, strength, quality, resolution, kernelSize); - - this.resolution = resolution; - this.quality = quality; - this.blur = strength; - - this.repeatEdgePixels = false; - } - - apply(filterManager, input, output, clearMode) { - const xStrength = Math.abs(this.blurXFilter.strength); - const yStrength = Math.abs(this.blurYFilter.strength); - - if (xStrength && yStrength) { - const renderTarget = filterManager.getFilterTexture(); - - this.blurXFilter.apply(filterManager, input, renderTarget, PIXI.CLEAR_MODES.CLEAR); - this.blurYFilter.apply(filterManager, renderTarget, output, clearMode); - - filterManager.returnFilterTexture(renderTarget); - } else if (yStrength) { - this.blurYFilter.apply(filterManager, input, output, clearMode); - } else { - this.blurXFilter.apply(filterManager, input, output, clearMode); - } - } - - updatePadding() { - if (this._repeatEdgePixels) { - this.padding = 0; - } else { - this.padding = Math.max(Math.abs(this.blurXFilter.strength), Math.abs(this.blurYFilter.strength)) * 2; - } - } - - get blur() { - return this.blurXFilter.blur; - } - - set blur(value) { - this.blurXFilter.blur = this.blurYFilter.blur = value; - this.updatePadding(); - } - - get quality() { - return this.blurXFilter.quality; - } - - set quality(value) { - this.blurXFilter.quality = this.blurYFilter.quality = value; - } - - get blurX() { - return this.blurXFilter.blur; - } - - set blurX(value) { - this.blurXFilter.blur = value; - this.updatePadding(); - } - - get blurY() { - return this.blurYFilter.blur; - } - - set blurY(value) { - this.blurYFilter.blur = value; - this.updatePadding(); - } - - get blendMode() { - return this.blurYFilter.blendMode; - } - - set blendMode(value) { - this.blurYFilter.blendMode = value; - } - - get repeatEdgePixels() { - return this._repeatEdgePixels; - } - - set repeatEdgePixels(value) { - this._repeatEdgePixels = value; - this.updatePadding(); - } -} - -export class BlurFilterPassEx extends CustomFilter { - horizontal; - strength; - passes; - _quality; - - constructor(horizontal, strength = 8, quality = 4, resolution = PIXI.settings.FILTER_RESOLUTION, kernelSize = 5) { - const vertSrc = generateBlurVertSource(kernelSize, horizontal); - const fragSrc = generateBlurFragSource(kernelSize); - - super( - // vertex shader - vertSrc, - // fragment shader - fragSrc - ); - - this.horizontal = horizontal; - - this.resolution = resolution; - - this._quality = 0; - - this.quality = quality; - - this.blur = strength; - } - - apply(filterManager, input, output, clearMode) { - if (output) { - if (this.horizontal) { - this.uniforms.strength = (1 / output.width) * (output.width / input.width); - } else { - this.uniforms.strength = (1 / output.height) * (output.height / input.height); - } - } else { - if (this.horizontal) { - this.uniforms.strength = (1 / filterManager.renderer.width) * (filterManager.renderer.width / input.width); - } else { - this.uniforms.strength = (1 / filterManager.renderer.height) * (filterManager.renderer.height / input.height); - } - } - - // screen space! - this.uniforms.strength *= this.strength; - this.uniforms.strength /= this.passes; - - if (this.passes === 1) { - filterManager.applyFilter(this, input, output, clearMode); - } else { - const renderTarget = filterManager.getFilterTexture(); - const renderer = filterManager.renderer; - - let flip = input; - let flop = renderTarget; - - this.state.blend = false; - filterManager.applyFilter(this, flip, flop, PIXI.CLEAR_MODES.CLEAR); - - for (let i = 1; i < this.passes - 1; i++) { - filterManager.bindAndClear(flip, PIXI.CLEAR_MODES.BLIT); - - this.uniforms.uSampler = flop; - - const temp = flop; - - flop = flip; - flip = temp; - - renderer.shader.bind(this); - renderer.geometry.draw(5); - } - - this.state.blend = true; - filterManager.applyFilter(this, flop, output, clearMode); - filterManager.returnFilterTexture(renderTarget); - } - } - - get blur() { - return this.strength; - } - - set blur(value) { - this.padding = 1 + Math.abs(value) * 2; - this.strength = value; - } - - get quality() { - return this._quality; - } - - set quality(value) { - this._quality = value; - this.passes = value; - } -} - -const GAUSSIAN_VALUES = { - 5: [0.153388, 0.221461, 0.250301], - 7: [0.071303, 0.131514, 0.189879, 0.214607], - 9: [0.028532, 0.067234, 0.124009, 0.179044, 0.20236], - 11: [0.0093, 0.028002, 0.065984, 0.121703, 0.175713, 0.198596], - 13: [0.002406, 0.009255, 0.027867, 0.065666, 0.121117, 0.174868, 0.197641], - 15: [0.000489, 0.002403, 0.009246, 0.02784, 0.065602, 0.120999, 0.174697, 0.197448], -}; - -const fragTemplate = [ - 'varying vec2 vBlurTexCoords[%size%];', - 'uniform sampler2D uSampler;', - - 'void main(void)', - '{', - ' gl_FragColor = vec4(0.0);', - ' %blur%', - '}', -].join('\n'); - -export function generateBlurFragSource(kernelSize) { - const kernel = GAUSSIAN_VALUES[kernelSize]; - const halfLength = kernel.length; - - let fragSource = fragTemplate; - - let blurLoop = ''; - const template = 'gl_FragColor += texture2D(uSampler, vBlurTexCoords[%index%]) * %value%;'; - let value; - - for (let i = 0; i < kernelSize; i++) { - let blur = template.replace('%index%', i.toString()); - - value = i; - - if (i >= halfLength) { - value = kernelSize - i - 1; - } - - blur = blur.replace('%value%', kernel[value].toString()); - - blurLoop += blur; - blurLoop += '\n'; - } - - fragSource = fragSource.replace('%blur%', blurLoop); - fragSource = fragSource.replace('%size%', kernelSize.toString()); - - return fragSource; -} - -const vertTemplate = ` - attribute vec2 aVertexPosition; - uniform mat3 projectionMatrix; - uniform float strength; - varying vec2 vBlurTexCoords[%size%]; - uniform vec4 inputSize; - uniform vec4 outputFrame; - vec4 filterVertexPosition( void ) - { - vec2 position = aVertexPosition * max(outputFrame.zw, vec2(0.)) + outputFrame.xy; - return vec4((projectionMatrix * vec3(position, 1.0)).xy, 0.0, 1.0); - } - vec2 filterTextureCoord( void ) - { - return aVertexPosition * (outputFrame.zw * inputSize.zw); - } - void main(void) - { - gl_Position = filterVertexPosition(); - vec2 textureCoord = filterTextureCoord(); - %blur% - }`; - -export function generateBlurVertSource(kernelSize, x) { - const halfLength = Math.ceil(kernelSize / 2); - - let vertSource = vertTemplate; - - let blurLoop = ''; - let template; - - if (x) { - template = 'vBlurTexCoords[%index%] = textureCoord + vec2(%sampleIndex% * strength, 0.0);'; - } else { - template = 'vBlurTexCoords[%index%] = textureCoord + vec2(0.0, %sampleIndex% * strength);'; - } - - for (let i = 0; i < kernelSize; i++) { - let blur = template.replace('%index%', i.toString()); - - blur = blur.replace('%sampleIndex%', `${i - (halfLength - 1)}.0`); - - blurLoop += blur; - blurLoop += '\n'; - } - - vertSource = vertSource.replace('%blur%', blurLoop); - vertSource = vertSource.replace('%size%', kernelSize.toString()); - - return vertSource; -} - -export function getMaxKernelSize(gl) { - const maxVaryings = PIXI.gl.getParameter(PIXI.gl.MAX_VARYING_VECTORS); - let kernelSize = 15; - - while (kernelSize > maxVaryings) { - kernelSize -= 2; - } - - return kernelSize; -} diff --git a/tokenmagic/fx/filters/FilterBulgePinch.js b/tokenmagic/fx/filters/FilterBulgePinch.js deleted file mode 100644 index 80473f1..0000000 --- a/tokenmagic/fx/filters/FilterBulgePinch.js +++ /dev/null @@ -1,31 +0,0 @@ -import { Anime } from '../Anime.js'; -import './proto/FilterProto.js'; - -export class FilterBulgePinch extends PIXI.filters.BulgePinchFilter { - constructor(params) { - super(); - - this.strength = 0; - this.radiusPercent = 100; - this.zOrder = 140; - this.autoFit = false; - - this.animated = {}; - this.setTMParams(params); - if (!this.dummy) { - this.anime = new Anime(this); - this.normalizeTMParams(); - } - - // Anchor point - this.center = [0.5, 0.5]; - } - - handleTransform() { - this.radius = - (Math.max(this.placeableImg.width, this.placeableImg.height) * - this.targetPlaceable.worldTransform.a * - this.radiusPercent) / - 200; - } -} diff --git a/tokenmagic/fx/filters/FilterCRT.js b/tokenmagic/fx/filters/FilterCRT.js deleted file mode 100644 index 87a8f6e..0000000 --- a/tokenmagic/fx/filters/FilterCRT.js +++ /dev/null @@ -1,23 +0,0 @@ -import { Anime } from '../Anime.js'; -import './proto/FilterProto.js'; - -export class FilterCRT extends PIXI.filters.CRTFilter { - constructor(params) { - super(); - this.curvature = 1.0; - this.lineWidth = 1.0; - this.lineContrast = 0.25; - this.verticalLine = false; - this.noise = 0.08; - this.noiseSize = 1.0; - this.seed = 0; - this.vignetting = 0; - this.zOrder = 320; - this.animated = {}; - this.setTMParams(params); - if (!this.dummy) { - this.anime = new Anime(this); - this.normalizeTMParams(); - } - } -} diff --git a/tokenmagic/fx/filters/FilterDDTint.js b/tokenmagic/fx/filters/FilterDDTint.js deleted file mode 100644 index 1d0bc45..0000000 --- a/tokenmagic/fx/filters/FilterDDTint.js +++ /dev/null @@ -1,27 +0,0 @@ -import { customVertex2D } from '../glsl/vertexshaders/customvertex2D.js'; -import { CustomFilter } from './CustomFilter.js'; -import { Anime } from '../Anime.js'; -import './proto/FilterProto.js'; -import { ddTint } from '../glsl/fragmentshaders/ddtint.js'; - -export class FilterDDTint extends CustomFilter { - constructor(params) { - super(customVertex2D, ddTint); - this.tint = [1, 0, 0]; - this.zOrder = 100; - this.animating = {}; - this.setTMParams(params); - if (!this.dummy) { - this.anime = new Anime(this); - this.normalizeTMParams(); - } - } - - get tint() { - return this.uniforms.tint; - } - - set tint(value) { - this.uniforms.tint = value; - } -} diff --git a/tokenmagic/fx/filters/FilterDistortion.js b/tokenmagic/fx/filters/FilterDistortion.js deleted file mode 100644 index fa5aef4..0000000 --- a/tokenmagic/fx/filters/FilterDistortion.js +++ /dev/null @@ -1,146 +0,0 @@ -import { Anime } from '../Anime.js'; -import './proto/FilterProto.js'; -import { fixPath } from '../../module/tokenmagic.js'; - -export class FilterDistortion extends PIXI.filters.DisplacementFilter { - constructor(params) { - // Loading distortion sprite - var displacementSpriteMask; - var spriteMaskPath; - spriteMaskPath = params.hasOwnProperty('maskPath') - ? fixPath(params.maskPath) - : 'modules/tokenmagic/fx/assets/distortion-1.png'; - displacementSpriteMask = PIXI.Sprite.from(spriteMaskPath); - super(displacementSpriteMask); - - // Configuring distortion sprite - this.sprite = displacementSpriteMask; - this.wrapMode = PIXI.WRAP_MODES.REPEAT; - this.position = new PIXI.Point(); - this.skew = new PIXI.Point(); - this.pivot = new PIXI.Point(); - this.anchorSet = 0.5; - this.transition = null; - this.padding = 15; // conf - this.enabled = false; - this.maskSpriteX = 0; - this.maskSpriteY = 0; - this.maskSpriteScaleX = 4; - this.maskSpriteScaleY = 4; - this.maskSpriteSkewX = 0; - this.maskSpriteSkewY = 0; - this.maskSpriteRotation = 0; - this.zOrder = 4000; - this.sticky = true; - - this.animated = {}; - this.setTMParams(params); - this.maskPath = spriteMaskPath; - if (!this.dummy) { - this.anime = new Anime(this); - this.normalizeTMParams(); - this.sprite.anchor.set(this.anchorSet); - this.sprite.texture.baseTexture.wrapMode = this.wrapMode; - } - } - - set maskSpriteX(value) { - this.position.x = value; - } - - set maskSpriteY(value) { - this.position.y = value; - } - - get maskSpriteX() { - return this.position.x; - } - - get maskSpriteY() { - return this.position.y; - } - - set maskSpriteScaleX(value) { - this.scale.x = value; - } - - set maskSpriteScaleY(value) { - this.scale.y = value; - } - - get maskSpriteScaleX() { - return this.scale.x; - } - - get maskSpriteScaleY() { - return this.scale.y; - } - - set maskSpriteRotation(value) { - this.rotation = value; - } - - get maskSpriteRotation() { - return this.rotation; - } - - set maskSpriteSkewX(value) { - this.skew.x = value; - } - - get maskSpriteSkewX() { - return this.skew.x; - } - - set maskSpriteSkewY(value) { - this.skew.y = value; - } - - get maskSpriteSkewY() { - return this.skew.y; - } - - set maskSpritePivotX(value) { - this.pivot.x = value; - } - - get maskSpritePivotX() { - return this.pivot.x; - } - - set maskSpritePivotY(value) { - this.pivot.y = value; - } - - get maskSpritePivotY() { - return this.pivot.y; - } - - handleTransform() { - this.sprite.position.x = this.targetPlaceable.x + this.placeableImg.x + this.position.x; - this.sprite.position.y = this.targetPlaceable.y + this.placeableImg.y + this.position.y; - this.sprite.skew.x = this.skew.x; - this.sprite.skew.x = this.skew.y; - this.sprite.rotation = this.rotation; - this.sprite.pivot.x = this.pivot.x; - this.sprite.pivot.y = this.pivot.y; - - if (this.sticky) this.sprite.rotation += this.placeableImg.rotation; - - this.sprite.transform.updateTransform(canvas.stage.transform); - } - - apply(filterManager, input, output, clear) { - this.uniforms.filterMatrix = filterManager.calculateSpriteMatrix(this.maskMatrix, this.maskSprite); - this.uniforms.scale.x = this.scale.x; - this.uniforms.scale.y = this.scale.y; - - const wt = this.maskSprite.worldTransform; - this.uniforms.rotation[0] = wt.a; - this.uniforms.rotation[1] = wt.b; - this.uniforms.rotation[2] = wt.c; - this.uniforms.rotation[3] = wt.d; - - filterManager.applyFilter(this, input, output, clear); - } -} diff --git a/tokenmagic/fx/filters/FilterDot.js b/tokenmagic/fx/filters/FilterDot.js deleted file mode 100644 index 3866a3e..0000000 --- a/tokenmagic/fx/filters/FilterDot.js +++ /dev/null @@ -1,18 +0,0 @@ -import { Anime } from '../Anime.js'; -import './proto/FilterProto.js'; - -export class FilterDot extends PIXI.filters.DotFilter { - constructor(params) { - super(); - this.scale = 1; - this.angle = 5; - this.grayscale = true; - this.zOrder = 330; - this.animated = {}; - this.setTMParams(params); - if (!this.dummy) { - this.anime = new Anime(this); - this.normalizeTMParams(); - } - } -} diff --git a/tokenmagic/fx/filters/FilterDropShadow.js b/tokenmagic/fx/filters/FilterDropShadow.js deleted file mode 100644 index ea39689..0000000 --- a/tokenmagic/fx/filters/FilterDropShadow.js +++ /dev/null @@ -1,29 +0,0 @@ -import { Anime } from '../Anime.js'; -import './proto/FilterProto.js'; -import { FilterDropShadowEx } from './FilterDropShadowEx.js'; - -export class FilterDropShadow extends FilterDropShadowEx { - constructor(params) { - super(); - this.enabled = false; - this.rotation = 45; - this.distance = 5; - this.color = 0x000000; - this.alpha = 0.5; - this.shadowOnly = false; - this.blur = 2; - this.quality = 3; - this.padding = 10; - this.zOrder = 110; - this.animated = {}; - this.resolution = game.settings.get('core', 'pixelRatioResolutionScaling') - ? window.devicePixelRatio - : PIXI.settings.FILTER_RESOLUTION; - this.setTMParams(params); - if (!this.dummy) { - this.anime = new Anime(this); - this.normalizeTMParams(); - } - this.autoFit = false; - } -} diff --git a/tokenmagic/fx/filters/FilterDropShadowEx.js b/tokenmagic/fx/filters/FilterDropShadowEx.js deleted file mode 100644 index 44cf1f1..0000000 --- a/tokenmagic/fx/filters/FilterDropShadowEx.js +++ /dev/null @@ -1,146 +0,0 @@ -import { CustomFilter } from './CustomFilter.js'; -import { dropShadow } from '../glsl/fragmentshaders/dropshadow.js'; -import { customVertex2D } from '../glsl/vertexshaders/customvertex2D.js'; -import './proto/FilterProto.js'; - -export class FilterDropShadowEx extends CustomFilter { - shadowOnly; - angle = 45; - - _distance = 5; - _resolution = PIXI.settings.FILTER_RESOLUTION; - _tintFilter; - _blurFilter; - - constructor(options = {}) { - super(); - - const opt = options ? { ...FilterDropShadowEx.defaults, ...options } : FilterDropShadowEx.defaults; - - const { kernels, blur, quality, resolution } = opt; - - this._tintFilter = new PIXI.Filter(customVertex2D, dropShadow); - this._tintFilter.uniforms.color = new Float32Array(4); - this._tintFilter.uniforms.shift = new PIXI.Point(); - this._tintFilter.resolution = resolution; - this._blurFilter = kernels - ? new PIXI.filters.KawaseBlurFilter(kernels) - : new PIXI.filters.KawaseBlurFilter(blur, quality); - - this._pixelSize = 1.0; - this.resolution = resolution; - - const { shadowOnly, rotation, distance, alpha, color } = opt; - - this.shadowOnly = shadowOnly; - this.rotation = rotation; - this.distance = distance; - this.alpha = alpha; - this.color = color; - } - - apply(filterManager, input, output, clear) { - this._updateShiftAndScale(); - const target = filterManager.getFilterTexture(); - - this._tintFilter.apply(filterManager, input, target, 1); - this._blurFilter.apply(filterManager, target, output, clear); - - if (this.shadowOnly !== true) { - filterManager.applyFilter(this, input, output, 0); - } - - filterManager.returnFilterTexture(target); - } - - _updateShiftAndScale() { - const scale = this.targetPlaceable?.worldTransform.a ?? 1.0; - this._tintFilter.uniforms.shift.set( - this.distance * Math.cos(this.angle) * scale, - this.distance * Math.sin(this.angle) * scale - ); - this._pixelSize = Math.max(1.0, 1.0 * scale); - } - - get resolution() { - return this._resolution; - } - set resolution(value) { - this._resolution = value; - - if (this._tintFilter) { - this._tintFilter.resolution = value; - } - if (this._blurFilter) { - this._blurFilter.resolution = value; - } - } - - get distance() { - return this._distance; - } - set distance(value) { - this._distance = value; - } - - get rotation() { - return this.angle / PIXI.DEG_TO_RAD; - } - set rotation(value) { - this.angle = value * PIXI.DEG_TO_RAD; - } - - get alpha() { - return this._tintFilter.uniforms.alpha; - } - set alpha(value) { - this._tintFilter.uniforms.alpha = value; - } - - get color() { - return PIXI.utils.rgb2hex(this._tintFilter.uniforms.color); - } - set color(value) { - new PIXI.Color(value).toRgbArray(this._tintFilter.uniforms.color); - } - - get kernels() { - return this._blurFilter.kernels; - } - set kernels(value) { - this._blurFilter.kernels = value; - } - - get blur() { - return this._blurFilter.blur; - } - set blur(value) { - this._blurFilter.blur = value; - } - - get quality() { - return this._blurFilter.quality; - } - set quality(value) { - this._blurFilter.quality = value; - } - - get _pixelSize() { - return this._blurFilter.pixelSize; - } - set _pixelSize(value) { - this._blurFilter.pixelSize = value; - } -} - -FilterDropShadowEx.defaults = { - rotation: 45, - distance: 5, - color: 0x000000, - alpha: 0.5, - shadowOnly: false, - kernels: null, - blur: 2, - quality: 3, - resolution: PIXI.settings.FILTER_RESOLUTION, -}; diff --git a/tokenmagic/fx/filters/FilterElectric.js b/tokenmagic/fx/filters/FilterElectric.js deleted file mode 100644 index fd57db8..0000000 --- a/tokenmagic/fx/filters/FilterElectric.js +++ /dev/null @@ -1,70 +0,0 @@ -import { zapElectricity } from '../glsl/fragmentshaders/electricity.js'; -import { customVertex2D } from '../glsl/vertexshaders/customvertex2D.js'; -import { CustomFilter } from './CustomFilter.js'; -import { Anime } from '../Anime.js'; -import './proto/FilterProto.js'; - -export class FilterElectric extends CustomFilter { - constructor(params) { - let { time, blend, color } = Object.assign({}, FilterElectric.defaults, params); - - var shaderFragment; - if (params.hasOwnProperty('intensity') && typeof params.intensity === 'number') { - var intensityVal = Math.floor(params.intensity); - shaderFragment = zapElectricity.replace('#define INTENSITY 5', '#define INTENSITY ' + intensityVal); - } else { - shaderFragment = zapElectricity; - } - - super(customVertex2D, shaderFragment); - - this.uniforms.color = new Float32Array([1.0, 1.0, 1.0, 1.0]); - this.uniforms.blend = 2; - - Object.assign(this, { - time, - blend, - color, - }); - - this.zOrder = 160; - this.animated = {}; - this.setTMParams(params); - if (!this.dummy) { - this.anime = new Anime(this); - this.normalizeTMParams(); - } - - this.quality = 0.5; - } - - get time() { - return this.uniforms.time; - } - - set time(value) { - this.uniforms.time = value; - } - - get color() { - return PIXI.utils.rgb2hex(this.uniforms.color); - } - - set color(value) { - new PIXI.Color(value).toRgbArray(this.uniforms.color); - } - - get blend() { - return this.uniforms.blend; - } - - set blend(value) { - this.uniforms.blend = Math.floor(value); - } -} - -FilterElectric.defaults = { - time: 0.0, - blend: 1, - color: 0xffffff, -}; diff --git a/tokenmagic/fx/filters/FilterFire.js b/tokenmagic/fx/filters/FilterFire.js deleted file mode 100644 index 41b0686..0000000 --- a/tokenmagic/fx/filters/FilterFire.js +++ /dev/null @@ -1,127 +0,0 @@ -import { burnFire } from '../glsl/fragmentshaders/fire.js'; -import { customVertex2D } from '../glsl/vertexshaders/customvertex2D.js'; -import { CustomFilter } from './CustomFilter.js'; -import { Anime } from '../Anime.js'; -import './proto/FilterProto.js'; - -export class FilterFire extends CustomFilter { - constructor(params) { - let { time, color, amplitude, intensity, fireBlend, blend, anchorX, anchorY, alphaDiscard } = Object.assign( - {}, - FilterFire.defaults, - params - ); - - // using specific vertex shader and fragment shader - super(customVertex2D, burnFire); - - this.uniforms.color = new Float32Array([1.0, 1.0, 1.0]); - this.uniforms.anchor = new Float32Array([1.0, 1.0]); - - Object.assign(this, { - time, - color, - amplitude, - intensity, - fireBlend, - blend, - anchorX, - anchorY, - alphaDiscard, - }); - - this.zOrder = 150; - this.animated = {}; - this.setTMParams(params); - if (!this.dummy) { - this.anime = new Anime(this); - this.normalizeTMParams(); - } - } - - get time() { - return this.uniforms.time; - } - - set time(value) { - this.uniforms.time = value; - } - - get color() { - return PIXI.utils.rgb2hex(this.uniforms.color); - } - - set color(value) { - new PIXI.Color(value).toRgbArray(this.uniforms.color); - } - - get amplitude() { - return this.uniforms.amplitude; - } - - set amplitude(value) { - this.uniforms.amplitude = value; - } - - get intensity() { - return this.uniforms.intensity; - } - - set intensity(value) { - this.uniforms.intensity = value; - } - - get fireBlend() { - return this.uniforms.fireBlend; - } - - set fireBlend(value) { - this.uniforms.fireBlend = Math.floor(value); - } - - get blend() { - return this.uniforms.blend; - } - - set blend(value) { - this.uniforms.blend = Math.floor(value); - } - - get anchorX() { - return this.uniforms.anchor[0]; - } - - set anchorX(value) { - this.uniforms.anchor[0] = value; - } - - get anchorY() { - return this.uniforms.anchor[1]; - } - - set anchorY(value) { - this.uniforms.anchor[1] = value; - } - - get alphaDiscard() { - return this.uniforms.alphaDiscard; - } - - set alphaDiscard(value) { - if (!(value == null) && typeof value === 'boolean') { - this.uniforms.alphaDiscard = value; - } - } -} - -FilterFire.defaults = { - time: 0, - color: 0xffffff, - amplitude: 1, - intensity: 1, - fireBlend: 1, - blend: 2, - anchorX: 1, - anchorY: 1, - alphaDiscard: false, -}; diff --git a/tokenmagic/fx/filters/FilterFlood.js b/tokenmagic/fx/filters/FilterFlood.js deleted file mode 100644 index 961890f..0000000 --- a/tokenmagic/fx/filters/FilterFlood.js +++ /dev/null @@ -1,115 +0,0 @@ -import { seaFlood } from '../glsl/fragmentshaders/flood.js'; -import { customVertex2D } from '../glsl/vertexshaders/customvertex2D.js'; -import { CustomFilter } from './CustomFilter.js'; -import { Anime } from '../Anime.js'; -import './proto/FilterProto.js'; - -export class FilterFlood extends CustomFilter { - constructor(params) { - let { time, scale, glint, billowy, color, shiftX, shiftY, tintIntensity } = Object.assign( - {}, - FilterFlood.defaults, - params - ); - - // using specific vertex shader and fragment shader - super(customVertex2D, seaFlood); - - this.uniforms.waterColor = new Float32Array([0.0, 0.18, 0.54]); - this.uniforms.shift = new Float32Array([0.0, 0.0]); - - Object.assign(this, { - time, - scale, - glint, - billowy, - color, - shiftX, - shiftY, - tintIntensity, - }); - - this.zOrder = 170; - this.animated = {}; - this.setTMParams(params); - if (!this.dummy) { - this.anime = new Anime(this); - this.normalizeTMParams(); - } - } - - get time() { - return this.uniforms.time; - } - - set time(value) { - this.uniforms.time = value; - } - - get color() { - return PIXI.utils.rgb2hex(this.uniforms.waterColor); - } - - set color(value) { - new PIXI.Color(value).toRgbArray(this.uniforms.waterColor); - } - - get scale() { - return this.uniforms.scale; - } - - set scale(value) { - this.uniforms.scale = value; - } - - get glint() { - return this.uniforms.glint; - } - - set glint(value) { - this.uniforms.glint = value; - } - - get billowy() { - return this.uniforms.billowy; - } - - set billowy(value) { - this.uniforms.billowy = value; - } - - get tintIntensity() { - return this.uniforms.tintIntensity; - } - - set tintIntensity(value) { - this.uniforms.tintIntensity = value; - } - - get shiftX() { - return this.uniforms.shift[0]; - } - - set shiftX(value) { - this.uniforms.shift[0] = value; - } - - get shiftY() { - this.uniforms.shift[1]; - } - - set shiftY(value) { - this.uniforms.shift[1] = value; - } -} - -FilterFlood.defaults = { - time: 0, - glint: 0.5, - scale: 70, - billowy: 0.5, - color: 0x0020a9, - shiftX: 0, - shiftY: 0, - tintIntensity: 0.2, -}; diff --git a/tokenmagic/fx/filters/FilterFog.js b/tokenmagic/fx/filters/FilterFog.js deleted file mode 100644 index e1b6bb7..0000000 --- a/tokenmagic/fx/filters/FilterFog.js +++ /dev/null @@ -1,80 +0,0 @@ -import { innerFog } from '../glsl/fragmentshaders/fog.js'; -import { customVertex2D } from '../glsl/vertexshaders/customvertex2D.js'; -import { CustomFilter } from './CustomFilter.js'; -import { Anime } from '../Anime.js'; - -export class FilterFog extends CustomFilter { - constructor(params) { - let { time, color, density, dimX, dimY } = Object.assign({}, FilterFog.defaults, params); - - // specific vertex and fragment shaders - super(customVertex2D, innerFog); - - this.uniforms.color = new Float32Array([1.0, 0.4, 0.1, 0.55]); - this.uniforms.dimensions = new Float32Array([1.0, 1.0]); - - Object.assign(this, { - time, - color, - density, - dimX, - dimY, - }); - - this.zOrder = 190; - this.animated = {}; - this.setTMParams(params); - if (!this.dummy) { - this.anime = new Anime(this); - this.normalizeTMParams(); - } - } - - get time() { - return this.uniforms.time; - } - - set time(value) { - this.uniforms.time = value; - } - - get color() { - return PIXI.utils.rgb2hex(this.uniforms.color); - } - - set color(value) { - new PIXI.Color(value).toRgbArray(this.uniforms.color); - } - - get density() { - return this.uniforms.density; - } - - set density(value) { - this.uniforms.density = value; - } - - get dimX() { - return this.uniforms.dimensions[0]; - } - - set dimX(value) { - this.uniforms.dimensions[0] = value; - } - - get dimY() { - return this.uniforms.dimensions[1]; - } - - set dimY(value) { - this.uniforms.dimensions[1] = value; - } -} - -FilterFog.defaults = { - time: 0.0, - color: 0xffffff, - density: 0.5, - dimX: 1.0, - dimY: 1.0, -}; diff --git a/tokenmagic/fx/filters/FilterForceField.js b/tokenmagic/fx/filters/FilterForceField.js deleted file mode 100644 index 93f5eb6..0000000 --- a/tokenmagic/fx/filters/FilterForceField.js +++ /dev/null @@ -1,201 +0,0 @@ -import { forceField } from '../glsl/fragmentshaders/forcefield.js'; -import { customVertex2D } from '../glsl/vertexshaders/customvertex2D.js'; -import { CustomFilter } from './CustomFilter.js'; -import { Anime } from '../Anime.js'; -import './proto/FilterProto.js'; - -export class FilterForceField extends CustomFilter { - constructor(params) { - let { - time, - color, - lightAlpha, - blend, - shieldType, - posLightX, - posLightY, - lightSize, - scale, - intensity, - radius, - hideRadius, - chromatic, - discardThreshold, - alphaDiscard, - } = Object.assign({}, FilterForceField.defaults, params); - - // using specific vertex shader and fragment shader - super(customVertex2D, forceField); - - this.uniforms.color = new Float32Array([1.0, 1.0, 1.0]); - this.uniforms.posLight = new Float32Array([1.0, 1.0]); - - Object.assign(this, { - time, - color, - lightAlpha, - blend, - shieldType, - posLightX, - posLightY, - lightSize, - scale, - intensity, - radius, - hideRadius, - chromatic, - discardThreshold, - alphaDiscard, - }); - - this.zOrder = 2000; - this.animated = {}; - this.setTMParams(params); - if (!this.dummy) { - this.anime = new Anime(this); - this.normalizeTMParams(); - } - } - - get time() { - return this.uniforms.time; - } - - set time(value) { - this.uniforms.time = value; - } - - get color() { - return PIXI.utils.rgb2hex(this.uniforms.color); - } - - set color(value) { - new PIXI.Color(value).toRgbArray(this.uniforms.color); - } - - get blend() { - return this.uniforms.blend; - } - - set blend(value) { - this.uniforms.blend = Math.floor(value); - } - - get lightAlpha() { - return this.uniforms.lightColorAlpha; - } - - set lightAlpha(value) { - this.uniforms.lightColorAlpha = value; - } - - get shieldType() { - return this.uniforms.shieldType; - } - - set shieldType(value) { - this.uniforms.shieldType = Math.floor(value); - } - - get posLightX() { - return this.uniforms.posLight[0]; - } - - set posLightX(value) { - this.uniforms.posLight[0] = value; - } - - get posLightY() { - return this.uniforms.posLight[1]; - } - - set posLightY(value) { - this.uniforms.posLight[1] = value; - } - - get lightSize() { - return this.uniforms.lightSize; - } - - set lightSize(value) { - this.uniforms.lightSize = value; - } - - get scale() { - return this.uniforms.scale; - } - - set scale(value) { - this.uniforms.scale = value; - } - - get intensity() { - return this.uniforms.intensity; - } - - set intensity(value) { - this.uniforms.intensity = value; - } - - get radius() { - return this.uniforms.radius; - } - - set radius(value) { - this.uniforms.radius = value; - } - - get hideRadius() { - return this.uniforms.hideRadius; - } - - set hideRadius(value) { - this.uniforms.hideRadius = value; - } - - get discardThreshold() { - return this.uniforms.discardThreshold; - } - - set discardThreshold(value) { - this.uniforms.discardThreshold = value; - } - - get alphaDiscard() { - return this.uniforms.alphaDiscard; - } - - set alphaDiscard(value) { - if (!(value == null) && typeof value === 'boolean') { - this.uniforms.alphaDiscard = value; - } - } - - get chromatic() { - return this.uniforms.chromatic; - } - - set chromatic(value) { - if (!(value == null) && typeof value === 'boolean') { - this.uniforms.chromatic = value; - } - } -} - -FilterForceField.defaults = { - time: 0, - color: 0xbbbbbb, - lightAlpha: 1.0, - blend: 2, - shieldType: 1, - posLightX: 0.65, - posLightY: 0.25, - lightSize: 0.483, - scale: 1, - intensity: 1, - radius: 1, - hideRadius: 0, - chromatic: false, - discardThreshold: 0.25, - alphaDiscard: false, -}; diff --git a/tokenmagic/fx/filters/FilterFumes.js b/tokenmagic/fx/filters/FilterFumes.js deleted file mode 100644 index fd96747..0000000 --- a/tokenmagic/fx/filters/FilterFumes.js +++ /dev/null @@ -1,81 +0,0 @@ -import { fumes } from '../glsl/fragmentshaders/fumes.js'; -import { customVertex2D } from '../glsl/vertexshaders/customvertex2D.js'; -import { CustomFilter } from './CustomFilter.js'; -import { Anime } from '../Anime.js'; -import './proto/FilterProto.js'; - -export class FilterFumes extends CustomFilter { - constructor(params) { - let { time, color, blend, dimX, dimY } = Object.assign({}, FilterFumes.defaults, params); - - // using specific vertex shader and fragment shader - super(customVertex2D, fumes); - - this.uniforms.color = new Float32Array([1.0, 1.0, 1.0]); - this.uniforms.dimensions = new Float32Array([1.0, 1.0]); - - Object.assign(this, { - time, - color, - blend, - dimX, - dimY, - }); - - this.zOrder = 210; - this.animated = {}; - this.setTMParams(params); - if (!this.dummy) { - this.anime = new Anime(this); - this.normalizeTMParams(); - } - } - - get time() { - return this.uniforms.time; - } - - set time(value) { - this.uniforms.time = value; - } - - get color() { - return PIXI.utils.rgb2hex(this.uniforms.color); - } - - set color(value) { - new PIXI.Color(value).toRgbArray(this.uniforms.color); - } - - get blend() { - return this.uniforms.blend; - } - - set blend(value) { - this.uniforms.blend = Math.floor(value); - } - - get dimX() { - return this.uniforms.dimensions[0]; - } - - set dimX(value) { - this.uniforms.dimensions[0] = value; - } - - get dimY() { - return this.uniforms.dimensions[1]; - } - - set dimY(value) { - this.uniforms.dimensions[1] = value; - } -} - -FilterFumes.defaults = { - time: 0, - color: 0xffffff, - blend: 2, - dimX: 1, - dimY: 1, -}; diff --git a/tokenmagic/fx/filters/FilterGleamingGlow.js b/tokenmagic/fx/filters/FilterGleamingGlow.js deleted file mode 100644 index 2adf159..0000000 --- a/tokenmagic/fx/filters/FilterGleamingGlow.js +++ /dev/null @@ -1,122 +0,0 @@ -import { magicGlow } from '../glsl/fragmentshaders/magicglow.js'; -import { customVertex2D } from '../glsl/vertexshaders/customvertex2D.js'; -import { CustomFilter } from './CustomFilter.js'; -import { Anime } from '../Anime.js'; -import './proto/FilterProto.js'; - -export class FilterGleamingGlow extends CustomFilter { - constructor(params) { - let { time, color, thickness, scale, auraIntensity, subAuraIntensity, discard, threshold, auraType } = - Object.assign({}, FilterGleamingGlow.defaults, params); - - // using specific vertex shader and fragment shader - super(customVertex2D, magicGlow); - - this.uniforms.color = new Float32Array([1.0, 0.4, 0.1, 1.0]); - this.uniforms.thickness = new Float32Array([0.01, 0.01]); - - Object.assign(this, { - time, - color, - thickness, - scale, - auraIntensity, - subAuraIntensity, - discard, - threshold, - auraType, - }); - - this.zOrder = 80; - this.animated = {}; - this.setTMParams(params); - if (!this.dummy) { - this.anime = new Anime(this); - this.normalizeTMParams(); - } - } - - get time() { - return this.uniforms.time; - } - - set time(value) { - this.uniforms.time = value; - } - - get scale() { - return this.uniforms.scale; - } - - set scale(value) { - this.uniforms.scale = value; - } - - get auraIntensity() { - return this.uniforms.auraIntensity; - } - - set auraIntensity(value) { - this.uniforms.auraIntensity = value; - } - - get subAuraIntensity() { - return this.uniforms.subAuraIntensity; - } - - set subAuraIntensity(value) { - this.uniforms.subAuraIntensity = value; - } - - get threshold() { - return this.uniforms.threshold; - } - - set threshold(value) { - this.uniforms.threshold = value; - } - - get color() { - return PIXI.utils.rgb2hex(this.uniforms.color); - } - - set color(value) { - new PIXI.Color(value).toRgbArray(this.uniforms.color); - } - - get discard() { - return this.uniforms.holes; - } - - set discard(value) { - if (!(value == null) && typeof value === 'boolean') { - this.uniforms.holes = value; - } - } - - get auraType() { - return this.uniforms.auraType; - } - - set auraType(value) { - this.uniforms.auraType = Math.floor(value); - } - - apply(filterManager, input, output, clear) { - this.uniforms.thickness[0] = (this.thickness * this.targetPlaceable.worldTransform.a) / input._frame.width; - this.uniforms.thickness[1] = (this.thickness * this.targetPlaceable.worldTransform.a) / input._frame.height; - super.apply(filterManager, input, output, clear); - } -} - -FilterGleamingGlow.defaults = { - time: 0, - color: 0xff8010, - thickness: 5, - scale: 1, - auraIntensity: 1, - subAuraIntensity: 1, - discard: false, - threshold: 0.5, - auraType: 1, -}; diff --git a/tokenmagic/fx/filters/FilterGlobes.js b/tokenmagic/fx/filters/FilterGlobes.js deleted file mode 100644 index 95975b3..0000000 --- a/tokenmagic/fx/filters/FilterGlobes.js +++ /dev/null @@ -1,82 +0,0 @@ -import { globes } from '../glsl/fragmentshaders/globes.js'; -import { customVertex2D } from '../glsl/vertexshaders/customvertex2D.js'; -import { CustomFilter } from './CustomFilter.js'; -import { Anime } from '../Anime.js'; -import './proto/FilterProto.js'; - -export class FilterGlobes extends CustomFilter { - constructor(params) { - let { time, color, scale, distortion, alphaDiscard } = Object.assign({}, FilterGlobes.defaults, params); - - // using specific vertex shader and fragment shader - super(customVertex2D, globes); - - this.uniforms.color = new Float32Array([0.75, 0.75, 0.75]); - - Object.assign(this, { - time, - color, - scale, - distortion, - alphaDiscard, - }); - - this.zOrder = 270; - this.animated = {}; - this.setTMParams(params); - if (!this.dummy) { - this.anime = new Anime(this); - this.normalizeTMParams(); - } - } - - get time() { - return this.uniforms.time; - } - - set time(value) { - this.uniforms.time = value; - } - - get color() { - return PIXI.utils.rgb2hex(this.uniforms.color); - } - - set color(value) { - new PIXI.Color(value).toRgbArray(this.uniforms.color); - } - - get scale() { - return this.uniforms.scale; - } - - set scale(value) { - this.uniforms.scale = value; - } - - get distortion() { - return this.uniforms.distortion; - } - - set distortion(value) { - this.uniforms.distortion = value; - } - - get alphaDiscard() { - return this.uniforms.alphaDiscard; - } - - set alphaDiscard(value) { - if (!(value == null) && typeof value === 'boolean') { - this.uniforms.alphaDiscard = value; - } - } -} - -FilterGlobes.defaults = { - time: 0.0, - color: 0xaa3050, - scale: 20, - distortion: 0.25, - alphaDiscard: false, -}; diff --git a/tokenmagic/fx/filters/FilterGlow.js b/tokenmagic/fx/filters/FilterGlow.js deleted file mode 100644 index 02228ef..0000000 --- a/tokenmagic/fx/filters/FilterGlow.js +++ /dev/null @@ -1,24 +0,0 @@ -import { Anime } from '../Anime.js'; -import './proto/FilterProto.js'; - -export class FilterGlow extends PIXI.filters.GlowFilter { - constructor(params) { - super(); - this.padding = 15; - this.enabled = false; - this.innerStrength = 0; - this.outerStrength = 6.5; - this.color = 0x0020ff; - this.quality = 1; - this.alpha = 1; - this.zOrder = 70; - this.animated = {}; - this.setTMParams(params); - // Imposed value. Should not be a shader uniform - this.distance = 10; - if (!this.dummy) { - this.anime = new Anime(this); - this.normalizeTMParams(); - } - } -} diff --git a/tokenmagic/fx/filters/FilterLiquid.js b/tokenmagic/fx/filters/FilterLiquid.js deleted file mode 100644 index 7c89bd6..0000000 --- a/tokenmagic/fx/filters/FilterLiquid.js +++ /dev/null @@ -1,108 +0,0 @@ -import { liquid } from '../glsl/fragmentshaders/liquid.js'; -import { customVertex2D } from '../glsl/vertexshaders/customvertex2D.js'; -import { CustomFilter } from './CustomFilter.js'; -import { Anime } from '../Anime.js'; -import './proto/FilterProto.js'; - -export class FilterLiquid extends CustomFilter { - constructor(params) { - let { time, color, scale, intensity, blend, spectral, alphaDiscard } = Object.assign( - {}, - FilterLiquid.defaults, - params - ); - - // using specific vertex shader and fragment shader - super(customVertex2D, liquid); - - this.uniforms.color = new Float32Array([0.1, 0.45, 1.0]); - - Object.assign(this, { - time, - color, - scale, - intensity, - blend, - spectral, - alphaDiscard, - }); - - this.zOrder = 180; - this.animated = {}; - this.setTMParams(params); - if (!this.dummy) { - this.anime = new Anime(this); - this.normalizeTMParams(); - } - } - - get time() { - return this.uniforms.time; - } - - set time(value) { - this.uniforms.time = value; - } - - get scale() { - return this.uniforms.scale; - } - - set scale(value) { - this.uniforms.scale = value; - } - - get color() { - return PIXI.utils.rgb2hex(this.uniforms.color); - } - - set color(value) { - new PIXI.Color(value).toRgbArray(this.uniforms.color); - } - - get intensity() { - return this.uniforms.intensity; - } - - set intensity(value) { - this.uniforms.intensity = value; - } - - get blend() { - return this.uniforms.blend; - } - - set blend(value) { - this.uniforms.blend = Math.floor(value); - } - - get spectral() { - return this.uniforms.spectral; - } - - set spectral(value) { - if (!(value == null) && typeof value === 'boolean') { - this.uniforms.spectral = value; - } - } - - get alphaDiscard() { - return this.uniforms.alphaDiscard; - } - - set alphaDiscard(value) { - if (!(value == null) && typeof value === 'boolean') { - this.uniforms.alphaDiscard = value; - } - } -} - -FilterLiquid.defaults = { - time: 0.0, - color: 0x0595ff, - scale: 1, - intensity: 5, - blend: 4, - spectral: false, - alphaDiscard: false, -}; diff --git a/tokenmagic/fx/filters/FilterMirrorImages.js b/tokenmagic/fx/filters/FilterMirrorImages.js deleted file mode 100644 index 97d7012..0000000 --- a/tokenmagic/fx/filters/FilterMirrorImages.js +++ /dev/null @@ -1,103 +0,0 @@ -import { mirrorImages } from '../glsl/fragmentshaders/mirrorimages.js'; -import { customVertex2D } from '../glsl/vertexshaders/customvertex2D.js'; -import { CustomFilter } from './CustomFilter.js'; -import { Anime } from '../Anime.js'; -import './proto/FilterProto.js'; - -export class FilterMirrorImages extends CustomFilter { - constructor(params) { - let { time, blend, alphaImg, alphaChr, nbImage, ampX, ampY } = Object.assign( - {}, - FilterMirrorImages.defaults, - params - ); - - // using specific vertex shader and fragment shader - super(customVertex2D, mirrorImages); - - Object.assign(this, { - time, - blend, - alphaImg, - alphaChr, - nbImage, - ampX, - ampY, - }); - - this.zOrder = 100; - this.autoFit = false; - this.animated = {}; - this.setTMParams(params); - if (!this.dummy) { - this.anime = new Anime(this); - this.normalizeTMParams(); - } - } - - get time() { - return this.uniforms.time; - } - - set time(value) { - this.uniforms.time = value; - } - - get alphaImg() { - return this.uniforms.alphaImg; - } - - set alphaImg(value) { - this.uniforms.alphaImg = value; - } - - get alphaChr() { - return this.uniforms.alphaChr; - } - - set alphaChr(value) { - this.uniforms.alphaChr = value; - } - - get nbImage() { - return this.uniforms.nbImage; - } - - set nbImage(value) { - this.uniforms.nbImage = Math.floor(value); - } - - get blend() { - return this.uniforms.blend; - } - - set blend(value) { - this.uniforms.blend = Math.floor(value); - } - - get ampX() { - return this.uniforms.ampX; - } - - set ampX(value) { - this.uniforms.ampX = value; - } - - get ampY() { - return this.uniforms.ampY; - } - - set ampY(value) { - this.uniforms.ampY = value; - } -} - -FilterMirrorImages.defaults = { - time: 0, - blend: 4, - alphaImg: 0.5, - alphaChr: 1.0, - nbImage: 4, - ampX: 0.15, - ampY: 0.15, -}; diff --git a/tokenmagic/fx/filters/FilterOldFilm.js b/tokenmagic/fx/filters/FilterOldFilm.js deleted file mode 100644 index 1667c40..0000000 --- a/tokenmagic/fx/filters/FilterOldFilm.js +++ /dev/null @@ -1,21 +0,0 @@ -import { Anime } from '../Anime.js'; -import './proto/FilterProto.js'; - -export class FilterOldFilm extends PIXI.filters.OldFilmFilter { - constructor(params) { - super(); - this.enabled = false; - this.vignetting = 0; - this.noise = 0.08; - this.scratch = 0.1; - this.scratchDensity = 0.1; - this.seed = 0; - this.zOrder = 60; - this.animated = {}; - this.setTMParams(params); - if (!this.dummy) { - this.anime = new Anime(this); - this.normalizeTMParams(); - } - } -} diff --git a/tokenmagic/fx/filters/FilterOutline.js b/tokenmagic/fx/filters/FilterOutline.js deleted file mode 100644 index 755cf3a..0000000 --- a/tokenmagic/fx/filters/FilterOutline.js +++ /dev/null @@ -1,21 +0,0 @@ -import { Anime } from '../Anime.js'; -import './proto/FilterProto.js'; - -export class FilterOutline extends PIXI.filters.OutlineFilter { - constructor(params) { - super(); - this.blendMode = PIXI.BLEND_MODES.NORMAL; - this.padding = 5; - this.enabled = false; - this.thickness = 3; - this.color = 0x000000; - this.quality = 1; - this.zOrder = 50; - this.animated = {}; - this.setTMParams(params); - if (!this.dummy) { - this.anime = new Anime(this); - this.normalizeTMParams(); - } - } -} diff --git a/tokenmagic/fx/filters/FilterPixelate.js b/tokenmagic/fx/filters/FilterPixelate.js deleted file mode 100644 index acc17dc..0000000 --- a/tokenmagic/fx/filters/FilterPixelate.js +++ /dev/null @@ -1,23 +0,0 @@ -import { Anime } from '../Anime.js'; -import './proto/FilterProto.js'; - -export class FilterPixelate extends PIXI.filters.PixelateFilter { - constructor(params) { - super(); - this.enabled = false; - this.animated = {}; - this.sizeX = 5; - this.sizeY = 5; - this.zOrder = 20; - this.setTMParams(params); - if (!this.dummy) { - this.anime = new Anime(this); - this.normalizeTMParams(); - } - } - - handleTransform() { - this.size.x = this.sizeX * this.targetPlaceable.worldTransform.a; - this.size.y = this.sizeY * this.targetPlaceable.worldTransform.a; - } -} diff --git a/tokenmagic/fx/filters/FilterPolymorph.js b/tokenmagic/fx/filters/FilterPolymorph.js deleted file mode 100644 index 3c33fe3..0000000 --- a/tokenmagic/fx/filters/FilterPolymorph.js +++ /dev/null @@ -1,144 +0,0 @@ -import { polymorph } from '../glsl/fragmentshaders/polymorph.js'; -import { customVertex2DSampler } from '../glsl/vertexshaders/customvertex2DSampler.js'; -import { CustomFilter } from './CustomFilter.js'; -import { Anime } from '../Anime.js'; -import './proto/FilterProto.js'; -import { fixPath } from '../../module/tokenmagic.js'; - -export class FilterPolymorph extends CustomFilter { - constructor(params) { - let { imagePath, progress, magnify, type } = Object.assign({}, FilterPolymorph.defaults, params); - - const targetSpriteMatrix = new PIXI.Matrix(); - - // using specific vertex shader and fragment shader - super(customVertex2DSampler, polymorph); - - // vertex uniforms - this.uniforms.targetUVMatrix = targetSpriteMatrix; - - // fragment uniforms - this.uniforms.inputClampTarget = new Float32Array([0, 0, 0, 0]); - - // to store sprite matrix from the filter manager (and send to vertex) - this.targetSpriteMatrix = targetSpriteMatrix; - - Object.assign(this, { - imagePath: fixPath(imagePath), - progress, - magnify, - type, - }); - - this.zOrder = 1; - this.autoFit = false; - this.animated = {}; - this.setTMParams(params); - if (!this.dummy) { - this.anime = new Anime(this); - this.normalizeTMParams(); - } - } - - setTMParams(params) { - super.setTMParams(params); - if (!this.dummy && 'imagePath' in params) { - this.assignTexture(); - } - } - - get progress() { - return this.uniforms.progress * 100; - } - - set progress(value) { - this.uniforms.progress = Math.min(Math.max(value * 0.01, 0), 1); - } - - get magnify() { - return this.uniforms.magnify; - } - - set magnify(value) { - this.uniforms.magnify = Math.min(Math.max(value, 0.1), 100); - } - - get type() { - return this.uniforms.type; - } - - set type(value) { - this.uniforms.type = Math.floor(value); - } - - get uSamplerTarget() { - return this.uniforms.uSamplerTarget; - } - - set uSamplerTarget(value) { - this.uniforms.uSamplerTarget = value; - } - - _setTargetSpriteSize() { - const sprite = this.targetSprite; - let ratioW = this.placeableImg._texture.baseTexture.realWidth / sprite.texture.baseTexture.realWidth; - sprite.width = sprite.texture.baseTexture.realWidth * ratioW; - sprite.height = sprite.texture.baseTexture.realHeight * ratioW; - sprite.anchor.set(0.5); - } - - assignTexture() { - if (this.hasOwnProperty('imagePath')) { - let tex = PIXI.Texture.from(this.imagePath); - let sprite = new PIXI.Sprite(tex); - - sprite.renderable = false; - this.targetSprite = sprite; - - // We may need to wait for the texture to be loaded before accessing it's width and height - // In such a case register an update listener which should be called when the texture is loaded/becomes valid - if (tex.valid) { - this._setTargetSpriteSize(); - } else { - tex.on('update', () => { - this._setTargetSpriteSize(); - }); - } - - this.uSamplerTarget = sprite._texture; - this.placeableImg.addChild(sprite); - } - } - - // override - apply(filterManager, input, output, clear) { - const targetSprite = this.targetSprite; - const tex = targetSprite._texture; - - if (tex.valid) { - if (!tex.uvMatrix) tex.uvMatrix = new PIXI.TextureMatrix(tex, 0.0); - tex.uvMatrix.update(); - - this.uniforms.uSamplerTarget = tex; - this.uniforms.targetUVMatrix = filterManager - .calculateSpriteMatrix(this.targetSpriteMatrix, targetSprite) - .prepend(tex.uvMatrix.mapCoord); - this.uniforms.inputClampTarget = tex.uvMatrix.uClampFrame; - } - - super.apply(filterManager, input, output, clear); - } - - // override - destroy() { - super.destroy(); - if (this.placeableImg) this.placeableImg.removeChild(this.targetSprite); - this.targetSprite.destroy({ children: true, texture: false, baseTexture: false }); - } -} - -FilterPolymorph.defaults = { - progress: 0, - magnify: 1, - type: 1, -}; diff --git a/tokenmagic/fx/filters/FilterRGBSplit.js b/tokenmagic/fx/filters/FilterRGBSplit.js deleted file mode 100644 index bf744e0..0000000 --- a/tokenmagic/fx/filters/FilterRGBSplit.js +++ /dev/null @@ -1,66 +0,0 @@ -import { Anime } from '../Anime.js'; -import './proto/FilterProto.js'; - -export class FilterRGBSplit extends PIXI.filters.RGBSplitFilter { - constructor(params) { - super(); - this.red = new Float32Array([-10, 0]); - this.green = new Float32Array([0, 10]); - this.blue = new Float32Array([0, 0]); - this.zOrder = 340; - this.animated = {}; - this.setTMParams(params); - if (!this.dummy) { - this.anime = new Anime(this); - this.normalizeTMParams(); - } - } - - get redX() { - return this.uniforms.red[0]; - } - - set redX(value) { - this.uniforms.red[0] = value; - } - - get redY() { - return this.uniforms.red[1]; - } - - set redY(value) { - this.uniforms.red[1] = value; - } - - get greenX() { - return this.uniforms.green[0]; - } - - set greenX(value) { - this.uniforms.green[0] = value; - } - - get greenY() { - return this.uniforms.green[1]; - } - - set greenY(value) { - this.uniforms.green[1] = value; - } - - get blueX() { - return this.uniforms.blue[0]; - } - - set blueX(value) { - this.uniforms.blue[0] = value; - } - - get blueY() { - return this.uniforms.blue[1]; - } - - set blueY(value) { - this.uniforms.blue[1] = value; - } -} diff --git a/tokenmagic/fx/filters/FilterRays.js b/tokenmagic/fx/filters/FilterRays.js deleted file mode 100644 index bba5860..0000000 --- a/tokenmagic/fx/filters/FilterRays.js +++ /dev/null @@ -1,130 +0,0 @@ -import { cosmicRayFrag } from '../glsl/fragmentshaders/cosmicray.js'; -import { customVertex2D } from '../glsl/vertexshaders/customvertex2D.js'; -import { CustomFilter } from './CustomFilter.js'; -import { Anime } from '../Anime.js'; -import './proto/FilterProto.js'; - -export class FilterRays extends CustomFilter { - constructor(params) { - let { time, color, divisor, alpha, anchorX, anchorY, dimX, dimY, alphaDiscard } = Object.assign( - {}, - FilterRays.defaults, - params - ); - - // using specific vertex shader and fragment shader - super(customVertex2D, cosmicRayFrag); - - this.uniforms.color = new Float32Array([1.0, 0.4, 0.1, 0.55]); - this.uniforms.anchor = new Float32Array([0.5, 0.5]); - this.uniforms.dimensions = new Float32Array([1.0, 1.0]); - - Object.assign(this, { - time, - color, - divisor, - alpha, - anchorX, - anchorY, - dimX, - dimY, - alphaDiscard, - }); - - this.zOrder = 120; - this.animated = {}; - this.setTMParams(params); - if (!this.dummy) { - this.anime = new Anime(this); - this.normalizeTMParams(); - } - } - - get time() { - return this.uniforms.time; - } - - set time(value) { - this.uniforms.time = value; - } - - get color() { - return PIXI.utils.rgb2hex(this.uniforms.color); - } - - set color(value) { - new PIXI.Color(value).toRgbArray(this.uniforms.color); - } - - get divisor() { - return this.uniforms.divisor; - } - - set divisor(value) { - this.uniforms.divisor = value; - } - - get alpha() { - return this.uniforms.color[3]; - } - - set alpha(value) { - if (value >= 0 && value <= 1) { - this.uniforms.color[3] = value; - } - } - - get anchorX() { - return this.uniforms.anchor[0]; - } - - set anchorX(value) { - this.uniforms.anchor[0] = value; - } - - get anchorY() { - return this.uniforms.anchor[1]; - } - - set anchorY(value) { - this.uniforms.anchor[1] = value; - } - - get dimX() { - return this.uniforms.dimensions[0]; - } - - set dimX(value) { - this.uniforms.dimensions[0] = value; - } - - get dimY() { - return this.uniforms.dimensions[1]; - } - - set dimY(value) { - this.uniforms.dimensions[1] = value; - } - - get alphaDiscard() { - return this.uniforms.alphaDiscard; - } - - set alphaDiscard(value) { - if (!(value == null) && typeof value === 'boolean') { - this.uniforms.alphaDiscard = value; - } - } -} - -FilterRays.defaults = { - time: 0.0, - color: 0xff8010, - divisor: 16, - alpha: 0.55, - anchorX: 0.5, - anchorY: 0.5, - dimX: 100, - dimY: 100, - alphaDiscard: false, -}; diff --git a/tokenmagic/fx/filters/FilterRemoveShadow.js b/tokenmagic/fx/filters/FilterRemoveShadow.js deleted file mode 100644 index d088f25..0000000 --- a/tokenmagic/fx/filters/FilterRemoveShadow.js +++ /dev/null @@ -1,36 +0,0 @@ -import { removeShadowFrag } from '../glsl/fragmentshaders/removeshadow.js'; -import { CustomFilter } from './CustomFilter.js'; -import { Anime } from '../Anime.js'; -import './proto/FilterProto.js'; - -export class FilterRemoveShadow extends CustomFilter { - constructor(params) { - let { alphaTolerance } = Object.assign({}, FilterRemoveShadow.defaults, params); - - // using the default vertex shader and the specific fragment shader - super(undefined, removeShadowFrag); - - Object.assign(this, { - alphaTolerance, - }); - - this.zOrder = 10; - this.animated = {}; - this.setTMParams(params); - if (!this.dummy) { - this.anime = new Anime(this); - this.normalizeTMParams(); - } - } - - get alphaTolerance() { - return this.uniforms.alphaTolerance; - } - set alphaTolerance(value) { - this.uniforms.alphaTolerance = value; - } -} - -FilterRemoveShadow.defaults = { - alphaTolerance: 0.8, -}; diff --git a/tokenmagic/fx/filters/FilterReplaceColor.js b/tokenmagic/fx/filters/FilterReplaceColor.js deleted file mode 100644 index 7fc2ea6..0000000 --- a/tokenmagic/fx/filters/FilterReplaceColor.js +++ /dev/null @@ -1,18 +0,0 @@ -import { Anime } from '../Anime.js'; -import './proto/FilterProto.js'; - -export class FilterReplaceColor extends PIXI.filters.ColorReplaceFilter { - constructor(params) { - super(); - this.originalColor = [1, 0, 0]; - this.newColor = [0, 1, 0]; - this.epsilon = 0.7; - this.zOrder = 100; - this.animating = {}; - this.setTMParams(params); - if (!this.dummy) { - this.anime = new Anime(this); - this.normalizeTMParams(); - } - } -} diff --git a/tokenmagic/fx/filters/FilterShockWave.js b/tokenmagic/fx/filters/FilterShockWave.js deleted file mode 100644 index 4d87ec8..0000000 --- a/tokenmagic/fx/filters/FilterShockWave.js +++ /dev/null @@ -1,29 +0,0 @@ -import { Anime } from '../Anime.js'; -import './proto/FilterProto.js'; - -export class FilterShockwave extends PIXI.filters.ShockwaveFilter { - constructor(params) { - super(); - this.enabled = false; - - this.time = 0; - this.amplitude = 5; - this.wavelength = 100; - this.speed = 50.0; - this.brightness = 1.5; - this.radius = 200; - - this.zOrder = 220; - this.animated = {}; - this.setTMParams(params); - if (!this.dummy) { - this.anime = new Anime(this); - this.normalizeTMParams(); - } - } - - handleTransform(state) { - this.center[0] = 0.5 * state.sourceFrame.width; - this.center[1] = 0.5 * state.sourceFrame.height; - } -} diff --git a/tokenmagic/fx/filters/FilterSmoke.js b/tokenmagic/fx/filters/FilterSmoke.js deleted file mode 100644 index c3be3ba..0000000 --- a/tokenmagic/fx/filters/FilterSmoke.js +++ /dev/null @@ -1,81 +0,0 @@ -import { innerSmoke } from '../glsl/fragmentshaders/smoke.js'; -import { customVertex2D } from '../glsl/vertexshaders/customvertex2D.js'; -import { CustomFilter } from './CustomFilter.js'; -import { Anime } from '../Anime.js'; -import './proto/FilterProto.js'; - -export class FilterSmoke extends CustomFilter { - constructor(params) { - let { time, color, blend, dimX, dimY } = Object.assign({}, FilterSmoke.defaults, params); - - // using specific vertex shader and fragment shader - super(customVertex2D, innerSmoke); - - this.uniforms.color = new Float32Array([1.0, 1.0, 1.0]); - this.uniforms.scale = new Float32Array([1.0, 1.0]); - - Object.assign(this, { - time, - color, - blend, - dimX, - dimY, - }); - - this.zOrder = 200; - this.animated = {}; - this.setTMParams(params); - if (!this.dummy) { - this.anime = new Anime(this); - this.normalizeTMParams(); - } - } - - get time() { - return this.uniforms.time; - } - - set time(value) { - this.uniforms.time = value; - } - - get color() { - return PIXI.utils.rgb2hex(this.uniforms.color); - } - - set color(value) { - new PIXI.Color(value).toRgbArray(this.uniforms.color); - } - - get blend() { - return this.uniforms.blend; - } - - set blend(value) { - this.uniforms.blend = Math.floor(value); - } - - get dimX() { - return this.uniforms.scale[0]; - } - - set dimX(value) { - this.uniforms.scale[0] = value; - } - - get dimY() { - return this.uniforms.scale[1]; - } - - set dimY(value) { - this.uniforms.scale[1] = value; - } -} - -FilterSmoke.defaults = { - time: 0, - color: 0xffffff, - blend: 13, - dimX: 1, - dimY: 1, -}; diff --git a/tokenmagic/fx/filters/FilterSolarRipples.js b/tokenmagic/fx/filters/FilterSolarRipples.js deleted file mode 100644 index 6418a14..0000000 --- a/tokenmagic/fx/filters/FilterSolarRipples.js +++ /dev/null @@ -1,90 +0,0 @@ -import { solarRipples } from '../glsl/fragmentshaders/ripples.js'; -import { customVertex2D } from '../glsl/vertexshaders/customvertex2D.js'; -import { CustomFilter } from './CustomFilter.js'; -import { Anime } from '../Anime.js'; -import './proto/FilterProto.js'; - -export class FilterSolarRipples extends CustomFilter { - constructor(params) { - let { time, color, amplitude, intensity, alphaDiscard, _octaves } = Object.assign( - {}, - FilterSolarRipples.defaults, - params - ); - - if (typeof _octaves !== 'number') _octaves = FilterSolarRipples.defaults._octave; - let fragment = solarRipples.replace(`#define OCTAVES 3`, `#define OCTAVES ${_octaves}`); - - // using specific vertex shader and fragment shader - super(customVertex2D, fragment); - - this.uniforms.color = new Float32Array([0.75, 0.75, 0.75]); - - Object.assign(this, { - time, - color, - amplitude, - intensity, - alphaDiscard, - }); - - this.zOrder = 250; - this.animated = {}; - this.setTMParams(params); - if (!this.dummy) { - this.anime = new Anime(this); - this.normalizeTMParams(); - } - } - - get time() { - return this.uniforms.time; - } - - set time(value) { - this.uniforms.time = value; - } - - get color() { - return PIXI.utils.rgb2hex(this.uniforms.color); - } - - set color(value) { - new PIXI.Color(value).toRgbArray(this.uniforms.color); - } - - get amplitude() { - return this.uniforms.amplitude; - } - - set amplitude(value) { - this.uniforms.amplitude = value; - } - - get intensity() { - return this.uniforms.intensity; - } - - set intensity(value) { - this.uniforms.intensity = value; - } - - get alphaDiscard() { - return this.uniforms.alphaDiscard; - } - - set alphaDiscard(value) { - if (!(value == null) && typeof value === 'boolean') { - this.uniforms.alphaDiscard = value; - } - } -} - -FilterSolarRipples.defaults = { - time: 0.0, - color: 0xbbbbbb, - amplitude: 1, - intensity: 0.001, - alphaDiscard: false, - _octave: 3, -}; diff --git a/tokenmagic/fx/filters/FilterSpiderWeb.js b/tokenmagic/fx/filters/FilterSpiderWeb.js deleted file mode 100644 index d605986..0000000 --- a/tokenmagic/fx/filters/FilterSpiderWeb.js +++ /dev/null @@ -1,137 +0,0 @@ -import { spiderWeb } from '../glsl/fragmentshaders/spiderweb.js'; -import { customVertex2D } from '../glsl/vertexshaders/customvertex2D.js'; -import { CustomFilter } from './CustomFilter.js'; -import { Anime } from '../Anime.js'; -import './proto/FilterProto.js'; - -export class FilterSpiderWeb extends CustomFilter { - constructor(params) { - let { time, anchorX, anchorY, color, thickness, div1, div2, tear, amplitude, alphaDiscard } = Object.assign( - {}, - FilterSpiderWeb.defaults, - params - ); - - // using specific vertex shader and fragment shader - super(customVertex2D, spiderWeb); - - this.uniforms.anchor = new Float32Array([0.5, -1.0]); - this.uniforms.color = new Float32Array([0.75, 0.75, 0.75]); - - Object.assign(this, { - time, - anchorX, - anchorY, - color, - thickness, - div1, - div2, - tear, - amplitude, - alphaDiscard, - }); - - this.zOrder = 260; - this.animated = {}; - this.setTMParams(params); - if (!this.dummy) { - this.anime = new Anime(this); - this.normalizeTMParams(); - } - } - - get time() { - return this.uniforms.time; - } - - set time(value) { - this.uniforms.time = value; - } - - get color() { - return PIXI.utils.rgb2hex(this.uniforms.color); - } - - set color(value) { - new PIXI.Color(value).toRgbArray(this.uniforms.color); - } - - get anchorX() { - return this.uniforms.anchor[0]; - } - - set anchorX(value) { - this.uniforms.anchor[0] = 0.5; - } - - get anchorY() { - return this.uniforms.anchor[1]; - } - - set anchorY(value) { - this.uniforms.anchor[1] = 0.5; - } - - get thickness() { - return this.uniforms.thickness; - } - - set thickness(value) { - this.uniforms.thickness = value; - } - - get tear() { - return this.uniforms.tear; - } - - set tear(value) { - this.uniforms.tear = value; - } - - get amplitude() { - return this.uniforms.amplitude; - } - - set amplitude(value) { - this.uniforms.amplitude = value; - } - - get div1() { - return this.uniforms.div1; - } - - set div1(value) { - this.uniforms.div1 = value; - } - - get div2() { - return this.uniforms.div2; - } - - set div2(value) { - this.uniforms.div2 = value; - } - - get alphaDiscard() { - return this.uniforms.alphaDiscard; - } - - set alphaDiscard(value) { - if (!(value == null) && typeof value === 'boolean') { - this.uniforms.alphaDiscard = value; - } - } -} - -FilterSpiderWeb.defaults = { - time: 0.0, - anchorX: 0.5, - anchorY: 0.5, - color: 0xbbbbbb, - thickness: 1, - div1: 10, - div2: 10, - tear: 0.54, - amplitude: 0.8, - alphaDiscard: false, -}; diff --git a/tokenmagic/fx/filters/FilterSplash.js b/tokenmagic/fx/filters/FilterSplash.js deleted file mode 100644 index 0669473..0000000 --- a/tokenmagic/fx/filters/FilterSplash.js +++ /dev/null @@ -1,157 +0,0 @@ -import { splash } from '../glsl/fragmentshaders/splash.js'; -import { customVertex2D } from '../glsl/vertexshaders/customvertex2D.js'; -import { CustomFilter } from './CustomFilter.js'; -import { Anime } from '../Anime.js'; -import './proto/FilterProto.js'; - -export class FilterSplash extends CustomFilter { - constructor(params) { - let { time, seed, spread, splashFactor, color, dimX, dimY, blend, cut, textureAlphaBlend, anchorX, anchorY } = - Object.assign({}, FilterSplash.defaults, params); - - // using specific vertex shader and fragment shader - super(customVertex2D, splash); - - this.uniforms.color = new Float32Array([1.0, 0.05, 0.05]); - this.uniforms.dimensions = new Float32Array([1.0, 1.0]); - this.uniforms.anchor = new Float32Array([0.0, 0.0]); - - Object.assign(this, { - time, - seed, - spread, - splashFactor, - color, - dimX, - dimY, - blend, - cut, - textureAlphaBlend, - anchorX, - anchorY, - }); - - this.zOrder = 5; - this.animated = {}; - this.setTMParams(params); - if (!this.dummy) { - this.anime = new Anime(this); - this.normalizeTMParams(); - } - } - - get time() { - return this.uniforms.time; - } - - set time(value) { - this.uniforms.time = value; - } - - get color() { - return PIXI.utils.rgb2hex(this.uniforms.color); - } - - set color(value) { - new PIXI.Color(value).toRgbArray(this.uniforms.color); - } - - get seed() { - return this.uniforms.seed; - } - - set seed(value) { - this.uniforms.seed = value; - } - - get spread() { - return this.uniforms.spread; - } - - set spread(value) { - this.uniforms.spread = value; - } - - get splashFactor() { - return this.uniforms.splashFactor; - } - - set splashFactor(value) { - this.uniforms.splashFactor = value; - } - - get dimX() { - return this.uniforms.dimensions[0]; - } - - set dimX(value) { - this.uniforms.dimensions[0] = value; - } - - get dimY() { - return this.uniforms.dimensions[1]; - } - - set dimY(value) { - this.uniforms.dimensions[1] = value; - } - - get anchorY() { - return this.uniforms.anchor[1] + 0.5; - } - - set anchorY(value) { - this.uniforms.anchor[1] = value - 0.5; - } - - get anchorX() { - return this.uniforms.anchor[0] + 0.5; - } - - set anchorX(value) { - this.uniforms.anchor[0] = value - 0.5; - } - - get blend() { - return this.uniforms.blend; - } - - set blend(value) { - this.uniforms.blend = Math.floor(value); - } - - get cut() { - return this.uniforms.cut; - } - - set cut(value) { - if (!(value == null) && typeof value === 'boolean') { - this.uniforms.cut = value; - } - } - - get textureAlphaBlend() { - return this.uniforms.textureAlphaBlend; - } - - set textureAlphaBlend(value) { - if (!(value == null) && typeof value === 'boolean') { - this.uniforms.textureAlphaBlend = value; - } - } -} - -FilterSplash.defaults = { - time: Math.random() * 2000, - color: 0xf00505, - seed: 0.1, - spread: 5, - splashFactor: 2, - dimX: 1, - dimY: 1, - blend: 8, - cut: false, - textureAlphaBlend: false, - anchorX: 0.5, - anchorY: 0.5, -}; diff --git a/tokenmagic/fx/filters/FilterSprite.js b/tokenmagic/fx/filters/FilterSprite.js deleted file mode 100644 index 0a5f334..0000000 --- a/tokenmagic/fx/filters/FilterSprite.js +++ /dev/null @@ -1,407 +0,0 @@ -import { sprite } from '../glsl/fragmentshaders/sprite.js'; -import { customVertex2DSampler } from '../glsl/vertexshaders/customvertex2DSampler.js'; -import { CustomFilter } from './CustomFilter.js'; -import { Anime } from '../Anime.js'; -import './proto/FilterProto.js'; -import { fixPath } from '../../module/tokenmagic.js'; - -export class FilterSprite extends CustomFilter { - tex = null; - - constructor(params) { - let { - imagePath, - color, - colorize, - inverse, - alpha, - alphaDiscard, - repeat, - top, - rotation, - twRadiusPercent, - twAngle, - twRotation, - bpRadiusPercent, - bpStrength, - scale, - scaleX, - scaleY, - translationX, - translationY, - play, - loop, - maintainAspectRatio, - maintainScale, - } = Object.assign({}, FilterSprite.defaults, params); - - const targetSpriteMatrix = new PIXI.Matrix(); - - // using specific vertex shader and fragment shader - super(customVertex2DSampler, sprite); - - // vertex uniforms - this.uniforms.targetUVMatrix = targetSpriteMatrix; - - // fragment uniforms - this.uniforms.inputClampTarget = new Float32Array([0, 0, 0, 0]); - this.uniforms.color = new Float32Array([0.0, 0.0, 0.0]); - this.uniforms.scale = new Float32Array([1.0, 1.0]); - this.uniforms.translation = new Float32Array([0.0, 0.0]); - - // to store sprite matrix from the filter manager (and send to vertex) - this.targetSpriteMatrix = targetSpriteMatrix; - - Object.assign(this, { - imagePath: fixPath(imagePath), - color, - colorize, - inverse, - alpha, - alphaDiscard, - repeat, - top, - rotation, - twRadiusPercent, - twAngle, - twRotation, - bpRadiusPercent, - bpStrength, - scale, - scaleX, - scaleY, - translationX, - translationY, - play, - loop, - maintainAspectRatio, - maintainScale, - }); - - this.zOrder = 0; - this.autoFit = false; - this.animated = {}; - this.setTMParams(params); - if (!this.dummy) { - this.anime = new Anime(this); - this.normalizeTMParams(); - } - } - - setTMParams(params) { - super.setTMParams(params); - if (!this.dummy && 'imagePath' in params) { - this.assignTexture(); - } - } - - _play = true; - _loop = true; - _maintainAspectRatio = false; - _maintainScale = false; - - get play() { - return this._play; - } - - set play(value) { - if (!(value == null) && typeof value === 'boolean') { - this._play = value; - this._playVideo(this._play); - } - } - - get loop() { - return this._loop; - } - - set loop(value) { - if (!(value == null) && typeof value === 'boolean') { - this._loop = value; - this._playVideo(this._play); - } - } - - get maintainAspectRatio() { - return this._maintainAspectRatio; - } - - set maintainAspectRatio(value) { - if (!(value == null) && typeof value === 'boolean') { - this._maintainAspectRatio = value; - } - } - - get maintainScale() { - return this._maintainScale; - } - - set maintainScale(value) { - if (!(value == null) && typeof value === 'boolean') { - this._maintainScale = value; - } - } - - get color() { - return PIXI.utils.rgb2hex(this.uniforms.color); - } - - set color(value) { - new PIXI.Color(value).toRgbArray(this.uniforms.color); - } - - get colorize() { - return this.uniforms.colorize; - } - - set colorize(value) { - if (!(value == null) && typeof value === 'boolean') { - this.uniforms.colorize = value; - } - } - - get inverse() { - return this.uniforms.inverse; - } - - set inverse(value) { - if (!(value == null) && typeof value === 'boolean') { - this.uniforms.inverse = value; - } - } - - get alpha() { - return this.uniforms.alpha; - } - - set alpha(value) { - this.uniforms.alpha = value; - } - - get alphaDiscard() { - return this.uniforms.alphaDiscard; - } - - set alphaDiscard(value) { - if (!(value == null) && typeof value === 'boolean') { - this.uniforms.alphaDiscard = value; - } - } - - get repeat() { - return this.uniforms.repeat; - } - - set repeat(value) { - if (!(value == null) && typeof value === 'boolean') { - this.uniforms.repeat = value; - } - } - - get top() { - return this.uniforms.top; - } - - set top(value) { - if (!(value == null) && typeof value === 'boolean') { - this.uniforms.top = value; - } - } - - get rotation() { - return this.uniforms.rotation; - } - - set rotation(value) { - this.uniforms.rotation = value; - } - - get twRadiusPercent() { - return this.uniforms.twRadius * 200; - } - - set twRadiusPercent(value) { - this.uniforms.twRadius = value / 200; - } - - get twAngle() { - return this.uniforms.twAngle; - } - - set twAngle(value) { - this.uniforms.twAngle = value; - } - - get twRotation() { - return this.uniforms.twAngle * (180 / Math.PI); - } - - set twRotation(value) { - this.uniforms.twAngle = value * (Math.PI / 180); - } - - get bpRadiusPercent() { - return this.uniforms.bpRadius * 200; - } - - set bpRadiusPercent(value) { - this.uniforms.bpRadius = value / 200; - } - - get bpStrength() { - return this.uniforms.bpStrength; - } - - set bpStrength(value) { - this.uniforms.bpStrength = value; - } - - get scale() { - // a little hack (we get only x) - return this.uniforms.scale[0]; - } - - set scale(value) { - this.uniforms.scale[1] = this.uniforms.scale[0] = value; - } - - get scaleX() { - return this.uniforms.scale[0]; - } - - set scaleX(value) { - this.uniforms.scale[0] = value; - } - - get scaleY() { - return this.uniforms.scale[1]; - } - - set scaleY(value) { - this.uniforms.scale[1] = value; - } - - get translationX() { - return this.uniforms.translation[0]; - } - - set translationX(value) { - this.uniforms.translation[0] = value; - } - - get translationY() { - return this.uniforms.translation[1]; - } - - set translationY(value) { - this.uniforms.translation[1] = value; - } - - get uSamplerTarget() { - return this.uniforms.uSamplerTarget; - } - - set uSamplerTarget(value) { - this.uniforms.uSamplerTarget = value; - } - - async _playVideo(value) { - // Play if baseTexture resource is a video - if (this.tex) { - const source = getProperty(this.tex, 'baseTexture.resource.source'); - if (source && source.tagName === 'VIDEO') { - if (isNaN(source.duration)) { - await new Promise((resolve) => { - source.onloadedmetadata = () => resolve(); - }); - } - if (value) game.video.play(source, { loop: this._loop, volume: 0 }); - else game.video.stop(source); - } - } - } - - assignTexture() { - if (this.hasOwnProperty('imagePath')) { - // Destroy the previous sprite - if (this.targetSprite && !this.targetSprite.destroyed) - this.targetSprite.destroy({ children: true, texture: false, baseTexture: false }); - this.tex = PIXI.Texture.from(this.imagePath); - - let sprite = new PIXI.Sprite(this.tex); - - sprite.renderable = false; - if (this.placeableImg._texture) { - sprite.width = this.placeableImg._texture.baseTexture.realWidth; - sprite.height = this.placeableImg._texture.baseTexture.realHeight; - sprite.anchor.set(0.5); - } else { - sprite.width = this.placeableImg.width; - sprite.height = this.placeableImg.height; - } - - this.targetSprite = sprite; - this.uSamplerTarget = sprite._texture; - this.placeableImg.addChild(sprite); - - this._playVideo(this._play); - } - } - - // override - apply(filterManager, input, output, clear) { - const targetSprite = this.targetSprite; - const tex = targetSprite._texture; - - if (tex.valid) { - if (!tex.uvMatrix) tex.uvMatrix = new PIXI.TextureMatrix(tex, 0.0); - tex.uvMatrix.update(); - - this.uniforms.uSamplerTarget = tex; - if (this.maintainScale) { - let pScale = targetSprite.parent.scale; - targetSprite.scale.set(1 / pScale.x, 1 / pScale.y); - } - - let w = targetSprite.worldTransform; - if (this.maintainAspectRatio) { - let scale = Math.min(w.a, w.d); - w.set(scale, w.b, w.c, scale, w.tx, w.ty); - } - - this.uniforms.targetUVMatrix = filterManager.calculateSpriteMatrix(this.targetSpriteMatrix, targetSprite); - this.uniforms.inputClampTarget = tex.uvMatrix.uClampFrame; - } - - super.apply(filterManager, input, output, clear); - } - - // override - destroy() { - super.destroy(); - if (!this.targetSprite.destroyed) this.targetSprite.destroy({ children: true, texture: false, baseTexture: false }); - } -} - -FilterSprite.defaults = { - color: 0x000000, - colorize: false, - inverse: false, - alpha: 1, - alphaDiscard: false, - repeat: false, - top: false, - rotation: 0.0, - twRadiusPercent: 0, - twAngle: 0, - bpRadiusPercent: 0, - bpStrength: 0, - scaleX: 1, - scaleY: 1, - translationX: 0, - translationY: 0, - play: true, - loop: true, - maintainAspectRatio: false, - maintainScale: false, -}; diff --git a/tokenmagic/fx/filters/FilterSpriteMask.js b/tokenmagic/fx/filters/FilterSpriteMask.js deleted file mode 100644 index 18a43fe..0000000 --- a/tokenmagic/fx/filters/FilterSpriteMask.js +++ /dev/null @@ -1,344 +0,0 @@ -import { spritemask } from '../glsl/fragmentshaders/spritemask.js'; -import { customVertex2DSampler } from '../glsl/vertexshaders/customvertex2DSampler.js'; -import { CustomFilter } from './CustomFilter.js'; -import { Anime } from '../Anime.js'; -import './proto/FilterProto.js'; -import { fixPath } from '../../module/tokenmagic.js'; - -export class FilterSpriteMask extends CustomFilter { - tex = null; - - constructor(params) { - let { - imagePath, - alpha, - repeat, - rotation, - twRadiusPercent, - twAngle, - twRotation, - bpRadiusPercent, - bpStrength, - scale, - scaleX, - scaleY, - translationX, - translationY, - play, - loop, - maintainAspectRatio, - maintainScale, - } = Object.assign({}, FilterSpriteMask.defaults, params); - - const targetSpriteMatrix = new PIXI.Matrix(); - - // using specific vertex shader and fragment shader - super(customVertex2DSampler, spritemask); - - // vertex uniforms - this.uniforms.targetUVMatrix = targetSpriteMatrix; - - // fragment uniforms - this.uniforms.inputClampTarget = new Float32Array([0, 0, 0, 0]); - this.uniforms.color = new Float32Array([0.0, 0.0, 0.0]); - this.uniforms.scale = new Float32Array([1.0, 1.0]); - this.uniforms.translation = new Float32Array([0.0, 0.0]); - - // to store sprite matrix from the filter manager (and send to vertex) - this.targetSpriteMatrix = targetSpriteMatrix; - - Object.assign(this, { - imagePath: fixPath(imagePath), - alpha, - repeat, - rotation, - twRadiusPercent, - twAngle, - twRotation, - bpRadiusPercent, - bpStrength, - scale, - scaleX, - scaleY, - translationX, - translationY, - play, - loop, - maintainAspectRatio, - maintainScale, - }); - - this.zOrder = 0; - this.autoFit = false; - this.animated = {}; - this.setTMParams(params); - if (!this.dummy) { - this.anime = new Anime(this); - this.normalizeTMParams(); - } - } - - setTMParams(params) { - super.setTMParams(params); - if (!this.dummy && 'imagePath' in params) { - this.assignTexture(); - } - } - - _play = true; - _loop = true; - _maintainAspectRatio = false; - _maintainScale = false; - - get play() { - return this._play; - } - - set play(value) { - if (!(value == null) && typeof value === 'boolean') { - this._play = value; - this._playVideo(this._play); - } - } - - get loop() { - return this._loop; - } - - set loop(value) { - if (!(value == null) && typeof value === 'boolean') { - this._loop = value; - this._playVideo(this._play); - } - } - - get maintainAspectRatio() { - return this._maintainAspectRatio; - } - - set maintainAspectRatio(value) { - if (!(value == null) && typeof value === 'boolean') { - this._maintainAspectRatio = value; - } - } - - get maintainScale() { - return this._maintainScale; - } - - set maintainScale(value) { - if (!(value == null) && typeof value === 'boolean') { - this._maintainScale = value; - } - } - - get alpha() { - return this.uniforms.alpha; - } - - set alpha(value) { - this.uniforms.alpha = value; - } - - get repeat() { - return this.uniforms.repeat; - } - - set repeat(value) { - if (!(value == null) && typeof value === 'boolean') { - this.uniforms.repeat = value; - } - } - - get rotation() { - return this.uniforms.rotation; - } - - set rotation(value) { - this.uniforms.rotation = value; - } - - get twRadiusPercent() { - return this.uniforms.twRadius * 200; - } - - set twRadiusPercent(value) { - this.uniforms.twRadius = value / 200; - } - - get twAngle() { - return this.uniforms.twAngle; - } - - set twAngle(value) { - this.uniforms.twAngle = value; - } - - get twRotation() { - return this.uniforms.twAngle * (180 / Math.PI); - } - - set twRotation(value) { - this.uniforms.twAngle = value * (Math.PI / 180); - } - - get bpRadiusPercent() { - return this.uniforms.bpRadius * 200; - } - - set bpRadiusPercent(value) { - this.uniforms.bpRadius = value / 200; - } - - get bpStrength() { - return this.uniforms.bpStrength; - } - - set bpStrength(value) { - this.uniforms.bpStrength = value; - } - - get scale() { - // a little hack (we get only x) - return this.uniforms.scale[0]; - } - - set scale(value) { - this.uniforms.scale[1] = this.uniforms.scale[0] = value; - } - - get scaleX() { - return this.uniforms.scale[0]; - } - - set scaleX(value) { - this.uniforms.scale[0] = value; - } - - get scaleY() { - return this.uniforms.scale[1]; - } - - set scaleY(value) { - this.uniforms.scale[1] = value; - } - - get translationX() { - return this.uniforms.translation[0]; - } - - set translationX(value) { - this.uniforms.translation[0] = value; - } - - get translationY() { - return this.uniforms.translation[1]; - } - - set translationY(value) { - this.uniforms.translation[1] = value; - } - - get uSamplerTarget() { - return this.uniforms.uSamplerTarget; - } - - set uSamplerTarget(value) { - this.uniforms.uSamplerTarget = value; - } - - async _playVideo(value) { - // Play if baseTexture resource is a video - if (this.tex) { - const source = getProperty(this.tex, 'baseTexture.resource.source'); - if (source && source.tagName === 'VIDEO') { - if (isNaN(source.duration)) { - await new Promise((resolve) => { - source.onloadedmetadata = () => resolve(); - }); - } - if (value) game.video.play(source, { loop: this._loop, volume: 0 }); - else game.video.stop(source); - } - } - } - - assignTexture() { - if (this.hasOwnProperty('imagePath')) { - // Destroy the previous sprite - if (this.targetSprite && !this.targetSprite.destroyed) - this.targetSprite.destroy({ children: true, texture: false, baseTexture: false }); - this.tex = PIXI.Texture.from(this.imagePath); - - let sprite = new PIXI.Sprite(this.tex); - - sprite.renderable = false; - if (this.placeableImg._texture) { - sprite.width = this.placeableImg._texture.baseTexture.realWidth; - sprite.height = this.placeableImg._texture.baseTexture.realHeight; - sprite.anchor.set(0.5); - } else { - sprite.width = this.placeableImg.width; - sprite.height = this.placeableImg.height; - } - - this.targetSprite = sprite; - this.uSamplerTarget = sprite._texture; - this.placeableImg.addChild(sprite); - - this._playVideo(this._play); - } - } - - // override - apply(filterManager, input, output, clear) { - const targetSprite = this.targetSprite; - const tex = targetSprite._texture; - - if (tex.valid) { - if (!tex.uvMatrix) tex.uvMatrix = new PIXI.TextureMatrix(tex, 0.0); - tex.uvMatrix.update(); - - this.uniforms.uSamplerTarget = tex; - if (this.maintainScale) { - let pScale = targetSprite.parent.scale; - targetSprite.scale.set(1 / pScale.x, 1 / pScale.y); - } - - let w = targetSprite.worldTransform; - if (this.maintainAspectRatio) { - let scale = Math.min(w.a, w.d); - w.set(scale, w.b, w.c, scale, w.tx, w.ty); - } - - this.uniforms.targetUVMatrix = filterManager.calculateSpriteMatrix(this.targetSpriteMatrix, targetSprite); - this.uniforms.inputClampTarget = tex.uvMatrix.uClampFrame; - } - - super.apply(filterManager, input, output, clear); - } - - // override - destroy() { - super.destroy(); - if (!this.targetSprite.destroyed) this.targetSprite.destroy({ children: true, texture: false, baseTexture: false }); - } -} - -FilterSpriteMask.defaults = { - alpha: 1, - repeat: false, - rotation: 0.0, - twRadiusPercent: 0, - twAngle: 0, - bpRadiusPercent: 0, - bpStrength: 0, - scaleX: 1, - scaleY: 1, - translationX: 0, - translationY: 0, - play: true, - loop: true, - maintainAspectRatio: false, - maintainScale: false, -}; diff --git a/tokenmagic/fx/filters/FilterTransform.js b/tokenmagic/fx/filters/FilterTransform.js deleted file mode 100644 index f27c1af..0000000 --- a/tokenmagic/fx/filters/FilterTransform.js +++ /dev/null @@ -1,175 +0,0 @@ -import { matrix } from '../glsl/fragmentshaders/matrix.js'; -import { customVertex2D } from '../glsl/vertexshaders/customvertex2D.js'; -import { CustomFilter } from './CustomFilter.js'; -import { Anime } from '../Anime.js'; -import './proto/FilterProto.js'; - -export class FilterTransform extends CustomFilter { - constructor(params) { - let { - rotation, - twRadiusPercent, - twAngle, - twRotation, - bpRadiusPercent, - bpStrength, - scale, - scaleX, - scaleY, - pivotX, - pivotY, - translationX, - translationY, - } = Object.assign({}, FilterTransform.defaults, params); - - super(customVertex2D, matrix); - - this.uniforms.scale = new Float32Array([1.0, 1.0]); - this.uniforms.pivot = new Float32Array([0.5, 0.5]); - this.uniforms.translation = new Float32Array([0.0, 0.0]); - - Object.assign(this, { - rotation, - twRadiusPercent, - twAngle, - twRotation, - bpRadiusPercent, - bpStrength, - scale, - scaleX, - scaleY, - pivotX, - pivotY, - translationX, - translationY, - }); - - this.zOrder = 1000; - this.autoFit = false; - this.animated = {}; - this.setTMParams(params); - if (!this.dummy) { - this.anime = new Anime(this); - this.normalizeTMParams(); - } - } - - get rotation() { - return this.uniforms.rotation; - } - - set rotation(value) { - this.uniforms.rotation = value; - } - - get twRadiusPercent() { - return this.uniforms.twRadius * 200; - } - - set twRadiusPercent(value) { - this.uniforms.twRadius = value / 200; - } - - get twAngle() { - return this.uniforms.twAngle; - } - - set twAngle(value) { - this.uniforms.twAngle = value; - } - - get twRotation() { - return this.uniforms.twAngle * (180 / Math.PI); - } - - set twRotation(value) { - this.uniforms.twAngle = value * (Math.PI / 180); - } - - get bpRadiusPercent() { - return this.uniforms.bpRadius * 200; - } - - set bpRadiusPercent(value) { - this.uniforms.bpRadius = value / 200; - } - - get bpStrength() { - return this.uniforms.bpStrength; - } - - set bpStrength(value) { - this.uniforms.bpStrength = value; - } - - get scale() { - // a little hack (we get only x) - return this.uniforms.scale[0]; - } - - set scale(value) { - this.uniforms.scale[1] = this.uniforms.scale[0] = value; - } - - get scaleX() { - return this.uniforms.scale[0]; - } - - set scaleX(value) { - this.uniforms.scale[0] = value; - } - - get scaleY() { - return this.uniforms.scale[1]; - } - - set scaleY(value) { - this.uniforms.scale[1] = value; - } - - get pivotX() { - return this.uniforms.pivot[0]; - } - - set pivotX(value) { - this.uniforms.pivot[0] = value; - } - - get pivotY() { - return this.uniforms.pivot[1]; - } - - set pivotY(value) { - this.uniforms.pivot[1] = value; - } - - get translationX() { - return this.uniforms.translation[0]; - } - - set translationX(value) { - this.uniforms.translation[0] = value; - } - - get translationY() { - return this.uniforms.translation[1]; - } - - set translationY(value) { - this.uniforms.translation[1] = value; - } -} - -FilterTransform.defaults = { - rotation: 0.0, - twRadiusPercent: 0, - twAngle: 0, - bpRadiusPercent: 0, - bpStrength: 0, - scaleX: 1, - scaleY: 1, - pivotX: 0.5, - pivotY: 0.5, - translationX: 0, - translationY: 0, -}; diff --git a/tokenmagic/fx/filters/FilterTwist.js b/tokenmagic/fx/filters/FilterTwist.js deleted file mode 100644 index 61edc1a..0000000 --- a/tokenmagic/fx/filters/FilterTwist.js +++ /dev/null @@ -1,30 +0,0 @@ -import { Anime } from '../Anime.js'; -import './proto/FilterProto.js'; - -export class FilterTwist extends PIXI.filters.TwistFilter { - constructor(params) { - super(); - this.enabled = false; - this.radiusPercent = 50; - this.angle = 4; - this.zOrder = 240; - this.animated = {}; - this.offset = [0, 0]; - this.autoFit = false; - this.setTMParams(params); - if (!this.dummy) { - this.anime = new Anime(this); - this.normalizeTMParams(); - } - } - - handleTransform() { - this.offset[0] = this.placeableImg.worldTransform.tx; - this.offset[1] = this.placeableImg.worldTransform.ty; - this.radius = - (Math.max(this.placeableImg.width, this.placeableImg.height) * - this.targetPlaceable.worldTransform.a * - this.radiusPercent) / - 200; - } -} diff --git a/tokenmagic/fx/filters/FilterWaves.js b/tokenmagic/fx/filters/FilterWaves.js deleted file mode 100644 index ca729dc..0000000 --- a/tokenmagic/fx/filters/FilterWaves.js +++ /dev/null @@ -1,127 +0,0 @@ -import { magicWaves } from '../glsl/fragmentshaders/waves.js'; -import { customVertex2D } from '../glsl/vertexshaders/customvertex2D.js'; -import { CustomFilter } from './CustomFilter.js'; -import { Anime } from '../Anime.js'; -import './proto/FilterProto.js'; - -export class FilterWaves extends CustomFilter { - constructor(params) { - let { time, color, inward, frequency, strength, minIntensity, maxIntensity, anchorX, anchorY } = Object.assign( - {}, - FilterWaves.defaults, - params - ); - - // using specific vertex shader and fragment shader - super(customVertex2D, magicWaves); - - this.uniforms.color = new Float32Array([1.0, 1.0, 1.0]); - this.uniforms.anchor = new Float32Array([0.5, 0.5]); - - Object.assign(this, { - time, - color, - inward, - frequency, - strength, - minIntensity, - maxIntensity, - anchorX, - anchorY, - }); - - this.zOrder = 280; - this.animated = {}; - this.setTMParams(params); - if (!this.dummy) { - this.anime = new Anime(this); - this.normalizeTMParams(); - } - } - - get time() { - return this.uniforms.time; - } - - set time(value) { - this.uniforms.time = value; - } - - get color() { - return PIXI.utils.rgb2hex(this.uniforms.color); - } - - set color(value) { - new PIXI.Color(value).toRgbArray(this.uniforms.color); - } - - get inward() { - return this.uniforms.inward; - } - - set inward(value) { - if (!(value == null) && typeof value === 'boolean') { - this.uniforms.inward = value; - } - } - - get anchorX() { - return this.uniforms.anchor[0]; - } - - set anchorX(value) { - this.uniforms.anchor[0] = value; - } - - get anchorY() { - return this.uniforms.anchor[1]; - } - - set anchorY(value) { - this.uniforms.anchor[1] = value; - } - - get frequency() { - return this.uniforms.frequency; - } - - set frequency(value) { - this.uniforms.frequency = value; - } - - get strength() { - return this.uniforms.strength; - } - - set strength(value) { - this.uniforms.strength = value; - } - - get minIntensity() { - return this.uniforms.minIntensity; - } - - set minIntensity(value) { - this.uniforms.minIntensity = value; - } - - get maxIntensity() { - return this.uniforms.maxIntensity; - } - - set maxIntensity(value) { - this.uniforms.maxIntensity = value; - } -} - -FilterWaves.defaults = { - time: 0, - color: 0xffffff, - inward: false, - frequency: 35, - strength: 0.01, - minIntensity: 1.2, - maxIntensity: 3.5, - anchorX: 0.5, - anchorY: 0.5, -}; diff --git a/tokenmagic/fx/filters/FilterXFire.js b/tokenmagic/fx/filters/FilterXFire.js deleted file mode 100644 index 7fc6410..0000000 --- a/tokenmagic/fx/filters/FilterXFire.js +++ /dev/null @@ -1,207 +0,0 @@ -import { burnXFire } from '../glsl/fragmentshaders/xfire.js'; -import { customVertex2D } from '../glsl/vertexshaders/customvertex2D.js'; -import { CustomFilter } from './CustomFilter.js'; -import { Anime } from '../Anime.js'; -import './proto/FilterProto.js'; - -export class FilterXFire extends CustomFilter { - constructor(params) { - let { - time, - color, - color1, - color2, - color3, - color4, - amplitude, - dispersion, - blend, - scaleX, - scaleY, - alphaDiscard, - discardThreshold, - chromatic, - inlay, - } = Object.assign({}, FilterXFire.defaults, params); - - // using specific vertex shader and fragment shader - super(customVertex2D, burnXFire); - - this.uniforms.color = new Float32Array([1.0, 1.0, 1.0]); - this.uniforms.color1 = new Float32Array([1.0, 1.0, 1.0]); - this.uniforms.color2 = new Float32Array([1.0, 1.0, 1.0]); - this.uniforms.color3 = new Float32Array([1.0, 1.0, 1.0]); - this.uniforms.color4 = new Float32Array([1.0, 1.0, 1.0]); - this.uniforms.scale = new Float32Array([1.0, 1.0]); - - Object.assign(this, { - time, - color, - color1, - color2, - color3, - color4, - amplitude, - dispersion, - blend, - scaleX, - scaleY, - alphaDiscard, - discardThreshold, - chromatic, - inlay, - }); - - this.zOrder = 145; - this.animated = {}; - this.setTMParams(params); - if (!this.dummy) { - this.anime = new Anime(this); - this.normalizeTMParams(); - } - } - - get time() { - return this.uniforms.time; - } - - set time(value) { - this.uniforms.time = value; - } - - get color() { - return PIXI.utils.rgb2hex(this.uniforms.color); - } - - set color(value) { - new PIXI.Color(value).toRgbArray(this.uniforms.color); - } - - get color1() { - return PIXI.utils.rgb2hex(this.uniforms.color1); - } - - set color1(value) { - new PIXI.Color(value).toRgbArray(this.uniforms.color1); - } - - get color2() { - return PIXI.utils.rgb2hex(this.uniforms.color2); - } - - set color2(value) { - new PIXI.Color(value).toRgbArray(this.uniforms.color2); - } - - get color3() { - return PIXI.utils.rgb2hex(this.uniforms.color3); - } - - set color3(value) { - new PIXI.Color(value).toRgbArray(this.uniforms.color3); - } - - get color4() { - return PIXI.utils.rgb2hex(this.uniforms.color4); - } - - set color4(value) { - new PIXI.Color(value).toRgbArray(this.uniforms.color4); - } - - get amplitude() { - return this.uniforms.amplitude; - } - - set amplitude(value) { - this.uniforms.amplitude = value; - } - - get dispersion() { - return this.uniforms.dispersion; - } - - set dispersion(value) { - this.uniforms.dispersion = value; - } - - get blend() { - return this.uniforms.blend; - } - - set blend(value) { - this.uniforms.blend = Math.floor(value); - } - - get scaleX() { - return this.uniforms.scale[0]; - } - - set scaleX(value) { - this.uniforms.scale[0] = value; - } - - get scaleY() { - return this.uniforms.scale[1]; - } - - set scaleY(value) { - this.uniforms.scale[1] = value; - } - - get alphaDiscard() { - return this.uniforms.alphaDiscard; - } - - set alphaDiscard(value) { - if (!(value == null) && typeof value === 'boolean') { - this.uniforms.alphaDiscard = value; - } - } - - get discardThreshold() { - return this.uniforms.discardThreshold; - } - - set discardThreshold(value) { - this.uniforms.discardThreshold = value; - } - - get chromatic() { - return this.uniforms.chromatic; - } - - set chromatic(value) { - if (!(value == null) && typeof value === 'boolean') { - this.uniforms.chromatic = value; - } - } - - get inlay() { - return this.uniforms.inlay; - } - - set inlay(value) { - if (!(value == null) && typeof value === 'boolean') { - this.uniforms.inlay = value; - } - } -} - -FilterXFire.defaults = { - time: 0, - color: 0x000000, - color1: 0x250000, - color2: 0xb20000, - color3: 0x330000, - color4: 0xffe500, - amplitude: 1, - dispersion: 0.25, - blend: 2, - scaleX: 1, - scaleY: 1, - discardThreshold: 0.1, - alphaDiscard: false, - chromatic: false, - inlay: false, -}; diff --git a/tokenmagic/fx/filters/FilterXFog.js b/tokenmagic/fx/filters/FilterXFog.js deleted file mode 100644 index 8508331..0000000 --- a/tokenmagic/fx/filters/FilterXFog.js +++ /dev/null @@ -1,61 +0,0 @@ -import { xFog } from '../glsl/fragmentshaders/xfog.js'; -import { customVertex2D } from '../glsl/vertexshaders/customvertex2D.js'; -import { CustomFilter } from './CustomFilter.js'; -import { Anime } from '../Anime.js'; - -export class FilterXFog extends CustomFilter { - constructor(params) { - let { time, color, alphaDiscard } = Object.assign({}, FilterXFog.defaults, params); - - // specific vertex and fragment shaders - super(customVertex2D, xFog); - - this.uniforms.color = new Float32Array([1.0, 0.4, 0.1, 0.55]); - - Object.assign(this, { - time, - color, - alphaDiscard, - }); - - this.zOrder = 230; - this.animated = {}; - this.setTMParams(params); - if (!this.dummy) { - this.anime = new Anime(this); - this.normalizeTMParams(); - } - } - - get time() { - return this.uniforms.time; - } - - set time(value) { - this.uniforms.time = value; - } - - get color() { - return PIXI.utils.rgb2hex(this.uniforms.color); - } - - set color(value) { - new PIXI.Color(value).toRgbArray(this.uniforms.color); - } - - get alphaDiscard() { - return this.uniforms.alphaDiscard; - } - - set alphaDiscard(value) { - if (!(value == null) && typeof value === 'boolean') { - this.uniforms.alphaDiscard = value; - } - } -} - -FilterXFog.defaults = { - time: 0.0, - color: 0xffffff, - alphaDiscard: false, -}; diff --git a/tokenmagic/fx/filters/FilterXRays.js b/tokenmagic/fx/filters/FilterXRays.js deleted file mode 100644 index 7cc0d57..0000000 --- a/tokenmagic/fx/filters/FilterXRays.js +++ /dev/null @@ -1,126 +0,0 @@ -import { xRay } from '../glsl/fragmentshaders/xray.js'; -import { customVertex2D } from '../glsl/vertexshaders/customvertex2D.js'; -import { CustomFilter } from './CustomFilter.js'; -import { Anime } from '../Anime.js'; -import './proto/FilterProto.js'; - -export class FilterXRays extends CustomFilter { - constructor(params) { - let { time, color, divisor, intensity, blend, anchorX, anchorY, dimX, dimY } = Object.assign( - {}, - FilterXRays.defaults, - params - ); - - // using specific vertex shader and fragment shader - super(customVertex2D, xRay); - - this.uniforms.color = new Float32Array([1.0, 0.4, 0.1]); - this.uniforms.anchor = new Float32Array([0.5, -1.0]); - this.uniforms.dimensions = new Float32Array([1.0, 1.0]); - - Object.assign(this, { - time, - color, - divisor, - intensity, - blend, - anchorX, - anchorY, - dimX, - dimY, - }); - - this.zOrder = 130; - this.animated = {}; - this.setTMParams(params); - if (!this.dummy) { - this.anime = new Anime(this); - this.normalizeTMParams(); - } - } - - get time() { - return this.uniforms.time; - } - - set time(value) { - this.uniforms.time = value; - } - - get color() { - return PIXI.utils.rgb2hex(this.uniforms.color); - } - - set color(value) { - new PIXI.Color(value).toRgbArray(this.uniforms.color); - } - - get divisor() { - return this.uniforms.divisor; - } - - set divisor(value) { - this.uniforms.divisor = value; - } - - get intensity() { - return this.uniforms.intensity; - } - - set intensity(value) { - this.uniforms.intensity = value; - } - - get blend() { - return this.uniforms.blend; - } - - set blend(value) { - this.uniforms.blend = Math.floor(value); - } - - get anchorX() { - return this.uniforms.anchor[0]; - } - - set anchorX(value) { - this.uniforms.anchor[0] = value; - } - - get anchorY() { - return this.uniforms.anchor[1]; - } - - set anchorY(value) { - this.uniforms.anchor[1] = value; - } - - get dimX() { - return this.uniforms.dimensions[0]; - } - - set dimX(value) { - this.uniforms.dimensions[0] = value; - } - - get dimY() { - return this.uniforms.dimensions[1]; - } - - set dimY(value) { - this.uniforms.dimensions[1] = value; - } -} - -FilterXRays.defaults = { - time: 0.0, - color: 0xff8010, - divisor: 40, - intensity: 0.1, - blend: 8, - anchorX: 0.5, - anchorY: -1.0, - dimX: 1, - dimY: 1, -}; diff --git a/tokenmagic/fx/filters/FilterZoomBlur.js b/tokenmagic/fx/filters/FilterZoomBlur.js deleted file mode 100644 index e1d6558..0000000 --- a/tokenmagic/fx/filters/FilterZoomBlur.js +++ /dev/null @@ -1,34 +0,0 @@ -import { Anime } from '../Anime.js'; -import './proto/FilterProto.js'; - -export class FilterZoomBlur extends PIXI.filters.ZoomBlurFilter { - constructor(params) { - super(); - this.enabled = false; - this.strength = 0.1; - this.radiusPercent = 50; - this.innerRadiusPercent = 10; - this.zOrder = 300; - this.animated = {}; - this.setTMParams(params); - if (!this.dummy) { - this.anime = new Anime(this); - this.normalizeTMParams(); - } - } - - handleTransform(state) { - this.center[0] = 0.5 * state.sourceFrame.width; - this.center[1] = 0.5 * state.sourceFrame.height; - this.radius = - (Math.max(this.placeableImg.width, this.placeableImg.height) * - this.targetPlaceable.worldTransform.a * - this.radiusPercent) / - 200; - this.innerRadius = - (Math.max(this.placeableImg.width, this.placeableImg.height) * - this.targetPlaceable.worldTransform.a * - this.innerRadiusPercent) / - 200; - } -} diff --git a/tokenmagic/fx/filters/proto/FilterProto.js b/tokenmagic/fx/filters/proto/FilterProto.js deleted file mode 100644 index 6138d8f..0000000 --- a/tokenmagic/fx/filters/proto/FilterProto.js +++ /dev/null @@ -1,177 +0,0 @@ -import { getPlaceableById, getMinPadding, PlaceableType } from '../../../module/tokenmagic.js'; -import '../../../module/proto/PlaceableObjectProto.js'; - -PIXI.Filter.prototype.setTMParams = function (params) { - this.autoDisable = false; - this.autoDestroy = false; - this.gridPadding = 0; - this.boundsPadding = new PIXI.Point(0, 0); - this.currentPadding = 0; - this.recalculatePadding = true; - this.dummy = false; - foundry.utils.mergeObject(this, params); - if (!this.dummy) { - this.rawPadding = this.rawPadding ?? this.padding ?? 0; - this.originalPadding = Math.max(this.rawPadding, getMinPadding()); - this.assignPlaceable(); - this.activateTransform(); - Object.defineProperty(this, 'padding', { - get: function () { - if (this.recalculatePadding) this.calculatePadding(); - return this.currentPadding; - }, - set: function (padding) { - this.rawPadding = padding; - this.originalPadding = Math.max(padding, getMinPadding()); - }, - }); - } else { - this.apply = function (filterManager, input, output, clear) { - filterManager.applyFilter(this, input, output, clear); - }; - } -}; - -PIXI.Filter.prototype.getPlaceable = function () { - return getPlaceableById(this.placeableId, this.placeableType); -}; - -PIXI.Filter.prototype.getPlaceableType = function () { - return this.placeableType; -}; - -PIXI.Filter.prototype.calculatePadding = function () { - const target = this.placeableImg; - let width; - let height; - - { - const ang = !this.sticky && this.placeableType !== PlaceableType.TOKEN ? target.rotation : 0; - const sin = Math.sin(ang); - const cos = Math.cos(ang); - width = Math.abs(target.width * cos) + Math.abs(target.height * sin); - height = Math.abs(target.width * sin) + Math.abs(target.height * cos); - } - - if (this.gridPadding > 0) { - const gridSize = canvas.dimensions.size; - this.boundsPadding.x = this.boundsPadding.y = (this.gridPadding - 1) * gridSize; - this.boundsPadding.x += (gridSize - 1 - ((width + gridSize - 1) % gridSize)) / 2; - this.boundsPadding.y += (gridSize - 1 - ((height + gridSize - 1) % gridSize)) / 2; - } else { - this.boundsPadding.x = this.boundsPadding.y = this.rawPadding; - } - - { - const ang = this.sticky ? target.rotation : 0; - const sin = Math.sin(ang); - const cos = Math.cos(ang); - this.currentPadding = - Math.max( - Math.abs(this.boundsPadding.x * cos) + Math.abs(this.boundsPadding.y * sin), - Math.abs(this.boundsPadding.x * sin) + Math.abs(this.boundsPadding.y * cos) - ) + - (this.originalPadding - this.rawPadding); - } - - this.boundsPadding.x += (width - target.width) / 2; - this.boundsPadding.y += (height - target.height) / 2; - - const scale = this.targetPlaceable.worldTransform.a; - - this.boundsPadding.x *= scale; - this.boundsPadding.y *= scale; - this.currentPadding *= scale; -}; - -PIXI.Filter.prototype.assignPlaceable = function () { - this.targetPlaceable = this.getPlaceable(); - this.targetPlaceable != null - ? (this.placeableImg = this.targetPlaceable._TMFXgetSprite()) - : (this.placeableImg = null); -}; - -PIXI.Filter.prototype.activateTransform = function () { - this.preComputation = this.filterTransform; - this.filterTransform(); - - const apply = this.apply; - this.apply = function (filterManager, input, output, clear, state) { - if ('handleTransform' in this) { - this.handleTransform(state); - } - return apply.apply(this, arguments); - }; -}; - -PIXI.Filter.prototype.filterTransform = function () { - if (this.hasOwnProperty('zIndex')) { - this.targetPlaceable.zIndex = this.zIndex; - } -}; - -PIXI.Filter.prototype.normalizeTMParams = function () { - if (this.hasOwnProperty('animated') && !(this.animated == null)) { - // Normalize animations properties - Object.keys(this.animated).forEach((effect) => { - if (this.animated[effect].active == null || typeof this.animated[effect].active != 'boolean') { - this.animated[effect].active = true; - } - if ( - this.animated[effect].loops == null || - typeof this.animated[effect].loops != 'number' || - this.animated[effect].loops <= 0 - ) { - this.animated[effect].loops = Infinity; - } - if ( - this.animated[effect].loopDuration == null || - typeof this.animated[effect].loopDuration != 'number' || - this.animated[effect].loopDuration <= 0 - ) { - this.animated[effect].loopDuration = 3000; - } - if (this.animated[effect].clockWise == null || typeof this.animated[effect].clockWise != 'boolean') { - this.animated[effect].clockWise = true; - } - if ( - this.animated[effect].pauseBetweenDuration == null || - typeof this.animated[effect].pauseBetweenDuration != 'number' || - this.animated[effect].pauseBetweenDuration <= 0 - ) { - this.animated[effect].pauseBetweenDuration = 0; - } - if ( - this.animated[effect].syncShift == null || - typeof this.animated[effect].syncShift != 'number' || - this.animated[effect].syncShift < 0 - ) { - this.animated[effect].syncShift = 0; - } - if (this.animated[effect].val1 == null || typeof this.animated[effect].val1 != 'number') { - this.animated[effect].val1 = 0; - } - if (this.animated[effect].val2 == null || typeof this.animated[effect].val2 != 'number') { - this.animated[effect].val2 = 0; - } - if (this.anime[this.animated[effect].animType] === undefined) { - this.animated[effect].animType = null; - } - if (this.animated[effect].speed == null || typeof this.animated[effect].speed != 'number') { - this.animated[effect].speed = 0; - } - if (this.animated[effect].chaosFactor == null || typeof this.animated[effect].chaosFactor != 'number') { - this.animated[effect].chaosFactor = 0.25; - } - if (this.animated[effect].wantInteger == null || typeof this.animated[effect].wantInteger != 'boolean') { - this.animated[effect].wantInteger = false; - } - - if (!this.anime.hasInternals(effect)) { - this.anime.initInternals(effect); - } - - this.anime.animated = this.animated; - }); - } -}; diff --git a/tokenmagic/fx/presets/defaultpresets.js b/tokenmagic/fx/presets/defaultpresets.js deleted file mode 100644 index ec735a8..0000000 --- a/tokenmagic/fx/presets/defaultpresets.js +++ /dev/null @@ -1,2677 +0,0 @@ -export const PresetsLibrary = { - MAIN: 'tmfx-main', - TEMPLATE: 'tmfx-template', -}; - -export var presets = []; - -let params = [ - { - filterType: 'bevel', - filterId: 'bevel', - rotation: 0, - thickness: 5, - lightColor: 0xff0000, - lightAlpha: 0.8, - shadowColor: 0x00ff00, - shadowAlpha: 0.5, - animated: { - rotation: { - active: true, - clockWise: true, - loopDuration: 1600, - animType: 'syncRotation', - }, - }, - }, -]; - -var presetObject = {}; -presetObject.name = 'bevel'; -presetObject.library = PresetsLibrary.MAIN; -presetObject.params = params; -presets.push(presetObject); - -params = [ - { - filterType: 'adjustment', - filterId: 'adjustment', - saturation: 1.5, - brightness: 1.5, - contrast: 2, - gamma: 2, - red: 4, - green: 0.25, - blue: 0.25, - alpha: 1, - animated: { - alpha: { - active: true, - loopDuration: 5000, - animType: 'syncCosOscillation', - val1: 0.15, - val2: 1, - }, - }, - }, -]; - -presetObject = new Object(); -presetObject.name = 'adjustment'; -presetObject.library = PresetsLibrary.MAIN; -presetObject.params = params; -presets.push(presetObject); - -params = [ - { - filterType: 'shadow', - filterId: 'dropshadow', - rotation: 35, - blur: 2, - quality: 5, - distance: 20, - alpha: 0.7, - padding: 10, - shadowOnly: false, - color: 0x000000, - animated: { - blur: { - active: true, - loopDuration: 1500, - animType: 'syncCosOscillation', - val1: 2, - val2: 3, - }, - rotation: { - active: true, - loopDuration: 150, - animType: 'syncSinOscillation', - val1: 33, - val2: 35, - }, - }, - }, -]; - -presetObject = new Object(); -presetObject.name = 'dropshadow'; -presetObject.library = PresetsLibrary.MAIN; -presetObject.params = params; -presets.push(presetObject); - -params = [ - { - filterType: 'outline', - filterId: 'outline', - padding: 10, - color: 0xee6035, - thickness: 1, - quality: 5, - animated: { - thickness: { - active: true, - loopDuration: 800, - animType: 'syncCosOscillation', - val1: 1, - val2: 6, - }, - }, - }, -]; - -presetObject = new Object(); -presetObject.name = 'outline'; -presetObject.library = PresetsLibrary.MAIN; -presetObject.params = params; -presets.push(presetObject); - -params = [ - { - filterType: 'glow', - filterId: 'glow', - outerStrength: 7, - innerStrength: 0, - color: 0x006000, - quality: 0.5, - padding: 10, - animated: { - color: { - active: true, - loopDuration: 3000, - animType: 'colorOscillation', - val1: 0x003000, - val2: 0x00ff00, - }, - }, - }, -]; - -presetObject = new Object(); -presetObject.name = 'glow'; -presetObject.library = PresetsLibrary.MAIN; -presetObject.params = params; -presets.push(presetObject); - -params = [ - { - filterType: 'xbloom', - filterId: 'bloom', - threshold: 0.35, - bloomScale: 0, - brightness: 1, - blur: 0.1, - padding: 10, - quality: 15, - blendMode: 0, - animated: { - bloomScale: { - active: true, - loopDuration: 2000, - animType: 'syncCosOscillation', - val1: 0, - val2: 2.1, - }, - threshold: { - active: false, - loopDuration: 1000, - animType: 'syncCosOscillation', - val1: 0.0, - val2: 1.9, - }, - }, - }, -]; - -presetObject = new Object(); -presetObject.name = 'bloom'; -presetObject.library = PresetsLibrary.MAIN; -presetObject.params = params; -presets.push(presetObject); - -params = [ - { - filterType: 'distortion', - filterId: 'distortion', - maskPath: 'modules/tokenmagic/fx/assets/distortion-1.png', - maskSpriteScaleX: 5, - maskSpriteScaleY: 5, - padding: 20, - animated: { - maskSpriteX: { active: true, speed: 0.05, animType: 'move' }, - maskSpriteY: { active: true, speed: 0.07, animType: 'move' }, - }, - }, -]; - -presetObject = new Object(); -presetObject.name = 'distortion'; -presetObject.library = PresetsLibrary.MAIN; -presetObject.params = params; -presets.push(presetObject); - -params = [ - { - filterType: 'oldfilm', - filterId: 'oldfilm', - sepia: 0.6, - noise: 0.2, - noiseSize: 1.0, - scratch: 0.8, - scratchDensity: 0.5, - scratchWidth: 1.2, - vignetting: 0.9, - vignettingAlpha: 0.6, - vignettingBlur: 0.2, - animated: { - seed: { - active: true, - animType: 'randomNumber', - val1: 0, - val2: 1, - }, - vignetting: { - active: true, - animType: 'syncCosOscillation', - loopDuration: 2000, - val1: 0.2, - val2: 0.4, - }, - }, - }, - { - filterType: 'outline', - filterId: 'oldfilm', - color: 0x000000, - thickness: 0, - }, -]; - -presetObject = new Object(); -presetObject.name = 'oldfilm'; -presetObject.library = PresetsLibrary.MAIN; -presetObject.params = params; -presets.push(presetObject); - -params = [ - { - filterType: 'twist', - filterId: 'twist', - radiusPercent: 120, - angle: 0, - animated: { - angle: { - active: true, - animType: 'sinOscillation', - loopDuration: 10000, - val1: -0.6 * Math.PI, - val2: +0.6 * Math.PI, - }, - }, - }, -]; - -presetObject = new Object(); -presetObject.name = 'twist'; -presetObject.library = PresetsLibrary.MAIN; -presetObject.params = params; -presets.push(presetObject); - -params = [ - { - filterType: 'bulgepinch', - filterId: 'bulge', - padding: 150, - strength: 0, - zIndex: 2, - radiusPercent: 200, - animated: { - strength: { - active: true, - animType: 'cosOscillation', - loopDuration: 2000, - val1: 0, - val2: 0.45, - }, - }, - }, -]; - -presetObject = new Object(); -presetObject.name = 'bulge'; -presetObject.library = PresetsLibrary.MAIN; -presetObject.params = params; -presets.push(presetObject); - -params = [ - { - filterType: 'blur', - filterId: 'blur', - padding: 10, - quality: 4.0, - blur: 0, - blurX: 0, - blurY: 0, - animated: { - blurX: { - active: true, - animType: 'syncCosOscillation', - loopDuration: 500, - val1: 0, - val2: 6, - }, - blurY: { - active: true, - animType: 'syncCosOscillation', - loopDuration: 750, - val1: 0, - val2: 6, - }, - }, - }, -]; - -presetObject = new Object(); -presetObject.name = 'blur'; -presetObject.library = PresetsLibrary.MAIN; -presetObject.params = params; -presets.push(presetObject); - -params = [ - { - filterType: 'zoomblur', - filterId: 'zoomblur', - strength: 0.15, - innerRadiusPercent: 65, - radiusPercent: 100, - padding: 30, - animated: { - innerRadiusPercent: { - active: true, - animType: 'sinOscillation', - loopDuration: 500, - val1: 65, - val2: 75, - }, - }, - }, -]; - -presetObject = new Object(); -presetObject.name = 'zoomblur'; -presetObject.library = PresetsLibrary.MAIN; -presetObject.params = params; -presets.push(presetObject); - -params = [ - { - filterType: 'shockwave', - filterId: 'shockwave', - time: 0, - amplitude: 8, - wavelength: 75, - radius: 500, - brightness: 1.5, - speed: 25, - padding: 0, - animated: { - time: { - animType: 'cosOscillation', - active: true, - loopDuration: 1800, - val1: 0, - val2: 10, - }, - }, - }, -]; - -presetObject = new Object(); -presetObject.name = 'shockwave'; -presetObject.library = PresetsLibrary.MAIN; -presetObject.params = params; -presets.push(presetObject); - -params = [ - { - filterType: 'zapshadow', - filterId: 'zapshadow', - alphaTolerance: 0.45, - }, -]; - -presetObject = new Object(); -presetObject.name = 'zapshadow'; -presetObject.library = PresetsLibrary.MAIN; -presetObject.params = params; -presets.push(presetObject); - -params = [ - { - filterType: 'ray', - filterId: 'rays', - time: 0, - color: 0xcf8000, - alpha: 0.5, - divisor: 32, - anchorX: 0, - anchorY: 0, - animated: { - time: { - active: true, - speed: 0.0005, - animType: 'move', - }, - }, - }, -]; - -presetObject = new Object(); -presetObject.name = 'rays'; -presetObject.library = PresetsLibrary.MAIN; -presetObject.params = params; -presets.push(presetObject); - -params = [ - { - filterType: 'fog', - filterId: 'fog', - color: 0x000000, - density: 0.65, - time: 0, - dimX: 1, - dimY: 1, - animated: { - time: { - active: true, - speed: 2.2, - animType: 'move', - }, - }, - }, -]; - -presetObject = new Object(); -presetObject.name = 'fog'; -presetObject.library = PresetsLibrary.MAIN; -presetObject.params = params; -presets.push(presetObject); - -params = [ - { - filterType: 'fumes', - filterId: 'fumes', - color: 0x808080, - time: 0, - blend: 8, - animated: { - time: { - active: true, - speed: 0.001, - animType: 'move', - }, - }, - }, -]; - -presetObject = new Object(); -presetObject.name = 'fumes'; -presetObject.library = PresetsLibrary.MAIN; -presetObject.params = params; -presets.push(presetObject); - -params = [ - { - filterType: 'electric', - filterId: 'electric', - color: 0xffffff, - time: 0, - blend: 1, - intensity: 5, - animated: { - time: { - active: true, - speed: 0.002, - animType: 'move', - }, - }, - }, -]; - -presetObject = new Object(); -presetObject.name = 'electric'; -presetObject.library = PresetsLibrary.MAIN; -presetObject.params = params; -presets.push(presetObject); - -params = [ - { - filterType: 'fire', - filterId: 'fire', - intensity: 1, - color: 0xffffff, - amplitude: 1, - time: 0, - blend: 2, - fireBlend: 1, - animated: { - time: { - active: true, - speed: -0.0024, - animType: 'move', - }, - intensity: { - active: true, - loopDuration: 15000, - val1: 0.8, - val2: 2, - animType: 'syncCosOscillation', - }, - amplitude: { - active: true, - loopDuration: 4400, - val1: 1, - val2: 1.4, - animType: 'syncCosOscillation', - }, - }, - }, -]; - -presetObject = new Object(); -presetObject.name = 'fire'; -presetObject.library = PresetsLibrary.MAIN; -presetObject.params = params; -presets.push(presetObject); - -params = [ - { - filterType: 'wave', - filterId: 'waves', - time: 0, - anchorX: 0.5, - anchorY: 0.5, - strength: 0.015, - frequency: 120, - color: 0xffffff, - maxIntensity: 2.5, - minIntensity: 0.9, - padding: 10, - animated: { - time: { - active: true, - speed: 0.0085, - animType: 'move', - }, - anchorX: { - active: false, - val1: 0.15, - val2: 0.85, - animType: 'syncChaoticOscillation', - loopDuration: 20000, - }, - anchorY: { - active: false, - val1: 0.15, - val2: 0.85, - animType: 'syncSinOscillation', - loopDuration: 20000, - }, - }, - }, -]; - -presetObject = new Object(); -presetObject.name = 'waves'; -presetObject.library = PresetsLibrary.MAIN; -presetObject.params = params; -presets.push(presetObject); - -params = [ - { - filterType: 'flood', - filterId: 'flood', - time: 0, - color: 0x0020bb, - billowy: 0.43, - tintIntensity: 0.72, - glint: 0.31, - scale: 70, - padding: 10, - animated: { - time: { - active: true, - speed: 0.0006, - animType: 'move', - }, - }, - }, -]; - -presetObject = new Object(); -presetObject.name = 'flood'; -presetObject.library = PresetsLibrary.MAIN; -presetObject.params = params; -presets.push(presetObject); - -params = [ - { - filterType: 'smoke', - filterId: 'smoke', - color: 0x5099dd, - time: 0, - blend: 2, - dimX: 0.1, - dimY: 1, - animated: { - time: { - active: true, - speed: 0.009, - animType: 'move', - }, - }, - }, -]; - -presetObject = new Object(); -presetObject.name = 'smoke'; -presetObject.library = PresetsLibrary.MAIN; -presetObject.params = params; -presets.push(presetObject); - -params = [ - { - filterType: 'images', - filterId: 'images', - time: 0, - nbImage: 4, - alphaImg: 1.0, - alphaChr: 0.0, - blend: 4, - ampX: 0.1, - ampY: 0.1, - animated: { - time: { - active: true, - speed: 0.001, - animType: 'move', - }, - }, - }, -]; - -presetObject = new Object(); -presetObject.name = 'images'; -presetObject.library = PresetsLibrary.MAIN; -presetObject.params = params; -presets.push(presetObject); - -params = [ - { - filterType: 'images', - filterId: 'chaos-images', - time: 0, - nbImage: 4, - alphaImg: 1.0, - alphaChr: 0.0, - blend: 4, - ampX: 0.1, - ampY: 0.1, - padding: 80, - animated: { - time: { - active: true, - speed: 0.001, - animType: 'move', - }, - ampX: { - active: true, - val1: 0.0, - val2: 0.3, - chaosFactor: 0.03, - animType: 'syncChaoticOscillation', - loopDuration: 2000, - }, - ampY: { - active: true, - val1: 0.0, - val2: 0.3, - chaosFactor: 0.04, - animType: 'syncChaoticOscillation', - loopDuration: 1650, - }, - alphaChr: { - active: true, - animType: 'randomNumberPerLoop', - val1: 0.0, - val2: 1, - loopDuration: 250, - }, - alphaImg: { - active: true, - animType: 'randomNumberPerLoop', - val1: 0.8, - val2: 1, - loopDuration: 250, - }, - nbImage: { - active: true, - val1: 1, - val2: 9, - animType: 'syncSinOscillation', - loopDuration: 1400, - }, - }, - }, -]; - -presetObject = new Object(); -presetObject.name = 'chaos-images'; -presetObject.library = PresetsLibrary.MAIN; -presetObject.params = params; -presets.push(presetObject); - -params = [ - { - filterType: 'images', - filterId: 'spectral-images', - time: 0, - blend: 4, - nbImage: 4, - padding: 100, - alphaImg: 0.5, - alphaChr: 0.0, - ampX: 0.1, - ampY: 0.1, - animated: { - time: { - speed: 0.001, - animType: 'move', - }, - ampX: { - val1: 0, - val2: 0.22, - animType: 'syncCosOscillation', - loopDuration: 2500, - }, - ampY: { - val1: 0, - val2: 0.24, - animType: 'syncCosOscillation', - loopDuration: 2500, - pauseBetweenDuration: 2500, - }, - alphaChr: { - val1: 1, - val2: 0, - animType: 'syncCosOscillation', - loopDuration: 2500, - }, - alphaImg: { - val1: 0.2, - val2: 0.8, - animType: 'syncSinOscillation', - loopDuration: 2500, - }, - }, - }, -]; - -presetObject = new Object(); -presetObject.name = 'spectral-images'; -presetObject.library = PresetsLibrary.MAIN; -presetObject.params = params; -presets.push(presetObject); - -params = [ - { - filterType: 'field', - filterId: 'hexa-field', - shieldType: 2, - gridPadding: 1.5, - color: 0xcc00cc, - time: 0, - blend: 3, - intensity: 1, - lightAlpha: 0.5, - lightSize: 0.5, - scale: 1, - radius: 1, - chromatic: false, - animated: { - time: { - active: true, - speed: 0.0015, - animType: 'move', - }, - }, - }, -]; - -presetObject = new Object(); -presetObject.name = 'hexa-field'; -presetObject.library = PresetsLibrary.MAIN; -presetObject.params = params; -presets.push(presetObject); - -params = [ - { - filterType: 'field', - filterId: 'fire-field', - shieldType: 1, - gridPadding: 2, - color: 0xe58550, - time: 0, - blend: 2, - intensity: 1.15, - lightAlpha: 2, - lightSize: 0.7, - scale: 1, - radius: 1, - chromatic: false, - animated: { - time: { - active: true, - speed: 0.0015, - animType: 'move', - }, - }, - }, -]; - -presetObject = new Object(); -presetObject.name = 'fire-field'; -presetObject.library = PresetsLibrary.MAIN; -presetObject.params = params; -presets.push(presetObject); - -params = [ - { - filterType: 'field', - filterId: 'smoke-field', - shieldType: 3, - gridPadding: 1.5, - color: 0x60cc70, - time: 0, - blend: 2, - intensity: 0.9, - lightAlpha: 1, - lightSize: 0.7, - scale: 1, - radius: 1, - chromatic: false, - animated: { - time: { - active: true, - speed: 0.0015, - animType: 'move', - }, - }, - }, -]; - -presetObject = new Object(); -presetObject.name = 'smoke-field'; -presetObject.library = PresetsLibrary.MAIN; -presetObject.params = params; -presets.push(presetObject); - -params = [ - { - filterType: 'field', - filterId: 'earth-field', - shieldType: 4, - gridPadding: 2, - color: 0xbb9070, - time: 0, - blend: 1, - intensity: 1.25, - lightAlpha: 1, - lightSize: 0.7, - scale: 1, - radius: 1, - chromatic: false, - animated: { - time: { - active: true, - speed: 0.0015, - animType: 'move', - }, - }, - }, -]; - -presetObject = new Object(); -presetObject.name = 'earth-field'; -presetObject.library = PresetsLibrary.MAIN; -presetObject.params = params; -presets.push(presetObject); - -params = [ - { - filterType: 'field', - filterId: 'earth-field-top', - shieldType: 5, - gridPadding: 3, - color: 0xaaaaaa, - time: 0, - blend: 5, - intensity: 1.9, - lightAlpha: 1, - lightSize: 0.7, - scale: 1, - radius: 1, - zIndex: 5, - chromatic: true, - animated: { - time: { - active: true, - speed: 0.0015, - animType: 'move', - }, - }, - }, -]; - -presetObject = new Object(); -presetObject.name = 'earth-field-top'; -presetObject.library = PresetsLibrary.MAIN; -presetObject.params = params; -presets.push(presetObject); - -params = [ - { - filterType: 'field', - filterId: 'air-field', - shieldType: 6, - gridPadding: 1.2, - color: 0x7090aa, - time: 0, - blend: 14, - intensity: 1, - lightAlpha: 1, - lightSize: 0.7, - scale: 1, - radius: 1, - chromatic: false, - animated: { - time: { - active: true, - speed: 0.0015, - animType: 'move', - }, - }, - }, -]; - -presetObject = new Object(); -presetObject.name = 'air-field'; -presetObject.library = PresetsLibrary.MAIN; -presetObject.params = params; -presets.push(presetObject); - -params = [ - { - filterType: 'field', - filterId: 'magic-field', - shieldType: 7, - gridPadding: 1, - color: 0xffffff, - time: 0, - blend: 10, - intensity: 0.8, - lightAlpha: 1, - lightSize: 0.45, - scale: 1, - radius: 1, - chromatic: false, - animated: { - time: { - active: true, - speed: 0.0015, - animType: 'move', - }, - }, - }, -]; - -presetObject = new Object(); -presetObject.name = 'magic-field'; -presetObject.library = PresetsLibrary.MAIN; -presetObject.params = params; -presets.push(presetObject); - -params = [ - { - filterType: 'field', - filterId: 'chromatic-field', - shieldType: 8, - gridPadding: 2, - color: 0xaaaaaa, - time: 0, - blend: 0, - intensity: 1, - lightAlpha: 0, - lightSize: 0, - scale: 1, - radius: 1, - chromatic: true, - animated: { - time: { - active: true, - speed: 0.0045, - animType: 'move', - }, - }, - }, -]; - -presetObject = new Object(); -presetObject.name = 'chromatic-field'; -presetObject.library = PresetsLibrary.MAIN; -presetObject.params = params; -presets.push(presetObject); - -params = [ - { - filterType: 'field', - filterId: 'water-field', - shieldType: 9, - gridPadding: 1.2, - color: 0x20bbee, - time: 0, - blend: 4, - intensity: 1, - lightAlpha: 0.7, - lightSize: 0.5, - scale: 0.6, - radius: 1, - chromatic: false, - animated: { - time: { - active: true, - speed: 0.0015, - animType: 'move', - }, - }, - }, -]; - -presetObject = new Object(); -presetObject.name = 'water-field'; -presetObject.library = PresetsLibrary.MAIN; -presetObject.params = params; -presets.push(presetObject); - -params = [ - { - filterType: 'field', - filterId: 'evil-field', - shieldType: 9, - gridPadding: 2, - color: 0xff3010, - time: 0, - blend: 5, - intensity: 1, - lightAlpha: 4, - lightSize: 0.8, - scale: 0.5, - radius: 1, - chromatic: false, - animated: { - time: { - active: true, - speed: 0.0012, - animType: 'move', - }, - lightSize: { - val1: 0.4, - val2: 1.5, - animType: 'syncCosOscillation', - loopDuration: 5000, - }, - }, - }, -]; - -presetObject = new Object(); -presetObject.name = 'evil-field'; -presetObject.library = PresetsLibrary.MAIN; -presetObject.params = params; -presets.push(presetObject); - -params = [ - { - filterType: 'field', - filterId: 'grid-field', - shieldType: 11, - gridPadding: 2, - color: 0x00cccc, - time: 0, - blend: 2, - intensity: 1, - lightAlpha: 1, - lightSize: 0.3, - scale: 0.5, - radius: 1, - chromatic: false, - animated: { - time: { - active: true, - speed: 0.0009, - animType: 'move', - }, - }, - }, -]; - -presetObject = new Object(); -presetObject.name = 'grid-field'; -presetObject.library = PresetsLibrary.MAIN; -presetObject.params = params; -presets.push(presetObject); - -params = [ - { - filterType: 'field', - filterId: 'warp-field', - shieldType: 12, - gridPadding: 2, - color: 0xffffff, - time: 0, - blend: 2, - intensity: 1, - lightAlpha: 0.8, - lightSize: 0.5, - scale: 0.9, - radius: 1, - chromatic: false, - animated: { - time: { - active: true, - speed: 0.0009, - animType: 'move', - }, - }, - }, -]; - -presetObject = new Object(); -presetObject.name = 'warp-field'; -presetObject.library = PresetsLibrary.MAIN; -presetObject.params = params; -presets.push(presetObject); - -params = [ - { - filterType: 'field', - filterId: 'color-field', - shieldType: 13, - gridPadding: 2, - color: 0x00cc00, - time: 0, - blend: 14, - intensity: 1, - lightAlpha: 0, - lightSize: 0, - scale: 1, - radius: 1, - chromatic: false, - animated: { - time: { - active: true, - speed: 0.0009, - animType: 'move', - }, - }, - }, -]; - -presetObject = new Object(); -presetObject.name = 'color-field'; -presetObject.library = PresetsLibrary.MAIN; -presetObject.params = params; -presets.push(presetObject); - -params = [ - { - filterType: 'xray', - filterId: 'sunburst', - time: 0, - color: 0xffbb00, - blend: 9, - dimX: 1, - dimY: 1, - anchorX: 0, - anchorY: 0, - divisor: 36, - intensity: 4, - animated: { - time: { - active: true, - speed: 0.0012, - animType: 'move', - }, - anchorX: { - animType: 'syncCosOscillation', - loopDuration: 6000, - val1: 0.4, - val2: 0.6, - }, - }, - }, -]; - -presetObject = new Object(); -presetObject.name = 'sunburst'; -presetObject.library = PresetsLibrary.MAIN; -presetObject.params = params; -presets.push(presetObject); - -params = [ - { - filterType: 'xray', - filterId: 'clover', - time: 0, - color: 0x00ff00, - blend: 9, - dimX: 0.05, - dimY: 0.05, - anchorX: 0.5, - anchorY: 0.5, - divisor: 4, - intensity: 1, - animated: { - time: { - active: true, - speed: 0.0012, - animType: 'move', - }, - anchorX: { - animType: 'syncCosOscillation', - loopDuration: 6000, - val1: 0.4, - val2: 0.6, - }, - anchorY: { - animType: 'syncSinOscillation', - loopDuration: 6000, - val1: 0.4, - val2: 0.6, - }, - }, - }, -]; - -presetObject = new Object(); -presetObject.name = 'clover'; -presetObject.library = PresetsLibrary.MAIN; -presetObject.params = params; -presets.push(presetObject); - -params = [ - { - filterType: 'xray', - filterId: 'scan', - time: 0, - color: 0xffffff, - blend: 5, - dimX: 20, - dimY: 20, - anchorX: 0.5, - anchorY: 0, - divisor: 8, - intensity: 1, - animated: { - time: { - active: true, - speed: 0.0005, - animType: 'move', - }, - }, - }, -]; - -presetObject = new Object(); -presetObject.name = 'scan'; -presetObject.library = PresetsLibrary.MAIN; -presetObject.params = params; -presets.push(presetObject); - -params = [ - { - filterType: 'xray', - filterId: 'blue-rays', - time: 0, - color: 0x1030ff, - blend: 9, - dimX: 1, - dimY: 1, - anchorX: 0, - anchorY: 0, - divisor: 24, - intensity: 1, - animated: { - time: { - active: true, - speed: 0.0002, - animType: 'move', - }, - anchorX: { - animType: 'syncCosOscillation', - loopDuration: 18000, - val1: 0.05, - val2: 0.95, - }, - anchorY: { - animType: 'syncSinOscillation', - loopDuration: 18000, - val1: 0.05, - val2: 0.95, - }, - }, - }, -]; - -presetObject = new Object(); -presetObject.name = 'blue-rays'; -presetObject.library = PresetsLibrary.MAIN; -presetObject.params = params; -presets.push(presetObject); - -params = [ - { - filterType: 'liquid', - filterId: 'spectral-body', - color: 0x20aaee, - time: 0, - blend: 8, - intensity: 4, - spectral: true, - scale: 0.9, - animated: { - time: { - active: true, - speed: 0.001, - animType: 'move', - }, - color: { - active: true, - loopDuration: 6000, - animType: 'colorOscillation', - val1: 0xffffff, - val2: 0x00aaff, - }, - }, - }, -]; - -presetObject = new Object(); -presetObject.name = 'spectral-body'; -presetObject.library = PresetsLibrary.MAIN; -presetObject.params = params; -presets.push(presetObject); - -params = [ - { - filterType: 'liquid', - filterId: 'mantle-of-madness', - color: 0x0090ff, - time: 0, - blend: 5, - intensity: 0.0001, - spectral: false, - scale: 7, - animated: { - time: { - active: true, - speed: 0.0015, - animType: 'move', - }, - intensity: { - active: true, - animType: 'syncCosOscillation', - loopDuration: 30000, - val1: 0.0001, - val2: 4, - }, - scale: { - active: true, - animType: 'syncCosOscillation', - loopDuration: 30000, - val1: 7, - val2: 1, - }, - }, - }, -]; - -presetObject = new Object(); -presetObject.name = 'mantle-of-madness'; -presetObject.library = PresetsLibrary.MAIN; -presetObject.params = params; -presets.push(presetObject); - -params = [ - { - filterType: 'wave', - filterId: 'drift-in-plans', - time: 0, - anchorX: 0.5, - anchorY: 0.5, - strength: 0.035, - frequency: 80, - color: 0xffffff, - maxIntensity: 1.5, - minIntensity: 0.5, - padding: 10, - animated: { - time: { - active: true, - speed: 0.0085, - animType: 'move', - }, - anchorX: { - active: true, - val1: 0.35, - val2: 0.65, - animType: 'syncCosOscillation', - loopDuration: 10000, - }, - anchorY: { - active: true, - val1: 0.35, - val2: 0.65, - animType: 'syncSinOscillation', - loopDuration: 10000, - }, - }, - }, - { - filterType: 'liquid', - filterId: 'drift-in-plans', - color: 0xff0000, - time: 0, - blend: 6, - intensity: 5, - spectral: false, - scale: 2.5, - animated: { - time: { - active: true, - speed: 0.0018, - animType: 'move', - }, - color: { - active: true, - loopDuration: 9000, - animType: 'colorOscillation', - val1: 0xff0000, - val2: 0xffffff, - }, - }, - }, -]; - -presetObject = new Object(); -presetObject.name = 'drift-in-plans'; -presetObject.library = PresetsLibrary.MAIN; -presetObject.params = params; -presets.push(presetObject); - -params = [ - { - filterType: 'zapshadow', - filterId: 'fire-aura', - alphaTolerance: 0.5, - }, - { - filterType: 'xglow', - filterId: 'fire-aura', - auraType: 2, - color: 0x903010, - thickness: 9.8, - scale: 4, - time: 0, - auraIntensity: 2, - subAuraIntensity: 1.5, - threshold: 0.4, - discard: true, - animated: { - time: { - active: true, - speed: 0.0027, - animType: 'move', - }, - thickness: { - active: true, - loopDuration: 3000, - animType: 'cosOscillation', - val1: 2, - val2: 5, - }, - }, - }, -]; - -presetObject = new Object(); -presetObject.name = 'fire-aura'; -presetObject.library = PresetsLibrary.MAIN; -presetObject.params = params; -presets.push(presetObject); - -params = [ - { - filterType: 'zapshadow', - filterId: 'glacial-aura', - alphaTolerance: 0.5, - }, - { - filterType: 'xglow', - filterId: 'glacial-aura', - auraType: 1, - color: 0x5099dd, - thickness: 4.5, - scale: 3, - time: 0, - auraIntensity: 0.8, - subAuraIntensity: 0.25, - threshold: 0.5, - discard: false, - animated: { - time: { - active: true, - speed: 0.0018, - animType: 'move', - }, - thickness: { - val1: 2, - val2: 4.7, - animType: 'cosOscillation', - loopDuration: 3000, - }, - subAuraIntensity: { - val1: 0.45, - val2: 0.65, - animType: 'cosOscillation', - loopDuration: 6000, - }, - auraIntensity: { - val1: 0.9, - val2: 2.2, - animType: 'cosOscillation', - loopDuration: 3000, - }, - }, - }, -]; - -presetObject = new Object(); -presetObject.name = 'glacial-aura'; -presetObject.library = PresetsLibrary.MAIN; -presetObject.params = params; -presets.push(presetObject); - -params = [ - { - filterType: 'zapshadow', - filterId: 'anti-aura', - alphaTolerance: 0.5, - }, - { - filterType: 'xglow', - filterId: 'anti-aura', - auraType: 2, - color: 0x050505, - thickness: 2.7, - scale: 7, - time: 0, - auraIntensity: 5, - subAuraIntensity: 2, - threshold: 0.08, - discard: false, - animated: { - time: { - active: true, - speed: 0.0012, - animType: 'move', - }, - auraIntensity: { - active: true, - loopDuration: 3000, - animType: 'syncCosOscillation', - val1: 5, - val2: 0, - }, - subAuraIntensity: { - active: true, - loopDuration: 3000, - animType: 'syncCosOscillation', - val1: 2, - val2: 0, - }, - color: { - active: true, - loopDuration: 6000, - animType: 'syncColorOscillation', - val1: 0x050505, - val2: 0x200000, - }, - threshold: { - active: true, - loopDuration: 1500, - animType: 'syncCosOscillation', - val1: 0.02, - val2: 0.5, - }, - }, - }, -]; - -presetObject = new Object(); -presetObject.name = 'anti-aura'; -presetObject.library = PresetsLibrary.MAIN; -presetObject.params = params; -presets.push(presetObject); - -params = [ - { - filterType: 'fire', - filterId: 'pure-fire-aura', - intensity: 1, - color: 0xffffff, - amplitude: 1, - time: 0, - blend: 2, - fireBlend: 1, - animated: { - time: { - active: true, - speed: -0.0024, - animType: 'move', - }, - intensity: { - active: true, - loopDuration: 15000, - val1: 0.8, - val2: 2, - animType: 'syncCosOscillation', - }, - amplitude: { - active: true, - loopDuration: 4400, - val1: 1, - val2: 1.4, - animType: 'syncCosOscillation', - }, - }, - }, - { - filterType: 'zapshadow', - filterId: 'pure-fire-aura', - alphaTolerance: 0.5, - }, - { - filterType: 'xglow', - filterId: 'pure-fire-aura', - auraType: 2, - color: 0x903010, - thickness: 9.8, - scale: 4, - time: 0, - auraIntensity: 2, - subAuraIntensity: 1.5, - threshold: 0.4, - discard: true, - animated: { - time: { - active: true, - speed: 0.0027, - animType: 'move', - }, - thickness: { - active: true, - loopDuration: 3000, - animType: 'cosOscillation', - val1: 2, - val2: 5, - }, - }, - }, -]; - -presetObject = new Object(); -presetObject.name = 'pure-fire-aura'; -presetObject.library = PresetsLibrary.MAIN; -presetObject.params = params; -presets.push(presetObject); - -params = [ - { - filterType: 'zapshadow', - filterId: 'pure-fire-aura-2', - alphaTolerance: 0.5, - }, - { - filterType: 'xglow', - filterId: 'pure-fire-aura-2', - auraType: 2, - color: 0x903010, - thickness: 9.8, - scale: 4, - time: 0, - auraIntensity: 1, - subAuraIntensity: 0.3, - threshold: 0.5, - discard: true, - animated: { - time: { - active: true, - speed: 0.0027, - animType: 'move', - }, - thickness: { - active: true, - loopDuration: 3000, - animType: 'cosOscillation', - val1: 2, - val2: 3.6, - }, - }, - }, - { - filterType: 'fire', - filterId: 'pure-fire-aura-2', - intensity: 1, - color: 0xffffff, - amplitude: 1, - time: 0, - blend: 2, - fireBlend: 1, - animated: { - time: { - active: true, - speed: -0.0024, - animType: 'move', - }, - intensity: { - active: true, - loopDuration: 15000, - val1: 0.8, - val2: 3, - animType: 'syncCosOscillation', - }, - amplitude: { - active: true, - loopDuration: 4400, - val1: 1, - val2: 1.6, - animType: 'syncCosOscillation', - }, - }, - }, -]; - -presetObject = new Object(); -presetObject.name = 'pure-fire-aura-2'; -presetObject.library = PresetsLibrary.MAIN; -presetObject.params = params; -presets.push(presetObject); - -params = [ - { - filterType: 'zapshadow', - filterId: 'pure-ice-aura', - alphaTolerance: 0.5, - }, - { - filterType: 'xglow', - filterId: 'pure-ice-aura', - auraType: 1, - color: 0x5099dd, - thickness: 4.5, - scale: 10, - time: 0, - auraIntensity: 0.25, - subAuraIntensity: 1, - threshold: 0.5, - discard: false, - animated: { - time: { - active: true, - speed: 0.0018, - animType: 'move', - }, - thickness: { - val1: 2, - val2: 3.3, - animType: 'cosOscillation', - loopDuration: 3000, - }, - subAuraIntensity: { - val1: 0.45, - val2: 0.65, - animType: 'cosOscillation', - loopDuration: 6000, - }, - auraIntensity: { - val1: 0.9, - val2: 2.2, - animType: 'cosOscillation', - loopDuration: 3000, - }, - }, - }, - { - filterType: 'smoke', - filterId: 'pure-ice-aura', - color: 0x80ccff, - time: 0, - blend: 2, - dimX: 0.3, - dimY: 1, - animated: { - time: { - active: true, - speed: -0.006, - animType: 'move', - }, - dimX: { - val1: 0.4, - val2: 0.2, - animType: 'cosOscillation', - loopDuration: 3000, - }, - }, - }, -]; - -presetObject = new Object(); -presetObject.name = 'pure-ice-aura'; -presetObject.library = PresetsLibrary.MAIN; -presetObject.params = params; -presets.push(presetObject); - -params = [ - { - filterType: 'pixel', - filterId: 'pixelate', - sizeX: 2.5, - sizeY: 2.5, - }, -]; - -presetObject = new Object(); -presetObject.name = 'pixelate'; -presetObject.library = PresetsLibrary.MAIN; -presetObject.params = params; -presets.push(presetObject); - -export var templatePresets = []; - -// white : **electric , **waves, ***xrays, **liquid (normal), (clover) -// black : **liquid (protoplasm), **smoke, **rays, outline, **fumes, **fog, **flood, **fire -// no texture : **glow, **bulge, **blur, **bloom - -params = [ - { - filterType: 'flood', - filterId: 'Watery Surface', - time: 0, - color: 0x0020bb, - billowy: 0.43, - tintIntensity: 0.72, - glint: 0.31, - scale: 70, - padding: 10, - animated: { - time: { - active: true, - speed: 0.0006, - animType: 'move', - }, - }, - }, -]; - -presetObject = {}; -presetObject.name = 'Watery Surface'; -presetObject.library = PresetsLibrary.TEMPLATE; -presetObject.defaultTexture = 'modules/tokenmagic/fx/assets/templates/black-tone-strong-opacity.png'; -presetObject.params = params; -templatePresets.push(presetObject); - -params = [ - { - filterType: 'liquid', - filterId: 'Protoplasm', - color: 0x20aaee, - time: 0, - blend: 8, - intensity: 4, - spectral: true, - scale: 1.4, - animated: { - time: { - active: true, - speed: 0.001, - animType: 'move', - }, - }, - }, -]; - -presetObject = {}; -presetObject.name = 'Protoplasm'; -presetObject.library = PresetsLibrary.TEMPLATE; -presetObject.defaultTexture = 'modules/tokenmagic/fx/assets/templates/black-tone-strong-opacity.png'; -presetObject.params = params; -templatePresets.push(presetObject); - -params = [ - { - filterType: 'liquid', - filterId: 'Watery Surface 2', - color: 0x20aaee, - time: 0, - blend: 8, - intensity: 4, - spectral: false, - scale: 1.4, - animated: { - time: { - active: true, - speed: 0.001, - animType: 'move', - }, - }, - }, -]; - -presetObject = {}; -presetObject.name = 'Watery Surface 2'; -presetObject.library = PresetsLibrary.TEMPLATE; -presetObject.defaultTexture = 'modules/tokenmagic/fx/assets/templates/white-tone-strong-opacity.png'; -presetObject.params = params; -templatePresets.push(presetObject); - -params = [ - { - filterType: 'smoke', - filterId: 'Smoky Area', - color: 0xaaaaaa, - time: 0, - blend: 2, - dimX: 1, - dimY: 1, - animated: { - time: { - active: true, - speed: 0.002, - animType: 'move', - }, - }, - }, -]; - -presetObject = {}; -presetObject.name = 'Smoky Area'; -presetObject.library = PresetsLibrary.TEMPLATE; -presetObject.defaultTexture = 'modules/tokenmagic/fx/assets/templates/black-tone-strong-opacity.png'; -presetObject.params = params; -templatePresets.push(presetObject); - -params = [ - { - filterType: 'electric', - filterId: 'Shock', - color: 0xffffff, - time: 0, - blend: 1, - intensity: 5, - animated: { - time: { - active: true, - speed: 0.002, - animType: 'move', - }, - }, - }, -]; - -presetObject = {}; -presetObject.name = 'Shock'; -presetObject.library = PresetsLibrary.TEMPLATE; -presetObject.defaultTexture = 'modules/tokenmagic/fx/assets/templates/white-tone-strong-opacity.png'; -presetObject.params = params; -templatePresets.push(presetObject); - -params = [ - { - filterType: 'xray', - filterId: 'Annihilating Rays', - time: 0, - color: 0xffbb00, - blend: 9, - dimX: 1, - dimY: 1, - anchorX: 0, - anchorY: 0, - divisor: 6, - intensity: 4, - animated: { - time: { - active: true, - speed: 0.0012, - animType: 'move', - }, - }, - }, -]; - -presetObject = {}; -presetObject.name = 'Annihilating Rays'; -presetObject.library = PresetsLibrary.TEMPLATE; -presetObject.defaultTexture = 'modules/tokenmagic/fx/assets/templates/white-tone-strong-opacity.png'; -presetObject.params = params; -templatePresets.push(presetObject); - -params = [ - { - filterType: 'ray', - filterId: 'Classic Rays', - time: 0, - color: 0xcf8000, - alpha: 0.5, - divisor: 32, - anchorX: 0, - anchorY: 0, - animated: { - time: { - active: true, - speed: 0.0005, - animType: 'move', - }, - }, - }, -]; - -presetObject = {}; -presetObject.name = 'Classic Rays'; -presetObject.library = PresetsLibrary.TEMPLATE; -presetObject.defaultTexture = 'modules/tokenmagic/fx/assets/templates/black-tone-strong-opacity.png'; -presetObject.params = params; -templatePresets.push(presetObject); - -params = [ - { - filterType: 'fumes', - filterId: 'Smoke Filaments', - color: 0x808080, - time: 0, - blend: 8, - animated: { - time: { - active: true, - speed: 0.001, - animType: 'move', - }, - }, - }, -]; - -presetObject = {}; -presetObject.name = 'Smoke Filaments'; -presetObject.library = PresetsLibrary.TEMPLATE; -presetObject.defaultTexture = 'modules/tokenmagic/fx/assets/templates/black-tone-strong-opacity.png'; -presetObject.params = params; -templatePresets.push(presetObject); - -params = [ - { - filterType: 'fire', - filterId: 'Flames', - intensity: 1.5, - color: 0xffffff, - amplitude: 1.3, - time: 0, - blend: 2, - fireBlend: 1, - animated: { - time: { - active: true, - speed: -0.0016, - animType: 'move', - }, - }, - }, -]; - -presetObject = {}; -presetObject.name = 'Flames'; -presetObject.library = PresetsLibrary.TEMPLATE; -presetObject.defaultTexture = 'modules/tokenmagic/fx/assets/templates/black-tone-strong-opacity.png'; -presetObject.params = params; -templatePresets.push(presetObject); - -params = [ - { - filterType: 'xfog', - filterId: 'Thick Fog', - autoFit: false, - color: 0x3090ff, - time: 0, - animated: { - time: { - active: true, - speed: 0.0006, - animType: 'move', - }, - }, - }, -]; - -presetObject = {}; -presetObject.name = 'Thick Fog'; -presetObject.library = PresetsLibrary.TEMPLATE; -presetObject.defaultTexture = 'modules/tokenmagic/fx/assets/templates/black-tone-vstrong-opacity.png'; -presetObject.params = params; -templatePresets.push(presetObject); - -params = [ - { - filterType: 'glow', - filterId: 'Glowing Outline', - outerStrength: 5.5, - innerStrength: 0, - color: 0x006000, - quality: 0.5, - padding: 10, - animated: { - outerStrength: { - active: true, - loopDuration: 3000, - animType: 'syncCosOscillation', - val1: 5.5, - val2: 1.5, - }, - }, - }, -]; - -presetObject = {}; -presetObject.name = 'Glowing Outline'; -presetObject.library = PresetsLibrary.TEMPLATE; -presetObject.params = params; -templatePresets.push(presetObject); - -params = [ - { - filterType: 'wave', - filterId: 'Waves', - time: 0, - anchorX: 0.5, - anchorY: 0.5, - strength: 0.015, - frequency: 120, - color: 0xffffff, - maxIntensity: 2.5, - minIntensity: 0.9, - padding: 10, - animated: { - time: { - active: true, - speed: 0.0085, - animType: 'move', - }, - }, - }, -]; - -presetObject = {}; -presetObject.name = 'Waves'; -presetObject.library = PresetsLibrary.TEMPLATE; -presetObject.defaultTexture = 'modules/tokenmagic/fx/assets/templates/white-tone-strong-opacity.png'; -presetObject.params = params; -templatePresets.push(presetObject); - -params = [ - { - filterType: 'wave', - filterId: 'Waves 2', - time: 0, - anchorX: 0.5, - anchorY: 0.5, - strength: 0.014, - frequency: 400, - color: 0xffffff, - maxIntensity: 2.4, - minIntensity: 0.8, - padding: 10, - animated: { - time: { - active: true, - speed: 0.0385, - animType: 'move', - }, - }, - }, -]; - -presetObject = {}; -presetObject.name = 'Waves 2'; -presetObject.library = PresetsLibrary.TEMPLATE; -presetObject.defaultTexture = 'modules/tokenmagic/fx/assets/templates/white-tone-strong-opacity.png'; -presetObject.params = params; -templatePresets.push(presetObject); - -params = [ - { - filterType: 'wave', - filterId: 'Waves 3', - time: 0, - anchorX: 0.5, - anchorY: 0.5, - strength: 0.017, - frequency: 35, - color: 0xffffff, - maxIntensity: 2.6, - minIntensity: 0.9, - padding: 20, - animated: { - time: { - active: true, - speed: 0.0085, - animType: 'move', - }, - }, - }, -]; - -presetObject = {}; -presetObject.name = 'Waves 3'; -presetObject.library = PresetsLibrary.TEMPLATE; -presetObject.defaultTexture = 'modules/tokenmagic/fx/assets/templates/white-tone-strong-opacity.png'; -presetObject.params = params; -templatePresets.push(presetObject); - -params = [ - { - filterType: 'xglow', - filterId: 'Zone : Fire', - auraType: 1, - color: 0x903010, - scale: 1.5, - time: 0, - auraIntensity: 1.8, - subAuraIntensity: 0.25, - threshold: 0.6, - discard: false, - animated: { - time: { - active: true, - speed: 0.0027, - animType: 'move', - }, - thickness: { - active: true, - loopDuration: 3000, - animType: 'cosOscillation', - val1: 2, - val2: 5, - }, - }, - }, - { - filterType: 'fire', - filterId: 'Zone : Fire', - intensity: 1.5, - color: 0xffffff, - amplitude: 1, - time: 0, - blend: 2, - fireBlend: 1, - animated: { - time: { - active: true, - speed: -0.0015, - animType: 'move', - }, - }, - }, -]; - -presetObject = {}; -presetObject.name = 'Zone : Fire'; -presetObject.library = PresetsLibrary.TEMPLATE; -presetObject.defaultTexture = 'modules/tokenmagic/fx/assets/templates/black-tone-strong-opacity.png'; -presetObject.params = params; -templatePresets.push(presetObject); - -params = [ - { - filterType: 'xglow', - filterId: 'Zone : Electricity', - auraType: 2, - color: 0x303030, - scale: 1.5, - time: 0, - auraIntensity: 1, - subAuraIntensity: 0.9, - threshold: 0, - discard: true, - animated: { - time: { - active: true, - speed: 0.0027, - animType: 'move', - }, - thickness: { - active: true, - loopDuration: 3000, - animType: 'cosOscillation', - val1: 1, - val2: 2, - }, - }, - }, - { - filterType: 'electric', - filterId: 'Zone : Electricity', - color: 0xffffff, - time: 0, - blend: 1, - intensity: 5, - animated: { - time: { - active: true, - speed: 0.002, - animType: 'move', - }, - }, - }, -]; - -presetObject = {}; -presetObject.name = 'Zone : Electricity'; -presetObject.library = PresetsLibrary.TEMPLATE; -presetObject.defaultTexture = 'modules/tokenmagic/fx/assets/templates/white-tone-strong-opacity.png'; -presetObject.params = params; -templatePresets.push(presetObject); - -params = [ - { - filterType: 'xglow', - filterId: 'Zone : Blizzard', - auraType: 1, - color: 0x5099dd, - thickness: 4.5, - scale: 5, - time: 0, - auraIntensity: 0.25, - subAuraIntensity: 1, - threshold: 0.5, - discard: false, - animated: { - time: { - active: true, - speed: 0.0018, - animType: 'move', - }, - thickness: { - val1: 2, - val2: 3.3, - animType: 'cosOscillation', - loopDuration: 3000, - }, - subAuraIntensity: { - val1: 0.05, - val2: 0.1, - animType: 'cosOscillation', - loopDuration: 6000, - }, - auraIntensity: { - val1: 0.9, - val2: 2.2, - animType: 'cosOscillation', - loopDuration: 3000, - }, - }, - }, - { - filterType: 'smoke', - filterId: 'Zone : Blizzard', - color: 0x80ccff, - time: 0, - blend: 2, - dimY: 1, - animated: { - time: { - active: true, - speed: -0.005, - animType: 'move', - }, - dimX: { - val1: 0.4, - val2: 0.2, - animType: 'cosOscillation', - loopDuration: 3000, - }, - }, - }, -]; - -presetObject = {}; -presetObject.name = 'Zone : Blizzard'; -presetObject.library = PresetsLibrary.TEMPLATE; -presetObject.defaultTexture = 'modules/tokenmagic/fx/assets/templates/black-tone-strong-opacity.png'; -presetObject.params = params; -templatePresets.push(presetObject); - -params = [ - { - filterType: 'bulgepinch', - filterId: 'Bulging Out', - padding: 150, - strength: 0, - radiusPercent: 200, - animated: { - strength: { - active: true, - animType: 'cosOscillation', - loopDuration: 2000, - val1: 0, - val2: 0.45, - }, - }, - }, -]; - -presetObject = {}; -presetObject.name = 'Bulging Out'; -presetObject.library = PresetsLibrary.TEMPLATE; -presetObject.params = params; -templatePresets.push(presetObject); - -params = [ - { - filterType: 'blur', - filterId: 'Blurred Texture', - padding: 25, - quality: 4.0, - blur: 0, - blurX: 0, - blurY: 0, - animated: { - blurX: { - active: true, - animType: 'syncCosOscillation', - loopDuration: 500, - val1: 0, - val2: 6, - }, - blurY: { - active: true, - animType: 'syncCosOscillation', - loopDuration: 750, - val1: 0, - val2: 6, - }, - }, - }, -]; - -presetObject = {}; -presetObject.name = 'Blurred Texture'; -presetObject.library = PresetsLibrary.TEMPLATE; -presetObject.params = params; -templatePresets.push(presetObject); - -params = [ - { - filterType: 'xbloom', - filterId: 'Bloomed Texture', - threshold: 0.35, - bloomScale: 0, - brightness: 1, - blur: 0.1, - padding: 10, - quality: 15, - blendMode: 0, - animated: { - bloomScale: { - active: true, - loopDuration: 2000, - animType: 'syncCosOscillation', - val1: 0, - val2: 2.1, - }, - threshold: { - active: false, - loopDuration: 1000, - animType: 'syncCosOscillation', - val1: 0.0, - val2: 1.9, - }, - }, - }, -]; - -presetObject = {}; -presetObject.name = 'Bloomed Texture'; -presetObject.library = PresetsLibrary.TEMPLATE; -presetObject.params = params; -templatePresets.push(presetObject); - -params = [ - { - filterType: 'liquid', - filterId: 'Wild Magic', - color: 0xff0000, - time: 0, - blend: 6, - intensity: 5, - spectral: false, - scale: 2.5, - animated: { - time: { - active: true, - speed: 0.0018, - animType: 'move', - }, - }, - }, - { - filterType: 'wave', - filterId: 'Wild Magic', - time: 0, - anchorX: 0.5, - anchorY: 0.5, - strength: 0.014, - frequency: 10, - color: 0xffffff, - maxIntensity: 1.3, - minIntensity: 0.6, - padding: 10, - animated: { - time: { - active: true, - speed: 0.0065, - animType: 'move', - }, - }, - }, -]; - -presetObject = {}; -presetObject.name = 'Wild Magic'; -presetObject.library = PresetsLibrary.TEMPLATE; -presetObject.defaultTexture = 'modules/tokenmagic/fx/assets/templates/black-tone-strong-opacity.png'; -presetObject.params = params; -templatePresets.push(presetObject); - -params = [ - { - filterType: 'web', - filterId: 'Spider Web 1', - anchorX: 0.5, - anchorY: 0.5, - color: 0xffffff, - thickness: 2, - div2: 5, - time: 98.8, - animated: { - time: { - active: true, - loopDuration: 5000, - animType: 'cosOscillation', - val1: 98.8, - val2: 99.7, - }, - }, - }, -]; - -presetObject = {}; -presetObject.name = 'Spider Web 1'; -presetObject.library = PresetsLibrary.TEMPLATE; -presetObject.defaultTexture = 'modules/tokenmagic/fx/assets/templates/black-tone-strong-opacity.png'; -presetObject.params = params; -templatePresets.push(presetObject); - -params = [ - { - filterType: 'web', - filterId: 'Spider Web 2', - anchorX: 0.5, - anchorY: 0.5, - color: 0xcccccc, - animated: { - time: { - active: true, - speed: 0.0005, - animType: 'move', - }, - }, - }, - { - filterType: 'liquid', - filterId: 'Spider Web 2', - color: 0xff0000, - time: 0, - blend: 4, - intensity: 8, - spectral: false, - scale: 0.2, - animated: { - time: { - active: true, - speed: 0.0005, - animType: 'move', - }, - }, - }, -]; - -presetObject = {}; -presetObject.name = 'Spider Web 2'; -presetObject.library = PresetsLibrary.TEMPLATE; -presetObject.defaultTexture = 'modules/tokenmagic/fx/assets/templates/black-tone-strong-opacity.png'; -presetObject.params = params; -templatePresets.push(presetObject); - -params = [ - { - filterType: 'web', - filterId: 'Spider Web 3', - anchorX: 0.5, - anchorY: 0.5, - color: 0xcccccc, - time: 100, - }, - { - filterType: 'liquid', - filterId: 'Spider Web 3', - color: 0xff0000, - time: 0, - blend: 1, - intensity: 4, - spectral: true, - scale: 0.2, - animated: { - time: { - active: true, - speed: 0.0005, - animType: 'move', - }, - }, - }, -]; - -presetObject = {}; -presetObject.name = 'Spider Web 3'; -presetObject.library = PresetsLibrary.TEMPLATE; -presetObject.defaultTexture = 'modules/tokenmagic/fx/assets/templates/black-tone-strong-opacity.png'; -presetObject.params = params; -templatePresets.push(presetObject); - -export var allPresets = presets.concat(templatePresets); diff --git a/tokenmagic/import/TMFX-default-presets.json b/tokenmagic/import/TMFX-default-presets.json deleted file mode 100644 index 6eab9b6..0000000 --- a/tokenmagic/import/TMFX-default-presets.json +++ /dev/null @@ -1,2444 +0,0 @@ -[ - { - "name": "bevel", - "params": [ - { - "filterType": "bevel", - "filterId": "bevel", - "rotation": 0, - "thickness": 5, - "lightColor": 16711680, - "lightAlpha": 0.8, - "shadowColor": 65280, - "shadowAlpha": 0.5, - "animated": { - "rotation": { - "active": true, - "clockWise": true, - "loopDuration": 1600, - "animType": "syncRotation" - } - } - } - ], - "library": "tmfx-main" - }, - { - "name": "adjustment", - "params": [ - { - "filterType": "adjustment", - "filterId": "adjustment", - "saturation": 1.5, - "brightness": 1.5, - "contrast": 2, - "gamma": 2, - "red": 4, - "green": 0.25, - "blue": 0.25, - "alpha": 1, - "animated": { - "alpha": { - "active": true, - "loopDuration": 5000, - "animType": "syncCosOscillation", - "val1": 0.15, - "val2": 1 - } - } - } - ], - "library": "tmfx-main" - }, - { - "name": "dropshadow", - "params": [ - { - "filterType": "shadow", - "filterId": "dropshadow", - "rotation": 35, - "blur": 2, - "quality": 5, - "distance": 20, - "alpha": 0.7, - "padding": 10, - "shadowOnly": false, - "color": 0, - "animated": { - "blur": { - "active": true, - "loopDuration": 1500, - "animType": "syncCosOscillation", - "val1": 2, - "val2": 3 - }, - "rotation": { - "active": true, - "loopDuration": 150, - "animType": "syncSinOscillation", - "val1": 33, - "val2": 35 - } - } - } - ], - "library": "tmfx-main" - }, - { - "name": "outline", - "params": [ - { - "filterType": "outline", - "filterId": "outline", - "padding": 10, - "color": 15622197, - "thickness": 1, - "quality": 5, - "animated": { - "thickness": { - "active": true, - "loopDuration": 800, - "animType": "syncCosOscillation", - "val1": 1, - "val2": 6 - } - } - } - ], - "library": "tmfx-main" - }, - { - "name": "glow", - "params": [ - { - "filterType": "glow", - "filterId": "glow", - "outerStrength": 7, - "innerStrength": 0, - "color": 24576, - "quality": 0.5, - "padding": 10, - "animated": { - "color": { - "active": true, - "loopDuration": 3000, - "animType": "colorOscillation", - "val1": 12288, - "val2": 65280 - } - } - } - ], - "library": "tmfx-main" - }, - { - "name": "bloom", - "params": [ - { - "filterType": "xbloom", - "filterId": "bloom", - "threshold": 0.35, - "bloomScale": 0, - "brightness": 1, - "blur": 0.1, - "padding": 10, - "quality": 15, - "blendMode": 0, - "animated": { - "bloomScale": { - "active": true, - "loopDuration": 2000, - "animType": "syncCosOscillation", - "val1": 0, - "val2": 2.1 - }, - "threshold": { - "active": false, - "loopDuration": 1000, - "animType": "syncCosOscillation", - "val1": 0, - "val2": 1.9 - } - } - } - ], - "library": "tmfx-main" - }, - { - "name": "distortion", - "params": [ - { - "filterType": "distortion", - "filterId": "distortion", - "maskPath": "modules/tokenmagic/fx/assets/distortion-1.png", - "maskSpriteScaleX": 5, - "maskSpriteScaleY": 5, - "padding": 20, - "animated": { - "maskSpriteX": { - "active": true, - "speed": 0.05, - "animType": "move" - }, - "maskSpriteY": { - "active": true, - "speed": 0.07, - "animType": "move" - } - } - } - ], - "library": "tmfx-main" - }, - { - "name": "oldfilm", - "params": [ - { - "filterType": "oldfilm", - "filterId": "oldfilm", - "sepia": 0.6, - "noise": 0.2, - "noiseSize": 1, - "scratch": 0.8, - "scratchDensity": 0.5, - "scratchWidth": 1.2, - "vignetting": 0.9, - "vignettingAlpha": 0.6, - "vignettingBlur": 0.2, - "animated": { - "seed": { - "active": true, - "animType": "randomNumber", - "val1": 0, - "val2": 1 - }, - "vignetting": { - "active": true, - "animType": "syncCosOscillation", - "loopDuration": 2000, - "val1": 0.2, - "val2": 0.4 - } - } - }, - { - "filterType": "outline", - "filterId": "oldfilm", - "color": 0, - "thickness": 0 - } - ], - "library": "tmfx-main" - }, - { - "name": "twist", - "params": [ - { - "filterType": "twist", - "filterId": "twist", - "radiusPercent": 120, - "angle": 0, - "animated": { - "angle": { - "active": true, - "animType": "sinOscillation", - "loopDuration": 10000, - "val1": -1.8849555921538759, - "val2": 1.8849555921538759 - } - } - } - ], - "library": "tmfx-main" - }, - { - "name": "bulge", - "params": [ - { - "filterType": "bulgepinch", - "filterId": "bulge", - "padding": 150, - "strength": 0, - "zIndex": 2, - "radiusPercent": 200, - "animated": { - "strength": { - "active": true, - "animType": "cosOscillation", - "loopDuration": 2000, - "val1": 0, - "val2": 0.45 - } - } - } - ], - "library": "tmfx-main" - }, - { - "name": "blur", - "params": [ - { - "filterType": "blur", - "filterId": "blur", - "padding": 10, - "quality": 4, - "blur": 0, - "blurX": 0, - "blurY": 0, - "animated": { - "blurX": { - "active": true, - "animType": "syncCosOscillation", - "loopDuration": 500, - "val1": 0, - "val2": 6 - }, - "blurY": { - "active": true, - "animType": "syncCosOscillation", - "loopDuration": 750, - "val1": 0, - "val2": 6 - } - } - } - ], - "library": "tmfx-main" - }, - { - "name": "zoomblur", - "params": [ - { - "filterType": "zoomblur", - "filterId": "zoomblur", - "strength": 0.15, - "innerRadiusPercent": 65, - "radiusPercent": 100, - "padding": 30, - "animated": { - "innerRadiusPercent": { - "active": true, - "animType": "sinOscillation", - "loopDuration": 500, - "val1": 65, - "val2": 75 - } - } - } - ], - "library": "tmfx-main" - }, - { - "name": "shockwave", - "params": [ - { - "filterType": "shockwave", - "filterId": "shockwave", - "time": 0, - "amplitude": 8, - "wavelength": 75, - "radius": 500, - "brightness": 1.5, - "speed": 25, - "padding": 0, - "animated": { - "time": { - "animType": "cosOscillation", - "active": true, - "loopDuration": 1800, - "val1": 0, - "val2": 10 - } - } - } - ], - "library": "tmfx-main" - }, - { - "name": "zapshadow", - "params": [ - { - "filterType": "zapshadow", - "filterId": "zapshadow", - "alphaTolerance": 0.45 - } - ], - "library": "tmfx-main" - }, - { - "name": "rays", - "params": [ - { - "filterType": "ray", - "filterId": "rays", - "time": 0, - "color": 13598720, - "alpha": 0.5, - "divisor": 32, - "anchorX": 0, - "anchorY": 0, - "animated": { - "time": { - "active": true, - "speed": 0.0005, - "animType": "move" - } - } - } - ], - "library": "tmfx-main" - }, - { - "name": "fog", - "params": [ - { - "filterType": "fog", - "filterId": "fog", - "color": 0, - "density": 0.65, - "time": 0, - "dimX": 1, - "dimY": 1, - "animated": { - "time": { - "active": true, - "speed": 2.2, - "animType": "move" - } - } - } - ], - "library": "tmfx-main" - }, - { - "name": "fumes", - "params": [ - { - "filterType": "fumes", - "filterId": "fumes", - "color": 8421504, - "time": 0, - "blend": 8, - "animated": { - "time": { - "active": true, - "speed": 0.001, - "animType": "move" - } - } - } - ], - "library": "tmfx-main" - }, - { - "name": "electric", - "params": [ - { - "filterType": "electric", - "filterId": "electric", - "color": 16777215, - "time": 0, - "blend": 1, - "intensity": 5, - "animated": { - "time": { - "active": true, - "speed": 0.002, - "animType": "move" - } - } - } - ], - "library": "tmfx-main" - }, - { - "name": "fire", - "params": [ - { - "filterType": "fire", - "filterId": "fire", - "intensity": 1, - "color": 16777215, - "amplitude": 1, - "time": 0, - "blend": 2, - "fireBlend": 1, - "animated": { - "time": { - "active": true, - "speed": -0.0024, - "animType": "move" - }, - "intensity": { - "active": true, - "loopDuration": 15000, - "val1": 0.8, - "val2": 2, - "animType": "syncCosOscillation" - }, - "amplitude": { - "active": true, - "loopDuration": 4400, - "val1": 1, - "val2": 1.4, - "animType": "syncCosOscillation" - } - } - } - ], - "library": "tmfx-main" - }, - { - "name": "waves", - "params": [ - { - "filterType": "wave", - "filterId": "waves", - "time": 0, - "anchorX": 0.5, - "anchorY": 0.5, - "strength": 0.015, - "frequency": 120, - "color": 16777215, - "maxIntensity": 2.5, - "minIntensity": 0.9, - "padding": 10, - "animated": { - "time": { - "active": true, - "speed": 0.0085, - "animType": "move" - }, - "anchorX": { - "active": false, - "val1": 0.15, - "val2": 0.85, - "animType": "syncChaoticOscillation", - "loopDuration": 20000 - }, - "anchorY": { - "active": false, - "val1": 0.15, - "val2": 0.85, - "animType": "syncSinOscillation", - "loopDuration": 20000 - } - } - } - ], - "library": "tmfx-main" - }, - { - "name": "flood", - "params": [ - { - "filterType": "flood", - "filterId": "flood", - "time": 0, - "color": 8379, - "billowy": 0.43, - "tintIntensity": 0.72, - "glint": 0.31, - "scale": 70, - "padding": 10, - "animated": { - "time": { - "active": true, - "speed": 0.0006, - "animType": "move" - } - } - } - ], - "library": "tmfx-main" - }, - { - "name": "smoke", - "params": [ - { - "filterType": "smoke", - "filterId": "smoke", - "color": 5282269, - "time": 0, - "blend": 2, - "dimX": 0.1, - "dimY": 1, - "animated": { - "time": { - "active": true, - "speed": 0.009, - "animType": "move" - } - } - } - ], - "library": "tmfx-main" - }, - { - "name": "images", - "params": [ - { - "filterType": "images", - "filterId": "images", - "time": 0, - "nbImage": 4, - "alphaImg": 1, - "alphaChr": 0, - "blend": 4, - "ampX": 0.1, - "ampY": 0.1, - "animated": { - "time": { - "active": true, - "speed": 0.001, - "animType": "move" - } - } - } - ], - "library": "tmfx-main" - }, - { - "name": "chaos-images", - "params": [ - { - "filterType": "images", - "filterId": "chaos-images", - "time": 0, - "nbImage": 4, - "alphaImg": 1, - "alphaChr": 0, - "blend": 4, - "ampX": 0.1, - "ampY": 0.1, - "padding": 80, - "animated": { - "time": { - "active": true, - "speed": 0.001, - "animType": "move" - }, - "ampX": { - "active": true, - "val1": 0, - "val2": 0.3, - "chaosFactor": 0.03, - "animType": "syncChaoticOscillation", - "loopDuration": 2000 - }, - "ampY": { - "active": true, - "val1": 0, - "val2": 0.3, - "chaosFactor": 0.04, - "animType": "syncChaoticOscillation", - "loopDuration": 1650 - }, - "alphaChr": { - "active": true, - "animType": "randomNumberPerLoop", - "val1": 0, - "val2": 1, - "loopDuration": 250 - }, - "alphaImg": { - "active": true, - "animType": "randomNumberPerLoop", - "val1": 0.8, - "val2": 1, - "loopDuration": 250 - }, - "nbImage": { - "active": true, - "val1": 1, - "val2": 9, - "animType": "syncSinOscillation", - "loopDuration": 1400 - } - } - } - ], - "library": "tmfx-main" - }, - { - "name": "spectral-images", - "params": [ - { - "filterType": "images", - "filterId": "spectral-images", - "time": 0, - "blend": 4, - "nbImage": 4, - "padding": 100, - "alphaImg": 0.5, - "alphaChr": 0, - "ampX": 0.1, - "ampY": 0.1, - "animated": { - "time": { - "speed": 0.001, - "animType": "move" - }, - "ampX": { - "val1": 0, - "val2": 0.22, - "animType": "syncCosOscillation", - "loopDuration": 2500 - }, - "ampY": { - "val1": 0, - "val2": 0.24, - "animType": "syncCosOscillation", - "loopDuration": 2500, - "pauseBetweenDuration": 2500 - }, - "alphaChr": { - "val1": 1, - "val2": 0, - "animType": "syncCosOscillation", - "loopDuration": 2500 - }, - "alphaImg": { - "val1": 0.2, - "val2": 0.8, - "animType": "syncSinOscillation", - "loopDuration": 2500 - } - } - } - ], - "library": "tmfx-main" - }, - { - "name": "hexa-field", - "params": [ - { - "filterType": "field", - "filterId": "hexa-field", - "shieldType": 2, - "gridPadding": 1.5, - "color": 13369548, - "time": 0, - "blend": 3, - "intensity": 1, - "lightAlpha": 0.5, - "lightSize": 0.5, - "scale": 1, - "radius": 1, - "chromatic": false, - "animated": { - "time": { - "active": true, - "speed": 0.0015, - "animType": "move" - } - } - } - ], - "library": "tmfx-main" - }, - { - "name": "fire-field", - "params": [ - { - "filterType": "field", - "filterId": "fire-field", - "shieldType": 1, - "gridPadding": 2, - "color": 15041872, - "time": 0, - "blend": 2, - "intensity": 1.15, - "lightAlpha": 2, - "lightSize": 0.7, - "scale": 1, - "radius": 1, - "chromatic": false, - "animated": { - "time": { - "active": true, - "speed": 0.0015, - "animType": "move" - } - } - } - ], - "library": "tmfx-main" - }, - { - "name": "smoke-field", - "params": [ - { - "filterType": "field", - "filterId": "smoke-field", - "shieldType": 3, - "gridPadding": 1.5, - "color": 6343792, - "time": 0, - "blend": 2, - "intensity": 0.9, - "lightAlpha": 1, - "lightSize": 0.7, - "scale": 1, - "radius": 1, - "chromatic": false, - "animated": { - "time": { - "active": true, - "speed": 0.0015, - "animType": "move" - } - } - } - ], - "library": "tmfx-main" - }, - { - "name": "earth-field", - "params": [ - { - "filterType": "field", - "filterId": "earth-field", - "shieldType": 4, - "gridPadding": 2, - "color": 12292208, - "time": 0, - "blend": 1, - "intensity": 1.25, - "lightAlpha": 1, - "lightSize": 0.7, - "scale": 1, - "radius": 1, - "chromatic": false, - "animated": { - "time": { - "active": true, - "speed": 0.0015, - "animType": "move" - } - } - } - ], - "library": "tmfx-main" - }, - { - "name": "earth-field-top", - "params": [ - { - "filterType": "field", - "filterId": "earth-field-top", - "shieldType": 5, - "gridPadding": 3, - "color": 11184810, - "time": 0, - "blend": 5, - "intensity": 1.9, - "lightAlpha": 1, - "lightSize": 0.7, - "scale": 1, - "radius": 1, - "zIndex": 5, - "chromatic": true, - "animated": { - "time": { - "active": true, - "speed": 0.0015, - "animType": "move" - } - } - } - ], - "library": "tmfx-main" - }, - { - "name": "air-field", - "params": [ - { - "filterType": "field", - "filterId": "air-field", - "shieldType": 6, - "gridPadding": 1.2, - "color": 7377066, - "time": 0, - "blend": 14, - "intensity": 1, - "lightAlpha": 1, - "lightSize": 0.7, - "scale": 1, - "radius": 1, - "chromatic": false, - "animated": { - "time": { - "active": true, - "speed": 0.0015, - "animType": "move" - } - } - } - ], - "library": "tmfx-main" - }, - { - "name": "magic-field", - "params": [ - { - "filterType": "field", - "filterId": "magic-field", - "shieldType": 7, - "gridPadding": 1, - "color": 16777215, - "time": 0, - "blend": 10, - "intensity": 0.8, - "lightAlpha": 1, - "lightSize": 0.45, - "scale": 1, - "radius": 1, - "chromatic": false, - "animated": { - "time": { - "active": true, - "speed": 0.0015, - "animType": "move" - } - } - } - ], - "library": "tmfx-main" - }, - { - "name": "chromatic-field", - "params": [ - { - "filterType": "field", - "filterId": "chromatic-field", - "shieldType": 8, - "gridPadding": 2, - "color": 11184810, - "time": 0, - "blend": 0, - "intensity": 1, - "lightAlpha": 0, - "lightSize": 0, - "scale": 1, - "radius": 1, - "chromatic": true, - "animated": { - "time": { - "active": true, - "speed": 0.0045, - "animType": "move" - } - } - } - ], - "library": "tmfx-main" - }, - { - "name": "water-field", - "params": [ - { - "filterType": "field", - "filterId": "water-field", - "shieldType": 9, - "gridPadding": 1.2, - "color": 2145262, - "time": 0, - "blend": 4, - "intensity": 1, - "lightAlpha": 0.7, - "lightSize": 0.5, - "scale": 0.6, - "radius": 1, - "chromatic": false, - "animated": { - "time": { - "active": true, - "speed": 0.0015, - "animType": "move" - } - } - } - ], - "library": "tmfx-main" - }, - { - "name": "evil-field", - "params": [ - { - "filterType": "field", - "filterId": "evil-field", - "shieldType": 9, - "gridPadding": 2, - "color": 16723984, - "time": 0, - "blend": 5, - "intensity": 1, - "lightAlpha": 4, - "lightSize": 0.8, - "scale": 0.5, - "radius": 1, - "chromatic": false, - "animated": { - "time": { - "active": true, - "speed": 0.0012, - "animType": "move" - }, - "lightSize": { - "val1": 0.4, - "val2": 1.5, - "animType": "syncCosOscillation", - "loopDuration": 5000 - } - } - } - ], - "library": "tmfx-main" - }, - { - "name": "grid-field", - "params": [ - { - "filterType": "field", - "filterId": "grid-field", - "shieldType": 11, - "gridPadding": 2, - "color": 52428, - "time": 0, - "blend": 2, - "intensity": 1, - "lightAlpha": 1, - "lightSize": 0.3, - "scale": 0.5, - "radius": 1, - "chromatic": false, - "animated": { - "time": { - "active": true, - "speed": 0.0009, - "animType": "move" - } - } - } - ], - "library": "tmfx-main" - }, - { - "name": "warp-field", - "params": [ - { - "filterType": "field", - "filterId": "warp-field", - "shieldType": 12, - "gridPadding": 2, - "color": 16777215, - "time": 0, - "blend": 2, - "intensity": 1, - "lightAlpha": 0.8, - "lightSize": 0.5, - "scale": 0.9, - "radius": 1, - "chromatic": false, - "animated": { - "time": { - "active": true, - "speed": 0.0009, - "animType": "move" - } - } - } - ], - "library": "tmfx-main" - }, - { - "name": "color-field", - "params": [ - { - "filterType": "field", - "filterId": "color-field", - "shieldType": 13, - "gridPadding": 2, - "color": 52224, - "time": 0, - "blend": 14, - "intensity": 1, - "lightAlpha": 0, - "lightSize": 0, - "scale": 1, - "radius": 1, - "chromatic": false, - "animated": { - "time": { - "active": true, - "speed": 0.0009, - "animType": "move" - } - } - } - ], - "library": "tmfx-main" - }, - { - "name": "sunburst", - "params": [ - { - "filterType": "xray", - "filterId": "sunburst", - "time": 0, - "color": 16759552, - "blend": 9, - "dimX": 1, - "dimY": 1, - "anchorX": 0, - "anchorY": 0, - "divisor": 36, - "intensity": 4, - "animated": { - "time": { - "active": true, - "speed": 0.0012, - "animType": "move" - }, - "anchorX": { - "animType": "syncCosOscillation", - "loopDuration": 6000, - "val1": 0.4, - "val2": 0.6 - } - } - } - ], - "library": "tmfx-main" - }, - { - "name": "clover", - "params": [ - { - "filterType": "xray", - "filterId": "clover", - "time": 0, - "color": 65280, - "blend": 9, - "dimX": 0.05, - "dimY": 0.05, - "anchorX": 0.5, - "anchorY": 0.5, - "divisor": 4, - "intensity": 1, - "animated": { - "time": { - "active": true, - "speed": 0.0012, - "animType": "move" - }, - "anchorX": { - "animType": "syncCosOscillation", - "loopDuration": 6000, - "val1": 0.4, - "val2": 0.6 - }, - "anchorY": { - "animType": "syncSinOscillation", - "loopDuration": 6000, - "val1": 0.4, - "val2": 0.6 - } - } - } - ], - "library": "tmfx-main" - }, - { - "name": "scan", - "params": [ - { - "filterType": "xray", - "filterId": "scan", - "time": 0, - "color": 16777215, - "blend": 5, - "dimX": 20, - "dimY": 20, - "anchorX": 0.5, - "anchorY": 0, - "divisor": 8, - "intensity": 1, - "animated": { - "time": { - "active": true, - "speed": 0.0005, - "animType": "move" - } - } - } - ], - "library": "tmfx-main" - }, - { - "name": "blue-rays", - "params": [ - { - "filterType": "xray", - "filterId": "blue-rays", - "time": 0, - "color": 1061119, - "blend": 9, - "dimX": 1, - "dimY": 1, - "anchorX": 0, - "anchorY": 0, - "divisor": 24, - "intensity": 1, - "animated": { - "time": { - "active": true, - "speed": 0.0002, - "animType": "move" - }, - "anchorX": { - "animType": "syncCosOscillation", - "loopDuration": 18000, - "val1": 0.05, - "val2": 0.95 - }, - "anchorY": { - "animType": "syncSinOscillation", - "loopDuration": 18000, - "val1": 0.05, - "val2": 0.95 - } - } - } - ], - "library": "tmfx-main" - }, - { - "name": "spectral-body", - "params": [ - { - "filterType": "liquid", - "filterId": "spectral-body", - "color": 2140910, - "time": 0, - "blend": 8, - "intensity": 4, - "spectral": true, - "scale": 0.9, - "animated": { - "time": { - "active": true, - "speed": 0.001, - "animType": "move" - }, - "color": { - "active": true, - "loopDuration": 6000, - "animType": "colorOscillation", - "val1": 16777215, - "val2": 43775 - } - } - } - ], - "library": "tmfx-main" - }, - { - "name": "mantle-of-madness", - "params": [ - { - "filterType": "liquid", - "filterId": "mantle-of-madness", - "color": 37119, - "time": 0, - "blend": 5, - "intensity": 0.0001, - "spectral": false, - "scale": 7, - "animated": { - "time": { - "active": true, - "speed": 0.0015, - "animType": "move" - }, - "intensity": { - "active": true, - "animType": "syncCosOscillation", - "loopDuration": 30000, - "val1": 0.0001, - "val2": 4 - }, - "scale": { - "active": true, - "animType": "syncCosOscillation", - "loopDuration": 30000, - "val1": 7, - "val2": 1 - } - } - } - ], - "library": "tmfx-main" - }, - { - "name": "drift-in-plans", - "params": [ - { - "filterType": "wave", - "filterId": "drift-in-plans", - "time": 0, - "anchorX": 0.5, - "anchorY": 0.5, - "strength": 0.035, - "frequency": 80, - "color": 16777215, - "maxIntensity": 1.5, - "minIntensity": 0.5, - "padding": 10, - "animated": { - "time": { - "active": true, - "speed": 0.0085, - "animType": "move" - }, - "anchorX": { - "active": true, - "val1": 0.35, - "val2": 0.65, - "animType": "syncCosOscillation", - "loopDuration": 10000 - }, - "anchorY": { - "active": true, - "val1": 0.35, - "val2": 0.65, - "animType": "syncSinOscillation", - "loopDuration": 10000 - } - } - }, - { - "filterType": "liquid", - "filterId": "drift-in-plans", - "color": 16711680, - "time": 0, - "blend": 6, - "intensity": 5, - "spectral": false, - "scale": 2.5, - "animated": { - "time": { - "active": true, - "speed": 0.0018, - "animType": "move" - }, - "color": { - "active": true, - "loopDuration": 9000, - "animType": "colorOscillation", - "val1": 16711680, - "val2": 16777215 - } - } - } - ], - "library": "tmfx-main" - }, - { - "name": "fire-aura", - "params": [ - { - "filterType": "zapshadow", - "filterId": "fire-aura", - "alphaTolerance": 0.5 - }, - { - "filterType": "xglow", - "filterId": "fire-aura", - "auraType": 2, - "color": 9449488, - "thickness": 9.8, - "scale": 4, - "time": 0, - "auraIntensity": 2, - "subAuraIntensity": 1.5, - "threshold": 0.4, - "discard": true, - "animated": { - "time": { - "active": true, - "speed": 0.0027, - "animType": "move" - }, - "thickness": { - "active": true, - "loopDuration": 3000, - "animType": "cosOscillation", - "val1": 2, - "val2": 5 - } - } - } - ], - "library": "tmfx-main" - }, - { - "name": "glacial-aura", - "params": [ - { - "filterType": "zapshadow", - "filterId": "glacial-aura", - "alphaTolerance": 0.5 - }, - { - "filterType": "xglow", - "filterId": "glacial-aura", - "auraType": 1, - "color": 5282269, - "thickness": 4.5, - "scale": 3, - "time": 0, - "auraIntensity": 0.8, - "subAuraIntensity": 0.25, - "threshold": 0.5, - "discard": false, - "animated": { - "time": { - "active": true, - "speed": 0.0018, - "animType": "move" - }, - "thickness": { - "val1": 2, - "val2": 4.7, - "animType": "cosOscillation", - "loopDuration": 3000 - }, - "subAuraIntensity": { - "val1": 0.45, - "val2": 0.65, - "animType": "cosOscillation", - "loopDuration": 6000 - }, - "auraIntensity": { - "val1": 0.9, - "val2": 2.2, - "animType": "cosOscillation", - "loopDuration": 3000 - } - } - } - ], - "library": "tmfx-main" - }, - { - "name": "anti-aura", - "params": [ - { - "filterType": "zapshadow", - "filterId": "anti-aura", - "alphaTolerance": 0.5 - }, - { - "filterType": "xglow", - "filterId": "anti-aura", - "auraType": 2, - "color": 328965, - "thickness": 2.7, - "scale": 7, - "time": 0, - "auraIntensity": 5, - "subAuraIntensity": 2, - "threshold": 0.08, - "discard": false, - "animated": { - "time": { - "active": true, - "speed": 0.0012, - "animType": "move" - }, - "auraIntensity": { - "active": true, - "loopDuration": 3000, - "animType": "syncCosOscillation", - "val1": 5, - "val2": 0 - }, - "subAuraIntensity": { - "active": true, - "loopDuration": 3000, - "animType": "syncCosOscillation", - "val1": 2, - "val2": 0 - }, - "color": { - "active": true, - "loopDuration": 6000, - "animType": "syncColorOscillation", - "val1": 328965, - "val2": 2097152 - }, - "threshold": { - "active": true, - "loopDuration": 1500, - "animType": "syncCosOscillation", - "val1": 0.02, - "val2": 0.5 - } - } - } - ], - "library": "tmfx-main" - }, - { - "name": "pure-fire-aura", - "params": [ - { - "filterType": "fire", - "filterId": "pure-fire-aura", - "intensity": 1, - "color": 16777215, - "amplitude": 1, - "time": 0, - "blend": 2, - "fireBlend": 1, - "animated": { - "time": { - "active": true, - "speed": -0.0024, - "animType": "move" - }, - "intensity": { - "active": true, - "loopDuration": 15000, - "val1": 0.8, - "val2": 2, - "animType": "syncCosOscillation" - }, - "amplitude": { - "active": true, - "loopDuration": 4400, - "val1": 1, - "val2": 1.4, - "animType": "syncCosOscillation" - } - } - }, - { - "filterType": "zapshadow", - "filterId": "pure-fire-aura", - "alphaTolerance": 0.5 - }, - { - "filterType": "xglow", - "filterId": "pure-fire-aura", - "auraType": 2, - "color": 9449488, - "thickness": 9.8, - "scale": 4, - "time": 0, - "auraIntensity": 2, - "subAuraIntensity": 1.5, - "threshold": 0.4, - "discard": true, - "animated": { - "time": { - "active": true, - "speed": 0.0027, - "animType": "move" - }, - "thickness": { - "active": true, - "loopDuration": 3000, - "animType": "cosOscillation", - "val1": 2, - "val2": 5 - } - } - } - ], - "library": "tmfx-main" - }, - { - "name": "pure-fire-aura-2", - "params": [ - { - "filterType": "zapshadow", - "filterId": "pure-fire-aura-2", - "alphaTolerance": 0.5 - }, - { - "filterType": "xglow", - "filterId": "pure-fire-aura-2", - "auraType": 2, - "color": 9449488, - "thickness": 9.8, - "scale": 4, - "time": 0, - "auraIntensity": 1, - "subAuraIntensity": 0.3, - "threshold": 0.5, - "discard": true, - "animated": { - "time": { - "active": true, - "speed": 0.0027, - "animType": "move" - }, - "thickness": { - "active": true, - "loopDuration": 3000, - "animType": "cosOscillation", - "val1": 2, - "val2": 3.6 - } - } - }, - { - "filterType": "fire", - "filterId": "pure-fire-aura-2", - "intensity": 1, - "color": 16777215, - "amplitude": 1, - "time": 0, - "blend": 2, - "fireBlend": 1, - "animated": { - "time": { - "active": true, - "speed": -0.0024, - "animType": "move" - }, - "intensity": { - "active": true, - "loopDuration": 15000, - "val1": 0.8, - "val2": 3, - "animType": "syncCosOscillation" - }, - "amplitude": { - "active": true, - "loopDuration": 4400, - "val1": 1, - "val2": 1.6, - "animType": "syncCosOscillation" - } - } - } - ], - "library": "tmfx-main" - }, - { - "name": "pure-ice-aura", - "params": [ - { - "filterType": "zapshadow", - "filterId": "pure-ice-aura", - "alphaTolerance": 0.5 - }, - { - "filterType": "xglow", - "filterId": "pure-ice-aura", - "auraType": 1, - "color": 5282269, - "thickness": 4.5, - "scale": 10, - "time": 0, - "auraIntensity": 0.25, - "subAuraIntensity": 1, - "threshold": 0.5, - "discard": false, - "animated": { - "time": { - "active": true, - "speed": 0.0018, - "animType": "move" - }, - "thickness": { - "val1": 2, - "val2": 3.3, - "animType": "cosOscillation", - "loopDuration": 3000 - }, - "subAuraIntensity": { - "val1": 0.45, - "val2": 0.65, - "animType": "cosOscillation", - "loopDuration": 6000 - }, - "auraIntensity": { - "val1": 0.9, - "val2": 2.2, - "animType": "cosOscillation", - "loopDuration": 3000 - } - } - }, - { - "filterType": "smoke", - "filterId": "pure-ice-aura", - "color": 8441087, - "time": 0, - "blend": 2, - "dimX": 0.3, - "dimY": 1, - "animated": { - "time": { - "active": true, - "speed": -0.006, - "animType": "move" - }, - "dimX": { - "val1": 0.4, - "val2": 0.2, - "animType": "cosOscillation", - "loopDuration": 3000 - } - } - } - ], - "library": "tmfx-main" - }, - { - "name": "pixelate", - "params": [ - { - "filterType": "pixel", - "filterId": "pixelate", - "sizeX": 2.5, - "sizeY": 2.5 - } - ], - "library": "tmfx-main" - }, - { - "name": "Watery Surface", - "library": "tmfx-template", - "defaultTexture": "modules/tokenmagic/fx/assets/templates/black-tone-strong-opacity.png", - "params": [ - { - "filterType": "flood", - "filterId": "Watery Surface", - "time": 0, - "color": 8379, - "billowy": 0.43, - "tintIntensity": 0.72, - "glint": 0.31, - "scale": 70, - "padding": 10, - "animated": { - "time": { - "active": true, - "speed": 0.0006, - "animType": "move" - } - } - } - ] - }, - { - "name": "Protoplasm", - "library": "tmfx-template", - "defaultTexture": "modules/tokenmagic/fx/assets/templates/black-tone-strong-opacity.png", - "params": [ - { - "filterType": "liquid", - "filterId": "Protoplasm", - "color": 2140910, - "time": 0, - "blend": 8, - "intensity": 4, - "spectral": true, - "scale": 1.4, - "animated": { - "time": { - "active": true, - "speed": 0.001, - "animType": "move" - } - } - } - ] - }, - { - "name": "Watery Surface 2", - "library": "tmfx-template", - "defaultTexture": "modules/tokenmagic/fx/assets/templates/white-tone-strong-opacity.png", - "params": [ - { - "filterType": "liquid", - "filterId": "Watery Surface 2", - "color": 2140910, - "time": 0, - "blend": 8, - "intensity": 4, - "spectral": false, - "scale": 1.4, - "animated": { - "time": { - "active": true, - "speed": 0.001, - "animType": "move" - } - } - } - ] - }, - { - "name": "Smoky Area", - "library": "tmfx-template", - "defaultTexture": "modules/tokenmagic/fx/assets/templates/black-tone-strong-opacity.png", - "params": [ - { - "filterType": "smoke", - "filterId": "Smoky Area", - "color": 11184810, - "time": 0, - "blend": 2, - "dimX": 1, - "dimY": 1, - "animated": { - "time": { - "active": true, - "speed": 0.002, - "animType": "move" - } - } - } - ] - }, - { - "name": "Shock", - "library": "tmfx-template", - "defaultTexture": "modules/tokenmagic/fx/assets/templates/white-tone-strong-opacity.png", - "params": [ - { - "filterType": "electric", - "filterId": "Shock", - "color": 16777215, - "time": 0, - "blend": 1, - "intensity": 5, - "animated": { - "time": { - "active": true, - "speed": 0.002, - "animType": "move" - } - } - } - ] - }, - { - "name": "Annihilating Rays", - "library": "tmfx-template", - "defaultTexture": "modules/tokenmagic/fx/assets/templates/white-tone-strong-opacity.png", - "params": [ - { - "filterType": "xray", - "filterId": "Annihilating Rays", - "time": 0, - "color": 16759552, - "blend": 9, - "dimX": 1, - "dimY": 1, - "anchorX": 0, - "anchorY": 0, - "divisor": 6, - "intensity": 4, - "animated": { - "time": { - "active": true, - "speed": 0.0012, - "animType": "move" - } - } - } - ] - }, - { - "name": "Classic Rays", - "library": "tmfx-template", - "defaultTexture": "modules/tokenmagic/fx/assets/templates/black-tone-strong-opacity.png", - "params": [ - { - "filterType": "ray", - "filterId": "Classic Rays", - "time": 0, - "color": 13598720, - "alpha": 0.5, - "divisor": 32, - "anchorX": 0, - "anchorY": 0, - "animated": { - "time": { - "active": true, - "speed": 0.0005, - "animType": "move" - } - } - } - ] - }, - { - "name": "Smoke Filaments", - "library": "tmfx-template", - "defaultTexture": "modules/tokenmagic/fx/assets/templates/black-tone-strong-opacity.png", - "params": [ - { - "filterType": "fumes", - "filterId": "Smoke Filaments", - "color": 8421504, - "time": 0, - "blend": 8, - "animated": { - "time": { - "active": true, - "speed": 0.001, - "animType": "move" - } - } - } - ] - }, - { - "name": "Flames", - "library": "tmfx-template", - "defaultTexture": "modules/tokenmagic/fx/assets/templates/black-tone-strong-opacity.png", - "params": [ - { - "filterType": "fire", - "filterId": "Flames", - "intensity": 1.5, - "color": 16777215, - "amplitude": 1.3, - "time": 0, - "blend": 2, - "fireBlend": 1, - "animated": { - "time": { - "active": true, - "speed": -0.0016, - "animType": "move" - } - } - } - ] - }, - { - "name": "Thick Fog", - "library": "tmfx-template", - "defaultTexture": "modules/tokenmagic/fx/assets/templates/black-tone-vstrong-opacity.png", - "params": [ - { - "filterType": "xfog", - "filterId": "Thick Fog", - "autoFit": false, - "color": 3182847, - "time": 0, - "animated": { - "time": { - "active": true, - "speed": 0.0006, - "animType": "move" - } - } - } - ] - }, - { - "name": "Glowing Outline", - "library": "tmfx-template", - "params": [ - { - "filterType": "glow", - "filterId": "Glowing Outline", - "outerStrength": 5.5, - "innerStrength": 0, - "color": 24576, - "quality": 0.5, - "padding": 10, - "animated": { - "outerStrength": { - "active": true, - "loopDuration": 3000, - "animType": "syncCosOscillation", - "val1": 5.5, - "val2": 1.5 - } - } - } - ] - }, - { - "name": "Waves", - "library": "tmfx-template", - "defaultTexture": "modules/tokenmagic/fx/assets/templates/white-tone-strong-opacity.png", - "params": [ - { - "filterType": "wave", - "filterId": "Waves", - "time": 0, - "anchorX": 0.5, - "anchorY": 0.5, - "strength": 0.015, - "frequency": 120, - "color": 16777215, - "maxIntensity": 2.5, - "minIntensity": 0.9, - "padding": 10, - "animated": { - "time": { - "active": true, - "speed": 0.0085, - "animType": "move" - } - } - } - ] - }, - { - "name": "Waves 2", - "library": "tmfx-template", - "defaultTexture": "modules/tokenmagic/fx/assets/templates/white-tone-strong-opacity.png", - "params": [ - { - "filterType": "wave", - "filterId": "Waves 2", - "time": 0, - "anchorX": 0.5, - "anchorY": 0.5, - "strength": 0.014, - "frequency": 400, - "color": 16777215, - "maxIntensity": 2.4, - "minIntensity": 0.8, - "padding": 10, - "animated": { - "time": { - "active": true, - "speed": 0.0385, - "animType": "move" - } - } - } - ] - }, - { - "name": "Waves 3", - "library": "tmfx-template", - "defaultTexture": "modules/tokenmagic/fx/assets/templates/white-tone-strong-opacity.png", - "params": [ - { - "filterType": "wave", - "filterId": "Waves 3", - "time": 0, - "anchorX": 0.5, - "anchorY": 0.5, - "strength": 0.017, - "frequency": 35, - "color": 16777215, - "maxIntensity": 2.6, - "minIntensity": 0.9, - "padding": 20, - "animated": { - "time": { - "active": true, - "speed": 0.0085, - "animType": "move" - } - } - } - ] - }, - { - "name": "Zone : Fire", - "library": "tmfx-template", - "defaultTexture": "modules/tokenmagic/fx/assets/templates/black-tone-strong-opacity.png", - "params": [ - { - "filterType": "xglow", - "filterId": "Zone : Fire", - "auraType": 1, - "color": 9449488, - "scale": 1.5, - "time": 0, - "auraIntensity": 1.8, - "subAuraIntensity": 0.25, - "threshold": 0.6, - "discard": false, - "animated": { - "time": { - "active": true, - "speed": 0.0027, - "animType": "move" - }, - "thickness": { - "active": true, - "loopDuration": 3000, - "animType": "cosOscillation", - "val1": 2, - "val2": 5 - } - } - }, - { - "filterType": "fire", - "filterId": "Zone : Fire", - "intensity": 1.5, - "color": 16777215, - "amplitude": 1, - "time": 0, - "blend": 2, - "fireBlend": 1, - "animated": { - "time": { - "active": true, - "speed": -0.0015, - "animType": "move" - } - } - } - ] - }, - { - "name": "Zone : Electricity", - "library": "tmfx-template", - "defaultTexture": "modules/tokenmagic/fx/assets/templates/white-tone-strong-opacity.png", - "params": [ - { - "filterType": "xglow", - "filterId": "Zone : Electricity", - "auraType": 2, - "color": 3158064, - "scale": 1.5, - "time": 0, - "auraIntensity": 1, - "subAuraIntensity": 0.9, - "threshold": 0, - "discard": true, - "animated": { - "time": { - "active": true, - "speed": 0.0027, - "animType": "move" - }, - "thickness": { - "active": true, - "loopDuration": 3000, - "animType": "cosOscillation", - "val1": 1, - "val2": 2 - } - } - }, - { - "filterType": "electric", - "filterId": "Zone : Electricity", - "color": 16777215, - "time": 0, - "blend": 1, - "intensity": 5, - "animated": { - "time": { - "active": true, - "speed": 0.002, - "animType": "move" - } - } - } - ] - }, - { - "name": "Zone : Blizzard", - "library": "tmfx-template", - "defaultTexture": "modules/tokenmagic/fx/assets/templates/black-tone-strong-opacity.png", - "params": [ - { - "filterType": "xglow", - "filterId": "Zone : Blizzard", - "auraType": 1, - "color": 5282269, - "thickness": 4.5, - "scale": 5, - "time": 0, - "auraIntensity": 0.25, - "subAuraIntensity": 1, - "threshold": 0.5, - "discard": false, - "animated": { - "time": { - "active": true, - "speed": 0.0018, - "animType": "move" - }, - "thickness": { - "val1": 2, - "val2": 3.3, - "animType": "cosOscillation", - "loopDuration": 3000 - }, - "subAuraIntensity": { - "val1": 0.05, - "val2": 0.1, - "animType": "cosOscillation", - "loopDuration": 6000 - }, - "auraIntensity": { - "val1": 0.9, - "val2": 2.2, - "animType": "cosOscillation", - "loopDuration": 3000 - } - } - }, - { - "filterType": "smoke", - "filterId": "Zone : Blizzard", - "color": 8441087, - "time": 0, - "blend": 2, - "dimY": 1, - "animated": { - "time": { - "active": true, - "speed": -0.005, - "animType": "move" - }, - "dimX": { - "val1": 0.4, - "val2": 0.2, - "animType": "cosOscillation", - "loopDuration": 3000 - } - } - } - ] - }, - { - "name": "Bulging Out", - "library": "tmfx-template", - "params": [ - { - "filterType": "bulgepinch", - "filterId": "Bulging Out", - "padding": 150, - "strength": 0, - "radiusPercent": 200, - "animated": { - "strength": { - "active": true, - "animType": "cosOscillation", - "loopDuration": 2000, - "val1": 0, - "val2": 0.45 - } - } - } - ] - }, - { - "name": "Blurred Texture", - "library": "tmfx-template", - "params": [ - { - "filterType": "blur", - "filterId": "Blurred Texture", - "padding": 25, - "quality": 4, - "blur": 0, - "blurX": 0, - "blurY": 0, - "animated": { - "blurX": { - "active": true, - "animType": "syncCosOscillation", - "loopDuration": 500, - "val1": 0, - "val2": 6 - }, - "blurY": { - "active": true, - "animType": "syncCosOscillation", - "loopDuration": 750, - "val1": 0, - "val2": 6 - } - } - } - ] - }, - { - "name": "Bloomed Texture", - "library": "tmfx-template", - "params": [ - { - "filterType": "xbloom", - "filterId": "Bloomed Texture", - "threshold": 0.35, - "bloomScale": 0, - "brightness": 1, - "blur": 0.1, - "padding": 10, - "quality": 15, - "blendMode": 0, - "animated": { - "bloomScale": { - "active": true, - "loopDuration": 2000, - "animType": "syncCosOscillation", - "val1": 0, - "val2": 2.1 - }, - "threshold": { - "active": false, - "loopDuration": 1000, - "animType": "syncCosOscillation", - "val1": 0, - "val2": 1.9 - } - } - } - ] - }, - { - "name": "Wild Magic", - "library": "tmfx-template", - "defaultTexture": "modules/tokenmagic/fx/assets/templates/black-tone-strong-opacity.png", - "params": [ - { - "filterType": "liquid", - "filterId": "Wild Magic", - "color": 16711680, - "time": 0, - "blend": 6, - "intensity": 5, - "spectral": false, - "scale": 2.5, - "animated": { - "time": { - "active": true, - "speed": 0.0018, - "animType": "move" - } - } - }, - { - "filterType": "wave", - "filterId": "Wild Magic", - "time": 0, - "anchorX": 0.5, - "anchorY": 0.5, - "strength": 0.014, - "frequency": 10, - "color": 16777215, - "maxIntensity": 1.3, - "minIntensity": 0.6, - "padding": 10, - "animated": { - "time": { - "active": true, - "speed": 0.0065, - "animType": "move" - } - } - } - ] - }, - { - "name": "Spider Web 1", - "library": "tmfx-template", - "defaultTexture": "modules/tokenmagic/fx/assets/templates/black-tone-strong-opacity.png", - "params": [ - { - "filterType": "web", - "filterId": "Spider Web 1", - "anchorX": 0.5, - "anchorY": 0.5, - "animated": { - "time": { - "active": true, - "speed": 0.0005, - "animType": "move" - } - } - }, - { - "filterType": "blur", - "filterId": "Spider Web 1", - "padding": 10, - "quality": 5, - "blur": 1.4 - }, - { - "filterType": "liquid", - "filterId": "Spider Web 1", - "color": 16711680, - "time": 0, - "blend": 1, - "intensity": 8, - "spectral": false, - "scale": 0.2, - "animated": { - "time": { - "active": true, - "speed": 0.0005, - "animType": "move" - } - } - } - ] - }, - { - "name": "Spider Web 2", - "library": "tmfx-template", - "defaultTexture": "modules/tokenmagic/fx/assets/templates/black-tone-strong-opacity.png", - "params": [ - { - "filterType": "web", - "filterId": "Spider Web 2", - "anchorX": 0.5, - "anchorY": 0.5, - "time": 100 - }, - { - "filterType": "blur", - "filterId": "Spider Web 2", - "padding": 10, - "quality": 5, - "blur": 1.4 - }, - { - "filterType": "xfog", - "filterId": "Spider Web 2", - "autoFit": false, - "color": 9474192, - "time": 0, - "animated": { - "time": { - "active": true, - "speed": 0.0002, - "animType": "move" - } - } - }, - { - "filterType": "bulgepinch", - "filterId": "Spider Web 2", - "strength": 0, - "padding": 50, - "radiusPercent": 120, - "animated": { - "strength": { - "active": true, - "animType": "cosOscillation", - "loopDuration": 3000, - "val1": 0.45, - "val2": 0 - } - } - } - ] - } -] diff --git a/tokenmagic/import/TMFX-update-presets-v040.json b/tokenmagic/import/TMFX-update-presets-v040.json deleted file mode 100644 index 12a9bc9..0000000 --- a/tokenmagic/import/TMFX-update-presets-v040.json +++ /dev/null @@ -1,569 +0,0 @@ -[ - { - "name": "Spider Web 4", - "library": "tmfx-template", - "defaultTexture": "modules/tokenmagic/fx/assets/templates/black-tone-strong-opacity.png", - "params": [ - { - "filterType": "web", - "filterId": "Spider Web 4", - "anchorX": 0.5, - "anchorY": 0.5, - "color": 13421772, - "thickness": 2, - "div2": 5, - "time": 98.8, - "zOrder": 1, - "alphaDiscard": true, - "animated": { - "time": { - "active": true, - "loopDuration": 5000, - "animType": "cosOscillation", - "val1": 98.8, - "val2": 99.7 - } - } - }, - { - "filterType": "glow", - "filterId": "Spider Web 4", - "outerStrength": 7, - "innerStrength": 3, - "color": 24576, - "quality": 0.5, - "padding": 10, - "zOrder": 2, - "animated": { - "outerStrength": { - "active": true, - "loopDuration": 3000, - "animType": "syncCosOscillation", - "val1": 7, - "val2": 4 - } - } - } - ] - }, - { - "name": "Spider Web 5", - "library": "tmfx-template", - "defaultTexture": "modules/tokenmagic/fx/assets/templates/black-tone-strong-opacity.png", - "params": [ - { - "filterType": "web", - "filterId": "Spider Web 5", - "anchorX": 0.5, - "anchorY": 0.5, - "color": 10395294, - "thickness": 0.8, - "div2": 7, - "div1": 15, - "time": 97.8, - "alphaDiscard": true, - "zOrder": 1, - "animated": { - "time": { - "active": true, - "loopDuration": 5000, - "animType": "cosOscillation", - "val1": 97.8, - "val2": 98.2 - } - } - }, - { - "filterType": "glow", - "filterId": "Spider Web 5", - "outerStrength": 6, - "innerStrength": 3, - "color": 10395294, - "quality": 0.5, - "padding": 10, - "zOrder": 2, - "animated": { - "outerStrength": { - "active": true, - "loopDuration": 3000, - "animType": "syncCosOscillation", - "val1": 6, - "val2": 4 - } - } - } - ] - }, - { - "name": "Ripples : Solar", - "library": "tmfx-template", - "defaultTexture": "modules/tokenmagic/fx/assets/templates/black-tone-strong-opacity.png", - "params": [ - { - "filterType": "ripples", - "filterId": "Ripples : Solar", - "color": 13206066, - "time": 98.8, - "zOrder": 1, - "animated": { - "time": { - "active": true, - "animType": "move", - "speed": 0.0005 - } - } - } - ] - }, - { - "name": "Ripples : Shadow Sun", - "library": "tmfx-template", - "defaultTexture": "modules/tokenmagic/fx/assets/templates/black-tone-strong-opacity.png", - "params": [ - { - "filterType": "ripples", - "filterId": "Ripples : Shadow Sun", - "color": 6560636, - "time": 98.8, - "zOrder": 1, - "alphaDiscard": true, - "animated": { - "time": { - "active": true, - "animType": "move", - "speed": 0.0005 - } - } - } - ] - }, - { - "name": "Ripples : Scars", - "library": "tmfx-template", - "defaultTexture": "modules/tokenmagic/fx/assets/templates/black-tone-strong-opacity.png", - "params": [ - { - "filterType": "ripples", - "filterId": "Ripples : Scars", - "color": 2516765, - "time": 98.8, - "zOrder": 1, - "alphaDiscard": true, - "animated": { - "time": { - "active": true, - "animType": "move", - "speed": 0.0005 - } - } - }, - { - "filterType": "glow", - "filterId": "Ripples : Scars", - "outerStrength": 7.5, - "innerStrength": 0.5, - "color": 2516765, - "quality": 0.5, - "padding": 10, - "zOrder": 2, - "animated": { - "outerStrength": { - "active": true, - "loopDuration": 3000, - "animType": "syncCosOscillation", - "val1": 7.5, - "val2": 5.5 - } - } - } - ] - }, - { - "name": "Fairy Fireflies : Calm", - "library": "tmfx-template", - "defaultTexture": "modules/tokenmagic/fx/assets/templates/black-tone-strong-opacity.png", - "params": [ - { - "filterType": "globes", - "filterId": "Fairy Fireflies : Calm", - "color": 2516765, - "time": 98.8, - "zOrder": 1, - "distortion": 0.25, - "scale": 80, - "alphaDiscard": true, - "animated": { - "time": { - "active": true, - "animType": "move", - "speed": 0.0007 - } - } - } - ] - }, - { - "name": "Fairy Fireflies : Excited", - "library": "tmfx-template", - "defaultTexture": "modules/tokenmagic/fx/assets/templates/black-tone-strong-opacity.png", - "params": [ - { - "filterType": "globes", - "filterId": "Fairy Fireflies : Excited", - "color": 31969, - "time": 98.8, - "zOrder": 1, - "distortion": 0.25, - "scale": 80, - "alphaDiscard": true, - "animated": { - "time": { - "active": true, - "animType": "move", - "speed": 0.0012 - } - } - }, - { - "filterType": "glow", - "filterId": "Fairy Fireflies : Excited", - "outerStrength": 7.5, - "innerStrength": 0.5, - "color": 31969, - "quality": 0.5, - "padding": 10, - "zOrder": 2, - "animated": { - "outerStrength": { - "active": true, - "loopDuration": 3000, - "animType": "syncCosOscillation", - "val1": 7.5, - "val2": 5.5 - } - } - } - ] - }, - { - "name": "Fairy Fireflies : Frenetic", - "library": "tmfx-template", - "defaultTexture": "modules/tokenmagic/fx/assets/templates/black-tone-strong-opacity.png", - "params": [ - { - "filterType": "globes", - "filterId": "Fairy Fireflies : Frenetic", - "color": 14803200, - "time": 98.8, - "zOrder": 1, - "distortion": 1.45, - "scale": 80, - "alphaDiscard": true, - "animated": { - "time": { - "active": true, - "animType": "move", - "speed": 0.0016 - } - } - }, - { - "filterType": "glow", - "filterId": "Fairy Fireflies : Frenetic", - "outerStrength": 7.5, - "innerStrength": 0.5, - "color": 14803200, - "quality": 0.5, - "padding": 10, - "zOrder": 2, - "animated": { - "outerStrength": { - "active": true, - "loopDuration": 3000, - "animType": "syncCosOscillation", - "val1": 7.5, - "val2": 5.5 - } - } - } - ] - }, - { - "name": "Living Fluid", - "library": "tmfx-template", - "defaultTexture": "modules/tokenmagic/fx/assets/templates/black-tone-vstrong-opacity.png", - "params": [ - { - "filterType": "xfog", - "filterId": "Living Fluid", - "color": 14872211, - "autoFit": false, - "time": 0, - "zOrder": 1, - "alphaDiscard": true, - "animated": { - "time": { - "active": true, - "animType": "move", - "speed": 0.0007 - } - } - } - ] - }, - { - "name": "Living Fluid 2", - "library": "tmfx-template", - "defaultTexture": "modules/tokenmagic/fx/assets/templates/black-tone-vstrong-opacity.png", - "params": [ - { - "filterType": "xfog", - "filterId": "Living Fluid 2", - "color": 14872211, - "autoFit": false, - "time": 0, - "zOrder": 1, - "alphaDiscard": true, - "animated": { - "time": { - "active": true, - "animType": "move", - "speed": 0.0007 - } - } - }, - { - "filterType": "glow", - "filterId": "Living Fluid 2", - "outerStrength": 0.5, - "innerStrength": 0.5, - "color": 14872211, - "quality": 0.5, - "padding": 10, - "zOrder": 2 - } - ] - }, - { - "name": "Living Fluid 3", - "library": "tmfx-template", - "defaultTexture": "modules/tokenmagic/fx/assets/templates/black-tone-vstrong-opacity.png", - "params": [ - { - "filterType": "liquid", - "filterId": "Living Fluid 3", - "color": 6937746, - "time": 0, - "blend": 8, - "intensity": 4, - "spectral": true, - "alphaDiscard": true, - "scale": 1.4, - "zOrder": 1, - "animated": { - "time": { - "active": true, - "speed": 0.001, - "animType": "move" - } - } - } - ] - }, - { - "name": "Living Fluid 4", - "library": "tmfx-template", - "defaultTexture": "modules/tokenmagic/fx/assets/templates/black-tone-vstrong-opacity.png", - "params": [ - { - "filterType": "liquid", - "filterId": "Living Fluid 4", - "color": 15107115, - "time": 0, - "blend": 8, - "intensity": 4, - "spectral": false, - "alphaDiscard": true, - "scale": 1.4, - "zOrder": 1, - "animated": { - "time": { - "active": true, - "speed": 0.001, - "animType": "move" - } - } - }, - { - "filterType": "glow", - "filterId": "Living Fluid 4", - "outerStrength": 1, - "innerStrength": 1, - "color": 15107115, - "quality": 0.5, - "padding": 10, - "zOrder": 2 - } - ] - }, - { - "name": "Flames 2", - "library": "tmfx-template", - "defaultTexture": "modules/tokenmagic/fx/assets/templates/black-tone-vstrong-opacity.png", - "params": [ - { - "filterType": "fire", - "filterId": "Flames 2", - "intensity": 1.5, - "color": "0xFFFFFF", - "amplitude": 1.3, - "time": 0, - "blend": 2, - "fireBlend": 1, - "alphaDiscard": true, - "zOrder": 1, - "animated": { - "time": { - "active": true, - "speed": -0.0016, - "animType": "move" - } - } - } - ] - }, - { - "name": "Flames 3", - "library": "tmfx-template", - "defaultTexture": "modules/tokenmagic/fx/assets/templates/black-tone-pure.png", - "params": [ - { - "filterType": "fire", - "filterId": "Flames 3", - "intensity": 1.5, - "color": "0xFFFFFF", - "amplitude": 1.3, - "time": 0, - "blend": 2, - "fireBlend": 1, - "alphaDiscard": true, - "zOrder": 1, - "animated": { - "time": { - "active": true, - "speed": -0.0016, - "animType": "move" - } - } - }, - { - "filterType": "xglow", - "filterId": "Flames 3", - "auraType": 1, - "color": "0x903010", - "thickness": 2, - "scale": "3", - "time": 0, - "auraIntensity": 1, - "subAuraIntensity": 1, - "threshold": 0.4, - "discard": true, - "zOrder": 2, - "animated": { - "time": { - "active": true, - "speed": 0.0027, - "animType": "move" - }, - "thickness": { - "active": true, - "loopDuration": 3000, - "animType": "cosOscillation", - "val1": 2, - "val2": 5 - } - } - } - ] - }, - { - "name": "Classic Rays 2", - "library": "tmfx-template", - "defaultTexture": "modules/tokenmagic/fx/assets/templates/black-tone-vstrong-opacity.png", - "params": [ - { - "filterType": "ray", - "filterId": "Classic Rays 2", - "time": 0, - "color": "0xCF8000", - "alpha": 1, - "divisor": 16, - "anchorX": 0, - "anchorY": 0, - "alphaDiscard": true, - "zOrder": 1, - "animated": { - "time": { - "active": true, - "speed": 0.0009, - "animType": "move" - } - } - } - ] - }, - { - "name": "Fire Rays", - "library": "tmfx-template", - "defaultTexture": "modules/tokenmagic/fx/assets/templates/black-tone-pure.png", - "params": [ - { - "filterType": "ray", - "filterId": "Fire Rays", - "time": 0, - "color": "0xCF8000", - "alpha": 1, - "divisor": 24, - "anchorX": 0, - "anchorY": 0, - "alphaDiscard": true, - "zOrder": 1, - "animated": { - "time": { - "active": true, - "speed": 0.0009, - "animType": "move" - } - } - }, - { - "filterType": "glow", - "filterId": "Fire Rays", - "outerStrength": 1, - "innerStrength": 1, - "color": "0x906000", - "quality": 0.5, - "padding": 10, - "zOrder": 2 - }, - { - "filterType": "fire", - "filterId": "Fire Rays", - "intensity": 1.5, - "color": "0xFFFFFF", - "amplitude": 1.3, - "time": 0, - "blend": 2, - "fireBlend": 1, - "zOrder": 3, - "animated": { - "time": { - "active": true, - "speed": -0.0016, - "animType": "move" - } - } - } - ] - } -] diff --git a/tokenmagic/import/TMFX-update-presets-v040b.json b/tokenmagic/import/TMFX-update-presets-v040b.json deleted file mode 100644 index 2060cd0..0000000 --- a/tokenmagic/import/TMFX-update-presets-v040b.json +++ /dev/null @@ -1,162 +0,0 @@ -[ - { - "name": "Flames 2", - "library": "tmfx-template", - "defaultTexture": "modules/tokenmagic/fx/assets/templates/black-tone-vstrong-opacity.png", - "params": [ - { - "filterType": "fire", - "filterId": "Flames 2", - "intensity": 1.5, - "color": 16777215, - "amplitude": 1.3, - "time": 0, - "blend": 2, - "fireBlend": 1, - "alphaDiscard": true, - "zOrder": 1, - "animated": { - "time": { - "active": true, - "speed": -0.0016, - "animType": "move" - } - } - } - ] - }, - { - "name": "Flames 3", - "library": "tmfx-template", - "defaultTexture": "modules/tokenmagic/fx/assets/templates/black-tone-pure.png", - "params": [ - { - "filterType": "fire", - "filterId": "Flames 3", - "intensity": 1.5, - "color": 16777215, - "amplitude": 1.3, - "time": 0, - "blend": 2, - "fireBlend": 1, - "alphaDiscard": true, - "zOrder": 1, - "animated": { - "time": { - "active": true, - "speed": -0.0016, - "animType": "move" - } - } - }, - { - "filterType": "xglow", - "filterId": "Flames 3", - "auraType": 1, - "color": 9449488, - "thickness": 2, - "scale": "3", - "time": 0, - "auraIntensity": 1, - "subAuraIntensity": 1, - "threshold": 0.4, - "discard": true, - "zOrder": 2, - "animated": { - "time": { - "active": true, - "speed": 0.0027, - "animType": "move" - }, - "thickness": { - "active": true, - "loopDuration": 3000, - "animType": "cosOscillation", - "val1": 2, - "val2": 5 - } - } - } - ] - }, - { - "name": "Classic Rays 2", - "library": "tmfx-template", - "defaultTexture": "modules/tokenmagic/fx/assets/templates/black-tone-vstrong-opacity.png", - "params": [ - { - "filterType": "ray", - "filterId": "Classic Rays 2", - "time": 0, - "color": 13598720, - "alpha": 1, - "divisor": 16, - "anchorX": 0, - "anchorY": 0, - "alphaDiscard": true, - "zOrder": 1, - "animated": { - "time": { - "active": true, - "speed": 0.0009, - "animType": "move" - } - } - } - ] - }, - { - "name": "Fire Rays", - "library": "tmfx-template", - "defaultTexture": "modules/tokenmagic/fx/assets/templates/black-tone-pure.png", - "params": [ - { - "filterType": "ray", - "filterId": "Fire Rays", - "time": 0, - "color": 13598720, - "alpha": 1, - "divisor": 24, - "anchorX": 0, - "anchorY": 0, - "alphaDiscard": true, - "zOrder": 1, - "animated": { - "time": { - "active": true, - "speed": 0.0009, - "animType": "move" - } - } - }, - { - "filterType": "glow", - "filterId": "Fire Rays", - "outerStrength": 1, - "innerStrength": 1, - "color": 9461760, - "quality": 0.5, - "padding": 10, - "zOrder": 2 - }, - { - "filterType": "fire", - "filterId": "Fire Rays", - "intensity": 1.5, - "color": 16777215, - "amplitude": 1.3, - "time": 0, - "blend": 2, - "fireBlend": 1, - "zOrder": 3, - "animated": { - "time": { - "active": true, - "speed": -0.0016, - "animType": "move" - } - } - } - ] - } -] diff --git a/tokenmagic/import/TMFX-update-presets-v041.json b/tokenmagic/import/TMFX-update-presets-v041.json deleted file mode 100644 index 3c4a928..0000000 --- a/tokenmagic/import/TMFX-update-presets-v041.json +++ /dev/null @@ -1,148 +0,0 @@ -[ - { - "name": "Splash 1", - "library": "tmfx-template", - "defaultTexture": "modules/tokenmagic/fx/assets/templates/black-tone-vstrong-opacity.png", - "params": [ - { - "filterType": "splash", - "filterId": "Splash 1", - "color": 9438469, - "time": 25, - "seed": 0.1, - "splashFactor": 5, - "spread": 10, - "blend": 2, - "dimX": 1, - "dimY": 1, - "cut": true, - "textureAlphaBlend": true, - "padding": 200, - "zOrder": 1 - }, - { - "filterType": "glow", - "filterId": "Splash 1", - "outerStrength": 3.3, - "innerStrength": 1, - "color": 9438469, - "quality": 0.5, - "padding": 10, - "zOrder": 2 - } - ] - }, - { - "name": "Splash 2", - "library": "tmfx-template", - "defaultTexture": "modules/tokenmagic/fx/assets/templates/black-tone-vstrong-opacity.png", - "params": [ - { - "filterType": "splash", - "filterId": "Splash 2", - "color": 9438469, - "time": 25, - "seed": 0.1, - "splashFactor": 3, - "spread": 10, - "blend": 2, - "dimX": 1, - "dimY": 1, - "cut": true, - "textureAlphaBlend": true, - "padding": 200, - "zOrder": 1, - "animated": { - "time": { - "active": true, - "speed": 0.0009, - "animType": "move" - } - } - }, - { - "filterType": "glow", - "filterId": "Splash 2", - "outerStrength": 2, - "innerStrength": 1, - "color": 9438469, - "quality": 0.5, - "padding": 10, - "zOrder": 2 - } - ] - }, - { - "name": "Splash 3", - "library": "tmfx-template", - "defaultTexture": "modules/tokenmagic/fx/assets/templates/black-tone-vstrong-opacity.png", - "params": [ - { - "filterType": "fumes", - "filterId": "Splash 3", - "color": 3690878, - "time": 0, - "blend": 4, - "zOrder": 1, - "animated": { - "time": { - "active": true, - "speed": 0.001, - "animType": "move" - } - } - }, - { - "filterType": "splash", - "filterId": "Splash 3", - "color": 3690878, - "time": 25, - "seed": 0.1, - "splashFactor": 3, - "spread": 10, - "blend": 2, - "dimX": 1, - "dimY": 1, - "cut": true, - "textureAlphaBlend": true, - "padding": 200, - "zOrder": 2, - "animated": { - "time": { - "active": true, - "speed": 0.0009, - "animType": "move" - } - } - }, - { - "filterType": "glow", - "filterId": "Splash 3", - "outerStrength": 3, - "innerStrength": 0.5, - "color": 3690878, - "quality": 0.5, - "padding": 10, - "zOrder": 3 - }, - { - "filterType": "liquid", - "filterId": "Splash 3", - "color": 3690878, - "time": 0, - "blend": 8, - "intensity": 3, - "spectral": false, - "scale": 2, - "zOrder": 4, - "animated": { - "time": { - "active": true, - "speed": 0.0015, - "animType": "move" - } - } - } - ] - } -] diff --git a/tokenmagic/import/TMFX-update-presets-v043.json b/tokenmagic/import/TMFX-update-presets-v043.json deleted file mode 100644 index a8f171f..0000000 --- a/tokenmagic/import/TMFX-update-presets-v043.json +++ /dev/null @@ -1,409 +0,0 @@ -[ - { - "name": "Flames 4 (colorizable)", - "library": "tmfx-template", - "defaultTexture": "modules/tokenmagic/fx/assets/templates/black-tone-vstrong-opacity.png", - "params": [ - { - "filterType": "xfire", - "filterId": "Flames 4 (colorizable)", - "color": 0, - "blend": 1, - "amplitude": 1, - "dispersion": 0, - "inlay": false, - "zOrder": 1, - "animated": { - "time": { - "active": true, - "speed": -0.0015, - "animType": "move" - } - } - } - ] - }, - { - "name": "Flames 5 (colorizable)", - "library": "tmfx-template", - "defaultTexture": "modules/tokenmagic/fx/assets/templates/black-tone-vstrong-opacity.png", - "params": [ - { - "filterType": "xfire", - "filterId": "Flames 5 (colorizable)", - "color": 0, - "blend": 1, - "amplitude": 1, - "dispersion": 0, - "inlay": false, - "alphaDiscard": true, - "discardThreshold": 0.35, - "zOrder": 1, - "animated": { - "time": { - "active": true, - "speed": -0.0015, - "animType": "move" - } - } - } - ] - }, - { - "name": "Flames 6 (colorizable)", - "library": "tmfx-template", - "defaultTexture": "modules/tokenmagic/fx/assets/templates/black-tone-vstrong-opacity.png", - "params": [ - { - "filterType": "xfire", - "filterId": "Flames 6 (colorizable)", - "color": 0, - "blend": 1, - "amplitude": 1, - "dispersion": 0, - "inlay": false, - "alphaDiscard": true, - "discardThreshold": 0.35, - "zOrder": 1, - "animated": { - "time": { - "active": true, - "speed": -0.0015, - "animType": "move" - } - } - }, - { - "filterType": "blur", - "filterId": "Flames 6 (colorizable)", - "padding": 30, - "quality": 4.0, - "blur": 2, - "zOrder": 2 - } - ] - }, - { - "name": "Fire v2", - "library": "tmfx-main", - "params": [ - { - "filterType": "xfire", - "filterId": "Fire v2", - "time": 0, - "blend": 1, - "amplitude": 1, - "dispersion": 0, - "chromatic": false, - "scaleX": 1.5, - "scaleY": 1, - "inlay": false, - "animated": { - "time": { - "active": true, - "speed": -0.0015, - "animType": "move" - } - } - } - ] - }, - { - "name": "Fire v2 (chromatic)", - "library": "tmfx-main", - "params": [ - { - "filterType": "xfire", - "filterId": "Fire v2 (chromatic)", - "time": 0, - "blend": 2, - "amplitude": 1.1, - "dispersion": 0, - "chromatic": true, - "scaleX": 1, - "scaleY": 1, - "inlay": false, - "animated": { - "time": { - "active": true, - "speed": -0.0015, - "animType": "move" - } - } - } - ] - }, - { - "name": "Fire v2 (sparks)", - "library": "tmfx-main", - "params": [ - { - "filterType": "xfire", - "filterId": "Fire v2 (sparks)", - "time": 0, - "blend": 2, - "amplitude": 0.7, - "dispersion": 0, - "chromatic": false, - "scaleX": 2, - "scaleY": 2, - "inlay": false, - "animated": { - "time": { - "active": true, - "speed": -0.0015, - "animType": "move" - } - } - } - ] - }, - { - "name": "Fire v2 (coldfire)", - "library": "tmfx-main", - "params": [ - { - "filterType": "xfire", - "filterId": "Fire v2 (coldfire)", - "time": 0, - "color": 12312046, - "blend": 1, - "amplitude": 1, - "dispersion": 0, - "chromatic": false, - "scaleX": 1, - "scaleY": 1, - "inlay": false, - "animated": { - "time": { - "active": true, - "speed": -0.0015, - "animType": "move" - } - } - } - ] - }, - { - "name": "Fire v2 (blackfire)", - "library": "tmfx-main", - "params": [ - { - "filterType": "xfire", - "filterId": "Fire v2 (blackfire)", - "time": 0, - "color": 7368816, - "blend": 11, - "amplitude": 1, - "dispersion": 2.2, - "chromatic": false, - "scaleX": 2.5, - "scaleY": 2, - "inlay": false, - "animated": { - "time": { - "active": true, - "speed": -0.0015, - "animType": "move" - } - } - } - ] - }, - { - "name": "Super-Frost", - "library": "tmfx-main", - "params": [ - { - "filterType": "xfire", - "filterId": "Super-Frost", - "color": 11322821, - "time": 0, - "blend": 5, - "amplitude": 1, - "dispersion": 0, - "chromatic": false, - "scaleX": 1, - "scaleY": 1, - "inlay": true, - "animated": { - "time": { - "active": true, - "speed": -0.002, - "animType": "move" - } - } - } - ] - }, - { - "name": "Super-Heat", - "library": "tmfx-main", - "params": [ - { - "filterType": "xfire", - "filterId": "Super-Heat", - "time": 0, - "blend": 5, - "amplitude": 0.25, - "dispersion": -1, - "chromatic": false, - "scaleX": 1, - "scaleY": 1, - "inlay": true, - "animated": { - "time": { - "active": true, - "speed": -0.009, - "animType": "move" - } - } - } - ] - }, - { - "name": "Evade Stance", - "library": "tmfx-main", - "params": [ - { - "filterType": "transform", - "filterId": "Evade Stance", - "padding": 50, - "animated": { - "translationX": { - "animType": "sinOscillation", - "val1": -0.125, - "val2": 0.125, - "loopDuration": 1400 - }, - "translationY": { - "animType": "cosOscillation", - "val1": -0.035, - "val2": 0.035, - "loopDuration": 1400 - } - } - } - ] - }, - { - "name": "Saving Roll", - "library": "tmfx-main", - "params": [ - { - "filterType": "transform", - "filterId": "Saving Roll", - "autoDestroy": true, - "padding": 80, - "pivotX": 0.5, - "pivotY": 0.55, - "animated": { - "translationX": { - "animType": "sinOscillation", - "val1": -0.22, - "val2": 0.22, - "loops": 1, - "loopDuration": 1250 - }, - "rotation": { - "animType": "sinOscillation", - "val1": -360, - "val2": 360, - "loops": 1, - "loopDuration": 1250 - }, - "scaleY": { - "animType": "cosOscillation", - "val1": 1, - "val2": 1.3, - "loops": 2, - "loopDuration": 625 - }, - "scaleX": { - "animType": "cosOscillation", - "val1": 1, - "val2": 1.4, - "loops": 2, - "loopDuration": 625 - } - } - } - ] - }, - { - "name": "Dodge Jump", - "library": "tmfx-main", - "params": [ - { - "filterType": "transform", - "filterId": "Dodge Jump", - "autoDestroy": true, - "padding": 80, - "animated": { - "translationY": { - "animType": "cosOscillation", - "val1": 0, - "val2": -0.225, - "loops": 1, - "loopDuration": 900 - }, - "scaleY": { - "animType": "cosOscillation", - "val1": 1, - "val2": 0.65, - "loops": 2, - "loopDuration": 450 - }, - "scaleX": { - "animType": "cosOscillation", - "val1": 1, - "val2": 0.65, - "loops": 2, - "loopDuration": 450 - } - } - } - ] - }, - { - "name": "Fairy Outline", - "library": "tmfx-main", - "params": [ - { - "filterType": "globes", - "filterId": "Fairy Outline", - "time": 0, - "color": 3178734, - "distortion": 0.9, - "scale": 320, - "alphaDiscard": true, - "zOrder": 1, - "animated": { - "time": { - "active": true, - "speed": 0.0015, - "animType": "move" - } - } - }, - { - "filterType": "glow", - "filterId": "Fairy Outline", - "outerStrength": 4, - "innerStrength": 0, - "color": 16723968, - "quality": 0.5, - "padding": 10, - "animated": { - "color": { - "active": true, - "loopDuration": 3000, - "animType": "colorOscillation", - "val1": 16723968, - "val2": 3211008 - } - } - } - ] - } -] diff --git a/tokenmagic/lang/en.json b/tokenmagic/lang/en.json deleted file mode 100644 index 696fb3e..0000000 --- a/tokenmagic/lang/en.json +++ /dev/null @@ -1,58 +0,0 @@ -{ - "TMFX.TokenMagic": "TokenMagic", - "TMFX.preset.add.success": "The FX has been successfully added to the preset library.", - "TMFX.preset.add.permission.failure": "You are not allowed to add FX to the preset library.", - "TMFX.preset.add.params.failure": "The FX could not be added to the preset library. The parameters are incorrect.", - "TMFX.preset.add.duplicate.failure": "The FX could not be added to the preset library. An FX with the same name already exists.", - "TMFX.preset.delete.success": "The FX has been successfully removed from the preset library.", - "TMFX.preset.delete.permission.failure": "You are not allowed to delete FX in the preset library.", - "TMFX.preset.delete.params.failure": "Deletion failed : the \"name\" parameter must be a string.", - "TMFX.preset.delete.notfound.failure": "The FX to delete does not exist in the preset library.", - "TMFX.preset.delete.empty.failure": "Failure : the preset library is already empty !", - "TMFX.preset.import.format.failure": "The import could not be completed. Invalid format.", - "TMFX.preset.import.success": "The FX import was completed successfully.", - "TMFX.preset.import.failure": "The import could not be completed.", - "TMFX.preset.reset.message": "Are you sure you want to reset your library of presets?", - "TMFX.preset.reset.success": "Your preset library has been successfully reset.", - "TMFX.settings.importOverwrite.name": "Overwrite on import", - "TMFX.settings.importOverwrite.hint": "Check this option if you want to replace presets with the same name during an import.", - "TMFX.template.opacity": "Texture Opacity:", - "TMFX.template.fx": "Special Effects:", - "TMFX.template.tint": "Effect Tint:", - "TMFX.settings.autoFPS.name": "Auto framerate", - "TMFX.settings.autoFPS.hint": "Check this option to let the browser (or the application) choose the framerate limit. May suppress jerky animations on some configurations. (Warning : this option overrides Foundry framerate limit)", - "TMFX.settings.useMaxPadding.name": "FX in additive padding mode", - "TMFX.settings.useMaxPadding.hint": "By default, FX paddings are additives when applied on a given placeable. If the checkbox is unchecked, the maximum padding is used.", - "TMFX.settings.minPadding.name": "Minimum padding", - "TMFX.settings.minPadding.hint": "The minimum padding applied to an FX.", - "TMFX.settings.fxPlayerPermission.name": "Permissive mode", - "TMFX.settings.fxPlayerPermission.hint": "If this option is checked, non-GM players can add, modify and delete FX on placeables which they do not own. A GM must be connected.", - "TMFX.settings.useZOrder.name": "Order the FX", - "TMFX.settings.useZOrder.hint": "Check this option if you want the effects to be applied in the order of their zOrder property. Effects with the smallest zOrder are applied first. (See the documentation)", - "TMFX.settings.disableAnimations.name": "Disable FX Animations", - "TMFX.settings.disableAnimations.hint": "Check this option if you want to disable FX animations. Requires a foundry reload.", - "TMFX.settings.disableCaching.name": "Disable filter caching on startup", - "TMFX.settings.disableCaching.hint": "Check this option if you want to disable filter caching on foundry startup.", - "TMFX.settings.disableVideo.name": "Disable video support in templates", - "TMFX.settings.disableVideo.hint": "Check this option if you want to disable video support and texture autoresize in templates.", - "TMFX.settings.autoTemplateEnabled.name": "Enable automatic template effects", - "TMFX.settings.autoTemplateEnabled.hint": "Disabling this option will disable all automatic template effects. NOTE: Only affects newly placed templates.", - "TMFX.settings.defaultTemplateOnHover.name": "Default template grid on hover", - "TMFX.settings.defaultTemplateOnHover.hint": "Display the default template grid only when hovering.", - "TMFX.settings.autohideTemplateElements.name": "Automatically hide template elements", - "TMFX.settings.autohideTemplateElements.hint": "Display nonessential template elements only when hovering on the template layer.", - "TMFX.settings.autoTemplateSettings.button.name": "Automatic Template Effects", - "TMFX.settings.autoTemplateSettings.button.label": "Template Settings", - "TMFX.settings.autoTemplateSettings.button.hint": "On game systems that are supported, template effects can be enabled based on the type of spell area and damage type, or with overrides for specific spells.", - "TMFX.settings.autoTemplateSettings.tabs.general": "General", - "TMFX.settings.autoTemplateSettings.tabs.categories": "Categories", - "TMFX.settings.autoTemplateSettings.tabs.overrides": "Overrides", - "TMFX.settings.autoTemplateSettings.texture.label": "Texture (optional):", - "TMFX.settings.autoTemplateSettings.target.label": "Target:", - "TMFX.settings.autoTemplateSettings.texture.hint": "Optionally specify a texture for the filter, if one is not specified, an appropriate texture will be used.", - "TMFX.settings.autoTemplateSettings.unsupported": "This feature is currently unsupportted for this game system, contributions to enable more systems would be more than welcome!", - "TMFX.settings.autoTemplateSettings.overrides.introduction": "You may configure overrides for individual items/spells here. Enter the name of the item/spell as it appears in your Items/Compendiums in the Target field, and configure your preferred settings.", - "TMFX.settings.autoTemplateSettings.overrides.add": "Add Override", - "TMFX.settings.autoTemplateSettings.dialog.title": "Token Magic Template Settings", - "TMFX.save": "Save" -} diff --git a/tokenmagic/lang/es.json b/tokenmagic/lang/es.json deleted file mode 100644 index 43ae7f8..0000000 --- a/tokenmagic/lang/es.json +++ /dev/null @@ -1,59 +0,0 @@ -{ - "I18N.LANGUAGE": "Español", - "I18N.MAINTAINERS": "@Viriato139ac#0342", - - "TMFX.TokenMagic": "TokenMagic", - "TMFX.preset.add.success": "FX añadido con éxito a la biblioteca de parámetros predeterminados", - "TMFX.preset.add.permission.failure": "No tiene permisos para añadir el FX a la biblioteca de parámetros predeterminados", - "TMFX.preset.add.params.failure": "El FX no se ha podido añadir a la biblioteca de parámetros predeterminados. Parámetros incorrectos", - "TMFX.preset.add.duplicate.failure": "El FX no se ha podido añadir a la biblioteca de parámetros predeterminados. Ya existe un FX con el mismo nombre", - "TMFX.preset.delete.success": "Se ha eliminado correctamente el FX de la biblioteca de parámetros predeterminados", - "TMFX.preset.delete.permission.failure": "No tiene permisos para borrar el FX de la biblioteca de parámetros predeterminados", - "TMFX.preset.delete.params.failure": "Fallo en la eliminación : el parámetro \"name\" debe ser un carácter", - "TMFX.preset.delete.notfound.failure": "El FX que se quiere borrar no existe en la biblioteca de parámetros predeterminados", - "TMFX.preset.delete.empty.failure": "Fallo : ¡ la biblioteca de parámetros predeterminados ya está vacía !", - "TMFX.preset.import.format.failure": "Importación no completada. Formato inválido", - "TMFX.preset.import.success": "La importación de FX ha sido completada con éxito", - "TMFX.preset.import.failure": "La importación no pudo ser completada", - "TMFX.preset.reset.message": "¿Está seguro de que quiere reiniciar su bibloteca de parámetros predeterminados?", - "TMFX.preset.reset.success": "Su biblioteca de parámetros predeterminados ha sido reiniciada con éxito", - "TMFX.settings.importOverwrite.name": "Sobrescribir al importar", - "TMFX.settings.importOverwrite.hint": "Marque esta opción si quiere reemplazar los parámetros predeterminados que tengan los mismos nombres al importar", - "TMFX.template.opacity": "Opacidad de la Textura:", - "TMFX.template.fx": "Efectos Especiales:", - "TMFX.template.tint": "Efecto de Tono:", - "TMFX.settings.autoFPS.name": "Fotogramas por segundo automático", - "TMFX.settings.autoFPS.hint": "Habilite esta opción para que el navegador (o el cliente) elija automáticamente el límite de fotogramas por segundo (fps). En algunas configuraciones puede evitar que se entrecorten las animaciones (Aviso: esta opción sobrescribe el límite de fps de Foundry)", - "TMFX.settings.useMaxPadding.name": "FX en modo de relleno aditivo", - "TMFX.settings.useMaxPadding.hint": "Por defecto, los rellenos de FX son aditivos al aplicarlos a un determinado contenedor. Si se desmarca la casilla, se usa el relleno máximo", - "TMFX.settings.minPadding.name": "Relleno mínimo", - "TMFX.settings.minPadding.hint": "El relleno mínimo aplicado a un FX", - "TMFX.settings.fxPlayerPermission.name": "Modo permisivo", - "TMFX.settings.fxPlayerPermission.hint": "Si se marca esta opción, los usuarios no GM pueden añadir, modificar y borrar FX en contenedores que no son de su propiedad. El GM debe estar conectado", - "TMFX.settings.useZOrder.name": "Ordenar FX", - "TMFX.settings.useZOrder.hint": "Marque esta opción si quiere que los efectos se apliquen en el orden de su propiedad zOrder. Se aplican primero los efectos con el zOrder menor (leer la documentación)", - "TMFX.settings.disableAnimations.name": "Deshabilitar Animaciones FX", - "TMFX.settings.disableAnimations.hint": "Marque esta opción si quiere deshabilitar las animaciones FX. Requiere que se recargue Foundry", - "TMFX.settings.disableCaching.name": "Deshabilitar caché de filtros al inicio", - "TMFX.settings.disableCaching.hint": "Marque esta opción si quiere deshabilitar la caché de filtros al inicio de Foundry", - "TMFX.settings.disableVideo.name": "Deshabilitar soporte de vídeo en las plantillas", - "TMFX.settings.disableVideo.hint": "Marque esta opción si quiere deshabilitar soporte de vídeo y reescalado de texturas en las plantillas", - "TMFX.settings.autoTemplateEnabled.name": "Habilitar efectos de plantilla automáticos", - "TMFX.settings.autoTemplateEnabled.hint": "Desmarcar esta opción deshabilitará todos los efectos de plantilla automáticos. NOTA: Solo afecta a las plantillas colocadas recientemente", - "TMFX.settings.defaultTemplateOnHover.name": "Rejilla de plantilla por defecto al pasar el ratón", - "TMFX.settings.defaultTemplateOnHover.hint": "Muestra la rejilla de plantilla por defecto al pasar el ratón", - "TMFX.settings.autoTemplateSettings.button.name": "Efectos de Plantilla Automáticos", - "TMFX.settings.autoTemplateSettings.button.label": "Ajustes de Plantilla", - "TMFX.settings.autoTemplateSettings.button.hint": "En los sistemas que lo soporten, los efectos de plantilla pueden activarse en base al tipo de hechizo de área de efecto y tipo de daño, o sobrescribiendo para ciertos hechizos", - "TMFX.settings.autoTemplateSettings.tabs.general": "General", - "TMFX.settings.autoTemplateSettings.tabs.categories": "Categorías", - "TMFX.settings.autoTemplateSettings.tabs.overrides": "Sobrescribir", - "TMFX.settings.autoTemplateSettings.texture.label": "Textura (opcional):", - "TMFX.settings.autoTemplateSettings.target.label": "Objetivo:", - "TMFX.settings.autoTemplateSettings.texture.hint": "Especificar opcionalmente una textura para el filtro. Si no se especifica ninguna, se utilizará una textura apropiada", - "TMFX.settings.autoTemplateSettings.unsupported": "característica no soportada por el sistema, ¡Cualquier contribución para habilitar más sistemas es bienvenida!", - "TMFX.settings.autoTemplateSettings.overrides.introduction": "Aquí puede configurar la sobrescritura para objetos/hechizos individuales. Escriba en el Campo Objetivo el nombre del objeto/hechizo tal y como aparece en tus Objetos/Compendios y configure los ajustes que prefiera", - "TMFX.settings.autoTemplateSettings.overrides.add": "Añadir sobreescritura", - "TMFX.settings.autoTemplateSettings.dialog.title": "Ajustes de plantilla de Token Magic", - "TMFX.save": "Guardar" -} diff --git a/tokenmagic/lang/fr.json b/tokenmagic/lang/fr.json deleted file mode 100644 index 8470998..0000000 --- a/tokenmagic/lang/fr.json +++ /dev/null @@ -1,56 +0,0 @@ -{ - "TMFX.TokenMagic": "TokenMagic", - "TMFX.preset.add.success": "L'effet a été ajouté avec succès à la bibliothèque de prédéfinitions.", - "TMFX.preset.add.permission.failure": "Vous n'êtes pas autorisé à ajouter des effets dans la bibliothèque de prédéfinitions.", - "TMFX.preset.add.params.failure": "L'effet n'a pas pu être ajouté à la bibliothèque de prédéfinitions. Les paramètres sont incorrects.", - "TMFX.preset.add.duplicate.failure": "L'effet n'a pas pu être ajouté à la bibliothèque de prédéfinitions. Un effet avec le même nom existe déjà.", - "TMFX.preset.delete.success": "L'effet a été supprimé avec succès de la bibliothèque de prédéfinitions.", - "TMFX.preset.delete.permission.failure": "Vous n'êtes pas autorisé à supprimer des effets dans la bibliothèque de prédéfinitions.", - "TMFX.preset.delete.params.failure": "La suppression a échoué : le paramètre \"name\" doit être une chaîne de caractères.", - "TMFX.preset.delete.notfound.failure": "L'effet à supprimer n'existe pas dans la bibliothèque de prédéfinitions.", - "TMFX.preset.delete.empty.failure": "Echec : la bibliothèque de prédéfinitions est déjà vide !", - "TMFX.preset.import.format.failure": "Échec de l'importation. Objet JSON invalide.", - "TMFX.preset.import.success": "L'importation s'est terminée avec succès.", - "TMFX.preset.import.failure": "L'importation n'a pas pu aboutir.", - "TMFX.preset.reset.message": "Voulez-vous vraiment réinitialiser votre bibliothèque de prédéfinitions ?", - "TMFX.preset.reset.success": "Votre bibliothèque de prédéfinitions a été réinitialisée avec succès.", - "TMFX.template.opacity": "Opacité de la Texture:", - "TMFX.template.fx": "Effets Spéciaux:", - "TMFX.template.tint": "Teinte de l'Effet:", - "TMFX.settings.disableCaching.name": "Désactiver la mise en cache des filtres", - "TMFX.settings.disableCaching.hint": "Cochez cette option pour désactiver la mise en cache des filtres au démarrage de Foundry.", - "TMFX.settings.disableVideo.name": "Désactiver la prise en charge des vidéos", - "TMFX.settings.disableVideo.hint": "Cochez cette option si vous souhaitez désactiver la prise en charge des vidéos et le recadrage automatique des textures dans les templates.", - "TMFX.settings.autoTemplateEnabled.name": "Activation automatique des effets", - "TMFX.settings.autoTemplateEnabled.hint": "Décocher cette option désactivera tous les effets automatiques sur les templates. REMARQUE: affecte uniquement les templates nouvellement placés.", - "TMFX.settings.defaultTemplateOnHover.name": "Grille sur demande", - "TMFX.settings.defaultTemplateOnHover.hint": "Afficher uniquement la grille des templates en passant le curseur de la souris sur le sélecteur (dans la couche des templates.)", - "TMFX.settings.autoFPS.name": "Framerate automatique", - "TMFX.settings.autoFPS.hint": "Cochez cette option pour laisser le navigateur (ou l'application) décider de la limite du framerate. Peut supprimer les saccades sur certaines configurations. (Attention : cette option surcharge le paramètre de Foundry)", - "TMFX.settings.autoTemplateSettings.button.name": "Effets automatiques des templates", - "TMFX.settings.autoTemplateSettings.button.label": "Configuration des templates", - "TMFX.settings.autoTemplateSettings.button.hint": "Pour les systèmes de jeu supportés, les effets de template peuvent être activés en tenant compte du type de zone et de dégâts, ou en surchargeant des sorts spécifiques.", - "TMFX.settings.autoTemplateSettings.tabs.general": "Général", - "TMFX.settings.autoTemplateSettings.tabs.categories": "Catégories", - "TMFX.settings.autoTemplateSettings.tabs.overrides": "Surcharges", - "TMFX.settings.autoTemplateSettings.target.label": "Cible:", - "TMFX.settings.autoTemplateSettings.texture.label": "Texture (optionnelle):", - "TMFX.settings.autoTemplateSettings.texture.hint": "Vous pouvez choisir une texture spécifique. Dans le cas contraire, une texture appropriée au filtre sera sélectionnée.", - "TMFX.settings.autoTemplateSettings.unsupported": "Cette fonctionnalité n'est pour le moment pas prise en charge pour ce système de jeu, les contributions pour ajouter de nouveaux systèmes sont plus que bienvenues !", - "TMFX.settings.autoTemplateSettings.overrides.introduction": "Vous pouvez configurer des surcharges pour des sorts et des items spécifiques. Renseignez dans le champ Cible le nom du sort ou de l'item tel qu'il apparaît dans le compendium et configurez vos options personnalisées.", - "TMFX.settings.autoTemplateSettings.overrides.add": "Ajouter une surcharge", - "TMFX.settings.autoTemplateSettings.dialog.title": "Configuration des Templates Token Magic", - "TMFX.save": "Sauvegarder", - "TMFX.settings.useZOrder.name": "Ordonner les effets", - "TMFX.settings.useZOrder.hint": "Cochez cette option pour appliquer les effets dans l'ordre de leur propriété zOrder. Les effets avec le plus petit zOrder sont appliqués en premier. Voir la documentation.", - "TMFX.settings.disableAnimations.name": "Désactiver l'animation des effets", - "TMFX.settings.disableAnimations.hint": "Cochez cette option pour désactiver l'animation des effets. Nécessite un rechargement de Foundry.", - "TMFX.settings.importOverwrite.name": "Écraser lors d'une importation", - "TMFX.settings.importOverwrite.hint": "Cochez cette option si vous souhaitez écraser les prédéfinitions avec le même nom pendant une importation.", - "TMFX.settings.useMaxPadding.name": "Effet en mode padding additif", - "TMFX.settings.useMaxPadding.hint": "Par défaut, les effets additionnent leur padding en s'appliquant sur un objet donné. Si la case est décochée, c'est le padding maximum qui est utilisé.", - "TMFX.settings.minPadding.name": "Padding minimum", - "TMFX.settings.minPadding.hint": "Padding minimum appliqué aux effets.", - "TMFX.settings.fxPlayerPermission.name": "Mode permissif", - "TMFX.settings.fxPlayerPermission.hint": "Si cette option est cochée, les joueurs non-MJ peuvent ajouter, modifier et supprimer des effets sur des jetons qu'ils ne possèdent pas. Un MJ doit être connecté." -} diff --git a/tokenmagic/lang/ja.json b/tokenmagic/lang/ja.json deleted file mode 100644 index 8013ba3..0000000 --- a/tokenmagic/lang/ja.json +++ /dev/null @@ -1,58 +0,0 @@ -{ - "TMFX.TokenMagic": "トークン・マジック", - "TMFX.preset.add.success": "FXは無事にプリセットライブラリに追加されました。", - "TMFX.preset.add.permission.failure": "プリセットライブラリにFXを追加することはできません。", - "TMFX.preset.add.params.failure": "FXをプリセットライブラリに追加できませんでした。パラメータが正しくありません。", - "TMFX.preset.add.duplicate.failure": "FXをプリセットライブラリに追加できませんでした。同じ名前のFXが既に存在します。", - "TMFX.preset.delete.success": "FXはプリセットライブラリから正常に削除されました。", - "TMFX.preset.delete.permission.failure": "プリセットライブラリ内のFXを削除することはできません。", - "TMFX.preset.delete.params.failure": "削除失敗:\"name\" パラメータは文字列でなければなりません。", - "TMFX.preset.delete.notfound.failure": "削除するFXがプリセットライブラリに存在しません。", - "TMFX.preset.delete.empty.failure": "失敗:プリセットライブラリが既に空です!", - "TMFX.preset.import.format.failure": "インポートを完了できませんでした。無効なフォーマットです。", - "TMFX.preset.import.success": "無事にFXのインポートが完了しました。", - "TMFX.preset.import.failure": "インポートが完了できませんでした。", - "TMFX.preset.reset.message": "本当にプリセットのライブラリをリセットしますか?", - "TMFX.preset.reset.success": "プリセットライブラリが正常にリセットされました。", - "TMFX.settings.importOverwrite.name": "インポート時に上書きする", - "TMFX.settings.importOverwrite.hint": "インポート中にプリセットを同じ名前で置き換える場合は、このオプションをオンにします。", - "TMFX.template.opacity": "テクスチャの不透明度:", - "TMFX.template.fx": "特殊効果:", - "TMFX.template.tint": "効果の色合い:", - "TMFX.settings.autoFPS.name": "自動フレームレート", - "TMFX.settings.autoFPS.hint": "有効にすると、ブラウザ(またはアプリケーション)がフレームレートを制御するようになります。環境によってはアニメーションのジャギーが抑制されるかもしれません(警告: このオプションはFoundryのフレームレート制限を上書きします)。", - "TMFX.settings.useMaxPadding.name": "FXの加算パディングモード", - "TMFX.settings.useMaxPadding.hint": "デフォルトでは、FXのパディングは指定した領域に適用するときに加算が行われます。このチェックボックスを無効にすると、加算を行わず最大のパディングを使用するようになります。", - "TMFX.settings.minPadding.name": "最少パディング", - "TMFX.settings.minPadding.hint": "すべてのFXに適用される最小パディング値です。", - "TMFX.settings.fxPlayerPermission.name": "許可モード", - "TMFX.settings.fxPlayerPermission.hint": "このオプションを有効にすると、GMではないプレイヤーが自身が所有していない領域にFXを追加/修正/削除できるようになります。GMが接続している必要があります。", - "TMFX.settings.useZOrder.name": "FXのオーダー順", - "TMFX.settings.useZOrder.hint": "エフェクトをzOrderプロパティ順に適用したい場合は有効にしてください。zOrderが最も小さいエフェクトが最初に適用されます(詳しくはドキュメントを参照してください) 。", - "TMFX.settings.disableAnimations.name": "FXアニメーションを無効にする", - "TMFX.settings.disableAnimations.hint": "FXアニメーションを無効にしたい場合は、このオプションを有効にします。FVTTのリロードが必要です。", - "TMFX.settings.disableCaching.name": "起動時にフィルタのキャッシュを無効にする", - "TMFX.settings.disableCaching.hint": "FVTT起動時にフィルタのキャッシングを無効にしたい場合、このオプションを有効にします。", - "TMFX.settings.disableVideo.name": "テンプレートで動画サポートを無効にする", - "TMFX.settings.disableVideo.hint": "テンプレート内の動画サポートとテクスチャの自動サイズ変更を無効にする場合は、このオプションを有効にします。", - "TMFX.settings.autoTemplateEnabled.name": "自動テンプレート効果を有効にする", - "TMFX.settings.autoTemplateEnabled.hint": "無効にすると、すべての自動テンプレート効果がオフになります(注:影響するのは新しく配置されたテンプレートにのみです)。", - "TMFX.settings.defaultTemplateOnHover.name": "ホバー時の標準テンプレートグリッド", - "TMFX.settings.defaultTemplateOnHover.hint": "カーソルを合わせたときのみ、標準のテンプレートグリッドを表示します。", - "TMFX.settings.autohideTemplateElements.name": "テンプレート要素を自動的に隠す", - "TMFX.settings.autohideTemplateElements.hint": "必須でないテンプレート要素は、テンプレートレイヤーでカーソルを合わせたときにのみ表示されるようになります。", - "TMFX.settings.autoTemplateSettings.button.name": "自動テンプレート効果", - "TMFX.settings.autoTemplateSettings.button.label": "テンプレート設定", - "TMFX.settings.autoTemplateSettings.button.hint": "サポートされたゲームシステムでは、呪文の効果範囲とダメージ種別に基づき、テンプレートにエフェクトを適用できます。もしくは特定の呪文などを上書きする形でカスタマイズも可能です。", - "TMFX.settings.autoTemplateSettings.tabs.general": "一般", - "TMFX.settings.autoTemplateSettings.tabs.categories": "カテゴリー", - "TMFX.settings.autoTemplateSettings.tabs.overrides": "上書き", - "TMFX.settings.autoTemplateSettings.texture.label": "テクスチャ(オプション):", - "TMFX.settings.autoTemplateSettings.target.label": "ターゲット:", - "TMFX.settings.autoTemplateSettings.texture.hint": "オプションでフィルターのテクスチャを指定できますが、 指定しない場合は適切なテクスチャが使われます。", - "TMFX.settings.autoTemplateSettings.unsupported": "この機能は現在、このゲームシステムではサポートされていません。より多くのシステムを可能にするための貢献を歓迎します!", - "TMFX.settings.autoTemplateSettings.overrides.introduction": "ここでは、個々のアイテム/スペルの設定を上書きできます。アイテム一覧/辞典に表示されるアイテム/呪文の名前を「ターゲット」フィールドに入力して、お好みの設定を行います。", - "TMFX.settings.autoTemplateSettings.overrides.add": "上書きの追加", - "TMFX.settings.autoTemplateSettings.dialog.title": "トークン・マジック テンプレート設定", - "TMFX.save": "セーヴ" -} diff --git a/tokenmagic/lang/ko.json b/tokenmagic/lang/ko.json deleted file mode 100644 index ac66de4..0000000 --- a/tokenmagic/lang/ko.json +++ /dev/null @@ -1,54 +0,0 @@ -{ - "TMFX.TokenMagic": "TokenMagic", - "TMFX.preset.add.success": "FX가 프리셋 라이브러리에 성공적으로 추가되었습니다.", - "TMFX.preset.add.permission.failure": "FX를 프리셋 라이브러리에 추가하지 못했습니다.", - "TMFX.preset.add.params.failure": "FX를 프리셋 라이브러리에 추가하지 못했습니다. 패러미터가 잘못 되었습니다.", - "TMFX.preset.add.duplicate.failure": "FX를 프리셋 라이브러리에 추가하지 못했습니다. 같은 이름의 FX가 이미 존재합니다.", - "TMFX.preset.delete.success": "FX가 프리셋 라이브러리에서 성공적으로 제거되었습니다.", - "TMFX.preset.delete.permission.failure": "프리셋 라이브러리에서 FX를 삭제할 수 없습니다.", - "TMFX.preset.delete.params.failure": "삭제 실패 : \"name\" 패러미터는 문자열이어야 합니다.", - "TMFX.preset.delete.notfound.failure": "삭제할 FX가 프리셋 라이브러리에 존재하지 않습니다.", - "TMFX.preset.delete.empty.failure": "실패 : 프리셋 라이브러리가 이미 비어있습니다!", - "TMFX.preset.import.format.failure": "가져오기를 완료할 수 없습니다. 잘못된 형식입니다.", - "TMFX.preset.import.success": "FX 가져오기가 성공적으로 완료되었습니다.", - "TMFX.preset.import.failure": "가져오기를 완료할 수 없습니다.", - "TMFX.preset.reset.message": "프리셋 라이브러리를 재설정하시겠습니까?", - "TMFX.preset.reset.success": "프리셋 라이브러리가 성공적으로 재설정 되었습니다.", - "TMFX.settings.importOverwrite.name": "가져오기시 덮어쓰기", - "TMFX.settings.importOverwrite.hint": "가져오기시 프리셋을 동일한 이름으로 대체하려면 이 옵션을 선택하십시오.", - "TMFX.template.opacity": "텍스처 불투명도:", - "TMFX.template.fx": "특수 효과:", - "TMFX.template.tint": "효과 색조:", - "TMFX.settings.useMaxPadding.name": "부가적 패딩 모드 FX", - "TMFX.settings.useMaxPadding.hint": "기본적으로 FX 패딩은 지정된 장소에 적용될 때의 부가적 요소이다. 이 체크박스를 선택하지 않으면 최대치의 패딩이 사용된다.", - "TMFX.settings.minPadding.name": "패딩 최소화", - "TMFX.settings.minPadding.hint": "FX에 최소한의 패딩이 적용된다.", - "TMFX.settings.fxPlayerPermission.name": "허가 모드", - "TMFX.settings.fxPlayerPermission.hint": "이 옵션을 선택하면 GM 외 플레이어는 자신이 소유하고 있지 않은 지정성 FX를 추가 및 수정할 수 있다. GM이 반드시 접속해야 한다.", - "TMFX.settings.useZOrder.name": "FX 순서", - "TMFX.settings.useZOrder.hint": "zOrder 속성의 순서대로 효과를 적용하려면 이 옵션을 선택한다. zOrder는 가장 작은 효과를 먼저 적용한다.(문서 참조)", - "TMFX.settings.disableAnimations.name": "FX 애니메이션 비활성화", - "TMFX.settings.disableAnimations.hint": "FX 애니메이션을 비활성화하려면 이 옵션을 선택한다. Foundry 리로드가 필요하다.", - "TMFX.settings.disableCaching.name": "시작시 필터 캐싱 비활성화", - "TMFX.settings.disableCaching.hint": "Foundry 시작시 필터 캐싱을 비활성화하려면 이 옵션을 선택한다.", - "TMFX.settings.disableVideo.name": "템플릿에서 비디오 지원 비활성화", - "TMFX.settings.disableVideo.hint": "템플릿에서 비디오 지원 및 텍스처 자동 크기 재조정을 비활성화 하려면 이 옵션을 선택한다.", - "TMFX.settings.autoTemplateEnabled.name": "자동 템플릿 효과 활성화", - "TMFX.settings.autoTemplateEnabled.hint": "이 옵션을 비활성화하면 모든 자동 템플릿 효과가 비활성화된다. 참고: 새로 배치된 템플릿에만 유효하다.", - "TMFX.settings.defaultTemplateOnHover.name": "호버시 기본 템플릿 그리드", - "TMFX.settings.defaultTemplateOnHover.hint": "템플릿 레이어에 호버링 할 동안에만 기본 템플릿 그리드를 표시한다.", - "TMFX.settings.autoTemplateSettings.button.name": "자동적 템플릿 효과", - "TMFX.settings.autoTemplateSettings.button.label": "템플릿 세팅", - "TMFX.settings.autoTemplateSettings.button.hint": "지원되는 게임 시스템에서 주문 영역 유형과 피해 유형에 따라 템플릿 효과를 활성화하거나 특정 주문에 대한 덮어쓰기를 할 수 있다.", - "TMFX.settings.autoTemplateSettings.tabs.general": "보통", - "TMFX.settings.autoTemplateSettings.tabs.categories": "카테고리", - "TMFX.settings.autoTemplateSettings.tabs.overrides": "덮어쓰기", - "TMFX.settings.autoTemplateSettings.texture.label": "텍스처 (옵션):", - "TMFX.settings.autoTemplateSettings.target.label": "대상:", - "TMFX.settings.autoTemplateSettings.texture.hint": "필터에 따른 텍스처를 선택 지정하십시오. 텍스처가 지정되지 않은 경우 적절한 텍스처가 사용됩니다.", - "TMFX.settings.autoTemplateSettings.unsupported": "이 기능은 현재 게임 시스템에 지원되지 않으며, 더 많은 시스템을 활성화하기 위한 기여는 언제든지 환영입니다!", - "TMFX.settings.autoTemplateSettings.overrides.introduction": "개별 아이템/주문에 대한 재설정을 여기서 할 수 있습니다. 대상 필드에 아이템/컴펜디엄에 표시되는 아이템/주문의 이름을 입력하고 원하는 설정을 구성하십시오.", - "TMFX.settings.autoTemplateSettings.overrides.add": "덮어쓰기 추가", - "TMFX.settings.autoTemplateSettings.dialog.title": "Token Magic 템플릿 설정", - "TMFX.save": "저장" -} diff --git a/tokenmagic/lang/pt-BR.json b/tokenmagic/lang/pt-BR.json deleted file mode 100644 index 30faa17..0000000 --- a/tokenmagic/lang/pt-BR.json +++ /dev/null @@ -1,52 +0,0 @@ -{ - "TMFX.TokenMagic": "TokenMagic", - "TMFX.preset.add.success": "O efeito foi adicionado com sucesso na biblioteca.", - "TMFX.preset.add.permission.failure": "Você não possui permissão para adicionar efeitos na biblioteca.", - "TMFX.preset.add.params.failure": "O efeito não pode ser adicionado na biblioteca. Os parâmetros estão incorretos.", - "TMFX.preset.add.duplicate.failure": "O efeito não pode ser adicionado na biblioteca. Um efeito com mesmo nome já existe.", - "TMFX.preset.delete.success": "O efeito foi removido com sucesso da sua biblioteca.", - "TMFX.preset.delete.permission.failure": "Você não possui permissão para remover efeitos da biblioteca.", - "TMFX.preset.delete.params.failure": "Remoção falhou : o parâmetro \"name\" deve ser um texto.", - "TMFX.preset.delete.notfound.failure": "O efeito a ser removido não existe na biblioteca.", - "TMFX.preset.delete.empty.failure": "Falha : a biblioteca já está vazia !", - "TMFX.preset.import.format.failure": "A importação não pode ser concluída. Formato inválido.", - "TMFX.preset.import.success": "A importação do efeito foi concluída com sucesso.", - "TMFX.preset.import.failure": "A importação não pode ser concluída.", - "TMFX.preset.reset.message": "Você tem certeza que deseja resetar sua biblioteca de efeitos?", - "TMFX.preset.reset.success": "Sua biblioteca foi resetada com sucesso.", - "TMFX.settings.importOverwrite.name": "Sobrescrever na importação", - "TMFX.settings.importOverwrite.hint": "Marque esta opção se deseja sobrescrever efeitos com mesmo nome durante a importação.", - "TMFX.template.opacity": "Opacidade da textura:", - "TMFX.template.fx": "Efeitos Especiais:", - "TMFX.template.tint": "Efeito Matiz:", - "TMFX.settings.useMaxPadding.name": "Efeito em modo de preenchimento aditivo", - "TMFX.settings.useMaxPadding.hint": "Por padrão, os efeitos de preenchimento são aditivos quando são aplicados em um determinado objeto na tela. Se a caixa estiver desmarcada, o preenchimento máximo é usado.", - "TMFX.settings.minPadding.name": "Preenchimento mínimo", - "TMFX.settings.minPadding.hint": "O preenchimento mínimo é aplicado em um efeito.", - "TMFX.settings.fxPlayerPermission.name": "Modo permissivo", - "TMFX.settings.fxPlayerPermission.hint": "Se um objeto estiver selecionado, jogadores não-GM pode adicionar, modificar e deletar efeitos em objetos na tela que ele não controla. Um GM deve estar conectado.", - "TMFX.settings.useZOrder.name": "Ordem do efeito", - "TMFX.settings.useZOrder.hint": "Marque esta opção se deseja que os efeitos sejam aplicados na ordem de sua propriedade zOrder. Efeitos com o menor zOrder são aplicados primeiro. (Veja a documentação)", - "TMFX.settings.disableAnimations.name": "Desativar Animação dos Efeitos", - "TMFX.settings.disableAnimations.hint": "Marque esta opção se deseja desativar as animação dos efeitos. Requer que o foundry seja recarregado.", - "TMFX.settings.disableCaching.name": "Desabilitar pré-carregamento de filtros ao iniciar", - "TMFX.settings.disableCaching.hint": "Marque esta opção se deseja desabilitar o pré-carregamento de filtros quando o foundry é iniciado.", - "TMFX.settings.autoTemplateEnabled.name": "Habilitar automaticamente efeitos no modelo", - "TMFX.settings.autoTemplateEnabled.hint": "Desativar esta opção irá desativar todos efeitos automáticos nos modelos. NOTA: Afeta somente novos modelos.", - "TMFX.settings.defaultTemplateOnHover.name": "Grid do modelo ao passar o mouse", - "TMFX.settings.defaultTemplateOnHover.hint": "Mostrar o grid padrão do modelo somente quando passar o mouse estando na camada de modelos.", - "TMFX.settings.autoTemplateSettings.button.name": "Efeitos nos Modelos Automaticamente", - "TMFX.settings.autoTemplateSettings.button.label": "Configurações dos Modelos", - "TMFX.settings.autoTemplateSettings.button.hint": "Em sistemas de jogo que possuem suporte, os efeitos nos modelos podem ser ativados com base no tipo de área e de dano da magia, ou com sobrescrição para magias específicas.", - "TMFX.settings.autoTemplateSettings.tabs.general": "Geral", - "TMFX.settings.autoTemplateSettings.tabs.categories": "Categorias", - "TMFX.settings.autoTemplateSettings.tabs.overrides": "Sobrescrição", - "TMFX.settings.autoTemplateSettings.texture.label": "Textura (opcional):", - "TMFX.settings.autoTemplateSettings.target.label": "Alvo:", - "TMFX.settings.autoTemplateSettings.texture.hint": "Opcionalmente especifique uma textura para o filtro, se nenhuma for especificada, uma textura apropriada será utilizada.", - "TMFX.settings.autoTemplateSettings.unsupported": "Esta opção atualmente não possui suporte para este sistema de jogo, contribuições para habilidar mais sistemas são mais que bem vindas!", - "TMFX.settings.autoTemplateSettings.overrides.introduction": "Você pode configurar sobrescrição para items/magias individualmente aqui. Informe o nome do item/magia da mesma forma que ele aparece em seus Items/Compendiums no campo Alvo, e use suas configurações preferidas.", - "TMFX.settings.autoTemplateSettings.overrides.add": "Adicionar Sobrescrição", - "TMFX.settings.autoTemplateSettings.dialog.title": "Configurações de Modelo Token Magic", - "TMFX.save": "Salvar" -} diff --git a/tokenmagic/lang/ru.json b/tokenmagic/lang/ru.json deleted file mode 100644 index ab68d5d..0000000 --- a/tokenmagic/lang/ru.json +++ /dev/null @@ -1,58 +0,0 @@ -{ - "TMFX.TokenMagic": "TokenMagic", - "TMFX.preset.add.success": "FX был успешно добавлен в библиотеку шаблонов.", - "TMFX.preset.add.permission.failure": "У вас нет прав добавлять FX в библиотеку шаблонов.", - "TMFX.preset.add.params.failure": "FX не может быть добавлен в библиотеку шаблонов. Параметры неверны.", - "TMFX.preset.add.duplicate.failure": "FX не может быть добавлен в библиотеку шаблонов. FX с тем же именем уже существует.", - "TMFX.preset.delete.success": "FX был успешно удален из библиотеки шаблонов.", - "TMFX.preset.delete.permission.failure": "У вас нет прав на удаление FX из библиотеки шаблонов.", - "TMFX.preset.delete.params.failure": "Удаление не удалось : \"name\" параметр должен быть строковым.", - "TMFX.preset.delete.notfound.failure": "FX не существует в библиотеке шаблонов.", - "TMFX.preset.delete.empty.failure": "Ошибка : библиотека шаблонов уже пуста !", - "TMFX.preset.import.format.failure": "Импорт не может быть завершен. Неверный формат.", - "TMFX.preset.import.success": "FX импорт был завершен успешно.", - "TMFX.preset.import.failure": "Импорт не может быть завершен.", - "TMFX.preset.reset.message": "Вы уверены, что хотите сбросить вашу библиотеку шаблонов?", - "TMFX.preset.reset.success": "Настройки библиотеки шаблонов успешно сброшены.", - "TMFX.settings.importOverwrite.name": "Перезапись при импорте", - "TMFX.settings.importOverwrite.hint": "Выберите эту опцию если хотите заменить шаблоны с тем же именем при импорте.", - "TMFX.template.opacity": "Прозрачность:", - "TMFX.template.fx": "Спец эффекты:", - "TMFX.template.tint": "Цвет эффекта:", - "TMFX.settings.autoFPS.name": "Авто фреймрейт", - "TMFX.settings.autoFPS.hint": "Выберите эту опцию чтобы браузер (или приложение) выбрало лимит фреймрейта. Может исправить ошибки анимации. (Внимание : эта опция перезапишет Foundry framerate limit)", - "TMFX.settings.useMaxPadding.name": "Запуск FX в режиме экстра-отступ ", - "TMFX.settings.useMaxPadding.hint": "По умолчанию, FX добавляет отступы, когда применяется наложенной области. Если опция не выбрана - применяются максимальные отступы.", - "TMFX.settings.minPadding.name": "Минимальный отступ", - "TMFX.settings.minPadding.hint": "Минимальный отступ применимый к FX.", - "TMFX.settings.fxPlayerPermission.name": "Доверительный режим", - "TMFX.settings.fxPlayerPermission.hint": "Если эта опция выбрана, любой игрок может добавлять, модифицировать и удалять FX, которыми он не владеет. ГМ должен быть в игре.", - "TMFX.settings.useZOrder.name": "Упорядочить FX", - "TMFX.settings.useZOrder.hint": "Выберите эту опцию если хотите, чтобы эффекты применялись на основании их zOrder значения. Эффекты с наименьшим zOrder будут применены в первую очередь. (См. документацию)", - "TMFX.settings.disableAnimations.name": "Отключить FX анимации", - "TMFX.settings.disableAnimations.hint": "Выберите эту опцию если вы хотите отключить FX аминации. Требуется перезагрузка фаундри.", - "TMFX.settings.disableCaching.name": "Отключить кеширование фильтров при загрузке", - "TMFX.settings.disableCaching.hint": "Выберите эту опцию если хотите отключить кеширование фильтров при старте фаундри.", - "TMFX.settings.disableVideo.name": "Отключить поддержку видео в шаблонах", - "TMFX.settings.disableVideo.hint": "Выберите эту опцию если хотите отключить поддержку видео и авторесайз текстур в шаблонах.", - "TMFX.settings.autoTemplateEnabled.name": "Использовать авто шаблоны", - "TMFX.settings.autoTemplateEnabled.hint": "Отключение этой опции отключит все авто шаблонов. ВАЖНО: действует только на новые шаблоны.", - "TMFX.settings.defaultTemplateOnHover.name": "Стандартный вид шаблонов при наведении", - "TMFX.settings.defaultTemplateOnHover.hint": "Отображать стандартную сетку шаблонов только при наведении.", - "TMFX.settings.autohideTemplateElements.name": "Автоматически прятать элементы шаблонов", - "TMFX.settings.autohideTemplateElements.hint": "Отображать элементы шаблонов только при наведении на слой шаблона.", - "TMFX.settings.autoTemplateSettings.button.name": "Автоматические шаблоны эффектов", - "TMFX.settings.autoTemplateSettings.button.label": "Настройки шаблонов", - "TMFX.settings.autoTemplateSettings.button.hint": "В поддерживаемых игровых системах шаблоны эффектов могут быть включены для типа области заклинания, типа урона или же для конкретного заклинания.", - "TMFX.settings.autoTemplateSettings.tabs.general": "Общие", - "TMFX.settings.autoTemplateSettings.tabs.categories": "Категории", - "TMFX.settings.autoTemplateSettings.tabs.overrides": "Переопределения", - "TMFX.settings.autoTemplateSettings.texture.label": "Текструра (опц):", - "TMFX.settings.autoTemplateSettings.target.label": "Цель:", - "TMFX.settings.autoTemplateSettings.texture.hint": "Опционально указать текстуру для фильтра. Если текстура не указана для фильтра - будет использована указанная.", - "TMFX.settings.autoTemplateSettings.unsupported": "Эта функция не поддерживается данной игровой системой. Вклад в развитие проекта приветствуется!", - "TMFX.settings.autoTemplateSettings.overrides.introduction": "Вы можете настроить переопределения для личных заклинаний/предметов. Добавьте имя заклинания/предмета в поле Цель (также как оно отображается в компендиуме) и настройте по своему вкусу.", - "TMFX.settings.autoTemplateSettings.overrides.add": "Добавить переопределение", - "TMFX.settings.autoTemplateSettings.dialog.title": "Настройки шаблонов Token Magic", - "TMFX.save": "Сохранить" -} diff --git a/tokenmagic/lang/zh-tw.json b/tokenmagic/lang/zh-tw.json deleted file mode 100644 index 749cafc..0000000 --- a/tokenmagic/lang/zh-tw.json +++ /dev/null @@ -1,58 +0,0 @@ -{ - "TMFX.TokenMagic": "棋子魔法", - "TMFX.preset.add.success": "效果(FX)已成功添加到預設集中.", - "TMFX.preset.add.permission.failure": "你不被允許將效果(FX)添加到預設集。", - "TMFX.preset.add.params.failure": "無法將效果(FX)添加到預設集中。 參數錯誤。", - "TMFX.preset.add.duplicate.failure": "無法將效果(FX)添加到預設集中。 已經存在擁有相同名稱的效果(FX)。", - "TMFX.preset.delete.success": "效果(FX)已成功從預設集中刪除.", - "TMFX.preset.delete.permission.failure": "你不被允許刪除預設集中的效果(FX)。", - "TMFX.preset.delete.params.failure": "刪除失敗:\"name\"參數必須為字符串。", - "TMFX.preset.delete.notfound.failure": "預設集中不存在要刪除的效果(FX)。", - "TMFX.preset.delete.empty.failure": "失敗:預設集已經為空!", - "TMFX.preset.import.format.failure": "滙入無法完成。格式無效。", - "TMFX.preset.import.success": "效果(FX)滙入已成功完成。.", - "TMFX.preset.import.failure": "無法完成滙入。.", - "TMFX.preset.reset.message": "您確定要重置你的預設集嗎?", - "TMFX.preset.reset.success": "您的預設集已成功重置。", - "TMFX.settings.importOverwrite.name": "滙入時覆蓋", - "TMFX.settings.importOverwrite.hint": "如果要在滙入過程中用相同的名稱替換預設,請勾選此項。", - "TMFX.template.opacity": "紋理不透明度:", - "TMFX.template.fx": "特殊效果:", - "TMFX.template.tint": "效果色調:", - "TMFX.settings.autoFPS.name": "自動FPS", - "TMFX.settings.autoFPS.hint": "勾選此項以使瀏覽器(或應用程序)進行FPS限制。在某些配置上可能會抑制動畫的晃動。(警告:此選項將覆蓋Foundry的FPS限制)", - "TMFX.settings.useMaxPadding.name": "附加填充模式下的效果(FX)", - "TMFX.settings.useMaxPadding.hint": "默認情況下,在可放置對像上應用效果(FX)添加填充。如果未勾選此項,則使用最大填充。", - "TMFX.settings.minPadding.name": "最小填充", - "TMFX.settings.minPadding.hint": "在效果(FX)應用 最小填充。", - "TMFX.settings.fxPlayerPermission.name": "許可模式", - "TMFX.settings.fxPlayerPermission.hint": "如果勾選此項,則非GM玩家可以在他們不擁有的可放置的位置上添加,修改和刪除效果(FX)。GM必須同時在線。", - "TMFX.settings.useZOrder.name": "效果(FX)次序", - "TMFX.settings.useZOrder.hint": "如果要按其zOrder屬性的順序應用效果,請勾選此項。具有最細zOrder的效果將首先應用。(請參閱文件)", - "TMFX.settings.disableAnimations.name": "禁用效果(FX)動畫", - "TMFX.settings.disableAnimations.hint": "如果要禁用效果(FX)動畫,請勾選此項。需要重新加載FoundryVTT。", - "TMFX.settings.disableCaching.name": "在啟動時,禁用Filter緩存", - "TMFX.settings.disableCaching.hint": "如果要在FoundryVTT啟動時禁用Filter緩存,請勾選此項。", - "TMFX.settings.disableVideo.name": "在模板中禁用視頻支持”", - "TMFX.settings.disableVideo.hint": "如果要在模板中禁用視頻支持和紋理自動調整大小,請勾選此項。", - "TMFX.settings.autoTemplateEnabled.name": "啟用自動模板效果", - "TMFX.settings.autoTemplateEnabled.hint": "禁用此選項將禁用所有自動模板效果。注意:僅影響新放置的模板。", - "TMFX.settings.defaultTemplateOnHover.name": "懸停時的默認模板網格", - "TMFX.settings.defaultTemplateOnHover.hint": "僅在懸停時顯示默認模板網格。", - "TMFX.settings.autohideTemplateElements.name": "自動隱藏模板元素", - "TMFX.settings.autohideTemplateElements.hint": "僅當在模板層上懸停時才顯示非必要模板元素。", - "TMFX.settings.autoTemplateSettings.button.name": "自動模板效果", - "TMFX.settings.autoTemplateSettings.button.label": "模板設定", - "TMFX.settings.autoTemplateSettings.button.hint": "在受支持的遊戲系統上,可以根據咒語區域和傷害類型或特定咒語的替代來啟用模板效果。", - "TMFX.settings.autoTemplateSettings.tabs.general": "一般", - "TMFX.settings.autoTemplateSettings.tabs.categories": "類別", - "TMFX.settings.autoTemplateSettings.tabs.overrides": "替代", - "TMFX.settings.autoTemplateSettings.texture.label": "紋理(可選):", - "TMFX.settings.autoTemplateSettings.target.label": "目標:", - "TMFX.settings.autoTemplateSettings.texture.hint": "可選地為Filter指定一種紋理,如果未指定,則將使用適當的紋理。", - "TMFX.settings.autoTemplateSettings.unsupported": "此遊戲系統目前不支持此功能,非常歡迎為啟用更多系統作出貢獻!", - "TMFX.settings.autoTemplateSettings.overrides.introduction": "您可以在此處設定個別道具/咒語的替代。在「目標」欄的「項目/合集」中輸入該道具/咒語的名稱,然後進行設定。", - "TMFX.settings.autoTemplateSettings.overrides.add": "添加替代", - "TMFX.settings.autoTemplateSettings.dialog.title": "棋子魔法模板設定", - "TMFX.save": "儲存" -} diff --git a/tokenmagic/libs/filters/pixi-filters.js b/tokenmagic/libs/filters/pixi-filters.js deleted file mode 100644 index 11d1782..0000000 --- a/tokenmagic/libs/filters/pixi-filters.js +++ /dev/null @@ -1,1839 +0,0 @@ -/*! - * pixi-filters - v5.1.1 - * Compiled Wed, 11 Jan 2023 23:08:23 UTC - * - * pixi-filters is licensed under the MIT License. - * http://www.opensource.org/licenses/mit-license - */var __filters=function(n,o,H,b){"use strict";var J=`attribute vec2 aVertexPosition; -attribute vec2 aTextureCoord; - -uniform mat3 projectionMatrix; - -varying vec2 vTextureCoord; - -void main(void) -{ - gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0); - vTextureCoord = aTextureCoord; -}`,ee=`varying vec2 vTextureCoord; -uniform sampler2D uSampler; - -uniform float gamma; -uniform float contrast; -uniform float saturation; -uniform float brightness; -uniform float red; -uniform float green; -uniform float blue; -uniform float alpha; - -void main(void) -{ - vec4 c = texture2D(uSampler, vTextureCoord); - - if (c.a > 0.0) { - c.rgb /= c.a; - - vec3 rgb = pow(c.rgb, vec3(1. / gamma)); - rgb = mix(vec3(.5), mix(vec3(dot(vec3(.2125, .7154, .0721), rgb)), rgb, saturation), contrast); - rgb.r *= red; - rgb.g *= green; - rgb.b *= blue; - c.rgb = rgb * brightness; - - c.rgb *= c.a; - } - - gl_FragColor = c * alpha; -} -`;class te extends o.Filter{constructor(e){super(J,ee),this.gamma=1,this.saturation=1,this.contrast=1,this.brightness=1,this.red=1,this.green=1,this.blue=1,this.alpha=1,Object.assign(this,e)}apply(e,r,i,s){this.uniforms.gamma=Math.max(this.gamma,1e-4),this.uniforms.saturation=this.saturation,this.uniforms.contrast=this.contrast,this.uniforms.brightness=this.brightness,this.uniforms.red=this.red,this.uniforms.green=this.green,this.uniforms.blue=this.blue,this.uniforms.alpha=this.alpha,e.applyFilter(this,r,i,s)}}var re=`attribute vec2 aVertexPosition; -attribute vec2 aTextureCoord; - -uniform mat3 projectionMatrix; - -varying vec2 vTextureCoord; - -void main(void) -{ - gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0); - vTextureCoord = aTextureCoord; -}`,ie=` -varying vec2 vTextureCoord; -uniform sampler2D uSampler; - -uniform vec2 uOffset; - -void main(void) -{ - vec4 color = vec4(0.0); - - // Sample top left pixel - color += texture2D(uSampler, vec2(vTextureCoord.x - uOffset.x, vTextureCoord.y + uOffset.y)); - - // Sample top right pixel - color += texture2D(uSampler, vec2(vTextureCoord.x + uOffset.x, vTextureCoord.y + uOffset.y)); - - // Sample bottom right pixel - color += texture2D(uSampler, vec2(vTextureCoord.x + uOffset.x, vTextureCoord.y - uOffset.y)); - - // Sample bottom left pixel - color += texture2D(uSampler, vec2(vTextureCoord.x - uOffset.x, vTextureCoord.y - uOffset.y)); - - // Average - color *= 0.25; - - gl_FragColor = color; -}`,oe=` -varying vec2 vTextureCoord; -uniform sampler2D uSampler; - -uniform vec2 uOffset; -uniform vec4 filterClamp; - -void main(void) -{ - vec4 color = vec4(0.0); - - // Sample top left pixel - color += texture2D(uSampler, clamp(vec2(vTextureCoord.x - uOffset.x, vTextureCoord.y + uOffset.y), filterClamp.xy, filterClamp.zw)); - - // Sample top right pixel - color += texture2D(uSampler, clamp(vec2(vTextureCoord.x + uOffset.x, vTextureCoord.y + uOffset.y), filterClamp.xy, filterClamp.zw)); - - // Sample bottom right pixel - color += texture2D(uSampler, clamp(vec2(vTextureCoord.x + uOffset.x, vTextureCoord.y - uOffset.y), filterClamp.xy, filterClamp.zw)); - - // Sample bottom left pixel - color += texture2D(uSampler, clamp(vec2(vTextureCoord.x - uOffset.x, vTextureCoord.y - uOffset.y), filterClamp.xy, filterClamp.zw)); - - // Average - color *= 0.25; - - gl_FragColor = color; -} -`;class h extends o.Filter{constructor(e=4,r=3,i=!1){super(re,i?oe:ie),this._kernels=[],this._blur=4,this._quality=3,this.uniforms.uOffset=new Float32Array(2),this._pixelSize=new o.Point,this.pixelSize=1,this._clamp=i,Array.isArray(e)?this.kernels=e:(this._blur=e,this.quality=r)}apply(e,r,i,s){const a=this._pixelSize.x/r._frame.width,l=this._pixelSize.y/r._frame.height;let u;if(this._quality===1||this._blur===0)u=this._kernels[0]+.5,this.uniforms.uOffset[0]=u*a,this.uniforms.uOffset[1]=u*l,e.applyFilter(this,r,i,s);else{const c=e.getFilterTexture();let d=r,m=c,g;const Q=this._quality-1;for(let _=0;_e+r+.5,0))}_generateKernels(){const e=this._blur,r=this._quality,i=[e];if(e>0){let s=e;const a=e/r;for(let l=1;l0?(this._kernels=e,this._quality=e.length,this._blur=Math.max(...e)):(this._kernels=[0],this._quality=1)}get clamp(){return this._clamp}set pixelSize(e){typeof e=="number"?(this._pixelSize.x=e,this._pixelSize.y=e):Array.isArray(e)?(this._pixelSize.x=e[0],this._pixelSize.y=e[1]):e instanceof o.Point?(this._pixelSize.x=e.x,this._pixelSize.y=e.y):(this._pixelSize.x=1,this._pixelSize.y=1)}get pixelSize(){return this._pixelSize}get quality(){return this._quality}set quality(e){this._quality=Math.max(1,Math.round(e)),this._generateKernels()}get blur(){return this._blur}set blur(e){this._blur=e,this._generateKernels()}}var S=`attribute vec2 aVertexPosition; -attribute vec2 aTextureCoord; - -uniform mat3 projectionMatrix; - -varying vec2 vTextureCoord; - -void main(void) -{ - gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0); - vTextureCoord = aTextureCoord; -}`,se=` -uniform sampler2D uSampler; -varying vec2 vTextureCoord; - -uniform float threshold; - -void main() { - vec4 color = texture2D(uSampler, vTextureCoord); - - // A simple & fast algorithm for getting brightness. - // It's inaccuracy , but good enought for this feature. - float _max = max(max(color.r, color.g), color.b); - float _min = min(min(color.r, color.g), color.b); - float brightness = (_max + _min) * 0.5; - - if(brightness > threshold) { - gl_FragColor = color; - } else { - gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0); - } -} -`;class ae extends o.Filter{constructor(e=.5){super(S,se),this.threshold=e}get threshold(){return this.uniforms.threshold}set threshold(e){this.uniforms.threshold=e}}var le=`uniform sampler2D uSampler; -varying vec2 vTextureCoord; - -uniform sampler2D bloomTexture; -uniform float bloomScale; -uniform float brightness; - -void main() { - vec4 color = texture2D(uSampler, vTextureCoord); - color.rgb *= brightness; - vec4 bloomColor = vec4(texture2D(bloomTexture, vTextureCoord).rgb, 0.0); - bloomColor.rgb *= bloomScale; - gl_FragColor = color + bloomColor; -} -`;const T=class extends o.Filter{constructor(t){super(S,le),this.bloomScale=1,this.brightness=1,this._resolution=o.settings.FILTER_RESOLUTION,typeof t=="number"&&(t={threshold:t});const e=Object.assign(T.defaults,t);this.bloomScale=e.bloomScale,this.brightness=e.brightness;const{kernels:r,blur:i,quality:s,pixelSize:a,resolution:l}=e;this._extractFilter=new ae(e.threshold),this._extractFilter.resolution=l,this._blurFilter=r?new h(r):new h(i,s),this.pixelSize=a,this.resolution=l}apply(t,e,r,i,s){const a=t.getFilterTexture();this._extractFilter.apply(t,e,a,1,s);const l=t.getFilterTexture();this._blurFilter.apply(t,a,l,1),this.uniforms.bloomScale=this.bloomScale,this.uniforms.brightness=this.brightness,this.uniforms.bloomTexture=l,t.applyFilter(this,e,r,i),t.returnFilterTexture(l),t.returnFilterTexture(a)}get resolution(){return this._resolution}set resolution(t){this._resolution=t,this._extractFilter&&(this._extractFilter.resolution=t),this._blurFilter&&(this._blurFilter.resolution=t)}get threshold(){return this._extractFilter.threshold}set threshold(t){this._extractFilter.threshold=t}get kernels(){return this._blurFilter.kernels}set kernels(t){this._blurFilter.kernels=t}get blur(){return this._blurFilter.blur}set blur(t){this._blurFilter.blur=t}get quality(){return this._blurFilter.quality}set quality(t){this._blurFilter.quality=t}get pixelSize(){return this._blurFilter.pixelSize}set pixelSize(t){this._blurFilter.pixelSize=t}};let F=T;F.defaults={threshold:.5,bloomScale:1,brightness:1,kernels:null,blur:8,quality:4,pixelSize:1,resolution:o.settings.FILTER_RESOLUTION};var ne=`attribute vec2 aVertexPosition; -attribute vec2 aTextureCoord; - -uniform mat3 projectionMatrix; - -varying vec2 vTextureCoord; - -void main(void) -{ - gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0); - vTextureCoord = aTextureCoord; -}`,ue=`varying vec2 vTextureCoord; - -uniform vec4 filterArea; -uniform float pixelSize; -uniform sampler2D uSampler; - -vec2 mapCoord( vec2 coord ) -{ - coord *= filterArea.xy; - coord += filterArea.zw; - - return coord; -} - -vec2 unmapCoord( vec2 coord ) -{ - coord -= filterArea.zw; - coord /= filterArea.xy; - - return coord; -} - -vec2 pixelate(vec2 coord, vec2 size) -{ - return floor(coord / size) * size; -} - -vec2 getMod(vec2 coord, vec2 size) -{ - return mod(coord, size) / size; -} - -float character(float n, vec2 p) -{ - p = floor(p*vec2(4.0, 4.0) + 2.5); - - if (clamp(p.x, 0.0, 4.0) == p.x) - { - if (clamp(p.y, 0.0, 4.0) == p.y) - { - if (int(mod(n/exp2(p.x + 5.0*p.y), 2.0)) == 1) return 1.0; - } - } - return 0.0; -} - -void main() -{ - vec2 coord = mapCoord(vTextureCoord); - - // get the grid position - vec2 pixCoord = pixelate(coord, vec2(pixelSize)); - pixCoord = unmapCoord(pixCoord); - - // sample the color at grid position - vec4 color = texture2D(uSampler, pixCoord); - - // brightness of the color as it's perceived by the human eye - float gray = 0.3 * color.r + 0.59 * color.g + 0.11 * color.b; - - // determine the character to use - float n = 65536.0; // . - if (gray > 0.2) n = 65600.0; // : - if (gray > 0.3) n = 332772.0; // * - if (gray > 0.4) n = 15255086.0; // o - if (gray > 0.5) n = 23385164.0; // & - if (gray > 0.6) n = 15252014.0; // 8 - if (gray > 0.7) n = 13199452.0; // @ - if (gray > 0.8) n = 11512810.0; // # - - // get the mod.. - vec2 modd = getMod(coord, vec2(pixelSize)); - - gl_FragColor = color * character( n, vec2(-1.0) + modd * 2.0); - -} -`;class ce extends o.Filter{constructor(e=8){super(ne,ue),this.size=e}get size(){return this.uniforms.pixelSize}set size(e){this.uniforms.pixelSize=e}}var fe=`attribute vec2 aVertexPosition; -attribute vec2 aTextureCoord; - -uniform mat3 projectionMatrix; - -varying vec2 vTextureCoord; - -void main(void) -{ - gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0); - vTextureCoord = aTextureCoord; -}`,de=`precision mediump float; - -varying vec2 vTextureCoord; -uniform sampler2D uSampler; -uniform vec4 filterArea; - -uniform float transformX; -uniform float transformY; -uniform vec3 lightColor; -uniform float lightAlpha; -uniform vec3 shadowColor; -uniform float shadowAlpha; - -void main(void) { - vec2 transform = vec2(1.0 / filterArea) * vec2(transformX, transformY); - vec4 color = texture2D(uSampler, vTextureCoord); - float light = texture2D(uSampler, vTextureCoord - transform).a; - float shadow = texture2D(uSampler, vTextureCoord + transform).a; - - color.rgb = mix(color.rgb, lightColor, clamp((color.a - light) * lightAlpha, 0.0, 1.0)); - color.rgb = mix(color.rgb, shadowColor, clamp((color.a - shadow) * shadowAlpha, 0.0, 1.0)); - gl_FragColor = vec4(color.rgb * color.a, color.a); -} -`;class he extends o.Filter{constructor(e){super(fe,de),this._thickness=2,this._angle=0,this.uniforms.lightColor=new Float32Array(3),this.uniforms.shadowColor=new Float32Array(3),Object.assign(this,{rotation:45,thickness:2,lightColor:16777215,lightAlpha:.7,shadowColor:0,shadowAlpha:.7},e),this.padding=1}_updateTransform(){this.uniforms.transformX=this._thickness*Math.cos(this._angle),this.uniforms.transformY=this._thickness*Math.sin(this._angle)}get rotation(){return this._angle/o.DEG_TO_RAD}set rotation(e){this._angle=e*o.DEG_TO_RAD,this._updateTransform()}get thickness(){return this._thickness}set thickness(e){this._thickness=e,this._updateTransform()}get lightColor(){return o.utils.rgb2hex(this.uniforms.lightColor)}set lightColor(e){o.utils.hex2rgb(e,this.uniforms.lightColor)}get lightAlpha(){return this.uniforms.lightAlpha}set lightAlpha(e){this.uniforms.lightAlpha=e}get shadowColor(){return o.utils.rgb2hex(this.uniforms.shadowColor)}set shadowColor(e){o.utils.hex2rgb(e,this.uniforms.shadowColor)}get shadowAlpha(){return this.uniforms.shadowAlpha}set shadowAlpha(e){this.uniforms.shadowAlpha=e}}class me extends o.Filter{constructor(e=2,r=4,i=o.settings.FILTER_RESOLUTION,s=5){super();let a,l;typeof e=="number"?(a=e,l=e):e instanceof o.Point?(a=e.x,l=e.y):Array.isArray(e)&&(a=e[0],l=e[1]),this.blurXFilter=new b.BlurFilterPass(!0,a,r,i,s),this.blurYFilter=new b.BlurFilterPass(!1,l,r,i,s),this.blurYFilter.blendMode=o.BLEND_MODES.SCREEN,this.defaultFilter=new H.AlphaFilter}apply(e,r,i,s){const a=e.getFilterTexture();this.defaultFilter.apply(e,r,i,s),this.blurXFilter.apply(e,r,a,1),this.blurYFilter.apply(e,a,i,0),e.returnFilterTexture(a)}get blur(){return this.blurXFilter.blur}set blur(e){this.blurXFilter.blur=this.blurYFilter.blur=e}get blurX(){return this.blurXFilter.blur}set blurX(e){this.blurXFilter.blur=e}get blurY(){return this.blurYFilter.blur}set blurY(e){this.blurYFilter.blur=e}}var ve=`attribute vec2 aVertexPosition; -attribute vec2 aTextureCoord; - -uniform mat3 projectionMatrix; - -varying vec2 vTextureCoord; - -void main(void) -{ - gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0); - vTextureCoord = aTextureCoord; -}`,ge=`uniform float radius; -uniform float strength; -uniform vec2 center; -uniform sampler2D uSampler; -varying vec2 vTextureCoord; - -uniform vec4 filterArea; -uniform vec4 filterClamp; -uniform vec2 dimensions; - -void main() -{ - vec2 coord = vTextureCoord * filterArea.xy; - coord -= center * dimensions.xy; - float distance = length(coord); - if (distance < radius) { - float percent = distance / radius; - if (strength > 0.0) { - coord *= mix(1.0, smoothstep(0.0, radius / distance, percent), strength * 0.75); - } else { - coord *= mix(1.0, pow(percent, 1.0 + strength * 0.75) * radius / distance, 1.0 - percent); - } - } - coord += center * dimensions.xy; - coord /= filterArea.xy; - vec2 clampedCoord = clamp(coord, filterClamp.xy, filterClamp.zw); - vec4 color = texture2D(uSampler, clampedCoord); - if (coord != clampedCoord) { - color *= max(0.0, 1.0 - length(coord - clampedCoord)); - } - - gl_FragColor = color; -} -`;const z=class extends o.Filter{constructor(t){super(ve,ge),this.uniforms.dimensions=new Float32Array(2),Object.assign(this,z.defaults,t)}apply(t,e,r,i){const{width:s,height:a}=e.filterFrame;this.uniforms.dimensions[0]=s,this.uniforms.dimensions[1]=a,t.applyFilter(this,e,r,i)}get radius(){return this.uniforms.radius}set radius(t){this.uniforms.radius=t}get strength(){return this.uniforms.strength}set strength(t){this.uniforms.strength=t}get center(){return this.uniforms.center}set center(t){this.uniforms.center=t}};let A=z;A.defaults={center:[.5,.5],radius:100,strength:1};var xe=`attribute vec2 aVertexPosition; -attribute vec2 aTextureCoord; - -uniform mat3 projectionMatrix; - -varying vec2 vTextureCoord; - -void main(void) -{ - gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0); - vTextureCoord = aTextureCoord; -}`,pe=`varying vec2 vTextureCoord; -uniform sampler2D uSampler; -uniform sampler2D colorMap; -uniform float _mix; -uniform float _size; -uniform float _sliceSize; -uniform float _slicePixelSize; -uniform float _sliceInnerSize; -void main() { - vec4 color = texture2D(uSampler, vTextureCoord.xy); - - vec4 adjusted; - if (color.a > 0.0) { - color.rgb /= color.a; - float innerWidth = _size - 1.0; - float zSlice0 = min(floor(color.b * innerWidth), innerWidth); - float zSlice1 = min(zSlice0 + 1.0, innerWidth); - float xOffset = _slicePixelSize * 0.5 + color.r * _sliceInnerSize; - float s0 = xOffset + (zSlice0 * _sliceSize); - float s1 = xOffset + (zSlice1 * _sliceSize); - float yOffset = _sliceSize * 0.5 + color.g * (1.0 - _sliceSize); - vec4 slice0Color = texture2D(colorMap, vec2(s0,yOffset)); - vec4 slice1Color = texture2D(colorMap, vec2(s1,yOffset)); - float zOffset = fract(color.b * innerWidth); - adjusted = mix(slice0Color, slice1Color, zOffset); - - color.rgb *= color.a; - } - gl_FragColor = vec4(mix(color, adjusted, _mix).rgb, color.a); - -}`;class ye extends o.Filter{constructor(e,r=!1,i=1){super(xe,pe),this.mix=1,this._size=0,this._sliceSize=0,this._slicePixelSize=0,this._sliceInnerSize=0,this._nearest=!1,this._scaleMode=null,this._colorMap=null,this._scaleMode=null,this.nearest=r,this.mix=i,this.colorMap=e}apply(e,r,i,s){this.uniforms._mix=this.mix,e.applyFilter(this,r,i,s)}get colorSize(){return this._size}get colorMap(){return this._colorMap}set colorMap(e){!e||(e instanceof o.Texture||(e=o.Texture.from(e)),e!=null&&e.baseTexture&&(e.baseTexture.scaleMode=this._scaleMode,e.baseTexture.mipmap=o.MIPMAP_MODES.OFF,this._size=e.height,this._sliceSize=1/this._size,this._slicePixelSize=this._sliceSize/this._size,this._sliceInnerSize=this._slicePixelSize*(this._size-1),this.uniforms._size=this._size,this.uniforms._sliceSize=this._sliceSize,this.uniforms._slicePixelSize=this._slicePixelSize,this.uniforms._sliceInnerSize=this._sliceInnerSize,this.uniforms.colorMap=e),this._colorMap=e)}get nearest(){return this._nearest}set nearest(e){this._nearest=e,this._scaleMode=e?o.SCALE_MODES.NEAREST:o.SCALE_MODES.LINEAR;const r=this._colorMap;r&&r.baseTexture&&(r.baseTexture._glTextures={},r.baseTexture.scaleMode=this._scaleMode,r.baseTexture.mipmap=o.MIPMAP_MODES.OFF,r._updateID++,r.baseTexture.emit("update",r.baseTexture))}updateColorMap(){const e=this._colorMap;e&&e.baseTexture&&(e._updateID++,e.baseTexture.emit("update",e.baseTexture),this.colorMap=e)}destroy(e=!1){this._colorMap&&this._colorMap.destroy(e),super.destroy()}}var Ce=`attribute vec2 aVertexPosition; -attribute vec2 aTextureCoord; - -uniform mat3 projectionMatrix; - -varying vec2 vTextureCoord; - -void main(void) -{ - gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0); - vTextureCoord = aTextureCoord; -}`,_e=`varying vec2 vTextureCoord; -uniform sampler2D uSampler; -uniform vec3 color; -uniform float alpha; - -void main(void) { - vec4 currentColor = texture2D(uSampler, vTextureCoord); - gl_FragColor = vec4(mix(currentColor.rgb, color.rgb, currentColor.a * alpha), currentColor.a); -} -`;class be extends o.Filter{constructor(e=0,r=1){super(Ce,_e),this._color=0,this._alpha=1,this.uniforms.color=new Float32Array(3),this.color=e,this.alpha=r}set color(e){const r=this.uniforms.color;typeof e=="number"?(o.utils.hex2rgb(e,r),this._color=e):(r[0]=e[0],r[1]=e[1],r[2]=e[2],this._color=o.utils.rgb2hex(r))}get color(){return this._color}set alpha(e){this.uniforms.alpha=e,this._alpha=e}get alpha(){return this._alpha}}var Se=`attribute vec2 aVertexPosition; -attribute vec2 aTextureCoord; - -uniform mat3 projectionMatrix; - -varying vec2 vTextureCoord; - -void main(void) -{ - gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0); - vTextureCoord = aTextureCoord; -}`,Te=`varying vec2 vTextureCoord; -uniform sampler2D uSampler; -uniform vec3 originalColor; -uniform vec3 newColor; -uniform float epsilon; -void main(void) { - vec4 currentColor = texture2D(uSampler, vTextureCoord); - vec3 colorDiff = originalColor - (currentColor.rgb / max(currentColor.a, 0.0000000001)); - float colorDistance = length(colorDiff); - float doReplace = step(colorDistance, epsilon); - gl_FragColor = vec4(mix(currentColor.rgb, (newColor + colorDiff) * currentColor.a, doReplace), currentColor.a); -} -`;class Fe extends o.Filter{constructor(e=16711680,r=0,i=.4){super(Se,Te),this._originalColor=16711680,this._newColor=0,this.uniforms.originalColor=new Float32Array(3),this.uniforms.newColor=new Float32Array(3),this.originalColor=e,this.newColor=r,this.epsilon=i}set originalColor(e){const r=this.uniforms.originalColor;typeof e=="number"?(o.utils.hex2rgb(e,r),this._originalColor=e):(r[0]=e[0],r[1]=e[1],r[2]=e[2],this._originalColor=o.utils.rgb2hex(r))}get originalColor(){return this._originalColor}set newColor(e){const r=this.uniforms.newColor;typeof e=="number"?(o.utils.hex2rgb(e,r),this._newColor=e):(r[0]=e[0],r[1]=e[1],r[2]=e[2],this._newColor=o.utils.rgb2hex(r))}get newColor(){return this._newColor}set epsilon(e){this.uniforms.epsilon=e}get epsilon(){return this.uniforms.epsilon}}var ze=`attribute vec2 aVertexPosition; -attribute vec2 aTextureCoord; - -uniform mat3 projectionMatrix; - -varying vec2 vTextureCoord; - -void main(void) -{ - gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0); - vTextureCoord = aTextureCoord; -}`,Ae=`precision mediump float; - -varying mediump vec2 vTextureCoord; - -uniform sampler2D uSampler; -uniform vec2 texelSize; -uniform float matrix[9]; - -void main(void) -{ - vec4 c11 = texture2D(uSampler, vTextureCoord - texelSize); // top left - vec4 c12 = texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y - texelSize.y)); // top center - vec4 c13 = texture2D(uSampler, vec2(vTextureCoord.x + texelSize.x, vTextureCoord.y - texelSize.y)); // top right - - vec4 c21 = texture2D(uSampler, vec2(vTextureCoord.x - texelSize.x, vTextureCoord.y)); // mid left - vec4 c22 = texture2D(uSampler, vTextureCoord); // mid center - vec4 c23 = texture2D(uSampler, vec2(vTextureCoord.x + texelSize.x, vTextureCoord.y)); // mid right - - vec4 c31 = texture2D(uSampler, vec2(vTextureCoord.x - texelSize.x, vTextureCoord.y + texelSize.y)); // bottom left - vec4 c32 = texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y + texelSize.y)); // bottom center - vec4 c33 = texture2D(uSampler, vTextureCoord + texelSize); // bottom right - - gl_FragColor = - c11 * matrix[0] + c12 * matrix[1] + c13 * matrix[2] + - c21 * matrix[3] + c22 * matrix[4] + c23 * matrix[5] + - c31 * matrix[6] + c32 * matrix[7] + c33 * matrix[8]; - - gl_FragColor.a = c22.a; -} -`;class Pe extends o.Filter{constructor(e,r=200,i=200){super(ze,Ae),this.uniforms.texelSize=new Float32Array(2),this.uniforms.matrix=new Float32Array(9),e!==void 0&&(this.matrix=e),this.width=r,this.height=i}get matrix(){return this.uniforms.matrix}set matrix(e){e.forEach((r,i)=>{this.uniforms.matrix[i]=r})}get width(){return 1/this.uniforms.texelSize[0]}set width(e){this.uniforms.texelSize[0]=1/e}get height(){return 1/this.uniforms.texelSize[1]}set height(e){this.uniforms.texelSize[1]=1/e}}var we=`attribute vec2 aVertexPosition; -attribute vec2 aTextureCoord; - -uniform mat3 projectionMatrix; - -varying vec2 vTextureCoord; - -void main(void) -{ - gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0); - vTextureCoord = aTextureCoord; -}`,Me=`precision mediump float; - -varying vec2 vTextureCoord; - -uniform sampler2D uSampler; - -void main(void) -{ - float lum = length(texture2D(uSampler, vTextureCoord.xy).rgb); - - gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0); - - if (lum < 1.00) - { - if (mod(gl_FragCoord.x + gl_FragCoord.y, 10.0) == 0.0) - { - gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0); - } - } - - if (lum < 0.75) - { - if (mod(gl_FragCoord.x - gl_FragCoord.y, 10.0) == 0.0) - { - gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0); - } - } - - if (lum < 0.50) - { - if (mod(gl_FragCoord.x + gl_FragCoord.y - 5.0, 10.0) == 0.0) - { - gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0); - } - } - - if (lum < 0.3) - { - if (mod(gl_FragCoord.x - gl_FragCoord.y - 5.0, 10.0) == 0.0) - { - gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0); - } - } -} -`;class De extends o.Filter{constructor(){super(we,Me)}}var Oe=`attribute vec2 aVertexPosition; -attribute vec2 aTextureCoord; - -uniform mat3 projectionMatrix; - -varying vec2 vTextureCoord; - -void main(void) -{ - gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0); - vTextureCoord = aTextureCoord; -}`,Re=`varying vec2 vTextureCoord; -uniform sampler2D uSampler; - -uniform vec4 filterArea; -uniform vec2 dimensions; - -const float SQRT_2 = 1.414213; - -const float light = 1.0; - -uniform float curvature; -uniform float lineWidth; -uniform float lineContrast; -uniform bool verticalLine; -uniform float noise; -uniform float noiseSize; - -uniform float vignetting; -uniform float vignettingAlpha; -uniform float vignettingBlur; - -uniform float seed; -uniform float time; - -float rand(vec2 co) { - return fract(sin(dot(co.xy, vec2(12.9898, 78.233))) * 43758.5453); -} - -void main(void) -{ - vec2 pixelCoord = vTextureCoord.xy * filterArea.xy; - vec2 dir = vec2(vTextureCoord.xy * filterArea.xy / dimensions - vec2(0.5, 0.5)); - - gl_FragColor = texture2D(uSampler, vTextureCoord); - vec3 rgb = gl_FragColor.rgb; - - if (noise > 0.0 && noiseSize > 0.0) - { - pixelCoord.x = floor(pixelCoord.x / noiseSize); - pixelCoord.y = floor(pixelCoord.y / noiseSize); - float _noise = rand(pixelCoord * noiseSize * seed) - 0.5; - rgb += _noise * noise; - } - - if (lineWidth > 0.0) - { - float _c = curvature > 0. ? curvature : 1.; - float k = curvature > 0. ?(length(dir * dir) * 0.25 * _c * _c + 0.935 * _c) : 1.; - vec2 uv = dir * k; - - float v = (verticalLine ? uv.x * dimensions.x : uv.y * dimensions.y) * min(1.0, 2.0 / lineWidth ) / _c; - float j = 1. + cos(v * 1.2 - time) * 0.5 * lineContrast; - rgb *= j; - float segment = verticalLine ? mod((dir.x + .5) * dimensions.x, 4.) : mod((dir.y + .5) * dimensions.y, 4.); - rgb *= 0.99 + ceil(segment) * 0.015; - } - - if (vignetting > 0.0) - { - float outter = SQRT_2 - vignetting * SQRT_2; - float darker = clamp((outter - length(dir) * SQRT_2) / ( 0.00001 + vignettingBlur * SQRT_2), 0.0, 1.0); - rgb *= darker + (1.0 - darker) * (1.0 - vignettingAlpha); - } - - gl_FragColor.rgb = rgb; -} -`;const P=class extends o.Filter{constructor(t){super(Oe,Re),this.time=0,this.seed=0,this.uniforms.dimensions=new Float32Array(2),Object.assign(this,P.defaults,t)}apply(t,e,r,i){const{width:s,height:a}=e.filterFrame;this.uniforms.dimensions[0]=s,this.uniforms.dimensions[1]=a,this.uniforms.seed=this.seed,this.uniforms.time=this.time,t.applyFilter(this,e,r,i)}set curvature(t){this.uniforms.curvature=t}get curvature(){return this.uniforms.curvature}set lineWidth(t){this.uniforms.lineWidth=t}get lineWidth(){return this.uniforms.lineWidth}set lineContrast(t){this.uniforms.lineContrast=t}get lineContrast(){return this.uniforms.lineContrast}set verticalLine(t){this.uniforms.verticalLine=t}get verticalLine(){return this.uniforms.verticalLine}set noise(t){this.uniforms.noise=t}get noise(){return this.uniforms.noise}set noiseSize(t){this.uniforms.noiseSize=t}get noiseSize(){return this.uniforms.noiseSize}set vignetting(t){this.uniforms.vignetting=t}get vignetting(){return this.uniforms.vignetting}set vignettingAlpha(t){this.uniforms.vignettingAlpha=t}get vignettingAlpha(){return this.uniforms.vignettingAlpha}set vignettingBlur(t){this.uniforms.vignettingBlur=t}get vignettingBlur(){return this.uniforms.vignettingBlur}};let w=P;w.defaults={curvature:1,lineWidth:1,lineContrast:.25,verticalLine:!1,noise:0,noiseSize:1,seed:0,vignetting:.3,vignettingAlpha:1,vignettingBlur:.3,time:0};var $e=`attribute vec2 aVertexPosition; -attribute vec2 aTextureCoord; - -uniform mat3 projectionMatrix; - -varying vec2 vTextureCoord; - -void main(void) -{ - gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0); - vTextureCoord = aTextureCoord; -}`,Ee=`precision mediump float; - -varying vec2 vTextureCoord; -varying vec4 vColor; - -uniform vec4 filterArea; -uniform sampler2D uSampler; - -uniform float angle; -uniform float scale; -uniform bool grayscale; - -float pattern() -{ - float s = sin(angle), c = cos(angle); - vec2 tex = vTextureCoord * filterArea.xy; - vec2 point = vec2( - c * tex.x - s * tex.y, - s * tex.x + c * tex.y - ) * scale; - return (sin(point.x) * sin(point.y)) * 4.0; -} - -void main() -{ - vec4 color = texture2D(uSampler, vTextureCoord); - vec3 colorRGB = vec3(color); - - if (grayscale) - { - colorRGB = vec3(color.r + color.g + color.b) / 3.0; - } - - gl_FragColor = vec4(colorRGB * 10.0 - 5.0 + pattern(), color.a); -} -`;class ke extends o.Filter{constructor(e=1,r=5,i=!0){super($e,Ee),this.scale=e,this.angle=r,this.grayscale=i}get scale(){return this.uniforms.scale}set scale(e){this.uniforms.scale=e}get angle(){return this.uniforms.angle}set angle(e){this.uniforms.angle=e}get grayscale(){return this.uniforms.grayscale}set grayscale(e){this.uniforms.grayscale=e}}var je=`attribute vec2 aVertexPosition; -attribute vec2 aTextureCoord; - -uniform mat3 projectionMatrix; - -varying vec2 vTextureCoord; - -void main(void) -{ - gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0); - vTextureCoord = aTextureCoord; -}`,Le=`varying vec2 vTextureCoord; -uniform sampler2D uSampler; -uniform float alpha; -uniform vec3 color; - -uniform vec2 shift; -uniform vec4 inputSize; - -void main(void){ - vec4 sample = texture2D(uSampler, vTextureCoord - shift * inputSize.zw); - - // Premultiply alpha - sample.rgb = color.rgb * sample.a; - - // alpha user alpha - sample *= alpha; - - gl_FragColor = sample; -}`,Ie=Object.defineProperty,M=Object.getOwnPropertySymbols,Ve=Object.prototype.hasOwnProperty,Ne=Object.prototype.propertyIsEnumerable,D=(t,e,r)=>e in t?Ie(t,e,{enumerable:!0,configurable:!0,writable:!0,value:r}):t[e]=r,O=(t,e)=>{for(var r in e||(e={}))Ve.call(e,r)&&D(t,r,e[r]);if(M)for(var r of M(e))Ne.call(e,r)&&D(t,r,e[r]);return t};const x=class extends o.Filter{constructor(t){super(),this.angle=45,this._distance=5,this._resolution=o.settings.FILTER_RESOLUTION;const e=t?O(O({},x.defaults),t):x.defaults,{kernels:r,blur:i,quality:s,pixelSize:a,resolution:l}=e;this._tintFilter=new o.Filter(je,Le),this._tintFilter.uniforms.color=new Float32Array(4),this._tintFilter.uniforms.shift=new o.Point,this._tintFilter.resolution=l,this._blurFilter=r?new h(r):new h(i,s),this.pixelSize=a,this.resolution=l;const{shadowOnly:u,rotation:c,distance:d,alpha:m,color:g}=e;this.shadowOnly=u,this.rotation=c,this.distance=d,this.alpha=m,this.color=g,this._updatePadding()}apply(t,e,r,i){const s=t.getFilterTexture();this._tintFilter.apply(t,e,s,1),this._blurFilter.apply(t,s,r,i),this.shadowOnly!==!0&&t.applyFilter(this,e,r,0),t.returnFilterTexture(s)}_updatePadding(){this.padding=this.distance+this.blur*2}_updateShift(){this._tintFilter.uniforms.shift.set(this.distance*Math.cos(this.angle),this.distance*Math.sin(this.angle))}get resolution(){return this._resolution}set resolution(t){this._resolution=t,this._tintFilter&&(this._tintFilter.resolution=t),this._blurFilter&&(this._blurFilter.resolution=t)}get distance(){return this._distance}set distance(t){this._distance=t,this._updatePadding(),this._updateShift()}get rotation(){return this.angle/o.DEG_TO_RAD}set rotation(t){this.angle=t*o.DEG_TO_RAD,this._updateShift()}get alpha(){return this._tintFilter.uniforms.alpha}set alpha(t){this._tintFilter.uniforms.alpha=t}get color(){return o.utils.rgb2hex(this._tintFilter.uniforms.color)}set color(t){o.utils.hex2rgb(t,this._tintFilter.uniforms.color)}get kernels(){return this._blurFilter.kernels}set kernels(t){this._blurFilter.kernels=t}get blur(){return this._blurFilter.blur}set blur(t){this._blurFilter.blur=t,this._updatePadding()}get quality(){return this._blurFilter.quality}set quality(t){this._blurFilter.quality=t}get pixelSize(){return this._blurFilter.pixelSize}set pixelSize(t){this._blurFilter.pixelSize=t}};let R=x;R.defaults={rotation:45,distance:5,color:0,alpha:.5,shadowOnly:!1,kernels:null,blur:2,quality:3,pixelSize:1,resolution:o.settings.FILTER_RESOLUTION};var Be=`attribute vec2 aVertexPosition; -attribute vec2 aTextureCoord; - -uniform mat3 projectionMatrix; - -varying vec2 vTextureCoord; - -void main(void) -{ - gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0); - vTextureCoord = aTextureCoord; -}`,Xe=`precision mediump float; - -varying vec2 vTextureCoord; - -uniform sampler2D uSampler; -uniform float strength; -uniform vec4 filterArea; - - -void main(void) -{ - vec2 onePixel = vec2(1.0 / filterArea); - - vec4 color; - - color.rgb = vec3(0.5); - - color -= texture2D(uSampler, vTextureCoord - onePixel) * strength; - color += texture2D(uSampler, vTextureCoord + onePixel) * strength; - - color.rgb = vec3((color.r + color.g + color.b) / 3.0); - - float alpha = texture2D(uSampler, vTextureCoord).a; - - gl_FragColor = vec4(color.rgb * alpha, alpha); -} -`;class Ge extends o.Filter{constructor(e=5){super(Be,Xe),this.strength=e}get strength(){return this.uniforms.strength}set strength(e){this.uniforms.strength=e}}var qe=`attribute vec2 aVertexPosition; -attribute vec2 aTextureCoord; - -uniform mat3 projectionMatrix; - -varying vec2 vTextureCoord; - -void main(void) -{ - gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0); - vTextureCoord = aTextureCoord; -}`,Ke=`// precision highp float; - -varying vec2 vTextureCoord; -uniform sampler2D uSampler; - -uniform vec4 filterArea; -uniform vec4 filterClamp; -uniform vec2 dimensions; -uniform float aspect; - -uniform sampler2D displacementMap; -uniform float offset; -uniform float sinDir; -uniform float cosDir; -uniform int fillMode; - -uniform float seed; -uniform vec2 red; -uniform vec2 green; -uniform vec2 blue; - -const int TRANSPARENT = 0; -const int ORIGINAL = 1; -const int LOOP = 2; -const int CLAMP = 3; -const int MIRROR = 4; - -void main(void) -{ - vec2 coord = (vTextureCoord * filterArea.xy) / dimensions; - - if (coord.x > 1.0 || coord.y > 1.0) { - return; - } - - float cx = coord.x - 0.5; - float cy = (coord.y - 0.5) * aspect; - float ny = (-sinDir * cx + cosDir * cy) / aspect + 0.5; - - // displacementMap: repeat - // ny = ny > 1.0 ? ny - 1.0 : (ny < 0.0 ? 1.0 + ny : ny); - - // displacementMap: mirror - ny = ny > 1.0 ? 2.0 - ny : (ny < 0.0 ? -ny : ny); - - vec4 dc = texture2D(displacementMap, vec2(0.5, ny)); - - float displacement = (dc.r - dc.g) * (offset / filterArea.x); - - coord = vTextureCoord + vec2(cosDir * displacement, sinDir * displacement * aspect); - - if (fillMode == CLAMP) { - coord = clamp(coord, filterClamp.xy, filterClamp.zw); - } else { - if( coord.x > filterClamp.z ) { - if (fillMode == TRANSPARENT) { - discard; - } else if (fillMode == LOOP) { - coord.x -= filterClamp.z; - } else if (fillMode == MIRROR) { - coord.x = filterClamp.z * 2.0 - coord.x; - } - } else if( coord.x < filterClamp.x ) { - if (fillMode == TRANSPARENT) { - discard; - } else if (fillMode == LOOP) { - coord.x += filterClamp.z; - } else if (fillMode == MIRROR) { - coord.x *= -filterClamp.z; - } - } - - if( coord.y > filterClamp.w ) { - if (fillMode == TRANSPARENT) { - discard; - } else if (fillMode == LOOP) { - coord.y -= filterClamp.w; - } else if (fillMode == MIRROR) { - coord.y = filterClamp.w * 2.0 - coord.y; - } - } else if( coord.y < filterClamp.y ) { - if (fillMode == TRANSPARENT) { - discard; - } else if (fillMode == LOOP) { - coord.y += filterClamp.w; - } else if (fillMode == MIRROR) { - coord.y *= -filterClamp.w; - } - } - } - - gl_FragColor.r = texture2D(uSampler, coord + red * (1.0 - seed * 0.4) / filterArea.xy).r; - gl_FragColor.g = texture2D(uSampler, coord + green * (1.0 - seed * 0.3) / filterArea.xy).g; - gl_FragColor.b = texture2D(uSampler, coord + blue * (1.0 - seed * 0.2) / filterArea.xy).b; - gl_FragColor.a = texture2D(uSampler, coord).a; -} -`;const p=class extends o.Filter{constructor(t){super(qe,Ke),this.offset=100,this.fillMode=p.TRANSPARENT,this.average=!1,this.seed=0,this.minSize=8,this.sampleSize=512,this._slices=0,this._offsets=new Float32Array(1),this._sizes=new Float32Array(1),this._direction=-1,this.uniforms.dimensions=new Float32Array(2),this._canvas=document.createElement("canvas"),this._canvas.width=4,this._canvas.height=this.sampleSize,this.texture=o.Texture.from(this._canvas,{scaleMode:o.SCALE_MODES.NEAREST}),Object.assign(this,p.defaults,t)}apply(t,e,r,i){const{width:s,height:a}=e.filterFrame;this.uniforms.dimensions[0]=s,this.uniforms.dimensions[1]=a,this.uniforms.aspect=a/s,this.uniforms.seed=this.seed,this.uniforms.offset=this.offset,this.uniforms.fillMode=this.fillMode,t.applyFilter(this,e,r,i)}_randomizeSizes(){const t=this._sizes,e=this._slices-1,r=this.sampleSize,i=Math.min(this.minSize/r,.9/this._slices);if(this.average){const s=this._slices;let a=1;for(let l=0;l0;r--){const i=Math.random()*r>>0,s=t[r];t[r]=t[i],t[i]=s}}_randomizeOffsets(){for(let t=0;t0?i:0,c=i<0?-i:0;r.fillStyle=`rgba(${u}, ${c}, 0, 1)`,r.fillRect(0,s>>0,t,l+1>>0),s+=l}e.baseTexture.update(),this.uniforms.displacementMap=e}set sizes(t){const e=Math.min(this._slices,t.length);for(let r=0;r>0)+1}set offset(e){this.uniforms.uOffset=e}get offset(){return this.uniforms.uOffset}}var ot=`attribute vec2 aVertexPosition; -attribute vec2 aTextureCoord; - -uniform mat3 projectionMatrix; - -varying vec2 vTextureCoord; - -void main(void) -{ - gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0); - vTextureCoord = aTextureCoord; -}`,st=`varying vec2 vTextureCoord; -uniform sampler2D uSampler; - -uniform float epsilon; - -const int MAX_COLORS = %maxColors%; - -uniform vec3 originalColors[MAX_COLORS]; -uniform vec3 targetColors[MAX_COLORS]; - -void main(void) -{ - gl_FragColor = texture2D(uSampler, vTextureCoord); - - float alpha = gl_FragColor.a; - if (alpha < 0.0001) - { - return; - } - - vec3 color = gl_FragColor.rgb / alpha; - - for(int i = 0; i < MAX_COLORS; i++) - { - vec3 origColor = originalColors[i]; - if (origColor.r < 0.0) - { - break; - } - vec3 colorDiff = origColor - color; - if (length(colorDiff) < epsilon) - { - vec3 targetColor = targetColors[i]; - gl_FragColor = vec4((targetColor + colorDiff) * alpha, alpha); - return; - } - } -} -`;class at extends o.Filter{constructor(e,r=.05,i=e.length){super(ot,st.replace(/%maxColors%/g,i.toFixed(0))),this._replacements=[],this._maxColors=0,this.epsilon=r,this._maxColors=i,this.uniforms.originalColors=new Float32Array(i*3),this.uniforms.targetColors=new Float32Array(i*3),this.replacements=e}set replacements(e){const r=this.uniforms.originalColors,i=this.uniforms.targetColors,s=e.length;if(s>this._maxColors)throw new Error(`Length of replacements (${s}) exceeds the maximum colors length (${this._maxColors})`);r[s*3]=-1;for(let a=0;a 0.5) then: 1 - 2 * (1 - dst) * (1 - src) - return vec3((dst.x <= 0.5) ? (2.0 * src.x * dst.x) : (1.0 - 2.0 * (1.0 - dst.x) * (1.0 - src.x)), - (dst.y <= 0.5) ? (2.0 * src.y * dst.y) : (1.0 - 2.0 * (1.0 - dst.y) * (1.0 - src.y)), - (dst.z <= 0.5) ? (2.0 * src.z * dst.z) : (1.0 - 2.0 * (1.0 - dst.z) * (1.0 - src.z))); -} - - -void main() -{ - gl_FragColor = texture2D(uSampler, vTextureCoord); - vec3 color = gl_FragColor.rgb; - - if (sepia > 0.0) - { - float gray = (color.x + color.y + color.z) / 3.0; - vec3 grayscale = vec3(gray); - - color = Overlay(SEPIA_RGB, grayscale); - - color = grayscale + sepia * (color - grayscale); - } - - vec2 coord = vTextureCoord * filterArea.xy / dimensions.xy; - - if (vignetting > 0.0) - { - float outter = SQRT_2 - vignetting * SQRT_2; - vec2 dir = vec2(vec2(0.5, 0.5) - coord); - dir.y *= dimensions.y / dimensions.x; - float darker = clamp((outter - length(dir) * SQRT_2) / ( 0.00001 + vignettingBlur * SQRT_2), 0.0, 1.0); - color.rgb *= darker + (1.0 - darker) * (1.0 - vignettingAlpha); - } - - if (scratchDensity > seed && scratch != 0.0) - { - float phase = seed * 256.0; - float s = mod(floor(phase), 2.0); - float dist = 1.0 / scratchDensity; - float d = distance(coord, vec2(seed * dist, abs(s - seed * dist))); - if (d < seed * 0.6 + 0.4) - { - highp float period = scratchDensity * 10.0; - - float xx = coord.x * period + phase; - float aa = abs(mod(xx, 0.5) * 4.0); - float bb = mod(floor(xx / 0.5), 2.0); - float yy = (1.0 - bb) * aa + bb * (2.0 - aa); - - float kk = 2.0 * period; - float dw = scratchWidth / dimensions.x * (0.75 + seed); - float dh = dw * kk; - - float tine = (yy - (2.0 - dh)); - - if (tine > 0.0) { - float _sign = sign(scratch); - - tine = s * tine / period + scratch + 0.1; - tine = clamp(tine + 1.0, 0.5 + _sign * 0.5, 1.5 + _sign * 0.5); - - color.rgb *= tine; - } - } - } - - if (noise > 0.0 && noiseSize > 0.0) - { - vec2 pixelCoord = vTextureCoord.xy * filterArea.xy; - pixelCoord.x = floor(pixelCoord.x / noiseSize); - pixelCoord.y = floor(pixelCoord.y / noiseSize); - // vec2 d = pixelCoord * noiseSize * vec2(1024.0 + seed * 512.0, 1024.0 - seed * 512.0); - // float _noise = snoise(d) * 0.5; - float _noise = rand(pixelCoord * noiseSize * seed) - 0.5; - color += _noise * noise; - } - - gl_FragColor.rgb = color; -} -`;const L=class extends o.Filter{constructor(t,e=0){super(lt,nt),this.seed=0,this.uniforms.dimensions=new Float32Array(2),typeof t=="number"?(this.seed=t,t=void 0):this.seed=e,Object.assign(this,L.defaults,t)}apply(t,e,r,i){var s,a;this.uniforms.dimensions[0]=(s=e.filterFrame)==null?void 0:s.width,this.uniforms.dimensions[1]=(a=e.filterFrame)==null?void 0:a.height,this.uniforms.seed=this.seed,t.applyFilter(this,e,r,i)}set sepia(t){this.uniforms.sepia=t}get sepia(){return this.uniforms.sepia}set noise(t){this.uniforms.noise=t}get noise(){return this.uniforms.noise}set noiseSize(t){this.uniforms.noiseSize=t}get noiseSize(){return this.uniforms.noiseSize}set scratch(t){this.uniforms.scratch=t}get scratch(){return this.uniforms.scratch}set scratchDensity(t){this.uniforms.scratchDensity=t}get scratchDensity(){return this.uniforms.scratchDensity}set scratchWidth(t){this.uniforms.scratchWidth=t}get scratchWidth(){return this.uniforms.scratchWidth}set vignetting(t){this.uniforms.vignetting=t}get vignetting(){return this.uniforms.vignetting}set vignettingAlpha(t){this.uniforms.vignettingAlpha=t}get vignettingAlpha(){return this.uniforms.vignettingAlpha}set vignettingBlur(t){this.uniforms.vignettingBlur=t}get vignettingBlur(){return this.uniforms.vignettingBlur}};let I=L;I.defaults={sepia:.3,noise:.3,noiseSize:1,scratch:.5,scratchDensity:.3,scratchWidth:1,vignetting:.3,vignettingAlpha:1,vignettingBlur:.3};var ut=`attribute vec2 aVertexPosition; -attribute vec2 aTextureCoord; - -uniform mat3 projectionMatrix; - -varying vec2 vTextureCoord; - -void main(void) -{ - gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0); - vTextureCoord = aTextureCoord; -}`,ct=`varying vec2 vTextureCoord; -uniform sampler2D uSampler; - -uniform float alpha; -uniform vec2 thickness; -uniform vec4 outlineColor; -uniform vec4 filterClamp; - -const float DOUBLE_PI = 3.14159265358979323846264 * 2.; - -void main(void) { - vec4 ownColor = texture2D(uSampler, vTextureCoord); - vec4 curColor; - float maxAlpha = 0.; - vec2 displaced; - for (float angle = 0.; angle <= DOUBLE_PI; angle += \${angleStep}) { - displaced.x = vTextureCoord.x + thickness.x * cos(angle); - displaced.y = vTextureCoord.y + thickness.y * sin(angle); - curColor = texture2D(uSampler, clamp(displaced, filterClamp.xy, filterClamp.zw)); - maxAlpha = max(maxAlpha, curColor.a * alpha); - } - float resultAlpha = max(maxAlpha, ownColor.a); - gl_FragColor = vec4((ownColor.rgb + outlineColor.rgb * (1. - ownColor.a)) * resultAlpha, resultAlpha); -} -`;const v=class extends o.Filter{constructor(t=1,e=0,r=.1,i=1){super(ut,ct.replace(/\$\{angleStep\}/,v.getAngleStep(r))),this._thickness=1,this._alpha=1,this.uniforms.thickness=new Float32Array([0,0]),this.uniforms.outlineColor=new Float32Array([0,0,0,1]),this.uniforms.alpha=i,Object.assign(this,{thickness:t,color:e,quality:r,alpha:i})}static getAngleStep(t){const e=Math.max(t*v.MAX_SAMPLES,v.MIN_SAMPLES);return(Math.PI*2/e).toFixed(7)}apply(t,e,r,i){this.uniforms.thickness[0]=this._thickness/e._frame.width,this.uniforms.thickness[1]=this._thickness/e._frame.height,this.uniforms.alpha=this._alpha,t.applyFilter(this,e,r,i)}get alpha(){return this._alpha}set alpha(t){this._alpha=t}get color(){return o.utils.rgb2hex(this.uniforms.outlineColor)}set color(t){o.utils.hex2rgb(t,this.uniforms.outlineColor)}get thickness(){return this._thickness}set thickness(t){this._thickness=t,this.padding=t}};let y=v;y.MIN_SAMPLES=1,y.MAX_SAMPLES=100;var ft=`attribute vec2 aVertexPosition; -attribute vec2 aTextureCoord; - -uniform mat3 projectionMatrix; - -varying vec2 vTextureCoord; - -void main(void) -{ - gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0); - vTextureCoord = aTextureCoord; -}`,dt=`precision mediump float; - -varying vec2 vTextureCoord; - -uniform vec2 size; -uniform sampler2D uSampler; - -uniform vec4 filterArea; - -vec2 mapCoord( vec2 coord ) -{ - coord *= filterArea.xy; - coord += filterArea.zw; - - return coord; -} - -vec2 unmapCoord( vec2 coord ) -{ - coord -= filterArea.zw; - coord /= filterArea.xy; - - return coord; -} - -vec2 pixelate(vec2 coord, vec2 size) -{ - return floor( coord / size ) * size; -} - -void main(void) -{ - vec2 coord = mapCoord(vTextureCoord); - - coord = pixelate(coord, size); - - coord = unmapCoord(coord); - - gl_FragColor = texture2D(uSampler, coord); -} -`;class ht extends o.Filter{constructor(e=10){super(ft,dt),this.size=e}get size(){return this.uniforms.size}set size(e){typeof e=="number"&&(e=[e,e]),this.uniforms.size=e}}var mt=`attribute vec2 aVertexPosition; -attribute vec2 aTextureCoord; - -uniform mat3 projectionMatrix; - -varying vec2 vTextureCoord; - -void main(void) -{ - gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0); - vTextureCoord = aTextureCoord; -}`,vt=`varying vec2 vTextureCoord; -uniform sampler2D uSampler; -uniform vec4 filterArea; - -uniform float uRadian; -uniform vec2 uCenter; -uniform float uRadius; -uniform int uKernelSize; - -const int MAX_KERNEL_SIZE = 2048; - -void main(void) -{ - vec4 color = texture2D(uSampler, vTextureCoord); - - if (uKernelSize == 0) - { - gl_FragColor = color; - return; - } - - float aspect = filterArea.y / filterArea.x; - vec2 center = uCenter.xy / filterArea.xy; - float gradient = uRadius / filterArea.x * 0.3; - float radius = uRadius / filterArea.x - gradient * 0.5; - int k = uKernelSize - 1; - - vec2 coord = vTextureCoord; - vec2 dir = vec2(center - coord); - float dist = length(vec2(dir.x, dir.y * aspect)); - - float radianStep = uRadian; - if (radius >= 0.0 && dist > radius) { - float delta = dist - radius; - float gap = gradient; - float scale = 1.0 - abs(delta / gap); - if (scale <= 0.0) { - gl_FragColor = color; - return; - } - radianStep *= scale; - } - radianStep /= float(k); - - float s = sin(radianStep); - float c = cos(radianStep); - mat2 rotationMatrix = mat2(vec2(c, -s), vec2(s, c)); - - for(int i = 0; i < MAX_KERNEL_SIZE - 1; i++) { - if (i == k) { - break; - } - - coord -= center; - coord.y *= aspect; - coord = rotationMatrix * coord; - coord.y /= aspect; - coord += center; - - vec4 sample = texture2D(uSampler, coord); - - // switch to pre-multiplied alpha to correctly blur transparent images - // sample.rgb *= sample.a; - - color += sample; - } - - gl_FragColor = color / float(uKernelSize); -} -`;class gt extends o.Filter{constructor(e=0,r=[0,0],i=5,s=-1){super(mt,vt),this._angle=0,this.angle=e,this.center=r,this.kernelSize=i,this.radius=s}apply(e,r,i,s){this.uniforms.uKernelSize=this._angle!==0?this.kernelSize:0,e.applyFilter(this,r,i,s)}set angle(e){this._angle=e,this.uniforms.uRadian=e*Math.PI/180}get angle(){return this._angle}get center(){return this.uniforms.uCenter}set center(e){this.uniforms.uCenter=e}get radius(){return this.uniforms.uRadius}set radius(e){(e<0||e===1/0)&&(e=-1),this.uniforms.uRadius=e}}var xt=`attribute vec2 aVertexPosition; -attribute vec2 aTextureCoord; - -uniform mat3 projectionMatrix; - -varying vec2 vTextureCoord; - -void main(void) -{ - gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0); - vTextureCoord = aTextureCoord; -}`,pt=`varying vec2 vTextureCoord; -uniform sampler2D uSampler; - -uniform vec4 filterArea; -uniform vec4 filterClamp; -uniform vec2 dimensions; - -uniform bool mirror; -uniform float boundary; -uniform vec2 amplitude; -uniform vec2 waveLength; -uniform vec2 alpha; -uniform float time; - -float rand(vec2 co) { - return fract(sin(dot(co.xy, vec2(12.9898, 78.233))) * 43758.5453); -} - -void main(void) -{ - vec2 pixelCoord = vTextureCoord.xy * filterArea.xy; - vec2 coord = pixelCoord / dimensions; - - if (coord.y < boundary) { - gl_FragColor = texture2D(uSampler, vTextureCoord); - return; - } - - float k = (coord.y - boundary) / (1. - boundary + 0.0001); - float areaY = boundary * dimensions.y / filterArea.y; - float v = areaY + areaY - vTextureCoord.y; - float y = mirror ? v : vTextureCoord.y; - - float _amplitude = ((amplitude.y - amplitude.x) * k + amplitude.x ) / filterArea.x; - float _waveLength = ((waveLength.y - waveLength.x) * k + waveLength.x) / filterArea.y; - float _alpha = (alpha.y - alpha.x) * k + alpha.x; - - float x = vTextureCoord.x + cos(v * 6.28 / _waveLength - time) * _amplitude; - x = clamp(x, filterClamp.x, filterClamp.z); - - vec4 color = texture2D(uSampler, vec2(x, y)); - - gl_FragColor = color * _alpha; -} -`;const V=class extends o.Filter{constructor(t){super(xt,pt),this.time=0,this.uniforms.amplitude=new Float32Array(2),this.uniforms.waveLength=new Float32Array(2),this.uniforms.alpha=new Float32Array(2),this.uniforms.dimensions=new Float32Array(2),Object.assign(this,V.defaults,t)}apply(t,e,r,i){var s,a;this.uniforms.dimensions[0]=(s=e.filterFrame)==null?void 0:s.width,this.uniforms.dimensions[1]=(a=e.filterFrame)==null?void 0:a.height,this.uniforms.time=this.time,t.applyFilter(this,e,r,i)}set mirror(t){this.uniforms.mirror=t}get mirror(){return this.uniforms.mirror}set boundary(t){this.uniforms.boundary=t}get boundary(){return this.uniforms.boundary}set amplitude(t){this.uniforms.amplitude[0]=t[0],this.uniforms.amplitude[1]=t[1]}get amplitude(){return this.uniforms.amplitude}set waveLength(t){this.uniforms.waveLength[0]=t[0],this.uniforms.waveLength[1]=t[1]}get waveLength(){return this.uniforms.waveLength}set alpha(t){this.uniforms.alpha[0]=t[0],this.uniforms.alpha[1]=t[1]}get alpha(){return this.uniforms.alpha}};let N=V;N.defaults={mirror:!0,boundary:.5,amplitude:[0,20],waveLength:[30,100],alpha:[1,1],time:0};var yt=`attribute vec2 aVertexPosition; -attribute vec2 aTextureCoord; - -uniform mat3 projectionMatrix; - -varying vec2 vTextureCoord; - -void main(void) -{ - gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0); - vTextureCoord = aTextureCoord; -}`,Ct=`precision mediump float; - -varying vec2 vTextureCoord; - -uniform sampler2D uSampler; -uniform vec4 filterArea; -uniform vec2 red; -uniform vec2 green; -uniform vec2 blue; - -void main(void) -{ - gl_FragColor.r = texture2D(uSampler, vTextureCoord + red/filterArea.xy).r; - gl_FragColor.g = texture2D(uSampler, vTextureCoord + green/filterArea.xy).g; - gl_FragColor.b = texture2D(uSampler, vTextureCoord + blue/filterArea.xy).b; - gl_FragColor.a = texture2D(uSampler, vTextureCoord).a; -} -`;class _t extends o.Filter{constructor(e=[-10,0],r=[0,10],i=[0,0]){super(yt,Ct),this.red=e,this.green=r,this.blue=i}get red(){return this.uniforms.red}set red(e){this.uniforms.red=e}get green(){return this.uniforms.green}set green(e){this.uniforms.green=e}get blue(){return this.uniforms.blue}set blue(e){this.uniforms.blue=e}}var bt=`attribute vec2 aVertexPosition; -attribute vec2 aTextureCoord; - -uniform mat3 projectionMatrix; - -varying vec2 vTextureCoord; - -void main(void) -{ - gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0); - vTextureCoord = aTextureCoord; -}`,St=`varying vec2 vTextureCoord; -uniform sampler2D uSampler; -uniform vec4 filterArea; -uniform vec4 filterClamp; - -uniform vec2 center; - -uniform float amplitude; -uniform float wavelength; -// uniform float power; -uniform float brightness; -uniform float speed; -uniform float radius; - -uniform float time; - -const float PI = 3.14159; - -void main() -{ - float halfWavelength = wavelength * 0.5 / filterArea.x; - float maxRadius = radius / filterArea.x; - float currentRadius = time * speed / filterArea.x; - - float fade = 1.0; - - if (maxRadius > 0.0) { - if (currentRadius > maxRadius) { - gl_FragColor = texture2D(uSampler, vTextureCoord); - return; - } - fade = 1.0 - pow(currentRadius / maxRadius, 2.0); - } - - vec2 dir = vec2(vTextureCoord - center / filterArea.xy); - dir.y *= filterArea.y / filterArea.x; - float dist = length(dir); - - if (dist <= 0.0 || dist < currentRadius - halfWavelength || dist > currentRadius + halfWavelength) { - gl_FragColor = texture2D(uSampler, vTextureCoord); - return; - } - - vec2 diffUV = normalize(dir); - - float diff = (dist - currentRadius) / halfWavelength; - - float p = 1.0 - pow(abs(diff), 2.0); - - // float powDiff = diff * pow(p, 2.0) * ( amplitude * fade ); - float powDiff = 1.25 * sin(diff * PI) * p * ( amplitude * fade ); - - vec2 offset = diffUV * powDiff / filterArea.xy; - - // Do clamp : - vec2 coord = vTextureCoord + offset; - vec2 clampedCoord = clamp(coord, filterClamp.xy, filterClamp.zw); - vec4 color = texture2D(uSampler, clampedCoord); - if (coord != clampedCoord) { - color *= max(0.0, 1.0 - length(coord - clampedCoord)); - } - - // No clamp : - // gl_FragColor = texture2D(uSampler, vTextureCoord + offset); - - color.rgb *= 1.0 + (brightness - 1.0) * p * fade; - - gl_FragColor = color; -} -`;const B=class extends o.Filter{constructor(t=[0,0],e,r=0){super(bt,St),this.center=t,Object.assign(this,B.defaults,e),this.time=r}apply(t,e,r,i){this.uniforms.time=this.time,t.applyFilter(this,e,r,i)}get center(){return this.uniforms.center}set center(t){this.uniforms.center=t}get amplitude(){return this.uniforms.amplitude}set amplitude(t){this.uniforms.amplitude=t}get wavelength(){return this.uniforms.wavelength}set wavelength(t){this.uniforms.wavelength=t}get brightness(){return this.uniforms.brightness}set brightness(t){this.uniforms.brightness=t}get speed(){return this.uniforms.speed}set speed(t){this.uniforms.speed=t}get radius(){return this.uniforms.radius}set radius(t){this.uniforms.radius=t}};let X=B;X.defaults={amplitude:30,wavelength:160,brightness:1,speed:500,radius:-1};var Tt=`attribute vec2 aVertexPosition; -attribute vec2 aTextureCoord; - -uniform mat3 projectionMatrix; - -varying vec2 vTextureCoord; - -void main(void) -{ - gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0); - vTextureCoord = aTextureCoord; -}`,Ft=`varying vec2 vTextureCoord; -uniform sampler2D uSampler; -uniform sampler2D uLightmap; -uniform vec4 filterArea; -uniform vec2 dimensions; -uniform vec4 ambientColor; -void main() { - vec4 diffuseColor = texture2D(uSampler, vTextureCoord); - vec2 lightCoord = (vTextureCoord * filterArea.xy) / dimensions; - vec4 light = texture2D(uLightmap, lightCoord); - vec3 ambient = ambientColor.rgb * ambientColor.a; - vec3 intensity = ambient + light.rgb; - vec3 finalColor = diffuseColor.rgb * intensity; - gl_FragColor = vec4(finalColor, diffuseColor.a); -} -`;class zt extends o.Filter{constructor(e,r=0,i=1){super(Tt,Ft),this._color=0,this.uniforms.dimensions=new Float32Array(2),this.uniforms.ambientColor=new Float32Array([0,0,0,i]),this.texture=e,this.color=r}apply(e,r,i,s){var a,l;this.uniforms.dimensions[0]=(a=r.filterFrame)==null?void 0:a.width,this.uniforms.dimensions[1]=(l=r.filterFrame)==null?void 0:l.height,e.applyFilter(this,r,i,s)}get texture(){return this.uniforms.uLightmap}set texture(e){this.uniforms.uLightmap=e}set color(e){const r=this.uniforms.ambientColor;typeof e=="number"?(o.utils.hex2rgb(e,r),this._color=e):(r[0]=e[0],r[1]=e[1],r[2]=e[2],r[3]=e[3],this._color=o.utils.rgb2hex(r))}get color(){return this._color}get alpha(){return this.uniforms.ambientColor[3]}set alpha(e){this.uniforms.ambientColor[3]=e}}var At=`attribute vec2 aVertexPosition; -attribute vec2 aTextureCoord; - -uniform mat3 projectionMatrix; - -varying vec2 vTextureCoord; - -void main(void) -{ - gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0); - vTextureCoord = aTextureCoord; -}`,Pt=`varying vec2 vTextureCoord; - -uniform sampler2D uSampler; -uniform float blur; -uniform float gradientBlur; -uniform vec2 start; -uniform vec2 end; -uniform vec2 delta; -uniform vec2 texSize; - -float random(vec3 scale, float seed) -{ - return fract(sin(dot(gl_FragCoord.xyz + seed, scale)) * 43758.5453 + seed); -} - -void main(void) -{ - vec4 color = vec4(0.0); - float total = 0.0; - - float offset = random(vec3(12.9898, 78.233, 151.7182), 0.0); - vec2 normal = normalize(vec2(start.y - end.y, end.x - start.x)); - float radius = smoothstep(0.0, 1.0, abs(dot(vTextureCoord * texSize - start, normal)) / gradientBlur) * blur; - - for (float t = -30.0; t <= 30.0; t++) - { - float percent = (t + offset - 0.5) / 30.0; - float weight = 1.0 - abs(percent); - vec4 sample = texture2D(uSampler, vTextureCoord + delta / texSize * percent * radius); - sample.rgb *= sample.a; - color += sample * weight; - total += weight; - } - - color /= total; - color.rgb /= color.a + 0.00001; - - gl_FragColor = color; -} -`;class C extends o.Filter{constructor(e=100,r=600,i,s){super(At,Pt),this.uniforms.blur=e,this.uniforms.gradientBlur=r,this.uniforms.start=i||new o.Point(0,window.innerHeight/2),this.uniforms.end=s||new o.Point(600,window.innerHeight/2),this.uniforms.delta=new o.Point(30,30),this.uniforms.texSize=new o.Point(window.innerWidth,window.innerHeight),this.updateDelta()}updateDelta(){this.uniforms.delta.x=0,this.uniforms.delta.y=0}get blur(){return this.uniforms.blur}set blur(e){this.uniforms.blur=e}get gradientBlur(){return this.uniforms.gradientBlur}set gradientBlur(e){this.uniforms.gradientBlur=e}get start(){return this.uniforms.start}set start(e){this.uniforms.start=e,this.updateDelta()}get end(){return this.uniforms.end}set end(e){this.uniforms.end=e,this.updateDelta()}}class G extends C{updateDelta(){const e=this.uniforms.end.x-this.uniforms.start.x,r=this.uniforms.end.y-this.uniforms.start.y,i=Math.sqrt(e*e+r*r);this.uniforms.delta.x=e/i,this.uniforms.delta.y=r/i}}class q extends C{updateDelta(){const e=this.uniforms.end.x-this.uniforms.start.x,r=this.uniforms.end.y-this.uniforms.start.y,i=Math.sqrt(e*e+r*r);this.uniforms.delta.x=-r/i,this.uniforms.delta.y=e/i}}class wt extends o.Filter{constructor(e=100,r=600,i,s){super(),this.tiltShiftXFilter=new G(e,r,i,s),this.tiltShiftYFilter=new q(e,r,i,s)}apply(e,r,i,s){const a=e.getFilterTexture();this.tiltShiftXFilter.apply(e,r,a,1),this.tiltShiftYFilter.apply(e,a,i,s),e.returnFilterTexture(a)}get blur(){return this.tiltShiftXFilter.blur}set blur(e){this.tiltShiftXFilter.blur=this.tiltShiftYFilter.blur=e}get gradientBlur(){return this.tiltShiftXFilter.gradientBlur}set gradientBlur(e){this.tiltShiftXFilter.gradientBlur=this.tiltShiftYFilter.gradientBlur=e}get start(){return this.tiltShiftXFilter.start}set start(e){this.tiltShiftXFilter.start=this.tiltShiftYFilter.start=e}get end(){return this.tiltShiftXFilter.end}set end(e){this.tiltShiftXFilter.end=this.tiltShiftYFilter.end=e}}var Mt=`attribute vec2 aVertexPosition; -attribute vec2 aTextureCoord; - -uniform mat3 projectionMatrix; - -varying vec2 vTextureCoord; - -void main(void) -{ - gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0); - vTextureCoord = aTextureCoord; -}`,Dt=`varying vec2 vTextureCoord; - -uniform sampler2D uSampler; -uniform float radius; -uniform float angle; -uniform vec2 offset; -uniform vec4 filterArea; - -vec2 mapCoord( vec2 coord ) -{ - coord *= filterArea.xy; - coord += filterArea.zw; - - return coord; -} - -vec2 unmapCoord( vec2 coord ) -{ - coord -= filterArea.zw; - coord /= filterArea.xy; - - return coord; -} - -vec2 twist(vec2 coord) -{ - coord -= offset; - - float dist = length(coord); - - if (dist < radius) - { - float ratioDist = (radius - dist) / radius; - float angleMod = ratioDist * ratioDist * angle; - float s = sin(angleMod); - float c = cos(angleMod); - coord = vec2(coord.x * c - coord.y * s, coord.x * s + coord.y * c); - } - - coord += offset; - - return coord; -} - -void main(void) -{ - - vec2 coord = mapCoord(vTextureCoord); - - coord = twist(coord); - - coord = unmapCoord(coord); - - gl_FragColor = texture2D(uSampler, coord ); - -} -`;const K=class extends o.Filter{constructor(t){super(Mt,Dt),Object.assign(this,K.defaults,t)}get offset(){return this.uniforms.offset}set offset(t){this.uniforms.offset=t}get radius(){return this.uniforms.radius}set radius(t){this.uniforms.radius=t}get angle(){return this.uniforms.angle}set angle(t){this.uniforms.angle=t}};let W=K;W.defaults={radius:200,angle:4,padding:20,offset:new o.Point};var Ot=`attribute vec2 aVertexPosition; -attribute vec2 aTextureCoord; - -uniform mat3 projectionMatrix; - -varying vec2 vTextureCoord; - -void main(void) -{ - gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0); - vTextureCoord = aTextureCoord; -}`,Rt=`varying vec2 vTextureCoord; -uniform sampler2D uSampler; -uniform vec4 filterArea; - -uniform vec2 uCenter; -uniform float uStrength; -uniform float uInnerRadius; -uniform float uRadius; - -const float MAX_KERNEL_SIZE = \${maxKernelSize}; - -// author: http://byteblacksmith.com/improvements-to-the-canonical-one-liner-glsl-rand-for-opengl-es-2-0/ -highp float rand(vec2 co, float seed) { - const highp float a = 12.9898, b = 78.233, c = 43758.5453; - highp float dt = dot(co + seed, vec2(a, b)), sn = mod(dt, 3.14159); - return fract(sin(sn) * c + seed); -} - -void main() { - - float minGradient = uInnerRadius * 0.3; - float innerRadius = (uInnerRadius + minGradient * 0.5) / filterArea.x; - - float gradient = uRadius * 0.3; - float radius = (uRadius - gradient * 0.5) / filterArea.x; - - float countLimit = MAX_KERNEL_SIZE; - - vec2 dir = vec2(uCenter.xy / filterArea.xy - vTextureCoord); - float dist = length(vec2(dir.x, dir.y * filterArea.y / filterArea.x)); - - float strength = uStrength; - - float delta = 0.0; - float gap; - if (dist < innerRadius) { - delta = innerRadius - dist; - gap = minGradient; - } else if (radius >= 0.0 && dist > radius) { // radius < 0 means it's infinity - delta = dist - radius; - gap = gradient; - } - - if (delta > 0.0) { - float normalCount = gap / filterArea.x; - delta = (normalCount - delta) / normalCount; - countLimit *= delta; - strength *= delta; - if (countLimit < 1.0) - { - gl_FragColor = texture2D(uSampler, vTextureCoord); - return; - } - } - - // randomize the lookup values to hide the fixed number of samples - float offset = rand(vTextureCoord, 0.0); - - float total = 0.0; - vec4 color = vec4(0.0); - - dir *= strength; - - for (float t = 0.0; t < MAX_KERNEL_SIZE; t++) { - float percent = (t + offset) / MAX_KERNEL_SIZE; - float weight = 4.0 * (percent - percent * percent); - vec2 p = vTextureCoord + dir * percent; - vec4 sample = texture2D(uSampler, p); - - // switch to pre-multiplied alpha to correctly blur transparent images - // sample.rgb *= sample.a; - - color += sample * weight; - total += weight; - - if (t > countLimit){ - break; - } - } - - color /= total; - // switch back from pre-multiplied alpha - // color.rgb /= color.a + 0.00001; - - gl_FragColor = color; -} -`,Y=Object.getOwnPropertySymbols,$t=Object.prototype.hasOwnProperty,Et=Object.prototype.propertyIsEnumerable,kt=(t,e)=>{var r={};for(var i in t)$t.call(t,i)&&e.indexOf(i)<0&&(r[i]=t[i]);if(t!=null&&Y)for(var i of Y(t))e.indexOf(i)<0&&Et.call(t,i)&&(r[i]=t[i]);return r};const Z=class extends o.Filter{constructor(t){const e=Object.assign(Z.defaults,t),{maxKernelSize:r}=e,i=kt(e,["maxKernelSize"]);super(Ot,Rt.replace("${maxKernelSize}",r.toFixed(1))),Object.assign(this,i)}get center(){return this.uniforms.uCenter}set center(t){this.uniforms.uCenter=t}get strength(){return this.uniforms.uStrength}set strength(t){this.uniforms.uStrength=t}get innerRadius(){return this.uniforms.uInnerRadius}set innerRadius(t){this.uniforms.uInnerRadius=t}get radius(){return this.uniforms.uRadius}set radius(t){(t<0||t===1/0)&&(t=-1),this.uniforms.uRadius=t}};let U=Z;return U.defaults={strength:.1,center:[0,0],innerRadius:0,radius:-1,maxKernelSize:32},n.AdjustmentFilter=te,n.AdvancedBloomFilter=F,n.AsciiFilter=ce,n.BevelFilter=he,n.BloomFilter=me,n.BulgePinchFilter=A,n.CRTFilter=w,n.ColorMapFilter=ye,n.ColorOverlayFilter=be,n.ColorReplaceFilter=Fe,n.ConvolutionFilter=Pe,n.CrossHatchFilter=De,n.DotFilter=ke,n.DropShadowFilter=R,n.EmbossFilter=Ge,n.GlitchFilter=f,n.GlowFilter=E,n.GodrayFilter=j,n.GrayscaleFilter=et,n.KawaseBlurFilter=h,n.MotionBlurFilter=it,n.MultiColorReplaceFilter=at,n.OldFilmFilter=I,n.OutlineFilter=y,n.PixelateFilter=ht,n.RGBSplitFilter=_t,n.RadialBlurFilter=gt,n.ReflectionFilter=N,n.ShockwaveFilter=X,n.SimpleLightmapFilter=zt,n.TiltShiftAxisFilter=C,n.TiltShiftFilter=wt,n.TiltShiftXFilter=G,n.TiltShiftYFilter=q,n.TwistFilter=W,n.ZoomBlurFilter=U,Object.defineProperty(n,"__esModule",{value:!0}),n}({},PIXI,PIXI.filters,PIXI.filters);Object.assign(PIXI.filters,__filters); -//# sourceMappingURL=pixi-filters.js.map diff --git a/tokenmagic/migration/migration.js b/tokenmagic/migration/migration.js deleted file mode 100644 index 4a39b03..0000000 --- a/tokenmagic/migration/migration.js +++ /dev/null @@ -1,176 +0,0 @@ -import { TokenMagic, isTheOne, log, warn, error } from '../module/tokenmagic.js'; -import { PresetsLibrary, templatePresets } from '../fx/presets/defaultpresets.js'; - -const Magic = TokenMagic(); - -// TODO create a generic function to import JSON by version - -export const DataVersion = { - ARCHAIC: '', - V030: '0.3.0', - V040: '0.4.0', - V040b: '0.4.0b', - V041: '0.4.1', - V043: '0.4.3', -}; - -// migration function - will evolve constantly -export async function tmfxDataMigration() { - if (isTheOne()) { - var dataVersionNow; - try { - dataVersionNow = game.settings.get('tokenmagic', 'migration'); - } catch (e) { - dataVersionNow = DataVersion.ARCHAIC; - } - if (dataVersionNow < DataVersion.V030) { - await updatePresetsV030(); - } - if (dataVersionNow < DataVersion.V040) { - await updatePresetsV040(); - } - if (dataVersionNow < DataVersion.V040b) { - await updatePresetsV040b(); - } - if (dataVersionNow < DataVersion.V041) { - await updatePresetsV041(); - } - if (dataVersionNow < DataVersion.V043) { - await updatePresetsV043(); - } - } -} - -// migrating to the new presets data -async function updatePresetsV030() { - var presets = game.settings.get('tokenmagic', 'presets'); - - if (!(presets == null)) { - log(`Migration 0.3.0 - Launching presets data migration...`); - - let foundTemplateLibrary = false; - - for (const preset of presets) { - if (!preset.hasOwnProperty('library')) { - preset.library = PresetsLibrary.MAIN; - log(`Migration 0.3.0 - Adding ${preset.name} to ${PresetsLibrary.MAIN}`); - } else if (preset.library === PresetsLibrary.TEMPLATE && !foundTemplateLibrary) { - foundTemplateLibrary = true; - log(`Migration 0.3.0 - Found template presets. Templates will not be added.`); - } - } - - if (!foundTemplateLibrary) log(`Migration 0.3.0 - Merging templates presets.`); - - let newPresets = foundTemplateLibrary ? presets : presets.concat(templatePresets); - - try { - await game.settings.set('tokenmagic', 'presets', newPresets); - await game.settings.set('tokenmagic', 'migration', DataVersion.V030); - log(`Migration 0.3.0 - Migration successful!`); - } catch (e) { - error(`Migration 0.3.0 - Migration failed.`); - error(e); - } - } -} - -async function updatePresetsV040() { - var presets = game.settings.get('tokenmagic', 'presets'); - - if (!(presets == null)) { - log(`Migration 0.4.0 - Launching presets data migration...`); - - // Adding zOrder for the template presets only - // Does not break visuals - for (const preset of presets) { - if (preset.library === PresetsLibrary.TEMPLATE) { - log(`Migration 0.4.0 - Checking template preset ${preset.name}...`); - let zOrder = 1; - for (const filter of preset.params) { - if (!filter.hasOwnProperty('zOrder')) { - filter.zOrder = zOrder; - log(`Migration 0.4.0 - Updating ${filter.filterType} in ${preset.name}...`); - zOrder++; - } - } - } - } - - try { - await game.settings.set('tokenmagic', 'presets', presets); - log(`Migration 0.4.0 - Importing new template presets...`); - await Magic.importPresetLibraryFromPath('modules/tokenmagic/import/TMFX-update-presets-v040.json', { - overwrite: false, - }); - await game.settings.set('tokenmagic', 'migration', DataVersion.V040); - log(`Migration 0.4.0 - Migration successful!`); - } catch (e) { - error(`Migration 0.4.0 - Migration failed.`); - error(e); - } - } -} - -async function updatePresetsV040b() { - var presets = game.settings.get('tokenmagic', 'presets'); - - if (!(presets == null)) { - log(`Migration 0.4.0b - Launching presets data migration...`); - - try { - await game.settings.set('tokenmagic', 'presets', presets); - log(`Migration 0.4.0b - updating template presets...`); - await Magic.importPresetLibraryFromPath('modules/tokenmagic/import/TMFX-update-presets-v040b.json', { - overwrite: true, - }); - await game.settings.set('tokenmagic', 'migration', DataVersion.V040b); - log(`Migration 0.4.0b - Migration successful!`); - } catch (e) { - error(`Migration 0.4.0b - Migration failed.`); - error(e); - } - } -} - -async function updatePresetsV041() { - var presets = game.settings.get('tokenmagic', 'presets'); - - if (!(presets == null)) { - log(`Migration 0.4.1 - Launching presets data migration...`); - - try { - await game.settings.set('tokenmagic', 'presets', presets); - log(`Migration 0.4.1 - updating template presets...`); - await Magic.importPresetLibraryFromPath('modules/tokenmagic/import/TMFX-update-presets-v041.json', { - overwrite: true, - }); - await game.settings.set('tokenmagic', 'migration', DataVersion.V041); - log(`Migration 0.4.1 - Migration successful!`); - } catch (e) { - error(`Migration 0.4.1 - Migration failed.`); - error(e); - } - } -} - -async function updatePresetsV043() { - var presets = game.settings.get('tokenmagic', 'presets'); - - if (!(presets == null)) { - log(`Migration 0.4.3 - Launching presets data migration...`); - - try { - await game.settings.set('tokenmagic', 'presets', presets); - log(`Migration 0.4.3 - updating template presets...`); - await Magic.importPresetLibraryFromPath('modules/tokenmagic/import/TMFX-update-presets-v043.json', { - overwrite: true, - }); - await game.settings.set('tokenmagic', 'migration', DataVersion.V043); - log(`Migration 0.4.3 - Migration successful!`); - } catch (e) { - error(`Migration 0.4.3 - Migration failed.`); - error(e); - } - } -} diff --git a/tokenmagic/module.json b/tokenmagic/module.json deleted file mode 100644 index f404493..0000000 --- a/tokenmagic/module.json +++ /dev/null @@ -1,127 +0,0 @@ -{ - "id": "tokenmagic", - "title": "Token Magic FX", - "description": "

    Add special effects and animations on your tokens, tiles, drawings and templates.

    ", - "version": "0.6.5.0", - "compatibility": { - "minimum": "11", - "verified": "11.304" - }, - "authors": [ - { - "name": "SecretFire", - "flags": {} - }, - { - "name": "sPOiDar", - "flags": {} - }, - { - "name": "Zimm", - "flags": {} - }, - { - "name": "Lozalojo", - "flags": {} - }, - { - "name": "Moerill", - "flags": {} - }, - { - "name": "KLO", - "flags": {} - }, - { - "name": "dev7355608", - "flags": {} - }, - { - "name": "Mestre Digital", - "flags": {} - }, - { - "name": "BrotherSharper-Touge", - "flags": {} - }, - { - "name": "OsiJr", - "flags": {} - } - ], - "scripts": ["libs/filters/pixi-filters.js"], - "esmodules": ["module/tokenmagicBundle.js"], - "styles": ["styles/tokenmagic.css"], - "packs": [ - { - "name": "tmMacros", - "label": "TokenMagic Portfolio", - "path": "packs/token-magic-portfolio", - "type": "Macro", - "private": false, - "flags": {} - }, - { - "name": "tmSampleCompendium", - "label": "TokenMagic Book of Fire", - "path": "packs/token-magic-book-of-fire", - "type": "Macro", - "private": false, - "flags": {} - } - ], - "languages": [ - { - "lang": "en", - "name": "English", - "path": "lang/en.json", - "flags": {} - }, - { - "lang": "ru", - "name": "Russian", - "path": "lang/ru.json", - "flags": {} - }, - { - "lang": "fr", - "name": "French (FRANCE)", - "path": "lang/fr.json", - "flags": {} - }, - { - "lang": "pt-BR", - "name": "Português (Brasil)", - "path": "lang/pt-BR.json", - "flags": {} - }, - { - "lang": "es", - "name": "Spanish", - "path": "lang/es.json", - "flags": {} - }, - { - "lang": "ko", - "name": "Korean", - "path": "lang/ko.json", - "flags": {} - }, - { - "lang": "zh-tw", - "name": "正體中文", - "path": "lang/zh-tw.json", - "flags": {} - }, - { - "lang": "ja", - "name": "日本語", - "path": "lang/ja.json", - "flags": {} - } - ], - "socket": true, - "url": "https://github.com/Feu-Secret/Tokenmagic", - "manifest": "https://raw.githubusercontent.com/Feu-Secret/Tokenmagic/master/tokenmagic/module.json", - "download": "https://github.com/Feu-Secret/Tokenmagic/releases/download/v0.6.5.0-beta/tokenmagic.zip" -} diff --git a/tokenmagic/module/autoTemplate/TheWitcherTRPG.js b/tokenmagic/module/autoTemplate/TheWitcherTRPG.js deleted file mode 100644 index e6cef6d..0000000 --- a/tokenmagic/module/autoTemplate/TheWitcherTRPG.js +++ /dev/null @@ -1,151 +0,0 @@ -import { defaultOpacity, emptyPreset } from '../constants.js'; - -export class AutoTemplateTheWitcherTRPG { - static get defaultConfiguration() { - const defaultConfig = { - categories: {}, - overrides: { - 0: { - target: 'Игни', - opacity: 0.5, - tint: '#00a80b', - preset: 'Flames', - texture: null, - }, - }, - }; - - Object.keys(CONFIG.witcher.meleeSkills).forEach((meleeSkillType) => { - if (defaultConfig.categories[meleeSkillType] == undefined) { - const config = { opacity: defaultOpacity, tint: null }; - switch (meleeSkillType.toLowerCase()) { - case 'brawling': - config.tint = '#2d8000'; - config.opacity = 0.6; - break; - case 'melee': - config.tint = '#47b3ff'; - break; - case 'small blades': - config.tint = '#502673'; - break; - case 'staff/spear': - config.tint = '#00a80b'; - break; - case 'swordsmanship': - config.tint = '#8000ff'; - break; - case 'athletics': - config.tint = '#0060ff'; - break; - default: - break; - } - defaultConfig.categories[meleeSkillType] = config; - } - Object.keys(CONFIG.MeasuredTemplate.types).forEach((tplType) => { - const config = { preset: emptyPreset, texture: null }; - switch (meleeSkillType.toLowerCase()) { - case 'acid': - config.preset = 'slashing'; - break; - case 'cold': - config.preset = 'bludgeoning'; - break; - case 'fire': - config.preset = 'piercing'; - break; - case 'force': - config.preset = 'elemental'; - break; - default: - break; - } - defaultConfig.categories[meleeSkillType][tplType] = config; - }); - }); - - return defaultConfig; - } - - constructor() { - this._enabled = false; - } - - get enabled() { - return this._enabled; - } - - configure(enabled = false) { - if (game.system.id !== 'TheWitcherTRPG') return; - this._enabled = enabled; - } - - getData() { - return { - hasAutoTemplates: true, - meleeSkills: CONFIG.witcher.meleeSkills, - templateTypes: CONFIG.MeasuredTemplate.types, - }; - } - - preCreateMeasuredTemplate(template) { - let hasPreset = template.hasOwnProperty('tmfxPreset'); - if (hasPreset) { - return template; - } - const settings = game.settings.get('tokenmagic', 'autoTemplateSettings'); - let updated = settings.overrides ? fromOverrides(Object.values(settings.overrides), template) : false; - if (!updated) { - fromCategories(settings.categories, template); - } - } -} - -function fromConfig(config, templateData) { - const o = { tokenmagic: { options: {} } }; - if (config.preset && config.preset !== '' && config.preset !== emptyPreset) { - o.tokenmagic.options.tmfxPreset = config.preset; - } - if (config.texture && config.texture !== '') { - o.tokenmagic.options.tmfxTexture = config.texture; - } - if (config.tint && config.tint !== '') { - o.tokenmagic.options.tmfxTint = config.tint; - } - o.tokenmagic.options.tmfxTextureAlpha = config.opacity; - mergeObject(templateData, { 'flags.tokenmagic': o.tokenmagic }); -} - -function fromOverrides(overrides = [], templateData) { - const name = templateData.flags.witcher?.origin?.name; - let config = overrides.find((el) => el.target.toLowerCase() === name?.toLowerCase()); - if (!config) { - return false; - } - fromConfig(config, templateData); - return true; -} - -function fromCategories(categories = {}, templateData) { - const traits = templateData.flags.witcher?.origin?.traits ?? []; - - let config, dmgSettings; - for (const trait of traits) { - dmgSettings = categories[trait] || {}; - config = dmgSettings[templateData.t]; - - if (config && config.preset !== emptyPreset) { - break; - } - } - - if (!config) { - return false; - } - - fromConfig(mergeObject(config, { opacity: dmgSettings.opacity, tint: dmgSettings.tint }, true, true), templateData); - return true; -} - -export const witcherTemplates = new AutoTemplateTheWitcherTRPG(); diff --git a/tokenmagic/module/autoTemplate/dnd5e.js b/tokenmagic/module/autoTemplate/dnd5e.js deleted file mode 100644 index 2a76e22..0000000 --- a/tokenmagic/module/autoTemplate/dnd5e.js +++ /dev/null @@ -1,206 +0,0 @@ -import { defaultOpacity, emptyPreset } from '../constants.js'; - -export class AutoTemplateDND5E { - static get defaultConfiguration() { - const defaultConfig = { - categories: {}, - overrides: { - 0: { - target: 'Stinking Cloud', - opacity: 0.5, - tint: '#00a80b', - preset: 'Smoky Area', - texture: null, - }, - 1: { - target: 'Web', - opacity: 0.5, - tint: '#808080', - preset: 'Spider Web 2', - texture: null, - }, - }, - }; - - Object.keys(CONFIG.DND5E.damageTypes).forEach((dmgType) => { - if (defaultConfig.categories[dmgType] == undefined) { - const config = { opacity: defaultOpacity, tint: null }; - switch (dmgType.toLowerCase()) { - case 'acid': - config.tint = '#2d8000'; - config.opacity = 0.6; - break; - case 'cold': - config.tint = '#47b3ff'; - break; - case 'necrotic': - config.tint = '#502673'; - break; - case 'poison': - config.tint = '#00a80b'; - break; - case 'psychic': - config.tint = '#8000ff'; - break; - case 'thunder': - config.tint = '#0060ff'; - break; - default: - break; - } - defaultConfig.categories[dmgType] = config; - } - Object.keys(CONFIG.MeasuredTemplate.types).forEach((tplType) => { - const config = { preset: emptyPreset, texture: null }; - switch (dmgType.toLowerCase()) { - case 'acid': - config.preset = 'Watery Surface 2'; - break; - case 'cold': - config.preset = 'Thick Fog'; - break; - case 'fire': - config.preset = 'Flames'; - break; - case 'force': - config.preset = 'Waves 3'; - break; - case 'lightning': - config.preset = 'Shock'; - break; - case 'necrotic': - config.preset = 'Smoke Filaments'; - break; - case 'poison': - config.preset = 'Smoky Area'; - break; - case 'psychic': - config.preset = 'Classic Rays'; - break; - case 'radiant': - config.preset = 'Annihilating Rays'; - break; - case 'thunder': - config.preset = 'Waves'; - break; - default: - break; - } - defaultConfig.categories[dmgType][tplType] = config; - }); - }); - - return defaultConfig; - } - - constructor() { - this._enabled = false; - } - - get enabled() { - return this._enabled; - } - - configure(enabled = false) { - if (game.system.id !== 'dnd5e') return; - - if (!enabled) { - if (this._enabled) { - if (game.modules.get('lib-wrapper')?.active) { - libWrapper.unregister('tokenmagic', 'game.dnd5e.canvas.AbilityTemplate.fromItem'); - } else { - window.location.reload(); - } - } - } else { - if (!this._enabled) { - if (game.modules.get('lib-wrapper')?.active) { - libWrapper.register('tokenmagic', 'game.dnd5e.canvas.AbilityTemplate.fromItem', fromItem, 'WRAPPER'); - } else { - const origFromItem = game.dnd5e.canvas.AbilityTemplate.fromItem; - game.dnd5e.canvas.AbilityTemplate.fromItem = function () { - return fromItem.call(this, origFromItem.bind(this), ...arguments); - }; - } - } - } - - this._enabled = enabled; - } - - getData() { - return { - hasAutoTemplates: true, - dmgTypes: CONFIG.DND5E.damageTypes, - templateTypes: CONFIG.MeasuredTemplate.types, - }; - } -} - -function fromConfig(config, template) { - const o = { tokenmagic: { options: {} } }; - if (config.preset && config.preset !== '' && config.preset !== emptyPreset) { - o.tokenmagic.options.tmfxPreset = config.preset; - } - if (config.texture && config.texture !== '') { - o.tokenmagic.options.tmfxTexture = config.texture; - } - if (config.tint && config.tint !== '') { - o.tokenmagic.options.tmfxTint = config.tint; - } - o.tokenmagic.options.tmfxTextureAlpha = config.opacity; - template.document.updateSource({ flags: { tokenmagic: o.tokenmagic } }); -} - -function fromOverrides(overrides = [], item, template) { - let config = overrides.find((el) => el.target.toLowerCase() === item.name.toLowerCase()); - if (!config) { - return false; - } - fromConfig(config, template); - return true; -} - -function fromCategories(categories = {}, item, template) { - if (!item.hasDamage) { - return false; - } - - let config, dmgSettings; - - // some items/spells have multiple damage types - // this loop looks over all the types until it finds one with a valid fx preset - for (const [_, dmgType] of item.data.data.damage.parts) { - dmgSettings = categories[dmgType] || {}; - config = dmgSettings[template.data.t]; - - if (config && config.preset !== emptyPreset) { - break; - } - } - if (!config) { - return false; - } - fromConfig(mergeObject(config, { opacity: dmgSettings.opacity, tint: dmgSettings.tint }, true, true), template); - return true; -} - -function fromItem(wrapped, ...args) { - const [item] = args; - const template = wrapped(...args); - if (!template) { - return template; - } - let hasPreset = template.hasOwnProperty('tmfxPreset'); - if (hasPreset) { - return template; - } - const settings = game.settings.get('tokenmagic', 'autoTemplateSettings'); - let updated = settings.overrides ? fromOverrides(Object.values(settings.overrides), item, template) : false; - if (!updated) { - fromCategories(settings.categories, item, template); - } - return template; -} - -export const dnd5eTemplates = new AutoTemplateDND5E(); diff --git a/tokenmagic/module/autoTemplate/pf2e.js b/tokenmagic/module/autoTemplate/pf2e.js deleted file mode 100644 index 12bc634..0000000 --- a/tokenmagic/module/autoTemplate/pf2e.js +++ /dev/null @@ -1,206 +0,0 @@ -import { defaultOpacity, emptyPreset } from '../constants.js'; - -export class AutoTemplatePF2E { - static get defaultConfiguration() { - const defaultConfig = { - categories: {}, - overrides: { - 0: { - target: 'Stinking Cloud', - opacity: 0.5, - tint: '#00a80b', - preset: 'Smoky Area', - texture: null, - }, - 1: { - target: 'Sanguine Mist', - opacity: 0.6, - tint: '#c41212', - preset: 'Smoky Area', - }, - 2: { - target: 'Web', - opacity: 0.5, - tint: '#808080', - preset: 'Spider Web 2', - texture: null, - }, - 3: { - target: 'Incendiary Aura', - opacity: 0.2, - tint: '#b12910', - preset: 'Smoke Filaments', - texture: null, - }, - }, - }; - - Object.keys(CONFIG.PF2E.damageTraits).forEach((dmgType) => { - if (defaultConfig.categories[dmgType] == undefined) { - const config = { opacity: defaultOpacity, tint: null }; - switch (dmgType.toLowerCase()) { - case 'acid': - config.tint = '#2d8000'; - config.opacity = 0.6; - break; - case 'cold': - config.tint = '#47b3ff'; - break; - case 'electricity': - break; - case 'fire': - break; - case 'force': - break; - case 'mental': - config.tint = '#8000ff'; - break; - case 'negative': - config.tint = '#502673'; - break; - case 'poison': - config.tint = '#00a80b'; - break; - case 'positive': - break; - case 'sonic': - config.tint = '#0060ff'; - break; - default: - break; - } - defaultConfig.categories[dmgType] = config; - } - Object.keys(CONFIG.MeasuredTemplate.types).forEach((tplType) => { - const config = { preset: emptyPreset, texture: null }; - switch (dmgType.toLowerCase()) { - case 'acid': - config.preset = 'Watery Surface 2'; - break; - case 'cold': - config.preset = 'Thick Fog'; - break; - case 'electricity': - config.preset = 'Shock'; - break; - case 'fire': - config.preset = 'Flames'; - break; - case 'force': - config.preset = 'Waves 3'; - break; - case 'mental': - config.preset = 'Classic Rays'; - break; - case 'negative': - config.preset = 'Smoke Filaments'; - break; - case 'poison': - config.preset = 'Smoky Area'; - break; - case 'positive': - config.preset = 'Annihilating Rays'; - break; - case 'sonic': - config.preset = 'Waves'; - break; - default: - break; - } - defaultConfig.categories[dmgType][tplType] = config; - }); - }); - - return defaultConfig; - } - - constructor() { - this._enabled = false; - } - - configure(enabled = false) { - if (game.system.id !== 'pf2e') return; - this._enabled = enabled; - } - - get enabled() { - return this._enabled; - } - - set enabled(value) {} - - getData() { - return { - hasAutoTemplates: true, - dmgTypes: CONFIG.PF2E.damageTraits, - templateTypes: CONFIG.MeasuredTemplate.types, - }; - } - - preCreateMeasuredTemplate(template) { - let hasPreset = template.hasOwnProperty('tmfxPreset'); - if (hasPreset) { - return template; - } - - const origin = template.flags?.pf2e?.origin; - const settings = game.settings.get('tokenmagic', 'autoTemplateSettings'); - let updated = settings.overrides ? fromOverrides(Object.values(settings.overrides), origin, template) : false; - if (!updated) { - fromCategories(settings.categories, origin, template); - } - return template; - } -} - -function fromConfig(config, template) { - const o = { tokenmagic: { options: {} } }; - if (config.preset && config.preset !== '' && config.preset !== emptyPreset) { - o.tokenmagic.options.tmfxPreset = config.preset; - } - if (config.texture && config.texture !== '') { - o.tokenmagic.options.tmfxTexture = config.texture; - } - if (config.tint && config.tint !== '') { - o.tokenmagic.options.tmfxTint = config.tint; - } - o.tokenmagic.options.tmfxTextureAlpha = config.opacity; - template.updateSource({ flags: { tokenmagic: o.tokenmagic } }); -} - -function fromOverrides(overrides = [], origin, template) { - const { name, slug } = origin; - - let config = overrides.find((el) => el.target.toLowerCase() === name?.toLowerCase()); - if (!config) { - return false; - } - fromConfig(config, template); - return true; -} - -function fromCategories(categories = {}, origin, template) { - if (!origin.traits?.length) { - return false; - } - - let config, dmgSettings; - - // some templates may have multiple traits - // this loop looks over all of them until it finds one with a valid fx preset - for (const trait of origin.traits) { - dmgSettings = categories[trait.toLowerCase()] || {}; - config = dmgSettings[template.t]; - - if (config && config.preset !== emptyPreset) { - break; - } - } - if (!config) { - return false; - } - fromConfig(mergeObject(config, { opacity: dmgSettings.opacity, tint: dmgSettings.tint }, true, true), template); - return true; -} - -export const pf2eTemplates = new AutoTemplatePF2E(); diff --git a/tokenmagic/module/proto/PlaceableObjectProto.js b/tokenmagic/module/proto/PlaceableObjectProto.js deleted file mode 100644 index 775a0cc..0000000 --- a/tokenmagic/module/proto/PlaceableObjectProto.js +++ /dev/null @@ -1,171 +0,0 @@ -import { PlaceableType, Magic, broadcast, SocketAction, mustBroadCast, isZOrderConfig } from '../tokenmagic.js'; -import { emptyPreset, autoMinRank } from '../constants.js'; - -export var gMaxRank = autoMinRank; - -PlaceableObject.prototype.TMFXaddFilters = async function (paramsArray, replace = false) { - await Magic.addFilters(this, paramsArray, replace); -}; - -PlaceableObject.prototype.TMFXupdateFilters = async function (paramsArray) { - await Magic.updateFiltersByPlaceable(this, paramsArray); -}; - -PlaceableObject.prototype.TMFXaddUpdateFilters = async function (paramsArray) { - await Magic.addUpdateFilters(this, paramsArray); -}; - -PlaceableObject.prototype.TMFXdeleteFilters = async function (filterId = null) { - await Magic.deleteFilters(this, filterId); -}; - -PlaceableObject.prototype.TMFXhasFilterType = function (filterType) { - return Magic.hasFilterType(this, filterType); -}; - -PlaceableObject.prototype.TMFXhasFilterId = function (filterId) { - return Magic.hasFilterId(this, filterId); -}; - -PlaceableObject.prototype._TMFXsetFlag = async function (flag) { - if (mustBroadCast()) broadcast(this, flag, SocketAction.SET_FLAG); - else await this.document.setFlag('tokenmagic', 'filters', flag); -}; - -PlaceableObject.prototype._TMFXsetAnimeFlag = async function (flag) { - if (mustBroadCast()) broadcast(this, flag, SocketAction.SET_ANIME_FLAG); - else await this.document.setFlag('tokenmagic', 'animeInfo', flag); -}; - -PlaceableObject.prototype._TMFXunsetFlag = async function () { - if (mustBroadCast()) broadcast(this, null, SocketAction.SET_FLAG); - else await this.document.unsetFlag('tokenmagic', 'filters'); -}; - -PlaceableObject.prototype._TMFXunsetAnimeFlag = async function () { - if (mustBroadCast()) broadcast(this, null, SocketAction.SET_ANIME_FLAG); - else await this.document.unsetFlag('tokenmagic', 'animeInfo'); -}; - -PlaceableObject.prototype._TMFXgetSprite = function () { - const type = this._TMFXgetPlaceableType(); - switch (type) { - case PlaceableType.TOKEN: - return this.mesh; - case PlaceableType.TILE: - return this.mesh ?? this.bg; - case PlaceableType.TEMPLATE: - return this.template; - case PlaceableType.DRAWING: - return this.hasText ? this.text : this.shape; - default: - return null; - } -}; - -PlaceableObject.prototype._TMFXgetPlaceablePadding = function () { - // get the placeable padding, by taking into account all filters and options - let accPadding = 0; - const filters = this._TMFXgetSprite().filters; - if (filters instanceof Array) { - for (const filter of filters) { - if (!filter.enabled) continue; - if (canvas.app.renderer.filter.useMaxPadding) { - accPadding = Math.max(accPadding, filter.padding); - } else { - accPadding += filter.padding; - } - } - } - return accPadding; -}; - -PlaceableObject.prototype._TMFXcheckSprite = function () { - const type = this._TMFXgetPlaceableType(); - switch (type) { - case PlaceableType.TOKEN: - case PlaceableType.TILE: - return !(this.mesh == null); - case PlaceableType.TEMPLATE: - return !(this.template == null); - case PlaceableType.DRAWING: - return !(this.shape == null); - default: - return null; - } -}; - -PlaceableObject.prototype._TMFXgetMaxFilterRank = function () { - const sprite = this._TMFXgetSprite(); - if (sprite == null) { - return gMaxRank++; - } - if (sprite.filters == null) { - return gMaxRank++; - } else { - let maxRank = Math.max(...sprite.filters.map((f) => f.rank), autoMinRank); - gMaxRank = Math.max(maxRank, gMaxRank) + 1; - return gMaxRank; - } -}; - -PlaceableObject.prototype._TMFXsetRawFilters = function (filters) { - function insertFilter(filters) { - function filterZOrderCompare(a, b) { - if (a.zOrder < b.zOrder) return -1; - if (a.zOrder > b.zOrder) return 1; - return 0; - } - - function filterRankCompare(a, b) { - if (a.rank < b.rank) return -1; - if (a.rank > b.rank) return 1; - return 0; - } - - if (!isZOrder) { - if (!filters.hasOwnProperty('rank')) { - let maxRank = Math.max(...sprite.filters.map((f) => f.rank), autoMinRank); - filters.rank = maxRank + 1; - } - } - - sprite.filters.push(filters); - isZOrder ? sprite.filters.sort(filterZOrderCompare) : sprite.filters.sort(filterRankCompare); - } - - function addFilter(filters) { - if (!isZOrder && !filters.hasOwnProperty('rank')) { - filters.rank = autoMinRank; - } - sprite.filters = [filters]; - } - - const isZOrder = isZOrderConfig(); - const sprite = this._TMFXgetSprite(); - if (sprite == null) { - return false; - } - - if (filters == null) { - sprite.filters = null; - } else { - sprite.filters == null ? addFilter(filters) : insertFilter(filters); - } - - return true; -}; - -PlaceableObject.prototype._TMFXunsetRawFilters = function () { - return this._TMFXsetRawFilters(null); -}; - -PlaceableObject.prototype._TMFXgetPlaceableType = function () { - if ( - [PlaceableType.TOKEN, PlaceableType.TEMPLATE, PlaceableType.TILE, PlaceableType.DRAWING].includes( - this.constructor.embeddedName - ) - ) - return this.constructor.embeddedName; - return PlaceableType.NOT_SUPPORTED; -}; diff --git a/tokenmagic/module/settings.js b/tokenmagic/module/settings.js deleted file mode 100644 index 876ddbd..0000000 --- a/tokenmagic/module/settings.js +++ /dev/null @@ -1,613 +0,0 @@ -import { presets as defaultPresets, PresetsLibrary } from '../fx/presets/defaultpresets.js'; -import { DataVersion } from '../migration/migration.js'; -import { TokenMagic, isVideoDisabled, fixPath } from './tokenmagic.js'; -import { dnd5eTemplates } from './autoTemplate/dnd5e.js'; -import { pf2eTemplates } from './autoTemplate/pf2e.js'; -import { witcherTemplates } from './autoTemplate/TheWitcherTRPG.js'; -import { defaultOpacity, emptyPreset } from './constants.js'; - -const Magic = TokenMagic(); - -export class TokenMagicSettings extends FormApplication { - constructor(object = {}, options) { - super(object, options); - } - - /** @override */ - static get defaultOptions() { - return { - ...super.defaultOptions, - template: 'modules/tokenmagic/templates/settings/settings.html', - height: 'auto', - title: game.i18n.localize('TMFX.settings.autoTemplateSettings.dialog.title'), - width: 600, - classes: ['tokenmagic', 'settings'], - tabs: [ - { - navSelector: '.tabs', - contentSelector: 'form', - initial: 'name', - }, - ], - submitOnClose: false, - }; - } - - static init() { - const menuAutoTemplateSettings = { - key: 'autoTemplateSettings', - config: { - name: game.i18n.localize('TMFX.settings.autoTemplateSettings.button.name'), - label: game.i18n.localize('TMFX.settings.autoTemplateSettings.button.label'), - hint: game.i18n.localize('TMFX.settings.autoTemplateSettings.button.hint'), - type: TokenMagicSettings, - restricted: true, - }, - }; - - const settingAutoTemplateSettings = { - key: 'autoTemplateSettings', - config: { - name: game.i18n.localize('TMFX.settings.autoTemplateSettings.name'), - hint: game.i18n.localize('TMFX.settings.autoTemplateSettings.hint'), - scope: 'world', - config: false, - default: {}, - type: Object, - }, - }; - - const templates = this.getSystemTemplates(); - let hasAutoTemplates = !!templates; - if (templates) { - game.settings.registerMenu('tokenmagic', menuAutoTemplateSettings.key, menuAutoTemplateSettings.config); - game.settings.register( - 'tokenmagic', - settingAutoTemplateSettings.key, - mergeObject( - settingAutoTemplateSettings.config, - { - default: templates.constructor.defaultConfiguration, - }, - true, - true - ) - ); - } - - game.settings.register('tokenmagic', 'autoTemplateEnabled', { - name: game.i18n.localize('TMFX.settings.autoTemplateEnabled.name'), - hint: game.i18n.localize('TMFX.settings.autoTemplateEnabled.hint'), - scope: 'world', - config: hasAutoTemplates, - default: hasAutoTemplates, - type: Boolean, - onChange: (value) => TokenMagicSettings.configureAutoTemplate(value), - }); - - game.settings.register('tokenmagic', 'defaultTemplateOnHover', { - name: game.i18n.localize('TMFX.settings.defaultTemplateOnHover.name'), - hint: game.i18n.localize('TMFX.settings.defaultTemplateOnHover.hint'), - scope: 'world', - config: true, - default: hasAutoTemplates, - type: Boolean, - onChange: () => window.location.reload(), - }); - - game.settings.register('tokenmagic', 'autohideTemplateElements', { - name: game.i18n.localize('TMFX.settings.autohideTemplateElements.name'), - hint: game.i18n.localize('TMFX.settings.autohideTemplateElements.hint'), - scope: 'world', - config: true, - default: true, - type: Boolean, - onChange: () => window.location.reload(), - }); - - game.settings.register('tokenmagic', 'useAdditivePadding', { - name: game.i18n.localize('TMFX.settings.useMaxPadding.name'), - hint: game.i18n.localize('TMFX.settings.useMaxPadding.hint'), - scope: 'world', - config: true, - default: false, - type: Boolean, - }); - - game.settings.register('tokenmagic', 'minPadding', { - name: game.i18n.localize('TMFX.settings.minPadding.name'), - hint: game.i18n.localize('TMFX.settings.minPadding.hint'), - scope: 'world', - config: true, - default: 50, - type: Number, - }); - - game.settings.register('tokenmagic', 'fxPlayerPermission', { - name: game.i18n.localize('TMFX.settings.fxPlayerPermission.name'), - hint: game.i18n.localize('TMFX.settings.fxPlayerPermission.hint'), - scope: 'world', - config: true, - default: false, - type: Boolean, - }); - - game.settings.register('tokenmagic', 'importOverwrite', { - name: game.i18n.localize('TMFX.settings.importOverwrite.name'), - hint: game.i18n.localize('TMFX.settings.importOverwrite.hint'), - scope: 'world', - config: true, - default: false, - type: Boolean, - }); - - game.settings.register('tokenmagic', 'useZOrder', { - name: game.i18n.localize('TMFX.settings.useZOrder.name'), - hint: game.i18n.localize('TMFX.settings.useZOrder.hint'), - scope: 'world', - config: true, - default: false, - type: Boolean, - }); - - game.settings.register('tokenmagic', 'disableAnimations', { - name: game.i18n.localize('TMFX.settings.disableAnimations.name'), - hint: game.i18n.localize('TMFX.settings.disableAnimations.hint'), - scope: 'client', - config: true, - default: false, - type: Boolean, - onChange: () => window.location.reload(), - }); - - game.settings.register('tokenmagic', 'disableCaching', { - name: game.i18n.localize('TMFX.settings.disableCaching.name'), - hint: game.i18n.localize('TMFX.settings.disableCaching.hint'), - scope: 'client', - config: true, - default: true, - type: Boolean, - }); - - game.settings.register('tokenmagic', 'disableVideo', { - name: game.i18n.localize('TMFX.settings.disableVideo.name'), - hint: game.i18n.localize('TMFX.settings.disableVideo.hint'), - scope: 'world', - config: true, - default: false, - type: Boolean, - onChange: () => window.location.reload(), - }); - - game.settings.register('tokenmagic', 'presets', { - name: 'Token Magic FX presets', - hint: 'Token Magic FX presets', - scope: 'world', - config: false, - default: defaultPresets, - type: Object, - }); - - game.settings.register('tokenmagic', 'migration', { - name: 'TMFX Data Version', - hint: 'TMFX Data Version', - scope: 'world', - config: false, - default: DataVersion.ARCHAIC, - type: String, - }); - - loadTemplates([ - 'modules/tokenmagic/templates/settings/settings.html', - 'modules/tokenmagic/templates/settings/dnd5e/categories.html', - 'modules/tokenmagic/templates/settings/dnd5e/overrides.html', - 'modules/tokenmagic/templates/settings/pf2e/categories.html', - 'modules/tokenmagic/templates/settings/pf2e/overrides.html', - 'modules/tokenmagic/templates/settings/TheWitcherTRPG/categories.html', - 'modules/tokenmagic/templates/settings/TheWitcherTRPG/overrides.html', - ]); - } - - static configureAutoTemplate(enabled = false) { - this.getSystemTemplates()?.configure(enabled); - } - - static getSystemTemplates() { - switch (game.system.id) { - case 'dnd5e': - return dnd5eTemplates; - case 'pf2e': - return pf2eTemplates; - case 'TheWitcherTRPG': - return witcherTemplates; - default: - return null; - } - } - - getSettingsData() { - let settingsData = { - autoTemplateEnable: game.settings.get('tokenmagic', 'autoTemplateEnabled'), - }; - if (TokenMagicSettings.getSystemTemplates()) { - settingsData['autoTemplateSettings'] = game.settings.get('tokenmagic', 'autoTemplateSettings'); - } - return settingsData; - } - - /** @override */ - getData() { - let data = super.getData(); - data.hasAutoTemplates = false; - data.emptyPreset = emptyPreset; - const templates = TokenMagicSettings.getSystemTemplates(); - if (templates) { - mergeObject(data, templates.getData()); - } - - data.presets = Magic.getPresets(PresetsLibrary.TEMPLATE).sort(function (a, b) { - if (a.name < b.name) return -1; - if (a.name > b.name) return 1; - return 0; - }); - data.system = { id: game.system.id, title: game.system.title }; - data.settings = this.getSettingsData(); - data.submitText = game.i18n.localize('TMFX.save'); - return data; - } - - /** @override */ - async _updateObject(_, formData) { - const data = expandObject(formData); - for (let [key, value] of Object.entries(data)) { - if (key === 'autoTemplateSettings' && value.overrides) { - const compacted = {}; - Object.values(value.overrides).forEach((val, idx) => (compacted[idx] = val)); - value.overrides = compacted; - } - await game.settings.set('tokenmagic', key, value); - } - } - - /** @override */ - activateListeners(html) { - super.activateListeners(html); - - html.find('button.add-override').click(this._onAddOverride.bind(this)); - html.find('button.remove-override').click(this._onRemoveOverride.bind(this)); - } - - async _onAddOverride(event) { - event.preventDefault(); - let idx = 0; - const entries = event.target.closest('div.tab').querySelectorAll('div.override-entry'); - const last = entries[entries.length - 1]; - if (last) { - idx = last.dataset.idx + 1; - } - let updateData = {}; - updateData[`autoTemplateSettings.overrides.${idx}.target`] = ''; - updateData[`autoTemplateSettings.overrides.${idx}.opacity`] = defaultOpacity; - updateData[`autoTemplateSettings.overrides.${idx}.tint`] = null; - updateData[`autoTemplateSettings.overrides.${idx}.preset`] = emptyPreset; - updateData[`autoTemplateSettings.overrides.${idx}.texture`] = null; - await this._onSubmit(event, { updateData: updateData, preventClose: true }); - this.render(); - } - - async _onRemoveOverride(event) { - event.preventDefault(); - let idx = event.target.dataset.idx; - const el = event.target.closest(`div[data-idx="${idx}"]`); - if (!el) { - return true; - } - el.remove(); - await this._onSubmit(event, { preventClose: true }); - this.render(); - } -} - -Hooks.once('init', () => { - // Extracted from https://github.com/leapfrogtechnology/just-handlebars-helpers/ - Handlebars.registerHelper('concat', function (...params) { - // Ignore the object appended by handlebars. - if (typeof params[params.length - 1] === 'object') { - params.pop(); - } - - return params.join(''); - }); - TokenMagicSettings.init(); - TokenMagicSettings.configureAutoTemplate(game.settings.get('tokenmagic', 'autoTemplateEnabled')); - - const wmtdUpdate = async function (wrapped, ...args) { - const [document] = args; - let preset, hasPresetData; - - const tex = document.texture ?? ''; - const hasTexture = !!document.texture; - const opt = document.flags?.tokenmagic?.options ?? null; - if (!opt) { - preset = document['flags.tokenmagic.templateData.preset']; - } - hasPresetData = !!preset; - - //const hasOpt = data["flags.tokenmagic"]?.options ?? null; - - if (hasTexture) { - document.texture = fixPath(document.texture); - } - - if (opt == null) { - if (hasPresetData && preset !== emptyPreset) { - let defaultTexture = Magic._getPresetTemplateDefaultTexture(preset); - if (!(defaultTexture == null)) { - if (tex === '' || tex.startsWith('modules/tokenmagic/fx/assets/templates/')) - document.texture = defaultTexture; - } - } else if ( - hasTexture && - tex.startsWith('modules/tokenmagic/fx/assets/templates/') && - hasPresetData && - preset === emptyPreset - ) { - document.texture = ''; - } - } - - return await wrapped(...args); - }; - - const wmtDraw = async function (wrapped, ...args) { - if (this.document.texture) { - this.document.texture = fixPath(this.document.texture); - } - const retVal = await wrapped(...args); - this.template.alpha = this.document.getFlag('tokenmagic', 'templateData')?.opacity ?? 1; - return retVal; - }; - - let wmtApplyRenderFlags; - let wmtApplyRenderFlagsType; - - let wmtRefreshTemplate; - let wmtRefreshTemplateType; - - if (!isVideoDisabled()) { - const toRadians = Math.toRadians; - - wmtApplyRenderFlagsType = 'WRAPPER'; - - wmtApplyRenderFlags = function (wrapped, ...args) { - const [flags] = args; - if (flags?.refreshShape) flags.refreshShape = this.template && !this.template._destroyed; - return wrapped(...args); - }; - - /* ------------------------------------------------------------------------------------ */ - - wmtRefreshTemplateType = 'OVERRIDE'; - - /** - * - * @return {wmtRefreshTemplate} - */ - wmtRefreshTemplate = function () { - const t = this.template.clear(); - if (!this.isVisible) return; - - // Draw the Template outline - t.lineStyle(this._borderThickness, this.borderColor, 0.75).beginFill(0x000000, 0.0); - - // Fill Color or Texture - if (this.texture) { - let mat = PIXI.Matrix.IDENTITY; - // rectangle - if (this.shape.width && this.shape.height) - mat.scale(this.shape.width / this.texture.width, this.shape.height / this.texture.height); - else if (this.shape.radius) { - mat.scale((this.shape.radius * 2) / this.texture.height, (this.shape.radius * 2) / this.texture.width); - // Circle center is texture start... - mat.translate(-this.shape.radius, -this.shape.radius); - } else if (this.document.t === 'ray') { - const d = canvas.dimensions, - height = (this.document.width * d.size) / d.distance, - width = (this.document.distance * d.size) / d.distance; - mat.scale(width / this.texture.width, height / this.texture.height); - mat.translate(0, -height * 0.5); - - mat.rotate(toRadians(this.document.direction)); - } else { - // cone - const d = canvas.dimensions; - - // Extract and prepare data - let { direction, distance, angle } = this.document; - distance *= d.size / d.distance; - direction = Math.toRadians(direction); - const width = (this.document.distance * d.size) / d.distance; - - const angles = [angle / -2, angle / 2]; - distance = distance / Math.cos(Math.toRadians(angle / 2)); - - // Get the cone shape as a polygon - const rays = angles.map((a) => Ray.fromAngle(0, 0, direction + Math.toRadians(a), distance + 1)); - const height = Math.sqrt( - (rays[0].B.x - rays[1].B.x) * (rays[0].B.x - rays[1].B.x) + - (rays[0].B.y - rays[1].B.y) * (rays[0].B.y - rays[1].B.y) - ); - mat.scale(width / this.texture.width, height / this.texture.height); - mat.translate(0, -height / 2); - mat.rotate(toRadians(this.document.direction)); - } - - t.beginTextureFill({ - texture: this.texture, - matrix: mat, - alpha: 1.0, - }); - const source = getProperty(this.texture, 'baseTexture.resource.source'); - if (source && source.tagName === 'VIDEO') { - source.loop = true; - source.muted = true; - game.video.play(source); - } - } else t.beginFill(0x000000, 0.0); - - // Draw the shape - t.drawShape(this.shape); - - // Draw origin and destination points - t.lineStyle(this._borderThickness, 0x000000) - .beginFill(0x000000, 0.5) - .drawCircle(0, 0, 6) - .drawCircle(this.ray.dx, this.ray.dy, 6); - - // Update visibility - this.controlIcon.visible = !!this.layer.active; - this.controlIcon.border.visible = !!this.hover; - const alpha = this.document.getFlag('tokenmagic', 'templateData')?.opacity ?? 1; - t.alpha = this.hover ? alpha / 1.25 : alpha; - - return this; - }; - - /* ------------------------------------------------------------------------------------ */ - } - - if (game.settings.get('tokenmagic', 'autohideTemplateElements')) { - /** - * - * @param wrapped - * @param args - * @return {*} - */ - const autohideTemplateElements = function (wrapped, ...args) { - // Save texture and border thickness - const texture = this.texture; - const borderThickness = this._borderThickness; - - // Hide template texture while moving - if (this._original || this.parent === canvas.templates.preview) { - this.texture = null; - } - - // Show border outline only on hover if the template is textured - if (this.texture && this.texture !== '' && !this._hover) { - this._borderThickness = 0; - } - - const retVal = wrapped(...args); - - // Restore texture and border thickness - this.texture = texture; - this._borderThickness = borderThickness; - - { - // Show the origin/destination points and ruler text only on hover or while creating but not while moving - const template = this._original ?? this; - const show = !this._original && (this._hover || this.parent === canvas.templates.preview); - - if (!show && template.template?.geometry) { - // Hide origin and destination points, i.e., hide everything except the template shape - for (const document of template.template.geometry.graphicsData) { - if (document.shape !== template.shape) { - document.fillStyle.visible = false; - document.lineStyle.visible = false; - } - } - template.template.geometry.invalidate(); - } - - if (template.ruler) template.ruler.renderable = show; - if (template.controlIcon) template.controlIcon.renderable = template.owner; - if (template.handle) template.handle.renderable = template.owner; - } - return retVal; - }; - - /* ------------------------------------------------------------------------------------ */ - - if (wmtApplyRenderFlags) { - const _wmtApplyRenderFlags = wmtApplyRenderFlags; - wmtApplyRenderFlags = function () { - return autohideTemplateElements.call(this, _wmtApplyRenderFlags.bind(this), ...arguments); - }; - } else { - wmtApplyRenderFlagsType = 'WRAPPER'; - wmtApplyRenderFlags = autohideTemplateElements; - } - } - - if (game.settings.get('tokenmagic', 'defaultTemplateOnHover')) { - Hooks.on('canvasReady', () => { - canvas.stage.on('mousemove', (event) => { - const { x: mx, y: my } = event.data.getLocalPosition(canvas.templates); - for (const template of canvas.templates.placeables) { - const hl = canvas.grid.getHighlightLayer(`MeasuredTemplate.${template.id}`); - const opacity = template.document.getFlag('tokenmagic', 'templateData')?.opacity ?? 1; - if (template.texture && template.texture !== '') { - const { x: cx, y: cy } = template.center; - const mouseover = template.shape?.contains(mx - cx, my - cy); - hl.renderable = mouseover; - template.template.alpha = (mouseover ? 0.5 : 1.0) * opacity; - } else { - hl.renderable = true; - template.template.alpha = opacity; - } - } - }); - }); - } - - if (game.modules.get('lib-wrapper')?.active) { - libWrapper.register('tokenmagic', 'MeasuredTemplateDocument.prototype.update', wmtdUpdate, 'WRAPPER'); - libWrapper.register('tokenmagic', 'MeasuredTemplate.prototype._draw', wmtDraw, 'WRAPPER'); - if (wmtApplyRenderFlags) - libWrapper.register( - 'tokenmagic', - 'MeasuredTemplate.prototype._applyRenderFlags', - wmtApplyRenderFlags, - wmtApplyRenderFlagsType - ); - if (wmtRefreshTemplate) - libWrapper.register( - 'tokenmagic', - 'MeasuredTemplate.prototype._refreshTemplate', - wmtRefreshTemplate, - wmtRefreshTemplateType - ); - } else { - const cmtdUpdate = MeasuredTemplateDocument.prototype.update; - MeasuredTemplateDocument.prototype.update = function () { - return wmtdUpdate.call(this, cmtdUpdate.bind(this), ...arguments); - }; - const cmtDraw = MeasuredTemplate.prototype._draw; - MeasuredTemplate.prototype._draw = function () { - return wmtDraw.call(this, cmtDraw.bind(this), ...arguments); - }; - - if (wmtApplyRenderFlags) { - if (wmtApplyRenderFlagsType && wmtApplyRenderFlagsType !== 'OVERRIDE') { - const cmtApplyRenderFlags = MeasuredTemplate.prototype._applyRenderFlags; - MeasuredTemplate.prototype._applyRenderFlags = function () { - return wmtApplyRenderFlags.call(this, cmtApplyRenderFlags.bind(this), ...arguments); - }; - } else { - MeasuredTemplate.prototype._applyRenderFlags = wmtApplyRenderFlags; - } - } - - if (wmtRefreshTemplate) { - if (wmtRefreshTemplateType && wmtRefreshTemplateType !== 'OVERRIDE') { - const cmtRefreshTemplate = MeasuredTemplate.prototype._refreshTemplate; - MeasuredTemplate.prototype._refreshTemplate = function () { - return wmtRefreshTemplate.call(this, cmtRefreshTemplate.bind(this), ...arguments); - }; - } else { - MeasuredTemplate.prototype._refreshTemplate = wmtRefreshTemplate; - } - } - } -}); diff --git a/tokenmagic/module/tokenmagic.js b/tokenmagic/module/tokenmagic.js deleted file mode 100644 index 60361f3..0000000 --- a/tokenmagic/module/tokenmagic.js +++ /dev/null @@ -1,2080 +0,0 @@ -import { FilterAdjustment } from '../fx/filters/FilterAdjustment.js'; -import { FilterAscii } from '../fx/filters/FilterAscii.js'; -import { FilterXBloom } from '../fx/filters/FilterAdvancedBloom.js'; -import { FilterDot } from '../fx/filters/FilterDot.js'; -import { FilterDistortion } from '../fx/filters/FilterDistortion.js'; -import { FilterOldFilm } from '../fx/filters/FilterOldFilm.js'; -import { FilterGlow } from '../fx/filters/FilterGlow.js'; -import { FilterOutline } from '../fx/filters/FilterOutline.js'; -import { FilterBevel } from '../fx/filters/FilterBevel.js'; -import { FilterDropShadow } from '../fx/filters/FilterDropShadow.js'; -import { FilterTwist } from '../fx/filters/FilterTwist.js'; -import { FilterZoomBlur } from '../fx/filters/FilterZoomBlur.js'; -import { FilterBlur } from '../fx/filters/FilterBlur.js'; -import { FilterShockwave } from '../fx/filters/FilterShockWave.js'; -import { FilterBulgePinch } from '../fx/filters/FilterBulgePinch.js'; -import { FilterRemoveShadow } from '../fx/filters/FilterRemoveShadow.js'; -import { FilterRays } from '../fx/filters/FilterRays.js'; -import { FilterFog } from '../fx/filters/FilterFog.js'; -import { FilterXFog } from '../fx/filters/FilterXFog.js'; -import { FilterElectric } from '../fx/filters/FilterElectric.js'; -import { FilterWaves } from '../fx/filters/FilterWaves.js'; -import { FilterFire } from '../fx/filters/FilterFire.js'; -import { FilterFumes } from '../fx/filters/FilterFumes.js'; -import { FilterFlood } from '../fx/filters/FilterFlood.js'; -import { FilterSmoke } from '../fx/filters/FilterSmoke.js'; -import { FilterForceField } from '../fx/filters/FilterForceField.js'; -import { FilterMirrorImages } from '../fx/filters/FilterMirrorImages.js'; -import { FilterXRays } from '../fx/filters/FilterXRays.js'; -import { FilterLiquid } from '../fx/filters/FilterLiquid.js'; -import { FilterGleamingGlow } from '../fx/filters/FilterGleamingGlow.js'; -import { FilterPixelate } from '../fx/filters/FilterPixelate.js'; -import { FilterSpiderWeb } from '../fx/filters/FilterSpiderWeb.js'; -import { FilterSolarRipples } from '../fx/filters/FilterSolarRipples.js'; -import { FilterGlobes } from '../fx/filters/FilterGlobes.js'; -import { FilterTransform } from '../fx/filters/FilterTransform.js'; -import { FilterSplash } from '../fx/filters/FilterSplash.js'; -import { FilterPolymorph } from '../fx/filters/FilterPolymorph.js'; -import { FilterXFire } from '../fx/filters/FilterXFire.js'; -import { FilterSprite } from '../fx/filters/FilterSprite.js'; -import { FilterSpriteMask } from '../fx/filters/FilterSpriteMask.js'; -import { FilterReplaceColor } from '../fx/filters/FilterReplaceColor.js'; -import { FilterDDTint } from '../fx/filters/FilterDDTint.js'; -import { Anime } from '../fx/Anime.js'; -import { allPresets, PresetsLibrary } from '../fx/presets/defaultpresets.js'; -import { tmfxDataMigration } from '../migration/migration.js'; -import { emptyPreset } from './constants.js'; -import './proto/PlaceableObjectProto.js'; -import { FilterCRT } from '../fx/filters/FilterCRT.js'; -import { FilterRGBSplit } from '../fx/filters/FilterRGBSplit.js'; -import { TokenMagicSettings } from './settings.js'; - -/* - -It's getting messy here ! -I will fix it in a future version -(+ duplicated code to factorize and code to improve) - -*/ - -const moduleTM = 'module.tokenmagic'; - -// Filters Class Keys -export const FilterType = { - adjustment: FilterAdjustment, - ascii: FilterAscii, - dot: FilterDot, - distortion: FilterDistortion, - crt: FilterCRT, - oldfilm: FilterOldFilm, - glow: FilterGlow, - outline: FilterOutline, - bevel: FilterBevel, - xbloom: FilterXBloom, - shadow: FilterDropShadow, - twist: FilterTwist, - zoomblur: FilterZoomBlur, - blur: FilterBlur, - bulgepinch: FilterBulgePinch, - zapshadow: FilterRemoveShadow, - ray: FilterRays, - fog: FilterFog, - xfog: FilterXFog, - electric: FilterElectric, - wave: FilterWaves, - shockwave: FilterShockwave, - fire: FilterFire, - fumes: FilterFumes, - smoke: FilterSmoke, - flood: FilterFlood, - images: FilterMirrorImages, - field: FilterForceField, - xray: FilterXRays, - liquid: FilterLiquid, - xglow: FilterGleamingGlow, - pixel: FilterPixelate, - web: FilterSpiderWeb, - ripples: FilterSolarRipples, - globes: FilterGlobes, - transform: FilterTransform, - splash: FilterSplash, - polymorph: FilterPolymorph, - xfire: FilterXFire, - sprite: FilterSprite, - spriteMask: FilterSpriteMask, - replaceColor: FilterReplaceColor, - ddTint: FilterDDTint, - rgbSplit: FilterRGBSplit, -}; - -export const PlaceableType = { - TOKEN: Token.embeddedName, - TILE: Tile.embeddedName, - TEMPLATE: MeasuredTemplate.embeddedName, - DRAWING: Drawing.embeddedName, - NOT_SUPPORTED: null, -}; - -function i18n(key) { - return game.i18n.localize(key); -} - -async function exportObjectAsJson(exportObj, exportName) { - let jsonStr = JSON.stringify(exportObj, null, 4); - - const a = document.createElement('a'); - const file = new Blob([jsonStr], { type: 'plain/text' }); - - a.href = URL.createObjectURL(file); - a.download = exportName + '.json'; - a.click(); - - URL.revokeObjectURL(a.href); -} - -export const SocketAction = { - SET_FLAG: 'TMFXSetFlag', - SET_ANIME_FLAG: 'TMFXSetAnimeFlag', -}; - -export function broadcast(placeable, flag, socketAction) { - const data = { - tmAction: socketAction, - tmPlaceableId: placeable.id, - tmPlaceableType: placeable._TMFXgetPlaceableType(), - tmFlag: flag, - tmViewedScene: game.user.viewedScene, - }; - game.socket.emit(moduleTM, data, (resp) => {}); -} - -export function isActiveModule(moduleName) { - return game.modules.has(moduleName) && game.modules.get(moduleName).active === true; -} - -export function getMinPadding() { - return game.settings.get('tokenmagic', 'minPadding'); -} - -export function isAdditivePaddingConfig() { - return game.settings.get('tokenmagic', 'useAdditivePadding'); -} - -export function isFilterCachingDisabled() { - return game.settings.get('tokenmagic', 'disableCaching'); -} - -export function isVideoDisabled() { - return game.settings.get('tokenmagic', 'disableVideo'); -} - -export function isTheOne() { - const theOne = game.users.find((user) => user.isGM && user.active); - return theOne && game.user === theOne; -} - -export function mustBroadCast() { - return game.settings.get('tokenmagic', 'fxPlayerPermission') && !isTheOne(); -} - -export function autosetPaddingMode() { - canvas.app.renderer.filter.useMaxPadding = !isAdditivePaddingConfig(); -} - -export function isZOrderConfig() { - return game.settings.get('tokenmagic', 'useZOrder'); -} - -export function isAnimationDisabled() { - return game.settings.get('tokenmagic', 'disableAnimations'); -} - -export function log(output) { - let logged = '%cTokenMagic %c| ' + output; - console.log(logged, 'color:#4BC470', 'color:#B3B3B3'); -} - -export function warn(output) { - let logged = 'TokenMagic | ' + output; - console.warn(logged); -} - -export function error(output) { - let logged = 'TokenMagic | ' + output; - console.error(logged); -} - -export function fixPath(path) { - /* - /prefix/... => ... - /modules/tokenmagic/... => modules/tokenmagic/... - */ - if (path) { - const base = '/modules/tokenmagic'; - const url = new URL(path, window.location.href); - - if (url.origin === window.location.origin) { - let prefix = '/'; - - try { - if (ROUTE_PREFIX) { - prefix = new URL(ROUTE_PREFIX, window.location.origin).pathname; - } - } catch (err) {} - - path = url.pathname; - - if (prefix === '/') { - path = path.slice(1); - } else if (path.startsWith(prefix) && (path.length === prefix.length || path[prefix.length] === '/')) { - path = path.slice(prefix.length + 1); - } else if (path.startsWith(base) && (path.length === base.length || path[base.length] === '/')) { - path = path.slice(1); - } - } else { - path = url.href; - } - } - - return path; -} - -export function getControlledPlaceables() { - const authorizedLayers = [canvas.tokens, canvas.tiles, canvas.drawings]; - if (authorizedLayers.some((layer) => layer === canvas.activeLayer)) { - return canvas.activeLayer.placeables.filter((p) => p.controlled === true) || []; - } else return []; -} - -export function getTargetedTokens() { - return canvas.tokens.placeables.filter((placeable) => placeable.isTargeted); -} - -export function getPlaceableById(id, type) { - let placeable = null; - - function findPlaceable(placeables, id) { - let rplaceable = null; - if (!(placeables == null) && placeables.length > 0) { - rplaceable = placeables.find((n) => n.id === id); - } - return rplaceable; - } - - switch (type) { - case PlaceableType.TOKEN: - placeable = findPlaceable(canvas.tokens.placeables, id); - break; - case PlaceableType.TILE: - placeable = findPlaceable(canvas.tiles.placeables, id); - break; - case PlaceableType.TEMPLATE: - placeable = findPlaceable(canvas.templates.placeables, id); - break; - case PlaceableType.DRAWING: - placeable = findPlaceable(canvas.drawings.placeables, id); - break; - } - - return placeable; -} - -/** - * Randomizes params using 'randomized' field. - * 'randomized' is an object consisting of keys named after params to be randomized, which map either - * to arrays or ranges which will be used to generate a random value. - * e.g. - * { - * param1: ['foo1', 'foo2', 'foo3'], - * param2: { list: ['foo1', 'foo2', 'foo3'], link: 'param5'}, - * param3: { val1: 0, val2: 1, step: 0.1}, - * param4: { val1: 0, val2: 10, step: 1, link: 'param6'}, - * } - * 'link' will assign the same generated value to one other param. - */ -function randomizeParams(params) { - if (params.randomized.hasOwnProperty('active') && !params.randomized.active) return; - - for (const [param, opts] of Object.entries(params.randomized)) { - let rVal; - if (Array.isArray(opts) || opts.hasOwnProperty('list')) { - const list = opts.list ?? opts; - rVal = list[Math.floor(Math.random() * list.length)]; - } else { - const min = Math.min(opts.val1, opts.val2); - const max = Math.max(opts.val1, opts.val2); - const step = opts.step ?? 1; - const stepsInRange = (max - min + (Number.isInteger(step) ? 1 : 0)) / step; - rVal = Math.floor(Math.random() * stepsInRange) * step + min; - } - setProperty(params, param, rVal); - if (opts.hasOwnProperty('link')) setProperty(params, opts.link, rVal); - } -} - -export function objectAssign(target, ...sources) { - sources.forEach((source) => { - Object.keys(source).forEach((key) => { - const s_val = source[key]; - const t_val = target[key]; - if (s_val instanceof Array) target[key] = [...s_val]; - else - target[key] = - t_val && s_val && typeof t_val === 'object' && typeof s_val === 'object' ? objectAssign(t_val, s_val) : s_val; - }); - }); - return target; -} - -export function TokenMagic() { - let _cachedContainer = new PIXI.Container(); - - async function addFiltersOnSelected(paramsArray, replace = false) { - if (!Array.isArray(paramsArray)) { - paramsArray = getPreset(paramsArray); - } - - const controlled = getControlledPlaceables(); - - if (!(controlled == null) && controlled.length > 0) { - for (const placeable of controlled) { - await addFilters(placeable, paramsArray, replace); - } - } - } - - async function addUpdateFiltersOnSelected(paramsArray) { - if (!Array.isArray(paramsArray)) { - paramsArray = getPreset(paramsArray); - } - - const controlled = getControlledPlaceables(); - - if (!(controlled == null) && controlled.length > 0) { - for (const placeable of controlled) { - await addUpdateFilters(placeable, paramsArray); - } - } - } - - async function addUpdateFiltersOnTargeted(paramsArray) { - if (!Array.isArray(paramsArray)) { - paramsArray = getPreset(paramsArray); - } - - const targeted = getTargetedTokens(); - - if (!(targeted == null) && targeted.length > 0) { - for (const token of targeted) { - await addUpdateFilters(token, paramsArray); - } - } - } - - async function addFiltersOnTargeted(paramsArray, replace = false) { - if (!Array.isArray(paramsArray)) { - paramsArray = getPreset(paramsArray); - } - - const targeted = getTargetedTokens(); - - if (!(targeted == null) && targeted.length > 0) { - for (const token of targeted) { - await addFilters(token, paramsArray, replace); - } - } - } - - async function addFilters(placeable, paramsArray, replace = false) { - if (!Array.isArray(paramsArray)) { - paramsArray = getPreset(paramsArray); - } - if (!(paramsArray instanceof Array && paramsArray.length > 0) || placeable == null) return; - - let actualFlags = replace ? null : placeable.document.getFlag('tokenmagic', 'filters'); - let newFlags = []; - - for (const params of paramsArray) { - if (!params.hasOwnProperty('filterType') || !FilterType.hasOwnProperty(params.filterType)) { - // one invalid ? all rejected. - return; - } - - if (!params.hasOwnProperty('rank')) { - params.rank = placeable._TMFXgetMaxFilterRank(); - } - - if (!params.hasOwnProperty('filterId') || params.filterId == null) { - params.filterId = randomID(); - } - - if (!params.hasOwnProperty('enabled') || !(typeof params.enabled === 'boolean')) { - params.enabled = true; - } - - if (params.hasOwnProperty('randomized')) { - randomizeParams(params); - } - - params.placeableId = placeable.id; - params.filterInternalId = randomID(); - params.filterOwner = game.data.userId; - params.placeableType = placeable._TMFXgetPlaceableType(); - params.updateId = randomID(); - - newFlags.push({ - tmFilters: { - tmFilterId: params.filterId, - tmFilterInternalId: params.filterInternalId, - tmFilterType: params.filterType, - tmFilterOwner: params.filterOwner, - tmParams: params, - }, - }); - } - - if (!(actualFlags == null)) { - newFlags = actualFlags.concat(newFlags); - } - - await placeable._TMFXsetFlag(newFlags); - } - - async function addUpdateFilters(placeable, paramsArray) { - if (!paramsArray instanceof Array || paramsArray.length < 1) { - return; - } - - let flags = placeable.document.getFlag('tokenmagic', 'filters'); - let workingFlags = []; - if (flags) { - flags.forEach((flag) => { - workingFlags.push(duplicate(flag)); - }); - } - - let newFlags = []; - let updateParams; - - for (const params of paramsArray) { - updateParams = false; - params.updateId = randomID(); - - if (params.hasOwnProperty('randomized')) { - randomizeParams(params); - } - - workingFlags.forEach((flag) => { - if (flag.tmFilters.tmFilterId === params.filterId && flag.tmFilters.tmFilterType === params.filterType) { - if (flag.tmFilters.hasOwnProperty('tmParams')) { - objectAssign(flag.tmFilters.tmParams, params); - updateParams = true; - } - } - }); - - if (!updateParams) { - if (!params.hasOwnProperty('filterType') || !FilterType.hasOwnProperty(params.filterType)) { - // one invalid ? all rejected (even the update) - return; - } - - if (!params.hasOwnProperty('rank')) { - params.rank = placeable._TMFXgetMaxFilterRank(); - } - - if (!params.hasOwnProperty('filterId') || params.filterId == null) { - params.filterId = randomID(); - } - - if (!params.hasOwnProperty('enabled') || !(typeof params.enabled === 'boolean')) { - params.enabled = true; - } - - params.placeableId = placeable.id; - params.filterInternalId = randomID(); - params.filterOwner = game.data.userId; - params.placeableType = placeable._TMFXgetPlaceableType(); - - newFlags.push({ - tmFilters: { - tmFilterId: params.filterId, - tmFilterInternalId: params.filterInternalId, - tmFilterType: params.filterType, - tmFilterOwner: params.filterOwner, - tmParams: params, - }, - }); - } - } - - if (newFlags.length > 0) { - workingFlags = newFlags.concat(workingFlags); - } - - await placeable._TMFXsetFlag(workingFlags); - } - - async function updateFilters(paramsArray) { - if (params == null || !params.hasOwnProperty('filterId')) { - return; - } - let placeableIdSet = new Set(); - let animations = Anime.getAnimeMap(); - if (animations.size <= 0) { - return; - } - - animations.forEach((anime, id) => { - let filterIdMatch = (params) => params.filterId === anime.puppet.filterId; - if (paramsArray.some(filterIdMatch)) { - placeableIdSet.add(anime.puppet.placeableId); - } - }); - - if (placeableIdSet.size <= 0) { - return; - } - - for (const placeableId of placeableIdSet) { - // we must browse the collection of placeables whatever their types - // we have just a filterId. - let placeable = getPlaceableById(placeableId, PlaceableType.TOKEN); - if (placeable == null) { - placeable = getPlaceableById(placeableId, PlaceableType.TEMPLATE); - } - if (placeable == null) { - placeable = getPlaceableById(placeableId, PlaceableType.TILE); - } - if (placeable == null) { - placeable = getPlaceableById(placeableId, PlaceableType.DRAWING); - } - if (!(placeable == null) && placeable instanceof PlaceableObject) { - await updateFiltersByPlaceable(placeable, paramsArray); - } - } - } - - async function updateFiltersOnSelected(paramsArray) { - let placeables = getControlledPlaceables(); - - if (placeables == null || placeables.length < 1) { - return; - } - if (typeof paramsArray === 'string') { - paramsArray = getPreset(paramsArray); - } - if (!(paramsArray instanceof Array) || paramsArray.length < 1) { - return; - } - - for (const placeable of placeables) { - await updateFiltersByPlaceable(placeable, paramsArray); - } - } - - async function updateFiltersOnTargeted(paramsArray) { - let targeted = getTargetedTokens(); - - if (targeted == null || targeted.length < 1) { - return; - } - - if (typeof paramsArray === 'string') { - paramsArray = getPreset(paramsArray); - } - - if (!(paramsArray instanceof Array) || paramsArray.length < 1) { - return; - } - - for (const token of targeted) { - await updateFiltersByPlaceable(token, paramsArray); - } - } - - async function updateFiltersByPlaceable(placeable, paramsArray) { - if (!(paramsArray instanceof Array) || paramsArray.length < 1) { - return; - } - - let flags = placeable.document.getFlag('tokenmagic', 'filters'); - if (flags == null || !(flags instanceof Array) || flags.length < 1) { - return; - } // nothing to update... - - let workingFlags = []; - flags.forEach((flag) => { - workingFlags.push(duplicate(flag)); - }); - - for (const params of paramsArray) { - params.updateId = randomID(); - - if (params.hasOwnProperty('randomized')) { - randomizeParams(params); - } - - workingFlags.forEach((flag) => { - if (flag.tmFilters.tmFilterId === params.filterId && flag.tmFilters.tmFilterType === params.filterType) { - if (flag.tmFilters.hasOwnProperty('tmParams')) { - objectAssign(flag.tmFilters.tmParams, params); - } - } - }); - } - await placeable._TMFXsetFlag(workingFlags); - } - - // Deleting filters on targeted tokens - async function deleteFiltersOnTargeted(filterId = null) { - let targeted = getTargetedTokens(); - if (!(targeted == null) && targeted.length > 0) { - for (const token of targeted) { - await deleteFilters(token, filterId); - } - } - } - - // Deleting filters on selected placeable(s) - async function deleteFiltersOnSelected(filterId = null) { - let placeables = getControlledPlaceables(); - if (!(placeables == null) && placeables.length > 0) { - for (const placeable of placeables) { - await deleteFilters(placeable, filterId); - } - } - } - - // Deleting all filters on a placeable in parameter - async function deleteFilters(placeable, filterId = null) { - if (placeable == null) { - return; - } - - if (filterId == null) { - await placeable._TMFXunsetFlag(); - await placeable._TMFXunsetAnimeFlag(); - } else if (typeof filterId === 'string') { - let flags = placeable.document.getFlag('tokenmagic', 'filters'); - if (flags == null || !(flags instanceof Array) || flags.length < 1) { - return; - } // nothing to delete... - - let workingFlags = []; - flags.forEach((flag) => { - if (flag.tmFilters.tmFilterId !== filterId) { - workingFlags.push(duplicate(flag)); - } - }); - - if (workingFlags.length > 0) await placeable._TMFXsetFlag(workingFlags); - else await placeable._TMFXunsetFlag(); - - flags = placeable.document.getFlag('tokenmagic', 'animeInfo'); - if (flags == null || !(flags instanceof Array) || flags.length < 1) { - return; - } // nothing to delete... - - workingFlags = []; - flags.forEach((flag) => { - if (flag.tmFilterId !== filterId) { - workingFlags.push(duplicate(flag)); - } - }); - - if (workingFlags.length > 0) await placeable._TMFXsetAnimeFlag(workingFlags); - else await placeable._TMFXunsetAnimeFlag(); - } - } - - function hasFilterType(placeable, filterType) { - if (placeable == null || filterType == null || !(placeable instanceof PlaceableObject)) { - return null; - } - - let flags = placeable.document.getFlag('tokenmagic', 'filters'); - if (flags == null || !(flags instanceof Array) || flags.length < 1) { - return false; - } - - const found = flags.find((flag) => flag.tmFilters.tmFilterType === filterType); - if (found === undefined) { - return false; - } - return true; - } - - function isApplicableUser(tmParams) { - const hasUser = (arr) => { - return arr.includes(game.user.name) || arr.includes(game.user.id); - }; - - if ( - (tmParams.users?.include?.length && !hasUser(tmParams.users.include)) || - (tmParams.users?.exclude?.length && hasUser(tmParams.users?.exclude)) - ) { - return false; - } - - return true; - } - - function hasFilterId(placeable, filterId) { - if (placeable == null || !(placeable instanceof PlaceableObject)) { - return null; - } - let flags = placeable.document.getFlag('tokenmagic', 'filters'); - return _checkFilterId(placeable, filterId, flags); - } - - function _checkFilterId(placeable, filterId, flags) { - if (placeable == null || filterId == null || !(placeable instanceof PlaceableObject)) { - return null; - } - - if (flags == null || !(flags instanceof Array) || flags.length < 1) { - return false; - } - - const found = flags.find((flag) => flag.tmFilters.tmFilterId === filterId); - if (found === undefined) { - return false; - } - return true; - } - - function setFilter(placeable, filter) { - placeable._TMFXsetRawFilters(filter); - } - - function _loadPersistedValues(params, animeInfos) { - if (!params.hasOwnProperty('animated')) { - return; - } - if (!animeInfos || animeInfos.length <= 0) { - return; - } - - for (const effect of Object.keys(params.animated)) { - for (const animeInfo of animeInfos.values()) { - if ( - animeInfo.tmFilterId === params.filterId && - animeInfo.tmFilterInternalId === params.filterInternalId && - animeInfo.tmFilterEffect === effect - ) { - params.animated[effect].active = false; - params[effect] = animeInfo.tmFilterEffectValue; - - // special case for halfCosOscillation - if (params.animated[effect].animType === 'halfCosOscillation') { - if (params.animated[effect].val1 !== animeInfo.tmFilterEffectValue) { - params.animated[effect].val2 = params.animated[effect].val1; - params.animated[effect].val1 = animeInfo.tmFilterEffectValue; - } - } - } - } - } - } - - function _assignFilters(placeable, filters, bulkLoading = false) { - if (filters == null || placeable == null) { - return; - } - // Assign all filters to the placeable - let animeInfos = placeable.document.getFlag('tokenmagic', 'animeInfo'); - for (const filterInfo of filters) { - // if bulkloading is on, we update with terminal value if it exists - if (bulkLoading) { - let params = filterInfo.tmFilters.tmParams; - _loadPersistedValues(params, animeInfos); - } - _assignFilter(placeable, filterInfo); - } - } - - function _assignFilter(placeable, filterInfo) { - if (filterInfo == null) { - return; - } - - // Do not assign the filter if it has been explicitly set as not applicable to the current user - if (!isApplicableUser(filterInfo.tmFilters.tmParams)) { - return; - } - - let workingFilterInfo = duplicate(filterInfo); - workingFilterInfo.tmFilters.tmParams.placeableId = placeable.id; - workingFilterInfo.tmFilters.tmParams.placeableType = placeable._TMFXgetPlaceableType(); - let filter = new FilterType[workingFilterInfo.tmFilters.tmFilterType](workingFilterInfo.tmFilters.tmParams); - setFilter(placeable, filter); - } - - function _loadFilters(placeables, bulkLoading = true) { - if (!(placeables == null)) { - placeables - .slice() - .reverse() - .forEach((placeable) => { - _singleLoadFilters(placeable, bulkLoading); - }); - } - } - - function _singleLoadFilters(placeable, bulkLoading = false) { - let placeableType = placeable._TMFXgetPlaceableType(); - if (placeableType === PlaceableType.TEMPLATE) { - let updateData = placeable.document.getFlag('tokenmagic', 'templateData'); - if (!(updateData == null)) { - placeable.document.tmfxTextureAlpha = placeable._TMFXgetSprite().alpha = updateData.opacity; - placeable.document.tmfxTint = updateData.tint; - } - } - - let filters = placeable.document.getFlag('tokenmagic', 'filters'); - if (!(filters == null)) { - if (placeableType === PlaceableType.TEMPLATE) { - // get the first filterId to assign tmfxPreset - placeable.document.tmfxPreset = filters[0].tmFilters.tmFilterId; - } - _assignFilters(placeable, filters, bulkLoading); - } - placeable.loadingRequest = false; - } - - function _fxPseudoEqual(flagObject, filterObject) { - function isObject(object) { - return object != null && typeof object === 'object'; - } - - const flagKeys = Object.keys(flagObject); - - for (const flagKey of flagKeys) { - let flagValue = flagObject[flagKey]; - const filterValue = filterObject[flagKey]; - const areObjects = isObject(flagValue) && isObject(filterValue); - - if (areObjects && !_fxPseudoEqual(flagValue, filterValue)) { - return false; - } - - // handling the Infinity exception with loops... thanks to JSON serialization... - if (!areObjects && flagKey === 'loops' && flagValue === null) { - flagValue = Infinity; // not nice, but works ! :-)= - } - - if (!areObjects && flagValue !== filterValue) { - return false; - } - } - return true; - } - - function _updateTemplateData(data, options, placeableType) { - if (!options.hasOwnProperty('flags') || !options.flags.hasOwnProperty('tokenmagic')) { - return; - } - if (data == null || !data.hasOwnProperty('_id')) { - return; - } - - let placeable = getPlaceableById(data._id, placeableType); - if (placeable == null) { - return; - } - - let updateData = placeable.document.getFlag('tokenmagic', 'templateData'); - if (!(updateData == null)) { - placeable._TMFXgetSprite().alpha = updateData.opacity; - } - } - - function _updateFilters(data, options, placeableType) { - if ( - !( - options.hasOwnProperty('flags') && - options.flags.hasOwnProperty('tokenmagic') && - (options.flags.tokenmagic.hasOwnProperty('filters') || options.flags.tokenmagic.hasOwnProperty('-=filters')) - ) - ) { - return; - } - if (data == null || !data.hasOwnProperty('_id')) { - return; - } - - let placeable = getPlaceableById(data._id, placeableType); - if (placeable == null) { - return; - } - - // Shortcut when all filters are deleted - if (options.flags.tokenmagic.hasOwnProperty('-=filters')) { - Anime.removeAnimation(data._id); // removing animations on this placeable - this._clearImgFiltersByPlaceable(placeable); // clearing the filters (owned by tokenmagic) - return; - } - - let filters = placeable.document.getFlag('tokenmagic', 'filters'); - if (filters == null) { - return; - } - - // CROSS-RESEARCH between the anime map and tokenmagic flags to add, delete or update filters on this placeable - - // we begin by detecting deleted filters - for (let anime of Anime.getAnimeMap().values()) { - // we test all the animes that are supposed to be on the placeable - if (anime.puppet.placeableId === placeable.id) { - // is the animation present in the tokenmagic flags for this placeable ? - // and is it applicable to the current user? - let foundFilter = false; - filters.forEach((filterFlag) => { - if ( - anime.puppet.filterId === filterFlag.tmFilters.tmFilterId && - anime.puppet.filterInternalId === filterFlag.tmFilters.tmFilterInternalId && - anime.puppet.placeableId === filterFlag.tmFilters.tmParams.placeableId && - isApplicableUser(filterFlag.tmFilters.tmParams) - ) { - // we find it ! - foundFilter = true; - } - }); - - // Not found, the animation is removed from the AnimeMap as well as the filter on the placeable - if (!foundFilter) { - Anime.removeAnimationByFilterId(data._id, anime.puppet.filterId); - this._clearImgFiltersByPlaceable(placeable, anime.puppet.filterId); - } - } - } - - // we test each tokenmagic filter flag in the placeable - filters.forEach((filterFlag) => { - if (filterFlag.tmFilters.hasOwnProperty('tmParams')) { - // we get the puppets in anime corresponding to this placeable - let puppets = Anime.getPuppetsByParams(filterFlag.tmFilters.tmParams); - if (puppets.length > 0) { - // we found corresponding filters - for (const puppet of puppets) { - // we update if needed - if (!_fxPseudoEqual(filterFlag.tmFilters.tmParams, puppet)) { - if ( - !puppet.hasOwnProperty('updateId') || - (puppet.hasOwnProperty('updateId') && puppet.updateId !== filterFlag.tmFilters.tmParams.updateId) - ) { - puppet.setTMParams(duplicate(filterFlag.tmFilters.tmParams)); - puppet.normalizeTMParams(); - } - } - } - } else { - // this is a new filter, we assign it to the placeable - _assignFilter(placeable, filterFlag); - } - } - }); - } - - function _clearImgFiltersByPlaceable(placeable, filterId = null) { - if (placeable == null) { - return; - } - - let filterById = filterId != null && typeof filterId === 'string'; - - function destroyClearedFilters(theFilters) { - if (theFilters instanceof Array) { - let tmFilters = theFilters.filter((filter) => - filterById - ? filter.hasOwnProperty('filterId') && filter.filterId === filterId - : filter.hasOwnProperty('filterId') - ); - - for (const filter of tmFilters) { - filter.enabled = false; - filter.destroy(); - } - } - } - - function filterTheFiltering(theFilters) { - if (theFilters instanceof Array) { - let tmFilters = theFilters.filter((filter) => - filterById - ? !(filter.hasOwnProperty('filterId') && filter.filterId === filterId) - : !filter.hasOwnProperty('filterId') - ); - return tmFilters.length === 0 ? null : tmFilters; - } - return theFilters; - } - - let sprite = placeable._TMFXgetSprite(); - if (sprite != null) { - destroyClearedFilters(sprite.filters); - sprite.filters = filterTheFiltering(sprite.filters); - } - } - - async function _importPresetContent(content, options = {}) { - // In internal, we can force overwrite - if (!options.hasOwnProperty('overwrite')) { - options.overwrite = game.settings.get('tokenmagic', 'importOverwrite'); - } - - /////////////////////////////////////////////// - // Checking the imported object format - - log('import -> checking import file format...'); - if (!(content instanceof Array) || content.length < 1) { - error('import -> file format check KO !'); - error(i18n('TMFX.preset.import.format.failure')); - return false; - } - log('import -> file format check OK !'); - // check object format end - ///////////////////////////////////////////////// - - let check = true; - - /////////////////////////////////////////////// - // Checking the imported content - log('import -> checking import file content...'); - for (const element of content) { - if ( - element.hasOwnProperty('name') && - typeof element.name === 'string' && - element.hasOwnProperty('params') && - element.params instanceof Array - ) { - for (const effect of element.params) { - if (!(effect.hasOwnProperty('filterType') && FilterType.hasOwnProperty(effect.filterType))) { - check = false; - break; - } - } - if (!check) break; - } else { - check = false; - break; - } - } - - if (!check) { - error('import -> file content check KO !'); - error(i18n('TMFX.preset.import.format.failure')); - return false; - } - log('import -> file content check OK !'); - - // check content end - ///////////////////////////////////////////////// - - // The preset libray must be replaced ? - if (options.hasOwnProperty('replaceLibrary') && options.replaceLibrary) { - await game.settings.set('tokenmagic', 'presets', content); - log('import -> preset library replaced'); - log(i18n('TMFX.preset.import.success')); - return true; - } - - let pst = game.settings.get('tokenmagic', 'presets'); - let it = 0; - for (const element of content) { - const preset = pst.find((el) => el.name === element.name); - if (preset == null) { - log('import -> add: ' + element.name); - pst.push(element); - it++; - } else { - if (options.hasOwnProperty('overwrite') && options.overwrite) { - const index = pst.indexOf(preset); - if (index > -1) { - log('import -> overwrite: ' + element.name); - pst[index] = element; - it++; - } - } else { - warn('import -> ignored: ' + element.name + ' -> already exists'); - } - } - } - - await game.settings.set('tokenmagic', 'presets', pst); - log('import -> ' + it + ' preset(s) added to the library'); - log(i18n('TMFX.preset.import.success')); - return true; - } - - async function _importTemplateSettingsContent(content, options = {}) { - /////////////////////////////////////////////// - // Checking the imported object format - - log('import -> checking import file format...'); - if (!(content instanceof Object)) { - error('import -> file format check KO !'); - error(i18n('TMFX.preset.import.format.failure')); - return false; - } - log('import -> file format check OK !'); - - // check object format end - ///////////////////////////////////////////////// - - await game.settings.set('tokenmagic', 'autoTemplateSettings', content); - log('import -> automatic template settings replaced'); - log(i18n('TMFX.preset.import.success')); - return true; - } - - async function resetPresetLibrary() { - if (!game.user.isGM) return; - - if (confirm(i18n('TMFX.preset.reset.message'))) { - try { - await game.settings.set('tokenmagic', 'presets', allPresets); - ui.notifications.info(i18n('TMFX.preset.reset.success')); - } catch (e) { - error(e.message); - } - } - } - - async function importPresetLibraryFromURL(url, options = {}) { - try { - $.getJSON(url, async function (content) { - return await _importPresetContent(content, options); - }); - } catch (e) { - error(e.message); - error(i18n('TMFX.preset.import.failure')); - return false; - } - } - - async function importPresetLibraryFromPath(path, options = {}) { - try { - const response = await fetch(path); - const content = await response.json(); - - return await _importPresetContent(content, options); - } catch (e) { - error(e.message); - error(i18n('TMFX.preset.import.failure')); - return false; - } - } - - async function importTemplateSettingsFromPath(path, options = {}) { - try { - const response = await fetch(path); - const content = await response.json(); - - return await _importTemplateSettingsContent(content, options); - } catch (e) { - error(e.message); - error(i18n('TMFX.preset.import.failure')); - return false; - } - } - - async function importPresetLibrary() { - const path = 'modules/tokenmagic/import'; - new FilePicker({ - type: 'json', - current: path, - callback: importPresetLibraryFromPath, - }).browse(); - } - - function exportPresetLibrary(exportName = 'tmfx-presets') { - let pst = game.settings.get('tokenmagic', 'presets'); - if (pst == null || typeof pst !== 'object') return false; - exportObjectAsJson(pst, exportName); - } - - async function importTemplateSettings() { - const path = 'modules/tokenmagic/import'; - new FilePicker({ - type: 'json', - current: path, - callback: importTemplateSettingsFromPath, - }).browse(); - } - - function exportTemplateSettings(exportName = 'tmfx-template-settings') { - let pst = game.settings.get('tokenmagic', 'autoTemplateSettings'); - if (pst == null || typeof pst !== 'object') return false; - exportObjectAsJson(pst, exportName); - } - - function getPresets(libraryName = PresetsLibrary.MAIN) { - let pst = game.settings.get('tokenmagic', 'presets'); - if (pst == null || typeof pst !== 'object') return []; - return pst.filter((preset) => preset.library === libraryName); - } - - function _getPresetTemplateDefaultTexture(presetName, presetLibrary = PresetsLibrary.TEMPLATE) { - let pst = game.settings.get('tokenmagic', 'presets'); - const preset = pst.find((el) => el['name'] === presetName && el['library'] === presetLibrary); - if (!(preset == null) && preset.hasOwnProperty('defaultTexture')) return fixPath(preset.defaultTexture); - else return null; - } - - function getPreset(presetName) { - let pName = null, - pLibrary = null; - let argIsObj = presetName instanceof Object; - const { name, library, ...adjustmentProp } = argIsObj ? presetName : {}; - if (argIsObj) { - if (presetName.hasOwnProperty('name')) { - pName = presetName.name; - } - if (presetName.hasOwnProperty('library')) { - pLibrary = presetName.library; - } - } else { - pName = presetName; - } - - if (pLibrary == null || typeof pLibrary !== 'string') { - pLibrary = PresetsLibrary.MAIN; - } - - if (typeof pName !== 'string') return undefined; - - let pst = game.settings.get('tokenmagic', 'presets'); - if (pst == null || typeof pst !== 'object') return undefined; - - const preset = pst.find((el) => el['name'] === pName && el['library'] === pLibrary); - if (!(preset == null) && preset.hasOwnProperty('params') && preset.params instanceof Array) { - for (const [filterProp, filterPropVal] of Object.entries(adjustmentProp)) { - //log(`getPreset ${filterProp}: ${filterPropVal}`); - for (const param of preset.params) { - if (param.hasOwnProperty(filterProp)) { - param[filterProp] = filterPropVal; - } - } - } - return deepClone(preset.params); - } - return undefined; - } - - async function deletePreset(presetName, silent = false) { - if (!game.user.isGM) { - if (!silent) ui.notifications.warn(i18n('TMFX.preset.delete.permission.failure')); - return false; - } - - let pName = null, - pLibrary = null; - - if (presetName instanceof Object) { - if (presetName.hasOwnProperty('name')) { - pName = presetName.name; - } - if (presetName.hasOwnProperty('library')) { - pLibrary = presetName.library; - } - } else { - pName = presetName; - } - - if (pLibrary == null || typeof pLibrary !== 'string') { - pLibrary = PresetsLibrary.MAIN; - } - - if (typeof pName !== 'string') { - if (!silent) ui.notifications.error(i18n('TMFX.preset.delete.params.failure')); - return false; - } - - let pst = game.settings.get('tokenmagic', 'presets'); - if (pst == null) { - if (!silent) ui.notifications.warn(i18n('TMFX.preset.delete.empty.failure')); - return false; - } - - let state = true; - const preset = pst.find((el) => el['name'] === pName && el['library'] === pLibrary); - - if (preset == null) { - if (!silent) ui.notifications.warn(i18n('TMFX.preset.delete.notfound.failure')); - state = false; - } else { - const index = pst.indexOf(preset); - if (index > -1) { - pst.splice(index, 1); - try { - await game.settings.set('tokenmagic', 'presets', pst); - if (!silent) ui.notifications.info(i18n('TMFX.preset.delete.success')); - } catch (e) { - if (!silent) ui.notifications.error(e.message); - console.error(e); - state = false; - } - } - } - return state; - } - - async function addPreset(presetName, params, silent = false) { - if (!game.user.isGM) { - if (!silent) ui.notifications.warn(i18n('TMFX.preset.add.permission.failure')); - return false; - } - - let pName = null, - pLibrary = null, - pDefaultTexture = null; - if (presetName instanceof Object) { - if (presetName.hasOwnProperty('name')) { - pName = presetName.name; - } - if (presetName.hasOwnProperty('library')) { - pLibrary = presetName.library; - } - if (presetName.hasOwnProperty('defaultTexture')) { - pDefaultTexture = fixPath(presetName.defaultTexture); - } - } else { - pName = presetName; - } - - if (pLibrary == null || typeof pLibrary !== 'string') { - pLibrary = PresetsLibrary.MAIN; - } - - if (typeof pDefaultTexture !== 'string') { - pDefaultTexture = null; - } - - if (typeof pName !== 'string' && !(params instanceof Array)) { - if (!silent) ui.notifications.error(i18n('TMFX.preset.add.params.failure')); - return false; - } - - for (const param of params) { - param.filterId = pName; - } - - let pst = game.settings.get('tokenmagic', 'presets'); - let presetObject = {}; - presetObject.name = pName; - presetObject.library = pLibrary; - presetObject.params = params; - if (pDefaultTexture != null) { - presetObject.defaultTexture = pDefaultTexture; - } - - let state = true; - if (pst == null) { - pst = [presetObject]; - } else { - const preset = pst.find((el) => el['name'] === pName && el['library'] === pLibrary); - if (preset == null) pst.push(presetObject); - else { - if (!silent) ui.notifications.warn(i18n('TMFX.preset.add.duplicate.failure')); - state = false; - } - } - - if (state) { - try { - await game.settings.set('tokenmagic', 'presets', pst); - if (!silent) ui.notifications.info(i18n('TMFX.preset.add.success')); - } catch (e) { - if (!silent) ui.notifications.error(e.message); - console.error(e); - state = false; - } - } - return state; - } - - return { - addFilters: addFilters, - addFiltersOnSelected: addFiltersOnSelected, - addFiltersOnTargeted: addFiltersOnTargeted, - addUpdateFilters: addUpdateFilters, - addUpdateFiltersOnSelected: addUpdateFiltersOnSelected, - addUpdateFiltersOnTargeted: addUpdateFiltersOnTargeted, - deleteFilters: deleteFilters, - deleteFiltersOnSelected: deleteFiltersOnSelected, - deleteFiltersOnTargeted: deleteFiltersOnTargeted, - updateFilters: updateFilters, - updateFiltersOnSelected: updateFiltersOnSelected, - updateFiltersOnTargeted: updateFiltersOnTargeted, - updateFiltersByPlaceable: updateFiltersByPlaceable, - hasFilterType: hasFilterType, - hasFilterId: hasFilterId, - importTemplateSettings: importTemplateSettings, - importTemplateSettingsFromPath: importTemplateSettingsFromPath, - exportTemplateSettings: exportTemplateSettings, - exportPresetLibrary: exportPresetLibrary, - importPresetLibrary: importPresetLibrary, - importPresetLibraryFromURL: importPresetLibraryFromURL, - importPresetLibraryFromPath: importPresetLibraryFromPath, - resetPresetLibrary: resetPresetLibrary, - getPresets: getPresets, - getPreset: getPreset, - addPreset: addPreset, - deletePreset: deletePreset, - getControlledPlaceables: getControlledPlaceables, - getTargetedTokens: getTargetedTokens, - getPlaceableById: getPlaceableById, - get filterTypes() { - return FilterType; - }, - _assignFilters: _assignFilters, - _loadFilters: _loadFilters, - _clearImgFiltersByPlaceable: _clearImgFiltersByPlaceable, - _getAnimeMap: Anime.getAnimeMap, - _updateFilters: _updateFilters, - _updateTemplateData: _updateTemplateData, - _singleLoadFilters: _singleLoadFilters, - _cachedContainer: _cachedContainer, - _checkFilterId: _checkFilterId, - _getPresetTemplateDefaultTexture: _getPresetTemplateDefaultTexture, - }; -} - -export const Magic = TokenMagic(); - -async function compilingShaders() { - // Caching filters to prevent freezing on first-time loading (shader compilation time) - // https://www.html5gamedevs.com/topic/43652-shader-compile-performance/ - - let params = { enabled: true, dummy: true }; - - Magic._cachedContainer.filters = []; - const filterTypes = Object.keys(FilterType); - for (const filterType of filterTypes) { - params.filterType = filterType; - log(`Caching ${filterType}`); - Magic._cachedContainer.filters.push(new FilterType[filterType](params)); - } - - log('Compiling shaders...'); - let tmpRenderTexture = new PIXI.RenderTexture.create({ width: 4, height: 4 }); - // A call to render triggers the compilation of all the shaders bound to the filters. - canvas.app.renderer.render(Magic._cachedContainer, { renderTexture: tmpRenderTexture }); - log('Shaders compiled for the GPU and ready!'); -} - -function initSocketListener() { - // Activate the listener only for the One - const theOne = game.users.find((user) => user.isGM && user.active); - if (theOne && game.user !== theOne) { - return; - } - - // Listener the listening - game.socket.on(moduleTM, async (data) => { - if (data == null || !data.hasOwnProperty('tmAction')) { - return; - } - - async function updateFlags(targetFlag) { - // getting the scene coming from the socket - let scene = game.scenes.get(data.tmViewedScene); - if (scene == null) return; - - // preparing flag data (with -= if the data is null) - let updateData; - if (data.tmFlag == null) updateData = { [`flags.tokenmagic.-=${targetFlag}`]: null }; - else updateData = { [`flags.tokenmagic.${targetFlag}`]: data.tmFlag }; - updateData['_id'] = data.tmPlaceableId; - - // updating the placeable in the scene - await scene.updateEmbeddedDocuments(data.tmPlaceableType, [updateData]); - } - - switch (data.tmAction) { - case SocketAction.SET_FLAG: - await updateFlags(`filters`); - break; - - case SocketAction.SET_ANIME_FLAG: - await updateFlags(`animeInfo`); - break; - } - }); -} - -async function requestLoadFilters(placeable, startTimeout = 0) { - let reqTimer; - placeable.loadingRequest = true; - - function launchRequest(placeable) { - reqTimer = setTimeout(() => { - if (placeable == null) return; - let check = placeable._TMFXcheckSprite(); - if (check == null) { - placeable.loadingRequest = false; - return; - } else if (check) Magic._singleLoadFilters(placeable); - else launchRequest(placeable); - }, 35); - } - - function setRequestTimeOut() { - setTimeout(() => { - clearTimeout(reqTimer); - }, 2000); - } - - setTimeout(() => { - setRequestTimeOut(); - launchRequest(placeable); - }, startTimeout); -} - -function getAnchor(direction, angle, shapeType) { - if (shapeType === 'circle' || shapeType === 'rect') return { x: 0.5, y: 0.5 }; - - // Compute emanation anchor point from the orthonormal bounding rect containing the polygon. - // Not complete (to rework later), but ok with cardinal and half-cardinal directions - let dirRad = (direction * Math.PI) / 180; - let angleRad = (angle * Math.PI) / 180; - - let cosRa1 = Math.cos(dirRad - angleRad / 2); - let rsinRa1 = -Math.sin(dirRad - angleRad / 2); - let cosRa2 = Math.cos(dirRad + angleRad / 2); - let rsinRa2 = -Math.sin(dirRad + angleRad / 2); - - let x = 0, - y = 1; - - if (cosRa1 < 0 && cosRa2 < 0) { - x = 1; - } else if (cosRa1 < 0 || cosRa2 < 0) { - x = (Math.sin(-dirRad - Math.PI / 2) + 1) / 2; - } - - if (rsinRa1 < 0 && rsinRa2 < 0) { - y = 0; - } else if (rsinRa1 < 0 || rsinRa2 < 0) { - y = (Math.cos(-dirRad - Math.PI / 2) + 1) / 2; - } - - return { x: x, y: y }; -} - -function onMeasuredTemplateConfig(data, html) { - if (!isVideoDisabled()) { - html[0].querySelector('.file-picker').dataset.type = 'imagevideo'; - } - - function compare(a, b) { - if (a.name < b.name) return -1; - if (a.name > b.name) return 1; - return 0; - } - - let tmTemplate = data.object; - - if (isNewerVersion(game.version, '0.8')) { - tmTemplate = tmTemplate.object; - } - - let opacity = tmTemplate.template.alpha; - let tint = ''; - let currentPreset = emptyPreset; - - // getting custom data - let tmfxTemplateData = tmTemplate.document.getFlag('tokenmagic', 'templateData'); - if (!(tmfxTemplateData == null) && tmfxTemplateData instanceof Object) { - opacity = tmTemplate.document.tmfxTextureAlpha = tmfxTemplateData.opacity; - tint = tmTemplate.document.tmfxTint = tmfxTemplateData.tint ? PIXI.utils.hex2string(tmfxTemplateData.tint) : ''; - - if (tmfxTemplateData.preset !== undefined) currentPreset = tmfxTemplateData.preset; - } - let filters = tmTemplate.document.getFlag('tokenmagic', 'filters'); - let presets = Magic.getPresets(PresetsLibrary.TEMPLATE); - - if (filters && filters instanceof Array && filters.length >= 1) currentPreset = filters[0].tmFilters.tmFilterId; - - // forming our injected html - let tmfxValues = ''; - let selected = ''; - tmfxValues += ``; - presets.sort(compare).forEach((preset) => { - selected = preset.name === currentPreset ? ' selected' : ''; - tmfxValues += ``; - }); - - let divPreset = ` -
    - -
    - - ${opacity} -
    -
    - -
    - - -
    - -
    - -
    - - -
    -
    - `; - - // injecting - const htmlForm = html.find('.form-group'); - htmlForm.last().after(divPreset); - - $(html).css({ 'min-height': '525px' }); -} - -/* -------------------------------------------- */ -/* Setup Management */ -/* -------------------------------------------- */ - -Hooks.on('ready', () => { - log('Hook -> ready'); - tmfxDataMigration(); - initSocketListener(); - window.TokenMagic = Magic; - - if (!game.modules.get('lib-wrapper')?.active && game.user.isGM) - ui.notifications.warn("The 'Token Magic FX' module recommends to install and activate the 'libWrapper' module."); - - Hooks.on('renderMeasuredTemplateConfig', onMeasuredTemplateConfig); -}); - -/* -------------------------------------------- */ -/* Canvas Management */ -/* -------------------------------------------- */ - -Hooks.once('canvasInit', (canvas) => { - if (!isFilterCachingDisabled()) { - log('Init -> canvasInit -> caching shaders'); - compilingShaders(); - } -}); - -/* -------------------------------------------- */ - -Hooks.on('canvasInit', (canvas) => { - log('Hook -> canvasInit'); - autosetPaddingMode(); - Anime.deactivateAnimation(); - Anime.resetAnimation(); -}); - -/* -------------------------------------------- */ - -Hooks.on('canvasReady', (canvas) => { - log('Hook -> canvasReady'); - if (!window.hasOwnProperty('TokenMagic')) { - window.TokenMagic = Magic; - } - if (canvas == null) { - return; - } - - const tokens = canvas.tokens.placeables; - Magic._loadFilters(tokens); - const tiles = canvas.tiles.placeables; - Magic._loadFilters(tiles); - const drawings = canvas.drawings.placeables; - Magic._loadFilters(drawings); - const templates = canvas.templates.placeables; - Magic._loadFilters(templates); - - Anime.activateAnimation(); -}); - -/* -------------------------------------------- */ -/* Scenes Management */ -/* -------------------------------------------- */ - -Hooks.on('deleteScene', (document) => { - if (document.id !== game.user.viewedScene) return; - Anime.deactivateAnimation(); - Anime.resetAnimation(); -}); - -/* -------------------------------------------- */ -/* Settings Management */ -/* -------------------------------------------- */ - -Hooks.on('closeSettingsConfig', () => { - autosetPaddingMode(); -}); - -/* -------------------------------------------- */ -/* Tokens Management */ -/* -------------------------------------------- */ - -Hooks.on('createToken', (document) => { - if (document.parent.id !== game.user.viewedScene) return; - - if (document.flags?.tokenmagic?.filters) { - let placeable = getPlaceableById(document._id, PlaceableType.TOKEN); - requestLoadFilters(placeable, 250); - } -}); - -/* -------------------------------------------- */ - -Hooks.on('deleteToken', (_, document) => { - if (!(document == null || !document._id)) { - Anime.removeAnimation(document._id); - } -}); - -/* -------------------------------------------- */ - -Hooks.on('updateToken', (document, options) => { - if (document.parent.id !== game.user.viewedScene) return; - - if (['img', 'tint', 'height', 'width', 'name'].some((k) => k in options)) { - let placeable = getPlaceableById(document._id, PlaceableType.TOKEN); - Anime.removeAnimation(document._id); // removing animations on this placeable - Magic._clearImgFiltersByPlaceable(placeable); // clearing the filters (owned by tokenmagic) - requestLoadFilters(placeable, 250); - } else { - Magic._updateFilters(document, options, PlaceableType.TOKEN); - } -}); - -/* -------------------------------------------- */ -/* Tiles Management */ -/* -------------------------------------------- */ - -Hooks.on('createTile', (document) => { - if (document.parent.id !== game.user.viewedScene) return; - - if (document.flags?.tokenmagic?.filters) { - const placeable = getPlaceableById(document._id, PlaceableType.TILE); - requestLoadFilters(placeable, 250); - } -}); - -/* -------------------------------------------- */ - -Hooks.on('deleteTile', (_, document) => { - if (!(document == null || !document._id)) { - Anime.removeAnimation(document._id); - } -}); - -/* -------------------------------------------- */ - -Hooks.on('updateTile', (document, options) => { - if (document.parent.id !== game.user.viewedScene) return; - - if (options.texture?.src || options.overhead) { - const placeable = getPlaceableById(document._id, PlaceableType.TILE); - Anime.removeAnimation(document._id); // removing animations on this placeable - Magic._clearImgFiltersByPlaceable(placeable); // clearing the filters (owned by tokenmagic) - requestLoadFilters(placeable, 250); - } else { - Magic._updateFilters(document, options, PlaceableType.TILE); - } -}); - -/* -------------------------------------------- */ -/* Drawings Management */ -/* -------------------------------------------- */ - -Hooks.on('createDrawing', (document) => { - if (document.parent.id !== game.user.viewedScene) return; - - if (document.flags?.tokenmagic?.filters) { - let placeable = getPlaceableById(document._id, PlaceableType.DRAWING); - requestLoadFilters(placeable, 250); - } -}); - -/* -------------------------------------------- */ - -Hooks.on('deleteDrawing', (_, document) => { - if (!(document == null || !document._id)) { - Anime.removeAnimation(document._id); - } -}); - -/* -------------------------------------------- */ - -Hooks.on('updateDrawing', (document, options) => { - if (document.parent.id !== game.user.viewedScene) return; - - if (!options.flags?.tokenmagic || options.x || options.y) { - let placeable = getPlaceableById(document._id, PlaceableType.DRAWING); - Anime.removeAnimation(document._id); // removing animations on this placeable - Magic._clearImgFiltersByPlaceable(placeable); // clearing the filters (owned by tokenmagic) - requestLoadFilters(placeable, 250); - } else { - Magic._updateFilters(document, options, PlaceableType.DRAWING); - } -}); - -/* -------------------------------------------- */ -/* Measured Templates Management */ -/* -------------------------------------------- */ - -Hooks.on('createMeasuredTemplate', (document) => { - const scene = document.parent; - if (!(scene == null) && scene.id === game.user.viewedScene && document.flags?.tokenmagic?.filters) { - let placeable = getPlaceableById(document._id, PlaceableType.TEMPLATE); - requestLoadFilters(placeable, 250); // request to load filters (when pixi containers are ready) - } -}); - -/* -------------------------------------------- */ - -Hooks.on('deleteMeasuredTemplate', (_, document) => { - if (!(document == null || !document._id)) { - Anime.removeAnimation(document._id); - } -}); - -/* -------------------------------------------- */ - -Hooks.on('updateMeasuredTemplate', (document, options) => { - if (document.parent.id !== game.user.viewedScene) return; - let placeable = getPlaceableById(document._id, PlaceableType.TEMPLATE); - if (!placeable) return; - - if (options.texture) { - Anime.removeAnimation(document._id); // removing animations on this placeable - Magic._clearImgFiltersByPlaceable(placeable); // clearing the filters (owned by tokenmagic) - requestLoadFilters(placeable, 250); // querying filters reload (when pixi containers are ready) - } else { - if (!placeable.loadingRequest) { - Magic._updateFilters(document, options, PlaceableType.TEMPLATE); - Magic._updateTemplateData(document, options, PlaceableType.TEMPLATE); - } - } -}); - -/* -------------------------------------------- */ - -Hooks.on('preUpdateMeasuredTemplate', async (document, options) => { - function getTint() { - if (options.flags?.tokenmagic?.templateData?.tint !== undefined) { - return options.flags.tokenmagic.templateData.tint; - } else if (document.flags?.tokenmagic?.tint !== undefined) { - return document.flags.tokenmagic.tint; - } else return ''; - } - - function getFX() { - if (options.flags?.tokenmagic?.templateData?.preset !== undefined) { - return options.flags.tokenmagic.templateData.preset; - } else if (document.flags?.tokenmagic?.templateData?.preset !== undefined) { - return document.flags.tokenmagic.templateData.preset; - } else if (document.tmfxPreset !== undefined) { - return document.tmfxPreset; - } else return emptyPreset; - } - - function getDirection() { - if (options.direction) { - return options.direction; - } else if (document.direction) { - return document.direction; - } else return 0; - } - - function getAngle() { - if (options.angle) { - return options.angle; - } else if (document.angle) { - return document.angle; - } else return 0; - } - - function getShapeType() { - if (options.t) { - return options.t; - } else if (document.t) { - return document.t; - } else return 'ITSBAD'; - } - - let measuredTemplateInstance = canvas.templates.get(document._id); - let templateTint = getTint(); - let presetUpdate = options.flags?.tokenmagic?.templateData?.preset !== undefined; - let tintUpdate = options.flags?.tokenmagic?.templateData?.tint !== undefined; - let directionUpdate = options.hasOwnProperty('direction'); - let angleUpdate = options.hasOwnProperty('angle'); - let typeUpdate = options.hasOwnProperty('t'); - - if (tintUpdate) - options.flags.tokenmagic.templateData.tint = templateTint !== '' ? Color.from(templateTint).valueOf() : null; - - if (presetUpdate || tintUpdate || directionUpdate || typeUpdate || angleUpdate) { - let templateFX = getFX(); - if (templateFX !== emptyPreset) { - let anchor = getAnchor(getDirection(), getAngle(), getShapeType()); - let presetOptions = { - name: templateFX, - library: PresetsLibrary.TEMPLATE, - anchorX: anchor.x, - anchorY: anchor.y, - }; - if (templateTint && templateTint !== '') { - presetOptions.color = Color.from(templateTint).valueOf(); - } - let preset = Magic.getPreset(presetOptions); - if (!(preset == null)) { - if (presetUpdate) await measuredTemplateInstance.TMFXaddFilters(preset, true); - else await measuredTemplateInstance.TMFXaddUpdateFilters(preset); - } - } else await measuredTemplateInstance.TMFXdeleteFilters(); - } -}); - -/* -------------------------------------------- */ - -Hooks.on('preCreateMeasuredTemplate', (document) => { - // Do nothing if we're on a 3D Canvas scene - if (game.Levels3DPreview?._active) return; - - // Apply auto-preset if needed - const templates = TokenMagicSettings.getSystemTemplates(); - if (templates?.enabled) { - templates.preCreateMeasuredTemplate?.(document); - } - - const hasFlags = document.flags; - let hasPreset = false; - let hasTint = false; - let hasOpacity = false; - let hasFlagsNoOptions = false; - - if (hasFlags && document.flags.tokenmagic?.options) { - const opt = document.flags.tokenmagic.options; - if (opt.tmfxPreset) { - document.tmfxPreset = opt.tmfxPreset; - hasPreset = true; - } - if (opt.tmfxTint) { - document.tmfxTint = opt.tmfxTint; - hasTint = true; - } - if (opt.tmfxTextureAlpha) { - document.tmfxTextureAlpha = opt.tmfxTextureAlpha; - hasOpacity = true; - } - if (opt.tmfxTexture) { - document.texture = opt.tmfxTexture; - document.updateSource({ texture: opt.tmfxTexture }); - } - } else hasFlagsNoOptions = true; - - let hasTexture = document.texture && document.texture !== ''; - let newFilters = []; - - let tmfxBaseFlags = { tokenmagic: { filters: null, templateData: null, options: null } }; - if (hasFlags && hasFlagsNoOptions) { - // the measured template comes with tokenmagic flags ? It is a copy ! We do nothing. - if (document.flags.tokenmagic) { - return; - } - document.flags = mergeObject(document.flags, tmfxBaseFlags, true, true); - } - - // normalizing color to value if needed - if (hasTint && typeof document.tmfxTint !== 'number') { - document.tmfxTint = Color.from(document.tmfxTint).valueOf(); - } - - let tmfxFiltersData = null; - - // FX to add ? - if (hasPreset) { - // Compute shader anchor point - let anchor = getAnchor(document.direction, document.angle, document.t); - - // Constructing the preset search object - let pstSearch = { - name: document.tmfxPreset, - library: PresetsLibrary.TEMPLATE, - anchorX: anchor.x, - anchorY: anchor.y, - }; - - // Adding tint if needed - if (hasTint) pstSearch.color = document.tmfxTint; - - // Retrieving the preset - let preset = Magic.getPreset(pstSearch); - - if (!(preset == null) && preset instanceof Array) { - let defaultTex = Magic._getPresetTemplateDefaultTexture(pstSearch.name); - if (!(defaultTex == null) && !hasTexture) { - document.updateSource({ texture: defaultTex }); - } - - let persist = true; - - // Constructing the filter flag parameters - for (const params of preset) { - if (!params.filterType || !FilterType.hasOwnProperty(params.filterType)) { - // one invalid ? all rejected. - persist = false; - break; - } - - // getPreset MUST provide a filter id - if (!params.filterId) { - persist = false; - break; - } - - if (!params.enabled || !(typeof params.enabled === 'boolean')) { - params.enabled = true; - } - - params.placeableId = null; - params.filterInternalId = randomID(); - params.filterOwner = game.data.userId; - params.placeableType = PlaceableType.TEMPLATE; - - newFilters.push({ - tmFilters: { - tmFilterId: params.filterId, - tmFilterInternalId: params.filterInternalId, - tmFilterType: params.filterType, - tmFilterOwner: params.filterOwner, - tmParams: params, - }, - }); - } - - if (persist) tmfxFiltersData = newFilters; - } - } else { - document.tmfxPreset = emptyPreset; - } - - if (!hasOpacity) document.tmfxTextureAlpha = 1; - if (!hasTint) document.tmfxTint = null; - - let tmfxFlags = { - templateData: { - opacity: document.tmfxTextureAlpha, - tint: document.tmfxTint, - }, - filters: tmfxFiltersData, - options: null, - }; - document.updateSource({ flags: { tokenmagic: tmfxFlags } }); -}); diff --git a/tokenmagic/packs/token-magic-book-of-fire/000386.log b/tokenmagic/packs/token-magic-book-of-fire/000386.log deleted file mode 100644 index e69de29..0000000 diff --git a/tokenmagic/packs/token-magic-book-of-fire/CURRENT b/tokenmagic/packs/token-magic-book-of-fire/CURRENT deleted file mode 100644 index 70d8a3a..0000000 --- a/tokenmagic/packs/token-magic-book-of-fire/CURRENT +++ /dev/null @@ -1 +0,0 @@ -MANIFEST-000384 diff --git a/tokenmagic/packs/token-magic-book-of-fire/LOG b/tokenmagic/packs/token-magic-book-of-fire/LOG deleted file mode 100644 index d690091..0000000 --- a/tokenmagic/packs/token-magic-book-of-fire/LOG +++ /dev/null @@ -1,7 +0,0 @@ -2023/11/01-09:21:40.153 41d8 Recovering log #382 -2023/11/01-09:21:40.159 41d8 Delete type=0 #382 -2023/11/01-09:21:40.160 41d8 Delete type=3 #380 -2023/11/01-10:26:08.102 4384 Level-0 table #387: started -2023/11/01-10:26:08.102 4384 Level-0 table #387: 0 bytes OK -2023/11/01-10:26:08.105 4384 Delete type=0 #385 -2023/11/01-10:26:08.105 4384 Manual compaction at level-0 from '!macros!8aHbX9wGc5ih56Gx' @ 72057594037927935 : 1 .. '!macros!ygP4EwZGwIChqLwG' @ 0 : 0; will stop at (end) diff --git a/tokenmagic/packs/token-magic-book-of-fire/LOG.old b/tokenmagic/packs/token-magic-book-of-fire/LOG.old deleted file mode 100644 index 9215945..0000000 --- a/tokenmagic/packs/token-magic-book-of-fire/LOG.old +++ /dev/null @@ -1,7 +0,0 @@ -2023/10/28-19:22:08.164 234c Recovering log #378 -2023/10/28-19:22:08.169 234c Delete type=0 #378 -2023/10/28-19:22:08.169 234c Delete type=3 #376 -2023/10/28-19:22:53.794 5a5c Level-0 table #383: started -2023/10/28-19:22:53.795 5a5c Level-0 table #383: 0 bytes OK -2023/10/28-19:22:53.796 5a5c Delete type=0 #381 -2023/10/28-19:22:53.797 5a5c Manual compaction at level-0 from '!macros!8aHbX9wGc5ih56Gx' @ 72057594037927935 : 1 .. '!macros!ygP4EwZGwIChqLwG' @ 0 : 0; will stop at (end) diff --git a/tokenmagic/packs/token-magic-portfolio/000389.log b/tokenmagic/packs/token-magic-portfolio/000389.log deleted file mode 100644 index e69de29..0000000 diff --git a/tokenmagic/packs/token-magic-portfolio/CURRENT b/tokenmagic/packs/token-magic-portfolio/CURRENT deleted file mode 100644 index 99be12b..0000000 --- a/tokenmagic/packs/token-magic-portfolio/CURRENT +++ /dev/null @@ -1 +0,0 @@ -MANIFEST-000387 diff --git a/tokenmagic/packs/token-magic-portfolio/LOG b/tokenmagic/packs/token-magic-portfolio/LOG deleted file mode 100644 index 0c303c1..0000000 --- a/tokenmagic/packs/token-magic-portfolio/LOG +++ /dev/null @@ -1,7 +0,0 @@ -2023/11/01-09:21:40.130 2900 Recovering log #385 -2023/11/01-09:21:40.136 2900 Delete type=0 #385 -2023/11/01-09:21:40.136 2900 Delete type=3 #383 -2023/11/01-10:26:08.099 4384 Level-0 table #390: started -2023/11/01-10:26:08.099 4384 Level-0 table #390: 0 bytes OK -2023/11/01-10:26:08.101 4384 Delete type=0 #388 -2023/11/01-10:26:08.105 4384 Manual compaction at level-0 from '!macros!0U6lS2hR1uMm7iFI' @ 72057594037927935 : 1 .. '!macros!zLsUrLWfdJn7BjTw' @ 0 : 0; will stop at (end) diff --git a/tokenmagic/packs/token-magic-portfolio/LOG.old b/tokenmagic/packs/token-magic-portfolio/LOG.old deleted file mode 100644 index a164645..0000000 --- a/tokenmagic/packs/token-magic-portfolio/LOG.old +++ /dev/null @@ -1,7 +0,0 @@ -2023/10/28-19:22:08.152 3478 Recovering log #381 -2023/10/28-19:22:08.158 3478 Delete type=0 #381 -2023/10/28-19:22:08.159 3478 Delete type=3 #379 -2023/10/28-19:22:53.789 5a5c Level-0 table #386: started -2023/10/28-19:22:53.789 5a5c Level-0 table #386: 0 bytes OK -2023/10/28-19:22:53.790 5a5c Delete type=0 #384 -2023/10/28-19:22:53.791 5a5c Manual compaction at level-0 from '!macros!0U6lS2hR1uMm7iFI' @ 72057594037927935 : 1 .. '!macros!zLsUrLWfdJn7BjTw' @ 0 : 0; will stop at (end) diff --git a/tokenmagic/styles/tokenmagic.css b/tokenmagic/styles/tokenmagic.css deleted file mode 100644 index 8e874e2..0000000 --- a/tokenmagic/styles/tokenmagic.css +++ /dev/null @@ -1,30 +0,0 @@ -.tokenmagic.settings nav.tabs { - flex: 0 0 32px; - line-height: 32px; - font-size: 16px; - border-bottom: 1px solid #000; -} - -.tokenmagic.settings section.content { - border-top: 1px solid #b5b3a4; -} - -.tokenmagic.settings section.content .settings-list { - max-height: calc(100vh - 150px); - overflow-y: auto; - padding-right: 0.5em; -} - -.tokenmagic.settings div.override-entry { - padding: 0.5em 0; - border-top: 1px solid #b5b3a4; -} - -.tokenmagic.settings div.remove-override-wrapper { - flex: 0; - margin-left: 0.5em; -} - -.tokenmagic.settings footer.add-override-wrapper { - margin-bottom: 0.5em; -} \ No newline at end of file diff --git a/utils/clean.mjs b/utils/clean.mjs new file mode 100644 index 0000000..15c9191 --- /dev/null +++ b/utils/clean.mjs @@ -0,0 +1,17 @@ +import fs from "fs"; +import path from "path"; + +// Clean output directory, or create build directory +const outDir = path.resolve(process.cwd(), "dist"); +if (fs.existsSync(outDir)) { + const filesToClean = fs.readdirSync(outDir).map((dirName) => path.resolve(outDir, dirName)); + for (const file of filesToClean) { + fs.rmSync(file, { recursive: true }); + } +} else { + fs.mkdirSync(outDir); +} + +// Delete static/packs dir to prevent overwrite during rebuilds (temporary backwards compatibility) +// const oldPacksDir = path.resolve(process.cwd(), "static/packs"); +// fs.rmSync(oldPacksDir, { recursive: true, force: true }); diff --git a/utils/packs.mjs b/utils/packs.mjs new file mode 100644 index 0000000..2fc7550 --- /dev/null +++ b/utils/packs.mjs @@ -0,0 +1,282 @@ + +import fs from "fs"; +import { readdir, readFile, writeFile } from "node:fs/promises"; +import logger from "fancy-log"; +import path from "path"; +import yargs from "yargs"; +import { hideBin } from "yargs/helpers"; +import { compilePack, extractPack } from "@foundryvtt/foundryvtt-cli"; +import { fileURLToPath } from "url"; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); + +const BASE_FULL_PATH_MODULE = path.resolve(path.join(path.resolve(__dirname, '..'),"src")); +const MODULE_JSON_FULL_PATH = path.join(BASE_FULL_PATH_MODULE,"module.json"); // MOD 4535992 + +/** + * Folder where the compiled compendium packs should be located relative to the + * base module folder. + * @type {string} + */ +const PACK_DEST = path.join(BASE_FULL_PATH_MODULE,"packs"); + +/** + * Folder where source JSON files should be located relative to the module folder. + * @type {string} + */ +const PACK_SRC = path.join(BASE_FULL_PATH_MODULE,"packs/_source"); + + +// eslint-disable-next-line +const argv = yargs(hideBin(process.argv)) + .command(packageCommand()) + .help().alias("help", "h") + .argv; + + +// eslint-disable-next-line +function packageCommand() { + return { + command: "package [action] [pack] [entry]", + describe: "Manage packages", + builder: yargs => { + yargs.positional("action", { + describe: "The action to perform.", + type: "string", + choices: ["unpack", "pack", "clean"] + }); + yargs.positional("pack", { + describe: "Name of the pack upon which to work.", + type: "string" + }); + yargs.positional("entry", { + describe: "Name of any entry within a pack upon which to work. Only applicable to extract & clean commands.", + type: "string" + }); + }, + handler: async argv => { + const { action, pack, entry } = argv; + switch ( action ) { + case "clean": + return await cleanPacks(pack, entry); + case "pack": + return await compilePacks(pack); + case "unpack": + return await extractPacks(pack, entry); + } + } + }; +} + + +/* ----------------------------------------- */ +/* Clean Packs */ +/* ----------------------------------------- */ + +/** + * Removes unwanted flags, permissions, and other data from entries before extracting or compiling. + * @param {object} data Data for a single entry to clean. + * @param {object} [options={}] + * @param {boolean} [options.clearSourceId=true] Should the core sourceId flag be deleted. + * @param {number} [options.ownership=0] Value to reset default ownership to. + */ +function cleanPackEntry(data, { clearSourceId=true, ownership=0 }={}) { + if ( data.ownership ) data.ownership = { default: ownership }; + if ( clearSourceId ) delete data.flags?.core?.sourceId; + delete data.flags?.importSource; + delete data.flags?.exportSource; + if ( data._stats?.lastModifiedBy ) data._stats.lastModifiedBy = "packsbuilder0000"; + + // Remove empty entries in flags + if ( !data.flags ) data.flags = {}; + Object.entries(data.flags).forEach(([key, contents]) => { + if (contents && Object.keys(contents).length === 0 ) delete data.flags[key]; + }); + + if ( data.system?.activation?.cost === 0 ) data.system.activation.cost = null; + if ( data.system?.duration?.value === "0" ) data.system.duration.value = ""; + if ( data.system?.target?.value === 0 ) data.system.target.value = null; + if ( data.system?.target?.width === 0 ) data.system.target.width = null; + if ( data.system?.range?.value === 0 ) data.system.range.value = null; + if ( data.system?.range?.long === 0 ) data.system.range.long = null; + if ( data.system?.uses?.value === 0 ) data.system.uses.value = null; + if ( data.system?.uses?.max === "0" ) data.system.duration.value = ""; + if ( data.system?.save?.dc === 0 ) data.system.save.dc = null; + if ( data.system?.capacity?.value === 0 ) data.system.capacity.value = null; + if ( data.system?.strength === 0 ) data.system.strength = null; + + // Remove mystery-man.svg from Actors + if ( ["character", "npc"].includes(data.type) && data.img === "icons/svg/mystery-man.svg" ) { + data.img = ""; + data.prototypeToken.texture.src = ""; + } + + if ( data.effects ) data.effects.forEach(i => cleanPackEntry(i, { clearSourceId: false })); + if ( data.items ) data.items.forEach(i => cleanPackEntry(i, { clearSourceId: false })); + if ( data.pages ) data.pages.forEach(i => cleanPackEntry(i, { ownership: -1 })); + if ( data.system?.description?.value ) data.system.description.value = cleanString(data.system.description.value); + if ( data.label ) data.label = cleanString(data.label); + if ( data.name ) data.name = cleanString(data.name); +} + + +/** + * Removes invisible whitespace characters and normalizes single- and double-quotes. + * @param {string} str The string to be cleaned. + * @returns {string} The cleaned string. + */ +function cleanString(str) { + return str.replace(/\u2060/gu, "").replace(/[‘’]/gu, "'").replace(/[“”]/gu, '"'); +} + + +/** + * Cleans and formats source JSON files, removing unnecessary permissions and flags and adding the proper spacing. + * @param {string} [packName] Name of pack to clean. If none provided, all packs will be cleaned. + * @param {string} [entryName] Name of a specific entry to clean. + * + * - `npm run build:clean` - Clean all source JSON files. + * - `npm run build:clean -- classes` - Only clean the source files for the specified compendium. + * - `npm run build:clean -- classes Barbarian` - Only clean a single item from the specified compendium. + */ +async function cleanPacks(packName, entryName) { + entryName = entryName?.toLowerCase(); + const folders = fs.readdirSync(PACK_SRC, { withFileTypes: true }).filter(file => + file.isDirectory() && ( !packName || (packName === file.name) ) + ); + + /** + * Walk through directories to find JSON files. + * @param {string} directoryPath + * @yields {string} + */ + async function* _walkDir(directoryPath) { + const directory = await readdir(directoryPath, { withFileTypes: true }); + for ( const entry of directory ) { + const entryPath = path.join(directoryPath, entry.name); + if ( entry.isDirectory() ) yield* _walkDir(entryPath); + else if ( path.extname(entry.name) === ".json" ) yield entryPath; + } + } + + for ( const folder of folders ) { + logger.info(`Cleaning pack ${folder.name}`); + for await ( const src of _walkDir(path.join(PACK_SRC, folder.name)) ) { + const json = JSON.parse(await readFile(src, { encoding: "utf8" })); + if ( entryName && (entryName !== json.name.toLowerCase()) ) continue; + if ( !json._id || !json._key ) { + console.log(`Failed to clean \x1b[31m${src}\x1b[0m, must have _id and _key.`); + continue; + } + cleanPackEntry(json); + fs.rmSync(src, { force: true }); + writeFile(src, `${JSON.stringify(json, null, 2)}\n`, { mode: 0o664 }); + } + } +} + + +/* ----------------------------------------- */ +/* Compile Packs */ +/* ----------------------------------------- */ + +/** + * Compile the source JSON files into compendium packs. + * @param {string} [packName] Name of pack to compile. If none provided, all packs will be packed. + * + * - `npm run build:db` - Compile all JSON files into their LevelDB files. + * - `npm run build:db -- classes` - Only compile the specified pack. + */ +async function compilePacks(packName) { + // Determine which source folders to process + const folders = fs.readdirSync(PACK_SRC, { withFileTypes: true }).filter(file => + file.isDirectory() && ( !packName || (packName === file.name) ) + ); + + for ( const folder of folders ) { + const src = path.join(PACK_SRC, folder.name); + const dest = path.join(PACK_DEST, folder.name); + logger.info(`Compiling pack ${folder.name}`); + await compilePack(src, dest, { recursive: true, log: true, transformEntry: cleanPackEntry }); + } +} + + +/* ----------------------------------------- */ +/* Extract Packs */ +/* ----------------------------------------- */ + +/** + * Extract the contents of compendium packs to JSON files. + * @param {string} [packName] Name of pack to extract. If none provided, all packs will be unpacked. + * @param {string} [entryName] Name of a specific entry to extract. + * + * - `npm build:json - Extract all compendium LevelDB files into JSON files. + * - `npm build:json -- classes` - Only extract the contents of the specified compendium. + * - `npm build:json -- classes Barbarian` - Only extract a single item from the specified compendium. + */ +async function extractPacks(packName, entryName) { + entryName = entryName?.toLowerCase(); + + // Load module.json. + const module = JSON.parse(fs.readFileSync(MODULE_JSON_FULL_PATH, { encoding: "utf8" })); // MOD 4535992 /src/module.json instead ./system.json and rename system to module + + // Determine which source packs to process. + const packs = module.packs.filter(p => !packName || p.name === packName); + + for ( const packInfo of packs ) { + const dest = path.join(PACK_SRC, packInfo.name); + const packInfoPath = path.join(PACK_DEST, packInfo.name); // MOD 4535992 + logger.info(`Extracting pack ${packInfo.name} from ${packInfoPath} to ${dest}`); + + const folders = {}; + const containers = {}; + await extractPack(packInfoPath, dest, { + log: false, transformEntry: e => { + if ( e._key.startsWith("!folders") ) folders[e._id] = { name: slugify(e.name), folder: e.folder }; + else if ( e.type === "container" ) containers[e._id] = { + name: slugify(e.name), container: e.system?.container, folder: e.folder + }; + return false; + } + }); + const buildPath = (collection, entry, parentKey) => { + let parent = collection[entry[parentKey]]; + entry.path = entry.name; + while ( parent ) { + entry.path = path.join(parent.name, entry.path); + parent = collection[parent[parentKey]]; + } + }; + Object.values(folders).forEach(f => buildPath(folders, f, "folder")); + Object.values(containers).forEach(c => { + buildPath(containers, c, "container"); + const folder = folders[c.folder]; + if ( folder ) c.path = path.join(folder.path, c.path); + }); + + await extractPack(packInfoPath, dest, { + log: true, transformEntry: entry => { + if ( entryName && (entryName !== entry.name.toLowerCase()) ) return false; + cleanPackEntry(entry); + }, transformName: entry => { + if ( entry._id in folders ) return path.join(folders[entry._id].path, "_folder.json"); + if ( entry._id in containers ) return path.join(containers[entry._id].path, "_container.json"); + const outputName = slugify(entry.name); + const parent = containers[entry.system?.container] ?? folders[entry.folder]; + return path.join(parent?.path ?? "", `${outputName}.json`); + } + }); + } +} + + +/** + * Standardize name format. + * @param {string} name + * @returns {string} + */ +function slugify(name) { + return name.toLowerCase().replace("'", "").replace(/[^a-z0-9]+/gi, " ").trim().replace(/\s+|-{2,}/g, "-"); +} diff --git a/vite.config.mjs b/vite.config.mjs new file mode 100644 index 0000000..41cfeac --- /dev/null +++ b/vite.config.mjs @@ -0,0 +1,215 @@ +import { svelte } from "@sveltejs/vite-plugin-svelte"; +import resolve from "@rollup/plugin-node-resolve"; // This resolves NPM modules from node_modules. +import preprocess from "svelte-preprocess"; +import { + postcssConfig, + terserConfig, + typhonjsRuntime +} from '@typhonjs-fvtt/runtime/rollup'; +import { viteStaticCopy } from 'vite-plugin-static-copy'; +import cleanPlugin from 'vite-plugin-clean'; +import { normalizePath } from 'vite'; +import path from 'path'; +import { run } from 'vite-plugin-run' + +// ATTENTION! +// Please modify the below variables: s_PACKAGE_ID and s_SVELTE_HASH_ID appropriately. + +// For convenience, you just need to modify the package ID below as it is used to fill in default proxy settings for +// the dev server. +const s_MODULE_ID = "tokenmagic"; +const s_PACKAGE_ID = "modules/"+s_MODULE_ID; +const s_ENTRY_JAVASCRIPT = "module.js"; + +// A short additional string to add to Svelte CSS hash values to make yours unique. This reduces the amount of +// duplicated framework CSS overlap between many TRL packages enabled on Foundry VTT at the same time. 'ese' is chosen +// by shortening 'essential-svelte-esm'. +const s_SVELTE_HASH_ID = "ese"; + +const s_COMPRESS = false; // Set to true to compress the module bundle. +const s_SOURCEMAPS = true; // Generate sourcemaps for the bundle (recommended). + +// EXPERIMENTAL: Set to true to enable linking against the TyphonJS Runtime Library module. +// You must add a Foundry module dependency on the `typhonjs` Foundry package or manually install it in Foundry from: +// https://github.com/typhonjs-fvtt-lib/typhonjs/releases/latest/download/module.json +const s_TYPHONJS_MODULE_LIB = false; + +// Used in bundling particularly during development. If you npm-link packages to your project add them here. +const s_RESOLVE_CONFIG = { + browser: true, + dedupe: ["svelte"], +}; + +// ATTENTION! +// You must change `base` and the `proxy` strings replacing `/modules/${s_MODULE_ID}/` with your +// module or system ID. + +export default () => { + /** @type {import('vite').UserConfig} */ + return { + root: "src/", // Source location / esbuild root. + base: `/${s_PACKAGE_ID}/`, // Base module path that 30001 / served dev directory. + publicDir: false, // No public resources to copy. + cacheDir: "../.vite-cache", // Relative from root directory. + + resolve: { conditions: ["import", "browser"] }, + + esbuild: { + target: ['es2022', 'chrome100'], + keepNames: true // Note: doesn't seem to work. + }, + + css: { + // Creates a standard configuration for PostCSS with autoprefixer & postcss-preset-env. + postcss: postcssConfig({ + compress: s_COMPRESS, + sourceMap: s_SOURCEMAPS + }), + }, + + // About server options: + // - Set to `open` to boolean `false` to not open a browser window automatically. This is useful if you set up a + // debugger instance in your IDE and launch it with the URL: 'http://localhost:30001/game'. + // + // - The top proxy entry redirects requests under the module path for `style.css` and following standard static + // directories: `assets`, `lang`, and `packs` and will pull those resources from the main Foundry / 30000 server. + // This is necessary to reference the dev resources as the root is `/src` and there is no public / static + // resources served with this particular Vite configuration. Modify the proxy rule as necessary for your + // static resources / project. + server: { + port: 29999, + open: "/game", + // open: false, + proxy: { + // Serves static files from main Foundry server. + [`^(/${s_PACKAGE_ID}/(images|fonts|assets|fx|gui|import|libs|lang|languages|packs|styles|templates|style.css))`]: + "http://127.0.0.1:30000", + + // All other paths besides package ID path are served from main Foundry server. + [`^(?!/${s_PACKAGE_ID}/)`]: "http://127.0.0.1:30000", + + // Enable socket.io from main Foundry server. + "/socket.io": { target: "ws://127.0.0.1:30000", ws: true }, + }, + }, + + build: { + outDir: normalizePath( path.resolve(__dirname, `./dist/${s_MODULE_ID}`)), // __dirname, + emptyOutDir: false, + sourcemap: s_SOURCEMAPS, + brotliSize: true, + minify: s_COMPRESS ? "terser" : false, + target: ['es2022', 'chrome100'], + terserOptions: s_COMPRESS ? { ...terserConfig(), ecma: 2022 } : void 0, + lib: { + entry: "./" + s_ENTRY_JAVASCRIPT, // "./module.js" + formats: ["es"], + fileName: "module", + }, + }, + + // Necessary when using the dev server for top-level await usage inside of TRL. + optimizeDeps: { + esbuildOptions: { + target: 'es2022' + } + }, + + plugins: [ + run([ + { + name: 'run sass', + run: ['sass', `src/styles:dist/${s_MODULE_ID}/styles`] + }, + ]), + viteStaticCopy({ + targets: [ + { + src: normalizePath(path.resolve(__dirname, './src/assets')) + '/[!.]*', // 1️ + dest: normalizePath(path.resolve(__dirname, `./dist/${s_MODULE_ID}/assets`)), // 2️ + }, + { + src: normalizePath(path.resolve(__dirname, './src/fx')) + '/[!.]*', // 1️ + dest: normalizePath(path.resolve(__dirname, `./dist/${s_MODULE_ID}/fx`)), // 2️ + }, + { + src: normalizePath(path.resolve(__dirname, './src/gui')) + '/[!.]*', // 1️ + dest: normalizePath(path.resolve(__dirname, `./dist/${s_MODULE_ID}/gui`)), // 2️ + }, + { + src: normalizePath(path.resolve(__dirname, './src/import')) + '/[!.]*', // 1️ + dest: normalizePath(path.resolve(__dirname, `./dist/${s_MODULE_ID}/import`)), // 2️ + }, + { + src: normalizePath(path.resolve(__dirname, './src/libs')) + '/[!.]*', // 1️ + dest: normalizePath(path.resolve(__dirname, `./dist/${s_MODULE_ID}/libs`)), // 2️ + }, + { + src: normalizePath(path.resolve(__dirname, './src/images')) + '/[!.]*', // 1️ + dest: normalizePath(path.resolve(__dirname, `./dist/${s_MODULE_ID}/images`)), // 2️ + }, + { + src: normalizePath(path.resolve(__dirname, './src/icons')) + '/[!.]*', // 1️ + dest: normalizePath(path.resolve(__dirname, `./dist/${s_MODULE_ID}/icons`)), // 2️ + }, + { + src: normalizePath(path.resolve(__dirname, './src/templates')) + '/[!.]*', // 1️ + dest: normalizePath(path.resolve(__dirname, `./dist/${s_MODULE_ID}/templates`)), // 2️ + }, + { + src: normalizePath(path.resolve(__dirname, './src/lang')) + '/[!.]*', + dest: normalizePath(path.resolve(__dirname, `./dist/${s_MODULE_ID}/lang`)), + }, + { + src: normalizePath(path.resolve(__dirname, './src/languages')) + '/[!.]*', + dest: normalizePath(path.resolve(__dirname, `./dist/${s_MODULE_ID}/languages`)), + }, + { + src: normalizePath(path.resolve(__dirname, './src/styles')) + '/**/*.css', + dest: normalizePath(path.resolve(__dirname, `./dist/${s_MODULE_ID}/styles`)), + }, + { + src: normalizePath(path.resolve(__dirname, './src/packs')) + '/[!.^(_?.*)]*', // + '/[!.^(_source)]*', + dest: normalizePath(path.resolve(__dirname, `./dist/${s_MODULE_ID}/packs`)), + }, + { + src: normalizePath(path.resolve(__dirname, './src/module.json')), + dest: normalizePath(path.resolve(__dirname, `./dist/${s_MODULE_ID}/`)), + }, + { + src: normalizePath(path.resolve(__dirname, './src/scripts/libs')) + '/[!.]*', + dest: normalizePath(path.resolve(__dirname, `./dist/${s_MODULE_ID}/scripts/libs`)), + }, + ], + }), + svelte({ + compilerOptions: { + // Provides a custom hash adding the string defined in `s_SVELTE_HASH_ID` to scoped Svelte styles; + // This is reasonable to do as the framework styles in TRL compiled across `n` different packages will + // be the same. Slightly modifying the hash ensures that your package has uniquely scoped styles for all + // TRL components and makes it easier to review styles in the browser debugger. + cssHash: ({ hash, css }) => `svelte-${s_SVELTE_HASH_ID}-${hash(css)}`, + }, + preprocess: preprocess(), + onwarn: (warning, handler) => { + // Suppress `a11y-missing-attribute` for missing href in links. + // Foundry doesn't follow accessibility rules. + if (warning.message.includes(` element should have an href attribute`)) { + return; + } + + // Let Rollup handle all other warnings normally. + handler(warning); + }, + }), + + resolve(s_RESOLVE_CONFIG), // Necessary when bundling npm-linked packages. + + // When s_TYPHONJS_MODULE_LIB is true transpile against the Foundry module version of TRL. + s_TYPHONJS_MODULE_LIB && typhonjsRuntime(), + + cleanPlugin() + ] + }; +}; + diff --git a/images/Compendium.JPG b/wiki/images/Compendium.JPG similarity index 100% rename from images/Compendium.JPG rename to wiki/images/Compendium.JPG diff --git a/images/SimpleGUIMacro-01.jpg b/wiki/images/SimpleGUIMacro-01.jpg similarity index 100% rename from images/SimpleGUIMacro-01.jpg rename to wiki/images/SimpleGUIMacro-01.jpg diff --git a/images/template-settings-base.png b/wiki/images/template-settings-base.png similarity index 100% rename from images/template-settings-base.png rename to wiki/images/template-settings-base.png diff --git a/images/template-settings-overrides.png b/wiki/images/template-settings-overrides.png similarity index 100% rename from images/template-settings-overrides.png rename to wiki/images/template-settings-overrides.png diff --git a/images/template-settings.png b/wiki/images/template-settings.png similarity index 100% rename from images/template-settings.png rename to wiki/images/template-settings.png diff --git a/images/templates-ex.png b/wiki/images/templates-ex.png similarity index 100% rename from images/templates-ex.png rename to wiki/images/templates-ex.png