├── 13th Age Official Character Sheet Companion ├── 1.0 │ └── 13th Age Official Character Sheet Companion.js └── script.json ├── 5eShapedScript ├── 5eShapedScript.js ├── README.md ├── changelog.md └── script.json ├── 5th Edition OGL by Roll20 Companion ├── 1.0 │ └── 5th Edition OGL by Roll20 Companion.js ├── 1.1 │ └── 5th Edition OGL by Roll20 Companion.js ├── 1.2 │ └── 5th Edition OGL by Roll20 Companion.js ├── 1.3 │ └── 5th Edition OGL by Roll20 Companion.js └── script.json ├── APIHeartBeat ├── 0.4.1 │ └── APIHeartBeat.js ├── APIHeartBeat.js └── script.json ├── Ammo ├── 0.3.1 │ └── Ammo.js ├── 0.3.2 │ └── Ammo.js ├── 0.3.3 │ └── Ammo.js ├── Ammo.js └── script.json ├── AmmunitionTracker ├── AmmunitionTracker.js ├── help.txt └── script.json ├── Animation ├── Help.txt ├── animation.js └── script.json ├── AnnounceRoll ├── 0.2.1 │ └── AnnounceRoll.js ├── AnnounceRoll.js └── script.json ├── AreasOfEffect ├── 1.0 │ └── aoe.js ├── README.md ├── demo.gif ├── sampleEffectGraphics │ ├── agniShine.png │ ├── agniShine.svg │ ├── icicleFall.png │ ├── icicleFall.svg │ ├── metalFatigue.png │ ├── metalFatigue.svg │ ├── moonlightRay.png │ ├── moonlightRay.svg │ ├── princessUndine.png │ ├── princessUndine.svg │ ├── rageTrilithon.png │ ├── rageTrilithon.svg │ ├── rainbowWindchime.png │ ├── rainbowWindchime.svg │ ├── sylphaeHorn.png │ └── sylphaeHorn.svg └── script.json ├── ArsMagica5eStressDie ├── ArsMagica5eStressDie.js ├── ArsMagica5eStressDie_nomod.js └── script.json ├── AutoFacing ├── AutoFacing.js └── script.json ├── Base64 ├── 0.3.1 │ └── Base64.js ├── Base64.js └── script.json ├── BashDice ├── 0.2.1 │ └── BashDice.js ├── BashDice.js └── script.json ├── Bet ├── 0.1.3 │ └── Bet.js ├── Bet.js └── script.json ├── Blood-and-Honor ├── BloodAndHonor.js ├── help.txt └── script.json ├── Bloodied and Dead Status Markers ├── Bloodied and Dead Status Markers.js ├── Help.txt └── script.json ├── BounceTokens ├── 0.1.0 │ └── BounceTokens.js ├── BounceTokens.js └── script.json ├── Bump ├── 0.2.10 │ └── Bump.js ├── 0.2.8 │ └── Bump.js ├── 0.2.9 │ └── Bump.js ├── Bump.js └── script.json ├── ChangeTokenImage ├── ChangeTokenImage.js ├── README.md └── script.json ├── CharUtils ├── 0.6.4 │ └── CharUtils.js ├── CharUtils.js └── script.json ├── Charsheet ├── 1.2 │ └── charsheet.js ├── README.md └── script.json ├── ChatSetAttr ├── 0.9.1 │ └── ChatSetAttr.js ├── 0.9 │ └── ChatSetAttr.js ├── 1.0 │ └── ChatSetAttr.js ├── ChatSetAttr.js └── script.json ├── CleanAbilities ├── 0.1.1 │ └── CleanAbilities.js ├── CleanAbilities.js └── script.json ├── Collision Detection ├── 1.0 │ └── Collision Detection.js ├── 2.0 │ └── Collision Detection.js ├── 2.1 │ └── Collision Detection.js ├── 2.2 │ └── Collision Detection.js ├── README.md └── script.json ├── ColorEmote ├── 0.1.3 │ └── ColorEmote.js ├── ColorEmote.js └── script.json ├── ColorNote ├── 0.2.1 │ └── ColorNote.js ├── ColorNote.js └── script.json ├── CommandShell ├── Help.txt ├── script.json └── shell.js ├── Conditions ├── Help.txt ├── conditions.js └── script.json ├── CthulhuTechDice ├── 0.1.12 │ └── CthulhuTechDice.js ├── CthulhuTechDice.js └── script.json ├── Custom FX ├── 0.1 │ └── Custom FX.js ├── README.md └── script.json ├── CustomStatusMarkers ├── 1.5 │ └── CustomStatusMarkers.js ├── 2.0 │ └── CustomStatusMarkers.js ├── 2.1 │ └── CustomStatusMarkers.js ├── README.md ├── demo.gif ├── icons │ ├── statusBerserk.png │ ├── statusBrain.png │ ├── statusCripppled.png │ ├── statusDisease.png │ ├── statusDrug.png │ ├── statusHaste.png │ ├── statusImmobilize.png │ ├── statusSilence.png │ ├── statusSleep.png │ ├── statusSlow.png │ ├── statusStars.png │ ├── statusStun.png │ └── statusTrueSight.png └── script.json ├── CypherSystemSheet ├── 1.2 │ └── cyphersystemsheet.js └── script.json ├── DarknessClosingIn ├── 0.2.1 │ └── DarknessClosingIn.js ├── DarknessClosingIn.js └── script.json ├── DiceInTheVineyard ├── Help.txt ├── ditv.js └── script.json ├── DryErase ├── 0.1.6 │ └── DryErase.js ├── DryErase.js └── script.json ├── DungeonUtils ├── DungeonUtils.js └── script.json ├── Dynamic Lighting Animation ├── 1.0 │ └── Dynamic Lighting Animation.js ├── 2.0 │ └── Dynamic Lighting Animation.js ├── 2.1 │ └── Dynamic Lighting Animation.js ├── 2.2 │ └── Dynamic Lighting Animation.js ├── 2.3 │ └── Dynamic Lighting Animation.js ├── README.md └── script.json ├── DynamicLightRecorder ├── .gitignore ├── DynamicLightRecorder.js ├── README.md └── script.json ├── ESRO ├── 0.1 │ └── ESRO.js ├── README.md └── script.json ├── EasyExperience ├── 0.4 │ └── EasyExperience.js ├── 1.0 │ └── EasyExperience.js ├── 1.01 │ └── EasyExperience.js ├── 1.02 │ └── EasyExperience.js ├── 1.03 │ └── EasyExperience.js ├── 1.04 │ └── EasyExperience.js ├── V0.4 │ └── EasyExperience.js.txt ├── V1.0 │ └── EasyExperience.js.txt └── script.json ├── Emas ├── 0.8.1 │ └── Emas.js ├── Emas.js └── script.json ├── Escalation ├── 0.2.1 │ └── Escalation.js ├── Escalation.js └── script.json ├── Exalted Successes ├── 1.0 │ └── Exalted Successes.js ├── 2.0 │ └── Exalted Successes.js ├── 2.1 │ └── Exalted Successes.js ├── 2.2 │ └── Exalted Successes.js ├── README.md └── script.json ├── ExperienceTracker ├── 2.1 │ └── ExperienceTracker.js ├── README.md └── script.json ├── ExtendedExpressions ├── Help.txt ├── extend.js └── script.json ├── FFG-SWRPG-Dice-Roller ├── 2.6 │ ├── EotE-Dice.js │ └── help.txt ├── 3.0 │ └── EotE-Dice.js ├── 4.0.2.17 │ └── FFG-SWRPG-Dice-Roller.js ├── 4.0.4.0 │ └── FFG-SWRPG-Dice-Roller.js ├── 4.0.4.3 │ ├── FFG-SWRPG-Dice-Roller.js │ └── help.txt ├── 6.3.0 │ └── FFG-SWRPG-Dice-Roller.js ├── dice │ ├── Ability │ │ ├── abilityA.png │ │ ├── abilityAA.png │ │ ├── abilityBlank.png │ │ ├── abilityS.png │ │ ├── abilitySA.png │ │ └── abilitySS.png │ ├── Boost │ │ ├── boostA.png │ │ ├── boostAA.png │ │ ├── boostBlank.png │ │ ├── boostS.png │ │ └── boostSA.png │ ├── Challenge │ │ ├── ChallengeBlank.png │ │ ├── ChallengeDespair.png │ │ ├── ChallengeF.png │ │ ├── ChallengeFF.png │ │ ├── ChallengeFT.png │ │ ├── ChallengeT.png │ │ └── ChallengeTT.png │ ├── Difficulty │ │ ├── DifficultyBlank.png │ │ ├── DifficultyF.png │ │ ├── DifficultyFF.png │ │ ├── DifficultyFT.png │ │ ├── DifficultyT.png │ │ └── DifficultyTT.png │ ├── Force │ │ ├── ForceD.png │ │ ├── ForceDD.png │ │ ├── ForceL.png │ │ └── ForceLL.png │ ├── Proficiency │ │ ├── ProficiencyA.png │ │ ├── ProficiencyAA.png │ │ ├── ProficiencyBlank.png │ │ ├── ProficiencyS.png │ │ ├── ProficiencySA.png │ │ ├── ProficiencySS.png │ │ └── ProficiencyTriumph.png │ ├── Setback │ │ ├── SetBackBlank.png │ │ ├── SetBackF.png │ │ └── SetBackT.png │ └── Symbols │ │ ├── A.png │ │ ├── D.png │ │ ├── Despair.png │ │ ├── F.png │ │ ├── L.png │ │ ├── S.png │ │ ├── T.png │ │ └── Triumph.png └── script.json ├── Facing ├── 0.1.2 │ └── Facing.js ├── Facing.js └── script.json ├── FalloutTerminal ├── 1.0 │ └── terminal.js ├── README.md ├── demo.gif ├── example.json └── script.json ├── FateDots ├── 0.2.1 │ └── FateDots.js ├── FateDots.js └── script.json ├── Flight ├── 1.0 │ └── Flight.js ├── 2.0 │ └── Flight.js ├── 3.0 │ └── Flight.js ├── 3.1 │ └── Flight.js ├── 3.2 │ └── Flight.js ├── 3.3 │ └── Flight.js ├── 3.4 │ └── Flight.js ├── README.md └── script.json ├── Flip Tokens ├── 1.0 │ └── Flip Tokens.js ├── 2.0 │ └── Flip Tokens.js ├── 2.1 │ └── Flip Tokens.js ├── 2.2 │ └── Flip Tokens.js ├── 2.3 │ └── Flip Tokens.js ├── README.md └── script.json ├── Fumbler ├── Fumbler.js ├── README.md └── script.json ├── GMCode ├── GMCode.js ├── Help.txt └── script.json ├── GUMSHOE ├── GUMSHOE.js ├── HELP.md └── script.json ├── GeigerCounter ├── 1.0 │ └── GeigerCounter.js ├── 1.1 │ └── GeigerCounter.js ├── README.md └── script.json ├── GroupInitiative ├── 0.9.17 │ └── GroupInitiative.js ├── 0.9.18 │ └── GroupInitiative.js ├── 0.9.19 │ └── GroupInitiative.js ├── 0.9.20 │ └── GroupInitiative.js ├── GroupInitiative.js └── script.json ├── HaloMythicUtilities ├── HaloMythicUtilities.js ├── help.txt └── script.json ├── HiddenRolls ├── Help.txt ├── hidden.js └── script.json ├── HtmlBuilder ├── 1.0 │ └── script.js ├── README.md └── script.json ├── InitiativeAssistant ├── 0.1.3 │ └── InitiativeAssistant.js ├── InitiativeAssistant.js └── script.json ├── InitiativeTracker ├── Help.txt ├── script.json └── tracker.js ├── Interpreted sendChat ├── 1.1 │ └── Interpreted sendChat.js ├── 2.0 │ └── Interpreted sendChat.js ├── 2.1 │ └── Interpreted sendChat.js ├── 2.2 │ └── Interpreted sendChat.js ├── README.md └── script.json ├── InventoryManager ├── InventoryManager.js ├── InventoryManager.min.js ├── InventoryManager.min.js.map ├── Readme.md └── script.json ├── IsGM ├── 0.7.1 │ └── IsGM.js ├── IsGM.js ├── README.md └── script.json ├── IsGreater ├── 0.2.1 │ └── IsGreater.js ├── IsGreater.js └── script.json ├── Its A Trap ├── 2.0 │ └── ItsATrap.js ├── 2.1 │ └── ItsATrap.js ├── 2.2 │ └── ItsATrap.js ├── 2.3 │ └── ItsATrap.js ├── 2.4 │ └── ItsATrap.js ├── 2.5 │ └── ItsATrap.js ├── 2.6 │ └── ItsATrap.js ├── 2.7 │ └── ItsATrap.js ├── ItsATrap.gif ├── README.md └── script.json ├── ItsATrap_theme_5E_OGL ├── 1.0 │ └── TrapTheme.js ├── 1.1 │ └── TrapTheme.js ├── 1.2 │ └── TrapTheme.js ├── README.md └── script.json ├── ItsATrap_theme_5E_Shaped ├── 1.0 │ └── theme.js ├── 1.1 │ └── theme.js ├── 1.2 │ └── theme.js ├── README.md └── script.json ├── ItsATrap_theme_DnD3.5 ├── 1.0 │ └── TrapTheme.js ├── 1.1 │ └── TrapTheme.js ├── 1.2 │ └── TrapTheme.js ├── README.md └── script.json ├── ItsATrap_theme_GammaWorld7 ├── 1.0 │ └── TrapTheme.js ├── 1.1 │ └── TrapTheme.js ├── 1.2 │ └── TrapTheme.js ├── README.md └── script.json ├── ItsATrap_theme_Pathfinder ├── 1.0 │ └── TrapTheme.js ├── 1.1 │ └── TrapTheme.js ├── README.md └── script.json ├── ItsATrap_theme_PathfinderSimple ├── 1.0 │ └── theme.js ├── README.md └── script.json ├── ItsATrap_theme_RoleplayingIsMagic4 ├── 1.0 │ └── TrapTheme.js ├── 1.1 │ └── TrapTheme.js ├── 1.2 │ └── TrapTheme.js ├── README.md └── script.json ├── LICENSE ├── Languages ├── Languages.js ├── help.txt └── script.json ├── ManualAttribute ├── 0.2.1 │ └── ManualAttribute.js ├── ManualAttribute.js └── script.json ├── MapChange ├── 1.0 │ └── MapChange.js ├── 1.1 │ └── MapChange.js ├── 1.2 │ └── MapChange.js ├── 1.3 │ └── MapChange.js ├── MapChange.js └── script.json ├── MapLock ├── 0.4.1 │ └── MapLock.js ├── 0.4.3 │ └── MapLock.js ├── MapLock.js └── script.json ├── MapSnap ├── 0.1.3 │ └── MapSnap.js ├── MapSnap.js └── script.json ├── MarchingOrder ├── 2.0 │ └── marchingOrder.js ├── 2.1 │ └── marchingOrder.js ├── README.md ├── demo.gif └── script.json ├── Mark ├── 0.3.2 │ └── Mark.js ├── 0.3.3 │ └── Mark.js ├── Mark.js └── script.json ├── Marking Conditions ├── 1.0 │ └── Marking Conditions.js ├── 1.1 │ └── Marking Conditions.js ├── 2.0 │ └── Marking Conditions.js ├── 3.0 │ └── Marking Conditions.js ├── 3.1 │ └── Marking Conditions.js ├── 3.2 │ └── Marking Conditions.js ├── 3.3 │ └── Marking Conditions.js ├── README.md └── script.json ├── Markov ├── Markov.js └── script.json ├── MatrixMath ├── 1.0 │ └── matrixMath.js ├── README.md └── script.json ├── Measure ├── 0.3.1 │ └── Measure.js ├── Measure.js └── script.json ├── MonsterHitDice ├── 0.3.3 │ └── MonsterHitDice.js ├── 0.3.4 │ └── MonsterHitDice.js ├── 0.3.5 │ └── MonsterHitDice.js ├── 0.3.6 │ └── MonsterHitDice.js ├── MonsterHitDice.js └── script.json ├── MotD ├── 0.2.1 │ └── MotD.js ├── MotD.js └── script.json ├── MovePlayers ├── 0.2.1 │ └── MovePlayers.js ├── MovePlayers.js └── script.json ├── MutantYearZero ├── 0.1.8 │ └── MutantYearZero.js ├── MutantYearZero.js └── script.json ├── No Token Rotation ├── 1.0 │ └── No Token Rotation.js ├── 1.1 │ └── No Token Rotation.js ├── README.md └── script.json ├── NoteLog ├── 0.1.1 │ └── NoteLog.js ├── NoteLog.js └── script.json ├── Numenera_Natha ├── 4.8 │ └── Numenera_Natha.js └── script.json ├── ObjectProperties ├── Help.txt ├── properties.js └── script.json ├── PCPP ├── 0.3.1 │ └── PCPP.js ├── PCPP.js └── script.json ├── Page Navigator ├── 1.031 │ └── PageNavigator.js ├── 1.3 │ └── PageNavigator.js ├── 1.4 │ ├── PageNavigator │ └── PageNavigator.js ├── 1.42 │ └── PageNavigator.js ├── 1.43 │ └── PageNavigator.js └── script.json ├── PageFX ├── 1.0 │ └── PageFX.js ├── 1.1 │ └── PageFX.js ├── 1.2 │ └── PageFX.js ├── PageFX.gif ├── README.md └── script.json ├── PageSize ├── Help.txt ├── pagesize.js └── script.json ├── PathMath ├── 1.0 │ └── PathMath.js ├── 1.1 │ └── PathMath.js ├── 1.2 │ └── PathMath.js ├── 1.3 │ └── PathMath.js ├── README.md └── script.json ├── PathSplitter ├── 1.0 │ └── PathSplitter.js ├── README.md ├── demo.gif └── script.json ├── Pathfinder HeroLab Import ├── 0.5 │ └── HL-Import.js ├── HL-Import.js └── script.json ├── Pathfinder PCGen Import ├── PCGenPFImport.js ├── csheet_pathfinder_roll20.txt.ftl └── script.json ├── Pathfinder Skillbook ├── 1.0 │ └── Skillbook.js ├── 1.1 │ └── Skillbook.js ├── 1.11 │ └── Skillbook.js ├── Skillbook.js └── script.json ├── PortesMonstresTresors ├── 1.3 │ └── pmt.js ├── 1.4 │ └── pmt.js └── script.json ├── README.md ├── Raise Count ├── 1.0 │ └── Raise Count.js ├── 2.0 │ └── Raise Count.js ├── 2.1 │ └── Raise Count.js ├── 2.2 │ └── Raise Count.js ├── 2.3 │ └── Raise Count.js ├── 2.4 │ └── Raise Count.js ├── 2.5 │ └── Raise Count.js ├── 2.6 │ └── Raise Count.js ├── README.md └── script.json ├── Random Turnorder ├── 1.0 │ └── Random Turnorder.js ├── 1.1 │ └── Random Turnorder.js ├── README.md └── script.json ├── RandomDepth ├── 0.3.1 │ └── RandomDepth.js ├── RandomDepth.js └── script.json ├── RandomEncounters ├── RandomEncounters.js └── script.json ├── RandomRotate ├── 0.2.1 │ └── RandomRotate.js ├── RandomRotate.js └── script.json ├── RecursiveTable ├── 0.1.2 │ └── RecursiveTable.js ├── RecursiveTable.js └── script.json ├── RoleplayingIsMagic_4E_Dice ├── 1.1 │ └── mlp_dice.js ├── README.md └── script.json ├── RollStats ├── Help.txt ├── script.json └── stats.js ├── Ryuutama Skill Check Totaler ├── ryuutama-check-totaler.js └── script.json ├── Ryuutama Token Status Markers ├── Ryuutama.js └── script.json ├── Saga Machine Roller ├── README.md ├── script.json └── sm_roller.js ├── ScaleOnAdd ├── 0.1.1 │ └── ScaleOnAdd.js ├── ScaleOnAdd.js └── script.json ├── ShareVision ├── 1.4 │ └── ShareVision.js └── script.json ├── SizeLock ├── 0.2.1 │ └── SizeLock.js ├── SizeLock.js └── script.json ├── Slide Tokens ├── 1.0 │ └── Slide Tokens.js ├── 1.1 │ └── Slide Tokens.js ├── 1.2 │ └── Slide Tokens.js ├── README.md └── script.json ├── SpeedFactor ├── SpeedFactor.js ├── help.txt └── script.json ├── SpellLevel5e ├── 0.2.1 │ └── SpellLevel5e.js ├── SpellLevel5e.js └── script.json ├── SpinTokens ├── 0.4.1 │ └── SpinTokens.js ├── SpinTokens.js └── script.json ├── StateBrowser ├── Help.txt ├── StateBrowser.js └── script.json ├── StatusFX ├── 1.0 │ └── statusFx.js ├── 1.1 │ └── statusFx.js ├── 1.2 │ └── statusFx.js ├── README.md ├── demo.gif └── script.json ├── Store Commands ├── 1.0 │ └── Store Commands.js ├── 2.0 │ └── Store Commands.js ├── 2.1 │ └── Store Commands.js ├── 2.2 │ └── Store Commands.js ├── 2.3 │ └── Store Commands.js ├── README.md └── script.json ├── TableExport ├── 0.2.3 │ └── TableExport.js ├── TableExport.js └── script.json ├── TableTokenSizer ├── 0.2.1 │ └── TableTokenSizer.js ├── TableTokenSizer.js └── script.json ├── TempHPAndStatus ├── 0.4.1 │ └── TempHPAndStatus.js ├── TempHPAndStatus.js ├── foo └── script.json ├── The Darkness is Closing In ├── Help.txt ├── The Darkness is Closing In.js └── script.json ├── Tile ├── 0.3.1 │ └── Tile.js ├── Tile.js └── script.json ├── TimeTracker ├── MacroQuery ├── README.md ├── TimeTracker.js └── script.json ├── Token Collisions ├── 1.1 │ └── TokenCollisions.js ├── 1.2 │ └── TokenCollisions.js ├── 1.3 │ └── TokenCollisions.js ├── 1.4 │ └── TokenCollisions.js ├── README.md └── script.json ├── TokenLock ├── 0.2.3 │ └── TokenLock.js ├── 0.2.4 │ └── TokenLock.js ├── 0.2.5 │ └── TokenLock.js ├── TokenLock.js └── script.json ├── TokenMod ├── 0.8.19 │ └── TokenMod.js ├── 0.8.20 │ └── TokenMod.js ├── 0.8.21 │ └── TokenMod.js ├── TokenMod.js └── script.json ├── TokenNameNumber ├── 0.5.6 │ └── TokenNameNumber.js ├── 0.5.7 │ └── TokenNameNumber.js ├── 0.5.8 │ └── TokenNameNumber.js ├── 0.5.9 │ └── TokenNameNumber.js ├── TokenNameNumber.js └── script.json ├── TokenPath ├── Help.txt ├── path.js └── script.json ├── Torch ├── 0.8.6 │ └── Torch.js ├── 0.8.7 │ └── Torch.js ├── 0.8.8 │ └── Torch.js ├── Torch.js └── script.json ├── TotalMana ├── 0.1.3 │ └── TotalMana.js ├── TotalMana.js └── script.json ├── Track V20 Attributes ├── README.md ├── Track V20 Attributes.js └── script.json ├── TurnLock ├── Help.txt ├── TurnLock.js └── script.json ├── TurnMarker1 ├── 1.3.3 │ └── TurnMarker1.js ├── 1.3.4 │ └── TurnMarker1.js ├── 1.3.5 │ └── TurnMarker1.js ├── 1.3.7 │ └── TurnMarker1.js ├── TurnMarker1.js └── script.json ├── Twins ├── 0.2.1 │ └── Twins.js ├── Twins.js └── script.json ├── UsePower ├── 0.4.1 │ └── UsePower.js ├── UsePower.js └── script.json ├── Vector Math ├── 1.0 │ └── VecMath.js ├── README.md └── script.json ├── WFRPDice ├── README.md ├── WFRPDice.js └── script.json ├── Walls ├── 0.3.1 │ └── Walls.js ├── Walls.js └── script.json ├── WeightedDice ├── 0.3.2 │ └── WeightedDice.js ├── WeightedDice.js └── script.json ├── WildDice ├── 0.3.1 │ └── WildDice.js ├── WildDice.js └── script.json ├── WorldMapDiscovery ├── 1.0 │ └── WorldMapDiscovery.js ├── 1.1 │ └── WorldMapDiscovery.js ├── README.md └── script.json ├── ZombieDice ├── 0.4.1 │ └── ZombieDice.js ├── ZombieDice.js └── script.json ├── _Example Script - Check for formatting details ├── 0.5 │ └── example.js ├── 1.0 │ └── example.js ├── 1.1 │ └── example.js ├── README.md └── script.json ├── approved.yaml ├── cron ├── Help.txt ├── cron.js └── script.json ├── levenshteinDistance ├── 1.0 │ └── levenshteinDistance.js ├── 1.1 │ └── levenshteinDistance.js ├── README.md └── script.json ├── splitArgs ├── 1.0 │ └── splitArgs.js ├── 1.1 │ └── splitArgs.js ├── README.md └── script.json └── textTimer ├── LICENSE ├── README.md ├── script.json └── textTimer.js /13th Age Official Character Sheet Companion/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "13th Age Official Character Sheet Companion", 3 | "script": "13th Age Official Character Sheet Companion.js", 4 | "version": "1.0", 5 | "previousversions": [], 6 | "description": "Enhances the Official 13th Age Character Sheet with quick Escalation Die tracking, automatic recovery tracking, token setup, and automatic staggered and down icons.\r\r**API COMMANDS**\r\r**!edie** will add the Escalation Die if there isn't one already in the scene. It will be placed at the top of the turn order. It will continue to count above 6 however it will never add more than a 6 bonus to roll attached to the character sheet. The associated character sheet stat is @{E-DIE} for use in personal macros or @{tracker|Escalation Die} for global macros. Note that the tracker attribute doesn't cap the result at 6 and can return a higher value.\r**!setup** will attempt to set up the bars of every token on the current page that represents a character. A token must already be set to represent a character for **!setup** to work. Bar1 is Temp HP, Bar2 is Recoveries, and Bar3 is HP. Note that the token still needs to be saved once for the HP_max to calculate since it's a disabled attribute.\r**!stag** is on by default. It will automatically add a Staggered or Dead status icon to tokens that represent a character. Using the **!stag** command will toggle the automatic icons on and off.\r**!rec** is on by default. It will automatically tick off a recovery each time to the rollbutton is used. Using the **!rec** command will toggle the automatic recovery tracking on and off.", 7 | "authors": "Steve K.", 8 | "roll20userid": "5047", 9 | "useroptions": [], 10 | "dependencies": [], 11 | "modifies": {}, 12 | "conflicts": [] 13 | } 14 | -------------------------------------------------------------------------------- /5eShapedScript/README.md: -------------------------------------------------------------------------------- 1 | # Roll20 Shaped Script 2 | This is a script designed for use with the API on [Roll20](http://roll20.net). This script is specifically designed to provide services and enhancements for the [5e Shaped Sheet](https://github.com/mlenser/roll20-character-sheets/tree/master/5eShaped). 3 | 4 | [Wiki](https://bitbucket.org/mlenser/5eshapedscript/wiki/Home) 5 | 6 | [Issue Tracker](https://bitbucket.org/mlenser/5eshapedscript/issues?status=new&status=open) -------------------------------------------------------------------------------- /5th Edition OGL by Roll20 Companion/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "5th Edition OGL by Roll20 Companion", 3 | "script": "5th Edition OGL by Roll20 Companion.js", 4 | "version": "1.3", 5 | "previousversions": ["1.0","1.1","1.2"], 6 | "description": "Enhances the Official 5th Edition OGL by Roll20 Character Sheet. The Companion currently supports Ammo Tracking, Automatic NPC Tokens, Automatic Death Save Tracking, and Automatic Spell Slot Tracking.\r\r**API Commands:**\r**!5ehelp** - Gives a list of the script's API commands in the chat tab.\r**!5estatus** - Lists the current status of the script's features in the chat tab.\r**!ammotracking** on/off/quiet - Automatically expends linked resource when attack is made\r**!autonpctoken** on/off - Automatically generates a NPC token on the GM's screen based on the default token when an NPC's health calculation is rolled\r**!deathsavetracking** on/off/quiet - Automatically ticks off successes and failures when death saves are rolled, clearing on death, stabilization, or hp recovery\r**!spelltracking** on/off/quiet - Automatically expends spell charges as cast, factoring in higher level casting\r**!longrest** character name - If spelltracking is on, this command will reset all of the character's spell slots to unspent.\r\r**Options:**\r**on** - Toggles the functionality on (default)\r**off** - Disables the functionality\r**quiet** - Maintains functionality while preventing results from being output to the chat.", 7 | "authors": "Steve K.", 8 | "roll20userid": "5047", 9 | "useroptions": [], 10 | "dependencies": [], 11 | "modifies": {}, 12 | "conflicts": [] 13 | } 14 | -------------------------------------------------------------------------------- /APIHeartBeat/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "APIHeartBeat", 3 | "version": "0.4.1", 4 | "description": "Provides an API Heartbeat by setting the requesting player's color continuously.", 5 | "authors": "The Aaron", 6 | "roll20userid": "104025", 7 | "patreon": "https://www.patreon.com/shdwjk", 8 | "dependencies": [], 9 | "modifies": { 10 | "state.APIHeartBeat": "read,write", 11 | "player.color": "write", 12 | "player.id": "read" 13 | }, 14 | "conflicts": [], 15 | "script": "APIHeartBeat.js", 16 | "useroptions": {}, 17 | "previousversions": [] 18 | } -------------------------------------------------------------------------------- /AmmunitionTracker/help.txt: -------------------------------------------------------------------------------- 1 | !bthelp - This will display a quick help section 2 | !setgun *SLOT* *NAME* *AMMUNITION* - Example "!setgun 1 revolver 200". 3 | !bullets *SLOT* - This decreases one point of ammunition from X slot 4 | !btdel *SLOT* - Deletes the contents of a slot 5 | !btedit *SLOT* *NEW_AMMUNITION_VALUE* - Changes the ammunition value of an already existing slot 6 | !btmyslots - Displays a list of all slots you own. -------------------------------------------------------------------------------- /AmmunitionTracker/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "AmmunitionTracker", 3 | "version": ".6", 4 | "description": "A bunch of commands to track ammunition.", 5 | "authors": "Tristan Beard", 6 | "roll20userid": "268993", 7 | "dependencies": {}, 8 | "modifies": { 9 | }, 10 | "conflicts": [ 11 | "GMCode" 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /Animation/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Animation", 3 | "version": "0.4", 4 | "description": "Create and display animations.", 5 | "authors": "manveti", 6 | "roll20userid": "503018", 7 | "dependencies": {}, 8 | "modifies": {}, 9 | "conflicts": [] 10 | } 11 | -------------------------------------------------------------------------------- /AnnounceRoll/0.2.1/AnnounceRoll.js: -------------------------------------------------------------------------------- 1 | // Github: https://github.com/shdwjk/Roll20API/blob/master/AnnouncRoll/AnnouncRoll.js 2 | // By: The Aaron, Arcane Scriptomancer 3 | // Contact: https://app.roll20.net/users/104025/the-aaron 4 | 5 | var AnnounceRoll = AnnounceRoll || (function() { 6 | 'use strict'; 7 | 8 | var version = '0.2.1', 9 | lastUpdate = 1427604233, 10 | 11 | checkInstall = function() { 12 | log('-=> AnnounceRoll v'+version+' <=- ['+(new Date(lastUpdate*1000))+']'); 13 | }, 14 | handleInput = function(msg) { 15 | var rolldata,out=[]; 16 | 17 | if (msg.type !== "rollresult") { 18 | return; 19 | } 20 | 21 | rolldata = JSON.parse(msg.content); 22 | _.each(rolldata.rolls,function(r){ 23 | if('R' === r.type && 20 === r.sides) { 24 | _.each(r.results, function(roll){ 25 | switch(roll.v) { 26 | case 1: 27 | out.push('
Fumble!
'); 28 | break; 29 | case 20: 30 | out.push('
Critical!
'); 31 | break; 32 | } 33 | }); 34 | } 35 | }); 36 | if(out.length) { 37 | sendChat('',out.join('')); 38 | } 39 | 40 | }, 41 | 42 | registerEventHandlers = function() { 43 | on('chat:message', handleInput); 44 | }; 45 | 46 | return { 47 | CheckInstall: checkInstall, 48 | RegisterEventHandlers: registerEventHandlers 49 | }; 50 | 51 | }()); 52 | 53 | on('ready',function() { 54 | 'use strict'; 55 | 56 | AnnounceRoll.CheckInstall(); 57 | AnnounceRoll.RegisterEventHandlers(); 58 | }); 59 | 60 | -------------------------------------------------------------------------------- /AnnounceRoll/AnnounceRoll.js: -------------------------------------------------------------------------------- 1 | // Github: https://github.com/shdwjk/Roll20API/blob/master/AnnouncRoll/AnnouncRoll.js 2 | // By: The Aaron, Arcane Scriptomancer 3 | // Contact: https://app.roll20.net/users/104025/the-aaron 4 | 5 | var AnnounceRoll = AnnounceRoll || (function() { 6 | 'use strict'; 7 | 8 | var version = '0.2.1', 9 | lastUpdate = 1427604233, 10 | 11 | checkInstall = function() { 12 | log('-=> AnnounceRoll v'+version+' <=- ['+(new Date(lastUpdate*1000))+']'); 13 | }, 14 | handleInput = function(msg) { 15 | var rolldata,out=[]; 16 | 17 | if (msg.type !== "rollresult") { 18 | return; 19 | } 20 | 21 | rolldata = JSON.parse(msg.content); 22 | _.each(rolldata.rolls,function(r){ 23 | if('R' === r.type && 20 === r.sides) { 24 | _.each(r.results, function(roll){ 25 | switch(roll.v) { 26 | case 1: 27 | out.push('
Fumble!
'); 28 | break; 29 | case 20: 30 | out.push('
Critical!
'); 31 | break; 32 | } 33 | }); 34 | } 35 | }); 36 | if(out.length) { 37 | sendChat('',out.join('')); 38 | } 39 | 40 | }, 41 | 42 | registerEventHandlers = function() { 43 | on('chat:message', handleInput); 44 | }; 45 | 46 | return { 47 | CheckInstall: checkInstall, 48 | RegisterEventHandlers: registerEventHandlers 49 | }; 50 | 51 | }()); 52 | 53 | on('ready',function() { 54 | 'use strict'; 55 | 56 | AnnounceRoll.CheckInstall(); 57 | AnnounceRoll.RegisterEventHandlers(); 58 | }); 59 | 60 | -------------------------------------------------------------------------------- /AnnounceRoll/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "AnnounceRoll", 3 | "version": "0.2.1", 4 | "description": "Prints an extra announcement of a critical or fumble to the chat when using /roll", 5 | "authors": "The Aaron", 6 | "roll20userid": "104025", 7 | "patreon": "https://www.patreon.com/shdwjk", 8 | "dependencies": [], 9 | "modifies": [], 10 | "conflicts": [], 11 | "script": "AnnounceRoll.js", 12 | "useroptions": {}, 13 | "previousversions": [] 14 | } -------------------------------------------------------------------------------- /AreasOfEffect/demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlenser/roll20-api-scripts/65a254bd1d44764076cf808e6c50abc995ee6938/AreasOfEffect/demo.gif -------------------------------------------------------------------------------- /AreasOfEffect/sampleEffectGraphics/agniShine.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlenser/roll20-api-scripts/65a254bd1d44764076cf808e6c50abc995ee6938/AreasOfEffect/sampleEffectGraphics/agniShine.png -------------------------------------------------------------------------------- /AreasOfEffect/sampleEffectGraphics/icicleFall.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlenser/roll20-api-scripts/65a254bd1d44764076cf808e6c50abc995ee6938/AreasOfEffect/sampleEffectGraphics/icicleFall.png -------------------------------------------------------------------------------- /AreasOfEffect/sampleEffectGraphics/metalFatigue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlenser/roll20-api-scripts/65a254bd1d44764076cf808e6c50abc995ee6938/AreasOfEffect/sampleEffectGraphics/metalFatigue.png -------------------------------------------------------------------------------- /AreasOfEffect/sampleEffectGraphics/moonlightRay.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlenser/roll20-api-scripts/65a254bd1d44764076cf808e6c50abc995ee6938/AreasOfEffect/sampleEffectGraphics/moonlightRay.png -------------------------------------------------------------------------------- /AreasOfEffect/sampleEffectGraphics/princessUndine.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlenser/roll20-api-scripts/65a254bd1d44764076cf808e6c50abc995ee6938/AreasOfEffect/sampleEffectGraphics/princessUndine.png -------------------------------------------------------------------------------- /AreasOfEffect/sampleEffectGraphics/rageTrilithon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlenser/roll20-api-scripts/65a254bd1d44764076cf808e6c50abc995ee6938/AreasOfEffect/sampleEffectGraphics/rageTrilithon.png -------------------------------------------------------------------------------- /AreasOfEffect/sampleEffectGraphics/rainbowWindchime.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlenser/roll20-api-scripts/65a254bd1d44764076cf808e6c50abc995ee6938/AreasOfEffect/sampleEffectGraphics/rainbowWindchime.png -------------------------------------------------------------------------------- /AreasOfEffect/sampleEffectGraphics/sylphaeHorn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlenser/roll20-api-scripts/65a254bd1d44764076cf808e6c50abc995ee6938/AreasOfEffect/sampleEffectGraphics/sylphaeHorn.png -------------------------------------------------------------------------------- /ArsMagica5eStressDie/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Ars Magica 5e--Automated Stress Die", 3 | "script": "ArsMagica5eStressDie.js", 4 | "version": "1.0", 5 | "previousversions": [], 6 | "description": "This allows players to enter '!st ' or '!st , ' (_nomod version: !st or !st ) to roll a stress die with modifier and optional botch dice count . Botch dice count defaults to 1 when used with one argument. The _nomod version is designed for users who want to add their modifier separately. Multiple botches are possible, and will be reported in the case of a botch. Note that a result of 1 in the code corresponds to a result of zero in the text, and a 10 in the code is a 1 described in the corebook's text. This does not bias results, as both are special cases. Only results of 2-9 actually keep their numeric value. A macro for a stress die--modified or otherwise--can be easily made with syntax similar to !st ?{Modifier|0}, ?{Botch Dice|1}", 7 | "authors": "Chris Lankford", 8 | "roll20userid": "390978", 9 | "useroptions": [ 10 | { 11 | "name": "Modifier", 12 | "type": "integer (as char)", 13 | "default": "", 14 | "description": "The basic version (as opposed to the _nomod version) of this script uses a modifier as the first input, and is required." 15 | }, 16 | { 17 | "name": "Botch dice count", 18 | "type": "nonnegative integer (as char)", 19 | "default": "1", 20 | "description": "This optional argument, which can be used with either the original or _nomod versions, determines the number of botch dice to roll when a critical failure is possible. Increasing this value increases the possibility and potential severity of critical failure." 21 | } 22 | ], 23 | "dependencies": ["Math"], 24 | "modifies": { 25 | "": "" 26 | }, 27 | "conflicts": ["The two versions (standard and _nomod) conflict with each other."] 28 | } -------------------------------------------------------------------------------- /AutoFacing/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "AutoFacing", 3 | "version": "1.0.0", 4 | "description": "Automatically rotates tokens based on last movement.", 5 | "authors": "Kevin Kragenbrink ", 6 | "roll20userid": "15313", 7 | "dependencies": { }, 8 | "modifies": { 9 | "graphic.left" : "read", 10 | "graphic.top" : "read", 11 | "graphic.layer" : "read", 12 | "graphic.lastmove" : "read", 13 | "graphic.rotation" : "write" 14 | }, 15 | "conflicts": [ ] 16 | } 17 | -------------------------------------------------------------------------------- /Base64/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Base64", 3 | "version": "0.3.1", 4 | "description": "Base 64 encoding for Roll20 Scripts. (Adapted from http://www.webtoolkit.info/ )", 5 | "authors": "The Aaron", 6 | "roll20userid": "104025", 7 | "patreon": "https://www.patreon.com/shdwjk", 8 | "dependencies": [], 9 | "modifies": [], 10 | "conflicts": [], 11 | "script": "Base64.js", 12 | "useroptions": {}, 13 | "previousversions": [] 14 | } -------------------------------------------------------------------------------- /BashDice/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "BashDice", 3 | "version": "0.2.1", 4 | "description": "Rolls the Bash UE Dice format with exploding.", 5 | "authors": "The Aaron", 6 | "roll20userid": "104025", 7 | "patreon": "https://www.patreon.com/shdwjk", 8 | "dependencies": [], 9 | "modifies": [], 10 | "conflicts": [], 11 | "script": "BashDice.js", 12 | "useroptions": {}, 13 | "previousversions": [] 14 | } -------------------------------------------------------------------------------- /Bet/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Bet", 3 | "version": "0.1.3", 4 | "description": "", 5 | "authors": "The Aaron", 6 | "roll20userid": "104025", 7 | "patreon": "https://www.patreon.com/shdwjk", 8 | "dependencies": {}, 9 | "modifies": { 10 | "state.Bet": "read,write" 11 | }, 12 | "conflicts": [], 13 | "script": "Bet.js", 14 | "useroptions": {}, 15 | "previousversions": [] 16 | } -------------------------------------------------------------------------------- /Blood-and-Honor/help.txt: -------------------------------------------------------------------------------- 1 | ## Blood and Honor 2 | 3 | Putting "noblood" in any token's GM Notes will cause it to never bleed. 4 | Use !clearblood and all blood will move to the top left corner of the map for convenient removal. 5 | There are currently three custom colors, but you can easily add your own in the script. Put one of the following into the GM Notes if you want the token to bleed a color other than red: 6 | bloodcolor_orange, bloodcolor_purple, bloodcolor_blue 7 | -------------------------------------------------------------------------------- /Blood-and-Honor/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Blood and Honor", 3 | "version": "0.8.2", 4 | "description": "Automatic blood spatter, pooling and trail effects.", 5 | "authors": "John C.", 6 | "roll20userid": "242509", 7 | "dependencies": { 8 | }, 9 | "modifies": { 10 | "bar3_value": "read", 11 | "bar3_max": "read", 12 | "left": "read", 13 | "top": "read", 14 | "gmnotes": "read", 15 | "_pageid": "read", 16 | "type": "read" 17 | }, 18 | "conflicts": [ 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /Bloodied and Dead Status Markers/Bloodied and Dead Status Markers.js: -------------------------------------------------------------------------------- 1 | on("change:graphic", function(obj) { 2 | if(obj.get("bar1_max") === "") return; 3 | 4 | if(obj.get("bar1_value") <= obj.get("bar1_max") / 2) { 5 | obj.set({ 6 | status_redmarker: true 7 | }); 8 | } 9 | else{ 10 | obj.set({ 11 | status_redmarker: false 12 | }) 13 | } 14 | 15 | if(obj.get("bar1_value") <= 0) { 16 | obj.set({ 17 | status_dead: true 18 | }); 19 | } 20 | else { 21 | obj.set({ 22 | status_dead: false 23 | }); 24 | } 25 | }); -------------------------------------------------------------------------------- /Bloodied and Dead Status Markers/Help.txt: -------------------------------------------------------------------------------- 1 | Bloodied and Dead Status Markers (Contributed by Ken Bauer) 2 | This script automatically adds the Red marker to represent the "bloodied" state for any tokens that drop below half their health, and the "dead" marker for any that drop to 0 or less. It's assumed that health is stored in Bar 1. -------------------------------------------------------------------------------- /Bloodied and Dead Status Markers/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Bloodied and Dead Status Markers", 3 | "version": "1.1", 4 | "description": "This script automatically adds the Red marker to represent the 'bloodied' state for any tokens that drop below half their health, and the 'dead' marker for any that drop to 0 or less. It's assumed that health is stored in Bar 1.", 5 | "authors": "Ken Bauer", 6 | "roll20userid": "370591", 7 | "dependencies": {}, 8 | "modifies": { 9 | "bar1_value": "read", 10 | "bar1_max": "read", 11 | "status_redmarker": "write", 12 | "status_dead": "write" 13 | }, 14 | "conflicts": [ 15 | "Blood and Honor" 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /BounceTokens/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "BounceTokens", 3 | "version": "0.1.0", 4 | "description": "Allows the GM to toggle bouncing of selected tokens.", 5 | "authors": "The Aaron", 6 | "roll20userid": "104025", 7 | "patreon": "https://www.patreon.com/shdwjk", 8 | "dependencies": [], 9 | "modifies": { 10 | "state.BounceTokens": "read,write", 11 | "campaign.playerpageid": "read", 12 | "campaign.playerspecificpages": "read", 13 | "graphic.pageid": "read", 14 | "graphic.rotation": "write", 15 | "graphic.subtype": "read" 16 | }, 17 | "conflicts": [], 18 | "script": "BounceTokens.js", 19 | "useroptions": [], 20 | "previousversions": [] 21 | } -------------------------------------------------------------------------------- /ChangeTokenImage/README.md: -------------------------------------------------------------------------------- 1 | !change-token-img --help to display the help 2 | 3 | New script to change a token's image when token uses a rollable table, when Gm want to select and change tokens already on the map. 4 | Discussion here: https://app.roll20.net/forum/post/2576603/script-change-token-image-from-rolltable 5 | -------------------------------------------------------------------------------- /ChangeTokenImage/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ChangeTokenImage", 3 | "version": "0.1.20", 4 | "description": "Interface to change token images from a rollable table.", 5 | "authors": "Chris B,Aaron", 6 | "roll20userid": "144324", 7 | "dependencies": [], 8 | "modifies": { 9 | "state.ChangeTokenImage": "read,write", 10 | "attribute.characterid": "read", 11 | "attribute.sides": "read", 12 | "attribute.currentSide": "read,write", 13 | "attribute.imgsrc": "write", 14 | "character.name": "read", 15 | "graphic.*": "read,write" 16 | }, 17 | "conflicts": [] 18 | } 19 | -------------------------------------------------------------------------------- /CharUtils/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "CharUtils", 3 | "version": "0.6.4", 4 | "description": "", 5 | "authors": "The Aaron", 6 | "roll20userid": "104025", 7 | "patreon": "https://www.patreon.com/shdwjk", 8 | "dependencies": {}, 9 | "modifies": { 10 | "abilities": "create,delete" 11 | }, 12 | "conflicts": [], 13 | "script": "CharUtils.js", 14 | "useroptions": {}, 15 | "previousversions": [] 16 | } -------------------------------------------------------------------------------- /Charsheet/1.2/charsheet.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Generates a blank character sheet. 3 | * The default is to make it viewable to all but editable by the person calling the script. 4 | * 5 | * Syntax: !charsheet 6 | */ 7 | 8 | var Charsheet = Charsheet || {}; 9 | 10 | on('chat:message', function(msg) { 11 | // Exit if not an api command 12 | if (msg.type != "api") { 13 | return; 14 | } 15 | 16 | if (msg.content.indexOf('!charsheet') != -1) { 17 | Charsheet.Generate(msg); 18 | } 19 | }); 20 | 21 | Charsheet.Generate = function(msg) { 22 | var player = msg.who; 23 | var character_name = msg.who+Date.now(); 24 | 25 | var character = createObj('character', { 26 | name: 'Blank_Character', 27 | gmnotes: 'Player: '+player+'
Generated by script Charsheet.js', 28 | archived: false, 29 | inplayerjournals: 'all', 30 | controlledby: msg.playerid 31 | }); 32 | 33 | /* Create attributes */ 34 | createObj('attribute', { 35 | name: 'player_name', 36 | current: player, 37 | _characterid: character.id 38 | }); 39 | createObj('attribute', { 40 | name: 'name', 41 | current: character_name, 42 | _characterid: character.id 43 | }) 44 | 45 | sendChat(player, "/me created a character named \""+character_name+"\"!"); 46 | }; 47 | 48 | if (!Date.now) { 49 | Date.now = function now() { 50 | return new Date().getTime(); 51 | }; 52 | } 53 | -------------------------------------------------------------------------------- /Charsheet/README.md: -------------------------------------------------------------------------------- 1 | # charsheet 2 | Simple Roll20 character sheet creator 3 | Syntax: !charsheet -------------------------------------------------------------------------------- /Charsheet/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "CharacterSheet", 3 | "script": "charsheet.js", 4 | "version": "1.2", 5 | "previousversions": [""], 6 | "description": "A simple script to allow players to create their own character sheets. Using the command '!charsheet' will generate a character sheet controlled by the user that runs the command and visible in the journal to all players named 'Blank_Character'.", 7 | "authors": "Base code by: GitHub user 'kevinsearle', Minor feature improvement and 1-click compatibility by: TECH", 8 | "roll20userid": "446206", 9 | "useroptions": [], 10 | "dependencies": [], 11 | "modifies": {}, 12 | "conflicts": [] 13 | } -------------------------------------------------------------------------------- /CleanAbilities/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "CleanAbilities", 3 | "version": "0.1.1", 4 | "description": "Removes all the abilities of the character represented by the selected tokens.", 5 | "authors": "The Aaron", 6 | "roll20userid": "104025", 7 | "patreon": "https://www.patreon.com/shdwjk", 8 | "dependencies": {}, 9 | "modifies": { 10 | "state.CleanAbilities": "read,write", 11 | "ability": "remove", 12 | "token.represents": "read" 13 | }, 14 | "conflicts": [], 15 | "script": "CleanAbilities.js", 16 | "useroptions": {}, 17 | "previousversions": [] 18 | } -------------------------------------------------------------------------------- /Collision Detection/README.md: -------------------------------------------------------------------------------- 1 | ## Collision Detection 2 | 3 | There are three configuration options available to you: 4 | 5 | * `Path Color`: The script only considers paths of a specific color, allowing you to also use paths of other colors which your players will not collide with. By default, this is fuchsia (#ff00ff); the color is specified as a hexadecimal web color, which you can see when selecting a color from the drawing interface. A path's fill color is ignored. 6 | * `Layer`: The script will only look at paths on the specified layer (valid values are "map", "objects", "gmlayer", or "walls"). You can also set this value to "all" and paths on every layer will be considered. 7 | * `Behavior`: You can customize the script's behavior when a collision event is detected. 8 | 9 | ### Usage Notes 10 | 11 | Currently, this script **only** considers **polygons and polylines** as "walls" to collide with, which means no freehand drawings or circles/ovals. Additionally, the math in the script does not handle paths which have been resized or rotated. 12 | 13 | Tokens which can only be moved by the GM (no player is assigned to control it, and the token isn't linked to a character sheet which is assigned to any player) do not collide with walls. This will let the GM move things around at will. However, if the GM is assigned as the controlling player for a token, or if the token is linked to a character sheet which has the GM assigned as the controlling player, the token will collide with the walls. 14 | 15 | The script will break if you go "warp speed" by holding down an arrow key to move, and the token passes through multiple walls before the script catches up. (If you drag a token through multiple walls, the script will collide at the first one.) 16 | 17 | In most cases, the dynamic lighting will not update before the token's position is reset to the correct side of the wall (assuming a relevant behavior is set), meaning the player won't see what's on the other side (if the wall is on the DL layer or there's a similarly-positioned wall on the DL layer). However, sometimes the DL will update first, and the player will catch a glimpse of the other side. -------------------------------------------------------------------------------- /ColorEmote/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ColorEmote", 3 | "version": "0.1.3", 4 | "description": "", 5 | "authors": "The Aaron", 6 | "roll20userid": "104025", 7 | "patreon": "https://www.patreon.com/shdwjk", 8 | "dependencies": {}, 9 | "modifies": { 10 | "state.ColorEmote": "read,write" 11 | }, 12 | "conflicts": [], 13 | "script": "ColorEmote.js", 14 | "useroptions": {}, 15 | "previousversions": [] 16 | } -------------------------------------------------------------------------------- /ColorNote/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ColorNote", 3 | "version": "0.2.1", 4 | "description": "", 5 | "authors": "The Aaron", 6 | "roll20userid": "104025", 7 | "patreon": "https://www.patreon.com/shdwjk", 8 | "dependencies": {}, 9 | "modifies": { 10 | "state.ColorNote": "read,write", 11 | "player.displayname": "read", 12 | "player.color": "read" 13 | }, 14 | "conflicts": [], 15 | "script": "ColorNote.js", 16 | "useroptions": {}, 17 | "previousversions": [] 18 | } -------------------------------------------------------------------------------- /CommandShell/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "CommandShell", 3 | "version": "1.3", 4 | "description": "Framework for chat commands", 5 | "authors": "manveti", 6 | "roll20userid": "503018", 7 | "dependencies": {}, 8 | "modifies": {}, 9 | "conflicts": [] 10 | } 11 | -------------------------------------------------------------------------------- /Conditions/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Conditions", 3 | "version": "0.6", 4 | "description": "Track attribute-modifying conditions.", 5 | "authors": "manveti", 6 | "roll20userid": "503018", 7 | "dependencies": {}, 8 | "modifies": {}, 9 | "conflicts": [] 10 | } 11 | -------------------------------------------------------------------------------- /CthulhuTechDice/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "CthulhuTechDice", 3 | "version": "0.1.12", 4 | "description": "", 5 | "authors": "The Aaron", 6 | "roll20userid": "104025", 7 | "patreon": "https://www.patreon.com/shdwjk", 8 | "dependencies": {}, 9 | "modifies": { 10 | "state.CthulhutechDice": "read,write" 11 | }, 12 | "conflicts": [], 13 | "script": "CthulhuTechDice.js", 14 | "useroptions": {}, 15 | "previousversions": [] 16 | } -------------------------------------------------------------------------------- /Custom FX/README.md: -------------------------------------------------------------------------------- 1 | ## Custom FX 2 | 3 | ### Commands 4 | * !createfx <_name_> [_properties_] 5 | * !previewfx [_properties_] 6 | * !savepreview <_name_> 7 | * !endpreview 8 | 9 | `!createfx` will create an FX object directly. You must supply a name. All properties are optional (default values will be used for any not specified), and may be labeled or not. Labeled properties take the form *propertyName:propertyValue*, and the names are case-sentitive. Unlabeled properties will be consumed in order: 10 | 11 | * angle 12 | * angleRandom 13 | * duration 14 | * emissionRate 15 | * endColour 16 | * endColourRandom 17 | * gravity 18 | * lifeSpan 19 | * lifeSpanRandom 20 | * maxParticles 21 | * size 22 | * sizeRandom 23 | * speed 24 | * speedRandom 25 | * startColour 26 | * startColourRandom 27 | 28 | The four color properties must be specified as an arracy of four values: `[red, green, blue, alpha]`. The first three should each be an integer in the range 0-255, and the last should be a number in the range 0-1. 29 | 30 | `gravity` must be specified as an object in the form `{ x: num, y: num }`. The spaces are optional, and the x/y can swap their order. 31 | 32 | Any properties with spaces must be enclosed in quotes. `gravity:"{ x: 5, y: 6}"`, `"gravity:{ x: 5, y: 6 }"`, and `gravity:{x:5,y:6}` are all valid. 33 | 34 | `!previewfx` takes the same property parameters as `!createfx`, but instead of immediately creating the FX object, it spawns a looping FX animation on the map, which you can change with additional calls to `!previewfx`. You can stop the animation with `!endpreview` (however, your saved properties will not be erased), and you can save the FX with `!savepreview`, which will erase your preview properties and create an FX object with the same values. -------------------------------------------------------------------------------- /Custom FX/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Custom FX", 3 | "script": "Custom FX.js", 4 | "version": "0.1", 5 | "previousversions": [], 6 | "description": "Enables the creation and previewing of FX objects. `!createfx` will create an FX object directly, while `!previewfx` will allow you to build an FX object incrementally, seeing the changes to the effect live. Use `!savepreview` to save the FX being built, and `!endpreview` to stop displaying it. (Ending the preview will not erase the saved properties for the preview object, however.) See `!help` for more detailed information.", 7 | "authors": "Brian Shields", 8 | "roll20userid": "235259", 9 | "patreon": "https://www.patreon.com/bshields", 10 | "useroptions": [], 11 | "dependencies": ["splitArgs"], 12 | "modifies": { 13 | "Campaign.playerpageid": "read", 14 | "graphic.left": "read", 15 | "graphic.top": "read", 16 | "path.top": "read,write", 17 | "path.left": "read,write", 18 | "path.rotation": "read,write", 19 | "path.width": "read,write", 20 | "path.height": "read,write", 21 | "path.scaleX": "read,write", 22 | "path.scaleY": "read,write", 23 | "state.bshields.customfx": "read,write" 24 | }, 25 | "conflicts": [] 26 | } 27 | -------------------------------------------------------------------------------- /CustomStatusMarkers/demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlenser/roll20-api-scripts/65a254bd1d44764076cf808e6c50abc995ee6938/CustomStatusMarkers/demo.gif -------------------------------------------------------------------------------- /CustomStatusMarkers/icons/statusBerserk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlenser/roll20-api-scripts/65a254bd1d44764076cf808e6c50abc995ee6938/CustomStatusMarkers/icons/statusBerserk.png -------------------------------------------------------------------------------- /CustomStatusMarkers/icons/statusBrain.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlenser/roll20-api-scripts/65a254bd1d44764076cf808e6c50abc995ee6938/CustomStatusMarkers/icons/statusBrain.png -------------------------------------------------------------------------------- /CustomStatusMarkers/icons/statusCripppled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlenser/roll20-api-scripts/65a254bd1d44764076cf808e6c50abc995ee6938/CustomStatusMarkers/icons/statusCripppled.png -------------------------------------------------------------------------------- /CustomStatusMarkers/icons/statusDisease.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlenser/roll20-api-scripts/65a254bd1d44764076cf808e6c50abc995ee6938/CustomStatusMarkers/icons/statusDisease.png -------------------------------------------------------------------------------- /CustomStatusMarkers/icons/statusDrug.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlenser/roll20-api-scripts/65a254bd1d44764076cf808e6c50abc995ee6938/CustomStatusMarkers/icons/statusDrug.png -------------------------------------------------------------------------------- /CustomStatusMarkers/icons/statusHaste.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlenser/roll20-api-scripts/65a254bd1d44764076cf808e6c50abc995ee6938/CustomStatusMarkers/icons/statusHaste.png -------------------------------------------------------------------------------- /CustomStatusMarkers/icons/statusImmobilize.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlenser/roll20-api-scripts/65a254bd1d44764076cf808e6c50abc995ee6938/CustomStatusMarkers/icons/statusImmobilize.png -------------------------------------------------------------------------------- /CustomStatusMarkers/icons/statusSilence.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlenser/roll20-api-scripts/65a254bd1d44764076cf808e6c50abc995ee6938/CustomStatusMarkers/icons/statusSilence.png -------------------------------------------------------------------------------- /CustomStatusMarkers/icons/statusSleep.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlenser/roll20-api-scripts/65a254bd1d44764076cf808e6c50abc995ee6938/CustomStatusMarkers/icons/statusSleep.png -------------------------------------------------------------------------------- /CustomStatusMarkers/icons/statusSlow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlenser/roll20-api-scripts/65a254bd1d44764076cf808e6c50abc995ee6938/CustomStatusMarkers/icons/statusSlow.png -------------------------------------------------------------------------------- /CustomStatusMarkers/icons/statusStars.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlenser/roll20-api-scripts/65a254bd1d44764076cf808e6c50abc995ee6938/CustomStatusMarkers/icons/statusStars.png -------------------------------------------------------------------------------- /CustomStatusMarkers/icons/statusStun.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlenser/roll20-api-scripts/65a254bd1d44764076cf808e6c50abc995ee6938/CustomStatusMarkers/icons/statusStun.png -------------------------------------------------------------------------------- /CustomStatusMarkers/icons/statusTrueSight.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlenser/roll20-api-scripts/65a254bd1d44764076cf808e6c50abc995ee6938/CustomStatusMarkers/icons/statusTrueSight.png -------------------------------------------------------------------------------- /CypherSystemSheet/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Cypher System Sheet", 3 | "script": "cyphersystemsheet.js", 4 | "previousversions" : [], 5 | "version": "1.2", 6 | "description": "Enables the applying of stat cost, recovery roll advance, auto calculation of PC state and damage track in the Cypher System Sheet, from the roll template, sheet buttons and/or macros. Read the [Wiki page](https://wiki.roll20.net/Script:Cypher_System_Sheet) for help about chat commands and macros.", 7 | "authors": "Natha", 8 | "roll20userid": "75857", 9 | "useroptions": [], 10 | "dependencies": {}, 11 | "modifies": { 12 | "token": "write", 13 | "bar1_value": "write", 14 | "bar2_value": "write", 15 | "bar3_value": "write", 16 | "character": "write" 17 | }, 18 | "conflicts": ["Natha's Numenera"] 19 | } 20 | -------------------------------------------------------------------------------- /DarknessClosingIn/0.2.1/DarknessClosingIn.js: -------------------------------------------------------------------------------- 1 | // Github: https://github.com/shdwjk/Roll20API/blob/master/DarknessClosingIn/DarknessClosingIn.js 2 | // By: The Aaron, Arcane Scriptomancer 3 | // Contact: https://app.roll20.net/users/104025/the-aaron 4 | 5 | var DarknessClosingIn = DarknessClosingIn || (function() { 6 | 'use strict'; 7 | 8 | var version = '0.2.1', 9 | lastUpdate = 1427604242, 10 | schemaVersion = 0.1, 11 | 12 | checkInstall = function() { 13 | log('-=> DarknessClosingIn v'+version+' <=- ['+(new Date(lastUpdate*1000))+']'); 14 | 15 | if( ! _.has(state,'DarknessClosingIn') || state.DarknessClosingIn.version !== schemaVersion) { 16 | log(' > Updating Schema to v'+schemaVersion+' <'); 17 | state.DarknessClosingIn = { 18 | version: schemaVersion, 19 | gettingDarker: false 20 | }; 21 | } 22 | }, 23 | 24 | handleInput = function(msg) { 25 | var args; 26 | 27 | if (msg.type !== "api" || ! playerIsGM(msg.playerid) ) { 28 | return; 29 | } 30 | 31 | args = msg.content.split(/\s+/); 32 | switch(args[0]) { 33 | case '!DarknessClosingIn': 34 | state.DarknessClosingIn.gettingDarker = ! state.DarknessClosingIn.gettingDarker; 35 | sendChat('','/w gm ' + ( state.DarknessClosingIn.gettingDarker ? 'Darkness is now closing in.' : 'Darkness is no longer closing in.' ) ); 36 | break; 37 | } 38 | }, 39 | 40 | gettingDarker = function(obj, prev) { 41 | if( state.DarknessClosingIn.gettingDarker 42 | && ( 43 | obj.get("left") !== prev.left 44 | || obj.get("top") !== prev.top 45 | ) 46 | ) { 47 | obj.set({ 48 | light_radius: Math.floor(obj.get("light_radius") * 0.90) 49 | }); 50 | } 51 | }, 52 | 53 | 54 | registerEventHandlers = function() { 55 | on('chat:message', handleInput); 56 | on("change:token", gettingDarker); 57 | }; 58 | 59 | return { 60 | CheckInstall: checkInstall, 61 | RegisterEventHandlers: registerEventHandlers 62 | }; 63 | 64 | }()); 65 | 66 | on('ready',function() { 67 | 'use strict'; 68 | 69 | DarknessClosingIn.CheckInstall(); 70 | DarknessClosingIn.RegisterEventHandlers(); 71 | }); 72 | -------------------------------------------------------------------------------- /DarknessClosingIn/DarknessClosingIn.js: -------------------------------------------------------------------------------- 1 | // Github: https://github.com/shdwjk/Roll20API/blob/master/DarknessClosingIn/DarknessClosingIn.js 2 | // By: The Aaron, Arcane Scriptomancer 3 | // Contact: https://app.roll20.net/users/104025/the-aaron 4 | 5 | var DarknessClosingIn = DarknessClosingIn || (function() { 6 | 'use strict'; 7 | 8 | var version = '0.2.1', 9 | lastUpdate = 1427604242, 10 | schemaVersion = 0.1, 11 | 12 | checkInstall = function() { 13 | log('-=> DarknessClosingIn v'+version+' <=- ['+(new Date(lastUpdate*1000))+']'); 14 | 15 | if( ! _.has(state,'DarknessClosingIn') || state.DarknessClosingIn.version !== schemaVersion) { 16 | log(' > Updating Schema to v'+schemaVersion+' <'); 17 | state.DarknessClosingIn = { 18 | version: schemaVersion, 19 | gettingDarker: false 20 | }; 21 | } 22 | }, 23 | 24 | handleInput = function(msg) { 25 | var args; 26 | 27 | if (msg.type !== "api" || ! playerIsGM(msg.playerid) ) { 28 | return; 29 | } 30 | 31 | args = msg.content.split(/\s+/); 32 | switch(args[0]) { 33 | case '!DarknessClosingIn': 34 | state.DarknessClosingIn.gettingDarker = ! state.DarknessClosingIn.gettingDarker; 35 | sendChat('','/w gm ' + ( state.DarknessClosingIn.gettingDarker ? 'Darkness is now closing in.' : 'Darkness is no longer closing in.' ) ); 36 | break; 37 | } 38 | }, 39 | 40 | gettingDarker = function(obj, prev) { 41 | if( state.DarknessClosingIn.gettingDarker 42 | && ( 43 | obj.get("left") !== prev.left 44 | || obj.get("top") !== prev.top 45 | ) 46 | ) { 47 | obj.set({ 48 | light_radius: Math.floor(obj.get("light_radius") * 0.90) 49 | }); 50 | } 51 | }, 52 | 53 | 54 | registerEventHandlers = function() { 55 | on('chat:message', handleInput); 56 | on("change:token", gettingDarker); 57 | }; 58 | 59 | return { 60 | CheckInstall: checkInstall, 61 | RegisterEventHandlers: registerEventHandlers 62 | }; 63 | 64 | }()); 65 | 66 | on('ready',function() { 67 | 'use strict'; 68 | 69 | DarknessClosingIn.CheckInstall(); 70 | DarknessClosingIn.RegisterEventHandlers(); 71 | }); 72 | -------------------------------------------------------------------------------- /DarknessClosingIn/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "DarknessClosingIn", 3 | "version": "0.2.1", 4 | "description": "A command wrapped version of the Darkness Closing In API sample script.", 5 | "authors": "The Aaron", 6 | "roll20userid": "104025", 7 | "patreon": "https://www.patreon.com/shdwjk", 8 | "dependencies": [], 9 | "modifies": { 10 | "state.DarknessClosingIn": "read,write", 11 | "graphic.left": "read", 12 | "graphic.light_radius": "read,write", 13 | "graphic.top": "read" 14 | }, 15 | "conflicts": [], 16 | "script": "DarknessClosingIn.js", 17 | "useroptions": {}, 18 | "previousversions": [] 19 | } -------------------------------------------------------------------------------- /DiceInTheVineyard/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "DiceInTheVineyard", 3 | "version": "0.1", 4 | "description": "Dice tracker for Dogs in the Vineyard. Stacks poker-chip-styled roll tokens in defined areas for characters to spend.", 5 | "authors": "manveti", 6 | "roll20userid": "503018", 7 | "dependencies": {}, 8 | "modifies": {}, 9 | "conflicts": [] 10 | } 11 | -------------------------------------------------------------------------------- /DryErase/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "DryErase", 3 | "version": "0.1.6", 4 | "description": "", 5 | "authors": "The Aaron", 6 | "roll20userid": "104025", 7 | "patreon": "https://www.patreon.com/shdwjk", 8 | "dependencies": {}, 9 | "modifies": { 10 | "state.DryErase": "read,write", 11 | "graphics": "create,remove", 12 | "graphics.width": "read,write", 13 | "graphics.height": "read,write", 14 | "graphics.top": "read,write", 15 | "graphics.left": "read,write", 16 | "path": "create,remove", 17 | "path.width": "read,write", 18 | "path.height": "read,write", 19 | "path.top": "read,write", 20 | "path.left": "read,write", 21 | "path.layer": "read,write" 22 | }, 23 | "conflicts": [], 24 | "script": "DryErase.js", 25 | "useroptions": {}, 26 | "previousversions": [] 27 | } -------------------------------------------------------------------------------- /DungeonUtils/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "DungeonUtils", 3 | "version": "1.0.0", 4 | "description": "A few handy functions for building maps quickly, including a random dungeon generator", 5 | "authors": "Alex Babis", 6 | "roll20userid": "518146", 7 | "keywords": [], 8 | "dependencies": [], 9 | "modifies": {}, 10 | "conflicts": [] 11 | } 12 | -------------------------------------------------------------------------------- /Dynamic Lighting Animation/README.md: -------------------------------------------------------------------------------- 1 | ## Dynamic Lighting Animation 2 | 3 | ### Commands 4 | * !snapshot _frames_ 5 | * !reset 6 | * !run 7 | * !stop 8 | 9 | You can record animation frames with `!snapshot`: set up the Dynamic Lighting as you like it, then use `!snapshot` along with the number of frames to hold that position. The animation runs as 20fps, so `!snapshot 20` will hold the position for 1s. 10 | 11 | `!reset` clears the animation buffer, and the commands `!run` and `!stop` predictably play or halt the animation. You cannot snapshot new positions while the animation is running. This script only stores a single animation, so you need to clear it before creating another one. 12 | 13 | Each snapshot only looks at the Dynamic Lighting paths on the page that currently has the player bookmark ribbon. -------------------------------------------------------------------------------- /Dynamic Lighting Animation/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Dynamic Lighting Animation", 3 | "script": "Dynamic Lighting Animation.js", 4 | "version": "2.3", 5 | "previousversions": ["2.2","2.1","2.0","1.0"], 6 | "description": "Animates paths on the Dynamic Lighting layer like a stop-motion video.", 7 | "authors": "Brian Shields", 8 | "roll20userid": "235259", 9 | "patreon": "https://www.patreon.com/bshields", 10 | "useroptions": [], 11 | "dependencies": ["splitArgs"], 12 | "modifies": { 13 | "Campaign.playerpageid": "read", 14 | "player.displayname": "read", 15 | "path.id": "read", 16 | "path.top": "read,write", 17 | "path.left": "read,write", 18 | "path.rotation": "read,write", 19 | "path.width": "read,write", 20 | "path.height": "read,write", 21 | "path.scaleX": "read,write", 22 | "path.scaleY": "read,write", 23 | "state.bshields.animation": "read,write" 24 | }, 25 | "conflicts": ["Store Commands"] 26 | } 27 | -------------------------------------------------------------------------------- /DynamicLightRecorder/.gitignore: -------------------------------------------------------------------------------- 1 | *.swp 2 | -------------------------------------------------------------------------------- /DynamicLightRecorder/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Dynamic Light Recorder", 3 | "script":"DynamicLightRecorder.js", 4 | "version": "1.0.1", 5 | "description": "Records dynamic lighting paths for map tiles & automatically recreates them when new tiles are placed.", 6 | "authors": "Lucian Holland", 7 | "roll20userid": "791452", 8 | "dependencies": [], 9 | "modifies": { 10 | "state.DynamicLightRecorder": "read,write", 11 | "graphic.*": "read,write", 12 | "path.*": "read,write" 13 | }, 14 | "conflicts":[] 15 | } 16 | -------------------------------------------------------------------------------- /EasyExperience/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "EasyExperience", 3 | "script": "EasyExperience.js", 4 | "version": "1.04", 5 | "previousversions": ["1.03","1.02","1.01","1.0","0.4"], 6 | "description": "Make awarding experience simple. Use !xp help to pull up the help menu for complete details.", 7 | "authors": "Scott C.", 8 | "roll20userid": "459831", 9 | "useroptions": [], 10 | "dependencies": [], 11 | "modifies": { 12 | "state.EASYEXPERIENCE": "read,write", 13 | "attribute.id": "read,write", 14 | "attribute": "read,write", 15 | "character": "read,write" 16 | }, 17 | "conflicts": [] 18 | } 19 | -------------------------------------------------------------------------------- /Emas/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "emas", 3 | "version": "0.8.1", 4 | "description": "Provides player !emas and !as commands.", 5 | "authors": "The Aaron", 6 | "roll20userid": "104025", 7 | "patreon": "https://www.patreon.com/shdwjk", 8 | "dependencies": [], 9 | "modifies": [], 10 | "conflicts": [], 11 | "script": "Emas.js", 12 | "useroptions": {}, 13 | "previousversions": [] 14 | } -------------------------------------------------------------------------------- /Escalation/0.2.1/Escalation.js: -------------------------------------------------------------------------------- 1 | // Github: https://github.com/shdwjk/Roll20API/blob/master/Escalation/Escalation.js 2 | // By: The Aaron, Arcane Scriptomancer 3 | // Contact: https://app.roll20.net/users/104025/the-aaron 4 | 5 | var Escalation = Escalation || (function() { 6 | 'use strict'; 7 | 8 | var version = '0.2.1', 9 | lastUpdate = 1427604246, 10 | dieName = 'Escalation Die', 11 | dieMax = 6, 12 | 13 | checkInstall = function() { 14 | log('-=> Escalation v'+version+' <=- ['+(new Date(lastUpdate*1000))+']'); 15 | 16 | if( "" === Campaign().get('turnorder')) { 17 | Campaign().set({turnorder: '[]'}); 18 | } 19 | handleEscalationDieReset(Campaign(),{}); 20 | }, 21 | 22 | handleEscalationDieReset = function(obj, prev) { 23 | var to=JSON.parse(obj.get('turnorder')), 24 | loc=_.find(to,function(e){ 25 | return dieName === e.custom; 26 | }); 27 | 28 | if(loc) { 29 | if(!obj.get('initiativepage')) { 30 | loc.pr=0; 31 | loc.forumla='+1'; 32 | } else if (dieMax !== loc.pr && '' === loc.formula) { 33 | loc.formula='+1'; 34 | } 35 | } else { 36 | to = _.union([{ 37 | id: '-1', 38 | pr: 0, 39 | custom: dieName, 40 | formula: '+1'}], to); 41 | } 42 | obj.set({turnorder: JSON.stringify(to)}); 43 | }, 44 | 45 | 46 | handleEscalationDieTurn = function(obj, prev) { 47 | var to,lastto; 48 | handleEscalationDieReset(obj,prev); 49 | 50 | to=JSON.parse(obj.get('turnorder')) || []; 51 | lastto=JSON.parse(prev.turnorder) || []; 52 | 53 | if((to[0] !== lastto[0]) 54 | && _.has(to[0],'custom') 55 | && dieName === to[0].custom 56 | && dieMax <= to[0].pr) { 57 | to[0].formula=''; 58 | to[0].pr=dieMax; 59 | } 60 | obj.set({turnorder: JSON.stringify(to)}); 61 | }, 62 | 63 | registerEventHandlers = function() { 64 | on("change:campaign:initiativepage", handleEscalationDieReset ); 65 | on("change:campaign:turnorder", handleEscalationDieTurn ); 66 | }; 67 | 68 | return { 69 | CheckInstall: checkInstall, 70 | RegisterEventHandlers: registerEventHandlers 71 | }; 72 | }()); 73 | 74 | on("ready",function(){ 75 | 'use strict'; 76 | 77 | Escalation.CheckInstall(); 78 | Escalation.RegisterEventHandlers(); 79 | }); 80 | -------------------------------------------------------------------------------- /Escalation/Escalation.js: -------------------------------------------------------------------------------- 1 | // Github: https://github.com/shdwjk/Roll20API/blob/master/Escalation/Escalation.js 2 | // By: The Aaron, Arcane Scriptomancer 3 | // Contact: https://app.roll20.net/users/104025/the-aaron 4 | 5 | var Escalation = Escalation || (function() { 6 | 'use strict'; 7 | 8 | var version = '0.2.1', 9 | lastUpdate = 1427604246, 10 | dieName = 'Escalation Die', 11 | dieMax = 6, 12 | 13 | checkInstall = function() { 14 | log('-=> Escalation v'+version+' <=- ['+(new Date(lastUpdate*1000))+']'); 15 | 16 | if( "" === Campaign().get('turnorder')) { 17 | Campaign().set({turnorder: '[]'}); 18 | } 19 | handleEscalationDieReset(Campaign(),{}); 20 | }, 21 | 22 | handleEscalationDieReset = function(obj, prev) { 23 | var to=JSON.parse(obj.get('turnorder')), 24 | loc=_.find(to,function(e){ 25 | return dieName === e.custom; 26 | }); 27 | 28 | if(loc) { 29 | if(!obj.get('initiativepage')) { 30 | loc.pr=0; 31 | loc.forumla='+1'; 32 | } else if (dieMax !== loc.pr && '' === loc.formula) { 33 | loc.formula='+1'; 34 | } 35 | } else { 36 | to = _.union([{ 37 | id: '-1', 38 | pr: 0, 39 | custom: dieName, 40 | formula: '+1'}], to); 41 | } 42 | obj.set({turnorder: JSON.stringify(to)}); 43 | }, 44 | 45 | 46 | handleEscalationDieTurn = function(obj, prev) { 47 | var to,lastto; 48 | handleEscalationDieReset(obj,prev); 49 | 50 | to=JSON.parse(obj.get('turnorder')) || []; 51 | lastto=JSON.parse(prev.turnorder) || []; 52 | 53 | if((to[0] !== lastto[0]) 54 | && _.has(to[0],'custom') 55 | && dieName === to[0].custom 56 | && dieMax <= to[0].pr) { 57 | to[0].formula=''; 58 | to[0].pr=dieMax; 59 | } 60 | obj.set({turnorder: JSON.stringify(to)}); 61 | }, 62 | 63 | registerEventHandlers = function() { 64 | on("change:campaign:initiativepage", handleEscalationDieReset ); 65 | on("change:campaign:turnorder", handleEscalationDieTurn ); 66 | }; 67 | 68 | return { 69 | CheckInstall: checkInstall, 70 | RegisterEventHandlers: registerEventHandlers 71 | }; 72 | }()); 73 | 74 | on("ready",function(){ 75 | 'use strict'; 76 | 77 | Escalation.CheckInstall(); 78 | Escalation.RegisterEventHandlers(); 79 | }); 80 | -------------------------------------------------------------------------------- /Escalation/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Escalation", 3 | "version": "0.2.1", 4 | "description": "Simple Escalation Die handling script, using the new custom entries with formulae.", 5 | "authors": "The Aaron", 6 | "roll20userid": "104025", 7 | "patreon": "https://www.patreon.com/shdwjk", 8 | "dependencies": [], 9 | "modifies": { 10 | "campaign.initiativepage": "read", 11 | "campaign.turnorder": "read,write" 12 | }, 13 | "conflicts": [], 14 | "script": "Escalation.js", 15 | "useroptions": {}, 16 | "previousversions": [] 17 | } -------------------------------------------------------------------------------- /Exalted Successes/1.0/Exalted Successes.js: -------------------------------------------------------------------------------- 1 | var exalted = exalted || {}; 2 | 3 | exalted.sendChat = function(name, id, msg) 4 | { 5 | var characters = findObjs({_type: 'character'}); 6 | var speaking; 7 | characters.forEach(function(chr) { if(chr.get('name') == name) speaking = chr; }); 8 | if(speaking) sendChat('character|'+speaking.id, msg); 9 | else sendChat('player|'+id, msg); 10 | }; 11 | 12 | on('chat:message', function(msg) { 13 | var json; 14 | var inline = false; 15 | try { json = JSON.parse(msg.content); } 16 | catch(e) 17 | { 18 | if(msg.inlinerolls) inline = true; 19 | else return; 20 | } 21 | 22 | var results = []; 23 | if(!inline) 24 | { 25 | json.rolls.forEach(function(j) { 26 | if(j.sides != 10) return; 27 | results.push(j.results); 28 | }); 29 | } 30 | else 31 | { 32 | json = msg.inlinerolls; 33 | json.forEach(function(j) { 34 | var rolls = j.results.rolls; 35 | rolls.forEach(function(r) { 36 | if(r.sides != 10) return; 37 | results.push(r.results); 38 | }); 39 | }); 40 | } 41 | 42 | var successes = 0; 43 | var botches = 0; 44 | results.forEach(function(r) { 45 | r.forEach(function(d) { 46 | var die = d['v']; 47 | successes += die >= 7 ? 1 : 0 48 | successes += die == 10 ? 1 : 0; 49 | botches += die == 1 ? 1 : 0; 50 | }); 51 | }); 52 | 53 | if(successes == 0 && botches != 0) 54 | { 55 | exalted.sendChat(msg.who, msg.playerid, botches+' botch'+(botches>1?'es':'')); 56 | } 57 | else if(successes == 0) 58 | { 59 | exalted.sendChat(msg.who, msg.playerid, 'Failure'); 60 | } 61 | else 62 | { 63 | exalted.sendChat(msg.who, msg.playerid, successes+' success'+(successes>1?'es':'')); 64 | } 65 | }); -------------------------------------------------------------------------------- /Exalted Successes/2.0/Exalted Successes.js: -------------------------------------------------------------------------------- 1 | var bshields = bshields || {}; 2 | bshields.exalted = (function() { 3 | 'use strict'; 4 | 5 | var version = 2.0; 6 | 7 | function handleInput(msg) { 8 | var json = msg.type === 'rollresult' ? JSON.parse(msg.content) : null, 9 | inline = !!msg.inlinerolls, 10 | results = [], 11 | successes = 0, 12 | botches = 0; 13 | 14 | if (json) { 15 | _.each(json.rolls, function(roll) { 16 | if (roll.sides !== 10) { return; } 17 | results.push(roll.results); 18 | }); 19 | } else if (inline) { 20 | _.each(msg.inlinerolls, function(rolldata) { 21 | _.each(rolldata.results.rolls, function(roll) { 22 | if (roll.sides !== 10) { return; } 23 | results.push(roll.results); 24 | }); 25 | }); 26 | } 27 | 28 | _.each(results, function(roll) { 29 | _.each(roll, function(die) { 30 | var value = die['v']; 31 | successes += value >= 7 ? 1 : 0; 32 | successes += value === 10 ? 1 : 0; 33 | botches += value === 1 ? 1 : 0; 34 | }); 35 | }); 36 | 37 | if (successes === 0 && botches > 0) { 38 | bshields.sendChat(msg, botches + ' botch' + (botches > 1 ? 'es' : '')) 39 | } else if (successes === 0) { 40 | bshields.sendChat(msg, 'Failure'); 41 | } else { 42 | bshields.sendChat(msg, successes + ' success' + (successes > 1 ? 'es' : '')); 43 | } 44 | } 45 | 46 | function registerEventHandlers() { 47 | on('chat:message', handleInput); 48 | } 49 | 50 | return { 51 | registerEventHandlers: registerEventHandlers 52 | }; 53 | }()); 54 | 55 | on('ready', function() { 56 | 'use strict'; 57 | 58 | bshields.exalted.registerEventHandlers(); 59 | }); -------------------------------------------------------------------------------- /Exalted Successes/2.2/Exalted Successes.js: -------------------------------------------------------------------------------- 1 | var bshields = bshields || {}; 2 | bshields.exalted = (function() { 3 | 'use strict'; 4 | 5 | var version = 2.2; 6 | 7 | function handleInput(msg) { 8 | var json = msg.type === 'rollresult' ? JSON.parse(msg.content) : null, 9 | inline = !!msg.inlinerolls, 10 | results = [], 11 | successes = 0, 12 | botches = 0; 13 | 14 | if (json) { 15 | _.each(json.rolls, function(roll) { 16 | if (roll.sides !== 10) { return; } 17 | results.push(roll.results); 18 | }); 19 | } else if (inline) { 20 | _.each(msg.inlinerolls, function(rolldata) { 21 | _.each(rolldata.results.rolls, function(roll) { 22 | if (roll.sides !== 10) { return; } 23 | results.push(roll.results); 24 | }); 25 | }); 26 | } 27 | 28 | if (results.length === 0) { 29 | return; 30 | } 31 | 32 | _.each(results, function(roll) { 33 | _.each(roll, function(die) { 34 | var value = die['v']; 35 | successes += value >= 7 ? 1 : 0; 36 | successes += value === 10 ? 1 : 0; 37 | botches += value === 1 ? 1 : 0; 38 | }); 39 | }); 40 | 41 | if (successes === 0 && botches > 0) { 42 | bshields.sendChat(msg, botches + ' botch' + (botches > 1 ? 'es' : '')) 43 | } else if (successes === 0) { 44 | bshields.sendChat(msg, 'Failure'); 45 | } else { 46 | bshields.sendChat(msg, successes + ' success' + (successes > 1 ? 'es' : '')); 47 | } 48 | } 49 | 50 | function registerEventHandlers() { 51 | on('chat:message', handleInput); 52 | } 53 | 54 | return { 55 | registerEventHandlers: registerEventHandlers 56 | }; 57 | }()); 58 | 59 | on('ready', function() { 60 | 'use strict'; 61 | 62 | bshields.exalted.registerEventHandlers(); 63 | }); -------------------------------------------------------------------------------- /Exalted Successes/README.md: -------------------------------------------------------------------------------- 1 | ## Exalted Successes 2 | 3 | Whenever a message is posted to the chat which includes rolling d10s, the script will foolow up by posting the number of successes for a roll in the _Exalted_ game system by White Wolf Publishing. Restuls of 7, 8, and 9 are each 1 success, 10s are 2 successes*, and 1s are botches _if and only if_ there are zero successes. 4 | 5 | \* There are corner cases in the game system where dice with values less than 7 count as successes (or 7, 8, and/or 9 _don't_ count as successes), and damage rolls do not normally count 10s as double. This script does not account for those cases. -------------------------------------------------------------------------------- /Exalted Successes/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Exalted Successes", 3 | "script": "Exalted Successes.js", 4 | "version": "2.2", 5 | "previousversions": ["2.1","2.0","1.0"], 6 | "description": "Reports successes on d10 rolls for use with the Exalted game system.", 7 | "authors": "Brian Shields", 8 | "roll20userid": "235259", 9 | "patreon": "https://www.patreon.com/bshields", 10 | "useroptions": [], 11 | "dependencies": ["Interpreted sendChat"], 12 | "modifies": {}, 13 | "conflicts": [] 14 | } 15 | -------------------------------------------------------------------------------- /ExperienceTracker/README.md: -------------------------------------------------------------------------------- 1 | ExperienceTracker 2 | 3 | This script creates a new character sheet which can be used to track party xp. 4 | 5 | Features: 6 | Easy to use !xp command. 7 | Level up announcer. 8 | Divide xp automatically with party size. 9 | Ability to set party size and level up threshold. 10 | 11 | Tool tip: 12 | create a macro like this "!xp @{selected|npc_xp}", and use it to assign xp when the party kills a foe in combat! 13 | -------------------------------------------------------------------------------- /ExperienceTracker/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Experience Tracker", 3 | "script": "ExperienceTracker.js", 4 | "version": "2.1", 5 | "previousversions": [], 6 | "description": "This script allows for automatic tracking of a Dungeons and Dragons 5e like experience system, aswell as level up announcement in chat. !xp handles experience and announces level up", 7 | "authors": "Kasper K.", 8 | "roll20userid": "56818", 9 | "useroptions": [], 10 | "dependencies": [], 11 | "modifies": { 12 | "attribute": "create", 13 | "attribute.characterid": "read", 14 | "attribute.current": "read,write", 15 | "attribute.id": "read", 16 | "attribute.max": "read", 17 | "attribute.name": "read", 18 | "character": "create", 19 | "character.id": "read", 20 | "character.name": "read" 21 | }, 22 | "conflicts": [] 23 | } 24 | -------------------------------------------------------------------------------- /ExtendedExpressions/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ExtendedExpressions", 3 | "version": "0.5", 4 | "description": "Extended roll expression syntax, supporting conditionals, variable references, bitwise operators, and more.", 5 | "authors": "manveti", 6 | "roll20userid": "503018", 7 | "dependencies": {}, 8 | "modifies": {}, 9 | "conflicts": [] 10 | } 11 | -------------------------------------------------------------------------------- /FFG-SWRPG-Dice-Roller/2.6/help.txt: -------------------------------------------------------------------------------- 1 | API Chat Commands 2 | 3 | Settings: 4 | Log 5 | * default: 'on' and 'single' 6 | * Description: Sets the visual output in the chat window for the dice rolls 7 | * Command: !eed log on|off|multi|single 8 | 9 | Graphics 10 | * default: 'on' and 'm' 11 | * Description: Sets chat window dice output as graphic, small, medium, or large if "on" or as text if "off" 12 | * Command: !eed graphics on|off|s|m|l 13 | 14 | Test 15 | * Description: Output every side of every die to the chat window 16 | * !eed test 17 | 18 | Roll: 19 | Label 20 | * default: null 21 | * Description: set the skill name of the roll 22 | * Command: !eed label(Name of Skill) 23 | 24 | Initiative 25 | * default: false 26 | * Description: Set NPC/PC initiative true 27 | * Command: !eed npcinit or pcinit and #b #g #y #blk #p #r #w 28 | 29 | Skill 30 | * default: 31 | * Description: create the ability and proficiency dice for a skill check 32 | * Command: !eed skill(char_value|skill_value) 33 | 34 | Opposed 35 | * default: 36 | * Description: create the difficulty and challenge dice for an opposed skill check 37 | * Command: !eed opposed(char_value|skill_value) 38 | 39 | Dice 40 | * default: 41 | * Description: Loop thru the dice and adds or subtracts them from the dice object 42 | * Command: !eed #g #y #b #blk #r #p #w #s #a 43 | 44 | Upgrade 45 | * default: 46 | * Description: upgrades ability and difficulty dice 47 | * Command: !eed upgrade(ability|#) or upgrade(difficulty|#) 48 | 49 | Downgrade 50 | * default: 51 | * Description: downgrades proficiency and challenge dice 52 | * Command: !eed downgrade(proficiency|#) or downgrade(challenge|#) 53 | -------------------------------------------------------------------------------- /FFG-SWRPG-Dice-Roller/3.0/EotE-Dice.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlenser/roll20-api-scripts/65a254bd1d44764076cf808e6c50abc995ee6938/FFG-SWRPG-Dice-Roller/3.0/EotE-Dice.js -------------------------------------------------------------------------------- /FFG-SWRPG-Dice-Roller/dice/Ability/abilityA.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlenser/roll20-api-scripts/65a254bd1d44764076cf808e6c50abc995ee6938/FFG-SWRPG-Dice-Roller/dice/Ability/abilityA.png -------------------------------------------------------------------------------- /FFG-SWRPG-Dice-Roller/dice/Ability/abilityAA.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlenser/roll20-api-scripts/65a254bd1d44764076cf808e6c50abc995ee6938/FFG-SWRPG-Dice-Roller/dice/Ability/abilityAA.png -------------------------------------------------------------------------------- /FFG-SWRPG-Dice-Roller/dice/Ability/abilityBlank.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlenser/roll20-api-scripts/65a254bd1d44764076cf808e6c50abc995ee6938/FFG-SWRPG-Dice-Roller/dice/Ability/abilityBlank.png -------------------------------------------------------------------------------- /FFG-SWRPG-Dice-Roller/dice/Ability/abilityS.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlenser/roll20-api-scripts/65a254bd1d44764076cf808e6c50abc995ee6938/FFG-SWRPG-Dice-Roller/dice/Ability/abilityS.png -------------------------------------------------------------------------------- /FFG-SWRPG-Dice-Roller/dice/Ability/abilitySA.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlenser/roll20-api-scripts/65a254bd1d44764076cf808e6c50abc995ee6938/FFG-SWRPG-Dice-Roller/dice/Ability/abilitySA.png -------------------------------------------------------------------------------- /FFG-SWRPG-Dice-Roller/dice/Ability/abilitySS.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlenser/roll20-api-scripts/65a254bd1d44764076cf808e6c50abc995ee6938/FFG-SWRPG-Dice-Roller/dice/Ability/abilitySS.png -------------------------------------------------------------------------------- /FFG-SWRPG-Dice-Roller/dice/Boost/boostA.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlenser/roll20-api-scripts/65a254bd1d44764076cf808e6c50abc995ee6938/FFG-SWRPG-Dice-Roller/dice/Boost/boostA.png -------------------------------------------------------------------------------- /FFG-SWRPG-Dice-Roller/dice/Boost/boostAA.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlenser/roll20-api-scripts/65a254bd1d44764076cf808e6c50abc995ee6938/FFG-SWRPG-Dice-Roller/dice/Boost/boostAA.png -------------------------------------------------------------------------------- /FFG-SWRPG-Dice-Roller/dice/Boost/boostBlank.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlenser/roll20-api-scripts/65a254bd1d44764076cf808e6c50abc995ee6938/FFG-SWRPG-Dice-Roller/dice/Boost/boostBlank.png -------------------------------------------------------------------------------- /FFG-SWRPG-Dice-Roller/dice/Boost/boostS.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlenser/roll20-api-scripts/65a254bd1d44764076cf808e6c50abc995ee6938/FFG-SWRPG-Dice-Roller/dice/Boost/boostS.png -------------------------------------------------------------------------------- /FFG-SWRPG-Dice-Roller/dice/Boost/boostSA.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlenser/roll20-api-scripts/65a254bd1d44764076cf808e6c50abc995ee6938/FFG-SWRPG-Dice-Roller/dice/Boost/boostSA.png -------------------------------------------------------------------------------- /FFG-SWRPG-Dice-Roller/dice/Challenge/ChallengeBlank.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlenser/roll20-api-scripts/65a254bd1d44764076cf808e6c50abc995ee6938/FFG-SWRPG-Dice-Roller/dice/Challenge/ChallengeBlank.png -------------------------------------------------------------------------------- /FFG-SWRPG-Dice-Roller/dice/Challenge/ChallengeDespair.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlenser/roll20-api-scripts/65a254bd1d44764076cf808e6c50abc995ee6938/FFG-SWRPG-Dice-Roller/dice/Challenge/ChallengeDespair.png -------------------------------------------------------------------------------- /FFG-SWRPG-Dice-Roller/dice/Challenge/ChallengeF.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlenser/roll20-api-scripts/65a254bd1d44764076cf808e6c50abc995ee6938/FFG-SWRPG-Dice-Roller/dice/Challenge/ChallengeF.png -------------------------------------------------------------------------------- /FFG-SWRPG-Dice-Roller/dice/Challenge/ChallengeFF.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlenser/roll20-api-scripts/65a254bd1d44764076cf808e6c50abc995ee6938/FFG-SWRPG-Dice-Roller/dice/Challenge/ChallengeFF.png -------------------------------------------------------------------------------- /FFG-SWRPG-Dice-Roller/dice/Challenge/ChallengeFT.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlenser/roll20-api-scripts/65a254bd1d44764076cf808e6c50abc995ee6938/FFG-SWRPG-Dice-Roller/dice/Challenge/ChallengeFT.png -------------------------------------------------------------------------------- /FFG-SWRPG-Dice-Roller/dice/Challenge/ChallengeT.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlenser/roll20-api-scripts/65a254bd1d44764076cf808e6c50abc995ee6938/FFG-SWRPG-Dice-Roller/dice/Challenge/ChallengeT.png -------------------------------------------------------------------------------- /FFG-SWRPG-Dice-Roller/dice/Challenge/ChallengeTT.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlenser/roll20-api-scripts/65a254bd1d44764076cf808e6c50abc995ee6938/FFG-SWRPG-Dice-Roller/dice/Challenge/ChallengeTT.png -------------------------------------------------------------------------------- /FFG-SWRPG-Dice-Roller/dice/Difficulty/DifficultyBlank.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlenser/roll20-api-scripts/65a254bd1d44764076cf808e6c50abc995ee6938/FFG-SWRPG-Dice-Roller/dice/Difficulty/DifficultyBlank.png -------------------------------------------------------------------------------- /FFG-SWRPG-Dice-Roller/dice/Difficulty/DifficultyF.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlenser/roll20-api-scripts/65a254bd1d44764076cf808e6c50abc995ee6938/FFG-SWRPG-Dice-Roller/dice/Difficulty/DifficultyF.png -------------------------------------------------------------------------------- /FFG-SWRPG-Dice-Roller/dice/Difficulty/DifficultyFF.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlenser/roll20-api-scripts/65a254bd1d44764076cf808e6c50abc995ee6938/FFG-SWRPG-Dice-Roller/dice/Difficulty/DifficultyFF.png -------------------------------------------------------------------------------- /FFG-SWRPG-Dice-Roller/dice/Difficulty/DifficultyFT.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlenser/roll20-api-scripts/65a254bd1d44764076cf808e6c50abc995ee6938/FFG-SWRPG-Dice-Roller/dice/Difficulty/DifficultyFT.png -------------------------------------------------------------------------------- /FFG-SWRPG-Dice-Roller/dice/Difficulty/DifficultyT.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlenser/roll20-api-scripts/65a254bd1d44764076cf808e6c50abc995ee6938/FFG-SWRPG-Dice-Roller/dice/Difficulty/DifficultyT.png -------------------------------------------------------------------------------- /FFG-SWRPG-Dice-Roller/dice/Difficulty/DifficultyTT.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlenser/roll20-api-scripts/65a254bd1d44764076cf808e6c50abc995ee6938/FFG-SWRPG-Dice-Roller/dice/Difficulty/DifficultyTT.png -------------------------------------------------------------------------------- /FFG-SWRPG-Dice-Roller/dice/Force/ForceD.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlenser/roll20-api-scripts/65a254bd1d44764076cf808e6c50abc995ee6938/FFG-SWRPG-Dice-Roller/dice/Force/ForceD.png -------------------------------------------------------------------------------- /FFG-SWRPG-Dice-Roller/dice/Force/ForceDD.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlenser/roll20-api-scripts/65a254bd1d44764076cf808e6c50abc995ee6938/FFG-SWRPG-Dice-Roller/dice/Force/ForceDD.png -------------------------------------------------------------------------------- /FFG-SWRPG-Dice-Roller/dice/Force/ForceL.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlenser/roll20-api-scripts/65a254bd1d44764076cf808e6c50abc995ee6938/FFG-SWRPG-Dice-Roller/dice/Force/ForceL.png -------------------------------------------------------------------------------- /FFG-SWRPG-Dice-Roller/dice/Force/ForceLL.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlenser/roll20-api-scripts/65a254bd1d44764076cf808e6c50abc995ee6938/FFG-SWRPG-Dice-Roller/dice/Force/ForceLL.png -------------------------------------------------------------------------------- /FFG-SWRPG-Dice-Roller/dice/Proficiency/ProficiencyA.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlenser/roll20-api-scripts/65a254bd1d44764076cf808e6c50abc995ee6938/FFG-SWRPG-Dice-Roller/dice/Proficiency/ProficiencyA.png -------------------------------------------------------------------------------- /FFG-SWRPG-Dice-Roller/dice/Proficiency/ProficiencyAA.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlenser/roll20-api-scripts/65a254bd1d44764076cf808e6c50abc995ee6938/FFG-SWRPG-Dice-Roller/dice/Proficiency/ProficiencyAA.png -------------------------------------------------------------------------------- /FFG-SWRPG-Dice-Roller/dice/Proficiency/ProficiencyBlank.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlenser/roll20-api-scripts/65a254bd1d44764076cf808e6c50abc995ee6938/FFG-SWRPG-Dice-Roller/dice/Proficiency/ProficiencyBlank.png -------------------------------------------------------------------------------- /FFG-SWRPG-Dice-Roller/dice/Proficiency/ProficiencyS.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlenser/roll20-api-scripts/65a254bd1d44764076cf808e6c50abc995ee6938/FFG-SWRPG-Dice-Roller/dice/Proficiency/ProficiencyS.png -------------------------------------------------------------------------------- /FFG-SWRPG-Dice-Roller/dice/Proficiency/ProficiencySA.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlenser/roll20-api-scripts/65a254bd1d44764076cf808e6c50abc995ee6938/FFG-SWRPG-Dice-Roller/dice/Proficiency/ProficiencySA.png -------------------------------------------------------------------------------- /FFG-SWRPG-Dice-Roller/dice/Proficiency/ProficiencySS.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlenser/roll20-api-scripts/65a254bd1d44764076cf808e6c50abc995ee6938/FFG-SWRPG-Dice-Roller/dice/Proficiency/ProficiencySS.png -------------------------------------------------------------------------------- /FFG-SWRPG-Dice-Roller/dice/Proficiency/ProficiencyTriumph.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlenser/roll20-api-scripts/65a254bd1d44764076cf808e6c50abc995ee6938/FFG-SWRPG-Dice-Roller/dice/Proficiency/ProficiencyTriumph.png -------------------------------------------------------------------------------- /FFG-SWRPG-Dice-Roller/dice/Setback/SetBackBlank.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlenser/roll20-api-scripts/65a254bd1d44764076cf808e6c50abc995ee6938/FFG-SWRPG-Dice-Roller/dice/Setback/SetBackBlank.png -------------------------------------------------------------------------------- /FFG-SWRPG-Dice-Roller/dice/Setback/SetBackF.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlenser/roll20-api-scripts/65a254bd1d44764076cf808e6c50abc995ee6938/FFG-SWRPG-Dice-Roller/dice/Setback/SetBackF.png -------------------------------------------------------------------------------- /FFG-SWRPG-Dice-Roller/dice/Setback/SetBackT.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlenser/roll20-api-scripts/65a254bd1d44764076cf808e6c50abc995ee6938/FFG-SWRPG-Dice-Roller/dice/Setback/SetBackT.png -------------------------------------------------------------------------------- /FFG-SWRPG-Dice-Roller/dice/Symbols/A.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlenser/roll20-api-scripts/65a254bd1d44764076cf808e6c50abc995ee6938/FFG-SWRPG-Dice-Roller/dice/Symbols/A.png -------------------------------------------------------------------------------- /FFG-SWRPG-Dice-Roller/dice/Symbols/D.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlenser/roll20-api-scripts/65a254bd1d44764076cf808e6c50abc995ee6938/FFG-SWRPG-Dice-Roller/dice/Symbols/D.png -------------------------------------------------------------------------------- /FFG-SWRPG-Dice-Roller/dice/Symbols/Despair.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlenser/roll20-api-scripts/65a254bd1d44764076cf808e6c50abc995ee6938/FFG-SWRPG-Dice-Roller/dice/Symbols/Despair.png -------------------------------------------------------------------------------- /FFG-SWRPG-Dice-Roller/dice/Symbols/F.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlenser/roll20-api-scripts/65a254bd1d44764076cf808e6c50abc995ee6938/FFG-SWRPG-Dice-Roller/dice/Symbols/F.png -------------------------------------------------------------------------------- /FFG-SWRPG-Dice-Roller/dice/Symbols/L.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlenser/roll20-api-scripts/65a254bd1d44764076cf808e6c50abc995ee6938/FFG-SWRPG-Dice-Roller/dice/Symbols/L.png -------------------------------------------------------------------------------- /FFG-SWRPG-Dice-Roller/dice/Symbols/S.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlenser/roll20-api-scripts/65a254bd1d44764076cf808e6c50abc995ee6938/FFG-SWRPG-Dice-Roller/dice/Symbols/S.png -------------------------------------------------------------------------------- /FFG-SWRPG-Dice-Roller/dice/Symbols/T.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlenser/roll20-api-scripts/65a254bd1d44764076cf808e6c50abc995ee6938/FFG-SWRPG-Dice-Roller/dice/Symbols/T.png -------------------------------------------------------------------------------- /FFG-SWRPG-Dice-Roller/dice/Symbols/Triumph.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlenser/roll20-api-scripts/65a254bd1d44764076cf808e6c50abc995ee6938/FFG-SWRPG-Dice-Roller/dice/Symbols/Triumph.png -------------------------------------------------------------------------------- /Facing/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Facing", 3 | "version": "0.1.2", 4 | "description": "Creates and maintains a facing indicator for tokens.", 5 | "authors": "The Aaron", 6 | "roll20userid": "104025", 7 | "patreon": "https://www.patreon.com/shdwjk", 8 | "dependencies": {}, 9 | "modifies": { 10 | "state.Facing": "read,write", 11 | "graphic": "create", 12 | "graphic.left": "read,write", 13 | "graphic.top": "read,write", 14 | "graphic.width": "read,write", 15 | "graphic.height": "read,write", 16 | "graphic.layer": "read,write", 17 | "graphic.rotation": "read,write", 18 | "attribute": "create", 19 | "attribute.current": "write", 20 | "page.zorder": "write" 21 | }, 22 | "conflicts": [], 23 | "script": "Facing.js", 24 | "useroptions": {}, 25 | "previousversions": [] 26 | } -------------------------------------------------------------------------------- /FalloutTerminal/demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlenser/roll20-api-scripts/65a254bd1d44764076cf808e6c50abc995ee6938/FalloutTerminal/demo.gif -------------------------------------------------------------------------------- /FateDots/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "FateDots", 3 | "version": "0.2.1", 4 | "description": "Provides numbered multi dots for Fate stress boxes.", 5 | "authors": "The Aaron", 6 | "roll20userid": "104025", 7 | "patreon": "https://www.patreon.com/shdwjk", 8 | "dependencies": [], 9 | "modifies": { 10 | "state.FateDots": "read,write", 11 | "graphic.statusmarkers": "read,write" 12 | }, 13 | "conflicts": [], 14 | "script": "FateDots.js", 15 | "useroptions": {}, 16 | "previousversions": [] 17 | } -------------------------------------------------------------------------------- /Flight/1.0/Flight.js: -------------------------------------------------------------------------------- 1 | on('chat:message', function(msg) { 2 | if(msg.type != 'api') return; 3 | var parts = msg.content.toLowerCase().split(' '); 4 | var command = parts.shift().substring(1); 5 | var selected = msg.selected; 6 | if(command != 'fly' || !selected) return; // use the !fly command, and have one or more things selected 7 | var height = +parts[0]; 8 | if(!height) height = 0; // if no height is returned, treat as 0 9 | _.each(selected, function(obj) { 10 | if(obj._type != 'graphic') return; // only fly graphics 11 | var tok = getObj('graphic', obj._id); 12 | if(tok.get('subtype') != 'token') return; // don't try to fly cards 13 | tok.set('status_fluffy-wing', false); 14 | if(height > 0) tok.set('status_fluffy-wing', ''+height); 15 | }); 16 | }); -------------------------------------------------------------------------------- /Flight/2.0/Flight.js: -------------------------------------------------------------------------------- 1 | on('chat:message', function(msg) { 2 | if(msg.type != 'api') return; 3 | var parts = msg.content.toLowerCase().split(' '); 4 | var command = parts.shift().substring(1); 5 | var selected = msg.selected; 6 | if(command != 'fly' || !selected) return; // use the !fly command, and have one or more things selected 7 | var height = +parts[0]; 8 | if(!height) height = 0; // if no height is returned, treat as 0 9 | _.each(selected, function(obj) { 10 | if(obj._type != 'graphic') return; // only fly graphics 11 | var tok = getObj('graphic', obj._id); 12 | if(tok.get('subtype') != 'token') return; // don't try to fly cards 13 | tok.set('status_fluffy-wing', false); 14 | var wings = ''; 15 | while(height > 0) 16 | { 17 | // get current digit, starting from ones 18 | var digit = height / 10; 19 | digit -= Math.floor(digit); 20 | digit = Math.round(digit * 10); 21 | // shift height 22 | height = Math.floor(height / 10); 23 | wings += 'fluffy-wing@'+digit+','; 24 | } 25 | if(wings.length > 0) wings = wings.substring(0, wings.length - 1); // trim trailing comma 26 | var markers = tok.get('statusmarkers'); 27 | if(markers != '') markers += ','; 28 | markers += wings; 29 | tok.set('statusmarkers', markers); 30 | }); 31 | }); -------------------------------------------------------------------------------- /Flight/README.md: -------------------------------------------------------------------------------- 1 | ## Flight 2 | 3 | Adds copies of the `fluffy-wing` status icon to the selected tokens with numbers indicating how high the token is flying. 4 | 5 | Use `!fly height` (where _height_ is a number) while selecting one or more tokens. If _height_ is 0 or is omitted, the wings will be removed. Any integer number can be used, although any digits of the number which are 0 will show up as wings without a number. 6 | 7 | ![Flying High](https://wiki.roll20.net/images/3/3e/Flight_Example.jpg) 8 | 9 | ### Editing the commands 10 | 11 | As of v3.4, if you _import_ this script, you can easily edit the statusmarker used or the !command required, including adding additional !commands. Creating a new command is simply a matter of copying 4 lines near the top of the script (lines 7-10 when unmodified) and changing 2 of them (the copied line 7 to change the !command required and the copied line 9 to change the marker used). -------------------------------------------------------------------------------- /Flight/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Flight", 3 | "script": "Flight.js", 4 | "version": "3.4", 5 | "previousversions": ["3.3", "3.2","3.1","3.0","2.0","1.0"], 6 | "description": "Adds 'fluffy-wings' status icon to selected token to represent some height.", 7 | "authors": "Brian Shields,Aaron C. Meadows", 8 | "roll20userid": "235259,104025", 9 | "patreon": "https://www.patreon.com/bshields", 10 | "useroptions": [], 11 | "dependencies": ["splitArgs"], 12 | "modifies": { 13 | "token.type": "read", 14 | "token.subtype": "read", 15 | "token.statusmarkers": "read,write" 16 | }, 17 | "conflicts": [] 18 | } 19 | -------------------------------------------------------------------------------- /Flip Tokens/1.0/Flip Tokens.js: -------------------------------------------------------------------------------- 1 | /** 2 | * If a player or GM uses the `!flip' command, all graphics they have selected 3 | * will flip horizontally. Try creating a macro button for this and making it 4 | * visible to all players! 5 | */ 6 | on('chat:message', function(msg) { 7 | if(msg.type == 'api' && msg.selected && msg.content.indexOf('!flip') == 0) 8 | { 9 | var selectedObjs = msg.selected; 10 | _.each(selectedObjs, function(obj) { 11 | if(obj._type == 'graphic') 12 | { 13 | var token = getObj('graphic', obj._id); 14 | token.set('fliph', !token.get('fliph')); 15 | } 16 | }); 17 | } 18 | }); -------------------------------------------------------------------------------- /Flip Tokens/README.md: -------------------------------------------------------------------------------- 1 | ## Flip Tokens 2 | 3 | Call `!flip` while selecting one or more graphic objects (tokens, cards), and they will flip horizontally. 4 | 5 | You can add any number of "horizontal" and "vertical" parameters to `!flip` in order to flip in the specified direction multiple times in sequence. -------------------------------------------------------------------------------- /Flip Tokens/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Flip Tokens", 3 | "script": "Flip Tokens.js", 4 | "version": "2.3", 5 | "previousversions": ["2.2","2.1","2.0","1.0"], 6 | "description": "Flips selected graphics horizontally and/or vertically. Especially useful for games with side-view tokens, and for players who do not have access to the same context menu as GMs.", 7 | "authors": "Brian Shields", 8 | "roll20userid": "235259", 9 | "patreon": "https://www.patreon.com/bshields", 10 | "useroptions": [], 11 | "dependencies": ["splitArgs"], 12 | "modifies": { 13 | "token.fliph": "read,write", 14 | "token.flipv": "read,write" 15 | }, 16 | "conflicts": [] 17 | } 18 | -------------------------------------------------------------------------------- /Fumbler/README.md: -------------------------------------------------------------------------------- 1 | Fumbler 2 | ======= 3 | 4 | This is a simple and sometimes humorous fumble generator. 5 | 6 | ---------- 7 | 8 | How to use 9 | ---------------- 10 | 11 | In the chat box enter `!fumble` and a random fumble will be output: 12 | 13 | > **Fumbler**: 35% **Clumsy** 14 | Fall down. Roll DEX or drop primary weapon. 15 | 16 | You can also enter an optional percent like `!fumble 93` 17 | 18 | > **Fumbler**: 93% **Very Unaware** 19 | Hit friend, normal damage. Friend stunned for 1 round. 20 | 21 | 22 | `!fumble 90` 23 | 24 | > **Fumbler**: 90% **Useless Moron** 25 | Hit self. Double damage. Stunned for 1 round. 26 | 27 | 28 | 29 | More cool stuff 30 | --------------- 31 | 32 | Check out other scripts I've written for Roll20 and other frameworks: https://github.com/RyanNerd?tab=repositories 33 | 34 | 35 | > **If you find these scripts useful consider contributing (or just stop by to say 'Hi')** 36 | https://www.patreon.com/user?u=3985594 -------------------------------------------------------------------------------- /Fumbler/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Fumbler", 3 | "script": "Fumbler.js", 4 | "version": "0.1.0", 5 | "previousversions": [], 6 | "description": "A simple and sometimes humorous fumble generator\r\rTo use enter !fumble [roll%] in the chat. The roll% is an optional % die roll, if not provided then a random percent will be selected.", 7 | "authors": "Ryan Jentzsch", 8 | "roll20userid": "1638601", 9 | "patreon": "https://patreon.com/user?u=3985594", 10 | "modifies": 11 | { 12 | "state.fumbler": "read,write" 13 | }, 14 | "conflicts": [], 15 | "useroptions": [] 16 | } 17 | -------------------------------------------------------------------------------- /GMCode/Help.txt: -------------------------------------------------------------------------------- 1 | To use: (GMC = Game Master Code) 2 | !gmcodehelp ~ A quick reference to the functions. 3 | !gencode YOURCODEHERE ~ Generates a random GMC. Generates a random code anyway if no code currently exists. 4 | !clearcode YOURCODEHERE ~ Clears the current GMC. Generates a random if none is present. 5 | !custcode YOURCODEHERE NEWCODEHERE ~ Changes the GMC to a custom one. 6 | 7 | The script often logs the GMC. Don't want the GM losing it eh? 8 | 9 | For coders: 10 | The variable to access the code is "state.gmcode". 11 | Example 12 | if (message[1] != state.gmcode && state.gmcode != null) 13 | { 14 | CODE HERE 15 | } 16 | 17 | It is recommended you message the player if the GMC input is incorrect OR one does not exist. -------------------------------------------------------------------------------- /GMCode/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "GMCode", 3 | "version": "1.0", 4 | "description": "Generates a unique code to authenticate the GM. Has no use on it's own, to be used with other code to provide more power to the GM.", 5 | "authors": "Tristan Beard", 6 | "roll20userid": "268993", 7 | "dependencies": {}, 8 | "modifies": { 9 | }, 10 | "conflicts": [ 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /GUMSHOE/HELP.md: -------------------------------------------------------------------------------- 1 | # GUMSHOE Engine for Roll20 2 | 3 | > A point-spending engine for GUMSHOE games on Roll20 4 | 5 | Currently Supported GUMSHOE Games: 6 | 7 | * Trail of Cthulhu 8 | 9 | ## Instructions 10 | 11 | See the [wiki page](https://wiki.roll20.net/Script:GUMSHOE) for the most up to date instructions. 12 | 13 | -------------------------------------------------------------------------------- /GUMSHOE/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "GUMSHOE", 3 | "version": "0.1", 4 | "description": "A point-spending script for GUMSHOE games. Integrates with supporting character sheets.", 5 | "authors": "Casey Link", 6 | "roll20userid": "388416", 7 | "dependencies": {}, 8 | "modifies": { 9 | "attribute": "write", 10 | "macro": "write", 11 | "character": "read" 12 | }, 13 | "conflicts": [] 14 | } 15 | -------------------------------------------------------------------------------- /GeigerCounter/README.md: -------------------------------------------------------------------------------- 1 | # Geiger Counter 2 | 3 | This script allows the GM to dynamically create radioactive areas in their 4 | maps. Characters that have Geiger counters will be alerted how many rads 5 | they are taking. 6 | 7 | ## To create a radioactive source object: 8 | 1. Create a token representing the source on the GM layer. 9 | 2. Set that token's 'radioactive' status marker to on. 10 | 3. Set its ```aura1 radius``` to the distance at which characters will start 11 | taking rads from it. 12 | 4. Set the ```bar1``` value to amount of rads/s characters will take at the edge 13 | of its aura. 14 | 5. Set the ```bar1 max value``` to the maximum amount of rads/s characters can take 15 | from it. 16 | 17 | ## To give a player a Geiger counter: 18 | 1. Give them a ```'hasGeigerCounter' attribute```. 19 | 2. Set the attribute to ```true```. 20 | 21 | If a character moves in a radioactive area and they have a Geiger counter, 22 | their Geiger counter will alert everyone how many rads/s they are taking. 23 | If a character moves in a radioactive area and they don't have a Geiger 24 | counter, only the GM will be alerted how many rads/s they are taking. 25 | -------------------------------------------------------------------------------- /GeigerCounter/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Geiger Counter", 3 | "script": "GeigerCounter.js", 4 | "version": "1.1", 5 | "previousversions": ["1.0"], 6 | "description": "# Geiger Counter\r\rThis script allows the GM to dynamically create radioactive areas in their maps. Characters that have Geiger counters will be alerted how many rads they are taking.\r\r## To create a radioactive source object:\r1. Create a token representing the source on the GM layer.\r2. Set that token's 'radioactive' status marker to on.\r3. Set its ```aura1 radius``` to the distance at which characters will start taking rads from it.\r4. Set the ```bar1``` value to amount of rads/s characters will take at the edge of its aura.\r5. Set the ```bar1 max value``` to the maximum amount of rads/s characters can take from it.\r\r## To give a player a Geiger counter:\r1. Give them a ```'hasGeigerCounter' attribute```.\r2. Set the attribute to ```true```.\r\rIf a character moves in a radioactive area and they have a Geiger counter, their Geiger counter will alert everyone how many rads/s they are taking. If a character moves in a radioactive area and they don't have a Geiger counter, only the GM will be alerted how many rads/s they are taking.", 7 | "authors": "Stephen Lindberg", 8 | "roll20userid": 46544, 9 | "useroptions": [], 10 | "dependencies": { 11 | }, 12 | "modifies": { 13 | "chat": "write", 14 | "aura1_radius": "read", 15 | "bar1_value": "read", 16 | "bar1_max": "read", 17 | "token": "read", 18 | "top": "read", 19 | "status_radioactive": "read" 20 | }, 21 | "conflicts": [] 22 | } 23 | -------------------------------------------------------------------------------- /HaloMythicUtilities/help.txt: -------------------------------------------------------------------------------- 1 | ## Halo Mythic Utilities 2 | 3 | * !specdmg [DAMAGE#] [PIERCE#] 4 | ** This command will take attack info then automatically roll on the hit location table, then the finger/toe table if necessary, then ask you for the armor for that location 5 | 6 | * !armor [ARMOR#] 7 | ** This command must be entered after prompted by !specdmg. After passing the armor in the final damage is calculated and information about the attack results is returned 8 | 9 | ## Changelog 10 | 11 | * 0.1.1 - fix pierce calculation 12 | * 0.1.0 - first release, with !specdmg and !armor commands -------------------------------------------------------------------------------- /HaloMythicUtilities/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Halo Mythic Utilities", 3 | "version": "0.1.1", 4 | "description": "Automatically handles hit location and special damage rolls.", 5 | "authors": "Brandon E.", 6 | "roll20userid": "157606", 7 | "dependencies": { 8 | }, 9 | "modifies": { 10 | }, 11 | "conflicts": [ 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /HiddenRolls/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "HiddenRolls", 3 | "version": "0.3", 4 | "description": "Various types of roll hiding (unmodified roll only, final result only, only show GM)", 5 | "authors": "manveti", 6 | "roll20userid": "503018", 7 | "dependencies": {}, 8 | "modifies": {}, 9 | "conflicts": [] 10 | } 11 | -------------------------------------------------------------------------------- /HtmlBuilder/README.md: -------------------------------------------------------------------------------- 1 | # HtmlBuilder 2 | 3 | This is a utility script that provides a library for constructing stylized 4 | HTML strings. It has no functionality of its own, but it can be used by other 5 | scripts to create HTML-formatted content to display in the chat. 6 | 7 | View the script's source file at 8 | https://github.com/Roll20/roll20-api-scripts/tree/master/HtmlBuilder 9 | for documentation. 10 | -------------------------------------------------------------------------------- /HtmlBuilder/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "HTML Builder", 3 | "script": "script.js", 4 | "version": "1.0", 5 | "previousversions": [], 6 | "description": "# HtmlBuilder\r\rThis is a utility script that provides a library for constructing stylized\rHTML strings. It has no functionality of its own, but it can be used by other\rscripts to create HTML-formatted content to display in the chat.\r\rView the script's source file at\rhttps://github.com/Roll20/roll20-api-scripts/tree/master/HtmlBuilder\rfor documentation.\r", 7 | "authors": "Stephen Lindberg", 8 | "roll20userid": 46544, 9 | "useroptions": [], 10 | "dependencies": [], 11 | "modifies": {}, 12 | "conflicts": [] 13 | } 14 | -------------------------------------------------------------------------------- /InitiativeAssistant/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "InitiativeAssistant", 3 | "version": "0.1.3", 4 | "description": "Provides an easy interface to adding players to the inititaive order.", 5 | "authors": "The Aaron", 6 | "roll20userid": "104025", 7 | "patreon": "https://www.patreon.com/shdwjk", 8 | "dependencies": {}, 9 | "modifies": { 10 | "state.InitiativeAssistant": "read,write", 11 | "campaign.turnorder": "read,write", 12 | "character.name": "read", 13 | "token.represents": "read" 14 | }, 15 | "conflicts": [], 16 | "script": "InitiativeAssistant.js", 17 | "useroptions": {}, 18 | "previousversions": [] 19 | } -------------------------------------------------------------------------------- /Interpreted sendChat/1.1/Interpreted sendChat.js: -------------------------------------------------------------------------------- 1 | on("chat:message", function(msg) { 2 | var message = ''; 3 | // Determine the contents of `message' 4 | 5 | var characters = findObjs({_type: 'character'}); 6 | var speaking; 7 | characters.forEach(function(chr) { if(chr.get('name') == msg.who) speaking = chr; }); 8 | 9 | if(speaking) sendChat('character|'+speaking.id, message); 10 | else sendChat('player|'+msg.playerid, message); 11 | }); -------------------------------------------------------------------------------- /Interpreted sendChat/2.0/Interpreted sendChat.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Sends a message to the chat as the same person who triggered a chat:message 3 | * event. In other words, if you're speaking out of character, the message will 4 | * be sent as you, and if you're speaking in-character, the message will be sent 5 | * as the character you have selected. 6 | * 7 | * Useful for sending messages on behalf of the player/character in response to 8 | * an API command. 9 | * 10 | * Example: 11 | 12 | on('chat:message', function(msg) { 13 | if (msg.type === 'api') { 14 | bshields.sendChat(msg, 'Hello World'); 15 | } 16 | }); 17 | 18 | */ 19 | var bshields = bshields || {}; 20 | bshields.sendChat = (function() { 21 | 'use strict'; 22 | 23 | var version = 2.0; 24 | 25 | function interpretedSendChat(chatMsg, message) { 26 | var who = chatMsg.who, 27 | speaking = _.sortBy(filterObjs(function(obj) { return obj.get('type') === 'character' && obj.get('name').indexOf(who) >= 0; }), 28 | function(chr) { return Math.abs(bshields.levenshteinDistance(chr.get('name'), who)); })[0]; 29 | 30 | sendChat(speaking ? 'character|' + speaking.id : 'player|' + chatMsg.playerid, message); 31 | } 32 | 33 | return interpretedSendChat; 34 | }()); -------------------------------------------------------------------------------- /Interpreted sendChat/2.1/Interpreted sendChat.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Sends a message to the chat as the same person who triggered a chat:message 3 | * event. In other words, if you're speaking out of character, the message will 4 | * be sent as you, and if you're speaking in-character, the message will be sent 5 | * as the character you have selected. 6 | * 7 | * Useful for sending messages on behalf of the player/character in response to 8 | * an API command. 9 | * 10 | * Example: 11 | 12 | on('chat:message', function(msg) { 13 | if (msg.type === 'api') { 14 | bshields.sendChat(msg, 'Hello World'); 15 | } 16 | }); 17 | 18 | */ 19 | var bshields = bshields || {}; 20 | bshields.sendChat = (function() { 21 | 'use strict'; 22 | 23 | var version = 2.1; 24 | 25 | function interpretedSendChat(chatMsg, message) { 26 | var who = chatMsg.who, 27 | speaking = _.sortBy(filterObjs(function(obj) { return obj.get('type') === 'character' && obj.get('name').indexOf(who) >= 0; }), 28 | function(chr) { return chr.get('name').toLowerCase().levenshteinDistance(who.toLowerCase()); })[0]; 29 | 30 | sendChat(speaking ? 'character|' + speaking.id : 'player|' + chatMsg.playerid, message); 31 | } 32 | 33 | return interpretedSendChat; 34 | }()); 35 | -------------------------------------------------------------------------------- /Interpreted sendChat/2.2/Interpreted sendChat.js: -------------------------------------------------------------------------------- 1 | var bshields = bshields || {}; 2 | bshields.sendChat = (function() { 3 | 'use strict'; 4 | 5 | var version = 2.2; 6 | 7 | function interpretedSendChat(chatMsg, message) { 8 | var who = chatMsg.who, 9 | speaking = _.sortBy(filterObjs(function(obj) { return obj.get('type') === 'character' && obj.get('name').indexOf(who) >= 0; }), 10 | function(chr) { return chr.get('name').toLowerCase().levenshteinDistance(who.toLowerCase()); })[0]; 11 | 12 | sendChat(speaking ? 'character|' + speaking.id : 'player|' + chatMsg.playerid, message); 13 | } 14 | 15 | return interpretedSendChat; 16 | }()); 17 | -------------------------------------------------------------------------------- /Interpreted sendChat/README.md: -------------------------------------------------------------------------------- 1 | ## Interpreted sendChat 2 | 3 | Provides a function for other scripts to use to assist in sending messages to the chat. This script is not intended to stand alone. 4 | 5 | `bshields.sendChat` will send a message as the same user or character that was used in the message object passed as the first parameter. This is useful for sending messages on behalf of a user in response to an API command, for example. -------------------------------------------------------------------------------- /Interpreted sendChat/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Interpreted sendChat", 3 | "script": "Interpreted sendChat.js", 4 | "version": "2.2", 5 | "previousversions": ["2.1","2.0","1.1"], 6 | "description": "Provides a function for other scripts to use to assist in sending messages to the chat. This script is not intended to stand alone.", 7 | "authors": "Brian Shields", 8 | "roll20userid": "235259", 9 | "patreon": "https://www.patreon.com/bshields", 10 | "useroptions": [], 11 | "dependencies": ["levenshteinDistance"], 12 | "modifies": { 13 | "character.type": "read", 14 | "character.name": "read" 15 | }, 16 | "conflicts": [] 17 | } 18 | -------------------------------------------------------------------------------- /InventoryManager/Readme.md: -------------------------------------------------------------------------------- 1 | ## Inventory Manager 2 | 3 | This script aims to provide a graphical user interface for inventory management. Ideally you will create a seperate campaign where your players can manage their inventories in a graphical way with tokens representing their items. -------------------------------------------------------------------------------- /InventoryManager/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Inventory Manager", 3 | "version": "1.0", 4 | "description": "A graphical inventory manager. Inspired by John C.", 5 | "authors": "Jonathan Burke", 6 | "roll20userid": "682814", 7 | "dependencies": { 8 | }, 9 | "modifies": { 10 | "bar1_value": "write", 11 | "bar1_max": "write", 12 | "bar2_value": "write", 13 | "bar2_max": "write", 14 | "bar3_value": "write", 15 | "status_markers": "write", 16 | "token": "write" 17 | }, 18 | "conflicts": [ 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /IsGM/README.md: -------------------------------------------------------------------------------- 1 | ***DEPRECATED*** 2 | 3 | For new scripts, you should use the playerIsGM() function that is now built into Roll20. 4 | 5 | -------------------------------------------------------------------------------- /IsGM/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "IsGMModule", 3 | "version": "0.7.1", 4 | "description": "Adds a function, isGM(id), which returns true for gms and false for players. GM database is built in the state object automatically as players and gms send chat messages.", 5 | "authors": "The Aaron", 6 | "roll20userid": "104025", 7 | "patreon": "https://www.patreon.com/shdwjk", 8 | "dependencies": [], 9 | "modifies": { 10 | "state.IsGM": "read,write", 11 | "player.displayname": "read", 12 | "player.speakingas": "read" 13 | }, 14 | "conflicts": [], 15 | "script": "IsGM.js", 16 | "useroptions": {}, 17 | "previousversions": [] 18 | } -------------------------------------------------------------------------------- /IsGreater/0.2.1/IsGreater.js: -------------------------------------------------------------------------------- 1 | // Github: https://github.com/shdwjk/Roll20API/blob/master/IsGreater/IsGreater.js 2 | // By: The Aaron, Arcane Scriptomancer 3 | // Contact: https://app.roll20.net/users/104025/the-aaron 4 | 5 | var IsGreater = IsGreater || (function() { 6 | 'use strict'; 7 | 8 | var version = '0.2.1', 9 | lastUpdate = 1427604251, 10 | 11 | checkInstall = function() { 12 | log('-=> IsGreater v'+version+' <=- ['+(new Date(lastUpdate*1000))+']'); 13 | }, 14 | 15 | handleInput = function(msg) { 16 | var args; 17 | 18 | if (msg.type !== "api") { 19 | return; 20 | } 21 | 22 | if(_.has(msg,'inlinerolls')){ 23 | msg.content = _.chain(msg.inlinerolls) 24 | .reduce(function(m,v,k){ 25 | m['$[['+k+']]']=v.results.total || 0; 26 | return m; 27 | },{}) 28 | .reduce(function(m,v,k){ 29 | return m.replace(k,v); 30 | },msg.content) 31 | .value(); 32 | } 33 | 34 | args = msg.content.split(/\s+/); 35 | switch(args[0]) { 36 | 37 | case '!isgreater': 38 | if(args[1] > args[2]) { 39 | sendChat('','Result: Success'); 40 | } else { 41 | sendChat('','Result: Failure'); 42 | } 43 | break; 44 | } 45 | }, 46 | 47 | registerEventHandlers = function() { 48 | on('chat:message', handleInput); 49 | }; 50 | 51 | return { 52 | CheckInstall: checkInstall, 53 | RegisterEventHandlers: registerEventHandlers 54 | }; 55 | }()); 56 | 57 | on("ready",function(){ 58 | 'use strict'; 59 | 60 | IsGreater.CheckInstall(); 61 | IsGreater.RegisterEventHandlers(); 62 | }); 63 | -------------------------------------------------------------------------------- /IsGreater/IsGreater.js: -------------------------------------------------------------------------------- 1 | // Github: https://github.com/shdwjk/Roll20API/blob/master/IsGreater/IsGreater.js 2 | // By: The Aaron, Arcane Scriptomancer 3 | // Contact: https://app.roll20.net/users/104025/the-aaron 4 | 5 | var IsGreater = IsGreater || (function() { 6 | 'use strict'; 7 | 8 | var version = '0.2.1', 9 | lastUpdate = 1427604251, 10 | 11 | checkInstall = function() { 12 | log('-=> IsGreater v'+version+' <=- ['+(new Date(lastUpdate*1000))+']'); 13 | }, 14 | 15 | handleInput = function(msg) { 16 | var args; 17 | 18 | if (msg.type !== "api") { 19 | return; 20 | } 21 | 22 | if(_.has(msg,'inlinerolls')){ 23 | msg.content = _.chain(msg.inlinerolls) 24 | .reduce(function(m,v,k){ 25 | m['$[['+k+']]']=v.results.total || 0; 26 | return m; 27 | },{}) 28 | .reduce(function(m,v,k){ 29 | return m.replace(k,v); 30 | },msg.content) 31 | .value(); 32 | } 33 | 34 | args = msg.content.split(/\s+/); 35 | switch(args[0]) { 36 | 37 | case '!isgreater': 38 | if(args[1] > args[2]) { 39 | sendChat('','Result: Success'); 40 | } else { 41 | sendChat('','Result: Failure'); 42 | } 43 | break; 44 | } 45 | }, 46 | 47 | registerEventHandlers = function() { 48 | on('chat:message', handleInput); 49 | }; 50 | 51 | return { 52 | CheckInstall: checkInstall, 53 | RegisterEventHandlers: registerEventHandlers 54 | }; 55 | }()); 56 | 57 | on("ready",function(){ 58 | 'use strict'; 59 | 60 | IsGreater.CheckInstall(); 61 | IsGreater.RegisterEventHandlers(); 62 | }); 63 | -------------------------------------------------------------------------------- /IsGreater/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "IsGreater", 3 | "version": "0.2.1", 4 | "description": "Trivial little script to check if the first value is greater than the second and report it to chat.", 5 | "authors": "The Aaron", 6 | "roll20userid": "104025", 7 | "patreon": "https://www.patreon.com/shdwjk", 8 | "dependencies": [], 9 | "modifies": [], 10 | "conflicts": [], 11 | "script": "IsGreater.js", 12 | "useroptions": {}, 13 | "previousversions": [] 14 | } -------------------------------------------------------------------------------- /Its A Trap/ItsATrap.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlenser/roll20-api-scripts/65a254bd1d44764076cf808e6c50abc995ee6938/Its A Trap/ItsATrap.gif -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014-2016 Roll20 and/or Individual Authors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Languages/help.txt: -------------------------------------------------------------------------------- 1 | Introduction: 2 | This script is a re-work of "WhatSaywithUnknown.js" by derekkoehl which is an enhancement on "What Did He Say?" by Stephen S. 3 | 4 | Forum Post: 5 | https://app.roll20.net/forum/post/2723217/script-languages 6 | 7 | Command 1: 8 | !theLanguage {theText} 9 | Example: 10 | > !Draconic hello there dragonborn 11 | Result: 12 | - If the player who enters this is speaking as a character that has Draconic, under the languages on their character sheet, they will say "hello there dragonborn" in Draconic. Any player who is currently online and is speaking as a character that also has Draconic on their character sheet will be whispered "hello there dragonborn". Others will be whispered symbols representing the language. 13 | - If the player who enters this is speaking as a character that does not have Draconic(under languages on their character sheet), they will "pretend to speak" Draconic. 14 | - If the player who enters this is speaking as a player, they will be notified that players cannot speak character languages. 15 | - GMs can speak any language with any player or character 16 | 17 | Command 2: 18 | !setLanguageTag {attribute name} 19 | Example: 20 | > !setLanguageTag playerlanguages 21 | Result: 22 | - If the player who enters this is a GM and playerlanguages is the name of a character sheet attribute in the campaign, the script will use "playerlanguages" when it searches character sheet attributes for player's languages (instead of the default "prolanguages") 23 | 24 | Command 3: 25 | !deleteLanguage {language name} 26 | Example: 27 | !deleteLanguage Dwarven 28 | Result: 29 | - If the player is a GM, Dwarven will be deleted as a language 30 | 31 | Command 4. 32 | !createLanguage {language name} {seed nubmer} {parent language} 33 | Example: 34 | !createLanguage Underdwarven 5 Dwarven 35 | Result: 36 | - If the player is a GM, Underdwarven will be created as a seed 5 language of Dwarven 37 | 38 | Languages: 39 | Abyssal Aquan Auran Celestial Common Draconic Druidic 40 | Druidic Dwarven Elven Giant Gnome Goblin Gnoll 41 | Halfling Ignan Infernal Orc Sylvan Terran Thieves'Cant 42 | Undercommon Unknown 43 | 44 | Future Plans: 45 | Create command for adding customized languages 46 | 47 | Notes: 48 | Please contact me if you find any bugs or have ideas for features that I can add to this script -------------------------------------------------------------------------------- /Languages/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Languages", 3 | "version": "1.1.1", 4 | "description": "An easy to use, fully function languages tool for all settings", 5 | "authors": "Anthony Tasca", 6 | "roll20userid": "1000007", 7 | "dependencies": [], 8 | "modifies": { 9 | "LanguageScript": "read,write" 10 | }, 11 | "conflicts": [] 12 | } -------------------------------------------------------------------------------- /ManualAttribute/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ManualAttribute", 3 | "version": "0.2.1", 4 | "description": "Creates a manual copy of an autocalculated field, and assigns it to the bar of a token.", 5 | "authors": "The Aaron", 6 | "roll20userid": "104025", 7 | "patreon": "https://www.patreon.com/shdwjk", 8 | "dependencies": [], 9 | "modifies": { 10 | "attribute": "create", 11 | "attribute.current": "write", 12 | "attribute.max": "read,write", 13 | "graphic.bar*_link": "write", 14 | "graphic.represents": "read" 15 | }, 16 | "conflicts": [], 17 | "script": "ManualAttribute.js", 18 | "useroptions": {}, 19 | "previousversions": [] 20 | } -------------------------------------------------------------------------------- /MapChange/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "MapChange", 3 | "script": "MapChange.js", 4 | "version": "1.3", 5 | "description": "Provides a way for users to move between maps in a campaign without the GM needing to move them.\n\nFor full information on how to use the script, use the command '!mc help' in game.", 6 | "authors": "TheWhiteWolves", 7 | "roll20userid": "1043", 8 | "patreon": "", 9 | "useroptions": [{ 10 | "name": "Debug Mode", 11 | "type": "checkbox", 12 | "description": "Set to true to use built in debug statements", 13 | "value": "false" 14 | }, { 15 | "name": "GM Notification", 16 | "type": "checkbox", 17 | "description": "Set to true to turn on notifing the GM when events happen.", 18 | "value": "false" 19 | }, { 20 | "name": "Marker", 21 | "type": "text", 22 | "default": "[GM]", 23 | "description": "The marker used to decide what is placed in the private map." 24 | }, { 25 | "name": "Hide Marker", 26 | "type": "text", 27 | "default": "[Hide]", 28 | "description": "The marker used to decide what is placed in the hidden map." 29 | }, { 30 | "name": "Inverted Marker", 31 | "type": "checkbox", 32 | "description": "When true this places the pages with name containing the marker into the public list.\nUse this if you want maps to be private by default instead of public by default.", 33 | "value": "false" 34 | }], 35 | "dependencies": [], 36 | "modifies": { 37 | "Campaign.playerpageid": "read,write", 38 | "Campaign.playerspecificpages": "read,write", 39 | "Page.name": "read", 40 | "Page._id": "read", 41 | "Page.archived": "read", 42 | "Player._displayname": "read", 43 | "Player._id": "read", 44 | "state.MapChange": "read,write" 45 | }, 46 | "conflicts": [], 47 | "previousversions": [1.0, 1.1, 1.2] 48 | } 49 | -------------------------------------------------------------------------------- /MapLock/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "MapLock", 3 | "version": "0.4.3", 4 | "description": "Provides locking of graphics to prevent moving/resizing/rotating them. Also highlighting.\r\rSee `!map-lock --help` from the console for help and configuration options.", 5 | "authors": "The Aaron", 6 | "roll20userid": "104025", 7 | "patreon": "https://www.patreon.com/shdwjk", 8 | "dependencies": [], 9 | "modifies": { 10 | "state.MapLock": "read,write", 11 | "graphic.height": "read,write", 12 | "graphic.left": "read,write", 13 | "graphic.rotation": "read,write", 14 | "graphic.tint_color": "read,write", 15 | "graphic.top": "read,write", 16 | "graphic.width": "read,write", 17 | "player.displayname": "read" 18 | }, 19 | "conflicts": [], 20 | "script": "MapLock.js", 21 | "useroptions": [], 22 | "previousversions": [ 23 | "0.4.1" 24 | ] 25 | } -------------------------------------------------------------------------------- /MapSnap/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "MapSnap", 3 | "version": "0.1.3", 4 | "description": "", 5 | "authors": "The Aaron", 6 | "roll20userid": "104025", 7 | "patreon": "https://www.patreon.com/shdwjk", 8 | "dependencies": {}, 9 | "modifies": { 10 | "state.MapSnap": "read,write", 11 | "graphic.top": "read,write", 12 | "graphic.left": "read,write" 13 | }, 14 | "conflicts": [], 15 | "script": "MapSnap.js", 16 | "useroptions": {}, 17 | "previousversions": [] 18 | } -------------------------------------------------------------------------------- /MarchingOrder/README.md: -------------------------------------------------------------------------------- 1 | # Marching Order 2 | 3 | _v2.1 Updates_ 4 | * The script now has a chat menu interface accessible through the 'showMarchingOrderMenu' macro. 5 | 6 | This script allows you to select tokens and tell them to follow each other 7 | in some specified marching order. 8 | 9 | ### To set one token to follow another 10 | 11 | Select the token that will be the follower. 12 | From the menu, click the 'Follow' button. In the prompt, enter the name of 13 | the token you want to follow. 14 | 15 | You can use this method consecutively for pairs of leader/follower 16 | tokens to specify a chain of tokens to be in some marching order. 17 | 18 | ### To specify several tokens making up a marching order 19 | 20 | Arrange the tokens in order from west to east, east to west, south to north, 21 | or north to south. 22 | 23 | Select all the tokens that will be in the marching order. 24 | 25 | In the menu, click 'North', 'East', South', or 'West'. 26 | 27 | For 'North', the northmost token will be the leader in the marching order 28 | and the southmost token will be the caboose. The same pattern follows for 29 | the other cardinal directions. 30 | 31 | ### To make tokens stop following each other 32 | 33 | Just manually drag-and-drop the token out of the marching order. 34 | They will step out of line in the marching order, but the rest of the 35 | marching order will be unaffected. If a token was following the token 36 | that stepped out of line, they will instead follow the token that the token 37 | which stepped out of line was following. 38 | -------------------------------------------------------------------------------- /MarchingOrder/demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlenser/roll20-api-scripts/65a254bd1d44764076cf808e6c50abc995ee6938/MarchingOrder/demo.gif -------------------------------------------------------------------------------- /MarchingOrder/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Marching Order", 3 | "script": "marchingOrder.js", 4 | "version": "2.1", 5 | "previousversions": ["2.0"], 6 | "description": "# Marching Order\r\r_v2.1 Updates_\r* The script now has a chat menu interface accessible through the 'showMarchingOrderMenu' macro.\r\rThis script allows you to select tokens and tell them to follow each other\rin some specified marching order.\r\r### To set one token to follow another\r\rSelect the token that will be the follower.\rFrom the menu, click the 'Follow' button. In the prompt, enter the name of\rthe token you want to follow.\r\rYou can use this method consecutively for pairs of leader/follower\rtokens to specify a chain of tokens to be in some marching order.\r\r### To specify several tokens making up a marching order\r\rArrange the tokens in order from west to east, east to west, south to north,\ror north to south.\r\rSelect all the tokens that will be in the marching order.\r\rIn the menu, click 'North', 'East', South', or 'West'.\r\rFor 'North', the northmost token will be the leader in the marching order\rand the southmost token will be the caboose. The same pattern follows for\rthe other cardinal directions.\r\r### To make tokens stop following each other\r\rJust manually drag-and-drop the token out of the marching order.\rThey will step out of line in the marching order, but the rest of the\rmarching order will be unaffected. If a token was following the token\rthat stepped out of line, they will instead follow the token that the token\rwhich stepped out of line was following.\r", 7 | "authors": "Stephen Lindberg", 8 | "roll20userid": 46544, 9 | "useroptions": [], 10 | "dependencies": {}, 11 | "modifies": { 12 | "left": "read, write", 13 | "rotation": "read, write", 14 | "token": "read", 15 | "top": "read, write" 16 | }, 17 | "conflicts": [] 18 | } 19 | -------------------------------------------------------------------------------- /Mark/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Mark", 3 | "version": "0.3.3", 4 | "description": "Mark places a numbered marker under each token whose id is supplied to it. Markers are cleared when the Turn Order changes, is closed, or when the player page changes. This script is intended to allow players to mark their targets for discussion with the GM, usually as part of an attack.\r\r## Commands\r\r```!mark [ ... ]```\r\rThis command requires a minimum of `1` parameter. For each supplied Token ID, a marker is placed beneath it with a numbered status. The status number starts at `1`, increases with each marker placed, and resets the when markers are cleared.\r\r**Note:** If you are using multiple `@{target|token_id}` calls in a macro, and need to mark fewer than the suppled number of arguments, simply select the same token several times. The duplicates will be removed.\r\r* `` -- A Token ID, usually supplied with something like `@{target|Target 1|token_id}`.\r\r```!mark-clear ```\r\rClears all the markers. (GM Only)", 5 | "authors": "The Aaron", 6 | "roll20userid": "104025", 7 | "patreon": "https://www.patreon.com/shdwjk", 8 | "dependencies": [], 9 | "modifies": { 10 | "state.Mark": "read,write", 11 | "campaign.initiativepage": "read", 12 | "campaign.playerpageid": "read", 13 | "campaign.playherspecificpages": "read", 14 | "campaign.turnorder": "read", 15 | "player.displayname": "read", 16 | "graphic.height": "read,write", 17 | "graphic.layer": "read,write", 18 | "graphic.left": "read,write", 19 | "graphic.statusmarkers": "read,write", 20 | "graphic.top": "read,write", 21 | "graphic.width": "read,write" 22 | }, 23 | "conflicts": [], 24 | "script": "Mark.js", 25 | "useroptions": [], 26 | "previousversions": [ 27 | "0.3.2" 28 | ] 29 | } -------------------------------------------------------------------------------- /Marking Conditions/README.md: -------------------------------------------------------------------------------- 1 | ## Marking Conditions 2 | 3 | Allows marking targeted or selected tokens with statusmarkers either directly by name (if known), or by a number of aliases based on D&D 4e statuses. 4 | 5 | Statusmarkers can be set with `!mark tokenid [status [type]]` or removed with `!unmark tokenid [status [type]]`, where _tokenid_ is a token object's id (obtained with `@{target|token_id}` or `@{selected|token_id}`), _status_ is the status to set (defaults to `purple` if ommitted), and _type_ is a D&D 4e damage type (only used if _status_ is "ongoing", "damage", or "dam"). 6 | 7 | The D&D 4e damage types are: 8 | 9 | * acid 10 | * cold 11 | * fire 12 | * force 13 | * lightning 14 | * necrotic 15 | * poison 16 | * psychic 17 | * radiant 18 | * thunder 19 | 20 | If _status_ is a value that requires a damage type parameter and none is provided, an icon for "untyped" damage will be used. -------------------------------------------------------------------------------- /Marking Conditions/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Marking Conditions", 3 | "script": "Marking Conditions.js", 4 | "version": "3.3", 5 | "previousversions": ["3.2","3.1","3.0","2.0","1.1","1.0"], 6 | "description": "Sets and removes statusmarkers on tokens.", 7 | "authors": "Brian Shields", 8 | "roll20userid": "235259", 9 | "patreon": "https://www.patreon.com/bshields", 10 | "useroptions": [], 11 | "dependencies": ["splitArgs"], 12 | "modifies": { 13 | "token.statusmarkers": "write" 14 | }, 15 | "conflicts": [] 16 | } 17 | -------------------------------------------------------------------------------- /Markov/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Markov", 3 | "script": "Markov.js", 4 | "version": "0.1.0", 5 | "previousversions": [], 6 | "description": "A simple name generator that uses markov chains\r\rTo use enter !markov in the chat and a new name will be generated using a markov chain.", 7 | "authors": "Ryan Jentzsch (retooled into Roll20 based on works created by drow and released into the public domain)", 8 | "roll20userid": "1638601", 9 | "patreon": "https://patreon.com/user?u=3985594", 10 | "modifies": { 11 | "state.marokov": "read,write" 12 | }, 13 | "conflicts": [], 14 | "useroptions": [] 15 | } 16 | -------------------------------------------------------------------------------- /Measure/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Measure", 3 | "version": "0.3.1", 4 | "description": "Measure distances between multiple tokens, both from the corners and the center.", 5 | "authors": "The Aaron", 6 | "roll20userid": "104025", 7 | "patreon": "https://www.patreon.com/shdwjk", 8 | "dependencies": [], 9 | "modifies": { 10 | "graphic.height": "read", 11 | "graphic.left": "read", 12 | "graphic.name": "read", 13 | "graphic.top": "read", 14 | "graphic.width": "read", 15 | "page.scale_number": "read", 16 | "page.scale_units": "read" 17 | }, 18 | "conflicts": [], 19 | "script": "Measure.js", 20 | "useroptions": {}, 21 | "previousversions": [] 22 | } -------------------------------------------------------------------------------- /MotD/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Message of the Day", 3 | "version": "0.2.1", 4 | "description": "Greets players that log in with the contents of a particular note.", 5 | "authors": "The Aaron", 6 | "roll20userid": "104025", 7 | "patreon": "https://www.patreon.com/shdwjk", 8 | "dependencies": [], 9 | "modifies": { 10 | "handout.archived": "read", 11 | "handout.name": "read", 12 | "handout.notes": "read,write", 13 | "handout.type": "read", 14 | "player.displayname": "read", 15 | "player.online": "read" 16 | }, 17 | "conflicts": [], 18 | "script": "MotD.js", 19 | "useroptions": {}, 20 | "previousversions": [] 21 | } -------------------------------------------------------------------------------- /MovePlayers/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "MovePlayers", 3 | "version": "0.2.1", 4 | "description": "Allows macros to move the player ribbon for players.", 5 | "authors": "The Aaron", 6 | "roll20userid": "104025", 7 | "patreon": "https://www.patreon.com/shdwjk", 8 | "dependencies": [], 9 | "modifies": { 10 | "campaign.playerpageid": "write", 11 | "graphic.pageid": "read" 12 | }, 13 | "conflicts": [], 14 | "script": "MovePlayers.js", 15 | "useroptions": {}, 16 | "previousversions": [] 17 | } -------------------------------------------------------------------------------- /MutantYearZero/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "MutantYearZero", 3 | "version": "0.1.8", 4 | "description": "!myz and !wmyz provide the Mutant Year Zero dice mechanics.", 5 | "authors": "The Aaron", 6 | "roll20userid": "104025", 7 | "patreon": "https://www.patreon.com/shdwjk", 8 | "dependencies": {}, 9 | "modifies": { 10 | "state.MutantYearZero": "read,write" 11 | }, 12 | "conflicts": [], 13 | "script": "MutantYearZero.js", 14 | "useroptions": {}, 15 | "previousversions": [] 16 | } -------------------------------------------------------------------------------- /No Token Rotation/1.0/No Token Rotation.js: -------------------------------------------------------------------------------- 1 | on('change:graphic:rotation', function(obj, prev) { obj.set('rotation', 0); }); -------------------------------------------------------------------------------- /No Token Rotation/1.1/No Token Rotation.js: -------------------------------------------------------------------------------- 1 | on('change:graphic:rotation', function(obj, prev) { obj.set('rotation', prev.rotation); }); -------------------------------------------------------------------------------- /No Token Rotation/README.md: -------------------------------------------------------------------------------- 1 | ## No Token Rotation 2 | 3 | Prevents tokens from being rotated by anyone (including the GM). Any tokens which were already rotated will remain so. -------------------------------------------------------------------------------- /No Token Rotation/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "No Token Rotation", 3 | "script": "No Token Rotation.js", 4 | "version": "1.1", 5 | "previousversions": ["1.0"], 6 | "description": "Prevents tokens from being rotated by anyone.", 7 | "authors": "Brian Shields", 8 | "roll20userid": "235259", 9 | "patreon": "https://www.patreon.com/bshields", 10 | "useroptions": [], 11 | "dependencies": [], 12 | "modifies": { 13 | "token.rotation": "write" 14 | }, 15 | "conflicts": [] 16 | } 17 | -------------------------------------------------------------------------------- /NoteLog/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "NoteLog", 3 | "version": "0.1.1", 4 | "description": "", 5 | "authors": "The Aaron", 6 | "roll20userid": "104025", 7 | "patreon": "https://www.patreon.com/shdwjk", 8 | "dependencies": {}, 9 | "modifies": { 10 | "state.NoteLog": "read,write", 11 | "handout.notes": "read,write" 12 | }, 13 | "conflicts": [], 14 | "script": "NoteLog.js", 15 | "useroptions": {}, 16 | "previousversions": [] 17 | } -------------------------------------------------------------------------------- /Numenera_Natha/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Natha's Numenera", 3 | "script": "Numenera_Natha.js", 4 | "previousversions" : [], 5 | "version": "4.8", 6 | "description": "Enables the use of advance rolls and functions in Natha's Numenera Tabbed character sheets (both english and french) version 4+. Read the [Wiki page](https://wiki.roll20.net/Script:Numenera_Natha) for help about chat commands and macros.", 7 | "authors": "Natha", 8 | "roll20userid": "75857", 9 | "useroptions": [], 10 | "dependencies": {}, 11 | "modifies": { 12 | "token": "write", 13 | "bar1_value": "write", 14 | "bar2_value": "write", 15 | "bar3_value": "write", 16 | "character": "write" 17 | }, 18 | "conflicts": ["Cypher System Sheet"] 19 | } 20 | -------------------------------------------------------------------------------- /ObjectProperties/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ObjectProperties", 3 | "version": "0.1", 4 | "description": "Get and set properties of selected/specified Roll20 objects.", 5 | "authors": "manveti", 6 | "roll20userid": "503018", 7 | "dependencies": {}, 8 | "modifies": {}, 9 | "conflicts": [] 10 | } 11 | -------------------------------------------------------------------------------- /PCPP/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "PCPP", 3 | "version": "0.3.1", 4 | "description": "PowerCard PreProcessor - Provides API time evaluation and preprocessing of commands for PowerCards v1 or v2.", 5 | "authors": "The Aaron", 6 | "roll20userid": "104025", 7 | "patreon": "https://www.patreon.com/shdwjk", 8 | "dependencies": {}, 9 | "modifies": { 10 | "state.PCPP": "read,write" 11 | }, 12 | "conflicts": [], 13 | "script": "PCPP.js", 14 | "useroptions": {}, 15 | "previousversions": [] 16 | } -------------------------------------------------------------------------------- /Page Navigator/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Page Navigator", 3 | "script": "PageNavigator.js", 4 | "version": "1.43", 5 | "previousversions": ["1.42","1.4","1.3","1.031"], 6 | "description": "Page Navigator allows you to more easily move your players from page to page. You can utilize the script through API commands or by relying on token collisions to provide a more interactive map for your players. Use !nav help in game to bring up a help dialog with details on using all the scripts features. Use !nav config to setup Page Navigator according to your preferences. If you were using a previous version of Page Navigator, the player page tag has changed to .players due to how variables interact with strings.", 7 | "authors": "Scott C.", 8 | "roll20userid": "459831", 9 | "useroptions": [], 10 | "dependencies": ["Token Collisions","Path Math","Vector Math","Matrix Math"], 11 | "modifies": { 12 | "Campaign.playerpageid": "read,write", 13 | "Campaign.playerspecificpages": "read,write", 14 | "state.PAGENAVIGATOR.version": "read,write", 15 | "token.statusmarker": "read", 16 | "token.gmnotes":"read", 17 | "character.defaulttoken":"read" 18 | }, 19 | "conflicts": [] 20 | } -------------------------------------------------------------------------------- /PageFX/PageFX.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlenser/roll20-api-scripts/65a254bd1d44764076cf808e6c50abc995ee6938/PageFX/PageFX.gif -------------------------------------------------------------------------------- /PageSize/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "PageSize", 3 | "version": "0.1", 4 | "description": "Resize page, optionally moving or scaling its contents in the process.", 5 | "authors": "manveti", 6 | "roll20userid": "503018", 7 | "dependencies": {}, 8 | "modifies": {}, 9 | "conflicts": [] 10 | } 11 | -------------------------------------------------------------------------------- /PathSplitter/README.md: -------------------------------------------------------------------------------- 1 | # Path Splitter 2 | 3 | ###### Required Scripts 4 | * [Matrix Math](https://github.com/Roll20/roll20-api-scripts/tree/master/MatrixMath) 5 | * [Path Math](https://github.com/Roll20/roll20-api-scripts/tree/master/PathMath) 6 | * [Vector Math](https://github.com/Roll20/roll20-api-scripts/tree/master/Vector%20Math) 7 | 8 | This script allows players to split up a polygonal path by drawing another 9 | polygonal path on top of it. The original path is split up where it intersects 10 | the splitting path. This script also supports scaled and rotated paths. 11 | 12 | ## To use: 13 | 14 | 1) Draw a a polygonal path over the path your want to split up. Set this path to 15 | the splitting path color (by default this is pink: #ff00ff). 16 | 17 | 2) Select the path you want to split and the splitting path. 18 | 19 | 3) In the chat, enter the command ```!pathSplit```. 20 | 21 | ## Changing the splitting path color: 22 | 23 | By default, the reserved color for the splitting path is pink (#ff00ff). 24 | To change it, set your splitting path to whichever color you want to use. 25 | Then, select it and enter the command ```!pathSplitColor``` in the chat. 26 | -------------------------------------------------------------------------------- /PathSplitter/demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlenser/roll20-api-scripts/65a254bd1d44764076cf808e6c50abc995ee6938/PathSplitter/demo.gif -------------------------------------------------------------------------------- /PathSplitter/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Path Splitter", 3 | "script": "PathSplitter.js", 4 | "version": "1.0", 5 | "previousversions": [], 6 | "description": "# Path Splitter\r\r###### Required Scripts\r* [Matrix Math](https://github.com/Roll20/roll20-api-scripts/tree/master/MatrixMath)\r* [Path Math](https://github.com/Roll20/roll20-api-scripts/tree/master/PathMath)\r* [Vector Math](https://github.com/Roll20/roll20-api-scripts/tree/master/Vector%20Math)\r\rThis script allows players to split up a polygonal path by drawing another polygonal path on top of it. The original path is split up where it intersects the splitting path. This script also supports scaled and rotated paths.\r\r## To use:\r\r1) Draw a a polygonal path over the path your want to split up. Set this path to the splitting path color (by default this is pink: #ff00ff).\r\r2) Select the path you want to split and the splitting path.\r\r3) In the chat, enter the command ```!pathSplit```.\r\r## Changing the splitting path color:\r\rBy default, the reserved color for the splitting path is pink (#ff00ff). To change it, set your splitting path to whichever color you want to use. Then, select it and enter the command ```!pathSplitColor``` in the chat.", 7 | "authors": "Stephen Lindberg", 8 | "roll20userid": 46544, 9 | "useroptions": [], 10 | "dependencies": ["Matrix Math", "Path Math", "Vector Math"], 11 | "modifies": { 12 | "path": "read, write" 13 | }, 14 | "conflicts": [] 15 | } 16 | -------------------------------------------------------------------------------- /Pathfinder HeroLab Import/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Pathfinder HeroLab Character Import", 3 | "script": "HL-Import.js", 4 | "version": "0.5", 5 | "description": "A script for importing characters from Hero Lab to the Pathfinder character sheet; visit the forum thread for usage: https://wiki.roll20.net/Script:HL-Import", 6 | "authors": "James W.", 7 | "roll20userid": "92730", 8 | "useroptions": [], 9 | "dependencies": [], 10 | "modifies": { 11 | "attribute.characterid": "read,write", 12 | "attribute.current": "read,write", 13 | "attribute.id": "read,write", 14 | "attribute.name": "read,write", 15 | "attribute.type": "read", 16 | "character.name": "read,write", 17 | "graphic.represents": "read,write" 18 | }, 19 | "conflicts": [], 20 | "previousversions": [ ] 21 | } -------------------------------------------------------------------------------- /Pathfinder PCGen Import/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Pathfinder PCGen Import", 3 | "script": "PCGenPFImport.js", 4 | "version": "1.0", 5 | "previousversions": [], 6 | "description": "This script allows for the import of characters from PCGen to Roll20. For instructions on use please refer to the wiki page https://wiki.roll20.net/Script:PCGenPFImport", 7 | "authors": "Norman G.", 8 | "roll20userid": "1109365", 9 | "useroptions": [], 10 | "dependencies": [], 11 | "modifies": { 12 | "attribute.characterid": "read,write", 13 | "attribute.current": "read,write", 14 | "attribute.id": "read,write", 15 | "attribute.name": "read,write", 16 | "attribute.type": "read", 17 | "character.name": "read,write", 18 | "graphic.represents": "read,write" 19 | }, 20 | "conflicts": [] 21 | } 22 | -------------------------------------------------------------------------------- /Pathfinder Skillbook/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Pathfinder Skillbook", 3 | "script": "Skillbook.js", 4 | "version": "1.11", 5 | "description": "Creates a token action to provide API buttons for each of a character's skills; for use with the Pathfinder character sheet. Use v1.0 for the current version (v.37) of the character sheet; use v1.1 for newer versions with extra Artistry and Lore skills.", 6 | "authors": "James W.", 7 | "roll20userid": "92730", 8 | "useroptions": [], 9 | "dependencies": [], 10 | "modifies": { 11 | "attribute.characterid": "read,write", 12 | "attribute.current": "read,write", 13 | "attribute.id": "read,write", 14 | "attribute.name": "read,write", 15 | "attribute.type": "read", 16 | "character.name": "read,write" 17 | }, 18 | "conflicts": [], 19 | "previousversions": [ "1.1", "1.0" ] 20 | } -------------------------------------------------------------------------------- /PortesMonstresTresors/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Portes Monstres Tresors", 3 | "script": "pmt.js", 4 | "version": "1.4", 5 | "previousversions" : [], 6 | "description": "Character creation helper for the Portes Monstres Tresors character sheet (french free OGL retroclone of DnD B/X). Chat command is !pmt-rollchar 0 or 1 to roll a character. Option 0 is 3d6 in order, 1 is 4d6 keeps the 3 best dice in order. The rest of the commands are handled through roll template buttons.", 7 | "authors": "Natha", 8 | "roll20userid": "75857", 9 | "useroptions": [], 10 | "dependencies": {}, 11 | "modifies": { 12 | "character": "write" 13 | }, 14 | "conflicts": [] 15 | } 16 | -------------------------------------------------------------------------------- /Raise Count/README.md: -------------------------------------------------------------------------------- 1 | ## Raise Count 2 | 3 | Counts the "raises" of a die roll for the _Savage Worlds_ game system. 4 | 5 | Use `!rc roll target` to roll. _roll_ should be a dice expression (do **not** include `/r`, `/roll`, or inline roll brackets `[[]]`), while _target_ should be the target number of the roll. 6 | 7 | ### Output Format 8 | 9 | You can change the formatting of the script's output message by altering the `Output Format` string. In the string, `{0}` will end up as an inline roll, `{1}` will be _target_, and `{2}` will be the number of raises that resulted from the roll. 10 | 11 | ### Raise Size 12 | 13 | You can chage the size of raises by modifying `Raise Size`. -------------------------------------------------------------------------------- /Raise Count/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Raise Count", 3 | "script": "Raise Count.js", 4 | "version": "2.6", 5 | "previousversions": ["2.5", "2.4", "2.3","2.2","2.1","2.0","1.0"], 6 | "description": "Counts raises for the Savage Worlds system. Use `!rc roll target` to make a roll.", 7 | "authors": "Brian Shields", 8 | "roll20userid": "235259", 9 | "patreon": "https://www.patreon.com/bshields", 10 | "useroptions": [ 11 | { 12 | "name": "Raise Size", 13 | "type": "number", 14 | "default": "4", 15 | "description": "The size of a \"raise\" for all rolls." 16 | }, 17 | { 18 | "name": "Output Format", 19 | "type": "text", 20 | "default": "Roll: {0}, Target: {1}, Raises: {2}", 21 | "description": "The text to output from the `!rc` command. `{0}` will be replaced with an inline roll, `{1}` will be the supplied target number, and `{2}` will be the number of raises." 22 | } 23 | ], 24 | "dependencies": ["splitArgs", "Interpreted sendChat"], 25 | "modifies": {}, 26 | "conflicts": [] 27 | } 28 | -------------------------------------------------------------------------------- /Random Turnorder/README.md: -------------------------------------------------------------------------------- 1 | ## Random Turnorder 2 | 3 | Call `!shuffleturnorder` to shuffle the items in the turnorder window randomly. If any tokens _not_ in the turn order are selected at the time, they will be added prior to the shuffling. -------------------------------------------------------------------------------- /Random Turnorder/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Random Turnorder", 3 | "script": "Random Turnorder.js", 4 | "version": "1.1", 5 | "previousversions": ["1.0"], 6 | "description": "Shuffles items in the turnorder window, and adds any selected tokens if they are not already present in the turnorder.", 7 | "authors": "Brian Shields", 8 | "roll20userid": "235259", 9 | "patreon": "https://www.patreon.com/bshields", 10 | "useroptions": [], 11 | "dependencies": ["splitArgs"], 12 | "modifies": { 13 | "Campaign.turnorder": "read,write", 14 | "token.id": "read" 15 | }, 16 | "conflicts": [] 17 | } 18 | -------------------------------------------------------------------------------- /RandomDepth/0.3.1/RandomDepth.js: -------------------------------------------------------------------------------- 1 | // Github: https://github.com/shdwjk/Roll20API/blob/master/RandomDepth/RandomDepth.js 2 | // By: The Aaron, Arcane Scriptomancer 3 | // Contact: https://app.roll20.net/users/104025/the-aaron 4 | 5 | var RandomDepth = RandomDepth || (function() { 6 | 'use strict'; 7 | 8 | var version = '0.3.1', 9 | lastUpdate = 1427604261, 10 | 11 | checkInstall = function() { 12 | log('-=> RandomDepth v'+version+' <=- ['+(new Date(lastUpdate*1000))+']'); 13 | }, 14 | 15 | randomToFrontList = function (l) { 16 | if( l.length ) { 17 | var i = randomInteger(l.length)-1; 18 | toFront(l[i]); 19 | if( l.length > 1) { 20 | setTimeout(_.partial(randomToFrontList,_.without(l,l[i])),5); 21 | } 22 | } 23 | }, 24 | 25 | handleMessages = function(msg) 26 | { 27 | if('api' !== msg.type ) { 28 | return; 29 | } 30 | 31 | var args = msg.content.split(/\s+/), 32 | objs; 33 | 34 | switch(args.shift()) 35 | { 36 | case '!random-depth': 37 | objs = _.chain(msg.selected) 38 | .map(function(o){ 39 | return getObj(o._type,o._id); 40 | }) 41 | .reject(_.isUndefined) 42 | .value(); 43 | 44 | randomToFrontList(objs); 45 | break; 46 | } 47 | }, 48 | 49 | registerEventHandlers = function(){ 50 | on('chat:message',handleMessages); 51 | }; 52 | 53 | return { 54 | CheckInstall: checkInstall, 55 | RegisterEventHandlers: registerEventHandlers 56 | }; 57 | 58 | }()); 59 | 60 | on('ready',function(){ 61 | 'use strict'; 62 | 63 | RandomDepth.CheckInstall(); 64 | RandomDepth.RegisterEventHandlers(); 65 | }); 66 | -------------------------------------------------------------------------------- /RandomDepth/RandomDepth.js: -------------------------------------------------------------------------------- 1 | // Github: https://github.com/shdwjk/Roll20API/blob/master/RandomDepth/RandomDepth.js 2 | // By: The Aaron, Arcane Scriptomancer 3 | // Contact: https://app.roll20.net/users/104025/the-aaron 4 | 5 | var RandomDepth = RandomDepth || (function() { 6 | 'use strict'; 7 | 8 | var version = '0.3.1', 9 | lastUpdate = 1427604261, 10 | 11 | checkInstall = function() { 12 | log('-=> RandomDepth v'+version+' <=- ['+(new Date(lastUpdate*1000))+']'); 13 | }, 14 | 15 | randomToFrontList = function (l) { 16 | if( l.length ) { 17 | var i = randomInteger(l.length)-1; 18 | toFront(l[i]); 19 | if( l.length > 1) { 20 | setTimeout(_.partial(randomToFrontList,_.without(l,l[i])),5); 21 | } 22 | } 23 | }, 24 | 25 | handleMessages = function(msg) 26 | { 27 | if('api' !== msg.type ) { 28 | return; 29 | } 30 | 31 | var args = msg.content.split(/\s+/), 32 | objs; 33 | 34 | switch(args.shift()) 35 | { 36 | case '!random-depth': 37 | objs = _.chain(msg.selected) 38 | .map(function(o){ 39 | return getObj(o._type,o._id); 40 | }) 41 | .reject(_.isUndefined) 42 | .value(); 43 | 44 | randomToFrontList(objs); 45 | break; 46 | } 47 | }, 48 | 49 | registerEventHandlers = function(){ 50 | on('chat:message',handleMessages); 51 | }; 52 | 53 | return { 54 | CheckInstall: checkInstall, 55 | RegisterEventHandlers: registerEventHandlers 56 | }; 57 | 58 | }()); 59 | 60 | on('ready',function(){ 61 | 'use strict'; 62 | 63 | RandomDepth.CheckInstall(); 64 | RandomDepth.RegisterEventHandlers(); 65 | }); 66 | -------------------------------------------------------------------------------- /RandomDepth/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "RandomDepth", 3 | "version": "0.3.1", 4 | "description": "Randomly adjusts the depth of selected tokens.", 5 | "authors": "The Aaron", 6 | "roll20userid": "104025", 7 | "patreon": "https://www.patreon.com/shdwjk", 8 | "dependencies": [], 9 | "modifies": { 10 | "page.zorder": "write" 11 | }, 12 | "conflicts": [], 13 | "script": "RandomDepth.js", 14 | "useroptions": {}, 15 | "previousversions": [] 16 | } -------------------------------------------------------------------------------- /RandomEncounters/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "RandomEncounters", 3 | "version": "0.1.0", 4 | "description": "Gives a random Encounter from a Rollable Table.", 5 | "authors": "Olav Müller & chipbuddy", 6 | "roll20userid": "61332", 7 | "dependencies": { 8 | }, 9 | "modifies": { 10 | "rollabletable._type": "read", 11 | "rollabletable._id": "read", 12 | "rollabletable.name": "read", 13 | "tableitem._type": "read", 14 | "tableitem._rollabletableid": "read", 15 | "tableitem.name": "read", 16 | "tableitem.weight": "read" 17 | }, 18 | "conflicts": [ 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /RandomRotate/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "RandomRotate", 3 | "version": "0.2.1", 4 | "description": "Allows the GM to easily rotate all selected tokens to a random angle.", 5 | "authors": "The Aaron", 6 | "roll20userid": "104025", 7 | "patreon": "https://www.patreon.com/shdwjk", 8 | "dependencies": [], 9 | "modifies": { 10 | "graphic.rotation": "write", 11 | "graphic.subtype": "read" 12 | }, 13 | "conflicts": [], 14 | "script": "RandomRotate.js", 15 | "useroptions": {}, 16 | "previousversions": [] 17 | } -------------------------------------------------------------------------------- /RecursiveTable/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "RecursiveTable", 3 | "version": "0.1.2", 4 | "description": "", 5 | "authors": "The Aaron", 6 | "roll20userid": "104025", 7 | "patreon": "https://www.patreon.com/shdwjk", 8 | "dependencies": {}, 9 | "modifies": { 10 | "state.RecursiveTable": "read,write" 11 | }, 12 | "conflicts": [], 13 | "script": "RecursiveTable.js", 14 | "useroptions": {}, 15 | "previousversions": [] 16 | } -------------------------------------------------------------------------------- /RoleplayingIsMagic_4E_Dice/README.md: -------------------------------------------------------------------------------- 1 | # Roleplaying is Magic 4E dice 2 | 3 | *Dependencies* 4 | * Roleplaying Is Magic 4E character sheet - v1.1+ 5 | 6 | *v1.1 Updates* 7 | * The script now has an API. 8 | * Compatible with the It's A Trap! MLP-RIM-4 theme. 9 | * Requires v1.1 of the Roleplaying is Magic 4E character sheet. 10 | 11 | This is a script for rolling dice checks checks for the 12 | [Roleplaying is Magic: Season 4 edition](http://roleplayingismagic.com/), 13 | a popular fan-created tabletop RPG system based upon the world of 14 | My Little Pony: Friendship is Magic and developed by Roan Arts. 15 | 16 | ## Character sheet 17 | 18 | This script is codependent with the [Roleplaying is Magic 4E character sheet](https://github.com/Cazra/roll20-character-sheets/tree/master/RoleplayingIsMagic_4E). 19 | It can be used either by using the chat command documented in the script or 20 | with the dice rolling buttons the character sheet's Skills section. 21 | 22 | ## Using it as a chat command 23 | 24 | You can use this script to roll dice checks for the RiM 4 system using the 25 | following chat command: 26 | 27 | ``` 28 | !r {skill name} [+/- ad hoc Advantages/Drawbacks] ["Any ad hoc notes about the skill roll"] 29 | ``` 30 | 31 | e.g. ```!r Stealth +1 "+2 if hiding in a wooded area"``` 32 | 33 | The skill name is case-insensitive and supports shortened names. For example 34 | instead of rolling ```!r Spellcasting```, you can roll ```!r spell```. 35 | 36 | *Important:* In order to roll a skill check for a character, you must be currently 37 | speaking as that character in the chat. 38 | -------------------------------------------------------------------------------- /RoleplayingIsMagic_4E_Dice/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Roleplaying is Magic 4E Dice", 3 | "script": "mlp_dice.js", 4 | "version": "1.1", 5 | "previousversions": [], 6 | "description": "# Roleplaying is Magic 4E dice\r\r*Dependencies*\r* Roleplaying Is Magic 4E character sheet - v1.1+\r\r*v1.1 Updates*\r* The script now has an API.\r* Compatible with the It's A Trap! MLP-RIM-4 theme.\r* Requires v1.1 of the Roleplaying is Magic 4E character sheet.\r\rThis is a script for rolling dice checks checks for the\r[Roleplaying is Magic: Season 4 edition](http://roleplayingismagic.com/),\ra popular fan-created tabletop RPG system based upon the world of\rMy Little Pony: Friendship is Magic and developed by Roan Arts.\r\r## Character sheet\r\rThis script is codependent with the [Roleplaying is Magic 4E character sheet](https://github.com/Cazra/roll20-character-sheets/tree/master/RoleplayingIsMagic_4E).\rIt can be used either by using the chat command documented in the script or\rwith the dice rolling buttons the character sheet's Skills section.\r\r## Using it as a chat command\r\rYou can use this script to roll dice checks for the RiM 4 system using the\rfollowing chat command:\r\r```\r!r {skill name} [+/- ad hoc Advantages/Drawbacks] [\"Any ad hoc notes about the skill roll\"]\r```\r\re.g. ```!r Stealth +1 \"+2 if hiding in a wooded area\"```\r\rThe skill name is case-insensitive and supports shortened names. For example\rinstead of rolling ```!r Spellcasting```, you can roll ```!r spell```.\r\r*Important:* In order to roll a skill check for a character, you must be currently\rspeaking as that character in the chat.\r", 7 | "authors": "Stephen Lindberg", 8 | "roll20userid": 46544, 9 | "useroptions": [], 10 | "dependencies": [], 11 | "modifies": {}, 12 | "conflicts": [] 13 | } 14 | -------------------------------------------------------------------------------- /RollStats/Help.txt: -------------------------------------------------------------------------------- 1 | RollStats 2 | 3 | RollStats tracks roll statistics and displays them in various formats. Rolls 4 | are tracked for each player, for each die size, both for the current session 5 | (since the API sandbox was started) and for all time. 6 | 7 | It is recommended that this script be used in conjunction with the CommandShell 8 | module, which will improve output formatting and command discovery. 9 | 10 | 11 | Syntax: 12 | 13 | !rollstats [options] 14 | 15 | The "rollstats" command accepts the following options: 16 | 17 | -h, --help Displays a help message and exits. 18 | 19 | -g, --global Shows stats for all players. 20 | -p P, --player P Shows stats for player P, specified by display name, 21 | player ID, or Roll20 user ID. 22 | 23 | -l, --leaderboard Shows summary information (roll count, average value, 24 | and expected value) for each player, sorted in 25 | decreasing order of value / expected (i.e. lucky to 26 | unlucky). 27 | -d N, --die N Shows more detailed stats (count and %, plus expected 28 | count and %, for each possible roll, along with the mean 29 | and expected mean) for the specified die size. 30 | 31 | -s, --session Shows only stats for the current session (since the API 32 | sandbox was last restarted). In most cases, this will 33 | be for the current play session, but it might be less if 34 | the sandbox was restarted during play or more if players 35 | remain connected between play sessions. 36 | 37 | -c, --chat Shows stats in the chat instead of whispering them to 38 | the player who executed the command. 39 | 40 | --clear Clears session stats if combined with -s; otherwise 41 | clears "all time" stats. Can only be executed by a GM. 42 | 43 | The default mode of operation shows a high-level summary (roll count, mean 44 | value, and expected value for each die size rolled) of all the rolls made by the 45 | player who executed the command. 46 | -------------------------------------------------------------------------------- /RollStats/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "RollStats", 3 | "version": "0.1", 4 | "description": "Track and display roll statistics.", 5 | "authors": "manveti", 6 | "roll20userid": "503018", 7 | "dependencies": {}, 8 | "modifies": {}, 9 | "conflicts": [] 10 | } 11 | -------------------------------------------------------------------------------- /Ryuutama Skill Check Totaler/ryuutama-check-totaler.js: -------------------------------------------------------------------------------- 1 | on("chat:message", function(msg) { 2 | if (msg.type == "general" && msg.rolltemplate == 'skillCheck' || msg.rolltemplate == 'accuracyCheck') { 3 | var total = 0; 4 | _.each(msg.inlinerolls, function(roll) { 5 | total += roll.results.total; 6 | }); 7 | sendChat(msg.who, "Total: " + total + ""); 8 | } 9 | }); 10 | -------------------------------------------------------------------------------- /Ryuutama Skill Check Totaler/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Ryuutama Skill Check Totaler", 3 | "version": "1.0", 4 | "description": "A script to automatically total the results of checks. The ability to total checks in the character sheet is nonexistent because of how critical hits have to be calculated.", 5 | "authors": "King Puff", 6 | "roll20userid": "665159", 7 | "dependencies": "Ryuutama Character Sheet (https://github.com/Roll20/roll20-character-sheets/tree/master/Ryuutama)", 8 | "modifies": [ 9 | "message: read", 10 | "message: write" 11 | ], 12 | "conflicts": "" 13 | } 14 | -------------------------------------------------------------------------------- /Ryuutama Token Status Markers/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Ryuutama Token Status Markers", 3 | "version": "1.0", 4 | "description": "A script to automatically update tokens with hp, mp, and status conditions. Meant to be used in conjunction with the Ryuutama character sheet, but can be used independently.", 5 | "authors": "King Puff", 6 | "roll20userid": "665159", 7 | "dependencies": "", 8 | "modifies": [ 9 | "attribute.name: read", 10 | "attribute.current: read", 11 | "graphic.bar1_link: write", 12 | "graphic.bar1_value: write", 13 | "graphic.bar1_max: write", 14 | "graphic.bar2_link: write", 15 | "graphic.bar2_value: write", 16 | "graphic.bar2_max: write", 17 | "graphic.bar3_link: write", 18 | "graphic.bar3_value: write", 19 | "graphic.aura1_color: write", 20 | "graphic.statusmarkers: write", 21 | "graphic.aura1_radius: write", 22 | "graphic._subtype: read", 23 | "graphic.showname: write", 24 | "graphic.showplayers_bar1: write", 25 | "graphic.showplayers_bar2: write", 26 | "graphic.showplayers_bar3: write", 27 | "graphic.showplayers_aura1: write", 28 | "graphic.showplayers_name: write", 29 | "graphic.represents: read" 30 | ], 31 | "conflicts": "" 32 | } 33 | -------------------------------------------------------------------------------- /Saga Machine Roller/README.md: -------------------------------------------------------------------------------- 1 | # Saga Machine Roller 2 | 3 | This script is designed to handle the optional ***Saga Machine*** die mechanic used in 4 | both ***Against the Dark Yogi*** and ***Shadows Over Sol***. For best effect, use this 5 | script in conjunction with the character sheets for the aforementioned games. -------------------------------------------------------------------------------- /Saga Machine Roller/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Saga Machine Roller Companion", 3 | "version": "1.0", 4 | "description": "Designed for use with the Against the Dark Yogi and Shadows Over Sol character sheets. Automatically adds result die to the results, checks for trump and checks for critical failure.", 5 | "authors": "Thorin Tabor", 6 | "roll20userid": "20810", 7 | "dependencies": "", 8 | "modifies": [], 9 | "conflicts": "" 10 | } 11 | -------------------------------------------------------------------------------- /ScaleOnAdd/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ScaleOnAdd", 3 | "version": "0.1.1", 4 | "description": "", 5 | "authors": "The Aaron", 6 | "roll20userid": "104025", 7 | "patreon": "https://www.patreon.com/shdwjk", 8 | "dependencies": {}, 9 | "modifies": { 10 | "state.ScaleOnAdd": "read,write", 11 | "graphic.width": "write", 12 | "graphic.height": "write" 13 | }, 14 | "conflicts": [], 15 | "script": "ScaleOnAdd.js", 16 | "useroptions": {}, 17 | "previousversions": [] 18 | } -------------------------------------------------------------------------------- /ShareVision/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ShareVision", 3 | "script": "ShareVision.js", 4 | "version": "1.4", 5 | "previousversions": [], 6 | "description": "ShareVision allows you to share a token's sight with the whole party. Use the aura status marker to share normal vision and the overdrive status marker to share darkvision.", 7 | "authors": "Scott C.", 8 | "roll20userid": "459831", 9 | "useroptions": [], 10 | "dependencies": [], 11 | "modifies": { 12 | "state.ShareVision.version": "read,write", 13 | "token.statusmarker": "read,write", 14 | }, 15 | "conflicts": [] 16 | } 17 | -------------------------------------------------------------------------------- /SizeLock/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "SizeLock", 3 | "version": "0.2.1", 4 | "description": "Toggles a state which reverts any size changes automatically.", 5 | "authors": "The Aaron", 6 | "roll20userid": "104025", 7 | "patreon": "https://www.patreon.com/shdwjk", 8 | "dependencies": [], 9 | "modifies": { 10 | "state.SizeLock": "read,write", 11 | "graphic.height": "read,write", 12 | "graphic.left": "write", 13 | "graphic.subtype": "read", 14 | "graphic.top": "write", 15 | "graphic.width": "read,write" 16 | }, 17 | "conflicts": [], 18 | "script": "SizeLock.js", 19 | "useroptions": {}, 20 | "previousversions": [] 21 | } -------------------------------------------------------------------------------- /Slide Tokens/README.md: -------------------------------------------------------------------------------- 1 | ## Slide Tokens 2 | 3 | Emulate the results of moving a token through waypoints manually by using an API command. 4 | 5 | ### Commands 6 | * !movetok _args_ 7 | * !mode _mode_ 8 | 9 | _mode_ may be one of **squares**, **units**, or **absolute**, or an alias for one of the modes (s, sq, square, u, un, unit, a, abs). _mode_ is not case-sensitive. If _mode_ is omitted or not a legal value, the current mode will be whispered back to you. 10 | 11 | The !mode command can only be used by GMs. 12 | 13 | _args_ is a space-separated list of changes to the selected token(s) position. Each argument is in the form [_direction_:]_coordinate_[,_coordinate_]. 14 | 15 | Each _coordinate_ is a number (which may be a fractional number or negative), and the second one is optional. _direction_ is optional, and may be one of: 16 | 17 | * absolute (alias: a) 18 | * left (alias: l, x) 19 | * top (alias: t, y) 20 | * right (alias: r) 21 | * bottom (alias: b) 22 | * top-left (alias: tl, xy) 23 | * top-right (alias: tr) 24 | * bottom-left (alias: bl) 25 | * bottom-right (alias: br) 26 | 27 | If _direction_ is "absolute", the coordinates will be treated as absolute coordinates on the map, with (0,0) being the top-left corner. All other directions are relative to the token. 28 | 29 | The directions top, right, bottom, and left will all ignore the second coordinate if it is supplied. All of the other directions will treat the second coordinate as 0 if it is not supplied. 30 | 31 | A positive coordinate given for left (the x-coordinate) will move the token to the right, and a positive coordinate given for top (the y-coordinate) will move the token down; this may be unintuitive for some users. The directions right and bottom will move the token in the opposite direction to left and top if given the same coordinate. 32 | 33 | Coordinates are in terms of grid squares if the mode is SQUARES, in terms of the map measurement units if the mode is UNITS, or in pixels if the mode is ABSOLUTE. (If the page's grid size is set to 1 unit, then each grid square is equal to 70 pixels.) Note that if the map's grid size is 0 units (for example, if the grid is turned off), movement using SQUARES will not function. -------------------------------------------------------------------------------- /SpeedFactor/help.txt: -------------------------------------------------------------------------------- 1 | Speed Factor Initiative: 2 | 3 | 1. DM selects tokens to be in intiative, and calls !sfstart. All tokens will be added to initiative with a value of "?". 4 | (For best results, these tokens should be attached to a character sheet with at least a size and a dexterity score.) 5 | 6 | 2. Menus appear for each player. They select actions by clicking the appropriate button. NPC menus will be sent to the DM. 7 | Once all PCs and NPCs have selected actions, their initiative bonus will appear in place of "?" in the turn order. 8 | 9 | 3. DM calls "!sfroll" and the initiative dice are rolled and turns are ordered. 10 | 11 | Utility functions: 12 | !sfround sets up a new round using the tokens that are currently in the initiative order 13 | !sfadd allows you to add selected tokens to the existing turnorder. 14 | 15 | -------------------------------------------------------------------------------- /SpeedFactor/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "SpeedFactor", 3 | "version": "1.1", 4 | "description": "This automates much of the rolling and value input for speed factor initiative in Dungeons & Dragons 5e.", 5 | "authors": "Nate Kharrl", 6 | "roll20userid": "475174", 7 | "dependencies": {}, 8 | "modifies": { 9 | "token": "read", 10 | "character": "read", 11 | "is_npc": "read", 12 | "npc_size": "read", 13 | "npc_initiative": "read", 14 | "npc_dexterity": "read", 15 | "size": "read", 16 | "initiative": "read", 17 | "dexterity": "read", 18 | "turnorder": "write" 19 | }, 20 | "conflicts": [] 21 | } -------------------------------------------------------------------------------- /SpellLevel5e/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "SpellLevel5e", 3 | "version": "0.2.1", 4 | "description": "Maintains a spell level attribute for each spellcasting class.", 5 | "authors": "The Aaron", 6 | "roll20userid": "104025", 7 | "patreon": "https://www.patreon.com/shdwjk", 8 | "dependencies": [], 9 | "modifies": { 10 | "state.SpellLevel5e": "read,write", 11 | "attribute": "create", 12 | "attribute.characterid": "read", 13 | "attribute.current": "read,write", 14 | "attribute.name": "read" 15 | }, 16 | "conflicts": [], 17 | "script": "SpellLevel5e.js", 18 | "useroptions": {}, 19 | "previousversions": [] 20 | } -------------------------------------------------------------------------------- /SpinTokens/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "SpinTokens", 3 | "version": "0.4.1", 4 | "description": "Allows the GM to toggle spinning of selected tokens.", 5 | "authors": "The Aaron", 6 | "roll20userid": "104025", 7 | "patreon": "https://www.patreon.com/shdwjk", 8 | "dependencies": [], 9 | "modifies": { 10 | "state.SpinTokens": "read,write", 11 | "campaign.playerpageid": "read", 12 | "campaign.playerspecificpages": "read", 13 | "graphic.pageid": "read", 14 | "graphic.rotation": "write", 15 | "graphic.subtype": "read" 16 | }, 17 | "conflicts": [], 18 | "script": "SpinTokens.js", 19 | "useroptions": {}, 20 | "previousversions": [] 21 | } -------------------------------------------------------------------------------- /StateBrowser/Help.txt: -------------------------------------------------------------------------------- 1 | StateBrowser 2 | 3 | StateBrowser allows the user to view and modify properties of the state object. 4 | 5 | It is recommended that this script be used in conjunction with the CommandShell 6 | module, which will improve output formatting and command discovery, and will 7 | allow whitespace to be preserved in property values. 8 | 9 | 10 | Commands: 11 | 12 | The "state" command operates in several modes: 13 | 14 | !state [PATH] 15 | Displays the value (in JSON) of the specified object within state (or 16 | all of state if PATH is not specified). 17 | 18 | !state -s PATH VALUE 19 | Sets the value of the specified object within state to VALUE (specified 20 | in JSON). 21 | 22 | !state -d PATH 23 | Deletes the specified object within state. 24 | 25 | The "state" command accepts the following options: 26 | 27 | -h, --help Displays a help message and exits. 28 | 29 | -s, --set Sets the value of an already-existing object 30 | within state. 31 | -S, --forceset Sets the value of an object within state, 32 | creating it and any intermediate objects if 33 | necessary. 34 | 35 | -d, --delete Deletes an object within state. Will prompt for 36 | confirmation before deleting. 37 | -D, --forcedelete Deletes an object within state without prompting 38 | for confirmation. 39 | 40 | 41 | Examples: 42 | 43 | !state foo.bar 44 | Displays the value of state.foo.bar, assuming it exists. If state.foo.bar 45 | does not exist, an error will be generated. 46 | 47 | !state -s foo.bar "{'blah': 'bloh'}" 48 | Sets state.foo.bar to an object with a single property: "blah", with value 49 | "bloh", assuming that state.foo.bar exists. If state.foo.bar does not 50 | exist, an error will be generated. 51 | 52 | !state -s foo.bar.baz 42 53 | Sets state.foo.bar.baz to 42. If state.foo.bar didn't already exist, it 54 | will now be {'baz': 42}. 55 | 56 | !state -d foo.bar 57 | If state.foo.bar exists, prompts the user to confirm deletion. Then (if the 58 | user clicks the button to confirm) deletes state.foo.bar. If state.foo.bar 59 | does not exist, an error will be generated. 60 | 61 | !state -D foo.bar 62 | Immediately deletes state.foo.bar if it exists. If it does not exist, an 63 | error will be generated. 64 | -------------------------------------------------------------------------------- /StateBrowser/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "StateBrowser", 3 | "version": "0.1", 4 | "description": "View/modify the state object.", 5 | "authors": "manveti", 6 | "roll20userid": "503018", 7 | "dependencies": {}, 8 | "modifies": {}, 9 | "conflicts": [] 10 | } 11 | -------------------------------------------------------------------------------- /StatusFX/README.md: -------------------------------------------------------------------------------- 1 | # Status FX 2 | 3 | _v1.2 Updates:_ 4 | * Added a user option to set the interval that it cycles through effects. 5 | * Improved the script's ability to detect when status markers change. 6 | 7 | This script allows you to assign special FX to appear on a token when status 8 | markers are turned on. When multiple status FX are assigned to a token, it 9 | will cycle through each one. Built-in and Custom FX are supported. 10 | 11 | FX are assigned to status markers through the One-Click user options for the 12 | script. For each status marker that you want to assign a special FX to, just 13 | enter the name of the special FX. If it is a beam-like effect (such as beam, 14 | breath, splatter, or a custom effect whose definition has an angle of -1), 15 | also enter the vector for the effect's direction in the form ```[X, Y]```. 16 | Beam-like effects can also be given a random vector with ```[random]```. 17 | 18 | Note: For most statuses, this script looks best using custom special FX with a 19 | short range and fewer,smaller particles. 20 | 21 | ### Examples: 22 | 23 | *green* ```bubbling-acid``` 24 | Creates green bubbles on the token when the 'green' status marker is on. 25 | 26 | *red* ```splatter-blood [1, -2]``` 27 | Creates a bleeding effect with blood spurting up and slightly to the right 28 | when the 'red' status marker is on. 29 | 30 | *death-zone* ```MyCustomEffect``` 31 | Creates some sort of custom effect when the 'death-zone' status marker is on. 32 | 33 | *chemical-bolt* ```splatter-holy [random]``` 34 | Creates a spark effect fired in a random direction when the 'chemical-bolt' 35 | status marker is on. 36 | 37 | *custom* ```sleep: glow-holy|stars: beam-fire [2,3]``` 38 | Example of FX for CustomStatusMarkers. 39 | Creates FX for the custom status markers 'sleep' and 'stars'. 40 | -------------------------------------------------------------------------------- /StatusFX/demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlenser/roll20-api-scripts/65a254bd1d44764076cf808e6c50abc995ee6938/StatusFX/demo.gif -------------------------------------------------------------------------------- /Store Commands/1.0/Store Commands.js: -------------------------------------------------------------------------------- 1 | var store_commands = store_commands || {}; 2 | 3 | store_commands.list = {}; 4 | 5 | on('chat:message', function(msg) { 6 | if(msg.type != 'api') return; 7 | 8 | var parts = msg.content.split(' '); 9 | var command = parts.shift().substring(1); 10 | var id = msg.playerid; 11 | 12 | if(!store_commands.list[id]) store_commands.list[id] = { cmds: [], delay: 500 }; 13 | 14 | switch(command) 15 | { 16 | case 'delay': 17 | store_commands.list[id].delay = parseInt(parts[0], 10); 18 | break; 19 | case 'store': 20 | var delay = 500; 21 | if(parts[0].indexOf('-') == 0) 22 | delay = parseInt(parts.shift().substring(1), 10); 23 | else if(store_commands.list[id].delay) 24 | delay = store_commands.list[id].delay; 25 | 26 | var obj = { text: parts.join(' '), delay: delay }; 27 | store_commands.list[id].cmds.push(obj); 28 | break; 29 | case 'clearstore': 30 | store_commands.list[id].cmds = []; 31 | break; 32 | case 'echostore': 33 | for(var i = 0; i < store_commands.list[id].cmds.length; i++) 34 | { 35 | var obj = store_commands.list[id].cmds[i]; 36 | sendChat('Store Commands.js', '/w ' + msg.who + ' {' + obj.delay + 'ms, ' + obj.text + '}'); 37 | } 38 | break; 39 | case 'run': 40 | var count = 0; 41 | for(var i = 0; i < store_commands.list[id].cmds.length; i++) 42 | { 43 | var obj = store_commands.list[id].cmds[i]; 44 | store_commands.echo(id, obj.text, count + obj.delay); 45 | count += obj.delay; 46 | } 47 | break; 48 | default: 49 | break; 50 | } 51 | }); 52 | 53 | store_commands.echo = function(id, text, delay) 54 | { 55 | setTimeout(function(){ sendChat('player|'+id, text); }, delay); 56 | }; -------------------------------------------------------------------------------- /Store Commands/README.md: -------------------------------------------------------------------------------- 1 | ## Store Commands 2 | 3 | Use `!delay time` (where _time_ is some number of milliseconds) to set the default delay between commands. If `!delay` is not used, nor is the _time_ parameter passed to `!store`, the time delay will be 500ms (0.5s). 4 | 5 | Use `!store -time command` or `!store command` to store a command. The command stored can be anything, including commands that are normally GM-only such as /direct or /emas. This will not give you access to API commands whose scripts restrict their use to GMs. 6 | 7 | Use `!clearstore` to clear the series of stored commands. This is the only way to remove commands from the sequence, meaning you can also use this script to store a series of commands you want to use over and over. Note that command sequences do not persist between game sessions, but they are unique per-player. 8 | 9 | Use `!echostore` to see a list of the commands in your serquence. 10 | 11 | Use `!run` to run the commands. -------------------------------------------------------------------------------- /Store Commands/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Store Commands", 3 | "script": "Store Commands.js", 4 | "version": "2.3", 5 | "previousversions": ["2.2","2.1","2.0","1.0"], 6 | "description": "Stores a series of commands (potentially with delays between them) to be executed in sequence later. Opens up GM-only commands such as /direct and /emas to players.", 7 | "authors": "Brian Shields", 8 | "roll20userid": "235259", 9 | "patreon": "https://www.patreon.com/bshields", 10 | "useroptions": [], 11 | "dependencies": ["splitArgs"], 12 | "modifies": { 13 | "player.displayname": "read" 14 | }, 15 | "conflicts": ["Dynamic Lighting Animation"] 16 | } 17 | -------------------------------------------------------------------------------- /TableExport/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "TableExport", 3 | "version": "0.2.3", 4 | "description": "A script for exporting Rollable Tables between accounts.", 5 | "authors": "The Aaron", 6 | "roll20userid": "104025", 7 | "patreon": "https://www.patreon.com/shdwjk", 8 | "dependencies": [], 9 | "modifies": { 10 | "rollabletable": "create", 11 | "rollabletable.name": "read", 12 | "rollabletable.showplayers": "read", 13 | "tableitem": "create", 14 | "tableitem.avatar": "read", 15 | "tableitem.name": "read", 16 | "tableitem.rollabletableid": "read", 17 | "tableitem.weight": "read" 18 | }, 19 | "conflicts": [], 20 | "script": "TableExport.js", 21 | "useroptions": {}, 22 | "previousversions": [] 23 | } -------------------------------------------------------------------------------- /TableTokenSizer/0.2.1/TableTokenSizer.js: -------------------------------------------------------------------------------- 1 | // Github: https://github.com/shdwjk/Roll20API/blob/master/TableTokenSizer/TableTokenSizer.js 2 | // By: The Aaron, Arcane Scriptomancer 3 | // Contact: https://app.roll20.net/users/104025/the-aaron 4 | 5 | var TableTokenSizer = TableTokenSizer || (function() { 6 | 'use strict'; 7 | 8 | var version = '0.2.1', 9 | lastUpdate = 1427604269, 10 | gridSize = 70, 11 | scaleSize = 3, 12 | 13 | sizeTableToken = function(obj, prev) { 14 | if(obj.get('sides')) { 15 | if( (gridSize * scaleSize) !== obj.get('width') ) { 16 | obj.set({ 17 | width: (gridSize * scaleSize), 18 | height: (gridSize * scaleSize), 19 | isdrawing: false 20 | }); 21 | } 22 | } 23 | }, 24 | 25 | checkInstall = function() { 26 | log('-=> TableTokenSizer v'+version+' <=- ['+(new Date(lastUpdate*1000))+']'); 27 | }, 28 | 29 | registerEventHandlers = function() { 30 | on('add:graphic', sizeTableToken); 31 | }; 32 | 33 | return { 34 | CheckInstall: checkInstall, 35 | RegisterEventHandlers: registerEventHandlers 36 | }; 37 | }()); 38 | 39 | 40 | on("ready",function(){ 41 | 'use strict'; 42 | 43 | TableTokenSizer.CheckInstall(); 44 | TableTokenSizer.RegisterEventHandlers(); 45 | }); 46 | -------------------------------------------------------------------------------- /TableTokenSizer/TableTokenSizer.js: -------------------------------------------------------------------------------- 1 | // Github: https://github.com/shdwjk/Roll20API/blob/master/TableTokenSizer/TableTokenSizer.js 2 | // By: The Aaron, Arcane Scriptomancer 3 | // Contact: https://app.roll20.net/users/104025/the-aaron 4 | 5 | var TableTokenSizer = TableTokenSizer || (function() { 6 | 'use strict'; 7 | 8 | var version = '0.2.1', 9 | lastUpdate = 1427604269, 10 | gridSize = 70, 11 | scaleSize = 3, 12 | 13 | sizeTableToken = function(obj, prev) { 14 | if(obj.get('sides')) { 15 | if( (gridSize * scaleSize) !== obj.get('width') ) { 16 | obj.set({ 17 | width: (gridSize * scaleSize), 18 | height: (gridSize * scaleSize), 19 | isdrawing: false 20 | }); 21 | } 22 | } 23 | }, 24 | 25 | checkInstall = function() { 26 | log('-=> TableTokenSizer v'+version+' <=- ['+(new Date(lastUpdate*1000))+']'); 27 | }, 28 | 29 | registerEventHandlers = function() { 30 | on('add:graphic', sizeTableToken); 31 | }; 32 | 33 | return { 34 | CheckInstall: checkInstall, 35 | RegisterEventHandlers: registerEventHandlers 36 | }; 37 | }()); 38 | 39 | 40 | on("ready",function(){ 41 | 'use strict'; 42 | 43 | TableTokenSizer.CheckInstall(); 44 | TableTokenSizer.RegisterEventHandlers(); 45 | }); 46 | -------------------------------------------------------------------------------- /TableTokenSizer/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "TableTokenSizer", 3 | "version": "0.2.1", 4 | "description": "Simple script to scale rollable tokens added to the tabletop to a given size (defaults to 3x3) an set them as not drawings.", 5 | "authors": "The Aaron", 6 | "roll20userid": "104025", 7 | "patreon": "https://www.patreon.com/shdwjk", 8 | "dependencies": [], 9 | "modifies": { 10 | "graphic.height": "write", 11 | "graphic.isdrawing": "write", 12 | "graphic.sides": "read", 13 | "graphic.width": "read,write" 14 | }, 15 | "conflicts": [], 16 | "script": "TableTokenSizer.js", 17 | "useroptions": {}, 18 | "previousversions": [] 19 | } -------------------------------------------------------------------------------- /TempHPAndStatus/foo: -------------------------------------------------------------------------------- 1 | 2 | var lights = function(radius,dim) { 3 | _.each(findObjs({ 4 | _type: 'graphic', 5 | name: "Torch" 6 | }), function(light){ 7 | light.set("light_radius", radius); 8 | light.set("light_dimradius", dim); 9 | }); 10 | }; 11 | on("chat:message", function(msg) { 12 | if(msg.type == "api" && msg.content.indexOf("!lightson") !== -1) { 13 | lights(30,20);};}); 14 | on("chat:message", function(msg) { 15 | if(msg.type == "api" && msg.content.indexOf("!lightsoff") !== -1) { 16 | lights(0,0);};}); 17 | -------------------------------------------------------------------------------- /TempHPAndStatus/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "TempHPAndStatus", 3 | "version": "0.4.1", 4 | "description": "Temp hit point manager and bloodied/dying/dead status markers.", 5 | "authors": "The Aaron", 6 | "roll20userid": "104025", 7 | "patreon": "https://www.patreon.com/shdwjk", 8 | "dependencies": [], 9 | "modifies": { 10 | "attribute.current": "read,write", 11 | "attribute.name": "read", 12 | "attribute.type": "read", 13 | "graphic.bar1_value": "read,write", 14 | "graphic.bar2_value": "read,write", 15 | "graphic.bar3_value": "read,write", 16 | "graphic.isdrawing": "read", 17 | "graphic.represents": "read", 18 | "graphic.status_*": "read,write" 19 | }, 20 | "conflicts": [], 21 | "script": "TempHPAndStatus.js", 22 | "useroptions": {}, 23 | "previousversions": [] 24 | } -------------------------------------------------------------------------------- /The Darkness is Closing In/Help.txt: -------------------------------------------------------------------------------- 1 | The Darkness is Closing In... 2 | This script reduces the light radius of a token by 10% every time that token moves. Great for simulating "lamps running out of oil" or similar high-stress situations. -------------------------------------------------------------------------------- /The Darkness is Closing In/The Darkness is Closing In.js: -------------------------------------------------------------------------------- 1 | on("change:token", function(obj, prev) { 2 | //Only do this if we actually moved. 3 | if(obj.get("left") == prev["left"] && obj.get("top") == prev["top"]) return; 4 | obj.set({ 5 | light_radius: Math.floor(obj.get("light_radius") * 0.90) 6 | }); 7 | }); -------------------------------------------------------------------------------- /The Darkness is Closing In/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "The Darkness is Closing In", 3 | "version": "1.1", 4 | "description": "This script reduces the light radius of a token by 10% every time that token moves. Great for simulating 'lamps running out of oil' or similar high-stress situations.", 5 | "authors": "Riley Dutton", 6 | "roll20userid": "1", 7 | "dependencies": {}, 8 | "modifies": { 9 | "token": "read", 10 | "light_radius": "write" 11 | }, 12 | "conflicts": [ 13 | "none" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /Tile/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Tile", 3 | "version": "0.3.1", 4 | "description": "Create tiled arrays of graphics on the map layer.", 5 | "authors": "The Aaron", 6 | "roll20userid": "104025", 7 | "patreon": "https://www.patreon.com/shdwjk", 8 | "dependencies": [], 9 | "modifies": { 10 | "graphic": "create", 11 | "graphic.height": "read", 12 | "graphic.imgsrc": "read", 13 | "graphic.layer": "read", 14 | "graphic.left": "read,write", 15 | "graphic.pageid": "read", 16 | "graphic.top": "read,write", 17 | "graphic.width": "read" 18 | }, 19 | "conflicts": [], 20 | "script": "Tile.js", 21 | "useroptions": {}, 22 | "previousversions": [] 23 | } -------------------------------------------------------------------------------- /TimeTracker/MacroQuery: -------------------------------------------------------------------------------- 1 | ## IMPORTANT NOTE ## When pasting into a macro, if it is opened after saving, the entire command will need to be repasted due to the way queries and macros interact. The ASCII formats must remain intact (ie, { and }) in order for the drop down queries to work as intended. 2 | 3 | !time -?{Time options|Plus Time,plus ?{hours|0}:?{minutes|0}|Add Event,addevent ?{name}:?{hours|0}:?{minutes|0}|List of Events,events|Set Time,set ?{hours|0}:?{minutes|0}|Show Time,show|Set Timeformat,setformat ?{format|24}} -------------------------------------------------------------------------------- /TimeTracker/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Example API Script", 3 | "version": "0.3", 4 | "description": "Tracking ingame time and events like lamps, torches and long duration spells (Mage Armor).", 5 | "authors": "Filip Čapek", 6 | "roll20userid": "474791", 7 | "dependencies": { 8 | }, 9 | "modifies": { 10 | "state.timetracker": "read,write" 11 | }, 12 | "conflicts": [ 13 | ] 14 | } -------------------------------------------------------------------------------- /Token Collisions/README.md: -------------------------------------------------------------------------------- 1 | # Token Collisions 2 | 3 | _v1.4 Updates:_ 4 | * getCollisions and getFirstCollision now accept an options object parameter. See the CollisionOptions typedef jsdoc for supported properties. 5 | 6 | _v1.3 Updates:_ 7 | * Supports circle-to-rectangle token collisions. 8 | * Added isOverlapping() function. 9 | 10 | This script provides a small library for checking for collisions between 11 | tokens. It provides no functionality by itself, but it is used by other 12 | scripts such as ```It's A Trap``` and ```World Map Discovery```. 13 | 14 | ## Rectangular tokens 15 | 16 | By default, all tokens are assumed to be circular with a diameter equal to their 17 | width. You can set a token to be rectangular for this script by setting its 18 | Aura1 to a square. 19 | 20 | ## API Documentation: 21 | 22 | The following functions are exposed by the ```TokenCollisions``` object: 23 | 24 | ``` 25 | /** 26 | * Returns the list of other tokens that some token collided with during 27 | * its last movement. 28 | * The tokens are sorted in the order they are collided with. 29 | * @param {Graphic} token 30 | * @param {Graphic[]} others 31 | * @return {Graphic[]} 32 | */ 33 | function getCollisions(token, others) 34 | ``` 35 | 36 | ``` 37 | /** 38 | * Returns the first token, from some list of tokens, that a token has 39 | * collided with during its last movement, or undfined if there was 40 | * no collision. 41 | * @param {Graphic} token 42 | * @param {Graphic[]} others 43 | * @return {Graphic} 44 | */ 45 | function getFirstCollision(token, others) 46 | ``` 47 | 48 | ``` 49 | /** 50 | * Checks if a non-moving token is currently overlapping another token. 51 | * This supports circular and rectangular tokens. 52 | * Tokens are considered to be rectangular if their aura1 is a square. 53 | * @param {Graphic} token 54 | * @param {Graphic} other 55 | * @param {boolean} [collideOnEdge=false] 56 | * Whether tokens should count as overlapping even if they are only 57 | * touching on the very edge. 58 | * @return {Boolean} 59 | */ 60 | function isOverlapping(token, other, collideOnEdge) 61 | ``` 62 | -------------------------------------------------------------------------------- /TokenLock/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "TokenLock", 3 | "version": "0.2.5", 4 | "description": "TokenLock allows the GM to selectively prevent players from moving their tokens. Since `change:graphic` events to not specify who changed the graphic, determination of player tokens is based on whether that token has an entry in the `controlled by` field of either the token or the character it represents. If `controlled by` is empty, the GM can freely move the token at any point. If there is any entry in `controlled by`, the token can only be moved when TokenLock is unlocked.\r \r Moving of player controlled cards is still permissible.\r \r ## Commands\r \r ```!tl ```\r \r Executing the command with no arguments prints this help. The following arguments may be supplied in order to change the configuration. All changes are persisted between script restarts.\r \r * `lock` -- Locks the player tokens to prevent moving them.\r * `unlock` -- Unlocks the player tokens allowing them to be moved.\r \r ```!tl-config [|--help]```\r \r Swaps the selected Tokens for their counterparts on the other layer.\r \r * `--help` -- Shows the Help screen.\r * `--toggle-allowmoveonturn` -- Sets whether tokens can be moved if they are at the top of the turn order.", 5 | "authors": "The Aaron", 6 | "roll20userid": "104025", 7 | "patreon": "https://www.patreon.com/shdwjk", 8 | "dependencies": [], 9 | "modifies": { 10 | "state.TokenLock": "read,write", 11 | "character.controlledby": "read", 12 | "graphic.controlledby": "read", 13 | "graphic.left": "read,write", 14 | "graphic.represents": "read", 15 | "graphic.rotation": "read,write", 16 | "graphic.subtype": "read", 17 | "graphic.top": "read,write" 18 | }, 19 | "conflicts": [], 20 | "script": "TokenLock.js", 21 | "useroptions": [], 22 | "previousversions": [ 23 | "0.2.3", 24 | "0.2.4" 25 | ] 26 | } -------------------------------------------------------------------------------- /TokenPath/Help.txt: -------------------------------------------------------------------------------- 1 | TokenPath 2 | 3 | TokenPath continuously tracks the movement of the token at the top of the turn 4 | tracker, automatically computing the token's shortest path. Waypoints can be 5 | placed to tweak the generated path as the user desires. 6 | 7 | 8 | Use: 9 | 10 | No special user action is required. Whenever the token at the top of the turn 11 | tracker moves, its path is automatically updated. The path is automatically 12 | cleared when the turn changes. Tokens moving when it is not their turn do not 13 | generate paths. 14 | 15 | The pips which display a token's path are controlled by the same user(s) as the 16 | token in question. When a pip is moved, it creates a waypoint, and the path is 17 | automatically updated to pass through that waypoint. Waypoints are ordered, so 18 | creating a new waypoint B by dragging a pip between existing waypoints A and C 19 | will create a path that passes through A, then B, then C. Deleting a waypoint 20 | will cause the path to be recomputed without that waypoint. 21 | 22 | Pips display distance based on the page settings (although they are not updated 23 | retroactively if the page settings are changed while a path is visible). Note 24 | that each step of the path will be fully into a square, so all travel will be 25 | along the eight cardinal and ordinal directions. However, when a page is 26 | configured to use Euclidean distance, the ruler tool does not follow this 27 | restriction, and can draw a direct line between any two squares. As a result, 28 | the ruler tool may report a different distance from that reported on the pips 29 | when Euclidean distance is in use. 30 | -------------------------------------------------------------------------------- /TokenPath/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "TokenPath", 3 | "version": "0.1", 4 | "description": "Track movement of token at top of tracker, displaying its path for the round.", 5 | "authors": "manveti", 6 | "roll20userid": "503018", 7 | "dependencies": {}, 8 | "modifies": {}, 9 | "conflicts": [] 10 | } 11 | -------------------------------------------------------------------------------- /TotalMana/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "TotalMana", 3 | "version": "0.1.3", 4 | "description": "", 5 | "authors": "The Aaron", 6 | "roll20userid": "104025", 7 | "patreon": "https://www.patreon.com/shdwjk", 8 | "dependencies": {}, 9 | "modifies": { 10 | "state.TotalMana": "read,write" 11 | }, 12 | "conflicts": [], 13 | "script": "TotalMana.js", 14 | "useroptions": {}, 15 | "previousversions": [] 16 | } -------------------------------------------------------------------------------- /Track V20 Attributes/README.md: -------------------------------------------------------------------------------- 1 | ## Track V20 Attributes 2 | 3 | The Vampire The Masquerade, 20th Anniversary Edition character sheet by Matt Zaldivar makes use of player filled text boxes for Disciplines and Backgrounds. These show up as generic Discipline1, Discipline2, etc. attributes when used, making it difficult to pull their values for macros and other functionality. This script solves the issue by creating named attributes for this missing information and keeping them consistent with what players are filling out on the sheet proper. Future versions will likely include support for Dark Ages V20, as well. 4 | 5 | **Customizing the Script** 6 | 7 | You may wish to add your own Disciplines, Paths, and Backgrounds, or incorporate new ones from V20 supplements as they are released. This is as simple as adding the new attributes you want to track to the appropriate associative array in the script. Each entry's key is the name players will type on their character sheet, while the value will be the attribute's name (which you can use in macros and other scripts). Afterwards be sure to update the `schemaVersion` to ensure attributes are added to preexisting characters. 8 | 9 | * `disciplineHash`: Disciplines 10 | * `pathHash`: Paths 11 | * `backgroundHash`: Backgrounds -------------------------------------------------------------------------------- /Track V20 Attributes/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Track V20 Attributes", 3 | "version": "0.1.0", 4 | "description": "Script for tracking attributes not present in the V20 character sheet", 5 | "authors": "Invincible Spleen", 6 | "roll20userid": "901082", 7 | "dependencies": [], 8 | "modifies": { 9 | "state.TrackV20Attributes": "read,write", 10 | "character.ID": "read", 11 | "attribute": "create", 12 | "attribute.current": "read,write", 13 | "attribute.characterid": "read", 14 | "attribute.name": "read" 15 | }, 16 | "conflicts": [] 17 | } -------------------------------------------------------------------------------- /TurnLock/Help.txt: -------------------------------------------------------------------------------- 1 | Commands: 2 | 3 | !tlock (enables turn lock, preventing tokens from moving if it is not their turn) 4 | !tunlock (disables turn lock) -------------------------------------------------------------------------------- /TurnLock/TurnLock.js: -------------------------------------------------------------------------------- 1 | // Github: https://github.com/anthonytasca/roll20-api-scripts/blob/master/TurnLock/TurnLock.js 2 | // By: Anthony Tasca 3 | // Contact: https://app.roll20.net/users/1000007/target 4 | 5 | var TurnLock = TurnLock || (function(){ 6 | 'use strict'; 7 | var tlocked = false; 8 | 9 | function handleChat(msg) { 10 | if (msg.type !== "api" || !playerIsGM(msg.playerid) ) { 11 | return; 12 | } 13 | if(msg.content == "!tlock"){ 14 | tlocked = true; 15 | }else if(msg.content == "!tunlock"){ 16 | tlocked = false; 17 | } 18 | }; 19 | 20 | function handleMove(obj, prev) { 21 | if(tlocked && 'token' === obj.get('subtype')){ 22 | var turnOrder = tOrder.Get(); 23 | var current = _.first(turnOrder); 24 | if( obj && current && current.id === obj.id ){ 25 | return; 26 | }else{ 27 | obj.set({left: prev.left, top: prev.top, rotation: prev.rotation}); 28 | } 29 | } 30 | }; 31 | 32 | function registerEventHandlers() { 33 | on('chat:message', handleChat); 34 | on('change:graphic', handleMove); 35 | }; 36 | 37 | return { 38 | RegisterEventHandlers: registerEventHandlers 39 | }; 40 | 41 | }()); 42 | 43 | on("ready",function(){ 44 | 'use strict'; 45 | TurnLock.RegisterEventHandlers(); 46 | }); 47 | 48 | var tOrder = tOrder || { 49 | Get: function(){ 50 | var to=Campaign().get("turnorder"); 51 | to=(''===to ? '[]' : to); 52 | return JSON.parse(to); 53 | }, 54 | } 55 | -------------------------------------------------------------------------------- /TurnLock/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "TurnLock", 3 | "version": "1.0.0", 4 | "description": "Allows controll of whether or not tokens can move when it is not their turn", 5 | "authors": "Anthony Tasca", 6 | "roll20userid": "1000007", 7 | "dependencies": [], 8 | "modifies": { 9 | "TurnLock": "read,write", 10 | "campaign.turnorder": "read", 11 | "graphic.left": "read,write", 12 | "graphic.rotation": "read,write", 13 | "graphic.top": "read,write" 14 | }, 15 | "conflicts": [] 16 | } -------------------------------------------------------------------------------- /TurnMarker1/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "TurnMarker1", 3 | "version": "1.3.7", 4 | "description": "Round counter and a moving marker that shows who's turn it is.", 5 | "authors": "The Aaron", 6 | "roll20userid": "104025", 7 | "patreon": "https://www.patreon.com/shdwjk", 8 | "dependencies": [], 9 | "modifies": { 10 | "state.TurnMarker": "read,write", 11 | "campaign.initiativepage": "read", 12 | "campaign.playerpageid": "read", 13 | "campaign.turnorder": "read,write", 14 | "character.controlledby": "read", 15 | "graphic": "create", 16 | "graphic.aura1_color": "read,write", 17 | "graphic.aura1_radius": "read,write", 18 | "graphic.aura2_color": "read,write", 19 | "graphic.aura2_radius": "read,write", 20 | "graphic.bar1_value": "read,write", 21 | "graphic.bar2_value": "read,write", 22 | "graphic.controlledby": "read", 23 | "graphic.height": "read,write", 24 | "graphic.layer": "read,write", 25 | "graphic.left": "read,write", 26 | "graphic.name": "read,write", 27 | "graphic.pageid": "read", 28 | "graphic.represents": "read", 29 | "graphic.rotation": "read,write", 30 | "graphic.showplayers_name": "read", 31 | "graphic.top": "read,write", 32 | "graphic.width": "read,write" 33 | }, 34 | "conflicts": [], 35 | "script": "TurnMarker1.js", 36 | "useroptions": [], 37 | "previousversions": [ 38 | "1.3.3", 39 | "1.3.4", 40 | "1.3.5" 41 | ] 42 | } -------------------------------------------------------------------------------- /Twins/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Twins", 3 | "version": "0.2.1", 4 | "description": "Links two tokens so that they mirror each other across pages.", 5 | "authors": "The Aaron", 6 | "roll20userid": "104025", 7 | "patreon": "https://www.patreon.com/shdwjk", 8 | "dependencies": [], 9 | "modifies": { 10 | "state.Twins": "read,write", 11 | "graphic.*": "read,write" 12 | }, 13 | "conflicts": [], 14 | "script": "Twins.js", 15 | "useroptions": {}, 16 | "previousversions": [] 17 | } -------------------------------------------------------------------------------- /UsePower/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "UsePower", 3 | "version": "0.4.1", 4 | "description": "A script for instrumenting and tracking the use of encounter and daily powers.", 5 | "authors": "The Aaron", 6 | "roll20userid": "104025", 7 | "patreon": "https://www.patreon.com/shdwjk", 8 | "dependencies": [], 9 | "modifies": { 10 | "state.UsePower": "read,write", 11 | "ability.action": "read,write", 12 | "ability.istokenaction": "write", 13 | "ability.name": "read", 14 | "character.name": "read", 15 | "player.displayname": "read" 16 | }, 17 | "conflicts": [], 18 | "script": "UsePower.js", 19 | "useroptions": {}, 20 | "previousversions": [] 21 | } 22 | -------------------------------------------------------------------------------- /WFRPDice/README.md: -------------------------------------------------------------------------------- 1 | # WFRP Dice 2 | ##### Version 0.2 3 | ###### By: omonubi (omonubi@hotmail.com) 4 | ###### Maintained by: [The Aaron](https://app.roll20.net/users/104025/the-aaron) 5 | 6 | This script rolls a certain number of WFRP 3rd Edition dice, and both displays and summarizes the result, in graphical format. The number of each type of WFRP 3e die to be rolled is specified by entering up to 7 digits, each digit representing one type of die. 7 | 8 | **The order of the digits are:** 9 | 10 | ``` 11 | /------- B - Characteristic 12 | |/------ R - Reckless 13 | ||/----- C - Conservative 14 | |||/---- E - Expertise 15 | ||||/--- F - Fortune 16 | |||||/-- X - Challenge 17 | ||||||/- M - Misfortune 18 | ||||||| 19 | !wfrp 3021231 20 | ``` 21 | 22 | Typing `!wfrp` alone rolls a single Characteristic die. 23 | Typing `!wfrp ?` display a short-hand reminder of the dice types and expected order ('BRCWFXM'). 24 | 25 | -------------------------------------------------------------------------------- /WFRPDice/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "WFRP Dice", 3 | "version": "0.2", 4 | "description": "This script rolls a certain number of WFRP 3rd Edition dice, and both displays and summarizes the result, in graphical format.", 5 | "authors": "Omonubi (original), The Aaron (maintainer)", 6 | "roll20userid": "510317,104025", 7 | "dependencies": { 8 | }, 9 | "modifies": { 10 | }, 11 | "conflicts": [ 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /Walls/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Walls", 3 | "version": "0.3.1", 4 | "description": "Builds dynamic lighting walls with an exported SVG path file.", 5 | "authors": "The Aaron", 6 | "roll20userid": "104025", 7 | "patreon": "https://www.patreon.com/shdwjk", 8 | "dependencies": [], 9 | "modifies": { 10 | "state.Walls": "read,write", 11 | "graphic.height": "read", 12 | "graphic.left": "read", 13 | "graphic.pageid": "read", 14 | "graphic.top": "read", 15 | "graphic.width": "read", 16 | "path": "create", 17 | "player.displayname": "read" 18 | }, 19 | "conflicts": [], 20 | "script": "Walls.js", 21 | "useroptions": {}, 22 | "previousversions": [] 23 | } -------------------------------------------------------------------------------- /WeightedDice/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "WeightedDice", 3 | "version": "0.3.2", 4 | "description": "Automated creation of rollable tables where a minimum value is weighted with values it replaces. (example d6min4 possible values: 4 4 4 4 5 6)", 5 | "authors": "The Aaron", 6 | "roll20userid": "104025", 7 | "patreon": "https://www.patreon.com/shdwjk", 8 | "dependencies": [], 9 | "modifies": { 10 | "state.WeightedDice": "read,write", 11 | "rollabletable": "create", 12 | "rollabletable.name": "read", 13 | "rollabletable.type": "read", 14 | "tableitem": "create" 15 | }, 16 | "conflicts": [], 17 | "script": "WeightedDice.js", 18 | "useroptions": {}, 19 | "previousversions": [] 20 | } -------------------------------------------------------------------------------- /WildDice/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "WildDice", 3 | "version": "0.3.1", 4 | "description": "Implements the Wild Dice rolling mechanic.", 5 | "authors": "The Aaron", 6 | "roll20userid": "104025", 7 | "patreon": "https://www.patreon.com/shdwjk", 8 | "dependencies": [], 9 | "modifies": [], 10 | "conflicts": [], 11 | "script": "WildDice.js", 12 | "useroptions": {}, 13 | "previousversions": [] 14 | } -------------------------------------------------------------------------------- /WorldMapDiscovery/README.md: -------------------------------------------------------------------------------- 1 | # World Map Discovery 2 | 3 | _v1.1 Updates:_ 4 | * Location discoveries now display an HTML-formatted message to the chat. 5 | * When locations are discovered, their white-tower status is removed. 6 | * The script now exposes some of its functions through its WorldMapDiscovery object. See the source code for details. 7 | 8 | This script allows the GM to set hidden locations on a world map that can be 9 | revealed when a character gets close enough. 10 | 11 | ### To use: 12 | 13 | 1. Turn on the landmark's ```white-tower status``` . 14 | 2. Set the landmark's ```aura 1 radius``` to whatever radius you want players to come within to discover the landmark. 15 | 3. Put the landmark on the ```GM layer```. 16 | 17 | ### Discovering landmarks: 18 | 19 | When a character token moves within the aura radius of the landmark, the landmark 20 | will appear on the graphics layer and a message will be displayed 21 | telling everyone that the character discovered it. When the landmark is 22 | discovered, its aura1 radius is removed. 23 | -------------------------------------------------------------------------------- /WorldMapDiscovery/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "World Map Discovery", 3 | "script": "WorldMapDiscovery.js", 4 | "version": "1.1", 5 | "previousversions": ["1.0"], 6 | "description": "# World Map Discovery\r\r_v1.1 Updates:_\r* Location discoveries now display an HTML-formatted message to the chat.\r* When locations are discovered, their white-tower status is removed.\r* The script now exposes some of its functions through its WorldMapDiscovery object. See the source code for details.\r\rThis script allows the GM to set hidden locations on a world map that can be\rrevealed when a character gets close enough.\r\r### To use:\r\r1. Turn on the landmark's ```white-tower status``` .\r2. Set the landmark's ```aura 1 radius``` to whatever radius you want players to come within to discover the landmark.\r3. Put the landmark on the ```GM layer```.\r\r### Discovering landmarks:\r\rWhen a character token moves within the aura radius of the landmark, the landmark\rwill appear on the graphics layer and a message will be displayed\rtelling everyone that the character discovered it. When the landmark is\rdiscovered, its aura1 radius is removed.\r", 7 | "authors": "Stephen Lindberg", 8 | "roll20userid": 46544, 9 | "useroptions": [], 10 | "dependencies": ["Vector Math"], 11 | "modifies": { 12 | "aura1_radius": "read, write", 13 | "chat": "write", 14 | "lastmove": "write", 15 | "layer": "read, write", 16 | "left": "read, write", 17 | "status_white-tower": "read", 18 | "token": "read", 19 | "top": "read, write" 20 | }, 21 | "conflicts": [] 22 | } 23 | -------------------------------------------------------------------------------- /ZombieDice/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ZombieDice", 3 | "version": "0.4.1", 4 | "description": "Rolls canceling Zombie Dice", 5 | "authors": "The Aaron", 6 | "roll20userid": "104025", 7 | "patreon": "https://www.patreon.com/shdwjk", 8 | "dependencies": [], 9 | "modifies": [], 10 | "conflicts": [], 11 | "script": "ZombieDice.js", 12 | "useroptions": {}, 13 | "previousversions": [] 14 | } -------------------------------------------------------------------------------- /_Example Script - Check for formatting details/0.5/example.js: -------------------------------------------------------------------------------- 1 | on('chat:message', function(msg) { 2 | if(msg.type == 'api' && msg.content.indexOf('!test') !== -1) 3 | { 4 | log(globalconfig); 5 | sendChat(msg.who, "/direct
TEST
"); 6 | } 7 | }); -------------------------------------------------------------------------------- /_Example Script - Check for formatting details/1.0/example.js: -------------------------------------------------------------------------------- 1 | on('chat:message', function(msg) { 2 | if(msg.type == 'api' && msg.content.indexOf('!test') !== -1) 3 | { 4 | log(globalconfig); 5 | sendChat(msg.who, "/direct
TEST
"); 6 | } 7 | }); -------------------------------------------------------------------------------- /_Example Script - Check for formatting details/1.1/example.js: -------------------------------------------------------------------------------- 1 | on('chat:message', function(msg) { 2 | if(msg.type == 'api' && msg.content.indexOf('!test') !== -1) 3 | { 4 | log(globalconfig); 5 | sendChat(msg.who, "/direct
TEST
"); 6 | } 7 | }); -------------------------------------------------------------------------------- /cron/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cron", 3 | "version": "0.11", 4 | "description": "Schedule (possibly recurring) commands to run at some point in the future.", 5 | "authors": "manveti", 6 | "roll20userid": "503018", 7 | "dependencies": {}, 8 | "modifies": {}, 9 | "conflicts": [] 10 | } 11 | -------------------------------------------------------------------------------- /levenshteinDistance/1.0/levenshteinDistance.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Compares two strings and returns the number of changes (substitutions, 3 | * insertions, and deletions) required to move from the first string to the 4 | * second. 5 | */ 6 | var bshields = bshields || {}; 7 | bshields.levenshteinDistance = (function() { 8 | 'use strict'; 9 | 10 | var version = 1.0; 11 | 12 | function levenshteinDistance(a, b) { 13 | var i, j, 14 | matrix = []; 15 | 16 | if (a.length === 0) { 17 | return b.length; 18 | } 19 | if (b.length === 0) { 20 | return a.length; 21 | } 22 | 23 | // Increment along the first column of each row 24 | for (i = 0; i <= b.length; i++) { 25 | matrix[i] = [i]; 26 | } 27 | 28 | // Increment each column in the first row 29 | for (j = 0; j <= a.length; j++) { 30 | matrix[0][j] = j; 31 | } 32 | 33 | // Fill in the rest of the matrix 34 | for (i = 1; i <= b.length; i++) { 35 | for (j = 1; j <= a.length; j++) { 36 | if (b.charAt(i - 1) === a.charAt(j - 1)) { 37 | matrix[i][j] = matrix[i - 1][j - 1]; 38 | } else { 39 | matrix[i][j] = Math.min(matrix[i - 1][j - 1] + 1, // Substitution 40 | Math.min(matrix[i][j - 1] + 1, // Insertion 41 | matrix[i - 1][j] + 1)); // Deletion 42 | } 43 | } 44 | } 45 | 46 | return matrix[b.length][a.length]; 47 | } 48 | 49 | return levenshteinDistance; 50 | }()); -------------------------------------------------------------------------------- /levenshteinDistance/1.1/levenshteinDistance.js: -------------------------------------------------------------------------------- 1 | var bshields = bshields || {}; 2 | bshields.levenshteinDistance = (function() { 3 | 'use strict'; 4 | 5 | var version = 1.1; 6 | 7 | function levenshteinDistance(a, b) { 8 | var i, j, 9 | matrix = []; 10 | 11 | if (a.length === 0) { 12 | return b.length; 13 | } 14 | if (b.length === 0) { 15 | return a.length; 16 | } 17 | 18 | // Increment along the first column of each row 19 | for (i = 0; i <= b.length; i++) { 20 | matrix[i] = [i]; 21 | } 22 | 23 | // Increment each column in the first row 24 | for (j = 0; j <= a.length; j++) { 25 | matrix[0][j] = j; 26 | } 27 | 28 | // Fill in the rest of the matrix 29 | for (i = 1; i <= b.length; i++) { 30 | for (j = 1; j <= a.length; j++) { 31 | if (b.charAt(i - 1) === a.charAt(j - 1)) { 32 | matrix[i][j] = matrix[i - 1][j - 1]; 33 | } else { 34 | matrix[i][j] = Math.min(matrix[i - 1][j - 1] + 1, // Substitution 35 | Math.min(matrix[i][j - 1] + 1, // Insertion 36 | matrix[i - 1][j] + 1)); // Deletion 37 | } 38 | } 39 | } 40 | 41 | return matrix[b.length][a.length]; 42 | } 43 | 44 | return levenshteinDistance; 45 | }()); 46 | 47 | String.prototype.levenshteinDistance = String.prototype.levenshteinDistance || function(b) { 48 | return bshields.levenshteinDistance(this, b); 49 | }; -------------------------------------------------------------------------------- /levenshteinDistance/README.md: -------------------------------------------------------------------------------- 1 | ## levenshteinDistance 2 | 3 | Provides a levenshteinDistance function for comparing strings. This script is not intended to stand alone. As a convenience, this function has been added to the String prototype. -------------------------------------------------------------------------------- /levenshteinDistance/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "levenshteinDistance", 3 | "script": "levenshteinDistance.js", 4 | "version": "1.1", 5 | "previousversions": ["1.0"], 6 | "description": "Provides a levenshteinDistance function for comparing strings. This script is not intended to stand alone.", 7 | "authors": "Brian Shields", 8 | "roll20userid": "235259", 9 | "patreon": "https://www.patreon.com/bshields", 10 | "useroptions": [], 11 | "dependencies": [], 12 | "modifies": [], 13 | "conflicts": [] 14 | } 15 | -------------------------------------------------------------------------------- /splitArgs/1.1/splitArgs.js: -------------------------------------------------------------------------------- 1 | var bshields = bshields || {}; 2 | bshields.splitArgs = (function() { 3 | 'use strict'; 4 | 5 | var version = 1.1; 6 | 7 | function splitArgs(input, separator) { 8 | var singleQuoteOpen = false, 9 | doubleQuoteOpen = false, 10 | tokenBuffer = [], 11 | ret = [], 12 | arr = input.split(''), 13 | element, i, matches; 14 | separator = separator || /\s/g; 15 | 16 | for (i = 0; i < arr.length; i++) { 17 | element = arr[i]; 18 | matches = element.match(separator); 19 | if (element === '\'') { 20 | if (!doubleQuoteOpen) { 21 | singleQuoteOpen = !singleQuoteOpen; 22 | continue; 23 | } 24 | } else if (element === '"') { 25 | if (!singleQuoteOpen) { 26 | doubleQuoteOpen = !doubleQuoteOpen; 27 | continue; 28 | } 29 | } 30 | 31 | if (!singleQuoteOpen && !doubleQuoteOpen) { 32 | if (matches) { 33 | if (tokenBuffer && tokenBuffer.length > 0) { 34 | ret.push(tokenBuffer.join('')); 35 | tokenBuffer = []; 36 | } 37 | } else { 38 | tokenBuffer.push(element); 39 | } 40 | } else if (singleQuoteOpen || doubleQuoteOpen) { 41 | tokenBuffer.push(element); 42 | } 43 | } 44 | if (tokenBuffer && tokenBuffer.length > 0) { 45 | ret.push(tokenBuffer.join('')); 46 | } 47 | 48 | return ret; 49 | } 50 | 51 | return splitArgs; 52 | }()); 53 | 54 | String.prototype.splitArgs = String.prototype.splitArgs || function(separator) { 55 | return bshields.splitArgs(this, separator); 56 | }; -------------------------------------------------------------------------------- /splitArgs/README.md: -------------------------------------------------------------------------------- 1 | ## splitArgs 2 | 3 | Provides a function for splitting arguments of an API command. This script is not intended to stand alone. As a convenience, this function has been added to the String prototype. 4 | 5 | This function is particularly useful for tokenizing API commands, as it allows the user to quote arguments. For example, `!command with parameters, "including 'with quotes'"` would be split into the array `["!command", "with", "parameters,", "including 'with quotes'"]`. -------------------------------------------------------------------------------- /splitArgs/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "splitArgs", 3 | "script": "splitArgs.js", 4 | "version": "1.1", 5 | "previousversions": ["1.0"], 6 | "description": "Provides a function for splitting arguments of an API command. This script is not intended to stand alone.", 7 | "authors": "Brian Shields", 8 | "roll20userid": "235259", 9 | "patreon": "https://www.patreon.com/bshields", 10 | "useroptions": [], 11 | "dependencies": [], 12 | "modifies": {}, 13 | "conflicts": [] 14 | } 15 | -------------------------------------------------------------------------------- /textTimer/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Jean-Luc 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /textTimer/README.md: -------------------------------------------------------------------------------- 1 | # textTimer 2 | A text timer for the roll20 API. Work in progress. 3 | 4 | This code was based off manveti's cron script (https://github.com/Roll20/roll20-api-scripts/tree/master/cron) 5 | A huge thanks goes to him. 6 | 7 | Will add more functionality in the future. 8 | -------------------------------------------------------------------------------- /textTimer/script.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "textTimer", 3 | "version": "0.1", 4 | "description": "Create visual timers for timed dungeons and other things", 5 | "authors": "Temennigru", 6 | "roll20userid": "843797", 7 | "dependencies": {}, 8 | "modifies": {}, 9 | "conflicts": [] 10 | } --------------------------------------------------------------------------------