From 102958ca1403cf72322c66ecc185dd79eb9ccb4b Mon Sep 17 00:00:00 2001 From: Ludovic D Date: Wed, 5 Aug 2020 12:49:41 +0200 Subject: [PATCH] Update v0.2.1 --- .vs/Tokenmagic/v16/.suo | Bin 151040 -> 162816 bytes .vs/VSWorkspaceState.json | 7 +- .vs/slnx.sqlite | Bin 90112 -> 90112 bytes README.md | 159 ++ Tokenmagic.zip | Bin 22099393 -> 22116684 bytes tokenmagic/fx/filters/FilterColorMatrix.js | 20 - tokenmagic/fx/filters/FilterElectric.js | 6 +- tokenmagic/fx/filters/FilterFire.js | 6 +- tokenmagic/fx/filters/FilterForceField.js | 6 +- tokenmagic/fx/filters/FilterGleamingGlow.js | 6 +- tokenmagic/fx/filters/FilterMirrorImages.js | 65 +- tokenmagic/fx/filters/FilterPixelate.js | 36 + tokenmagic/fx/filters/FilterSmoke.js | 6 +- tokenmagic/fx/filters/proto/FilterProto.js | 21 +- .../fx/glsl/fragmentshaders/cosmicray.js | 2 +- .../fx/glsl/fragmentshaders/electricity.js | 6 +- tokenmagic/fx/glsl/fragmentshaders/flood.js | 4 +- tokenmagic/fx/glsl/fragmentshaders/fog.js | 4 +- .../fx/glsl/fragmentshaders/forcefield.js | 88 +- tokenmagic/fx/glsl/fragmentshaders/fumes.js | 4 +- tokenmagic/fx/glsl/fragmentshaders/liquid.js | 16 +- .../fx/glsl/fragmentshaders/magicglow.js | 14 +- .../fx/glsl/fragmentshaders/mirrorimages.js | 125 +- tokenmagic/fx/glsl/fragmentshaders/smoke.js | 5 +- tokenmagic/fx/glsl/fragmentshaders/xray.js | 16 +- tokenmagic/fx/presets/defaultpresets.js | 1903 +++++++++++++++++ tokenmagic/import/TMFX-default-presets.json | 1663 ++++++++++++++ tokenmagic/lang/en.json | 20 +- tokenmagic/lang/fr.json | 22 +- tokenmagic/module.json | 5 +- .../module/proto/PlaceableObjectProto.js | 89 +- tokenmagic/module/tokenmagic.js | 624 +++++- tokenmagic/packs/token-magic-portfolio.db | 102 +- tokenmagic/updates/UPDATE-0.2.1.md | 161 ++ 34 files changed, 4885 insertions(+), 326 deletions(-) delete mode 100644 tokenmagic/fx/filters/FilterColorMatrix.js create mode 100644 tokenmagic/fx/filters/FilterPixelate.js create mode 100644 tokenmagic/fx/presets/defaultpresets.js create mode 100644 tokenmagic/import/TMFX-default-presets.json create mode 100644 tokenmagic/updates/UPDATE-0.2.1.md diff --git a/.vs/Tokenmagic/v16/.suo b/.vs/Tokenmagic/v16/.suo index 6836581e93d33d994b745118d24c2507b4d3660e..2bcd517c9bddd3e46cd6f845992d181f0da55c30 100644 GIT binary patch delta 13092 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 delta 9981 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 delta 4816 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 diff --git a/README.md b/README.md index cfd72b2..df564d9 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,162 @@ +# Token Magic FX - Update v0.2.1-alpha + +*Added :* +- An option to allow non-GM players to add, modify or delete FX on tokens which they do not own. +- Mirror-images filter overhaul with new properties : + - number of images + - alpha properties on images and character + - movement amplitude along the X and Y axis. + - 2 new macro in the portfolio (with an emphasis on new properties) +- Library of stored FX presets : + - comes with a default library (the same as in the portfolio) + - functions to add or delete presets in your library + - functions to export presets from your library into a json file + - functions to import presets into your library (local or URL) +- Added smooth edges on Force Field filter + +*New FX :* +- A pixelate filter (sample added in the portfolio) + +*Fixed issues :* +- Added the v0.2.0 missing macros in the portfolio. + - X-rays, liquid and x-glow macros +- Force field filter had a brightness and contrast problem. + - The colors are now more vivid. + - You may have to review your macros by adjusting color intensity. + - The Force field macros have been rewritten. +- Corrected some performances issues in the shaders +- Some animations could freeze with a large video or texture (animated tokens, etc.) + +*Thanks :* +- special thanks to @tposney + +## Managing Presets + +*Added new functions :* + +To add a preset in your library : +```javascript +(async) TokenMagic.addPreset(,,optional ) + +// Example +// You don't need to add a filterId when creating a preset. The filterId is created with the preset name. +// In the example below, the filterId will be equal to "FunnyGlow" +let params = + [{ + filterType: "glow", + color: Math.floor(Math.random() * 16777215) + }]; +TokenMagic.addPreset("FunnyGlow",params); +``` +To delete a preset in your library : +```javascript +(async) TokenMagic.deletePreset(,optional ); +``` +To get a preset from your library : +```javascript +TokenMagic.getPreset(); +``` + +To export your library in a json file +```javascript +TokenMagic.exportPresetLibrary(optional ); +``` + +To import presets into your library (open a file picker dialog) +```javascript +(async) TokenMagic.importPresetLibrary(); +``` + +To import presets into your library from a local path +```javascript +(async) TokenMagic.importPresetLibraryFromPath(); +``` + +To import presets into your library from an URL +```javascript +(async) TokenMagic.importPresetLibraryFromURL(); +``` + +To reset the preset library with the default presets (confirmation is requested) +```javascript +(async) TokenMagic.resetPresetLibrary(); +``` + +*A new option in the module option panel allow overwrite of duplicates (by preset name) on import. +By default, duplicates are ignored.* + +### Functions updates + +You can use presets with those functions below, by replacing the params with a preset name : +```javascript +TokenMagic.addFilters +TokenMagic.addFiltersOnSelected +TokenMagic.addFiltersOnTargeted +TokenMagic.addUpdateFiltersOnSelected +TokenMagic.addUpdateFiltersOnTargeted +TokenMagic.updateFiltersOnSelected +TokenMagic.updateFiltersOnTargeted +TokenMagic.updateFiltersByPlaceable + +// Example +TokenMagic.addFiltersOnTargeted("dead"); +``` + +### Default presets library content + +```javascript +0: {name: "bevel", params: Array(1)} +1: {name: "adjustment", params: Array(1)} +2: {name: "dropshadow", params: Array(1)} +3: {name: "outline", params: Array(1)} +4: {name: "glow", params: Array(1)} +5: {name: "bloom", params: Array(1)} +6: {name: "distortion", params: Array(1)} +7: {name: "oldfilm", params: Array(2)} +8: {name: "twist", params: Array(1)} +9: {name: "bulge", params: Array(1)} +10: {name: "blur", params: Array(1)} +11: {name: "zoomblur", params: Array(1)} +12: {name: "shockwave", params: Array(1)} +13: {name: "zapshadow", params: Array(1)} +14: {name: "rays", params: Array(1)} +15: {name: "fog", params: Array(1)} +16: {name: "fumes", params: Array(1)} +17: {name: "electric", params: Array(1)} +18: {name: "fire", params: Array(1)} +19: {name: "waves", params: Array(1)} +20: {name: "flood", params: Array(1)} +21: {name: "smoke", params: Array(1)} +22: {name: "images", params: Array(1)} +23: {name: "chaos-images", params: Array(1)} +24: {name: "spectral-images", params: Array(1)} +25: {name: "hexa-field", params: Array(1)} +26: {name: "fire-field", params: Array(1)} +27: {name: "smoke-field", params: Array(1)} +28: {name: "earth-field", params: Array(1)} +29: {name: "earth-field-top", params: Array(1)} +30: {name: "air-field", params: Array(1)} +31: {name: "magic-field", params: Array(1)} +32: {name: "chromatic-field", params: Array(1)} +33: {name: "water-field", params: Array(1)} +34: {name: "evil-field", params: Array(1)} +35: {name: "grid-field", params: Array(1)} +36: {name: "warp-field", params: Array(1)} +37: {name: "color-field", params: Array(1)} +38: {name: "sunburst", params: Array(1)} +39: {name: "clover", params: Array(1)} +40: {name: "scan", params: Array(1)} +41: {name: "blue-rays", params: Array(1)} +42: {name: "spectral-body", params: Array(1)} +43: {name: "mantle-of-madness", params: Array(1)} +44: {name: "drift-in-plans", params: Array(2)} +45: {name: "fire-aura", params: Array(2)} +46: {name: "glacial-aura", params: Array(2)} +47: {name: "anti-aura", params: Array(2)} +48: {name: "pure-fire-aura", params: Array(3)} +49: {name: "pure-fire-aura-2", params: Array(3)} +50: {name: "pure-ice-aura", params: Array(3)} +``` # Token Magic FX - Update v0.2.0-alpha *Added :* diff --git a/Tokenmagic.zip b/Tokenmagic.zip index 9c38fbb539453c6892ea80c9f019d7012f1977b3..138a2b44d8920ba99bbfdc20abaed2f6199f7f2b 100644 GIT binary patch delta 54274 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�st4>~h+EkGGdUVMuMvLBnbbjxc6F9uP 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 RA*uM+1M4oW_B3&X{0oiQPSyYb diff --git a/tokenmagic/fx/filters/FilterColorMatrix.js b/tokenmagic/fx/filters/FilterColorMatrix.js deleted file mode 100644 index 715bcc5..0000000 --- a/tokenmagic/fx/filters/FilterColorMatrix.js +++ /dev/null @@ -1,20 +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.animated = {}; - this.setTMParams(params); - this.anime = new Anime(this); - this.normalizeTMParams(); - } -} \ No newline at end of file diff --git a/tokenmagic/fx/filters/FilterElectric.js b/tokenmagic/fx/filters/FilterElectric.js index c463450..9e21200 100644 --- a/tokenmagic/fx/filters/FilterElectric.js +++ b/tokenmagic/fx/filters/FilterElectric.js @@ -31,8 +31,10 @@ export class FilterElectric extends PIXI.Filter { this.animated = {}; this.setTMParams(params); - this.anime = new Anime(this); - this.normalizeTMParams(); + if (!this.dummy) { + this.anime = new Anime(this); + this.normalizeTMParams(); + } this.quality = 0.5; } diff --git a/tokenmagic/fx/filters/FilterFire.js b/tokenmagic/fx/filters/FilterFire.js index e016ecd..c1ce85b 100644 --- a/tokenmagic/fx/filters/FilterFire.js +++ b/tokenmagic/fx/filters/FilterFire.js @@ -29,8 +29,10 @@ export class FilterFire extends PIXI.Filter { this.animated = {}; this.setTMParams(params); - this.anime = new Anime(this); - this.normalizeTMParams(); + if (!this.dummy) { + this.anime = new Anime(this); + this.normalizeTMParams(); + } } get time() { diff --git a/tokenmagic/fx/filters/FilterForceField.js b/tokenmagic/fx/filters/FilterForceField.js index 42679c8..b96d0a6 100644 --- a/tokenmagic/fx/filters/FilterForceField.js +++ b/tokenmagic/fx/filters/FilterForceField.js @@ -43,8 +43,10 @@ export class FilterForceField extends PIXI.Filter { this.animated = {}; this.setTMParams(params); - this.anime = new Anime(this); - this.normalizeTMParams(); + if (!this.dummy) { + this.anime = new Anime(this); + this.normalizeTMParams(); + } } get time() { diff --git a/tokenmagic/fx/filters/FilterGleamingGlow.js b/tokenmagic/fx/filters/FilterGleamingGlow.js index b25395e..3746128 100644 --- a/tokenmagic/fx/filters/FilterGleamingGlow.js +++ b/tokenmagic/fx/filters/FilterGleamingGlow.js @@ -31,8 +31,10 @@ export class FilterGleamingGlow extends PIXI.Filter { this.animated = {}; this.setTMParams(params); - this.anime = new Anime(this); - this.normalizeTMParams(); + if (!this.dummy) { + this.anime = new Anime(this); + this.normalizeTMParams(); + } } get time() { diff --git a/tokenmagic/fx/filters/FilterMirrorImages.js b/tokenmagic/fx/filters/FilterMirrorImages.js index e960550..efbce01 100644 --- a/tokenmagic/fx/filters/FilterMirrorImages.js +++ b/tokenmagic/fx/filters/FilterMirrorImages.js @@ -9,23 +9,26 @@ export class FilterMirrorImages extends PIXI.Filter { let { time, blend, - alpha, + alphaImg, + alphaChr, + nbImage, + ampX, + ampY } = Object.assign({}, FilterMirrorImages.defaults, params); // using specific vertex shader and fragment shader super(customVertex2D, mirrorImages); - //this.uniforms.color = new Float32Array([1.0, 1.0, 1.0]); - //this.uniforms.scale = new Float32Array([1.0, 1.0]); - Object.assign(this, { - time, blend, alpha + time, blend, alphaImg, alphaChr, nbImage, ampX, ampY }); this.animated = {}; this.setTMParams(params); - this.anime = new Anime(this); - this.normalizeTMParams(); + if (!this.dummy) { + this.anime = new Anime(this); + this.normalizeTMParams(); + } } get time() { @@ -36,12 +39,28 @@ export class FilterMirrorImages extends PIXI.Filter { this.uniforms.time = value; } - get alpha() { - return this.uniforms.alpha; + 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 alpha(value) { - this.uniforms.alpha = value; + set nbImage(value) { + this.uniforms.nbImage = Math.floor(value); } get blend() { @@ -51,12 +70,32 @@ export class FilterMirrorImages extends PIXI.Filter { 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: 2, - alpha: 0.5, + blend: 4, + alphaImg: 0.5, + alphaChr: 1.0, + nbImage: 4, + ampX: 0.15, + ampY: 0.15 }; diff --git a/tokenmagic/fx/filters/FilterPixelate.js b/tokenmagic/fx/filters/FilterPixelate.js new file mode 100644 index 0000000..c61d2eb --- /dev/null +++ b/tokenmagic/fx/filters/FilterPixelate.js @@ -0,0 +1,36 @@ +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.setTMParams(params); + this.anime = new Anime(this); + this.normalizeTMParams(); + } + + //get sizeX() { + // return this.size.x; + //} + + //set sizeX(value) { + // this.size.x = value; + //} + + //get sizeY() { + // return this.size.y; + //} + + //set sizeY(value) { + // this.size.y = value; + //} + + handleTransform() { + this.size.x = this.sizeX * this.placeableImg.parent.worldTransform.a; + this.size.y = this.sizeY * this.placeableImg.parent.worldTransform.a; + } +} diff --git a/tokenmagic/fx/filters/FilterSmoke.js b/tokenmagic/fx/filters/FilterSmoke.js index fe92291..52dbd24 100644 --- a/tokenmagic/fx/filters/FilterSmoke.js +++ b/tokenmagic/fx/filters/FilterSmoke.js @@ -26,8 +26,10 @@ export class FilterSmoke extends PIXI.Filter { this.animated = {}; this.setTMParams(params); - this.anime = new Anime(this); - this.normalizeTMParams(); + if (!this.dummy) { + this.anime = new Anime(this); + this.normalizeTMParams(); + } } get time() { diff --git a/tokenmagic/fx/filters/proto/FilterProto.js b/tokenmagic/fx/filters/proto/FilterProto.js index 42d5f87..266ae26 100644 --- a/tokenmagic/fx/filters/proto/FilterProto.js +++ b/tokenmagic/fx/filters/proto/FilterProto.js @@ -1,4 +1,5 @@ -import { objectAssign, getPlaceableById, getMinPadding } from "../../../module/tokenmagic.js"; +import { objectAssign, getPlaceableById, getMinPadding, PlaceableType } from "../../../module/tokenmagic.js"; +import "../../../module/proto/PlaceableObjectProto.js"; PIXI.Filter.prototype.setTMParams = function (params) { this.autoDisable = false; @@ -44,17 +45,11 @@ PIXI.Filter.prototype.calculatePadding = function () { } PIXI.Filter.prototype.assignPlaceable = function () { - if (this.placeableType === "Token") { - let parent = canvas.tokens.placeables.find(n => n.id === this.placeableId); - if (!(parent == null)) { - this.placeableImg = parent.icon; - } - } else { - let parent = canvas.tiles.placeables.find(n => n.id === this.placeableId); - if (!(parent == null)) { - this.placeableImg = parent.tile.img; - } - } + + let placeable = this.getPlaceable(); + placeable != null + ? this.placeableImg = placeable._TMFXgetSprite() + : this.placeableImg = null; } PIXI.Filter.prototype.activateTransform = function () { @@ -78,7 +73,7 @@ PIXI.Filter.prototype.filterTransform = function () { PIXI.Filter.prototype.normalizeTMParams = function () { - if (this.hasOwnProperty("animated") && !(this.animated == null) ) { + if (this.hasOwnProperty("animated") && !(this.animated == null)) { // Normalize animations properties Object.keys(this.animated).forEach((effect) => { diff --git a/tokenmagic/fx/glsl/fragmentshaders/cosmicray.js b/tokenmagic/fx/glsl/fragmentshaders/cosmicray.js index b6140ac..1311394 100644 --- a/tokenmagic/fx/glsl/fragmentshaders/cosmicray.js +++ b/tokenmagic/fx/glsl/fragmentshaders/cosmicray.js @@ -31,7 +31,7 @@ void main() { wobble = 48. + 24. * cos(time/5.), white = fract((angle) * divisor + sin((sqrt(len) * wobble) - time * speed)); - white = 2.* cos(white / (PI / 10.)); + white = 2.* cos(white / (PI * 0.1)); white *= floor(fract(angle * divisor + sin(time / speed - (len * 1.2) * wobble)) *subdivide) / subdivide; vec4 color1 = smoothstep(0., 1., white * color); diff --git a/tokenmagic/fx/glsl/fragmentshaders/electricity.js b/tokenmagic/fx/glsl/fragmentshaders/electricity.js index be09872..65c73ae 100644 --- a/tokenmagic/fx/glsl/fragmentshaders/electricity.js +++ b/tokenmagic/fx/glsl/fragmentshaders/electricity.js @@ -77,9 +77,9 @@ float Perlin(vec3 P) float fbm(vec3 p) { float v = 0.0; - v += Perlin(p * 0.9) * 1.5 * cos(1.2 * PI * (time / 2.5)); - v += Perlin(p * 3.99) * 0.5 * sin(PI * time / 2.5); - v += Perlin(p * 8.01) * 0.4 * cos(PI * time / 2.5); + v += Perlin(p * 0.9) * 1.5 * cos(1.2 * PI * (time * 0.4)); + v += Perlin(p * 3.99) * 0.5 * sin(PI * time * 0.4); + v += Perlin(p * 8.01) * 0.4 * cos(PI * time * 0.4); v += Perlin(p * 15.05) * 0.05 * sin(0.1 * PI * time * 8.); return v; diff --git a/tokenmagic/fx/glsl/fragmentshaders/flood.js b/tokenmagic/fx/glsl/fragmentshaders/flood.js index 16cf4c7..897807e 100644 --- a/tokenmagic/fx/glsl/fragmentshaders/flood.js +++ b/tokenmagic/fx/glsl/fragmentshaders/flood.js @@ -48,7 +48,7 @@ float makeWaves(vec2 uv, float theTime, float offset) vec4 water( vec2 fragCoord ) { vec4 fragColor; - vec2 uv = fragCoord.xy / 2.; + vec2 uv = fragCoord.xy * 0.5; vec2 uv2 = uv * scale; @@ -60,7 +60,7 @@ vec4 water( vec2 fragCoord ) result = makeWaves( uv2+vec2(time*timeSpeed,0.0), time, 0.1); result2 = makeWaves( uv2-vec2(time*0.8*timeSpeed,0.0), time*0.8+1.06, 0.26); - result /= 5.; + result *= 0.2; result = smoothstep(0.35,1.1,1.0-abs(result)); result2 = smoothstep(0.35,1.1,1.0-abs(result2)); diff --git a/tokenmagic/fx/glsl/fragmentshaders/fog.js b/tokenmagic/fx/glsl/fragmentshaders/fog.js index 797a5b9..388032b 100644 --- a/tokenmagic/fx/glsl/fragmentshaders/fog.js +++ b/tokenmagic/fx/glsl/fragmentshaders/fog.js @@ -47,7 +47,7 @@ float fbm(vec2 pos) mat4 contrastMatrix(float contrast) { - float t = ( 1.0 - contrast ) / 2.0; + float t = ( 1.0 - contrast ) * 0.5; return mat4( contrast, 0, 0, 0, 0, contrast, 0, 0, @@ -59,7 +59,7 @@ vec4 fog() { vec2 p = (vFilterCoord.xy * 8. - vFilterCoord.xy) * dimensions; - float time2 = 5. * (time/2000.); + float time2 = time * 0.0025; vec2 q = vec2(0.0); q.x = fbm(p); diff --git a/tokenmagic/fx/glsl/fragmentshaders/forcefield.js b/tokenmagic/fx/glsl/fragmentshaders/forcefield.js index 0b34634..b3c14a3 100644 --- a/tokenmagic/fx/glsl/fragmentshaders/forcefield.js +++ b/tokenmagic/fx/glsl/fragmentshaders/forcefield.js @@ -21,10 +21,14 @@ varying vec2 vFilterCoord; #define SQRT5B20 0.30901699 #define PI 3.14159265 #define SPEED 0.01 +#define MU_TWOPI 0.15915494309 +#define MU_289 0.00346020761 +#define MU_3 0.33333333334 +#define MU_1_5 0.66666666667 vec3 hsvToRgb(vec3 hsVcolor) { - vec4 K = vec4(1., 2.0 / 3.0, 1.0 / 3.0, 3.0); + vec4 K = vec4(1., 2.0 * MU_3, 1.0 * MU_3, 3.0); vec3 p = abs(fract(hsVcolor.xxx + K.xyz) * 6.0 - K.www); return hsVcolor.z @@ -33,7 +37,7 @@ vec3 hsvToRgb(vec3 hsVcolor) vec4 multihue(vec2 uv) { - float h = 0.5 + atan(uv.y, uv.x) / (2. * PI); + float h = 0.5 + atan(uv.y, uv.x) * MU_TWOPI; float b2 = .5 * ((1.0 - 1.) + 1. + sqrt((1.0 - 2.) * (1.0 - 2.) + 0.01)); @@ -53,22 +57,22 @@ vec2 random2(vec2 p) float bornedCos(float minimum, float maximum) { - return (maximum-minimum)*(cos(2.*PI*time/20. + 1.)/2.)+minimum; + return (maximum-minimum)*(cos(2.*PI*time*0.05 + 1.)*0.5)+minimum; } float bornedSin(float minimum, float maximum) { - return (maximum-minimum)*(sin(2.*PI*time/20. + 1.)/2.)+minimum; + return (maximum-minimum)*(sin(2.*PI*time*0.05 + 1.)*0.5)+minimum; } vec4 mod289(vec4 x) { - return x - floor(x * (1.0 / 289.0)) * 289.0; + return x - floor(x * (1.0 * MU_289)) * 289.0; } float mod289(float x) { - return x - floor(x * (1.0 / 289.0)) * 289.0; + return x - floor(x * (1.0 * MU_289)) * 289.0; } vec4 permute(vec4 x) @@ -181,10 +185,10 @@ float surface( vec4 coord ) vec4 ambientLight(vec4 pixel, vec2 fragCoord, vec2 posLg) { - vec3 lightColor = (color+vec3(2.))/3.; + vec3 lightColor = (color+vec3(2.)) * MU_3; vec2 position = posLg; - float maxDistance = lightSize + 0.055*sin(time*10.); + float maxDistance = lightSize; float distance = distance(fragCoord-posLg, position); float value = 1.0 - smoothstep(-0.2, maxDistance, distance); @@ -198,7 +202,7 @@ vec4 ambientLight(vec4 pixel, vec2 fragCoord, vec2 posLg) vec3 toGray(vec3 color) { - float average = (color.r + color.g + color.b) / 3.0; + float average = (color.r + color.g + color.b)*0.3333333; return vec3(average, average, average); } @@ -226,7 +230,7 @@ vec4 blenderVec3(int blend, vec4 fColv4, vec4 sColv4) else if (blend == 13) { fCol = fCol + sCol; return vec4(fCol,0.6); } else { fCol = fCol + sCol; } - return vec4(fCol,(fColv4.a+sColv4.a)/2.); + return vec4(fCol,(fColv4.a+sColv4.a)*0.5); } float hexDist(vec2 p) @@ -258,7 +262,7 @@ vec4 hexa(vec2 fragCoord) { float t = time; - vec2 uv = fragCoord/1.; + vec2 uv = fragCoord; vec2 uv1 = uv + vec2(0, sin(uv.x*1. +t)*.25); vec2 uv2 = .5*uv1 + .5*uv + vec2(sin(uv.y*5. + t)*.05, 0); @@ -268,8 +272,8 @@ vec4 hexa(vec2 fragCoord) uv2 *= mat2(c, -s, s, c); vec3 col = color; - col += (smoothstep(abs(uv2.y)/1.5, 3.99, hexCoords(uv2*15.).y) * 40.*(sin(t)+1.)); - col += (smoothstep(abs(uv2.x)/1.5, 3.99, hexCoords(uv2*15.).y) * 40.*(cos(t)+1.)); + col += (smoothstep(abs(uv2.y)*MU_1_5, 3.99, hexCoords(uv2*15.).y) * 40.*(sin(t)+1.)); + col += (smoothstep(abs(uv2.x)*MU_1_5, 3.99, hexCoords(uv2*15.).y) * 40.*(cos(t)+1.)); return vec4(colorize(toGray(clamp(col,0.,2.)),color),1.); } @@ -351,11 +355,11 @@ float fbm2(vec2 n) vec4 ripples(vec2 suv) { - suv.x += time/2.; - vec3 c1 = ( 0.0 ) * (color / 0.1); + suv.x += time*0.5; + vec3 c1 = ( 0.0 ) * (color * 10.); vec3 c2 = vec3(c1); vec3 c3 = vec3(c1); - vec3 c4 = vec3( color.r/0.2, color.g/0.3, color.b/0.5 ); + vec3 c4 = vec3(color.r*5., color.g*3.333, color.b*2.); vec3 c5 = vec3(c3); vec3 c6 = vec3(c1); vec2 p = suv; @@ -372,10 +376,10 @@ vec4 ripples(vec2 suv) vec4 fire(vec2 suv) { - vec3 c1 = color+(2.*vec3(0.1, 0.0, 0.))/3.; - vec3 c2 = color+(2.*vec3(0.7, 0.0, 0.))/3.; - vec3 c3 = color+(2.*vec3(0.2, 0.0, 0.))/3.; - vec3 c4 = color+(2.*vec3(1.0, 0.9, 0.))/3.; + vec3 c1 = color+(2.*vec3(0.1, 0.0, 0.))*0.3333333; + vec3 c2 = color+(2.*vec3(0.7, 0.0, 0.))*0.3333333; + vec3 c3 = color+(2.*vec3(0.2, 0.0, 0.))*0.3333333; + vec3 c4 = color+(2.*vec3(1.0, 0.9, 0.))*0.3333333; vec3 c5 = vec3(0.1); vec3 c6 = vec3(0.9); vec2 uv = suv - vec2(0.92,0.26); @@ -391,7 +395,7 @@ vec4 surface4d(vec2 suv) float s = suv.x + 0.61; float t = suv.y + 0.5; - float multiplier = 1.0 / ( 2.0 * PI ); + float multiplier = 1.0 * MU_TWOPI; float nx = cos( s * 2.0 * PI ) * multiplier; float ny = cos( t * 2.0 * PI ) * multiplier; float nz = sin( s * 2.0 * PI ) * multiplier; @@ -404,9 +408,9 @@ vec4 surface4d(vec2 suv) vec4 fbmy(vec2 suv) { vec4 noiseColor; - noiseColor.r = (color.r * fbm(suv + time/2.)); - noiseColor.g = (color.g * fbm(suv + time/2.)); - noiseColor.b = (color.b * fbm(suv + time/2.)); + noiseColor.r = (color.r * fbm(suv + time*0.5)); + noiseColor.g = (color.g * fbm(suv + time*0.5)); + noiseColor.b = (color.b * fbm(suv + time*0.5)); noiseColor.a = 1.; return clamp(noiseColor,0.,1.); } @@ -414,9 +418,9 @@ vec4 fbmy(vec2 suv) vec4 noisy(vec2 suv) { vec4 noiseColor; - noiseColor.r = (color.r * noise(suv + fbm(suv) + time/2.)); - noiseColor.g = (color.g * noise(suv + fbm(suv) + time/2.)); - noiseColor.b = (color.b * noise(suv + fbm(suv) + time/2.)); + noiseColor.r = (color.r * noise(suv + fbm(suv) + time*0.5)); + noiseColor.g = (color.g * noise(suv + fbm(suv) + time*0.5)); + noiseColor.b = (color.b * noise(suv + fbm(suv) + time*0.5)); noiseColor.a = 1.; return clamp(noiseColor,0.,1.); } @@ -451,10 +455,9 @@ vec4 denseSmoke(vec2 suv) vec2 uv; uv.x = (fbm(suv*2.)-suv.x); uv.y = (suv.y+fbm(suv*2.)); - uv *= 1.; - noiseColor.r = (color.r * min(fbm(uv - time/2.),fbm(uv)*1.5)); - noiseColor.g = (color.g * min(fbm(uv - time/2.),fbm(uv)*1.5)); - noiseColor.b = (color.b * min(fbm(uv - time/2.),fbm(uv)*1.5)); + noiseColor.r = (color.r * min(fbm(uv - time*0.5),fbm(uv)*1.5)); + noiseColor.g = (color.g * min(fbm(uv - time*0.5),fbm(uv)*1.5)); + noiseColor.b = (color.b * min(fbm(uv - time*0.5),fbm(uv)*1.5)); noiseColor.a = 1.0; return clamp(noiseColor,0.,1.); } @@ -509,7 +512,7 @@ vec4 grid(vec2 suv) vec4 galaxy(vec2 suv) { - vec2 uv = suv/6. + vec2 uv = suv*0.166666667 + vec2(bornedCos(0.0,0.7), bornedSin(0.0,0.7)); @@ -519,7 +522,7 @@ vec4 galaxy(vec2 suv) / ( length( uv.xy ) + 0.2 )) * 2.2; float si = sin( t * 1.5 ); - float co = cos( t / 1.5 ); + float co = cos( t * 0.66666667 ); mat2 matrix = mat2( -co, si, si, co ); float c; @@ -559,9 +562,7 @@ vec2 getSphere(out float alpha, out float r) vec2 tc = vFilterCoord.xy; vec2 p = (-1.0 + 2. * tc) * (1.01 / radius+0.000001); r = dot(p,p); - alpha = 1.0; - if (r > 1.0) alpha = (1./r)-0.85; - if (alpha < 0.) alpha = 0.; + r > 0.943 ? alpha = max(min(40.*log(1./r),1.),0.) : alpha = 1.; float f = (1.0-sqrt(1.0-r))/(r); vec2 uv; uv.x = p.x*f; @@ -573,9 +574,7 @@ void main() { float a, r; vec4 result; - vec4 pixel = texture2D(uSampler, vTextureCoord); - vec2 uv = getSphere(a, r); if (shieldType <= 1) { @@ -606,14 +605,8 @@ void main() result = vec4(color,1.); } - float glow = - 0.05 / (0.015 + distance(radius + .008, 0.99)); - - result.a = a; - vec4 colorized; vec3 chromaOption; - if (chromatic) { vec2 vHue = uv; vHue.x -= bornedCos(-0.,+2.2); @@ -622,18 +615,15 @@ void main() } else { chromaOption = color; } - colorized = (vec4( colorize( - toGray(result.rgb + glow), chromaOption), result.a) + result)/2.; - + toGray(result.rgb), chromaOption), result.a) + result)*0.5; vec4 final = clamp(ambientLight(clamp(colorized, 0., 1.)*intensity, uv, posLight-vec2(0.5,0.5)),0.,1.); - gl_FragColor = r > 1.0 ? pixel*(1.-a) : (pixel.a < 1. ? mix(blenderVec3(13, pixel, final),blenderVec3(blend, pixel, final),pixel.a) - : blenderVec3(blend, pixel, final)); + : blenderVec3(blend, pixel, final)) * a; } `; \ No newline at end of file diff --git a/tokenmagic/fx/glsl/fragmentshaders/fumes.js b/tokenmagic/fx/glsl/fragmentshaders/fumes.js index 3ac7d1b..e121fd9 100644 --- a/tokenmagic/fx/glsl/fragmentshaders/fumes.js +++ b/tokenmagic/fx/glsl/fragmentshaders/fumes.js @@ -15,7 +15,7 @@ varying vec2 vFilterCoord; vec4 toGray(in vec4 color) { - float average = (color.r + color.g + color.b) / 3.0; + float average = (color.r + color.g + color.b) * 0.33333334; return vec4(average, average, average, 1.0); } @@ -62,7 +62,7 @@ vec4 fog(vec2 fragCoord) c += 1.0 / length(vec2(.5 * p.x / (sin(0.40 * i.x + t) / intensity), p.y / (cos(i.y + t) / intensity))); } - c /= 6.; + c *= 0.16666667; c = 1.17 - pow(c, 1.4); vec3 colour = vec3(pow(abs(c), 8.0)); diff --git a/tokenmagic/fx/glsl/fragmentshaders/liquid.js b/tokenmagic/fx/glsl/fragmentshaders/liquid.js index 2dc016c..923679d 100644 --- a/tokenmagic/fx/glsl/fragmentshaders/liquid.js +++ b/tokenmagic/fx/glsl/fragmentshaders/liquid.js @@ -71,20 +71,20 @@ vec4 blenderVec3(int blend, vec4 fColv4, vec3 sCol) void main() { float distortion1 = fbm( - vec2( fbm( vFilterCoord * 2.5 * scale + time/2.), - fbm( (-vFilterCoord - vec2(0.01)) * 5. * scale + time/3.) ) + vec2( fbm( vFilterCoord * 2.5 * scale + time*0.5), + fbm( (-vFilterCoord - vec2(0.01)) * 5. * scale + time*0.3333334) ) ); float distortion2 = fbm( - vec2( fbm( -vFilterCoord * 5. * scale + time/2.), - fbm( (vFilterCoord + vec2(0.01)) * 2.5 * scale + time/3.) ) + vec2( fbm( -vFilterCoord * 5. * scale + time*0.5), + fbm( (vFilterCoord + vec2(0.01)) * 2.5 * scale + time*0.3333334) ) ); vec2 uv = vFilterCoord; - uv.x += 0.8*sin(min(distortion1/4.,distortion2/4.)); - uv.y += 0.8*cos(min(distortion1/4.,distortion2/4.)); - uv *= 1. + 0.11*(cos(sqrt(max(distortion1, distortion2))+1.)/2.); + uv.x += 0.8*sin(min(distortion1*0.25,distortion2*0.25)); + uv.y += 0.8*cos(min(distortion1*0.25,distortion2*0.25)); + uv *= 1. + 0.11*(cos(sqrt(max(distortion1, distortion2))+1.)*0.5); uv -= vec2(0.036,0.81); vec2 mappedCoord = (uv*vOutputFrame.zw) / vInputSize.xy; @@ -98,6 +98,6 @@ void main() { if (spectral) pixel.a = max(distortion1,distortion2)*3.75; - gl_FragColor = blenderVec3(blend,pixel,color/3.) * min(pixel.a,a); + gl_FragColor = blenderVec3(blend,pixel,color*0.3333334) * min(pixel.a,a); } `; \ No newline at end of file diff --git a/tokenmagic/fx/glsl/fragmentshaders/magicglow.js b/tokenmagic/fx/glsl/fragmentshaders/magicglow.js index 90aac4e..ae1a53b 100644 --- a/tokenmagic/fx/glsl/fragmentshaders/magicglow.js +++ b/tokenmagic/fx/glsl/fragmentshaders/magicglow.js @@ -99,7 +99,7 @@ vec4 glowing() float outerGlowAlpha = alphaRatio * outerStrength * (1. - curColor.a); float outerGlowStrength = min(1.0 - curColor.a, outerGlowAlpha); - vec4 outerGlowColor = (outerGlowStrength * (color.rgba/10.) ); + vec4 outerGlowColor = (outerGlowStrength * (color.rgba*0.1) ); float resultAlpha = outerGlowAlpha; return vec4(color.rgb * resultAlpha, resultAlpha); @@ -108,15 +108,15 @@ vec4 glowing() vec4 ripples(vec2 suv) { suv.x += time/2.; - vec3 c1 = ( 0.0 ) * (color.rgb / 0.1); + vec3 c1 = ( 0.0 ) * (color.rgb*10.); vec3 c2 = vec3(c1); vec3 c3 = vec3(c1); - vec3 c4 = vec3( color.r/0.2, color.g/0.3, color.b/0.5 ); + vec3 c4 = vec3( color.r*5., color.g*3.3333, color.b*2. ); vec3 c5 = vec3(c3); vec3 c6 = vec3(c1); vec2 p = suv; - float q = 2.*fbm(p + time/5.); - vec2 r = vec2(fbm(p + q + ( time/10. ) - p.x - p.y), fbm(p + p + ( time/10. ))); + float q = 2.*fbm(p + time*0.2); + vec2 r = vec2(fbm(p + q + ( time*0.1 ) - p.x - p.y), fbm(p + p + ( time*0.1 ))); //r.x += bornedCos(-0.3,-0.2); //r.y += 200.*bornedSin(-1.9,1.9); @@ -155,14 +155,14 @@ void main(void) } vec4 effect; - effect = ((glowlevel*subAuraIntensity)/10.) + ((outlinelevel*auraIntensity)/1.25); + effect = ((glowlevel*subAuraIntensity)*0.1) + ((outlinelevel*auraIntensity)*0.8); if (effect.a >= 0.) {effect.rgb = aura.rgb*(max(effect.a,0.));} float intensity = effect.r + effect.g + effect.b; if(intensity < threshold && effect.a != 0.) { if (holes) {discard;} - effect.rgb = (color.rgb)*(effect.a/2.); + effect.rgb = (color.rgb)*(effect.a*0.5); } gl_FragColor = pixel + effect * (1.-pixel.a); diff --git a/tokenmagic/fx/glsl/fragmentshaders/mirrorimages.js b/tokenmagic/fx/glsl/fragmentshaders/mirrorimages.js index b8ba271..0e04b1b 100644 --- a/tokenmagic/fx/glsl/fragmentshaders/mirrorimages.js +++ b/tokenmagic/fx/glsl/fragmentshaders/mirrorimages.js @@ -2,60 +2,101 @@ export const mirrorImages = ` precision mediump float; uniform float time; -uniform float alpha; +uniform float alphaImg; +uniform float alphaChr; +uniform float ampX; +uniform float ampY; uniform int blend; +uniform int nbImage; uniform sampler2D uSampler; +uniform vec4 filterClamp; varying vec2 vTextureCoord; varying vec2 vFilterCoord; const float PI = 3.14159265; -const vec2 resolution = vec2(1.0,1.0); -vec4 blenderVec3(int blend, vec4 fColv4, vec4 sColv4) +float bornedCos(float mi, float ma) { + return (ma-mi)*(cos(2.*PI*time*0.2+1.)*0.5)+mi; +} + +float bornedSin(float mi, float ma) { + return (ma-mi)*(sin(2.*PI*time*0.2+1.)*0.5)+mi; +} + +vec4 blender(int blend, vec4 fCol, vec4 sCol) { - vec3 fCol = vec3(fColv4); - vec3 sCol = vec3(sColv4); - if ( blend == 1) { fCol = fCol * sCol; } - else if (blend == 2) { fCol = (1. - (1. - fCol) * (1. - sCol)); } - else if (blend == 3) { fCol = min(fCol, sCol); } - else if (blend == 4) { fCol = max(fCol, sCol); } - else if (blend == 5) { fCol = abs(fCol - sCol); } - else if (blend == 6) { fCol = 1. - abs(1. - fCol - sCol); } - else if (blend == 7) { fCol = fCol + sCol - (2. * fCol * sCol); } - else if (blend == 8) { fCol = all(lessThanEqual(fCol, vec3(0.5, 0.5, 0.5))) ? (2. * fCol * sCol) : (1. - 2. * (1. - fCol) * (1. - sCol)); } - else if (blend == 9) { fCol = all(lessThanEqual(sCol, vec3(0.5, 0.5, 0.5))) ? (2. * fCol * sCol) : (1. - 2. * (1. - fCol) * (1. - sCol)); } - else if (blend == 10) { fCol = all(lessThanEqual(sCol, vec3(0.5, 0.5, 0.5))) ? (2. * fCol * sCol + fCol * fCol * (1. - 2. * sCol)) : sqrt(fCol) * (2. * sCol - 1.) + (2. * fCol) * (1. - sCol); } - else if (blend == 11) { fCol = fCol / (1.0 - sCol); } - else if (blend == 12) { fCol = 1.0 - (1.0 - fCol) / sCol; } - else if (blend == 13) { fCol = fCol + sCol; } - else if (blend == 14) { fCol = max(fCol,sCol)-(min(fCol,sCol)*0.5)+abs(fCol-sCol);} - else { fCol = fCol + sCol; } - - return vec4(fCol,max(fColv4.a,sColv4.a)); + if ( blend == 1) { fCol.rgb = fCol.rgb * sCol.rgb; } + else if (blend == 2) { fCol.rgb = (1. - (1. - fCol.rgb) * (1. - sCol.rgb)); } + else if (blend == 3) { fCol.rgb = min(fCol.rgb, sCol.rgb); } + else if (blend == 4) { fCol.rgb = max(fCol.rgb, sCol.rgb); } + else if (blend == 5) { fCol.rgb = abs(fCol.rgb - sCol.rgb); } + else if (blend == 6) { fCol.rgb = 1. - abs(1. - fCol.rgb - sCol.rgb); } + else if (blend == 7) { fCol.rgb = fCol.rgb + sCol.rgb - (2. * fCol.rgb * sCol.rgb); } + else if (blend == 8) { fCol.rgb = all(lessThanEqual(fCol.rgb, vec3(0.5, 0.5, 0.5))) ? (2. * fCol.rgb * sCol.rgb) : (1. - 2. * (1. - fCol.rgb) * (1. - sCol.rgb)); } + else if (blend == 9) { fCol.rgb = all(lessThanEqual(sCol.rgb, vec3(0.5, 0.5, 0.5))) ? (2. * fCol.rgb * sCol.rgb) : (1. - 2. * (1. - fCol.rgb) * (1. - sCol.rgb)); } + else if (blend == 10) { fCol.rgb = all(lessThanEqual(sCol.rgb, vec3(0.5, 0.5, 0.5))) ? (2. * fCol.rgb * sCol.rgb + fCol.rgb * fCol.rgb * (1. - 2. * sCol.rgb)) : sqrt(fCol.rgb) * (2. * sCol.rgb - 1.) + (2. * fCol.rgb) * (1. - sCol.rgb); } + else if (blend == 11) { fCol.rgb = fCol.rgb / (1.0 - sCol.rgb); } + else if (blend == 12) { fCol.rgb = 1.0 - (1.0 - fCol.rgb) / (sCol.rgb)+0.001; } + else if (blend == 13) { fCol.rgb = fCol.rgb + sCol.rgb; } + else if (blend == 14) { fCol.rgb = (max(fCol.rgb,sCol.rgb)-(min(fCol.rgb,sCol.rgb)))+abs(fCol.rgb-sCol.rgb);} + else { fCol.rgb = clamp(fCol.rgb + sCol.rgb,0.,1.); } + + fCol.a = max(fCol.a,sCol.a); + return fCol; +} + +vec4 renderMirror(vec2 translation, vec4 prevpix) +{ + vec2 displaced = vTextureCoord + translation; + return blender(blend, prevpix, + texture2D(uSampler, clamp(displaced, filterClamp.xy, filterClamp.zw))); } void main() { - float x = 0.05*cos(time); - float y = 0.05*sin(time); - - vec2 translator1 = vec2(x,y); - vec2 translator2 = 0.95*vec2(-x,y*0.5); - vec2 translator3 = 0.75*vec2(x,-y); - vec2 translator4 = 0.90*vec2(-x*0.5,-y); - - vec2 vUv = vTextureCoord; - vec2 uvImg1 = vUv + translator1; - vec2 uvImg2 = vUv + translator2; - vec2 uvImg3 = vUv + translator3; - vec2 uvImg4 = vUv + translator4; - - vec4 mirror1 = texture2D(uSampler, uvImg1); - vec4 mirror2 = texture2D(uSampler, uvImg2); - vec4 mirror3 = texture2D(uSampler, uvImg3); - vec4 mirror4 = texture2D(uSampler, uvImg4); - - gl_FragColor = blenderVec3(blend, blenderVec3(blend, blenderVec3(blend, mirror1,mirror2),mirror3),mirror4)*alpha; + float x = ampX * bornedCos(0.,1.); + float y = ampY * bornedSin(0.,1.); + vec4 renderedPixel; + vec2 translation; + + if (nbImage >= 1) { + translation = vec2(x,y); + renderedPixel = texture2D(uSampler, clamp(vTextureCoord + translation, filterClamp.xy, filterClamp.zw)); + } + if (nbImage >= 2) { + translation = 0.90*vec2(-x,y*0.5); + renderedPixel = renderMirror(translation, renderedPixel); + } + if (nbImage >= 3) { + translation = 0.70*vec2(x,-y); + renderedPixel = renderMirror(translation, renderedPixel); + } + if (nbImage >= 4) { + translation = 0.80*vec2(-x*0.6,-y); + renderedPixel = renderMirror(translation, renderedPixel); + } + if (nbImage >= 5) { + translation = 1.20*vec2(-x,y*0.4); + renderedPixel = renderMirror(translation, renderedPixel); + } + if (nbImage >= 6) { + translation = 1.10*vec2(x,-y); + renderedPixel = renderMirror(translation, renderedPixel); + } + if (nbImage >= 7) { + translation = 0.6*vec2(-x*0.4,-y); + renderedPixel = renderMirror(translation, renderedPixel); + } + if (nbImage >= 8) { + translation = 1.3*vec2(-x,y*0.70); + renderedPixel = renderMirror(translation, renderedPixel); + } + if (nbImage >= 9) { + translation = vec2(x*0.5,y*0.85); + renderedPixel = renderMirror(translation, renderedPixel); + } + renderedPixel = renderedPixel*alphaImg; + gl_FragColor = blender(blend,texture2D(uSampler, vTextureCoord)*alphaChr , renderedPixel); } `; \ No newline at end of file diff --git a/tokenmagic/fx/glsl/fragmentshaders/smoke.js b/tokenmagic/fx/glsl/fragmentshaders/smoke.js index d1b3eed..9c6e040 100644 --- a/tokenmagic/fx/glsl/fragmentshaders/smoke.js +++ b/tokenmagic/fx/glsl/fragmentshaders/smoke.js @@ -165,8 +165,9 @@ void main() return; } - float s = vFilterCoord.x * scale.x; - float t = vFilterCoord.y * scale.y; + vec2 uv = vFilterCoord - vec2(0.375*scale.x,0.375*scale.y); + float s = uv.x * scale.x; + float t = uv.y * scale.y; float multiplier = 1.0 / ( 2.0 * PI ); float nx = cos( s * 2.0 * PI ) * multiplier; diff --git a/tokenmagic/fx/glsl/fragmentshaders/xray.js b/tokenmagic/fx/glsl/fragmentshaders/xray.js index ab2fd02..fdd32d6 100644 --- a/tokenmagic/fx/glsl/fragmentshaders/xray.js +++ b/tokenmagic/fx/glsl/fragmentshaders/xray.js @@ -14,7 +14,9 @@ uniform vec3 color; varying vec2 vFilterCoord; varying vec2 vTextureCoord; -#define PI 3.14159265359 +const float MU_TWOPI = 0.15915494309; +const float MU_PI5 = 1.59154943092; +const float MU_256 = 0.00390625; vec4 blender(int blend, vec4 fColv4, vec4 sColv4) { @@ -49,16 +51,16 @@ void main() { vec2 uv = (vFilterCoord - anchor) / dimensions; - float len = length(uv *0.5); - float angle = atan(uv.x, uv.y) / (2. * PI); - float beam = fract((angle) * divisor + sin((sqrt(len) * 0.2) - (time/2.))); + float len = length(uv * 0.5); + float angle = atan(uv.x, uv.y) * MU_TWOPI; + float beam = fract((angle) * divisor + sin((sqrt(len) * 0.2) - (time*0.5))); - beam = 2.* cos(beam / (PI / 5.)); - beam *= floor(fract(angle * divisor + sin(time - (len * 1.2) * 0.2)) *256.) / 256.; + beam = 2.* cos(beam * MU_PI5); + beam *= floor(fract(angle * divisor + sin(time - (len * 1.2) * 0.2)) *256.) * MU_256; float fractburn = fract(beam); - vec4 color1 = smoothstep(0.0, 1., (beam*(intensity/10.) + pixel * vec4(color,1.)) / (fractburn == 0. ? fractburn+0.1 : fractburn) * 0.3 ); + vec4 color1 = smoothstep(0.0, 1., (beam*(intensity*0.1) + pixel * vec4(color,1.)) / (fractburn == 0. ? fractburn+0.1 : fractburn) * 0.3 ); vec4 result = blender(blend, pixel, color1); gl_FragColor = result*pixel.a; diff --git a/tokenmagic/fx/presets/defaultpresets.js b/tokenmagic/fx/presets/defaultpresets.js new file mode 100644 index 0000000..28a6e2d --- /dev/null +++ b/tokenmagic/fx/presets/defaultpresets.js @@ -0,0 +1,1903 @@ +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.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.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.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.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.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.00, + val2: 1.90 + } + } + }]; + +presetObject = new Object(); +presetObject.name = "bloom"; +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.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.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.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.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.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.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.params = params; +presets.push(presetObject); + +params = + [{ + filterType: "zapshadow", + filterId: "zapshadow", + alphaTolerance: 0.45 + }]; + +presetObject = new Object(); +presetObject.name = "zapshadow"; +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.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.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.params = params; +presets.push(presetObject); + +params = + [{ + filterType: "electric", + filterId: "electric", + color: 0xFFFFFF, + time: 0, + blend: 1, + intensity: 5, + animated: + { + time: + { + active: true, + speed: 0.0020, + animType: "move" + } + } + }]; + +presetObject = new Object(); +presetObject.name = "electric"; +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.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.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.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.params = params; +presets.push(presetObject); + +params = + [{ + filterType: "images", + filterId: "images", + time: 0, + nbImage: 4, + alphaImg: 1.0, + alphaChr: 0.0, + blend: 4, + ampX: 0.10, + ampY: 0.10, + animated: + { + time: + { + active: true, + speed: 0.0010, + animType: "move" + } + } + }]; + +presetObject = new Object(); +presetObject.name = "images"; +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.10, + ampY: 0.10, + padding: 80, + animated: + { + time: + { + active: true, + speed: 0.0010, + animType: "move" + }, + ampX: + { + active: true, + val1: 0.00, + val2: 0.30, + chaosFactor: 0.03, + animType: "syncChaoticOscillation", + loopDuration: 2000 + }, + ampY: + { + active: true, + val1: 0.00, + val2: 0.30, + 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.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.10, + ampY: 0.10, + animated: + { + time: + { + speed: 0.0010, + 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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.40, + val2: 0.60 + } + } + }]; + +presetObject = new Object(); +presetObject.name = "sunburst"; +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.40, + val2: 0.60 + }, + anchorY: + { + animType: "syncSinOscillation", + loopDuration: 6000, + val1: 0.40, + val2: 0.60 + } + } + }]; + +presetObject = new Object(); +presetObject.name = "clover"; +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.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.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.0010, + animType: "move" + }, + color: + { + active: true, + loopDuration: 6000, + animType: "colorOscillation", + val1: 0xFFFFFF, + val2: 0x00AAFF + } + } + }]; + +presetObject = new Object(); +presetObject.name = "spectral-body"; +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.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.params = params; +presets.push(presetObject); + +params = + [{ + filterType: "zapshadow", + filterId: "fire-aura", + alphaTolerance: 0.50 + }, + { + filterType: "xglow", + filterId: "fire-aura", + auraType: 2, + color: 0x903010, + thickness: 9.8, + scale: 4., + time: 0, + auraIntensity: 2, + subAuraIntensity: 1.5, + threshold: 0.40, + 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.params = params; +presets.push(presetObject); + +params = + [{ + filterType: "zapshadow", + filterId: "glacial-aura", + alphaTolerance: 0.50 + }, + { + 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.params = params; +presets.push(presetObject); + +params = + [{ + filterType: "zapshadow", + filterId: "anti-aura", + alphaTolerance: 0.50 + }, + { + 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.50 + } + } + }]; + +presetObject = new Object(); +presetObject.name = "anti-aura"; +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.50 + }, + { + filterType: "xglow", + filterId: "pure-fire-aura", + auraType: 2, + color: 0x903010, + thickness: 9.8, + scale: 4., + time: 0, + auraIntensity: 2, + subAuraIntensity: 1.5, + threshold: 0.40, + 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.params = params; +presets.push(presetObject); + +params = + [{ + filterType: "zapshadow", + filterId: "pure-fire-aura-2", + alphaTolerance: 0.50 + }, + { + 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.50, + 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.params = params; +presets.push(presetObject); + +params = + [{ + filterType: "zapshadow", + filterId: "pure-ice-aura", + alphaTolerance: 0.50 + }, + { + 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.params = params; +presets.push(presetObject); + +params = + [{ + filterType: "pixel", + filterId: "pixelate", + sizeX: 2.5, + sizeY: 2.5 + }] + +presetObject = new Object(); +presetObject.name = "pixelate"; +presetObject.params = params; +presets.push(presetObject); \ No newline at end of file diff --git a/tokenmagic/import/TMFX-default-presets.json b/tokenmagic/import/TMFX-default-presets.json new file mode 100644 index 0000000..f20716c --- /dev/null +++ b/tokenmagic/import/TMFX-default-presets.json @@ -0,0 +1,1663 @@ +[ + { + "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" + } + } + } + ] + }, + { + "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 + } + } + } + ] + }, + { + "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 + } + } + } + ] + }, + { + "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 + } + } + } + ] + }, + { + "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 + } + } + } + ] + }, + { + "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 + } + } + } + ] + }, + { + "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" + } + } + } + ] + }, + { + "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 + } + ] + }, + { + "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 + } + } + } + ] + }, + { + "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 + } + } + } + ] + }, + { + "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 + } + } + } + ] + }, + { + "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 + } + } + } + ] + }, + { + "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 + } + } + } + ] + }, + { + "name": "zapshadow", + "params": [ + { + "filterType": "zapshadow", + "filterId": "zapshadow", + "alphaTolerance": 0.45 + } + ] + }, + { + "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" + } + } + } + ] + }, + { + "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" + } + } + } + ] + }, + { + "name": "fumes", + "params": [ + { + "filterType": "fumes", + "filterId": "fumes", + "color": 8421504, + "time": 0, + "blend": 8, + "animated": { + "time": { + "active": true, + "speed": 0.001, + "animType": "move" + } + } + } + ] + }, + { + "name": "electric", + "params": [ + { + "filterType": "electric", + "filterId": "electric", + "color": 16777215, + "time": 0, + "blend": 1, + "intensity": 5, + "animated": { + "time": { + "active": true, + "speed": 0.002, + "animType": "move" + } + } + } + ] + }, + { + "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" + } + } + } + ] + }, + { + "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 + } + } + } + ] + }, + { + "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" + } + } + } + ] + }, + { + "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" + } + } + } + ] + }, + { + "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" + } + } + } + ] + }, + { + "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 + } + } + } + ] + }, + { + "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 + } + } + } + ] + }, + { + "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" + } + } + } + ] + }, + { + "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" + } + } + } + ] + }, + { + "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" + } + } + } + ] + }, + { + "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" + } + } + } + ] + }, + { + "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" + } + } + } + ] + }, + { + "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" + } + } + } + ] + }, + { + "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" + } + } + } + ] + }, + { + "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" + } + } + } + ] + }, + { + "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" + } + } + } + ] + }, + { + "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 + } + } + } + ] + }, + { + "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" + } + } + } + ] + }, + { + "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" + } + } + } + ] + }, + { + "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" + } + } + } + ] + }, + { + "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 + } + } + } + ] + }, + { + "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 + } + } + } + ] + }, + { + "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" + } + } + } + ] + }, + { + "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 + } + } + } + ] + }, + { + "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 + } + } + } + ] + }, + { + "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 + } + } + } + ] + }, + { + "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 + } + } + } + ] + }, + { + "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 + } + } + } + ] + }, + { + "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 + } + } + } + ] + }, + { + "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 + } + } + } + ] + }, + { + "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 + } + } + } + ] + }, + { + "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" + } + } + } + ] + }, + { + "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 + } + } + } + ] + }, + { + "name": "pixelate", + "params": [ + { + "filterType": "pixel", + "filterId": "pixelate", + "sizeX": 2.5, + "sizeY": 2.5 + } + ] + } +] \ No newline at end of file diff --git a/tokenmagic/lang/en.json b/tokenmagic/lang/en.json index 6c4989a..541dc44 100644 --- a/tokenmagic/lang/en.json +++ b/tokenmagic/lang/en.json @@ -1,7 +1,25 @@ { "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.importOverwrite.name": "Overwrite on import", + "TMFX.importOverwrite.hint": "Check this option if you want to replace presets with the same name during an import.", "TMFX.useMaxPadding.name": "FX in additive padding mode", "TMFX.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.minPadding.name": "Minimum padding", - "TMFX.minPadding.hint": "The minimum padding applied to a FX." + "TMFX.minPadding.hint": "The minimum padding applied to an FX.", + "TMFX.fxPlayerPermission.name": "Permissive mode", + "TMFX.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." } diff --git a/tokenmagic/lang/fr.json b/tokenmagic/lang/fr.json index 3fd3878..6a4cff3 100644 --- a/tokenmagic/lang/fr.json +++ b/tokenmagic/lang/fr.json @@ -1,7 +1,25 @@ { "TMFX.TokenMagic": "TokenMagic", - "TMFX.useMaxPadding.name": "Effets en mode padding additif", + "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.importOverwrite.name": "Écraser lors d'une importation", + "TMFX.importOverwrite.hint": "Cochez cette option si vous souhaitez écraser les prédéfinitions avec le même nom pendant une importation.", + "TMFX.useMaxPadding.name": "Effet en mode padding additif", "TMFX.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.minPadding.name": "Padding minimum", - "TMFX.minPadding.hint": "Padding minimum appliqué aux effets." + "TMFX.minPadding.hint": "Padding minimum appliqué aux effets.", + "TMFX.fxPlayerPermission.name": "Mode permissif", + "TMFX.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/module.json b/tokenmagic/module.json index 385f516..27f02ac 100644 --- a/tokenmagic/module.json +++ b/tokenmagic/module.json @@ -1,8 +1,8 @@ { "name": "tokenmagic", - "title": "Tokenmagic", + "title": "Token Magic FX", "description": "

