diff --git a/APIHeartBeat/APIHeartBeat.js b/APIHeartBeat/APIHeartBeat.js new file mode 100644 index 0000000000..7f91e985e8 --- /dev/null +++ b/APIHeartBeat/APIHeartBeat.js @@ -0,0 +1,96 @@ +// Github: https://github.com/shdwjk/Roll20API/blob/master/APIHeartBeat/APIHeartBeat.js +// By: The Aaron, Arcane Scriptomancer +// Contact: https://app.roll20.net/users/104025/the-aaron + +var APIHeartBeat = APIHeartBeat || (function() { + 'use strict'; + + var version = 0.1, + schemaVersion = 0.1, + beatInterval = false, + beatPeriod = 400, + beatCycle = (beatPeriod * 8), + + animateHeartBeat = function() { + var x = (Date.now()%beatCycle)*12.5, + scale = Math.max(0, ( Math.sin( (x-1)/2) - Math.sin(x-(1+(Math.PI/2))))), + beatColor = Math.round(0xff*scale).toString(16)+'0000'; + + _.chain(state.APIHeartBeat.heartBeaters) + .map(function(pid){ + return getObj('player',pid); + }) + .filter(_.isUndefined) + .each(function(p){ + p.set({ + color: beatColor + }); + }); + }, + + startStopBeat = function() { + if(!beatInterval && state.APIHeartBeat.heartBeaters.length) { + beatInterval = setInterval(animateHeartBeat,beatPeriod); + } else if(beatInterval && !state.APIHeartBeat.heartBeaters.length) { + clearInterval(beatInterval); + } + }, + + handleInput = function(msg) { + var args; + + if (msg.type !== "api") { + return; + } + + args = msg.content.split(/\s+/); + switch(args[0]) { + case '!api-heartbeat': + if(_.contains(state.APIHeartBeat.heartBeaters, msg.playerid)) { + state.APIHeartBeat.heartBeaters=_.without(state.APIHeartBeat.heartBeaters, msg.playerid); + } else { + state.APIHeartBeat.heartBeaters.push(msg.playerid); + } + + startStopBeat(); + + break; + } + }, + + checkInstall = function() { + if( ! _.has(state,'APIHeartBeat') || state.APIHeartBeat.version !== schemaVersion) { + log('APIHeartBeat: Resetting state'); + state.APIHeartBeat = { + version: schemaVersion, + heartBeaters: [] + }; + } + + startStopBeat(); + }, + + registerEventHandlers = function() { + on('chat:message', handleInput); + }; + + return { + CheckInstall: checkInstall, + RegisterEventHandlers: registerEventHandlers + }; + +}()); + +on('ready',function() { + 'use strict'; + + if("undefined" !== typeof isGM && _.isFunction(isGM)) { + APIHeartBeat.CheckInstall(); + APIHeartBeat.RegisterEventHandlers(); + } else { + log('--------------------------------------------------------------'); + log('APIHeartBeat requires the isGM module to work.'); + log('isGM GIST: https://gist.github.com/shdwjk/8d5bb062abab18463625'); + log('--------------------------------------------------------------'); + } +}); diff --git a/APIHeartBeat/pacakge.json b/APIHeartBeat/pacakge.json new file mode 100644 index 0000000000..209e7e4fb7 --- /dev/null +++ b/APIHeartBeat/pacakge.json @@ -0,0 +1,14 @@ +{ + "name": "APIHeartBeat", + "version": "0.1", + "description": "Provides an API Heartbeat by setting the requesting player's color continuously.", + "authors": "The Aaron", + "roll20userid": "104025", + "dependencies": { + }, + "modifies": { + "state.APIHeartBeat": "read,write", + }, + "conflicts": [ + ] +} diff --git a/Ammo/Ammo.js b/Ammo/Ammo.js new file mode 100644 index 0000000000..b38b7f047f --- /dev/null +++ b/Ammo/Ammo.js @@ -0,0 +1,315 @@ +// Github: https://github.com/shdwjk/Roll20API/blob/master/Ammo/Ammo.js +// By: The Aaron, Arcane Scriptomancer +// Contact: https://app.roll20.net/users/104025/the-aaron + +var Ammo = Ammo || (function() { + 'use strict'; + + var version = 0.2, + schemaVersion = 0.1, + + ch = function (c) { + var entities = { + '<' : 'lt', + '>' : 'gt', + "'" : '#39', + '@' : '#64', + '{' : '#123', + '|' : '#124', + '}' : '#125', + '[' : '#91', + ']' : '#93', + '"' : 'quot', + '-' : 'mdash', + ' ' : 'nbsp' + }; + + if(_.has(entities,c) ){ + return ('&'+entities[c]+';'); + } + return ''; + }, + sendMessage = function(message, who) { + sendChat('Ammo', (who ? ('/w '+who+' ') : '') + '
Ammo provides inventory management for ammunition stored in a character' + +'attribute. If the adjustment would change the attribute to be below 0 or above' + +'it\'s maximum value, a warning will be issued and the attribute will not be' + +'changed.
' + + +( (isGM(playerid)) ? 'Note: As the GM, bounds will not be ' + +'enforced for you. You will be whispered the warnings, but the operation ' + +'will succeed. You will also be told the previous and current state in case ' + +'you want to revert the change.' : '') + + +'
Allows statues to be used like Fate stress boxes by repeating them.
' + +'By default, Blue and Red will be treated specially. Assigning a number to them will cause them to be duplicated that many times, and numbered in decreasing order. Changing the number will change the number of pips that appear.
' + +'Available Status Markers:
' + +'Adding purple and skull, removing blue.
' + +'' + +'!fate-dots +purple +skull -blue' + +'' + +'
Rolls initiative for the selected tokens and adds them ' + +'to the turn order if they don'+ch("'")+'t have a turn yet.
' + + +'The calculation of initiative is handled by the ' + +'combination of Roller (See Roller Options below) and ' + +'a Bonus. The Bonus is determined based on an ordered list ' + +'of Stat Groups (See Bonus Stat Groups below). Stat ' + +'Groups are evaluated in order. The bonus computed by the first ' + +'Stat Group for which all attributes exist and have a ' + +'numeric value is used. This allows you to have several ' + +'Stat Groups that apply to different types of characters. ' + +'In practice you will probably only have one, but more are ' + +'there if you need them.
' + +'This command uses the configured Roller to ' + +'determine the initiative order for all selected ' + +'tokens.
' + +'This command displays the help.
' + +'Sets Roller to use for calculating initiative.
' + +'This command requires 1 parameter:' + +'Increases the importance the specified Bonus Stat Group.
' + +'This command requires 1 parameter:' + +'Deletes the specified Bonus Stat Group.
' + +'This command requires 1 parameter:' + +'Adds a new Bonus Stat Group to the end of the list. Each adjustment operation can be followed by another adjustment operation, but eventually must end in an attriute name. Adjustment operations are applied to the result of the adjustment operations that follow them.
' + +'For example: --Bounded:-2:2 --Stat-DnD wisdom|max would first computer the DnD Stat bonus for the max field of the wisdom attribute, then bound it between -2 and +2.
' + +'This command takes multiple parameters:' + +'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.
' + +'This 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.
' + +'Note: If you are using multiple '+ch('@')+ch('{')+'target'+ch('|')+'token_id'+ch('}')+' 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.
' + +'Clears all the markers. (GM Only)
' + +'MovePlayers provides facilities for moving your players around at will.
' + +'Moves the Players ribbon to the same page as the token identified by Token ID.
' + +'Allows the GM to easily randomize the rotation of the selected tokens.
' + +'SizeLock allows the GM to toggle the Campaign into a state where ' + +'any time a token is resized, the change is reverted automatically.' + +'
Allows the GM to toggle spinning of selected tokens
' + +'This script dumps commands to the chat for reconstructing a rollable table on another campaign. While this can be done on your own campaigns via the transmogrifyer, this script allows you to pass those commands to a friend and thus share your own creative works with others.
' + +'
Caveat: Avatar images that are not in your own library will be ignored by the API on import, but will not prevent creation of the table and table items.
' + +'For all table names, case is ignored and you may use partial names so long as they are unique. For example, '+ch('"')+'King Maximillian'+ch('"')+' could be called '+ch('"')+'max'+ch('"')+' as long as '+ch('"')+'max'+ch('"')+' does not appear in any other table names. Exception: An exact match will trump a partial match. In the previous example, if a table named '+ch('"')+'Max'+ch('"')+' existed, it would be the only table matched for --max.
' + +'This is the command output by !export-table to create the new table. You likely will not need issue these commands directly.
' + +'This is the command output by !export-table to create the new table. You likely will not need issue these commands directly.
' + +'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.
' + + 'Moving of player controlled cards is still permissible.
' + +'TokenMod provides an interface to setting almost all setable properties of a token.
' + +'This command takes a list of modifications and applies them to the selected tokens (or tokens specified with --ids by a GM or Player depending on configuration). Note that each --option can be specified multiple times and in any order.
' + +'Note: If you are using multiple '+ch('@')+ch('{')+'target'+ch('|')+'token_id'+ch('}')+' calls in a macro, and need to adjust fewer than the supplied number of token ids, simply select the same token several times. The duplicates will be removed.
' + +'--ids takes token ids to operate on, separated by spaces.
' + +'' + +'!token-mod --ids -Jbz-mlHr1UXlfWnGaLh -JbjeTZycgyo0JqtFj-r -JbjYq5lqfXyPE89CJVs --on showname showplayers_name' + +'' + +'
Usually, you will want to specify these with the @{target} syntax:
' + +''
+ +'!token-mod --ids @{target|1|token_id} @{target|2|token_id} @{target|3|token_id} --on showname showplayers_name'
+ +''
+
+ +'--config takes option value pairs, separated by | characters.
' + +'' + +'!token-mod --config option|value option|value' + +'' + +'
There is currently one configuration option:
' + + +'The --on, --off and --flip options only work on properties of a token that are either true or false, checkboxes. Specified properties will only be changed once, priority is given to arguments to --on first, then --off and finally to --flip.
' + +'' + +'!token-mod --on showname light_hassight --off isdrawing --flip flipv fliph' + +'' + +'
Available Boolean Properties:
' + +'Any of the booleans can be set with the --set command by passing a true or false as the value
' + +'' + +'!token-mod --set showname|yes isdrawing|no' + +'' + +'
--set takes key value pairs, separated by | characters.
' + +'' + +'!token-mod --set key|value key|value key|value' + +'' + + +'
Note: You can now use inline rolls wherever you like:
' + +''
+ +'!token-mod --set bar'+ch('[')+ch('[')+'1d3'+ch(']')+ch(']')+'_value|X statusmarkers|blue:'+ch('[')+ch('[')+'1d9'+ch(']')+ch(']')+'|green:'+ch('[')+ch('[')+'1d9'+ch(']')+ch(']')
+ +''
+
+ +'Note: You can now use + or - before any number to make an adjustment to the current value:
' + +'' + +'!token-mod --set bar1_value|-3 statusmarkers|blue:+1|green:-1' + +'' + + +'
There are several types of keys with special value formats:
' + + +'Number values can be any floating point number (though most fields will drop the fractional part).
' + +'Available Numbers Properties:
' + +'It'+ch("'")+'s probably a good idea not to set the location of a token off screen or the width or height to 0.
' + +'' + +'!token-mod --set top|0 left|0 width|50 height|50' + +'' + +'
Just like the Numbers fields, except you can set them to blank as well.
' + +'Available Numbers or Blank Properties:
' + +'Here is setting a standard DnD 5e torch, turning off aura1 and setting aura2 to 30. Note that the | is still required for setting a blank value, such as aura1_radius below.
' + +'' + +'!token-mod --set light_radius|40 light_dimradius|20 aura1_radius| aura2_radius|30' + +'' + +'
Any positive or negative integer.
' + +'Available Degrees Properties:
' + +'Rotating a token by 180 degrees, and setting line of sight angle to 90 degrees.
' + +'' + +'!token-mod --set rotation|180 light_losangle|90' + +'' + +'
Colors can be any hex number color (with or without preceeding #), or the word transparent.
' + +'Available Color Properties:
' + +'Turning off the tint and setting aura1 to a reddish color.
' + +'' + +'!token-mod --set tint_color|transparent aura1_color|ff3366' + +'' + +'
These can be pretty much anything. If your value has spaces in it, you need to enclose it in '+ch("'")+' or '+ch('quot')+'.
' + +'Available Text Properties:
' + +'Setting the name to Sir Thomas and bar1 to 23.
' + +''
+ +'!token-mod --set name|'+ch('"')+'Sir Thomas'+ch('"')+' bar1_value|23'
+ +''
+ +'bar1, bar2 and bar3 are special. Any value set on them will be set in both the _value and _max fields for that bar. This is most useful for setting hit points.
' + +''
+ +'!token-mod --set bar1|'+ch('[')+ch('[')+'3d6+8'+ch(']')+ch(']')
+ +''
+ +'There is only one Layer property. It can be one of 4 values, listed below.
' + +'Available Layer Property:
' + +'Available Layer Values:
' + + +'Moving something to the gmlayer.
' + +'' + +'!token-mod --set layer|gmlayer' + +'' + +'
There is only one Status property. Status has a somewhat complicated syntax to support the most possible flexibility.
' + +'Available Status Property:
' + +'Status is the only property that supports multiple values, all seperated by | as seen below.
' + +'' + +'!token-mod --set statusmarkers|blue|red|green|padlock|broken-shield' + +'' + +'
You can optionally preface each status with a + to remind you it is being added. This command is identical:
' + +'' + +'!token-mod --set statusmarkers|+blue|+red|+green|+padlock|+broken-shield' + +'' + +'
Each value can be followed by a colon and a number between 0 and 9. (The number following the dead status is ignored because it is special.)
' + +'' + +'!token-mod --set statusmarkers|blue:0|red:3|green|padlock:2|broken-shield:7' + +'' + +'
The numbers following a status can be prefaced with a + or -, which causes their value to be applyed to the current value. Here'+ch("'")+'s and example showing blue getting incremented by 2, and padlock getting decremented by 1. Values will be bounded between 0 and 9.
' + +'' + +'!token-mod --set statusmarkers|blue:+2|padlock:-1' + +'' + +'
By default, status markers will be added, retaining whichever status markers are already present. You can override this behavior by prefacing a value with a - to cause the status to be removed. Below will remove the blue and padlock status.
' + +'' + +'!token-mod --set statusmarkers|-blue|-padlock' + +'' + +'
Sometimes it is convenient to have a way to add a status if it is not there, but remove it if it is. This allows marking tokens with markers and clearing them with the same command. You can preface a status with ! to toggle it'+ch("'")+'s state on and off. Here is an example that will add or remove the Rook piece from a token.
' + +'' + +'!token-mod --set statusmarkers|!white-tower' + +'' + +'
Sometimes, you might want to clear all status marker as part of setting a new status marker. You can do this by prefacing a status marker with a =. Note that this affects all status markers before as well, so you will want to do this only on the first status marker. Below all status markers are removed and the dead marker is set. (If you want to remove all status markers, just specify the same marker twice with a = and then a -.)
' + +'' + +'!token-mod --set statusmarkers|=dead' + +'' + +'
Available Status Markers:
' + +'All of these operations can be combine in a single statusmarkers command.
' + +'' + +'!token-mod --set statusmarkers|blue:3|-dead|red:3' + +'' + +'
You can use the '+ch('@')+ch('{')+ch('<')+'character name'+ch('>')+ch('|')+'character_id'+ch('}')+' syntax to specify a character_id directly or use the name of a character (quoted if it contains spaces) or just the shortest part of the name that is unique ('+ch("'")+'Sir Maximus Strongbow'+ch("'")+' could just be '+ch("'")+'max'+ch("'")+'.). Not case sensitive: Max = max = MaX = MAX
' + +'Available Character ID Properties:
' + +'Here is setting the represents to the character Bob.
' + +''
+ +'!token-mod --set represents|'+ch('@')+ch('{')+'Bob'+ch('|')+'character_id'+ch('}')
+ +''
+ +'Note that setting the represents will clear the links for the bars, so you will probably want to set those again.
' + +'These are resolved from the represented character id. If the token doesn'+ch("'")+'t represent a character, these will be ignored.
' + +'Available Attribute Name Properties:
' + +'Here is setting the represents to the character Bob and setting bar1 to be the npc hitpoints attribute.
' + +''
+ +'!token-mod --set represents|'+ch('@')+ch('{')+'Bob'+ch('|')+'character_id'+ch('}')+' bar1_link|npc_HP'
+ +''
+ +'Torch provides commands for managing dynamic lighting. Supplying a first argument of help to any of the commands displays this help message, as will calling !torch or !snuff with nothing supplied or selected.
' + +'Torch now supports Jack Taylor inspired flickering lights. Flicker lights are only active on pages where a player is (GMs, drag yourself to other pages if you don'+ch("'")+'t want to move the party.) and are persisted in the state. Flicker lights can be used in addition to regular lights as they are implemented on a separate invisible token that follows the nomal token. Tokens for flicker lights that have been removed are stored on the GM layer in the upper left corner and can be removed if desired. They will be reused if a new flicker light is requested.
' + +'Sets the light for the selected/supplied tokens. Only GMs can supply token ids to adjust.
' + +'Note: If you are using multiple '+ch('@')+ch('{')+'target'+ch('|')+'token_id'+ch('}')+' calls in a macro, and need to adjust light on fewer than the supplied number of arguments, simply select the same token several times. The duplicates will be removed.
' + +'Turns off light for the selected/supplied tokens. Only GMs can supply token ids to adjust.
' + +'Note: If you are using multiple '+ch('@')+ch('{')+'target'+ch('|')+'token_id'+ch('}')+' calls in a macro, and need to adjust light on fewer than the supplied number of arguments, simply select the same token several times. The duplicates will be removed.
' + +'Behaves identically to !torch, save that it creates a flickering light.
' + +'Behaves identically to !snuff, save that it affects the flickering light.
' + +'Turns off dynamic lighting for the current player page, or the page of the selected/supplied token.
' + +'Turns on dynamic lighting for the current player page, or the page of the selected/supplied token.
' + +'UsePower provides a way to instrument and track daily and encounter powers. It is intended for D&D 4E, but could be used for any system that requires the capability to flag abilities as used and reset them. Using an instrumented ability will mark it used and remove it as a token action. (Caveat: it will disappear the next time the owner deselects the token.)
' + +'Daily powers are restored to token actions after !long-rest is executed. Encounter abilities are restored to token actions after !short-rest or !long-rest is executed. Activating a used power will whisper to the player and GM that the power was already used.
' + +'For all character names, case is ignored and you may use partial names so long as they are unique. For example, '+ch('"')+'King Maximillian'+ch('"')+' could be called '+ch('"')+'max'+ch('"')+' as long as '+ch('"')+'max'+ch('"')+' does not appear in any other names. Exception: An exact match will trump a partial match. In the previous example, if a character named '+ch('"')+'Max'+ch('"')+' existed, it would be the only character matched for --max.
' + +'Omitting any --encounter and --daily parameters will cause a list of the character'+ch("'")+'s powers with the expected index numbers (Caveat: These numbers will change if you add powers to the character. You should look them up again before instrumenting if you have changed the list of powers.)
' + +'This command restores all expended encounter powers to token macros.
' + +'This command restores all expended encounter and daily powers to token macros.
' + +'This command requires 2 parameters. It is usually added by the instrumenting code. If you copy it from one ability to another, it will be updated with the correct Ability ID on save. Duplicating an existing character will also cause the new character'+ch("'")+'s abilities to be corrected. All abilities are validated and updated on restart of the API.
' + +'