[BETA] Due to several issues that I cannot solve (details on the github project), the module has been categorized as beta, there is an open commission on the league server for anyone interested.
A user interface to manage the polymorph feature of Dnd5e with summoning animations.
Note: This is module is inspired from the wonderful work done by theRipper93 with its automated-evocations module. If you want to support more modules of this kind, I invite you to go and support his patreon
Should work with all system supported from the warpgate module "mutate" function, but for now the module is only used and tested with the Dnd5e system and the polymorph mechanism.
NOTE this module work very well with this other module Automated Evocations (Variant Fork)
NOTE: If you are a javascript developer and not a typescript developer, you can just use the javascript files under the dist folder
- Sadly i have to create a temprary actor for save the data of the polymorphed acotr (just like dnd5e do now), but everything is going by the plan you didn't notice because i automatically delete the actor when you revert the polymorphing, in the worst case scenario you can just go to delete the actor the standard way.
- Sadly i cannot understand a strange beahviour with warpgater after the mutation the mutated token is still linked to the original actor, i try everything, but it still show the original actor sheet. You can test the behaviour enabling the module settings 'Force use of Warpgate' Here a video of the problem:
- If you add or remove items on the polymorphed actor the "revert" action wil simply delete the actor without transfer any items, so beware about it
- At the moment the warpgate integration doesn't work, so don't use
I don't have time for check every system attributes and skill need help from the community for accomplish this, every system file has a method called `
async prepareDataFromTransformOptions(
originalActorData: Actor,
targetActorData: Actor,
sourceEffects: any[],
targetActorImages: string[],
transformOptions: TransformOptionsGeneric,
):Promise<any>
where usually as common values i use these:
const targetActorImages = await targetActor.getTokenImages();
const sourceEffects = sourceToken.actor ? sourceToken.actor.effects : sourceToken.effects;
const transformOptions = {
keepPhysical = false;
keepMental = false;
keepSaves = false;
keepSkills = false;
mergeSaves = false;
mergeSkills = false;
keepClass = false;
keepFeats = false;
keepSpells = false;
keepItems = false;
keepBio = false;
keepVision = false;
keepSelf = false;
keepAE = false;
keepAEOnlyOriginNotEquipment = false;
transformTokens = true;
explicitName = '';
}
These settings should customized
It's always easiest to install modules from the in game add-on browser.
To install this module manually:
- Inside the Foundry "Configuration and Setup" screen, click "Add-on Modules"
- Click "Install Module"
- In the "Manifest URL" field, paste the following url:
https://raw.githubusercontent.com/p4535992/foundryvtt-automated-polymorpher/master/src/module.json
- Click 'Install' and wait for installation to complete
- Don't forget to enable the module in game using the "Manage Module" button
This module uses the sequencer library. It is a hard dependency.
This module uses the warpgate library. It is a mandatory dependency and it is recommended for the best experience and compatibility with other modules.
This module uses the socketlib library for wrapping core methods. It is a hard dependency and it is recommended for the best experience and compatibility with other modules.
This module uses the advanced-macros library. It is a optional dependency and it is recommended for the best experience and compatibility with other modules.
NOTE: you need this only for the custom macro feature, i don't suggest it is much easier to create the actors and set them up, with the drag and drop but it's up to you
When the module setting 'Force use of Warpgate' is enabled , we tried to se the warpgate module for mutate the actor. You must understand the things:
- Warpgate is a high level module and can be cusomized in many way
- Warpgate let you mutate the token without the need to create a temporary actor like in the standard behaviour
Open any character sheet, in the header of the window you will see the polymorphers button
Upon opening you will be welcomed by a window, from here you can drag and drop actor into it to add them.
After adding actor to the window you will have some options:
- To mutate click on the actor image
- The dropdown will let you chose the summoning animation
Then you interact with the standard panel of the Polymorph (if the system is dnd5e)
An interface in the hud layer now allows you to speed up the transformations during a fight in a very intuitive way to manage the transformations there are three modes, at the level of the individual actor:
- Random: the next transformation is randomly taken from the list of transformations associated with the actor
- Ordered: the next transformation is taken according to the order of the list of transformations associated with the actor
- No random, No orderder: the standard method shows the configuration panel that you would have by clicking on the header sheet button
the actions on the hud button are of two types left click and right click.
- Left click activates the transformation event
- Right click reverts the transformation and returns to the original shape.
NOTE: you can't have both ordered and random NOTE: Remember you must own the token for see the HUD button
async game.modules.get('automated-polymorpher').api.invokePolymorpherManager(sourceTokenIdOrName: string, removePolymorpher = false, ordered = false, random = false, animationExternal:{ sequence:Sequence, timeToWait:number }|undefined = undefined) ⇒ Promise.<void>
Invoke the polymorpher manager feature from macro
Returns: Promise.<void>
- A empty promise
Param | Type | Description | Default |
---|---|---|---|
sourceTokenIdOrName | string |
The id or the name of the token (not the actor) | undefined |
removePolymorpher | boolean |
This action should revert the polymorpher if the current token is polymorphed | false |
ordered | boolean |
The 'ordered' feature is enabled for this polymorphing | false |
random | boolean |
The 'random' feature is enabled for this polymorphing | 0 |
explicitName | string |
The explicit name to assign to the target actor |
|
animationExternal | { sequence:Sequence, timeToWait:number } |
Advanced: Use your personal sequence animation and the time needed to wait before the polymorph action, checkout the Sequencer module for more information | undefined |
NOTE: If both 'random' and 'ordered' are false the standard dialog will be rendered.
Examples:
game.modules.get('automated-polymorpher').api.invokePolymorpherManager('Zruggig Widebrain')
game.modules.get('automated-polymorpher').api.invokePolymorpherManager('Zruggig Widebrain', true)
game.modules.get('automated-polymorpher').api.invokePolymorpherManager('Zruggig Widebrain', false, false)
game.modules.get('automated-polymorpher').api.invokePolymorpherManager('Zruggig Widebrain', false, false, false)
let sequence = new Sequence()
.effect()
.file("modules/animated-spell-effects-cartoon/spell-effects/cartoon/electricity/electrivity_blast_CIRCLE.webm")
.atLocation(tokenD)
.scale(0.35)
.wait(1000)
.effect()
.file("modules/animated-spell-effects-cartoon/spell-effects/cartoon/electricity/lightning_bolt_RECTANGLE_05.webm")
.atLocation(tokenD)
.reachTowards({
x: tokenD.center.x + canvas.grid.size*5,
y: tokenD.center.y
})
.wait(100)
.animation()
.on(tokenD)
.teleportTo({
x: tokenD.x + canvas.grid.size*5,
y: tokenD.y
})
.waitUntilFinished()
.effect()
.file("modules/animated-spell-effects-cartoon/spell-effects/cartoon/electricity/electric_ball_CIRCLE_06.webm")
.atLocation(tokenD)
.scale(0.5)
game.modules.get('automated-polymorpher').api.invokePolymorpherManager('Zruggig Widebrain', false, false, false, { sequence: sequence, timeToWait 1100})
async game.modules.get('automated-polymorpher').api.invokePolymorpherManagerFromActor(sourceActorIdOrName: string, removePolymorpher = false, ordered = false, random = false, animationExternal:{ sequence:Sequence, timeToWait:number }|undefined = undefined) ⇒ Promise.<void>
Invoke the polymorpher manager feature from macro
Returns: Promise.<void>
- A empty promise
Param | Type | Description | Default |
---|---|---|---|
sourceActorIdOrName | string |
The id or the name of the actor (not the token) | undefined |
removePolymorpher | boolean |
This action should revert the polymorpher if the current token is polymorphed | false |
ordered | boolean |
The 'ordered' feature is enabled for this polymorphing | false |
random | boolean |
The 'random' feature is enabled for this polymorphing | 0 |
explicitName | string |
The explicit name to assign to the target actor |
|
animationExternal | { sequence:Sequence, timeToWait:number } |
Advanced: Use your personal sequence animation and the time needed to wait before the polymorph action, checkout the Sequencer module for more information | undefined |
NOTE: If both 'random' and 'ordered' are false the standard dialog will be rendered.
Examples:
game.modules.get('automated-polymorpher').api.invokePolymorpherManagerFromActor('Zruggig Widebrain')
game.modules.get('automated-polymorpher').api.invokePolymorpherManagerFromActor('Zruggig Widebrain', true)
game.modules.get('automated-polymorpher').api.invokePolymorpherManagerFromActor('Zruggig Widebrain', false, false)
game.modules.get('automated-polymorpher').api.invokePolymorpherManagerFromActor('Zruggig Widebrain', false, false, false)
let sequence = new Sequence()
.effect()
.file("modules/animated-spell-effects-cartoon/spell-effects/cartoon/electricity/electrivity_blast_CIRCLE.webm")
.atLocation(tokenD)
.scale(0.35)
.wait(1000)
.effect()
.file("modules/animated-spell-effects-cartoon/spell-effects/cartoon/electricity/lightning_bolt_RECTANGLE_05.webm")
.atLocation(tokenD)
.reachTowards({
x: tokenD.center.x + canvas.grid.size*5,
y: tokenD.center.y
})
.wait(100)
.animation()
.on(tokenD)
.teleportTo({
x: tokenD.x + canvas.grid.size*5,
y: tokenD.y
})
.waitUntilFinished()
.effect()
.file("modules/animated-spell-effects-cartoon/spell-effects/cartoon/electricity/electric_ball_CIRCLE_06.webm")
.atLocation(tokenD)
.scale(0.5)
game.modules.get('automated-polymorpher').api.invokePolymorpherManagerFromActor('Zruggig Widebrain', false, false, false, { sequence: sequence, timeToWait 1100})
Examples:
game.modules.get('automated-polymorpher').api.cleanUpTokenSelected()
let sequence = new Sequence()
.effect()
.file("modules/animated-spell-effects-cartoon/spell-effects/cartoon/electricity/electrivity_blast_CIRCLE.webm")
.atLocation(tokenD)
.scale(0.35)
.wait(1000)
.effect()
.file("modules/animated-spell-effects-cartoon/spell-effects/cartoon/electricity/lightning_bolt_RECTANGLE_05.webm")
.atLocation(tokenD)
.reachTowards({
x: tokenD.center.x + canvas.grid.size*5,
y: tokenD.center.y
})
.wait(100)
.animation()
.on(tokenD)
.teleportTo({
x: tokenD.x + canvas.grid.size*5,
y: tokenD.y
})
.waitUntilFinished()
.effect()
.file("modules/animated-spell-effects-cartoon/spell-effects/cartoon/electricity/electric_ball_CIRCLE_06.webm")
.atLocation(tokenD)
.scale(0.5)
game.modules.get('automated-polymorpher').socket.executeAsGM('invokePolymorpherManager',['Zruggig Widebrain', false, false, false, { sequence: sequence, timeToWait 1100}]);
npm install
will build the code and copy all necessary assets into the dist folder and make a symlink to install the result into your foundry data; create a
foundryconfig.json
file with your Foundry Data path.
{
"dataPath": "~/.local/share/FoundryVTT/"
}
build
will build and set up a symlink between dist
and your dataPath
.
npm run-script build
You don't need to build the foundryconfig.json
file you can just copy the content of the dist
folder on the module folder under modules
of Foundry
build:watch
will build and watch for changes, rebuilding automatically.
npm run-script build:watch
clean
will remove all contents in the dist folder (but keeps the link from build:install).
npm run-script clean
prettier-format
launch the prettier plugin based on the configuration here
npm run-script prettier-format
package
generates a zip file containing the contents of the dist folder generated previously with the build
command. Useful for those who want to manually load the module or want to create their own release
npm run-script package
Any issues, bugs, or feature requests are always welcome to be reported directly to the Issue Tracker, or using the Bug Reporter Module.
-
Jack Kerouac's: GPL-3.0 License
-
JB2A: CC BY-NC-SA 4.0
-
Sequencer: Mit License
-
Warpgate: GPL-3.0 License
-
Automated Evocations: ???
-
Game Icons: CC BY 3.0
This package is under an GPL-3.0 License and the Foundry Virtual Tabletop Limited License Agreement for module development.
-
Jack Kerouac's: The Fire, Air, Lightning, Water, Energy, Magic, Heart, Crescendo, Four Elements animations assets are from Jack Kerouac's amazing https://github.com/jackkerouac/animated-spell-effects-cartoon module. (used with permission)
-
JB2A: The Chord, Darkness, Ice, Conjuration, Storm animations assets are courtesy of JB2A (Free animated assets), i strongly reccomend checking out their patreon for many more amazing animations and variations. (used with permission) https://discord.gg/A59GAZwB9M https://www.patreon.com/JB2A
-
Sequencer: This module is used to play the animations https://github.com/fantasycalendar/FoundryVTT-Sequencer
-
Warpgate: This module is used for the spawning https://github.com/trioderegion/warpgate
-
Automated Evocations: This module is used for the inspiration and base functionality https://github.com/theripper93/automated-evocations
-
Game Icons: Some images used are from https://game-icons.net/
Bootstrapped with League of Extraordinary FoundryVTT Developers foundry-vtt-types.
Mad props to the 'League of Extraordinary FoundryVTT Developers' community which helped me figure out a lot.