Add graphic filters and animations on your tokens and tiles.

", - "version": "0.2.0", + "version": "0.2.1", "compatibleCoreVersion": "0.6.5", "minimumCoreVersion": "0.6.0", "author": "SecretFire", @@ -54,6 +54,7 @@ "fx/filters/FilterXRays.js", "fx/filters/FilterLiquid.js", "fx/filters/FilterGleamingGlow.js", + "fx/filters/FilterPixelate.js", "fx/filters/proto/FilterProto.js" ], diff --git a/tokenmagic/module/proto/PlaceableObjectProto.js b/tokenmagic/module/proto/PlaceableObjectProto.js index 012c5fb..f667853 100644 --- a/tokenmagic/module/proto/PlaceableObjectProto.js +++ b/tokenmagic/module/proto/PlaceableObjectProto.js @@ -1,24 +1,101 @@ +import { PlaceableType, Magic, broadcast, SocketAction, mustBroadCast, isTheOne } from "../tokenmagic.js"; PlaceableObject.prototype.TMFXaddFilters = async function (paramsArray) { - await window.TokenMagic.addFilters(this, paramsArray); + await Magic.addFilters(this, paramsArray); } PlaceableObject.prototype.TMFXupdateFilters = async function (paramsArray) { - await window.TokenMagic.updateFiltersByPlaceable(this, paramsArray); + await Magic.updateFiltersByPlaceable(this, paramsArray); } PlaceableObject.prototype.TMFXaddUpdateFilters = async function (paramsArray) { - await window.TokenMagic.addUpdateFilters(this, paramsArray); + await Magic.addUpdateFilters(this, paramsArray); } PlaceableObject.prototype.TMFXdeleteFilters = async function (filterId = null) { - await window.TokenMagic.deleteFilters(this, filterId); + await Magic.deleteFilters(this, filterId); } PlaceableObject.prototype.TMFXhasFilterType = function (filterType) { - return window.TokenMagic.hasFilterType(this, filterType); + return Magic.hasFilterType(this, filterType); } PlaceableObject.prototype.TMFXhasFilterId = function (filterId) { - return window.TokenMagic.hasFilterId(this, filterId); + return Magic.hasFilterId(this, filterId); +} + +PlaceableObject.prototype._TMFXsetFlag = async function (flag) { + if (mustBroadCast()) broadcast(this, flag, SocketAction.SET_FLAG); + else await this.setFlag("tokenmagic", "filters", flag); +} + +PlaceableObject.prototype._TMFXunsetFlag = async function () { + if (mustBroadCast()) broadcast(this, null, SocketAction.SET_FLAG); + else await this.unsetFlag("tokenmagic", "filters"); +} + +PlaceableObject.prototype._TMFXgetSprite = function () { + + switch (this.constructor.embeddedName) { + case PlaceableType.TOKEN: + return this.icon; + break; + case PlaceableType.TILE: + return this.tile.img; + break; + case PlaceableType.TEMPLATE: + return this.template; + break; + default: + return null; + } +} + +PlaceableObject.prototype._TMFXcheckSprite = function () { + + switch (this.constructor.embeddedName) { + case PlaceableType.TOKEN: + return (this.hasOwnProperty("icon") + && !(this.icon == null)); + break; + case PlaceableType.TILE: + return (this.hasOwnProperty("tile") + && this.tile.hasOwnProperty("img") + && !(this.tile.img == null)); + break; + case PlaceableType.TEMPLATE: + return (this.hasOwnProperty("template") + && !(this.template == null)); + break; + default: + return null; + } +} + +PlaceableObject.prototype._TMFXsetRawFilters = function (filters) { + + let sprite; + sprite = this._TMFXgetSprite(); + if (sprite == null) { return false; } + + if (filters == null) { + sprite.filters = null; + } else { + sprite.filters == null + ? sprite.filters = [filters] + : sprite.filters.push(filters); + } + + return true; +} + +PlaceableObject.prototype._TMFXunsetRawFilters = function () { + return this._TMFXsetRawFilters(null); +} + +PlaceableObject.prototype._TMFXgetPlaceableType = function () { + if ([PlaceableType.TOKEN, PlaceableType.TILE, PlaceableType.TEMPLATE] + .includes(this.constructor.embeddedName)) return this.constructor.embeddedName; + + return PlaceableType.NOT_SUPPORTED; } \ No newline at end of file diff --git a/tokenmagic/module/tokenmagic.js b/tokenmagic/module/tokenmagic.js index 51dd12d..61d4c05 100644 --- a/tokenmagic/module/tokenmagic.js +++ b/tokenmagic/module/tokenmagic.js @@ -25,7 +25,9 @@ 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 { Anime } from "../fx/Anime.js"; +import { presets as defaultPresets } from "../fx/presets/defaultpresets.js"; import "./proto/PlaceableObjectProto.js"; const moduleTM = "module.tokenmagic"; @@ -58,20 +60,70 @@ export const FilterType = { field: FilterForceField, xray: FilterXRays, liquid: FilterLiquid, - xglow: FilterGleamingGlow + xglow: FilterGleamingGlow, + pixel: FilterPixelate +}; + +var cachedFilters = {}; + +async function cacheFilters() { + // Only caching filters with heavy shaders that takes time to compile + // https://www.html5gamedevs.com/topic/43652-shader-compile-performance/ + let params = + { + filterType: "field", + enabled: true, + dummy: true + }; + cachedFilters.filterForceField = new FilterForceField(params); + + params.filterType = "electric"; + cachedFilters.filterElectric = new FilterElectric(params); + + params.filterType = "xglow"; + cachedFilters.filterGleamingGlow = new FilterGleamingGlow(params); + + params.filterType = "fire"; + cachedFilters.filterFire = new FilterFire(params); + + params.filterType = "smoke"; + cachedFilters.filterSmoke = new FilterSmoke(params); + + params.filterType = "images"; + cachedFilters.filterImages = new FilterMirrorImages(params); +} + +export const PlaceableType = { + TOKEN: Token.embeddedName, + TILE: Tile.embeddedName, + TEMPLATE: MeasuredTemplate.embeddedName, + NOT_SUPPORTED: null }; function i18n(key) { return game.i18n.localize(key); } -export function registerSettings() { +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); +} + +function registerSettings() { game.settings.register("tokenmagic", "useAdditivePadding", { name: i18n("TMFX.useMaxPadding.name"), hint: i18n("TMFX.useMaxPadding.hint"), scope: "world", config: true, - default: true, + default: false, type: Boolean }); @@ -80,12 +132,54 @@ export function registerSettings() { hint: i18n("TMFX.minPadding.hint"), scope: "world", config: true, - default: 0, + default: 50, type: Number }); + + game.settings.register("tokenmagic", "fxPlayerPermission", { + name: i18n("TMFX.fxPlayerPermission.name"), + hint: i18n("TMFX.fxPlayerPermission.hint"), + scope: "world", + config: true, + default: false, + type: Boolean + }); + + game.settings.register("tokenmagic", "importOverwrite", { + name: i18n("TMFX.importOverwrite.name"), + hint: i18n("TMFX.importOverwrite.hint"), + scope: "world", + config: true, + default: false, + type: Boolean + }); + + game.settings.register("tokenmagic", "presets", { + name: "Token Magic FX presets", + hint: "Token Magic FX presets", + scope: "world", + config: false, + default: defaultPresets, + type: Object + }); } -const sleep = m => new Promise(r => setTimeout(r, m)); +export const SocketAction = { + SET_FLAG: "TMFXSetFlag" +}; + +export function broadcast(placeable, flag, socketAction) { + + var 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) @@ -100,6 +194,17 @@ export function isAdditivePaddingConfig() { return game.settings.get("tokenmagic", "useAdditivePadding"); } +export function isTheOne() { + const theOne = game.users.find((user) => user.isGM && user.active); + if (theOne && game.user !== theOne) { + return false; + } else return true +} + +export function mustBroadCast() { + return game.settings.get("tokenmagic", "fxPlayerPermission") && !isTheOne(); +} + export function autosetPaddingMode() { canvas.app.renderer.filter.useMaxPadding = !isAdditivePaddingConfig(); } @@ -109,35 +214,47 @@ export function log(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 getControlledPlaceables() { var controlled = []; switch (canvas.activeLayer.name) { - case "TokenLayer": + case TokenLayer.name: controlled = canvas.tokens.controlled; break; - case "TilesLayer": + case TilesLayer.name: controlled = canvas.tiles.controlled; break; } return controlled; } -// Only for tokens export function getTargetedTokens() { return canvas.tokens.placeables.filter(placeable => placeable.isTargeted); } export function getPlaceableById(id, type) { - let placeable; - let placeables; + let placeable = null; + let placeables = null; switch (type) { - case "Token": + case PlaceableType.TOKEN: placeables = canvas.tokens.placeables; break; - case "Tile": + case PlaceableType.TILE: placeables = canvas.tiles.placeables; break; + case PlaceableType.TEMPLATE: + placeables = canvas.templates.placeables; + break; } if (!(placeables == null) && placeables.length > 0) { @@ -160,16 +277,10 @@ export function objectAssign(target, ...sources) { return target; } -// NOTES FOR DEV : API will be extended in a near future, to allow more control over filters export function TokenMagic() { - // Add a filter on selected placeable(s) async function addFilterOnSelected(params) { - if (params == null - || !params.hasOwnProperty("filterType") - || !FilterType.hasOwnProperty(params.filterType)) { - return; - } + if (params == null) return; var controlled = getControlledPlaceables(); @@ -180,7 +291,24 @@ export function TokenMagic() { } }; + async function addUpdateFilterOnSelected(params) { + if (params == null) return; + + var controlled = getControlledPlaceables(); + + if (!(controlled == null) && controlled.length > 0) { + for (const placeable of controlled) { + await addUpdateFilter(placeable, params); + } + } + }; + async function addFiltersOnSelected(paramsArray) { + + if (typeof paramsArray === "string") { + paramsArray = getPreset(paramsArray); + } + if (paramsArray instanceof Array && paramsArray.length > 0) { for (const params of paramsArray) { await addFilterOnSelected(params); @@ -188,12 +316,21 @@ export function TokenMagic() { } }; - async function addFilterOnTargeted(params) { - if (params == null - || !params.hasOwnProperty("filterType") - || !FilterType.hasOwnProperty(params.filterType)) { - return; + async function addUpdateFiltersOnSelected(paramsArray) { + + if (typeof paramsArray === "string") { + paramsArray = getPreset(paramsArray); + } + + if (paramsArray instanceof Array && paramsArray.length > 0) { + for (const params of paramsArray) { + await addUpdateFilterOnSelected(params); + } } + }; + + async function addFilterOnTargeted(params) { + if (params == null) return; var targeted = getTargetedTokens(); @@ -205,6 +342,11 @@ export function TokenMagic() { } async function addFiltersOnTargeted(paramsArray) { + + if (typeof paramsArray === "string") { + paramsArray = getPreset(paramsArray); + } + if (paramsArray instanceof Array && paramsArray.length > 0) { for (const params of paramsArray) { await addFilterOnTargeted(params); @@ -212,7 +354,6 @@ export function TokenMagic() { } } - // Add a filter on a placeable async function addFilter(placeable, params) { if (placeable == null || params == null @@ -232,15 +373,7 @@ export function TokenMagic() { params.placeableId = placeable.id; params.filterInternalId = randomID(); params.filterOwner = game.data.userId; - - // TODO : to rework - if (placeable instanceof Token) { - params.placeableType = "Token"; - } else if (placeable instanceof Tile) { - params.placeableType = "Tile"; - } else { - params.placeableType = ""; - } + params.placeableType = placeable._TMFXgetPlaceableType(); var placeableNewFlag = [{ tmFilters: { @@ -261,7 +394,7 @@ export function TokenMagic() { placeableFlag = placeableActualFlag.concat(placeableNewFlag); } - await placeable.setFlag("tokenmagic", "filters", placeableFlag); + await placeable._TMFXsetFlag(placeableFlag); }; async function addUpdateFilters(placeable, paramsArray) { @@ -280,7 +413,8 @@ export function TokenMagic() { return; } - if (params.hasOwnProperty("filterId") && placeable.TMFXhasFilterId(params.filterId)) { + if (params.hasOwnProperty("filterId") && placeable.TMFXhasFilterId(params.filterId) + && placeable.TMFXhasFilterType(params.filterType)) { await updateFilterByPlaceable(params, placeable); } else { await addFilter(placeable, params); @@ -288,6 +422,9 @@ export function TokenMagic() { }; async function addFilters(placeable, paramsArray) { + if (typeof paramsArray === "string") { + paramsArray = getPreset(paramsArray); + } if (paramsArray instanceof Array && paramsArray.length > 0) { for (const params of paramsArray) { await addFilter(placeable, params); @@ -321,10 +458,14 @@ export function TokenMagic() { if (placeableIdSet.size <= 0) { return; } for (const placeableId of placeableIdSet) { - // TODO : to improve - var placeable = getPlaceableById(placeableId, "Token"); + // we must browse the collection of placeables whatever their types + // we have just a filterId. + var placeable = getPlaceableById(placeableId, PlaceableType.TOKEN); if (placeable == null) { - placeable = getPlaceableById(placeableId, "Tile"); + placeable = getPlaceableById(placeableId, PlaceableType.TILE); + } + if (placeable == null) { + placeable = getPlaceableById(placeableId, PlaceableType.TEMPLATE); } if (!(placeable == null) && placeable instanceof PlaceableObject) { await updateFilterByPlaceable(params, placeable); @@ -336,6 +477,9 @@ export function TokenMagic() { var 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) { @@ -349,6 +493,9 @@ export function TokenMagic() { var placeables = getTargetedTokens(); 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) { @@ -359,6 +506,10 @@ export function TokenMagic() { } async function updateFiltersByPlaceable(placeable, paramsArray) { + + if (typeof paramsArray === "string") { + paramsArray = getPreset(paramsArray); + } if (paramsArray instanceof Array && paramsArray.length > 0) { for (const params of paramsArray) { await updateFilterByPlaceable(params, placeable); @@ -376,13 +527,14 @@ export function TokenMagic() { }); workingFlags.forEach(flag => { - if (flag.tmFilters.tmFilterId === params.filterId) { + if (flag.tmFilters.tmFilterId === params.filterId + && flag.tmFilters.tmFilterType === params.filterType) { if (flag.tmFilters.hasOwnProperty("tmParams")) { objectAssign(flag.tmFilters.tmParams, params); } } }); - await placeable.setFlag("tokenmagic", "filters", workingFlags); + await placeable._TMFXsetFlag(workingFlags); }; @@ -412,9 +564,8 @@ export function TokenMagic() { async function deleteFilters(placeable, filterId = null) { if (placeable == null) { return; } - if (filterId == null) { - await placeable.unsetFlag("tokenmagic", "filters"); - } else if (typeof filterId === "string") { + if (filterId == null) await placeable._TMFXunsetFlag(); + else if (typeof filterId === "string") { var flags = placeable.getFlag("tokenmagic", "filters"); if (flags == null || !flags instanceof Array || flags.length < 1) { return; } // nothing to delete... @@ -426,11 +577,8 @@ export function TokenMagic() { } }); - if (workingFlags.length > 0) { - await placeable.setFlag("tokenmagic", "filters", workingFlags); - } else { - await placeable.unsetFlag("tokenmagic", "filters"); - } + if (workingFlags.length > 0) await placeable._TMFXsetFlag(workingFlags); + else await placeable._TMFXunsetFlag(); } }; @@ -464,26 +612,11 @@ export function TokenMagic() { return true; }; - // TODO : to improve function setFilter(placeable, filter, params = {}) { params.placeableId = placeable.id; - - if (placeable instanceof Token) { - params.placeableType = "Token"; - if (placeable.icon.filters == null) { - placeable.icon.filters = [filter]; - } else { - placeable.icon.filters.push(filter); - } - } else if (placeable instanceof Tile) { - params.placeableType = "Tile"; - if (placeable.tile.img.filters == null) { - placeable.tile.img.filters = [filter]; - } else { - placeable.tile.img.filters.push(filter); - } - } + params.placeableType = placeable._TMFXgetPlaceableType(); + placeable._TMFXsetRawFilters(filter); }; function _assignFilters(placeable, filters) { @@ -622,20 +755,261 @@ export function TokenMagic() { return theFilters; }; - // The clean up - if (placeable instanceof Token) { - placeable.icon.filters = filterTheFiltering(placeable.icon.filters); - } else if (placeable instanceof Tile) { - placeable.tile.img.filters = filterTheFiltering(placeable.tile.img.filters); + var sprite = placeable._TMFXgetSprite(); + if (sprite != null) { + sprite.filters = filterTheFiltering(sprite.filters); } }; + async function _importContent(content, options = {}) { + + 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 + ///////////////////////////////////////////////// + + var 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; + } + + var pst = game.settings.get("tokenmagic", "presets"); + var 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 resetPresetLibrary() { + if (!game.user.isGM) return; + + if (confirm(i18n("TMFX.preset.reset.message"))) { + try { + await game.settings.set("tokenmagic", "presets", defaultPresets); + ui.notifications.info(i18n("TMFX.preset.reset.success")); + } catch (e) { + error(e.message); + } + } + } + + async function importPresetLibraryFromURL(url) { + try { + $.getJSON(url, async function (content) { + return await _importContent(content); + }); + } catch (e) { + error(e.message); + error(i18n("TMFX.preset.import.failure")); + return false; + } + } + + async function importPresetLibraryFromPath(path) { + try { + const response = await fetch(path); + const content = await response.json(); + + return await _importContent(content); + + } 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 = "token-magic-fx-presets") { + var pst = game.settings.get("tokenmagic", "presets"); + if (pst == null || typeof pst !== "object") return false; + exportObjectAsJson(pst, exportName); + } + + function getPreset(presetName) { + var pst = game.settings.get("tokenmagic", "presets"); + if (pst == null || typeof pst !== "object") return undefined; + + const preset = pst.find(el => el['name'] === presetName); + if (!(preset == null) + && preset.hasOwnProperty("params") + && preset.params instanceof Array) return 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; + } + + if (typeof presetName !== "string") { + if (!silent) ui.notifications.error(i18n("TMFX.preset.delete.params.failure")); + return false; + } + + var pst = game.settings.get("tokenmagic", "presets"); + if (pst == null) { + if (!silent) ui.notifications.warn(i18n("TMFX.preset.delete.empty.failure")); + return false; + } + + var state = true; + const preset = pst.find(el => el['name'] === presetName); + + 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; + } + + if (typeof presetName !== "string" + && !(params instanceof Array)) { + if (!silent) ui.notifications.error(i18n("TMFX.preset.add.params.failure")); + return false; + } + + for (const param of params) { + param.filterId = presetName; + } + + var pst = game.settings.get("tokenmagic", "presets"); + var presetObject = {}; + presetObject.name = presetName; + presetObject.params = params; + + var state = true; + if (pst == null) { + pst = [presetObject]; + } else { + const preset = pst.find(el => el['name'] === presetName); + 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 { addFilter: addFilter, addFilters: addFilters, addFilterOnSelected: addFilterOnSelected, addFiltersOnSelected: addFiltersOnSelected, addFiltersOnTargeted: addFiltersOnTargeted, + addUpdateFiltersOnSelected: addUpdateFiltersOnSelected, + addUpdateFilterOnSelected: addUpdateFilterOnSelected, addUpdateFilters: addUpdateFilters, addUpdateFilter: addUpdateFilter, deleteFilters: deleteFilters, @@ -649,6 +1023,14 @@ export function TokenMagic() { updateFilterByPlaceable: updateFilterByPlaceable, hasFilterType: hasFilterType, hasFilterId: hasFilterId, + exportPresetLibrary: exportPresetLibrary, + importPresetLibrary: importPresetLibrary, + importPresetLibraryFromURL: importPresetLibraryFromURL, + importPresetLibraryFromPath: importPresetLibraryFromPath, + resetPresetLibrary: resetPresetLibrary, + getPreset: getPreset, + addPreset: addPreset, + deletePreset: deletePreset, _assignFilters: _assignFilters, _loadFilters: _loadFilters, _clearImgFiltersByPlaceable: _clearImgFiltersByPlaceable, @@ -660,12 +1042,70 @@ export function TokenMagic() { export const Magic = TokenMagic(); +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; } + + switch (data.tmAction) { + case SocketAction.SET_FLAG: + // getting the scene coming from the socket + var scene = game.scenes.get(data.tmViewedScene); + if (scene == null) return; + + // preparing flag data (with -= if the data is null) + var updateData; + if (data.tmFlag == null) updateData = { [`flags.tokenmagic.-=filters`]: null } + else updateData = { [`flags.tokenmagic.filters`]: data.tmFlag }; + updateData["_id"] = data.tmPlaceableId; + + // updating the placeable in the scene + await scene.updateEmbeddedEntity(data.tmPlaceableType, updateData); + break; + } + }); +}; + +async function requestLoadFilters(placeable, startTimeout = 0) { + var reqTimer; + + function launchRequest(placeable) { + reqTimer = setTimeout(() => { + if (placeable == null) return; + var check = placeable._TMFXcheckSprite(); + if (check == null) return; + else if (check) Magic._singleLoadFilters(placeable); + else launchRequest(placeable); + }, 35); + } + + function setRequestTimeOut() { + setTimeout(() => { + clearTimeout(reqTimer); + }, 2000); + } + + setTimeout(() => { + setRequestTimeOut(); + launchRequest(placeable); + }, startTimeout); +}; + Hooks.once("init", () => { registerSettings(); }); Hooks.on("ready", () => { log("Hook -> ready"); + initSocketListener(); window.TokenMagic = Magic; }); @@ -676,6 +1116,11 @@ Hooks.on("canvasInit", (canvas) => { Anime.resetAnimation(); }); +Hooks.once("canvasReady", (canvas) => { + log("Init -> canvasReady -> caching shaders"); + cacheFilters(); +}); + Hooks.on("canvasReady", (canvas) => { log("Hook -> canvasReady"); @@ -717,22 +1162,23 @@ Hooks.on("createToken", (scene, data, options) => { && data.flags.hasOwnProperty("tokenmagic") && data.flags.tokenmagic.hasOwnProperty("filters")) { - var placeable = getPlaceableById(data._id, "Token"); + var placeable = getPlaceableById(data._id, PlaceableType.TOKEN); - (async () => { - await sleep(100); - Magic._singleLoadFilters(placeable); - })(); + // request to load filters (when pixi containers are ready) + requestLoadFilters(placeable, 250); } }); Hooks.on("updateToken", (scene, data, options) => { log("Hook -> updateToken"); + if (scene.id !== game.user.viewedScene) return; + if (options.hasOwnProperty("img") || options.hasOwnProperty("tint") - || options.hasOwnProperty("height") || options.hasOwnProperty("width") ) { + || options.hasOwnProperty("height") || options.hasOwnProperty("width") + || options.hasOwnProperty("name")) { - var placeable = getPlaceableById(data._id, "Token"); + var placeable = getPlaceableById(data._id, PlaceableType.TOKEN); // removing animations on this placeable Anime.removeAnimation(data._id); @@ -740,13 +1186,11 @@ Hooks.on("updateToken", (scene, data, options) => { // clearing the filters (owned by tokenmagic) Magic._clearImgFiltersByPlaceable(placeable); - (async () => { - await sleep(100); - Magic._singleLoadFilters(placeable); - })(); + // querying filters reload (when pixi containers are ready) + requestLoadFilters(placeable, 250); } else { - Magic._updateFilters(data, options, "Token"); + Magic._updateFilters(data, options, PlaceableType.TOKEN); } }); @@ -760,23 +1204,23 @@ Hooks.on("deleteTile", (parent, doc, options, userId) => { Hooks.on("updateTile", (scene, data, options) => { log("Hook -> updateTile"); + if (scene.id !== game.user.viewedScene) return; + if (options.hasOwnProperty("img") || options.hasOwnProperty("tint")) { - var placeable = getPlaceableById(data._id, "Tile"); + var placeable = getPlaceableById(data._id, PlaceableType.TILE); // removing animations on this placeable Anime.removeAnimation(data._id); - (async () => { - await sleep(100); - Magic._singleLoadFilters(placeable); - })(); + // querying filters reload (when pixi containers are ready) + requestLoadFilters(placeable, 250); } else { - Magic._updateFilters(data, options, "Tile"); + Magic._updateFilters(data, options, PlaceableType.TILE); } }); Hooks.on("closeSettingsConfig", () => { autosetPaddingMode(); -}); +}); \ No newline at end of file diff --git a/tokenmagic/packs/token-magic-portfolio.db b/tokenmagic/packs/token-magic-portfolio.db index 32f53e9..3f4069c 100644 --- a/tokenmagic/packs/token-magic-portfolio.db +++ b/tokenmagic/packs/token-magic-portfolio.db @@ -1,46 +1,68 @@ -{"name":"24 - T12 - Warp Time Aura","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"type":"script","flags":{},"scope":"global","command":"let params =\r\n[{\r\n filterType: \"field\",\r\n shieldType: 12,\r\n gridPadding: 2,\r\n color: 0xAAAAAA,\r\n time: 0,\r\n blend: 2,\r\n intensity: 1.1,\r\n lightAlpha: 0.5,\r\n lightSize: 0.3,\r\n scale: 1,\r\n radius: 1,\r\n chromatic: false,\r\n animated :\r\n {\r\n time : \r\n { \r\n active: true, \r\n speed: 0.0009, \r\n animType: \"move\" \r\n }\r\n }\r\n}];\r\n\r\nTokenMagic.addFiltersOnSelected(params);","author":"Njc5YzFjZDI5NjZl","img":"icons/svg/dice-target.svg","actorIds":[],"_id":"2IOkNL2J1jETUvSP"} -{"_id":"2zRNjnw7Ps26h5xz","name":"22 - Smoke","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"type":"script","flags":{},"scope":"global","command":"let params =\r\n[{\r\n filterType: \"smoke\",\r\n color: 0x00FF00,\r\n time: 0,\r\n blend: 0,\r\n dimX: 1,\r\n dimY: 1,\r\n animated :\r\n {\r\n time : \r\n { \r\n active: true, \r\n speed: -0.006, \r\n animType: \"move\"\r\n }\r\n }\r\n}];\r\n\r\nTokenMagic.addFiltersOnSelected(params);","author":"Njc5YzFjZDI5NjZl","img":"icons/svg/dice-target.svg","actorIds":[]} -{"_id":"359Mw23cvaEDevkP","name":"24 - T04 - Earth Shell","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"type":"script","flags":{},"scope":"global","command":"let params =\r\n[{\r\n filterType: \"field\",\r\n shieldType: 4,\r\n gridPadding: 2,\r\n color: 0x755050,\r\n time: 0,\r\n blend: 2,\r\n intensity: 1,\r\n lightAlpha: 1,\r\n lightSize: 0.7,\r\n scale: 1,\r\n radius: 1,\r\n chromatic: false,\r\n animated :\r\n {\r\n time : \r\n { \r\n active: true, \r\n speed: 0.0015, \r\n animType: \"move\" \r\n }\r\n }\r\n}];\r\n\r\nTokenMagic.addFiltersOnSelected(params);","author":"Njc5YzFjZDI5NjZl","img":"icons/svg/dice-target.svg","actorIds":[]} -{"_id":"37aHASDQzFvbqmJG","name":"15 - Cosmic Ray","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"type":"script","flags":{},"scope":"global","command":"let params =\r\n[{\r\n filterType: \"ray\",\r\n time: 0,\r\n color: 0xCF8000,\r\n alpha: 0.5,\r\n divisor: 32,\r\n anchorX: 0,\r\n anchorY: 0,\r\n animated :\r\n {\r\n time : \r\n { \r\n active: true, \r\n speed: 0.0005, \r\n animType: \"move\" \r\n }\r\n }\r\n}];\r\n\r\nTokenMagic.addFiltersOnSelected(params);","author":"Njc5YzFjZDI5NjZl","img":"icons/svg/dice-target.svg","actorIds":[]} -{"name":"24 - T10 - Evil Aura","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"type":"script","flags":{},"scope":"global","command":"let params =\r\n[{\r\n filterType: \"field\",\r\n shieldType: 10,\r\n gridPadding: 1,\r\n color: 0x902005,\r\n time: 0,\r\n blend: 5,\r\n intensity: 1,\r\n lightAlpha: 4,\r\n lightSize: 0.8,\r\n scale: 0.5,\r\n radius: 1,\r\n chromatic: false,\r\n animated :\r\n {\r\n time : \r\n { \r\n active: true, \r\n speed: 0.0015, \r\n animType: \"move\" \r\n }\r\n }\r\n}];\r\n\r\nTokenMagic.addFiltersOnSelected(params);","author":"Njc5YzFjZDI5NjZl","img":"icons/svg/dice-target.svg","actorIds":[],"_id":"4Ywsytul1no7EwKb"} -{"_id":"6Do4AOxfbtCG8R4j","name":"24 - T06 - Air Bubble","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"type":"script","flags":{},"scope":"global","command":"let params =\r\n[{\r\n filterType: \"field\",\r\n shieldType: 6,\r\n gridPadding: 1,\r\n color: 0x306090,\r\n time: 0,\r\n blend: 2,\r\n intensity: 1.3,\r\n lightAlpha: 1,\r\n lightSize: 0.7,\r\n scale: 1,\r\n radius: 1,\r\n chromatic: false,\r\n animated :\r\n {\r\n time : \r\n { \r\n active: true, \r\n speed: 0.0015, \r\n animType: \"move\" \r\n }\r\n }\r\n}];\r\n\r\nTokenMagic.addFiltersOnSelected(params);","author":"Njc5YzFjZDI5NjZl","img":"icons/svg/dice-target.svg","actorIds":[]} -{"_id":"6ZIpqLC3agLw2Vgx","name":"24 - T07 - Mage Armor","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"type":"script","flags":{},"scope":"global","command":"let params =\r\n[{\r\n filterType: \"field\",\r\n shieldType: 7,\r\n gridPadding: 1,\r\n color: 0x777777,\r\n time: 0,\r\n blend: 2,\r\n intensity: 1,\r\n lightAlpha: 1,\r\n lightSize: 0.7,\r\n scale: 1,\r\n radius: 1,\r\n chromatic: false,\r\n animated :\r\n {\r\n time : \r\n { \r\n active: true, \r\n speed: 0.0015, \r\n animType: \"move\" \r\n }\r\n }\r\n}];\r\n\r\nTokenMagic.addFiltersOnSelected(params);","author":"Njc5YzFjZDI5NjZl","img":"icons/svg/dice-target.svg","actorIds":[]} -{"_id":"AHoBr50LyDjnphDw","name":"07 - Distortion","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"type":"script","flags":{},"scope":"global","command":"// you can change the mask of the filter\r\n// the mask must have a power of 2 h and w (512x512, 128x128, ...) \r\n// the distortion applies on black and white and shades of grey\r\n// after testing the first version of this macro try this :\r\n// -> maskPath: \"/modules/tokenmagic/fx/assets/waves-2.png\"\r\n\r\nlet params =\r\n{\r\n filterType: \"distortion\",\r\n maskPath: \"/modules/tokenmagic/fx/assets/distortion-1.png\",\r\n maskSpriteScaleX: 5,\r\n maskSpriteScaleY: 5,\r\n padding: 20,\r\n animated:\r\n {\r\n maskSpriteX: { active: true, speed: 0.05, animType: \"move\" },\r\n maskSpriteY: { active: true, speed: 0.07, animType: \"move\" }\r\n }\r\n};\r\n\r\nTokenMagic.addFilterOnSelected(params);","author":"Njc5YzFjZDI5NjZl","img":"icons/svg/dice-target.svg","actorIds":[]} +{"_id":"2IOkNL2J1jETUvSP","name":"24 - T12 - Warp Time Aura","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"type":"script","flags":{},"scope":"global","command":"let params =\r\n[{\r\n filterType: \"field\",\r\n filterId: \"myWarpField\",\r\n shieldType: 12,\r\n gridPadding: 2,\r\n color: 0xFFFFFF,\r\n time: 0,\r\n blend: 2,\r\n intensity: 1,\r\n lightAlpha: 0.8,\r\n lightSize: 0.5,\r\n scale: 0.9,\r\n radius: 1,\r\n chromatic: false,\r\n animated :\r\n {\r\n time : \r\n { \r\n active: true, \r\n speed: 0.0009, \r\n animType: \"move\" \r\n }\r\n }\r\n}];\r\n\r\nTokenMagic.addUpdateFiltersOnSelected(params);","author":"Njc5YzFjZDI5NjZl","img":"icons/svg/dice-target.svg","actorIds":[]} +{"_id":"2zRNjnw7Ps26h5xz","name":"22 - Smoke","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"type":"script","flags":{},"scope":"global","command":"let params =\r\n[{\r\n filterType: \"smoke\",\r\n filterId: \"mySmoke\",\r\n color: 0x50FFAA,\r\n time: 0,\r\n blend: 2,\r\n dimX: 1,\r\n dimY: 1,\r\n animated :\r\n {\r\n time : \r\n { \r\n active: true, \r\n speed: 0.0015, \r\n animType: \"move\"\r\n }\r\n }\r\n}];\r\n\r\nTokenMagic.addUpdateFiltersOnSelected(params);","author":"Njc5YzFjZDI5NjZl","img":"icons/svg/dice-target.svg","actorIds":[]} +{"_id":"359Mw23cvaEDevkP","name":"24 - T04 - Earth Shell","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"type":"script","flags":{},"scope":"global","command":"let params =\r\n[{\r\n filterType: \"field\",\r\n filterId: \"myEarthField\",\r\n shieldType: 4,\r\n gridPadding: 2,\r\n color: 0xBB9070,\r\n time: 0,\r\n blend: 1,\r\n intensity: 1.25,\r\n lightAlpha: 1,\r\n lightSize: 0.7,\r\n scale: 1,\r\n radius: 1,\r\n chromatic: false,\r\n animated :\r\n {\r\n time : \r\n { \r\n active: true, \r\n speed: 0.0015, \r\n animType: \"move\" \r\n }\r\n }\r\n}];\r\n\r\nTokenMagic.addUpdateFiltersOnSelected(params);","author":"Njc5YzFjZDI5NjZl","img":"icons/svg/dice-target.svg","actorIds":[]} +{"_id":"37aHASDQzFvbqmJG","name":"15 - Cosmic Ray","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"type":"script","flags":{},"scope":"global","command":"let params =\r\n[{\r\n filterType: \"ray\",\r\n filterId : \"myRay\",\r\n time: 0,\r\n color: 0xCF8000,\r\n alpha: 0.5,\r\n divisor: 32,\r\n anchorX: 0,\r\n anchorY: 0,\r\n animated :\r\n {\r\n time : \r\n { \r\n active: true, \r\n speed: 0.0005, \r\n animType: \"move\" \r\n }\r\n }\r\n}];\r\n\r\nTokenMagic.addUpdateFiltersOnSelected(params);","author":"Njc5YzFjZDI5NjZl","img":"icons/svg/dice-target.svg","actorIds":[]} +{"_id":"4Ywsytul1no7EwKb","name":"24 - T10 - Evil Aura","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"type":"script","flags":{},"scope":"global","command":"let params =\r\n[{\r\n filterType: \"field\",\r\n filterId: \"myEvilField\",\r\n shieldType: 9,\r\n gridPadding: 1,\r\n color: 0xFF3010,\r\n time: 0,\r\n blend: 5,\r\n intensity: 1,\r\n lightAlpha: 4,\r\n lightSize: 0.8,\r\n scale: 0.5,\r\n radius: 1,\r\n chromatic: false,\r\n animated :\r\n {\r\n time : \r\n { \r\n active: true, \r\n speed: 0.0012, \r\n animType: \"move\" \r\n },\r\n lightSize: \r\n {\r\n val1: 0.4, val2: 1.5,\r\n animType: \"syncCosOscillation\",\r\n loopDuration: 5000\r\n }\r\n }\r\n}];\r\n\r\nTokenMagic.addUpdateFiltersOnSelected(params);","author":"Njc5YzFjZDI5NjZl","img":"icons/svg/dice-target.svg","actorIds":[]} +{"_id":"6Do4AOxfbtCG8R4j","name":"24 - T06 - Air Bubble","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"type":"script","flags":{},"scope":"global","command":"let params =\r\n[{\r\n filterType: \"field\",\r\n filterId: \"myAirField\",\r\n shieldType: 6,\r\n gridPadding: 1.2,\r\n color: 0x7090AA,\r\n time: 0,\r\n blend: 14,\r\n intensity: 1,\r\n lightAlpha: 1,\r\n lightSize: 0.7,\r\n scale: 1,\r\n radius: 1,\r\n chromatic: false,\r\n animated :\r\n {\r\n time : \r\n { \r\n active: true, \r\n speed: 0.0015, \r\n animType: \"move\" \r\n }\r\n }\r\n}];\r\n\r\nTokenMagic.addUpdateFiltersOnSelected(params);","author":"Njc5YzFjZDI5NjZl","img":"icons/svg/dice-target.svg","actorIds":[]} +{"_id":"6ZIpqLC3agLw2Vgx","name":"24 - T07 - Mage Armor","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"type":"script","flags":{},"scope":"global","command":"let params =\r\n[{\r\n filterType: \"field\",\r\n filterId: \"myMageField\",\r\n shieldType: 7,\r\n gridPadding: 1.05,\r\n color: 0xFFFFFF,\r\n time: 0,\r\n blend: 10,\r\n intensity: 0.8,\r\n lightAlpha: 1,\r\n lightSize: 0.45,\r\n scale: 1,\r\n radius: 1,\r\n chromatic: false,\r\n animated :\r\n {\r\n time : \r\n { \r\n active: true, \r\n speed: 0.0015, \r\n animType: \"move\" \r\n }\r\n }\r\n}];\r\n\r\nTokenMagic.addUpdateFiltersOnSelected(params);","author":"Njc5YzFjZDI5NjZl","img":"icons/svg/dice-target.svg","actorIds":[]} +{"_id":"8nsxKDYhS1Wcc139","name":"26 - T02 - Mantle of Madness (liquid)","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"type":"script","flags":{},"scope":"global","command":"let params =\r\n[{\r\n filterType: \"liquid\",\r\n filterId: \"myMantle\",\r\n color: 0x0090FF,\r\n time: 0,\r\n blend: 5,\r\n intensity: 0.0001,\r\n spectral: false,\r\n scale: 7,\r\n animated :\r\n {\r\n time : \r\n { \r\n active: true, \r\n speed: 0.0015, \r\n animType: \"move\" \r\n },\r\n intensity : \r\n { \r\n active: true, \r\n animType: \"syncCosOscillation\",\r\n loopDuration: 30000,\r\n val1: 0.0001, \r\n val2: 4 \r\n },\r\n scale: \r\n { \r\n active: true, \r\n animType: \"syncCosOscillation\",\r\n loopDuration: 30000,\r\n val1: 7, \r\n val2: 1 \r\n }\r\n }\r\n}];\r\n\r\nTokenMagic.addUpdateFiltersOnSelected(params);","author":"Njc5YzFjZDI5NjZl","img":"icons/svg/dice-target.svg","actorIds":[]} +{"_id":"AHoBr50LyDjnphDw","name":"07 - Distortion","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"type":"script","flags":{},"scope":"global","command":"// you can change the mask of the filter\r\n// the mask must have a power of 2 h and w (512x512, 128x128, ...) \r\n// the distortion applies on black and white and shades of grey\r\n// after testing the first version of this macro try this :\r\n// -> maskPath: \"/modules/tokenmagic/fx/assets/waves-2.png\"\r\n\r\nlet params =\r\n{\r\n filterType: \"distortion\",\r\n filterId: \"myDistortion\",\r\n maskPath: \"/modules/tokenmagic/fx/assets/distortion-1.png\",\r\n maskSpriteScaleX: 5,\r\n maskSpriteScaleY: 5,\r\n padding: 20,\r\n animated:\r\n {\r\n maskSpriteX: { active: true, speed: 0.05, animType: \"move\" },\r\n maskSpriteY: { active: true, speed: 0.07, animType: \"move\" }\r\n }\r\n};\r\n\r\nTokenMagic.addUpdateFilterOnSelected(params);","author":"Njc5YzFjZDI5NjZl","img":"icons/svg/dice-target.svg","actorIds":[]} {"_id":"As1JrHLEm38Nm667","name":"F - 01 - Delete filters by Placeable","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"type":"script","flags":{},"scope":"global","command":"// Delete all filters on the placeable in parameter (token or tile)\r\nTokenMagic.deleteFilters(_token);","author":"Njc5YzFjZDI5NjZl","img":"icons/svg/dice-target.svg","actorIds":[]} -{"_id":"BGz9j7xPy0H2QlBf","name":"E - Click, click, click and click !","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"type":"script","flags":{},"scope":"global","command":"let glowFunc = async function() {\r\n\r\n const tokens = canvas.tokens.placeables;\r\n\r\n for (const token of tokens){\r\n if (token.TMFXhasFilterId(\"funnyAlternateGlow\")) {\r\n await token.TMFXdeleteFilters(\"funnyAlternateGlow\");\r\n } else {\r\n let params =\r\n [{\r\n filterType: \"glow\",\r\n filterId: \"funnyAlternateGlow\",\r\n color: Math.floor(Math.random() * 16777215),\r\n animated: null\r\n }];\r\n await token.TMFXaddUpdateFilters(params);\r\n }\r\n }\r\n};\r\n\r\nglowFunc();","author":"Njc5YzFjZDI5NjZl","img":"icons/svg/dice-target.svg","actorIds":[]} -{"_id":"CdFhWPKBMb5wj7cM","name":"11 - Blur","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"type":"script","flags":{},"scope":"global","command":"let params =\r\n[{\r\n filterType: \"blur\",\r\n padding: 10,\r\n quality: 4.0,\r\n blur: 0,\r\n blurX: 0,\r\n blurY: 0,\r\n animated:\r\n {\r\n blurX: \r\n { \r\n active: true, \r\n animType: \"syncCosOscillation\", \r\n loopDuration: 500, \r\n val1: 0, \r\n val2: 6\r\n },\r\n blurY: \r\n { \r\n active: true, \r\n animType: \"syncCosOscillation\", \r\n loopDuration: 750, \r\n val1: 0, \r\n val2: 6}\r\n }\r\n}];\r\n\r\nTokenMagic.addFiltersOnSelected(params);","author":"Njc5YzFjZDI5NjZl","img":"icons/svg/dice-target.svg","actorIds":[]} +{"_id":"BGz9j7xPy0H2QlBf","name":"E - Click, click, click and click !","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"type":"script","flags":{},"scope":"global","command":"let glowFunc = async function() {\r\n\r\n const myTokens = canvas.tokens.placeables;\r\n\r\n for (const myToken of myTokens ){\r\n if (myToken.TMFXhasFilterId(\"funnyAlternateGlow\")) {\r\n await myToken.TMFXdeleteFilters(\"funnyAlternateGlow\");\r\n } else {\r\n let params =\r\n [{\r\n filterType: \"glow\",\r\n filterId: \"funnyAlternateGlow\",\r\n color: Math.floor(Math.random() * 16777215),\r\n animated: null\r\n }];\r\n await myToken.TMFXaddUpdateFilters(params);\r\n }\r\n }\r\n};\r\n\r\nglowFunc();","author":"Njc5YzFjZDI5NjZl","img":"icons/svg/dice-target.svg","actorIds":[]} +{"_id":"CdFhWPKBMb5wj7cM","name":"11 - Blur","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"type":"script","flags":{},"scope":"global","command":"let params =\r\n[{\r\n filterType: \"blur\",\r\n filterId: \"myBlur\",\r\n padding: 10,\r\n quality: 4.0,\r\n blur: 0,\r\n blurX: 0,\r\n blurY: 0,\r\n animated:\r\n {\r\n blurX: \r\n { \r\n active: true, \r\n animType: \"syncCosOscillation\", \r\n loopDuration: 500, \r\n val1: 0, \r\n val2: 6\r\n },\r\n blurY: \r\n { \r\n active: true, \r\n animType: \"syncCosOscillation\", \r\n loopDuration: 750, \r\n val1: 0, \r\n val2: 6}\r\n }\r\n}];\r\n\r\nTokenMagic.addUpdateFiltersOnSelected(params);","author":"Njc5YzFjZDI5NjZl","img":"icons/svg/dice-target.svg","actorIds":[]} {"_id":"DCRnfJDBd25fOQxc","name":"F - 02 - Delete filters on Selected","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"type":"script","flags":{},"scope":"global","command":"// Delete all filters on the selected tokens/tiles\r\nTokenMagic.deleteFiltersOnSelected();","author":"Njc5YzFjZDI5NjZl","img":"icons/svg/dice-target.svg","actorIds":[]} -{"_id":"DoXvYWKPRcTpHbPG","name":"20 - Waves","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"type":"script","flags":{},"scope":"global","command":"// Below, you can turn on the anchor animation.\r\nlet params =\r\n[{\r\n filterType: \"wave\",\r\n time: 0,\r\n anchorX: 0.5,\r\n anchorY: 0.5,\r\n strength: 0.015,\r\n frequency: 60,\r\n color: 0xFFFFFF,\r\n maxIntensity: 3.0,\r\n minIntensity: 0.8,\r\n padding:10,\r\n animated :\r\n {\r\n time : \r\n { \r\n active: true, \r\n speed: 0.0085, \r\n animType: \"move\" \r\n },\r\n anchorX :\r\n {\r\n active: false,\r\n val1: 0.15,\r\n val2: 0.85,\r\n animType: \"syncCosOscillation\",\r\n loopDuration: 20000\r\n },\r\n anchorY :\r\n {\r\n active: false,\r\n val1: 0.15,\r\n val2: 0.85,\r\n animType: \"syncSinOscillation\",\r\n loopDuration: 20000\r\n }\r\n }\r\n}];\r\n\r\nTokenMagic.addFiltersOnSelected(params);","author":"Njc5YzFjZDI5NjZl","img":"icons/svg/dice-target.svg","actorIds":[]} -{"_id":"Edw0KaZiBtWEG86g","name":"16 - Inner Fog","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"type":"script","flags":{},"scope":"global","command":"let params =\r\n[{\r\n filterType: \"fog\",\r\n color: 0xFFFFFF,\r\n density: 0.45,\r\n time: 0,\r\n dimX: 1,\r\n dimY: 1,\r\n animated :\r\n {\r\n time : \r\n { \r\n active: true, \r\n speed: 1.2, \r\n animType: \"move\" \r\n }\r\n }\r\n}];\r\n\r\nTokenMagic.addFiltersOnSelected(params);","author":"Njc5YzFjZDI5NjZl","img":"icons/svg/dice-target.svg","actorIds":[]} -{"_id":"F47j6ivhmXxeYVmY","name":"19 - Fire","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"type":"script","flags":{},"scope":"global","command":"let params =\r\n[{\r\n filterType: \"fire\",\r\n intensity: 1,\r\n color: 0xFFFFFF,\r\n amplitude: 1,\r\n time: 0,\r\n blend: 2,\r\n fireBlend : 1,\r\n animated :\r\n {\r\n time : \r\n { \r\n active: true, \r\n speed: -0.0019, \r\n animType: \"move\" \r\n },\r\n intensity:\r\n {\r\n active:true,\r\n loopDuration: 15485,\r\n val1: 1,\r\n val2: 2,\r\n animType: \"syncCosOscillation\"\r\n },\r\n amplitude:\r\n {\r\n active:true,\r\n loopDuration: 4567,\r\n val1: 1,\r\n val2: 2,\r\n animType: \"syncCosOscillation\"\r\n }\r\n \r\n }\r\n}];\r\n\r\nTokenMagic.addFiltersOnSelected(params);","author":"Njc5YzFjZDI5NjZl","img":"icons/svg/dice-target.svg","actorIds":[]} -{"_id":"FBQzhLveCvFKOvJ7","name":"10 - BulgePinch","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"type":"script","flags":{},"scope":"global","command":"let params =\r\n[{\r\n filterType: \"bulgepinch\",\r\n padding: 150,\r\n strength: 0,\r\n zIndex: 2,\r\n radiusPercent: 200,\r\n animated:\r\n {\r\n strength: \r\n { \r\n active: true, \r\n animType: \"cosOscillation\", \r\n loopDuration: 2000, \r\n val1: 0, \r\n val2: 0.8\r\n }\r\n }\r\n}];\r\n\r\nTokenMagic.addFiltersOnSelected(params);","author":"Njc5YzFjZDI5NjZl","img":"icons/svg/dice-target.svg","actorIds":[]} -{"_id":"GHbWoqQWjeUjcStr","name":"24 - T13 - Simple Color","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"type":"script","flags":{},"scope":"global","command":"let params =\r\n[{\r\n filterType: \"field\",\r\n shieldType: 13,\r\n gridPadding: 2,\r\n color: 0x006030,\r\n time: 0,\r\n blend: 2,\r\n intensity: 1,\r\n lightAlpha: 0,\r\n lightSize: 0,\r\n scale: 1,\r\n radius: 1,\r\n chromatic: false,\r\n animated :\r\n {\r\n time : \r\n { \r\n active: true, \r\n speed: 0.0009, \r\n animType: \"move\" \r\n }\r\n }\r\n}];\r\n\r\nTokenMagic.addFiltersOnSelected(params);","author":"Njc5YzFjZDI5NjZl","img":"icons/svg/dice-target.svg","actorIds":[]} -{"_id":"GvYp56Thtf3n9RYy","name":"01 - Bevel","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"type":"script","flags":{},"scope":"global","command":"let params = \r\n[{\r\n filterType: \"bevel\",\r\n rotation: 0,\r\n thickness: 4,\r\n lightColor: 0x00FF00,\r\n lightAlpha: 0.7,\r\n shadowColor: 0xFF0000,\r\n shadowAlpha: 0.4,\r\n animated :\r\n {\r\n rotation: \r\n { \r\n active: true,\r\n clockWise: true, \r\n loopDuration: 500, \r\n animType: \"syncRotation\"\r\n }\r\n }\r\n}];\r\n\r\nTokenMagic.addFiltersOnSelected(params);\r\n","author":"Njc5YzFjZDI5NjZl","img":"icons/svg/dice-target.svg","actorIds":[]} -{"_id":"H3rF4XGEf76ZylwP","name":"14 - Remove Shadow","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"type":"script","flags":{},"scope":"global","command":"// this simple filter remove pixels with a certain amount of alpha\r\n// it can be useful to remove shadows before using glow or outline filters.\r\n\r\nlet params =\r\n[{\r\n filterType: \"zapshadow\",\r\n alphaTolerance: 0.60\r\n}];\r\n\r\nTokenMagic.addFiltersOnSelected(params);","author":"Njc5YzFjZDI5NjZl","img":"icons/svg/dice-target.svg","actorIds":[]} +{"_id":"DoXvYWKPRcTpHbPG","name":"20 - Waves","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"type":"script","flags":{},"scope":"global","command":"// Below, you can turn on the anchor animation.\r\nlet params =\r\n[{\r\n filterType: \"wave\",\r\n filterId: \"myWaves\",\r\n time: 0,\r\n anchorX: 0.5,\r\n anchorY: 0.5,\r\n strength: 0.015,\r\n frequency: 120,\r\n color: 0xFFFFFF,\r\n maxIntensity: 2.5,\r\n minIntensity: 0.9,\r\n padding:10,\r\n animated :\r\n {\r\n time : \r\n { \r\n active: true, \r\n speed: 0.0085, \r\n animType: \"move\" \r\n },\r\n anchorX :\r\n {\r\n active: false,\r\n val1: 0.15,\r\n val2: 0.85,\r\n animType: \"syncChaoticOscillation\",\r\n loopDuration: 20000\r\n },\r\n anchorY :\r\n {\r\n active: false,\r\n val1: 0.15,\r\n val2: 0.85,\r\n animType: \"syncSinOscillation\",\r\n loopDuration: 20000\r\n }\r\n }\r\n}];\r\n\r\nTokenMagic.addUpdateFiltersOnSelected(params);","author":"Njc5YzFjZDI5NjZl","img":"icons/svg/dice-target.svg","actorIds":[]} +{"_id":"Edw0KaZiBtWEG86g","name":"16 - Inner Fog","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"type":"script","flags":{},"scope":"global","command":"let params =\r\n[{\r\n filterType: \"fog\",\r\n filterId: \"myFog\",\r\n color: 0x000000,\r\n density: 0.65,\r\n time: 0,\r\n dimX: 1,\r\n dimY: 1,\r\n animated :\r\n {\r\n time : \r\n { \r\n active: true, \r\n speed: 2.2, \r\n animType: \"move\" \r\n }\r\n }\r\n}];\r\n\r\nTokenMagic.addUpdateFiltersOnSelected(params);","author":"Njc5YzFjZDI5NjZl","img":"icons/svg/dice-target.svg","actorIds":[]} +{"_id":"F47j6ivhmXxeYVmY","name":"19 - Fire","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"type":"script","flags":{},"scope":"global","command":"let params =\r\n[{\r\n filterType: \"fire\",\r\n filterId: \"myFire\",\r\n intensity: 1,\r\n color: 0xFFFFFF,\r\n amplitude: 1,\r\n time: 0,\r\n blend: 2,\r\n fireBlend : 1,\r\n animated :\r\n {\r\n time : \r\n { \r\n active: true, \r\n speed: -0.0024, \r\n animType: \"move\" \r\n },\r\n intensity:\r\n {\r\n active:true,\r\n loopDuration: 15000,\r\n val1: 0.8,\r\n val2: 2,\r\n animType: \"syncCosOscillation\"\r\n },\r\n amplitude:\r\n {\r\n active:true,\r\n loopDuration: 4400,\r\n val1: 1,\r\n val2: 1.4,\r\n animType: \"syncCosOscillation\"\r\n }\r\n \r\n }\r\n}];\r\n\r\nTokenMagic.addUpdateFiltersOnSelected(params);","author":"Njc5YzFjZDI5NjZl","img":"icons/svg/dice-target.svg","actorIds":[]} +{"_id":"FBQzhLveCvFKOvJ7","name":"10 - BulgePinch","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"type":"script","flags":{},"scope":"global","command":"let params =\r\n[{\r\n filterType: \"bulgepinch\",\r\n filterId: \"myBulge\",\r\n padding: 150,\r\n strength: 0,\r\n zIndex: 2,\r\n radiusPercent: 200,\r\n animated:\r\n {\r\n strength: \r\n { \r\n active: true, \r\n animType: \"cosOscillation\", \r\n loopDuration: 2000, \r\n val1: 0, \r\n val2: 0.45\r\n }\r\n }\r\n}];\r\n\r\nTokenMagic.addUpdateFiltersOnSelected(params);","author":"Njc5YzFjZDI5NjZl","img":"icons/svg/dice-target.svg","actorIds":[]} +{"_id":"GHbWoqQWjeUjcStr","name":"24 - T13 - Simple Color","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"type":"script","flags":{},"scope":"global","command":"let params =\r\n[{\r\n filterType: \"field\",\r\n filterId: \"mySimpleField\",\r\n shieldType: 13,\r\n gridPadding: 2,\r\n color: 0x00CC00,\r\n time: 0,\r\n blend: 14,\r\n intensity: 1,\r\n lightAlpha: 0,\r\n lightSize: 0,\r\n scale: 1,\r\n radius: 1,\r\n chromatic: false,\r\n animated :\r\n {\r\n time : \r\n { \r\n active: true, \r\n speed: 0.0009, \r\n animType: \"move\" \r\n }\r\n }\r\n}];\r\n\r\nTokenMagic.addUpdateFiltersOnSelected(params);","author":"Njc5YzFjZDI5NjZl","img":"icons/svg/dice-target.svg","actorIds":[]} +{"_id":"GvYp56Thtf3n9RYy","name":"01 - Bevel","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"type":"script","flags":{},"scope":"global","command":"let params = \r\n[{\r\n filterType: \"bevel\",\r\n filterId: \"myBevel\",\r\n rotation: 0,\r\n thickness: 5,\r\n lightColor: 0xFF0000,\r\n lightAlpha: 0.8,\r\n shadowColor: 0x00FF00,\r\n shadowAlpha: 0.5,\r\n animated :\r\n {\r\n rotation: \r\n { \r\n active: true,\r\n clockWise: true, \r\n loopDuration: 1600, \r\n animType: \"syncRotation\"\r\n }\r\n }\r\n}];\r\n\r\nTokenMagic.addUpdateFiltersOnSelected(params);\r\n","author":"Njc5YzFjZDI5NjZl","img":"icons/svg/dice-target.svg","actorIds":[]} +{"_id":"Gzt5MfynWLcXDTZF","name":"23 - T03 - Spectral Images","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"type":"script","flags":{},"scope":"global","command":"// Another extreme example...\r\nlet params =\r\n[{\r\n filterType: \"images\",\r\n filterId: \"mySpectralImages\",\r\n time: 0, \r\n blend: 4,\r\n nbImage: 4, \r\n padding: 100,\r\n alphaImg: 0.5, \r\n alphaChr: 0.0,\r\n ampX: 0.10, \r\n ampY: 0.10,\r\n animated :\r\n {\r\n time: \r\n { \r\n speed: 0.0010, \r\n animType: \"move\" \r\n },\r\n ampX:\r\n {\r\n val1: 0, val2: 0.22,\r\n animType: \"syncCosOscillation\",\r\n loopDuration: 2500\r\n },\r\n ampY:\r\n {\r\n val1: 0, val2: 0.24,\r\n animType: \"syncCosOscillation\",\r\n loopDuration: 2500,\r\n pauseBetweenDuration: 2500\r\n },\r\n alphaChr: \r\n {\r\n val1: 1, val2: 0,\r\n animType: \"syncCosOscillation\",\r\n loopDuration: 2500\r\n },\r\n alphaImg: \r\n {\r\n val1: 0.2, val2: 0.8,\r\n animType: \"syncSinOscillation\",\r\n loopDuration: 2500\r\n }\r\n }\r\n}];\r\n\r\nTokenMagic.addUpdateFiltersOnSelected(params);","author":"Njc5YzFjZDI5NjZl","img":"icons/svg/dice-target.svg","actorIds":[]} +{"_id":"H3rF4XGEf76ZylwP","name":"14 - Remove Shadow","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"type":"script","flags":{},"scope":"global","command":"// this simple filter remove pixels with a certain amount of alpha\r\n// it can be useful to remove shadows before using glow or outline filters.\r\n\r\nlet params =\r\n[{\r\n filterType: \"zapshadow\",\r\n filterId: \"myZap\",\r\n alphaTolerance: 0.45\r\n}];\r\n\r\nTokenMagic.addUpdateFiltersOnSelected(params);","author":"Njc5YzFjZDI5NjZl","img":"icons/svg/dice-target.svg","actorIds":[]} {"_id":"HjzhkTFUng8sxWkH","name":"D - Auto-Destroy Example","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"type":"script","flags":{},"scope":"global","command":"let params = \r\n[{\r\n filterType: \"bevel\",\r\n autoDestroy: true,\r\n rotation: 0,\r\n thickness: 5,\r\n lightColor: 0x00FF00,\r\n lightAlpha: 0.7,\r\n shadowColor: 0xFF0000,\r\n shadowAlpha: 0.4,\r\n animated :\r\n {\r\n rotation: \r\n { \r\n active: true,\r\n clockWise: true, \r\n loopDuration: 1000,\r\n loops: 5,\r\n animType: \"rotation\"\r\n }\r\n }\r\n}];\r\n\r\nTokenMagic.addFiltersOnSelected(params);\r\n","author":"Njc5YzFjZDI5NjZl","img":"icons/svg/dice-target.svg","actorIds":[]} -{"_id":"IA3ofbRDpi3Rjgcy","name":"24 - T02 - Fire Shield","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"type":"script","flags":{},"scope":"global","command":"let params =\r\n[{\r\n filterType: \"field\",\r\n shieldType: 1,\r\n gridPadding: 2,\r\n color: 0xD08050,\r\n time: 0,\r\n blend: 2,\r\n intensity: 1.15,\r\n lightAlpha: 2,\r\n lightSize: 0.7,\r\n scale: 1,\r\n radius: 1,\r\n chromatic: false,\r\n animated :\r\n {\r\n time : \r\n { \r\n active: true, \r\n speed: 0.0015, \r\n animType: \"move\" \r\n }\r\n }\r\n}];\r\n\r\nTokenMagic.addFiltersOnSelected(params);","author":"Njc5YzFjZDI5NjZl","img":"icons/svg/dice-target.svg","actorIds":[]} +{"_id":"IA3ofbRDpi3Rjgcy","name":"24 - T02 - Fire Shield","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"type":"script","flags":{},"scope":"global","command":"let params =\r\n[{\r\n filterType: \"field\",\r\n filterId: \"myFireField\",\r\n shieldType: 1,\r\n gridPadding: 2,\r\n color: 0xE58550,\r\n time: 0,\r\n blend: 2,\r\n intensity: 1.15,\r\n lightAlpha: 2,\r\n lightSize: 0.7,\r\n scale: 1,\r\n radius: 1,\r\n chromatic: false,\r\n animated :\r\n {\r\n time : \r\n { \r\n active: true, \r\n speed: 0.0015, \r\n animType: \"move\" \r\n }\r\n }\r\n}];\r\n\r\nTokenMagic.addUpdateFiltersOnSelected(params);","author":"Njc5YzFjZDI5NjZl","img":"icons/svg/dice-target.svg","actorIds":[]} +{"_id":"IEl6F5dtFcYBZDDZ","name":"25 - T01 - Sunburst Rays (xray)","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"type":"script","flags":{},"scope":"global","command":"let params =\r\n[{\r\n filterType: \"xray\",\r\n filterId: \"mySunburstRays\",\r\n time: 0,\r\n color: 0xFFBB00,\r\n blend: 9,\r\n dimX: 1,\r\n dimY: 1,\r\n anchorX: 0,\r\n anchorY: 0,\r\n divisor: 36,\r\n intensity: 4,\r\n animated :\r\n {\r\n time : \r\n { \r\n active: true, \r\n speed: 0.0012, \r\n animType: \"move\" \r\n },\r\n anchorX:\r\n {\r\n animType: \"syncCosOscillation\",\r\n loopDuration : 6000,\r\n val1: 0.40,\r\n val2: 0.60\r\n }\r\n }\r\n}];\r\n\r\nTokenMagic.addUpdateFiltersOnSelected(params);","author":"Njc5YzFjZDI5NjZl","img":"icons/svg/dice-target.svg","actorIds":[]} {"_id":"Ia0tPcllVQq96yXF","name":"C - Electric Multi-Filters","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"type":"script","flags":{},"scope":"global","command":"// works better with tokens or tiles with no shadows\r\nlet params =\r\n[{\r\n filterType: \"shadow\",\r\n blur: 2,\r\n quality: 5,\r\n distance: 0,\r\n alpha: 1.,\r\n padding: 100,\r\n color: 0xFFFFFF,\r\n animated:\r\n {\r\n blur: \r\n { \r\n active: true, \r\n loopDuration: 500, \r\n animType: \"syncCosOscillation\", \r\n val1: 2, \r\n val2: 4\r\n },\r\n }\r\n},\r\n{\r\n filterType: \"electric\",\r\n color: 0xFFFFFF,\r\n time: 0,\r\n blend: 2,\r\n intensity: 5,\r\n animated :\r\n {\r\n time : \r\n { \r\n active: true, \r\n speed: 0.0020, \r\n animType: \"move\" \r\n }\r\n }\r\n}];\r\n\r\nTokenMagic.addFiltersOnSelected(params);","author":"Njc5YzFjZDI5NjZl","img":"icons/svg/dice-target.svg","actorIds":[]} -{"_id":"LrfXNjrImAWK5Hb2","name":"24 - T05 - Mega Earth Shell (on top)","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"type":"script","flags":{},"scope":"global","command":"let params =\r\n[{\r\n filterType: \"field\",\r\n shieldType: 5,\r\n gridPadding: 3,\r\n color: 0x905555,\r\n time: 0,\r\n blend: 2,\r\n intensity: 1.2,\r\n lightAlpha: 1,\r\n lightSize: 0.7,\r\n scale: 1,\r\n radius: 1,\r\n zIndex: 5,\r\n chromatic: false,\r\n animated :\r\n {\r\n time : \r\n { \r\n active: true, \r\n speed: 0.0015, \r\n animType: \"move\" \r\n }\r\n }\r\n}];\r\n\r\nTokenMagic.addFiltersOnSelected(params);","author":"Njc5YzFjZDI5NjZl","img":"icons/svg/dice-target.svg","actorIds":[]} -{"_id":"OWgJD9lvBlDzXALz","name":"09 - Twist","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"type":"script","flags":{},"scope":"global","command":"let params =\r\n[{\r\n filterType: \"twist\",\r\n radiusPercent: 120,\r\n angle: 0,\r\n animated:\r\n {\r\n angle: \r\n { \r\n active: true, \r\n animType: \"sinOscillation\",\r\n loopDuration: 10000, \r\n val1: -0.6*Math.PI, \r\n val2: +0.6*Math.PI\r\n }\r\n }\r\n}];\r\n\r\nTokenMagic.addFiltersOnSelected(params);","author":"Njc5YzFjZDI5NjZl","img":"icons/svg/dice-target.svg","actorIds":[]} -{"_id":"SSY0fjib0PgJaKEK","name":"24 - T03 - Poisoned Smoke","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"type":"script","flags":{},"scope":"global","command":"let params =\r\n[{\r\n filterType: \"field\",\r\n shieldType: 3,\r\n gridPadding: 1,\r\n color: 0x106040,\r\n time: 0,\r\n blend: 2,\r\n intensity: 1,\r\n lightAlpha: 1,\r\n lightSize: 0.7,\r\n scale: 1,\r\n radius: 1,\r\n chromatic: false,\r\n animated :\r\n {\r\n time : \r\n { \r\n active: true, \r\n speed: 0.0015, \r\n animType: \"move\" \r\n }\r\n }\r\n}];\r\n\r\nTokenMagic.addFiltersOnSelected(params);","author":"Njc5YzFjZDI5NjZl","img":"icons/svg/dice-target.svg","actorIds":[]} -{"_id":"VWTz2fKfSb6WK7Mo","name":"02 - Adjustment","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"type":"script","flags":{},"scope":"global","command":"let params =\r\n[{\r\n filterType: \"adjustment\",\r\n saturation: 1,\r\n brightness: 1,\r\n contrast: 1,\r\n gamma: 1,\r\n red: 4,\r\n green: 0.5,\r\n blue: 0.5,\r\n alpha: 0.5,\r\n animated:\r\n {\r\n alpha: \r\n { \r\n active: true, \r\n loopDuration: 5000, \r\n animType: \"syncCosOscillation\",\r\n val1: 0.5,\r\n val2: 1 }\r\n }\r\n}];\r\n\r\nTokenMagic.addFiltersOnSelected(params);","author":"Njc5YzFjZDI5NjZl","img":"icons/svg/dice-target.svg","actorIds":[]} -{"_id":"VuMHH9LMD51MNJzZ","name":"24 - T11 - Grid Force Field","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"type":"script","flags":{},"scope":"global","command":"let params =\r\n[{\r\n filterType: \"field\",\r\n shieldType: 11,\r\n gridPadding: 2,\r\n color: 0x009090,\r\n time: 0,\r\n blend: 2,\r\n intensity: 1,\r\n lightAlpha: 1,\r\n lightSize: 0.3,\r\n scale: 0.5,\r\n radius: 1,\r\n chromatic: false,\r\n animated :\r\n {\r\n time : \r\n { \r\n active: true, \r\n speed: 0.0009, \r\n animType: \"move\" \r\n }\r\n }\r\n}];\r\n\r\nTokenMagic.addFiltersOnSelected(params);","author":"Njc5YzFjZDI5NjZl","img":"icons/svg/dice-target.svg","actorIds":[]} -{"_id":"YJjeB7N0L1rGfZD2","name":"18 - Electric","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"type":"script","flags":{},"scope":"global","command":"let params =\r\n[{\r\n filterType: \"electric\",\r\n color: 0xFFFFFF,\r\n time: 0,\r\n blend: 1,\r\n intensity: 5,\r\n animated :\r\n {\r\n time : \r\n { \r\n active: true, \r\n speed: 0.0020, \r\n animType: \"move\" \r\n }\r\n }\r\n}];\r\n\r\nTokenMagic.addFiltersOnSelected(params);","author":"Njc5YzFjZDI5NjZl","img":"icons/svg/dice-target.svg","actorIds":[]} -{"_id":"aoqr6qPxif62zWLo","name":"24 - T09 - Water Defense","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"type":"script","flags":{},"scope":"global","command":"let params =\r\n[{\r\n filterType: \"field\",\r\n shieldType: 9,\r\n gridPadding: 1,\r\n color: 0x1090CC,\r\n time: 0,\r\n blend: 2,\r\n intensity: 1,\r\n lightAlpha: 1,\r\n lightSize: 0.7,\r\n scale: 2,\r\n radius: 1,\r\n chromatic: false,\r\n animated :\r\n {\r\n time : \r\n { \r\n active: true, \r\n speed: 0.0015, \r\n animType: \"move\" \r\n }\r\n }\r\n}];\r\n\r\nTokenMagic.addFiltersOnSelected(params);","author":"Njc5YzFjZDI5NjZl","img":"icons/svg/dice-target.svg","actorIds":[]} -{"_id":"b5Enw7tEwfjDNHuY","name":"04 - Outline","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"type":"script","flags":{"combat-utility-belt":{"macroTrigger":""}},"scope":"global","command":"let params = \r\n[{\r\n filterType: \"outline\",\r\n padding: 10,\r\n color: 0x05B0B0,\r\n thickness: 1,\r\n quality: 10,\r\n animated :\r\n {\r\n thickness: \r\n { \r\n active: true,\r\n loopDuration: 1000,\r\n animType: \"syncCosOscillation\",\r\n val1: 1, \r\n val2: 8\r\n }\r\n }\r\n}];\r\n\r\nTokenMagic.addFiltersOnSelected(params);","author":"Njc5YzFjZDI5NjZl","img":"icons/svg/dice-target.svg","actorIds":[]} -{"_id":"cCEOQFsJvjhSTbbM","name":"06 - Bloom","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"type":"script","flags":{},"scope":"global","command":"let params = \r\n[{\r\n filterType: \"xbloom\",\r\n threshold: 0.35,\r\n bloomScale: 0,\r\n brightness: 1.2,\r\n blur: 0.1,\r\n padding: 10,\r\n quality: 15,\r\n blendMode: 0,\r\n animated:\r\n {\r\n bloomScale: \r\n { \r\n active: true, \r\n loopDuration: 2000, \r\n animType: \"syncCosOscillation\", \r\n val1: 0, \r\n val2: 2\r\n },\r\n threshold: \r\n { \r\n active: false, \r\n loopDuration: 2000, \r\n animType: \"syncCosOscillation\", \r\n val1: 0.05, \r\n val2: 1.9\r\n }\r\n }\r\n}];\r\n\r\nTokenMagic.addFiltersOnSelected(params);\r\n","author":"Njc5YzFjZDI5NjZl","img":"icons/svg/dice-target.svg","actorIds":[]} -{"_id":"cOaB7NxSQ5jNDd5g","name":"27 - T01 - Burning Aura (xglow)","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"type":"script","flags":{},"scope":"global","command":"let params =\r\n[{\r\n filterType: \"zapshadow\",\r\n filterId: \"myZapShadow\",\r\n alphaTolerance: 0.50\r\n},\r\n{\r\n filterType: \"xglow\",\r\n filterId: \"myMagicGlow\",\r\n auraType: 2,\r\n color: 0x903010,\r\n thickness: 4.8,\r\n scale: 4.,\r\n time: 0,\r\n auraIntensity: 2,\r\n subAuraIntensity: 1.5,\r\n threshold: 0.40,\r\n discard: true,\r\n animated:\r\n {\r\n time : \r\n { \r\n active: true,\r\n speed: 0.0027, \r\n animType: \"move\" \r\n },\r\n thickness:\r\n {\r\n active: true,\r\n loopDuration: 3000, \r\n animType: \"cosOscillation\", \r\n val1:4.5, \r\n val2:6\r\n }\r\n }\r\n}];\r\n\r\nTokenMagic.addFiltersOnSelected(params);","author":"Njc5YzFjZDI5NjZl","img":"icons/svg/dice-target.svg","actorIds":[]} +{"_id":"Ku4jBl972O7hHczs","name":"F - 03 - Export FX Presets","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"type":"script","flags":{},"scope":"global","command":"TokenMagic.exportPresetLibrary();","author":"Njc5YzFjZDI5NjZl","img":"icons/svg/dice-target.svg","actorIds":[]} +{"_id":"LrfXNjrImAWK5Hb2","name":"24 - T05 - Mega Chroma Shell (on top)","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"type":"script","flags":{},"scope":"global","command":"let params =\r\n[{\r\n filterType: \"field\",\r\n filterId: \"myEarthFieldTop\",\r\n shieldType: 5,\r\n gridPadding: 3,\r\n color: 0xAAAAAA,\r\n time: 0,\r\n blend: 5,\r\n intensity: 1.9,\r\n lightAlpha: 1,\r\n lightSize: 0.7,\r\n scale: 1,\r\n radius: 1,\r\n zIndex: 5,\r\n chromatic: true,\r\n animated :\r\n {\r\n time : \r\n { \r\n active: true, \r\n speed: 0.0015, \r\n animType: \"move\" \r\n }\r\n }\r\n}];\r\n\r\nTokenMagic.addUpdateFiltersOnSelected(params);","author":"Njc5YzFjZDI5NjZl","img":"icons/svg/dice-target.svg","actorIds":[]} +{"_id":"OWgJD9lvBlDzXALz","name":"09 - Twist","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"type":"script","flags":{},"scope":"global","command":"let params =\r\n[{\r\n filterType: \"twist\",\r\n filterId: \"myTwist\",\r\n radiusPercent: 120,\r\n angle: 0,\r\n animated:\r\n {\r\n angle: \r\n { \r\n active: true, \r\n animType: \"sinOscillation\",\r\n loopDuration: 10000, \r\n val1: -0.6*Math.PI, \r\n val2: +0.6*Math.PI\r\n }\r\n }\r\n}];\r\n\r\nTokenMagic.addUpdateFiltersOnSelected(params);","author":"Njc5YzFjZDI5NjZl","img":"icons/svg/dice-target.svg","actorIds":[]} +{"_id":"QzFJd7hkaYesE7Ud","name":"F - 04 - Import FX Presets (local)","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"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","actorIds":[]} +{"_id":"SSY0fjib0PgJaKEK","name":"24 - T03 - Poisoned Smoke","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"type":"script","flags":{},"scope":"global","command":"let params =\r\n[{\r\n filterType: \"field\",\r\n filterId: \"mySmokeField\",\r\n shieldType: 3,\r\n gridPadding: 10,\r\n color: 0x60CC70,\r\n time: 0,\r\n blend: 2,\r\n intensity: 0.9,\r\n lightAlpha: 1,\r\n lightSize: 0.7,\r\n scale: 1,\r\n radius: 1,\r\n chromatic: false,\r\n animated :\r\n {\r\n time : \r\n { \r\n active: true, \r\n speed: 0.0015, \r\n animType: \"move\" \r\n }\r\n }\r\n}];\r\n\r\nTokenMagic.addUpdateFiltersOnSelected(params);","author":"Njc5YzFjZDI5NjZl","img":"icons/svg/dice-target.svg","actorIds":[]} +{"_id":"SpHEaIwubKpbwzvV","name":"25 - T04 - Blue Rays ! (xray)","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"type":"script","flags":{},"scope":"global","command":"let params =\r\n[{\r\n filterType: \"xray\",\r\n filterId: \"myBlueRay\",\r\n time: 0,\r\n color: 0x1030FF,\r\n blend: 9,\r\n dimX: 1,\r\n dimY: 1,\r\n anchorX: 0,\r\n anchorY: 0,\r\n divisor: 24,\r\n intensity: 1,\r\n animated :\r\n {\r\n time : \r\n { \r\n active: true, \r\n speed: 0.0002, \r\n animType: \"move\" \r\n },\r\n anchorX:\r\n {\r\n animType: \"syncCosOscillation\",\r\n loopDuration : 18000,\r\n val1: 0.05,\r\n val2: 0.95\r\n },\r\n anchorY:\r\n {\r\n animType: \"syncSinOscillation\",\r\n loopDuration : 18000,\r\n val1: 0.05,\r\n val2: 0.95\r\n }\r\n }\r\n}];\r\n\r\nTokenMagic.addUpdateFiltersOnSelected(params);","author":"Njc5YzFjZDI5NjZl","img":"icons/svg/dice-target.svg","actorIds":[]} +{"_id":"SpvVIO1eHYG96TGX","name":"26 - T01 - Spectral Body (liquid)","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"type":"script","flags":{},"scope":"global","command":"let params =\r\n[{\r\n filterType: \"liquid\",\r\n filterId: \"mySpectralBody\",\r\n color: 0x20AAEE,\r\n time: 0,\r\n blend: 8,\r\n intensity: 4,\r\n spectral: true,\r\n scale: 0.9,\r\n animated :\r\n {\r\n time : \r\n { \r\n active: true, \r\n speed: 0.0010, \r\n animType: \"move\" \r\n },\r\n color: \r\n {\r\n active: true, \r\n loopDuration: 6000, \r\n animType: \"colorOscillation\", \r\n val1:0xFFFFFF, \r\n val2:0x00AAFF\r\n }\r\n }\r\n}];\r\n\r\nTokenMagic.addUpdateFiltersOnSelected(params);","author":"Njc5YzFjZDI5NjZl","img":"icons/svg/dice-target.svg","actorIds":[]} +{"_id":"T953GJB235BbrCll","name":"26 - T03 - Drift in Plans (liquid+waves)","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"type":"script","flags":{},"scope":"global","command":"let params =\r\n[{\r\n filterType: \"wave\",\r\n filterId: \"myDriftWaves\",\r\n time: 0,\r\n anchorX: 0.5,\r\n anchorY: 0.5,\r\n strength: 0.035,\r\n frequency: 20,\r\n color: 0xFFFFFF,\r\n maxIntensity: 1.5,\r\n minIntensity: 0.5,\r\n padding:10,\r\n animated :\r\n {\r\n time : \r\n { \r\n active: true, \r\n speed: 0.0085, \r\n animType: \"move\" \r\n },\r\n anchorX :\r\n {\r\n active: true,\r\n val1: 0.35,\r\n val2: 0.65,\r\n animType: \"syncCosOscillation\",\r\n loopDuration: 10000\r\n },\r\n anchorY :\r\n {\r\n active: true,\r\n val1: 0.35,\r\n val2: 0.65,\r\n animType: \"syncSinOscillation\",\r\n loopDuration: 10000\r\n }\r\n }\r\n},\r\n{\r\n filterType: \"liquid\",\r\n filterId: \"myDriftLiquid\",\r\n color: 0xFF0000,\r\n time: 0,\r\n blend: 6,\r\n intensity: 5,\r\n spectral: false,\r\n scale: 2.5,\r\n animated :\r\n {\r\n time : \r\n { \r\n active: true, \r\n speed: 0.0018, \r\n animType: \"move\" \r\n },\r\n color: \r\n {\r\n active: true, \r\n loopDuration: 9000, \r\n animType: \"colorOscillation\", \r\n val1:0xFF0000, \r\n val2:0xFFFFFF\r\n }\r\n }\r\n}];\r\n\r\nTokenMagic.addUpdateFiltersOnSelected(params);","author":"Njc5YzFjZDI5NjZl","img":"icons/svg/dice-target.svg","actorIds":[]} +{"_id":"VWTz2fKfSb6WK7Mo","name":"02 - Adjustment","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"type":"script","flags":{},"scope":"global","command":"let params =\r\n[{\r\n filterType: \"adjustment\",\r\n filterId: \"myAdjust\",\r\n saturation: 1.5,\r\n brightness: 1.5,\r\n contrast: 2,\r\n gamma: 2,\r\n red: 4,\r\n green: 0.25,\r\n blue: 0.25,\r\n alpha: 1,\r\n animated:\r\n {\r\n alpha: \r\n { \r\n active: true, \r\n loopDuration: 5000, \r\n animType: \"syncCosOscillation\",\r\n val1: 0.15,\r\n val2: 1 }\r\n }\r\n}];\r\n\r\nTokenMagic.addUpdateFiltersOnSelected(params);","author":"Njc5YzFjZDI5NjZl","img":"icons/svg/dice-target.svg","actorIds":[]} +{"_id":"VuMHH9LMD51MNJzZ","name":"24 - T11 - Grid Force Field","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"type":"script","flags":{},"scope":"global","command":"let params =\r\n[{\r\n filterType: \"field\",\r\n filterId: \"myGridField\",\r\n shieldType: 11,\r\n gridPadding: 2,\r\n color: 0x00CCCC,\r\n time: 0,\r\n blend: 2,\r\n intensity: 1,\r\n lightAlpha: 1,\r\n lightSize: 0.3,\r\n scale: 0.5,\r\n radius: 1,\r\n chromatic: false,\r\n animated :\r\n {\r\n time : \r\n { \r\n active: true, \r\n speed: 0.0009, \r\n animType: \"move\" \r\n }\r\n }\r\n}];\r\n\r\nTokenMagic.addUpdateFiltersOnSelected(params);","author":"Njc5YzFjZDI5NjZl","img":"icons/svg/dice-target.svg","actorIds":[]} +{"_id":"YJjeB7N0L1rGfZD2","name":"18 - Electric","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"type":"script","flags":{},"scope":"global","command":"// Because the shader is dynamically compiled,\r\n// intensity is a one time init and can't be updated.\r\n// you must delete the filters to \"change\" it.\r\nlet params =\r\n[{\r\n filterType: \"electric\",\r\n filterId: \"myElectric\",\r\n color: 0xFFFFFF,\r\n time: 0,\r\n blend: 1,\r\n intensity: 5,\r\n animated :\r\n {\r\n time : \r\n { \r\n active: true, \r\n speed: 0.0020, \r\n animType: \"move\" \r\n }\r\n }\r\n}];\r\n\r\nTokenMagic.addUpdateFiltersOnSelected(params);","author":"Njc5YzFjZDI5NjZl","img":"icons/svg/dice-target.svg","actorIds":[]} +{"_id":"YPOoPH63FqcEoVTk","name":"25 - T02 - Lucky Clover (xray)","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"type":"script","flags":{},"scope":"global","command":"let params =\r\n[{\r\n filterType: \"xray\",\r\n filterId: \"myLuckyRays\",\r\n time: 0,\r\n color: 0x00FF00,\r\n blend: 9,\r\n dimX: 0.05,\r\n dimY: 0.05,\r\n anchorX: 0.5,\r\n anchorY: 0.5,\r\n divisor: 4,\r\n intensity: 1,\r\n animated :\r\n {\r\n time : \r\n { \r\n active: true, \r\n speed: 0.0012, \r\n animType: \"move\" \r\n },\r\n anchorX:\r\n {\r\n animType: \"syncCosOscillation\",\r\n loopDuration : 6000,\r\n val1: 0.40,\r\n val2: 0.60\r\n },\r\n anchorY:\r\n {\r\n animType: \"syncSinOscillation\",\r\n loopDuration : 6000,\r\n val1: 0.40,\r\n val2: 0.60\r\n }\r\n }\r\n}];\r\n\r\nTokenMagic.addUpdateFiltersOnSelected(params);","author":"Njc5YzFjZDI5NjZl","img":"icons/svg/dice-target.svg","actorIds":[]} +{"_id":"aoqr6qPxif62zWLo","name":"24 - T09 - Water Defense","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"type":"script","flags":{},"scope":"global","command":"let params =\r\n[{\r\n filterType: \"field\",\r\n filterId: \"myWaterField\",\r\n shieldType: 9,\r\n gridPadding: 1.2,\r\n color: 0x20BBEE,\r\n time: 0,\r\n blend: 4,\r\n intensity: 1,\r\n lightAlpha: 0.7,\r\n lightSize: 0.5,\r\n scale: 0.6,\r\n radius: 1,\r\n chromatic: false,\r\n animated :\r\n {\r\n time : \r\n { \r\n active: true, \r\n speed: 0.0015, \r\n animType: \"move\" \r\n }\r\n }\r\n}];\r\n\r\nTokenMagic.addUpdateFiltersOnSelected(params);","author":"Njc5YzFjZDI5NjZl","img":"icons/svg/dice-target.svg","actorIds":[]} +{"_id":"b5Enw7tEwfjDNHuY","name":"04 - Outline","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"type":"script","flags":{"combat-utility-belt":{"macroTrigger":""}},"scope":"global","command":"let params = \r\n[{\r\n filterType: \"outline\",\r\n filterId: \"myOutline\",\r\n padding: 10,\r\n color: 0xEE6035,\r\n thickness: 1,\r\n quality: 5,\r\n animated :\r\n {\r\n thickness: \r\n { \r\n active: true,\r\n loopDuration: 800,\r\n animType: \"syncCosOscillation\",\r\n val1: 1, \r\n val2: 6\r\n }\r\n }\r\n}];\r\n\r\nTokenMagic.addUpdateFiltersOnSelected(params);","author":"Njc5YzFjZDI5NjZl","img":"icons/svg/dice-target.svg","actorIds":[]} +{"_id":"bFFSpcJSickAe2Tr","name":"27 - T06 - Pure Ice (xglow+smoke)","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"type":"script","flags":{},"scope":"global","command":"let params =\r\n [{\r\n filterType: \"zapshadow\",\r\n filterId: \"myPureIceZapShadow\",\r\n alphaTolerance: 0.50\r\n },\r\n {\r\n filterType: \"xglow\",\r\n filterId: \"myPureIceAura\",\r\n auraType: 1,\r\n color: 0x5099DD,\r\n thickness: 4.5,\r\n scale: 10,\r\n time: 0,\r\n auraIntensity: 0.25,\r\n subAuraIntensity: 1,\r\n threshold: 0.5,\r\n discard: false,\r\n animated:\r\n {\r\n time:\r\n {\r\n active: true,\r\n speed: 0.0018,\r\n animType: \"move\"\r\n },\r\n thickness:\r\n {\r\n val1: 2, val2: 3.3,\r\n animType: \"cosOscillation\",\r\n loopDuration: 3000\r\n },\r\n subAuraIntensity:\r\n {\r\n val1: 0.45, val2: 0.65,\r\n animType: \"cosOscillation\",\r\n loopDuration: 6000\r\n },\r\n auraIntensity:\r\n {\r\n val1: 0.9, val2: 2.2,\r\n animType: \"cosOscillation\",\r\n loopDuration: 3000\r\n }\r\n }\r\n },\r\n {\r\n filterType: \"smoke\",\r\n filterId: \"myPureIceSmoke\",\r\n color: 0x80CCFF,\r\n time: 0,\r\n blend: 2,\r\n dimX: 0.3,\r\n dimY: 1,\r\n animated:\r\n {\r\n time:\r\n {\r\n active: true,\r\n speed: -0.006,\r\n animType: \"move\"\r\n },\r\n dimX:\r\n {\r\n val1: 0.4, val2: 0.2,\r\n animType: \"cosOscillation\",\r\n loopDuration: 3000\r\n }\r\n }\r\n }];\r\n\r\nTokenMagic.addUpdateFiltersOnSelected(params);","author":"Njc5YzFjZDI5NjZl","img":"icons/svg/dice-target.svg","actorIds":[]} +{"_id":"cCEOQFsJvjhSTbbM","name":"06 - Bloom","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"type":"script","flags":{},"scope":"global","command":"let params = \r\n[{\r\n filterType: \"xbloom\",\r\n filterId: \"letsShine\",\r\n threshold: 0.35,\r\n bloomScale: 0,\r\n brightness: 1,\r\n blur: 0.1,\r\n padding: 10,\r\n quality: 15,\r\n blendMode: 0,\r\n animated:\r\n {\r\n bloomScale: \r\n { \r\n active: true, \r\n loopDuration: 2000, \r\n animType: \"syncCosOscillation\", \r\n val1: 0, \r\n val2: 2.1\r\n },\r\n threshold: \r\n { \r\n active: false, \r\n loopDuration: 1000, \r\n animType: \"syncCosOscillation\", \r\n val1: 0.00, \r\n val2: 1.90\r\n }\r\n }\r\n}];\r\n\r\nTokenMagic.addUpdateFiltersOnSelected(params);\r\n","author":"Njc5YzFjZDI5NjZl","img":"icons/svg/dice-target.svg","actorIds":[]} +{"_id":"cOaB7NxSQ5jNDd5g","name":"27 - T01 - Burning Aura (xglow)","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"type":"script","flags":{},"scope":"global","command":"let params =\r\n[{\r\n filterType: \"zapshadow\",\r\n filterId: \"myZapShadow\",\r\n alphaTolerance: 0.50\r\n},\r\n{\r\n filterType: \"xglow\",\r\n filterId: \"myBurningAura\",\r\n auraType: 2,\r\n color: 0x903010,\r\n thickness: 9.8,\r\n scale: 4.,\r\n time: 0,\r\n auraIntensity: 2,\r\n subAuraIntensity: 1.5,\r\n threshold: 0.40,\r\n discard: true,\r\n animated:\r\n {\r\n time : \r\n { \r\n active: true,\r\n speed: 0.0027, \r\n animType: \"move\" \r\n },\r\n thickness:\r\n {\r\n active: true,\r\n loopDuration: 3000, \r\n animType: \"cosOscillation\", \r\n val1:2, \r\n val2:5\r\n }\r\n }\r\n}];\r\n\r\nTokenMagic.addUpdateFiltersOnSelected(params);","author":"Njc5YzFjZDI5NjZl","img":"icons/svg/dice-target.svg","actorIds":[]} +{"_id":"eJQSmnIitUUQMKDS","name":"27 - T04 - Pure Fire (xglow+fire)","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"type":"script","flags":{},"scope":"global","command":"let params =\r\n[{\r\n filterType: \"fire\",\r\n filterId: \"myPureFire\",\r\n intensity: 1,\r\n color: 0xFFFFFF,\r\n amplitude: 1,\r\n time: 0,\r\n blend: 2,\r\n fireBlend : 1,\r\n animated :\r\n {\r\n time : \r\n { \r\n active: true, \r\n speed: -0.0024, \r\n animType: \"move\" \r\n },\r\n intensity:\r\n {\r\n active:true,\r\n loopDuration: 15000,\r\n val1: 0.8,\r\n val2: 2,\r\n animType: \"syncCosOscillation\"\r\n },\r\n amplitude:\r\n {\r\n active:true,\r\n loopDuration: 4400,\r\n val1: 1,\r\n val2: 1.4,\r\n animType: \"syncCosOscillation\"\r\n }\r\n \r\n }\r\n},\r\n{\r\n filterType: \"zapshadow\",\r\n filterId: \"myPureFireShadow\",\r\n alphaTolerance: 0.50\r\n},\r\n{\r\n filterType: \"xglow\",\r\n filterId: \"myPureFireAura\",\r\n auraType: 2,\r\n color: 0x903010,\r\n thickness: 9.8,\r\n scale: 4.,\r\n time: 0,\r\n auraIntensity: 2,\r\n subAuraIntensity: 1.5,\r\n threshold: 0.40,\r\n discard: true,\r\n animated:\r\n {\r\n time : \r\n { \r\n active: true,\r\n speed: 0.0027, \r\n animType: \"move\" \r\n },\r\n thickness:\r\n {\r\n active: true,\r\n loopDuration: 3000, \r\n animType: \"cosOscillation\", \r\n val1:2, \r\n val2:5\r\n }\r\n }\r\n}];\r\n\r\nTokenMagic.addUpdateFiltersOnSelected(params);","author":"Njc5YzFjZDI5NjZl","img":"icons/svg/dice-target.svg","actorIds":[]} {"_id":"eJnsq5g4Pldh8Z6Q","name":"B - Multi-Filters Example","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"type":"script","flags":{},"scope":"global","command":"let params =\r\n[{\r\n filterType: \"distortion\",\r\n maskPath: \"/modules/tokenmagic/fx/assets/waves-2.png\",\r\n maskSpriteScaleX: 7,\r\n maskSpriteScaleY: 7,\r\n padding: 50,\r\n animated:\r\n {\r\n maskSpriteX: { active: true, speed: 0.05, animType: \"move\" },\r\n maskSpriteY: { active: true, speed: 0.07, animType: \"move\" }\r\n }\r\n},\r\n{\r\n filterType: \"ray\",\r\n time: 0,\r\n color: 0xEF9000,\r\n alpha: 0.25,\r\n divisor: 32,\r\n anchorY: 1,\r\n animated :\r\n {\r\n time : \r\n { \r\n active: true, \r\n speed: 0.0005, \r\n animType: \"move\" \r\n }\r\n }\r\n},\r\n{\r\n filterType: \"glow\",\r\n distance: 10,\r\n outerStrength: 8,\r\n innerStrength: 0,\r\n color: 0xB03000,\r\n quality: 0.5,\r\n animated:\r\n {\r\n color: \r\n {\r\n active: true, \r\n loopDuration: 3000, \r\n animType: \"colorOscillation\", \r\n val1:0xB03000, \r\n val2:0xFFD010\r\n }\r\n }\r\n}\r\n];\r\n\r\nTokenMagic.addFiltersOnSelected(params);","author":"Njc5YzFjZDI5NjZl","img":"icons/svg/dice-target.svg","actorIds":[]} -{"_id":"ebWbFeiJP8UZG4Fd","name":"17 - Fumes","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"type":"script","flags":{},"scope":"global","command":"let params =\r\n[{\r\n filterType: \"fumes\",\r\n color: 0x909090,\r\n time: 0,\r\n blend: 8,\r\n animated :\r\n {\r\n time : \r\n { \r\n active: true, \r\n speed: 0.001, \r\n animType: \"move\" \r\n }\r\n }\r\n}];\r\n\r\nTokenMagic.addFiltersOnSelected(params);","author":"Njc5YzFjZDI5NjZl","img":"icons/svg/dice-target.svg","actorIds":[]} -{"_id":"f74nx1SMT5m8RRn8","name":"24 - T08 - Chromatic Bubble","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"type":"script","flags":{},"scope":"global","command":"let params =\r\n[{\r\n filterType: \"field\",\r\n shieldType: 8,\r\n gridPadding: 2,\r\n color: 0x505050,\r\n time: 0,\r\n blend: 2,\r\n intensity: 1,\r\n lightAlpha: 0,\r\n lightSize: 0,\r\n scale: 2,\r\n radius: 1,\r\n chromatic: true,\r\n animated :\r\n {\r\n time : \r\n { \r\n active: true, \r\n speed: 0.0045, \r\n animType: \"move\" \r\n }\r\n }\r\n}];\r\n\r\nTokenMagic.addFiltersOnSelected(params);","author":"Njc5YzFjZDI5NjZl","img":"icons/svg/dice-target.svg","actorIds":[]} -{"_id":"g7O4u4dTaWcnajW7","name":"05 - Glow","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"type":"script","flags":{},"scope":"global","command":"let params =\r\n[{\r\n filterType: \"glow\",\r\n distance: 10,\r\n outerStrength: 8,\r\n innerStrength: 0,\r\n color: 0x003000,\r\n quality: 0.5,\r\n padding: 10,\r\n animated:\r\n {\r\n color: \r\n {\r\n active: true, \r\n loopDuration: 3000, \r\n animType: \"colorOscillation\", \r\n val1:0x003000, \r\n val2:0x00FF00\r\n }\r\n }\r\n}];\r\n\r\nTokenMagic.addFiltersOnSelected(params);","author":"Njc5YzFjZDI5NjZl","img":"icons/svg/dice-target.svg","actorIds":[]} -{"_id":"hayiRem3LXoEP3tL","name":"03 - Drop Shadow","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"type":"script","flags":{},"scope":"global","command":"let params =\r\n[{\r\n filterType: \"shadow\",\r\n rotation: 35,\r\n blur: 2,\r\n quality: 5,\r\n distance: 20,\r\n alpha: 0.7,\r\n padding: 10,\r\n shadowOnly: false,\r\n color: 0x000000,\r\n animated:\r\n {\r\n blur: \r\n { \r\n active: true, \r\n loopDuration: 500, \r\n animType: \"syncCosOscillation\", \r\n val1: 2, \r\n val2: 4\r\n },\r\n rotation:\r\n {\r\n active: true,\r\n loopDuration: 100,\r\n animType: \"syncSinOscillation\",\r\n val1: 33,\r\n val2: 37\r\n }\r\n }\r\n}];\r\n\r\nTokenMagic.addFiltersOnSelected(params);","author":"Njc5YzFjZDI5NjZl","img":"icons/svg/dice-target.svg","actorIds":[]} -{"_id":"lH53KTce3zYEFXos","name":"08 - Old film","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"type":"script","flags":{},"scope":"global","command":"// special : the OldFilm filter need an Outline filter to be contained (or else, it will affect all the container)\r\nlet params =\r\n[{\r\n filterType: \"oldfilm\",\r\n sepia: 0.9,\r\n noise: 0.3,\r\n noiseSize: 1.0,\r\n scratch: 0.8,\r\n scratchDensity: 0.5,\r\n scratchWidth: 1.2,\r\n vignetting: 0.3,\r\n vignettingAlpha: 0.7,\r\n vignettingBlur: 0.3,\r\n animated:\r\n {\r\n seed: \r\n { \r\n active: true, \r\n animType: \"randomNumber\", \r\n val1: 0, \r\n val2: 1 \r\n },\r\n vignetting: \r\n { \r\n active: true, \r\n animType: \"syncCosOscillation\" , \r\n loopDuration: 2000, \r\n val1: 0.2, \r\n val2: 0.4 }\r\n }\r\n},\r\n{\r\n filterType: \"outline\",\r\n color: 0x000000,\r\n thickness: 0,\r\n}];\r\n\r\nTokenMagic.addFiltersOnSelected(params);","author":"Njc5YzFjZDI5NjZl","img":"icons/svg/dice-target.svg","actorIds":[]} -{"_id":"r3JzTibAUnlpgPsD","name":"13 - Shockwave","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"type":"script","flags":{},"scope":"global","command":"let params =\r\n[{\r\n filterType: \"shockwave\",\r\n time: 0,\r\n amplitude: 8,\r\n wavelength: 75,\r\n radius: 500,\r\n brightness: 1.5,\r\n speed: 25,\r\n padding: 0,\r\n animated:\r\n {\r\n time: \r\n { \r\n animType: \"cosOscillation\",\r\n active: true, \r\n loopDuration: 1800, \r\n val1: -4, val2: +4\r\n }\r\n }\r\n}];\r\n\r\nTokenMagic.addFiltersOnSelected(params);","author":"Njc5YzFjZDI5NjZl","img":"icons/svg/dice-target.svg","actorIds":[]} -{"_id":"s01RgeSRy4En1aKP","name":"23 - Mirror Images","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"type":"script","flags":{},"scope":"global","command":"let params =\r\n[{\r\n filterType: \"images\",\r\n time: 0,\r\n padding: 60,\r\n alpha: 0.9,\r\n blend: 4,\r\n animated :\r\n {\r\n time : \r\n { \r\n active: true, \r\n speed: 0.0010, \r\n animType: \"move\" \r\n }\r\n }\r\n}];\r\n\r\nTokenMagic.addFiltersOnSelected(params);","author":"Njc5YzFjZDI5NjZl","img":"icons/svg/dice-target.svg","actorIds":[]} -{"_id":"sbP8KX50YRYtxVyB","name":"24 - T01 - Hexa Force Field","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"type":"script","flags":{},"scope":"global","command":"let params =\r\n[{\r\n filterType: \"field\",\r\n shieldType: 2,\r\n gridPadding: 0,\r\n color: 0x900090,\r\n time: 0,\r\n blend: 2,\r\n intensity: 1,\r\n lightAlpha: 0.75,\r\n lightSize: 0.45,\r\n scale: 2,\r\n radius: 1,\r\n chromatic: false,\r\n animated :\r\n {\r\n time : \r\n { \r\n active: true, \r\n speed: 0.0015, \r\n animType: \"move\" \r\n }\r\n }\r\n}];\r\n\r\nTokenMagic.addFiltersOnSelected(params);","author":"Njc5YzFjZDI5NjZl","img":"icons/svg/dice-target.svg","actorIds":[]} -{"_id":"t2MjFs4cVUCYsbMr","name":"12 - Zoom Blur","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"type":"script","flags":{},"scope":"global","command":"let params =\r\n[{\r\n filterType: \"zoomblur\",\r\n strength: 0.3,\r\n innerRadiusPercent: 70,\r\n radiusPercent: 120,\r\n padding: 30,\r\n animated:\r\n {\r\n innerRadiusPercent: \r\n { \r\n active: true, \r\n animType: \"sinOscillation\", \r\n loopDuration: 500, \r\n val1: 65, \r\n val2: 75\r\n }\r\n }\r\n}];\r\n\r\nTokenMagic.addFiltersOnSelected(params);","author":"Njc5YzFjZDI5NjZl","img":"icons/svg/dice-target.svg","actorIds":[]} +{"_id":"ebWbFeiJP8UZG4Fd","name":"17 - Fumes","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"type":"script","flags":{},"scope":"global","command":"let params =\r\n[{\r\n filterType: \"fumes\",\r\n filterId: \"myFumes\",\r\n color: 0x808080,\r\n time: 0,\r\n blend: 8,\r\n animated :\r\n {\r\n time : \r\n { \r\n active: true, \r\n speed: 0.001, \r\n animType: \"move\" \r\n }\r\n }\r\n}];\r\n\r\nTokenMagic.addUpdateFiltersOnSelected(params);","author":"Njc5YzFjZDI5NjZl","img":"icons/svg/dice-target.svg","actorIds":[]} +{"_id":"f74nx1SMT5m8RRn8","name":"24 - T08 - Chromatic Bubble","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"type":"script","flags":{},"scope":"global","command":"let params =\r\n[{\r\n filterType: \"field\",\r\n filterId: \"myChromaField\",\r\n shieldType: 8,\r\n gridPadding: 2,\r\n color: 0xAAAAAA,\r\n time: 0,\r\n blend: 0,\r\n intensity: 1,\r\n lightAlpha: 0,\r\n lightSize: 0,\r\n scale: 1,\r\n radius: 1,\r\n chromatic: true,\r\n animated :\r\n {\r\n time : \r\n { \r\n active: true, \r\n speed: 0.0045, \r\n animType: \"move\" \r\n }\r\n }\r\n}];\r\n\r\nTokenMagic.addUpdateFiltersOnSelected(params);","author":"Njc5YzFjZDI5NjZl","img":"icons/svg/dice-target.svg","actorIds":[]} +{"_id":"g7O4u4dTaWcnajW7","name":"05 - Glow","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"type":"script","flags":{},"scope":"global","command":"let params =\r\n[{\r\n filterType: \"glow\",\r\n filterId: \"superSpookyGlow\",\r\n outerStrength: 7,\r\n innerStrength: 0,\r\n color: 0x006000,\r\n quality: 0.5,\r\n padding: 10,\r\n animated:\r\n {\r\n color: \r\n {\r\n active: true, \r\n loopDuration: 3000, \r\n animType: \"colorOscillation\", \r\n val1:0x003000, \r\n val2:0x00FF00\r\n }\r\n }\r\n}];\r\n\r\nTokenMagic.addUpdateFiltersOnSelected(params);","author":"Njc5YzFjZDI5NjZl","img":"icons/svg/dice-target.svg","actorIds":[]} +{"_id":"hFZvMSE5VMCUiYNE","name":"25 - T03 - X-ray Scan (xray)","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"type":"script","flags":{},"scope":"global","command":"let params =\r\n[{\r\n filterType: \"xray\",\r\n filterId: \"myXrayScan\",\r\n time: 0,\r\n color: 0xFFFFFF,\r\n blend: 5,\r\n dimX: 20,\r\n dimY: 20,\r\n anchorX: 0.5,\r\n anchorY: 0,\r\n divisor: 8,\r\n intensity: 1,\r\n animated :\r\n {\r\n time : \r\n { \r\n active: true, \r\n speed: 0.00038, \r\n animType: \"move\" \r\n }\r\n }\r\n}];\r\n\r\nTokenMagic.addUpdateFiltersOnSelected(params);","author":"Njc5YzFjZDI5NjZl","img":"icons/svg/dice-target.svg","actorIds":[]} +{"_id":"hayiRem3LXoEP3tL","name":"03 - Drop Shadow","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"type":"script","flags":{},"scope":"global","command":"let params =\r\n[{\r\n filterType: \"shadow\",\r\n filterId: \"myShadow\",\r\n rotation: 35,\r\n blur: 2,\r\n quality: 5,\r\n distance: 20,\r\n alpha: 0.7,\r\n padding: 10,\r\n shadowOnly: false,\r\n color: 0x000000,\r\n animated:\r\n {\r\n blur: \r\n { \r\n active: true, \r\n loopDuration: 500, \r\n animType: \"syncCosOscillation\", \r\n val1: 2, \r\n val2: 4\r\n },\r\n rotation:\r\n {\r\n active: true,\r\n loopDuration: 100,\r\n animType: \"syncSinOscillation\",\r\n val1: 33,\r\n val2: 37\r\n }\r\n }\r\n}];\r\n\r\nTokenMagic.addUpdateFiltersOnSelected(params);","author":"Njc5YzFjZDI5NjZl","img":"icons/svg/dice-target.svg","actorIds":[]} +{"_id":"lH53KTce3zYEFXos","name":"08 - Old film","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"type":"script","flags":{},"scope":"global","command":"// special : the OldFilm filter need an Outline filter to be contained (or else, it will affect all the container)\r\nlet params =\r\n[{\r\n filterType: \"oldfilm\",\r\n filterId: \"myOldfilm\",\r\n sepia: 0.6,\r\n noise: 0.2,\r\n noiseSize: 1.0,\r\n scratch: 0.8,\r\n scratchDensity: 0.5,\r\n scratchWidth: 1.2,\r\n vignetting: 0.9,\r\n vignettingAlpha: 0.6,\r\n vignettingBlur: 0.2,\r\n animated:\r\n {\r\n seed: \r\n { \r\n active: true, \r\n animType: \"randomNumber\", \r\n val1: 0, \r\n val2: 1 \r\n },\r\n vignetting: \r\n { \r\n active: true, \r\n animType: \"syncCosOscillation\" , \r\n loopDuration: 2000, \r\n val1: 0.2, \r\n val2: 0.4 }\r\n }\r\n},\r\n{\r\n filterType: \"outline\",\r\n filterId: \"oldfilmOutline\",\r\n color: 0x000000,\r\n thickness: 0,\r\n}];\r\n\r\nTokenMagic.addUpdateFiltersOnSelected(params);","author":"Njc5YzFjZDI5NjZl","img":"icons/svg/dice-target.svg","actorIds":[]} +{"_id":"r3JzTibAUnlpgPsD","name":"13 - Shockwave","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"type":"script","flags":{},"scope":"global","command":"let params =\r\n[{\r\n filterType: \"shockwave\",\r\n filterId: \"myShockwave\",\r\n time: 0,\r\n amplitude: 8,\r\n wavelength: 75,\r\n radius: 500,\r\n brightness: 1.5,\r\n speed: 25,\r\n padding: 0,\r\n animated:\r\n {\r\n time: \r\n { \r\n animType: \"cosOscillation\",\r\n active: true, \r\n loopDuration: 1800, \r\n val1: 0, val2: 10\r\n }\r\n }\r\n}];\r\n\r\nTokenMagic.addUpdateFiltersOnSelected(params);","author":"Njc5YzFjZDI5NjZl","img":"icons/svg/dice-target.svg","actorIds":[]} +{"_id":"s01RgeSRy4En1aKP","name":"23 - T01 - Mirror Images","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"type":"script","flags":{},"scope":"global","command":"let params =\r\n[{\r\n filterType: \"images\",\r\n filterId: \"myMirrorImages\",\r\n time: 0,\r\n nbImage: 4,\r\n alphaImg: 1.0,\r\n alphaChr: 0.0,\r\n blend: 4,\r\n ampX: 0.10,\r\n ampY: 0.10,\r\n animated :\r\n {\r\n time: \r\n { \r\n active: true, \r\n speed: 0.0010, \r\n animType: \"move\" \r\n }\r\n }\r\n}];\r\n\r\nTokenMagic.addUpdateFiltersOnSelected(params);","author":"Njc5YzFjZDI5NjZl","img":"icons/svg/dice-target.svg","actorIds":[]} +{"_id":"sZmVZvLEYmlEC1bK","name":"F - 05 - Import FX Presets (URL)","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"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","actorIds":[]} +{"_id":"sbP8KX50YRYtxVyB","name":"24 - T01 - Hexa Force Field","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"type":"script","flags":{},"scope":"global","command":"let params =\r\n[{\r\n filterType: \"field\",\r\n filterId: \"myHexaField\",\r\n shieldType: 2,\r\n gridPadding: 3,\r\n color: 0xCC00CC,\r\n time: 0,\r\n blend: 3,\r\n intensity: 1,\r\n lightAlpha: 0.5,\r\n lightSize: 0.5,\r\n scale: 1,\r\n radius: 1,\r\n chromatic: false,\r\n animated :\r\n {\r\n time : \r\n { \r\n active: true, \r\n speed: 0.0015, \r\n animType: \"move\" \r\n }\r\n }\r\n}];\r\n\r\nTokenMagic.addUpdateFiltersOnSelected(params);","author":"Njc5YzFjZDI5NjZl","img":"icons/svg/dice-target.svg","actorIds":[]} +{"_id":"t2MjFs4cVUCYsbMr","name":"12 - Zoom Blur","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"type":"script","flags":{},"scope":"global","command":"let params =\r\n[{\r\n filterType: \"zoomblur\",\r\n filterId: \"myZoomBlur\",\r\n strength: 0.15,\r\n innerRadiusPercent: 65,\r\n radiusPercent: 100,\r\n padding: 30,\r\n animated:\r\n {\r\n innerRadiusPercent: \r\n { \r\n active: true, \r\n animType: \"sinOscillation\", \r\n loopDuration: 500, \r\n val1: 65, \r\n val2: 75\r\n }\r\n }\r\n}];\r\n\r\nTokenMagic.addUpdateFiltersOnSelected(params);","author":"Njc5YzFjZDI5NjZl","img":"icons/svg/dice-target.svg","actorIds":[]} {"_id":"tvDGSwbeQ97HNS8v","name":"A - Multi-Filters Example","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"type":"script","flags":{},"scope":"global","command":"let params =\r\n[{\r\n filterType: \"fog\",\r\n color: 0x00FF50,\r\n density: 0.20,\r\n time: 0,\r\n animated :\r\n {\r\n time : \r\n { \r\n active: true, \r\n speed: 1.2, \r\n animType: \"move\" \r\n }\r\n }\r\n},\r\n{\r\n filterType: \"ray\",\r\n time: 0,\r\n color: 0x00DE50,\r\n alpha: 0.25,\r\n divisor: 32,\r\n anchorY: 0,\r\n animated :\r\n {\r\n time : \r\n { \r\n active: true, \r\n speed: 0.0005, \r\n animType: \"move\" \r\n }\r\n }\r\n},\r\n{\r\n filterType: \"glow\",\r\n distance: 10,\r\n outerStrength: 8,\r\n innerStrength: 0,\r\n color: 0x003000,\r\n quality: 0.5,\r\n padding: 10,\r\n animated:\r\n {\r\n color: \r\n {\r\n active: true, \r\n loopDuration: 3000, \r\n animType: \"colorOscillation\", \r\n val1:0x003000, \r\n val2:0x00EF00\r\n }\r\n }\r\n}\r\n];\r\n\r\nTokenMagic.addFiltersOnSelected(params);","author":"Njc5YzFjZDI5NjZl","img":"icons/svg/dice-target.svg","actorIds":[]} -{"_id":"wdbgHdNcBwBETc1y","name":"27 - T02 - Glacial Aura (xglow)","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"type":"script","flags":{},"scope":"global","command":"let params =\r\n[{\r\n filterType: \"zapshadow\",\r\n filterId: \"myZapShadow\",\r\n alphaTolerance: 0.50\r\n},\r\n{\r\n filterType: \"xglow\",\r\n filterId: \"myMagicGlow\",\r\n auraType: 1,\r\n color: 0x70BBFF,\r\n thickness: 3.3,\r\n scale: 0.25,\r\n time: 0,\r\n auraIntensity: 1,\r\n subAuraIntensity: 0.25,\r\n threshold: 0.25,\r\n discard: false,\r\n animated:\r\n {\r\n time : \r\n { \r\n active: true,\r\n speed: 0.0006, \r\n animType: \"move\" \r\n }\r\n }\r\n}];\r\n\r\nTokenMagic.addFiltersOnSelected(params);","author":"Njc5YzFjZDI5NjZl","img":"icons/svg/dice-target.svg","actorIds":[]} -{"name":"27 - T03 - Ugly villains Aura (xglow)","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"type":"script","flags":{},"scope":"global","command":"let params =\r\n[{\r\n filterType: \"zapshadow\",\r\n filterId: \"myZapShadow\",\r\n alphaTolerance: 0.50\r\n},\r\n{\r\n filterType: \"xglow\",\r\n filterId: \"myMagicGlow\",\r\n auraType: 2,\r\n color: 0x050505,\r\n thickness: 2.7,\r\n scale: 7,\r\n time: 0,\r\n auraIntensity: 5,\r\n subAuraIntensity: 2,\r\n threshold: 0.08,\r\n discard: false,\r\n animated:\r\n {\r\n time : \r\n { \r\n active: true,\r\n speed: 0.0012, \r\n animType: \"move\" \r\n },\r\n auraIntensity:\r\n {\r\n active: true,\r\n loopDuration: 3000, \r\n animType: \"syncCosOscillation\", \r\n val1:5, \r\n val2:0\r\n },\r\n subAuraIntensity:\r\n {\r\n active: true,\r\n loopDuration: 3000, \r\n animType: \"syncCosOscillation\", \r\n val1:2, \r\n val2:0\r\n },\r\n color:\r\n {\r\n active: true,\r\n loopDuration: 6000, \r\n animType: \"syncColorOscillation\", \r\n val1:0x050505, \r\n val2:0x200000\r\n },\r\n threshold:\r\n {\r\n active: true,\r\n loopDuration: 1500, \r\n animType: \"syncCosOscillation\", \r\n val1:0.02, \r\n val2:0.50\r\n }\r\n }\r\n}];\r\n\r\nTokenMagic.addFiltersOnSelected(params);","author":"Njc5YzFjZDI5NjZl","img":"icons/svg/dice-target.svg","actorIds":[],"_id":"ydY1XOCO4yIhunkj"} -{"_id":"zCCp4x0EResFji7O","name":"21 - Flood","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"type":"script","flags":{},"scope":"global","command":"let params =\r\n[{\r\n filterType: \"flood\",\r\n time: 0,\r\n color: 0x0020BB,\r\n billowy: 0.43,\r\n tintIntensity: 0.72,\r\n glint: 0.31,\r\n scale: 70,\r\n padding: 10,\r\n animated :\r\n {\r\n time : \r\n { \r\n active: true, \r\n speed: 0.0006, \r\n animType: \"move\"\r\n }\r\n }\r\n}];\r\n\r\nTokenMagic.addFiltersOnSelected(params);","author":"Njc5YzFjZDI5NjZl","img":"icons/svg/dice-target.svg","actorIds":[]} +{"_id":"wRWqUK0wliNZSsgl","name":"27 - T05 - Pure Fire v2 (xglow+fire)","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"type":"script","flags":{},"scope":"global","command":"// In this version, the glow is blending with the fire\r\n// This is to show that the order of the filters is important\r\nlet params =\r\n[{\r\n filterType: \"zapshadow\",\r\n filterId: \"myPureFireShadow\",\r\n alphaTolerance: 0.50\r\n},\r\n{\r\n filterType: \"xglow\",\r\n filterId: \"myPureFireAura\",\r\n auraType: 2,\r\n color: 0x903010,\r\n thickness: 9.8,\r\n scale: 3.,\r\n time: 0,\r\n auraIntensity: 1,\r\n subAuraIntensity: 0.3,\r\n threshold: 0.25,\r\n discard: true,\r\n animated:\r\n {\r\n time : \r\n { \r\n active: true,\r\n speed: 0.0027, \r\n animType: \"move\" \r\n },\r\n thickness:\r\n {\r\n active: true,\r\n loopDuration: 3000, \r\n animType: \"cosOscillation\", \r\n val1:2, \r\n val2:3.6\r\n }\r\n }\r\n},\r\n{\r\n filterType: \"fire\",\r\n filterId: \"myPureFire\",\r\n intensity: 1,\r\n color: 0xFFFFFF,\r\n amplitude: 1,\r\n time: 0,\r\n blend: 2,\r\n fireBlend : 1,\r\n animated :\r\n {\r\n time : \r\n { \r\n active: true, \r\n speed: -0.0024, \r\n animType: \"move\" \r\n },\r\n intensity:\r\n {\r\n active:true,\r\n loopDuration: 15000,\r\n val1: 0.8,\r\n val2: 3,\r\n animType: \"syncCosOscillation\"\r\n },\r\n amplitude:\r\n {\r\n active:true,\r\n loopDuration: 4400,\r\n val1: 1,\r\n val2: 1.6,\r\n animType: \"syncCosOscillation\"\r\n }\r\n \r\n }\r\n}];\r\n\r\nTokenMagic.addUpdateFiltersOnSelected(params);","author":"Njc5YzFjZDI5NjZl","img":"icons/svg/dice-target.svg","actorIds":[]} +{"_id":"wdbgHdNcBwBETc1y","name":"27 - T02 - Glacial Aura (xglow)","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"type":"script","flags":{},"scope":"global","command":"let params =\r\n[{\r\n filterType: \"zapshadow\",\r\n filterId: \"myGlacialZapShadow\",\r\n alphaTolerance: 0.50\r\n},\r\n{\r\n filterType: \"xglow\",\r\n filterId: \"myGlacialAura\",\r\n auraType: 1,\r\n color: 0x5099DD,\r\n thickness: 4.5,\r\n scale: 3,\r\n time: 0,\r\n auraIntensity: 0.8,\r\n subAuraIntensity: 0.25,\r\n threshold: 0.5,\r\n discard: false,\r\n animated:\r\n {\r\n time : \r\n { \r\n active: true,\r\n speed: 0.0018, \r\n animType: \"move\" \r\n },\r\n thickness: \r\n {\r\n val1: 2, val2: 4.7,\r\n animType: \"cosOscillation\",\r\n loopDuration: 3000\r\n },\r\n subAuraIntensity: \r\n {\r\n val1: 0.45, val2: 0.65,\r\n animType: \"cosOscillation\",\r\n loopDuration: 6000\r\n },\r\n auraIntensity: \r\n {\r\n val1: 0.9, val2: 2.2,\r\n animType: \"cosOscillation\",\r\n loopDuration: 3000\r\n }\r\n }\r\n}];\r\n\r\nTokenMagic.addUpdateFiltersOnSelected(params);","author":"Njc5YzFjZDI5NjZl","img":"icons/svg/dice-target.svg","actorIds":[]} +{"_id":"ydY1XOCO4yIhunkj","name":"27 - T03 - Ugly Villains Aura (xglow)","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"type":"script","flags":{},"scope":"global","command":"let params =\r\n[{\r\n filterType: \"zapshadow\",\r\n filterId: \"myUglyZapShadow\",\r\n alphaTolerance: 0.50\r\n},\r\n{\r\n filterType: \"xglow\",\r\n filterId: \"myUglyGlow\",\r\n auraType: 2,\r\n color: 0x050505,\r\n thickness: 2.7,\r\n scale: 7,\r\n time: 0,\r\n auraIntensity: 5,\r\n subAuraIntensity: 2,\r\n threshold: 0.08,\r\n discard: false,\r\n animated:\r\n {\r\n time : \r\n { \r\n active: true,\r\n speed: 0.0012, \r\n animType: \"move\" \r\n },\r\n auraIntensity:\r\n {\r\n active: true,\r\n loopDuration: 3000, \r\n animType: \"syncCosOscillation\", \r\n val1:5, \r\n val2:0\r\n },\r\n subAuraIntensity:\r\n {\r\n active: true,\r\n loopDuration: 3000, \r\n animType: \"syncCosOscillation\", \r\n val1:2, \r\n val2:0\r\n },\r\n color:\r\n {\r\n active: true,\r\n loopDuration: 6000, \r\n animType: \"syncColorOscillation\", \r\n val1:0x050505, \r\n val2:0x200000\r\n },\r\n threshold:\r\n {\r\n active: true,\r\n loopDuration: 1500, \r\n animType: \"syncCosOscillation\", \r\n val1:0.02, \r\n val2:0.50\r\n }\r\n }\r\n}];\r\n\r\nTokenMagic.addUpdateFiltersOnSelected(params);","author":"Njc5YzFjZDI5NjZl","img":"icons/svg/dice-target.svg","actorIds":[]} +{"_id":"yl0TtF0CKuOkOPZv","name":"23 - T02 - Chaotic Images","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"type":"script","flags":{},"scope":"global","command":"// This is an extreme example...\r\nlet params =\r\n[{\r\n filterType: \"images\",\r\n filterId: \"myChaoticImages\",\r\n time: 0,\r\n nbImage: 4,\r\n alphaImg: 1.0,\r\n alphaChr: 0.0,\r\n blend: 4,\r\n ampX: 0.10,\r\n ampY: 0.10,\r\n padding: 80,\r\n animated :\r\n {\r\n time: \r\n { \r\n active: true, \r\n speed: 0.0010, \r\n animType: \"move\" \r\n },\r\n ampX:\r\n {\r\n active: true,\r\n val1: 0.00,\r\n val2: 0.30,\r\n chaosFactor: 0.03,\r\n animType: \"syncChaoticOscillation\",\r\n loopDuration: 2000\r\n },\r\n ampY:\r\n {\r\n active: true,\r\n val1: 0.00,\r\n val2: 0.30,\r\n chaosFactor: 0.04,\r\n animType: \"syncChaoticOscillation\",\r\n loopDuration: 1650\r\n },\r\n alphaChr: \r\n { \r\n active: true, \r\n animType: \"randomNumberPerLoop\", \r\n val1: 0.0, \r\n val2: 1,\r\n loopDuration: 250\r\n },\r\n alphaImg: \r\n { \r\n active: true, \r\n animType: \"randomNumberPerLoop\", \r\n val1: 0.8, \r\n val2: 1,\r\n loopDuration: 250\r\n },\r\n nbImage:\r\n {\r\n active: true,\r\n val1: 1,\r\n val2: 9,\r\n animType: \"syncSinOscillation\",\r\n loopDuration: 1400\r\n }\r\n }\r\n}];\r\n\r\nTokenMagic.addUpdateFiltersOnSelected(params);","author":"Njc5YzFjZDI5NjZl","img":"icons/svg/dice-target.svg","actorIds":[]} +{"_id":"zCCp4x0EResFji7O","name":"21 - Flood","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"type":"script","flags":{},"scope":"global","command":"let params =\r\n[{\r\n filterType: \"flood\",\r\n filterId: \"myFlood\",\r\n time: 0,\r\n color: 0x0020BB,\r\n billowy: 0.43,\r\n tintIntensity: 0.72,\r\n glint: 0.31,\r\n scale: 70,\r\n padding: 10,\r\n animated :\r\n {\r\n time : \r\n { \r\n active: true, \r\n speed: 0.0006, \r\n animType: \"move\"\r\n }\r\n }\r\n}];\r\n\r\nTokenMagic.addUpdateFiltersOnSelected(params);","author":"Njc5YzFjZDI5NjZl","img":"icons/svg/dice-target.svg","actorIds":[]} +{"_id":"Ku4jBl972O7hHczs","name":"F - 03 - Export FX Presets","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"type":"script","flags":{},"scope":"global","command":"TokenMagic.exportPresetLibrary();","author":"Njc5YzFjZDI5NjZl","img":"icons/svg/dice-target.svg","actorIds":[]} +{"_id":"T953GJB235BbrCll","name":"26 - T03 - Drift in Plans (liquid+waves)","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"type":"script","flags":{},"scope":"global","command":"let params =\r\n[{\r\n filterType: \"wave\",\r\n filterId: \"myDriftWaves\",\r\n time: 0,\r\n anchorX: 0.5,\r\n anchorY: 0.5,\r\n strength: 0.035,\r\n frequency: 20,\r\n color: 0xFFFFFF,\r\n maxIntensity: 1.5,\r\n minIntensity: 0.5,\r\n padding:10,\r\n animated :\r\n {\r\n time : \r\n { \r\n active: true, \r\n speed: 0.0085, \r\n animType: \"move\" \r\n },\r\n anchorX :\r\n {\r\n active: true,\r\n val1: 0.35,\r\n val2: 0.65,\r\n animType: \"syncCosOscillation\",\r\n loopDuration: 10000\r\n },\r\n anchorY :\r\n {\r\n active: true,\r\n val1: 0.35,\r\n val2: 0.65,\r\n animType: \"syncSinOscillation\",\r\n loopDuration: 10000\r\n }\r\n }\r\n},\r\n{\r\n filterType: \"liquid\",\r\n filterId: \"myDriftLiquid\",\r\n color: 0xFF0000,\r\n time: 0,\r\n blend: 6,\r\n intensity: 5,\r\n spectral: false,\r\n scale: 2.5,\r\n animated :\r\n {\r\n time : \r\n { \r\n active: true, \r\n speed: 0.0018, \r\n animType: \"move\" \r\n },\r\n color: \r\n {\r\n active: true, \r\n loopDuration: 9000, \r\n animType: \"colorOscillation\", \r\n val1:0xFF0000, \r\n val2:0xFFFFFF\r\n }\r\n }\r\n}];\r\n\r\nTokenMagic.addUpdateFiltersOnSelected(params);","author":"Njc5YzFjZDI5NjZl","img":"icons/svg/dice-target.svg","actorIds":[]} +{"_id":"ydY1XOCO4yIhunkj","name":"27 - T03 - Ugly Villains Aura (xglow)","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"type":"script","flags":{},"scope":"global","command":"let params =\r\n[{\r\n filterType: \"zapshadow\",\r\n filterId: \"myUglyZapShadow\",\r\n alphaTolerance: 0.50\r\n},\r\n{\r\n filterType: \"xglow\",\r\n filterId: \"myUglyGlow\",\r\n auraType: 2,\r\n color: 0x050505,\r\n thickness: 2.7,\r\n scale: 7,\r\n time: 0,\r\n auraIntensity: 5,\r\n subAuraIntensity: 2,\r\n threshold: 0.08,\r\n discard: false,\r\n animated:\r\n {\r\n time : \r\n { \r\n active: true,\r\n speed: 0.0012, \r\n animType: \"move\" \r\n },\r\n auraIntensity:\r\n {\r\n active: true,\r\n loopDuration: 3000, \r\n animType: \"syncCosOscillation\", \r\n val1:5, \r\n val2:0\r\n },\r\n subAuraIntensity:\r\n {\r\n active: true,\r\n loopDuration: 3000, \r\n animType: \"syncCosOscillation\", \r\n val1:2, \r\n val2:0\r\n },\r\n color:\r\n {\r\n active: true,\r\n loopDuration: 6000, \r\n animType: \"syncColorOscillation\", \r\n val1:0x050505, \r\n val2:0x200000\r\n },\r\n threshold:\r\n {\r\n active: true,\r\n loopDuration: 1500, \r\n animType: \"syncCosOscillation\", \r\n val1:0.02, \r\n val2:0.50\r\n }\r\n }\r\n}];\r\n\r\nTokenMagic.addUpdateFiltersOnSelected(params);","author":"Njc5YzFjZDI5NjZl","img":"icons/svg/dice-target.svg","actorIds":[]} +{"_id":"ydY1XOCO4yIhunkj","name":"27 - T03 - Ugly Villains Aura (xglow)","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"type":"script","flags":{},"scope":"global","command":"let params =\r\n[{\r\n filterType: \"zapshadow\",\r\n filterId: \"myUglyZapShadow\",\r\n alphaTolerance: 0.50\r\n},\r\n{\r\n filterType: \"xglow\",\r\n filterId: \"myUglyGlow\",\r\n auraType: 2,\r\n color: 0x050505,\r\n thickness: 2.7,\r\n scale: 7,\r\n time: 0,\r\n auraIntensity: 5,\r\n subAuraIntensity: 2,\r\n threshold: 0.08,\r\n discard: false,\r\n animated:\r\n {\r\n time : \r\n { \r\n active: true,\r\n speed: 0.0012, \r\n animType: \"move\" \r\n },\r\n auraIntensity:\r\n {\r\n active: true,\r\n loopDuration: 3000, \r\n animType: \"syncCosOscillation\", \r\n val1:5, \r\n val2:0\r\n },\r\n subAuraIntensity:\r\n {\r\n active: true,\r\n loopDuration: 3000, \r\n animType: \"syncCosOscillation\", \r\n val1:2, \r\n val2:0\r\n },\r\n color:\r\n {\r\n active: true,\r\n loopDuration: 6000, \r\n animType: \"syncColorOscillation\", \r\n val1:0x050505, \r\n val2:0x200000\r\n },\r\n threshold:\r\n {\r\n active: true,\r\n loopDuration: 1500, \r\n animType: \"syncCosOscillation\", \r\n val1:0.02, \r\n val2:0.50\r\n }\r\n }\r\n}];\r\n\r\nTokenMagic.addUpdateFiltersOnSelected(params);","author":"Njc5YzFjZDI5NjZl","img":"icons/svg/dice-target.svg","actorIds":[]} +{"_id":"SpvVIO1eHYG96TGX","name":"26 - T01 - Spectral Body (liquid)","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"type":"script","flags":{},"scope":"global","command":"let params =\r\n[{\r\n filterType: \"liquid\",\r\n filterId: \"mySpectralBody\",\r\n color: 0x20AAEE,\r\n time: 0,\r\n blend: 8,\r\n intensity: 4,\r\n spectral: true,\r\n scale: 0.9,\r\n animated :\r\n {\r\n time : \r\n { \r\n active: true, \r\n speed: 0.0010, \r\n animType: \"move\" \r\n },\r\n color: \r\n {\r\n active: true, \r\n loopDuration: 6000, \r\n animType: \"colorOscillation\", \r\n val1:0xFFFFFF, \r\n val2:0x00AAFF\r\n }\r\n }\r\n}];\r\n\r\nTokenMagic.addUpdateFiltersOnSelected(params);","author":"Njc5YzFjZDI5NjZl","img":"icons/svg/dice-target.svg","actorIds":[]} +{"name":"28 - Glory to Pixels","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"type":"script","flags":{},"scope":"global","command":"let params = \r\n[{\r\n filterType: \"pixel\",\r\n filterId: \"pixelate\",\r\n sizeX: 2.5,\r\n sizeY: 2.5\r\n}]\r\n\r\nTokenMagic.addUpdateFiltersOnSelected(params);","author":"Njc5YzFjZDI5NjZl","img":"icons/svg/dice-target.svg","actorIds":[],"_id":"8KIRbHAgs6SCs8mT"} +{"_id":"8KIRbHAgs6SCs8mT","name":"28 - Glory to Pixels","permission":{"default":0,"Njc5YzFjZDI5NjZl":3},"type":"script","flags":{},"scope":"global","command":"let params = \r\n[{\r\n filterType: \"pixel\",\r\n filterId: \"pixelate\",\r\n sizeX: 2.5,\r\n sizeY: 2.5\r\n}]\r\n\r\nTokenMagic.addUpdateFiltersOnSelected(params);","author":"Njc5YzFjZDI5NjZl","img":"icons/svg/dice-target.svg","actorIds":[]} diff --git a/tokenmagic/updates/UPDATE-0.2.1.md b/tokenmagic/updates/UPDATE-0.2.1.md new file mode 100644 index 0000000..9a32a08 --- /dev/null +++ b/tokenmagic/updates/UPDATE-0.2.1.md @@ -0,0 +1,161 @@ +# Token Magic FX - Update v0.2.1-alpha + +*Added :* +- An option to allow non-GM players to add, modify or delete FX on tokens which they do not own. +- Mirror-images filter overhaul with new properties : + - number of images + - alpha of the images and the main character + - movement amplitude along the X and Y axis. + - 2 new macro in the portfolio (with an emphasis on new properties) +- Library of stored FX presets : + - comes with a default library (the same as in the portfolio) + - functions to add or delete presets + - functions to export presets library into a json file + - functions to import presets into your library (local or URL) +- Added smooth edges on Force Field filter + +*New FX :* +- A pixelate filter (sample added in the portfolio) + +*Fixed issues :* +- Added the v0.2.0 missing macros in the portfolio. + - X-rays, liquid and x-glow macros +- Force field filter had a brightness and contrast problem. + - The colors are now more vivid. + - You may have to review your macros by adjusting color intensity. + - The Force field macros have been rewritten. +- Corrected some performances issues in the shaders +- Some animations could freeze with a large video or texture (animated tokens, etc.) + +*Thanks :* +- special thanks to @tposney + +## Managing Presets + +*Added new functions :* + +To add a preset in your library : +```javascript +(async) TokenMagic.addPreset(,,optional ) + +// Example +// You don't need to add a filterId when creating a preset. The filterId is created with the preset name. +// In the example below, the filterId will be equal to "FunnyGlow" +// If your preset is composed of multiple filter types, all the filterId will share the preset name +let params = + [{ + filterType: "glow", + filterId: "funnyAlternateGlow", + color: Math.floor(Math.random() * 16777215) + }]; +TokenMagic.addPreset("FunnyGlow",params); +``` +To delete a preset in your library : +```javascript +(async) TokenMagic.deletePreset(,optional ); +``` +To get a preset from your library : +```javascript +TokenMagic.getPreset(); +``` + +To export your library in a json file +```javascript +TokenMagic.exportPresetLibrary(optional ); +``` + +To import presets into your library (open a file picker dialog) +```javascript +(async) TokenMagic.importPresetLibrary(); +``` + +To import presets into your library from a local path +```javascript +(async) TokenMagic.importPresetLibraryFromPath(); +``` + +To import presets into your library from an URL +```javascript +(async) TokenMagic.importPresetLibraryFromURL(); +``` + +To reset the preset library with the default presets (confirmation is requested) +```javascript +(async) TokenMagic.resetPresetLibrary(); +``` + +*A new option in the module option panel allow overwrite of duplicates (by preset name) on import. +By default, duplicates are ignored.* + +### Functions updates + +You can use presets with those functions below, by replacing the params with a preset name : +```javascript +TokenMagic.addFilters +TokenMagic.addFiltersOnSelected +TokenMagic.addFiltersOnTargeted +TokenMagic.addUpdateFiltersOnSelected +TokenMagic.addUpdateFiltersOnTargeted +TokenMagic.updateFiltersOnSelected +TokenMagic.updateFiltersOnTargeted +TokenMagic.updateFiltersByPlaceable + +// Example +TokenMagic.addFiltersOnTargeted("dead"); +``` + +### Default presets library content + +```javascript +0: {name: "bevel", params: Array(1)} +1: {name: "adjustment", params: Array(1)} +2: {name: "dropshadow", params: Array(1)} +3: {name: "outline", params: Array(1)} +4: {name: "glow", params: Array(1)} +5: {name: "bloom", params: Array(1)} +6: {name: "distortion", params: Array(1)} +7: {name: "oldfilm", params: Array(2)} +8: {name: "twist", params: Array(1)} +9: {name: "bulge", params: Array(1)} +10: {name: "blur", params: Array(1)} +11: {name: "zoomblur", params: Array(1)} +12: {name: "shockwave", params: Array(1)} +13: {name: "zapshadow", params: Array(1)} +14: {name: "rays", params: Array(1)} +15: {name: "fog", params: Array(1)} +16: {name: "fumes", params: Array(1)} +17: {name: "electric", params: Array(1)} +18: {name: "fire", params: Array(1)} +19: {name: "waves", params: Array(1)} +20: {name: "flood", params: Array(1)} +21: {name: "smoke", params: Array(1)} +22: {name: "images", params: Array(1)} +23: {name: "chaos-images", params: Array(1)} +24: {name: "spectral-images", params: Array(1)} +25: {name: "hexa-field", params: Array(1)} +26: {name: "fire-field", params: Array(1)} +27: {name: "smoke-field", params: Array(1)} +28: {name: "earth-field", params: Array(1)} +29: {name: "earth-field-top", params: Array(1)} +30: {name: "air-field", params: Array(1)} +31: {name: "magic-field", params: Array(1)} +32: {name: "chromatic-field", params: Array(1)} +33: {name: "water-field", params: Array(1)} +34: {name: "evil-field", params: Array(1)} +35: {name: "grid-field", params: Array(1)} +36: {name: "warp-field", params: Array(1)} +37: {name: "color-field", params: Array(1)} +38: {name: "sunburst", params: Array(1)} +39: {name: "clover", params: Array(1)} +40: {name: "scan", params: Array(1)} +41: {name: "blue-rays", params: Array(1)} +42: {name: "spectral-body", params: Array(1)} +43: {name: "mantle-of-madness", params: Array(1)} +44: {name: "drift-in-plans", params: Array(2)} +45: {name: "fire-aura", params: Array(2)} +46: {name: "glacial-aura", params: Array(2)} +47: {name: "anti-aura", params: Array(2)} +48: {name: "pure-fire-aura", params: Array(3)} +49: {name: "pure-fire-aura-2", params: Array(3)} +50: {name: "pure-ice-aura", params: Array(3)} +``` \ No newline at end of file