From d387a0cbf982de2f3418b0c92517d8a364b84873 Mon Sep 17 00:00:00 2001
From: DameryDad <74715860+DameryDad@users.noreply.github.com>
Date: Tue, 26 Mar 2024 18:44:40 +0100
Subject: [PATCH] Non-functional sequencing release to synchronise versions
---
CommandMaster/3.3.0/CommandMaster.js | 5708 ++++++++++++++++++++++++++
CommandMaster/CommandMaster.js | 10 +-
CommandMaster/script.json | 4 +-
3 files changed, 5716 insertions(+), 6 deletions(-)
create mode 100644 CommandMaster/3.3.0/CommandMaster.js
diff --git a/CommandMaster/3.3.0/CommandMaster.js b/CommandMaster/3.3.0/CommandMaster.js
new file mode 100644
index 000000000..56297075e
--- /dev/null
+++ b/CommandMaster/3.3.0/CommandMaster.js
@@ -0,0 +1,5708 @@
+// Github: https://github.com/Roll20/roll20-api-scripts/tree/master/CommandMaster
+// Beta: https://github.com/DameryDad/roll20-api-scripts/tree/CommandMaster/CommandMaster
+// By: Richard @ Damery
+// Contact: https://app.roll20.net/users/6497708/richard-at-damery
+
+var API_Meta = API_Meta||{}; // eslint-disable-line no-var
+API_Meta.CommandMaster={offset:Number.MAX_SAFE_INTEGER,lineCount:-1};
+{try{throw new Error('');}catch(e){API_Meta.CommandMaster.offset=(parseInt(e.stack.split(/\n/)[1].replace(/^.*:(\d+):.*$/,'$1'),10)-8);}}
+
+/**
+ * CommandMaster.js
+ *
+ * * Copyright 2020: Richard @ Damery.
+ * Licensed under the GPL Version 3 license.
+ * http://www.gnu.org/licenses/gpl.html
+ *
+ * This script is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This script is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ *
+ * This script is the GM control capability for the RedMaster series
+ * of APIs for Roll20. It allows the other RedMaster series APIs to
+ * register with it with their current commands and ability button specs
+ * which are used by CommandMaster to build the GM Maintenance Menu,
+ * and to update Character Sheets that use the commands in abilities
+ * with the latest command structures. It supports other functions
+ * useful to the GM as needed.
+ *
+ * v0.001 02/05/2021 Initial creation as a clone of attackMaster
+ * v0.002-1.025 Early development. See v2.027 for details.
+ * v2.026 27/02/2022 Added Class-DB as a standard database. Fixed 'Specials' action
+ * button & updated command registration. Fixed command registration errors.
+ * Added token-setup buttons to add all possible character Powers & Priest
+ * spells from Class-DB.
+ * v2.027 10/03/2022 Add sychronisation of Database indexing to ensure happens after
+ * all databases loaded by all APIs before indexing done. Add
+ * "Creature" character class. Use AttackMaster version of --check-saves
+ * to unify character setup. Added token-setup buttons to check who
+ * controls what Char Sheets & toggle control DM/Player
+ * v2.030 28/03/2022 Moved all Table Mgt, Ability Mgt, Chat Mgt, Database Mgt to a
+ * shared library
+ * v2.031 24/04/2022 Moved all game-specific and character sheet-specific data structures
+ * to the RPGM game-specific library api.
+ * v0.2.32 20/07/2022 Converted to use revised internal database structures
+ * v0.2.33 17/09/2022 Moved additional common RPGMaster functions to Library. Moved common
+ * help handouts to Library. Optionally allow semi-colons as terminators
+ * for escaped characters in commands. Improve generating of spell lists
+ * for Priest classes, and Power lists for all classes. Change --help to
+ * provide a menu of links to help handouts
+ * v1.3.00 17/09/2022 First release of RPGMaster APIs with RPG-version-specific Library
+ * v1.3.01 04/10/2022 Allow Wizard and Priest spells to be stored as powers
+ * v1.3.02 23/10/2022 Fixed error with Specials action button
+ * v1.3.03 29/10/2022 Trap initialisation errors. Add All Powers will add race powers from
+ * the race database. Add Race selection to Class menu.
+ * v1.3.04 17/11/2022 Added possible creature data attributes, & fixed certain creature
+ * setup issues. Added weapon data update after race/class/level change
+ * to support things like attacks/round improvement
+ * v1.4.01 28/11/2022 Added support for the fighting Styles-DB. Fixed help menu. Improved
+ * creature attribute dice rolling. Improved creature HD & HP calcs.
+ * Added creature attribute dexdef dexterity bonus for ranged attacks.
+ * Added use of alpha indexed drop down for selection of creatures.
+ * Added suppression of power inheritance. Added function to check
+ * player, speakingas, token & character names for illegal characters.
+ * v1.4.02 13/12/2022 Added API button on token & character name checks to support immediate
+ * correction. Add ability to specify weapons and armour for creatures
+ * with probability of different sets. Split handling of PC Race specifications
+ * and Creature specifications, so that Races don't get set up with
+ * spurious creature specs.
+ * v1.4.03 16/01/2023 Added creature attkmsg & dmgmsg attributes to support messages to
+ * display with attack and damage rolls respectively.
+ * v1.4.04 24/01/2023 Added support for converting manually created character sheets to
+ * RPGMaster format. Added ability to configure the default token bars.
+ * Added functions to set token bars for all campaign tokens. Added
+ * separate Ammo list for Equipment conversion. Tidied up Token-Setup
+ * menu.
+ * v1.4.05 02/03/2023 Non-functional update release to maintain version sequence.
+ * v1.4.06 08/04/2023 Added support for when a magic item character sheet is first dragged
+ * to the player map, to set it to isdrawing=true and link to the CS.
+ * v1.4.07 14/04/2023 Fixed bug stopping Token Setup, Add to Spellbook from working.
+ * v1.5.01 19/05/2023 Non-functional version number synchronisation release.
+ * v2.1.0 06/06/2023 Made many more functions asynchronous to multi-thread. Parsed a
+ * creature's description in its database entry and created a Character
+ * Sheet Bio from it.
+ * v2.2.0 21/07/2023 Implemented The Aaron's API_Meta error handling. Added senderId override
+ * capability as id immediately after !magic & before 1st --cmd. Added
+ * Drag & Drop containers to the Drag & Drop system, using the
+ * Race-DB-Containers & Locks-Traps-DB databases. Made reSpellSpecs,
+ * reClassSpecs & reAttr accessible by other APIs from the library.
+ * Made –initialise command automatic on startup if the defined GM macros
+ * have changed. Enhanced parseDesc() to cater for both creatures and
+ * containers, locks & traps. Removed potential setTimeout() issues
+ * with asynchronous use of variable values – passed as parameters instead.
+ * Fixed error when cs attribute 'trap-name' is missing or empty.
+ * v2.3.0 30/09/2023 Added drag & drop query attribute that adds an extra level of query to
+ * drag & drop creature selection and returns variables based on the selection.
+ * Fixed parsing of {{prefix=...}} in drag & drop creature descriptions.
+ * Added new maths evaluation function to support new race 'query' variables.
+ * Add memorisation of random spells for spell-casting drag & drop creatures.
+ * Added new dice roll evaluator. Moved characterLevel() to library.
+ * v2.3.1 19/10/2023 Added "Token Image Quick Copy" --copyimg function. Added ^^gmid^^ field
+ * for container macros to support TokenMod --api-as parameter. Stop
+ * specification of races not in the database for now. Ensured spell names
+ * in spell books are hyphenated to avoid inconsistencies.
+ * v2.3.2 20/10/2023 Added age: attribute as a condition value for Drag & Drop creature items.
+ * Improved the maths parser to iterate more deeply. Changed how 'GM-Roll'
+ * flag builds GM rolls into container macros. Fixed hyphenation of
+ * reviewed weapons, spells & powers.
+ * v3.0.0 01/10/2023 Added support for other character sheets & game systems.
+ * Moved parseData() to library.
+ * v3.1.0 16/12/2023 Modified to support AD&D1e character sheet and rule set. Fixed weapon
+ * multi-hand parsing issue, clashing with % chance. Added library functions
+ * to support different ways of specifying and displaying the class & level
+ * on the character sheet. Fixed support for Drag & Drop creature hp ranges.
+ * v3.2.0 08/02/2024 Add proficiency list for AD&D1e version. Fix bug in some creature definitions
+ * that listed weapons in-hand.
+ * v3.2.1 23/02/2024 Improved parseStr() handling of undefined or empty strings without erroring.
+ * v3.3.0 18/03/2024 Non-functional sequencing release to synchronise versions
+ */
+
+var CommandMaster = (function() {
+ 'use strict';
+ var version = '3.3.0',
+ author = 'RED',
+ pending = null;
+ const lastUpdate = 1711471190;
+
+ /*
+ * Define redirections for functions moved to the RPGMaster library
+ */
+
+ const getRPGMap = (...a) => libRPGMaster.getRPGMap(...a);
+ const getHandoutIDs = (...a) => libRPGMaster.getHandoutIDs(...a);
+ const setAttr = (...a) => libRPGMaster.setAttr(...a);
+ const attrLookup = (...a) => libRPGMaster.attrLookup(...a);
+ const getTableField = (...t) => libRPGMaster.getTableField(...t);
+ const getTable = (...t) => libRPGMaster.getTable(...t);
+ const getLvlTable = (...t) => libRPGMaster.getLvlTable(...t);
+ const initValues = (...v) => libRPGMaster.initValues(...v);
+ const setAbility = (...a) => libRPGMaster.setAbility(...a);
+ const abilityLookup = (...a) => libRPGMaster.abilityLookup(...a);
+ const doDisplayAbility = (...a) => libRPGMaster.doDisplayAbility(...a);
+ const getAbility = (...a) => libRPGMaster.getAbility(...a);
+ const getDBindex = (...a) => libRPGMaster.getDBindex(...a);
+ const updateHandouts = (...a) => libRPGMaster.updateHandouts(...a);
+ const findThePlayer = (...a) => libRPGMaster.findThePlayer(...a);
+ const findCharacter = (...a) => libRPGMaster.findCharacter(...a);
+ const fixSenderId = (...a) => libRPGMaster.fixSenderId(...a);
+ const calcAttr = (...a) => libRPGMaster.calcAttr(...a);
+ const rollDice = (...a) => libRPGMaster.rollDice(...a);
+ const evalAttr = (...a) => libRPGMaster.evalAttr(...a);
+ const getCharacter = (...a) => libRPGMaster.getCharacter(...a);
+ const classObjects = (...a) => libRPGMaster.classObjects(...a);
+ const characterLevel = (...a) => libRPGMaster.characterLevel(...a);
+ const updateClassLevel = (...a) => libRPGMaster.updateClassLevel(...a);
+ const displayClassLevel = (...a) => libRPGMaster.displayClassLevel(...a);
+ const addMIspells = (...a) => libRPGMaster.addMIspells(...a);
+ const getMagicList = (...a) => libRPGMaster.getMagicList(...a);
+ const handleCheckSaves = (...a) => libRPGMaster.handleCheckSaves(...a);
+ const handleCheckWeapons = (...a) => libRPGMaster.handleCheckWeapons(...a);
+ const parseData = (...a) => libRPGMaster.parseData(...a);
+ const resolveData = (...a) => libRPGMaster.resolveData(...a);
+ const caster = (...a) => libRPGMaster.caster(...a);
+ const findPower = (...a) => libRPGMaster.findPower(...a);
+ const handleGetBaseThac0 = (...a) => libRPGMaster.handleGetBaseThac0(...a);
+ const creatureWeapDefs = (...a) => libRPGMaster.creatureWeapDefs(...a);
+ const sendToWho = (...m) => libRPGMaster.sendToWho(...m);
+ const sendPublic = (...m) => libRPGMaster.sendPublic(...m);
+ const sendAPI = (...m) => libRPGMaster.sendAPI(...m);
+ const sendFeedback = (...m) => libRPGMaster.sendFeedback(...m);
+ const sendResponse = (...m) => libRPGMaster.sendResponse(...m);
+ const sendResponsePlayer = (...p) => libRPGMaster.sendResponsePlayer(...p);
+ const sendResponseError = (...e) => libRPGMaster.sendResponseError(...e);
+ const sendError = (...e) => libRPGMaster.sendError(...e);
+ const sendCatchError = (...e) => libRPGMaster.sendCatchError(...e);
+ const sendParsedMsg = (...m) => libRPGMaster.sendParsedMsg(...m);
+ const sendGMquery = (...m) => libRPGMaster.sendGMquery(...m);
+ const sendWait = (...m) => libRPGMaster.sendWait(...m);
+
+ /*
+ * Handle for reference to character sheet field mapping table.
+ * See RPG library for your RPG/character sheet combination for
+ * full details of this mapping. See also the help handout on
+ * RPGMaster character sheet setup.
+ */
+
+ var fields = {
+ defaultTemplate: 'RPGMdefault',
+ warningTemplate: 'RPGMwarning',
+ menuTemplate: 'RPGMmenu',
+ };
+
+ /*
+ * List of the "standard" RPGMaster databases to support identification of
+ * custom user databases and db entries to give priority to.
+ */
+
+// const stdDB = ['MU_Spells_DB','PR_Spells_DB','Powers_DB','MI_DB','MI_DB_Ammo','MI_DB_Armour','MI_DB_Equipment','MI_DB_Potions','MI_DB_Rings','MI_DB_Scrolls_Books','MI_DB_Wands_Staves_Rods','MI_DB_Weapons','Attacks_DB','Class_DB','Race-DB','Race-DB-Creatures'];
+
+ /*
+ * Handle for the Database Index, used for rapid access to the character
+ * sheet ability fields used to hold database items.
+ */
+
+ var DBindex = {};
+
+ /*
+ * Handle for the API Databases in the RPGM Game-specific Library
+ */
+
+ var dbNames = {};
+
+ /*
+ * Handle for the library object used to pass back RPG & character sheet
+ * specific data tables.
+ */
+
+ var RPGMap = {};
+
+ /*
+ * CommandMaster related help handout information.
+ */
+
+ const handouts = Object.freeze({
+ CommandMaster_Help: {name:'CommandMaster Help',
+ version:3.01,
+ avatar:'https://s3.amazonaws.com/files.d20.io/images/257656656/ckSHhNht7v3u60CRKonRTg/thumb.png?1638050703',
+ bio:'
'
+ +'
Command Master API
'
+ +'
The CommandMaster API is part of the RPGMaster suite of APIs for Roll20, and manages the initialisation of a Campaign to use the RPGMaster APIs, communication and command syntax updates between the APIs and, most importantly for the DM, easy menu-driven setup of Tokens and Character Sheets to work with the APIs.
'
+ +'
Syntax of CommandMaster calls
'
+ +'
The CommandMaster API is called using !cmd.
'
+ +'
!cmd --initialise
'
+ +'
Commands to be sent to the CommandMaster API must be preceded by two hyphens \'--\' as above for the --initialise command. Parameters to these commands are separated by vertical bars \'|\', for example:
'
+ +'
!cmd --register action|description|api-call|api-command|parameters
'
+ +'
Commands can be stacked in the call, for example:
'
+ +'
!cmd --initialise --abilities
'
+ +'
When specifying the commands in this document, parameters enclosed in square brackets [like this] are optional: the square brackets are not included when calling the command with an optional parameter, they are just for description purposes in this document. Parameters that can be one of a small number of options have those options listed, separated by forward slash \'/\', meaning at least one of those listed must be provided (unless the parameter is also specified in [...] as optional): again, the slash \'/\' is not part of the command. Parameters in UPPERCASE are literal, and must be spelt as shown (though their case is actually irrelevant).
'
+ +'
Overriding the Controlling Player
'
+ +'
When a command is sent to Roll20 APIs / Mods, Roll20 tries to work out which player or character sent the command and tells the API its findings. The API then uses this information to direct any output appropriately. However, when it is the API itself that is sending commands, such as from a {{successcmd=...}} or {{failcmd=...}} sequence in a RPGMdefault Roll Template, Roll20 sees the API as the originator of the command and sends output to the GM by default. This is not always the desired result.
'
+ +'
To overcome this, or when output is being misdirected for any other reason, a Controlling Player Override Syntax (otherwise known as a SenderId Override) has been introduced (for RPGMaster Suite APIs only, I\'m afraid), with the following command format:
'
+ +'
!cmd [sender_override_id] --cmd1 args1... --cmd2 args2...
'
+ +'
The optional sender_override_id (don\'t include the [...], that\'s just the syntax for "optional") can be a Roll20 player_id, character_id or token_id. The API will work out which it is. If a player_id, the commands output will be sent to that player when player output is appropriate, even if that player is not on-line (i.e. no-one will get it if they are not on-line). If a character_id or token_id, the API will look for a controlling player who is on-line and send appropriate output to them - if no controlling players are on-line, or the token/character is controlled by the GM, the GM will receive all output. If the ID passed does not represent a player, character or token, or if no ID is provided, the API will send appropriate output to whichever player Roll20 tells the API to send it to.
'
+ +'
'
+ +'
How CommandMaster Works
'
+ +'
The CommandMaster API coordinates other APIs in the RPGMaster API series and provides the DM with facilities to set the Campaign up to use them. It will initialise a Campaign in Roll20 to use the RPGMaster series APIs. APIs can register their commands with CommandMaster and, should they change in the future, CommandMaster will search all Character Sheets and databases for that command and offer the DM the option to automatically update any or all of those found to the new command structure of that API. Selected Tokens and their associated Character Sheets can be set up with the correct Token Action Buttons, with spell-users given spells in their spell book, fighters given weapon proficiencies, setting saving throws correctly, and linking token circles to standard Character Sheet fields.
'
+ +'
Initialising a Campaign
'
+ +'
Using the --initialise command will add a number of Player Macros for the DM that will run the most-used RPGMater DM commands, which can be flagged to appear in the Macro Bar at the bottom of the DM\'s screen for ease of access.
'
+ +'
Setting up tokens & character sheets
'
+ +'
Selecting one or multiple tokens and running the --abilities command will allow token action buttons and RPGMaster API capabilities to be set up for all the represented Character Sheets at the same time, though all Character Sheets will be set up the same way.
'
+ +'
Registering API commands
'
+ +'
Any API command can be registered with CommandMaster using the --register command. This will allow the command registered to be added as a Token Action Button to Character Sheets by the abilities command, and to be optionally updated in all Character Sheets wherever used should the details of the registration change.
'
+ +'
Editing Character Sheet abilities
'
+ +'
Danger: this command is very powerful, and can ruin your campaign if mis-used! The --edit command can be used to change any string in Character Sheet ability macros to any other string, using \'escaped\' characters to replace even the most complex strings. However, use with care!
'
+ +'
'
+ +'
Command Index
'
+ +'
1. Campaign setup
'
+ +'
--initialise
'
+ +'--abilities
'
+ +'
2. Character Sheet configuration
'
+ +'
--conv-spells
'
+ +'--conv-items
'
+ +'--token-defaults
'
+ +'--check-chars
'
+ +'--class-menu [token_id]
'
+ +'--add-spells [POWERS/MUSPELLS/PRSPELLS] | [level]
'
+ +'--add-profs
'
+ +'--set-prof [NOT-PROF/PROFICIENT/SPECIALIST/MASTERY] | weapon | weapon-type
'
+ +'--set-all-prof
'
+ +'--token-img [token_id]
'
+ +'
3. Command and Ability maintenance
'
+ +'
--register action|description|api-call|api-command|parameters
'
+ +'--edit old-string | new-string
'
+ +'
4. Other commands
'
+ +'
--help
'
+ +'--debug [ON/OFF]
'
+ +'
'
+ +'
1. Campaign setup
'
+ +'
1.1 Initialise for RPGMaster APIs
'
+ +'
--initialise
'
+ +'
This command creates a number of Player Macros which can be found under the Player Macro tab in the Chat window (the tab that looks like three bulleted lines, next to the cog). These macros hold a number of DM commands that are useful in setting up and running a campaign. It is recommended that the "Show in Bar" flags for these macros are set, and the "Show Macro Bar" flag is set (the macro bar is standard Roll20 functionality - see Roll20 Help Centre for more information).
'
+ +'
The buttons added are:
'
+ +'
'
+ +' - Maint-menu: Runs the !init --maint command
'
+ +' - Token-setup: Runs the !cmd --abilities command
'
+ +' - Add-items: Runs the !magic --gm-edit-mi command
'
+ +' - End-of-Day: Runs the !init --end-of-day command
'
+ +' - Initiative-menu: Runs the !init --init command
'
+ +' - Check-tracker: Runs the !init --check-tracker command
'
+ +'
'
+ +'
The DM can drag Macro Bar buttons around on-screen to re-order them, or even right-click them to change their name and colour of the button. Feel free to do this to make the Macro Bar as usable for you as you desire.
'
+ +'
1.2 Setup Tokens & Character Sheets
'
+ +'
--abilities
'
+ +'
Displays a menu with which one or more selected tokens and the Character Sheets they represent can be set up with the correct Token Action Buttons and data specific to the RPGMaster APIs, to work with the APIs in the best way. The menu provides buttons to add any command registered with CommandMaster (see --register command) as a Token Action Button, change control of the sheet and set the visibility of the token name to players (which also affects RoundMaster behaviour), set the Character Class and Level of the Character, add spells to spell books, add granted powers, add or change weapon proficiencies and proficiency levels for each weapon, set the correct saving throws based on race, class & level of character / NPC / creature, and optionally clear or set the Token \'circles\' to represent AC (bar 1), base Thac0 (bar 2) and HP (bar 3). Essentially, using this menu accesses the commands in section 2 without the DM having to run them individually.
'
+ +'
All tokens selected when menu items are used will be set up the same way: exceptions to this are using the Set Saves button (sets saves for each selected token/character sheet correctly for the specifications of that sheet), and the Set All Profs button (sets weapon proficiencies to proficient based on the weapons in each individual token/character sheet\'s item bag). Different tokens can be selected and set up differently without having to refresh the menu.
'
+ +'
2. Character Sheet configuration
'
+ +'
The commands in this section can be accessed using the --abilities command menu. The individual commands below are used less frequently.
'
+ +'
2.1 Convert Character Sheet Spells
'
+ +'
--conv-spells
'
+ +'
Works on multiple selected tokens representing several Character Sheets.
'
+ +'
For Character Sheets that have not been created using the commands provided by the !cmd --abilities menu, pre-existing from previous Roll20 campaigns using the Advanced D&D2e Character Sheet, this command does its best to convert all spells in tables on the Character Sheet to RPGMaster format and replace them with spells that exist in the RPGMaster spell databases. Those that the system can\'t automatically match are subsequently displayed in a menu, with additional buttons that list the spells that do exist in the databases that can be used to replace them by selecting both the spell to be replaced and the replacement spell.
'
+ +'
It is possible that not all spells will be able to be replaced, if the Character Sheet reflects campaign experience where bespoke spells or spells from other handbooks have been available. In this case, the spells can be left unconverted, and the DM might add the spells to their own databases using the information provided in the Magic Database Help handout. Until the spells are added to the databases, they will not work, and cannot be memorised for spell use.
'
+ +'
This command can be used on multiple selected tokens, as stated above. All the Character Sheets represented by the selected tokens will be converted, and the displayed list of spells to manually match represents the unmatched spells from all those Character Sheets. As the spells are manually matched, they will be replaced on all of the selected Character Sheets.
'
+ +'
2.2 Convert Character Sheet Equipment
'
+ +'
--conv-items
'
+ +'
Works on multiple selected tokens representing several Character Sheets.
'
+ +'
As for the --conv-spells command, Character Sheets that have not been created using the commands provided by the !cmd --abilities menu, pre-existing from previous Roll20 campaigns using the Advanced D&D2e Character Sheet, this command does its best to convert all weapons, armour, other items of equipment and magical items such as potions, rings etc, in tables on the Character Sheet to RPGMaster format and replace them with weapons, armour and items that exist in the RPGMaster spell databases. Those that the system can\'t automatically match are subsequently displayed in a menu, with additional buttons that list the items that do exist in the databases that can be used to replace the unknown ones by selecting both the item to be replaced and the replacement item.
'
+ +'
It is possible that not all weapons, armour, equipment and especially magic items will be able to be matched if the Character Sheet reflects campaign experience where bespoke magic items and equipment or equipment from other handbooks have been available. In this case, the items can be left unconverted, and the DM might add the items to their own databases using the information provided in the Weapon & Armour Database Help or Magic Database Help handouts. Until the items of equipment are added to the databases, if they are weapons they cannot be taken in-hand to fight with, armour will not be counted towards armour class calculations, and items that contribute to saving throws will not do so.
'
+ +'
As with the --conv-spells command, this command can be used on multiple selected tokens. All the Character Sheets represented by the selected tokens will be converted, and the displayed list of items to manually match represents the unmatched items from all those Character Sheets. As the items are manually matched, they will be replaced on all of the selected Character Sheets.
'
+ +'
2.3 Set Default Token Bar mappings
'
+ +'
--token-defaults
'
+ +'
This command uses the selected token as a model to set the default token bar mappings that will be used in future by the RPGMaster APIs.
'
+ +'
The standard defaults distributed with the APIs are for token bar1 to represent AC, bar2 to represent Thac0-base, and bar3 to represent HP. However, alternative mappings can be made. It is highly recommended that HP, AC and Thac0-base are represented in some order because these are the most common values to be affected by spells and circumstances, both in and out of combat situations.
'
+ +'
If no token is selected, or the token selected to be the model does not have any bars linked to a character sheet, an error message will be displayed. If some but not all the bars are linked, then any bars not linked will be automatically matched to some of the recommended Character Sheet fields of AC, Thac0-base, and HP (in that order of priority).
'
+ +'
Once this mapping is done, a menu will be displayed that can be used to map other tokens to the new defaults: either just the selected tokens, or all tokens in the campaign, or just those tokens that have bars currently linked to Character Sheets (i.e. excluding creature mobs with multiple tokens with unlinked bars representing a single character sheet). A button also exists to clear the bar links for all selected tokens to create creature mobs.
'
+ +'
2.4 Check control of Character Sheets
'
+ +'
--check-chars
'
+ +'
Displays a list of every Character Sheet with a defined Class, Level, or Monster Hit Dice categorised by DM Controlled, Player Controlled PCs & NPCs, Player Controlled Creatures, and Controlled by Everyone. Each name is shown as a button which, if selected, swaps control of that Character Sheet between DM control and the control of a selected Player (the Player, of course, must be one that has already accepted an invite to join the campaign). A button is also provided at the bottom of this menu to toggle the running of this check whenever the Campaign is loaded.
'
+ +'
2.5 Set Character Class, Race & Species
'
+ +'
--class-menu [token_id]
'
+ +'
Takes an optional ID for a token representing a character. If not specified, takes the currently selected token
'
+ +'
Displays a menu from which the Race, Class and Level of a Character can be set, or a Creature species can be selected. Setting the Race, Class and Level of a Character (PC or NPC) enables all other capabilities to be used as appropriate for that character sheet in this and other APIs in the RPGMaster API suite, such as spell use, appropriate race & class powers, selection of allowed weapons, and the like. Selecting a Creature species automatically sets up the Character Sheet in an optimal way for the APIs to use it to represent the chosen creature, including saves, armour class, hit dice and rolling of hit points, as well as special attacks such as paralysation & level drain of high level undead, spell use by the likes of Orc Shamen, regeneration powers, and so on. However, it does not automatically give weapons, armour equipment, or magic items to Creatures - if appropriate this still needs to be done by the DM/Game Creator.
'
+ +'
DMs/Game Creatores can add to or amend the Class, Race and Creature definitions. Refer to the appropriate database help handout distributed with the APIs and created as handouts in your campaign for more information.
'
+ +'
2.6 Add spells to spell book
'
+ +'
--add-spells [POWERS/MUSPELLS/PRSPELLS] | [level]
'
+ +'
Displays a menu allowing spells in the Spells Databases to be added to the Character Sheet(s) represented by the selected Token(s). If no spell type and/or spell level is specified, the initial menu shown is for Level 1 Wizard spells (MUSPELLS). Buttons are shown on the menu that allow navigation to other levels, spell types and powers. For Priests, a button is also provided to add every spell allowed for the Priest\'s Class to their spellbooks at all levels (of course, they will only be able to memorise those that their experience level allows them to). For all Character Classes that have Powers (or Power-like capabilities, such as Priestly Turn Undead or Paladin Lay on Hands), there is a button on the Powers menu to add Powers that the character\'s Class can have.
'
+ +'
Note: adding spells / powers to a sheet does not mean the Character can immediately use them. They must be memorised first. Use the commands in the MagicMaster API to memorise spells and powers.
'
+ +'
2.7 Choose weapon proficiencies
'
+ +'
--add-profs
'
+ +'
Displays a menu from which to select proficiencies and level of proficiency for any weapons in the Weapon Databases for the Character Sheet(s) represented by the selected tokens. Also provides a button for making the Character proficient in all weapons carried (i.e. those currently in their Item table).
'
+ +'
All current proficiencies are displayed, with the proficiency level of each, which can be changed or removed. It is also now possible to select proficiencies in Fighting Styles as introduced by The Complete Fighter\'s Handbook: these can be found under the Choose Style button, and can also be set as Proficient or Specialised. Selecting a Fighting Style proficiency grants benefits as defined in the Handbook, or as modified by the DM - see the Styles Database Help handout for more information.
'
+ +'
Note: this does more than just entering the weapon in the proficiency table. It adds the weapon group that the weapon belongs to as a field to the table (see weapon database help handouts for details), which is then used by the AttackMaster API to manage related weapon attacks and give the correct proficiency bonuses or penalties for the class and weapon used.
'
+ +'
2.8 Set weapon proficiencies
'
+ +'
--set-prof [NOT-PROF/PROFICIENT/SPECIALIST/MASTERY] | weapon | weapon-type
'
+ +'
Sets a specific weapon proficiency to a named level. If the proficiency level is omitted, PROFICIENT is assumed. If the weapon already exists in the proficiencies table, the existing proficiency level is updated to that specified. Otherwise, the weapon (and its weapon group) are added to the table at the specified level.
'
+ +'
Note: this does more than just entering the weapon in the proficiency table. It adds the weapon group that the weapon belongs to as a field to the table (see weapon database help handouts for details), which is then used by the AttackMaster API to manage related weapon attacks and give the correct proficiency bonuses or penalties for the class and weapon used.
'
+ +'
2.9 Add proficiencies for all carried weapons
'
+ +'
--set-all-prof
'
+ +'
Adds all currently carried weapons (those in the Items table) to PROFICIENT, saving them and their weapon group to the weapon proficiency table. Those weapons found that are already in the table are reset to PROFICIENT (overwriting any existing different proficiency level). Any other proficiencies already in the table are not altered.
'
+ +'
Note: this command always adds a weapon proficiency called innate. This proficiency is used for attacks with innate weapons, such as claws and bites, but also for spells that require a touch attack. Indeed, to make this even more specific, the weapons database distributed with the AttackMaster and MagicMaster APIs includes a weapon called Touch.
'
+ +'
Tip: if using the MagicMaster API then running the !magic --gm-edit-mi command and adding weapons before running this command can speed up setting up character sheets.
'
+ +'
2.10 Change container images & variables
'
+ +'
--token-img [token_id]
'
+ +'
Displays a menu for changing the images and variables used for containers. The optional token_id (defaults to the selected token) must represent a character sheet, and the dialog expects it to be a character sheet of a container, potentially one set up using the Drag & Drop container functionality. Containers set up using Drag & Drop will have information about the use of images and variables in the "Bio" tab of the Character Sheet.
'
+ +'
3. Command and Ability maintenance
'
+ +'
3.1 Register an API command
'
+ +'
--register action|description|api-call|api-command|parameters
'
+ +'
Register an API command with the CommandMaster API to achieve two outcomes: allow the command to be set up as a Token Action Button, and/or automatically maintain & update the syntax of the commands in Character Sheet ability macros and the RPGMaster API databases.
'
+ +'
This is a powerful and potentially hazardous command. Registry of an API command is remembered by the system in the state variable, which is preserved throughout the life of the Campaign in Roll20. If a subsequent registration of the same action has different parameters, the system detects this and searches all Character Sheet ability macros for the old version of the command and replaces all of them with the new command. It also changes the parameters, using a syntax including a range of character \'escapes\' to substitute characters that Roll20 might otherwise interpret as commands itself. In detail, the --register command takes:
'
+ +'
'
+ +' action: | the unique name given to this command in the whole system. This can be any legal text name including A-Z, a-z, 1-9, -, _ only. Must start with an alpha. Case is ignored. |
'
+ +' description: | a short description of the command, which is displayed in the menu that allows the command to be added as a Token Action Button. |
'
+ +' api-call: | the API call without the !, e.g. cmd, or magic, etc |
'
+ +' api-command: | the command to be passed to the specified API, with the hyphens replaced by ~~ or plusses replaced by **, e.g. ~~cast-spell or **menu. |
'
+ +' parameters: | the parameters (or initial parameters) to be passed as part of this command to replace the matching existing command parameters. This string is \'escaped\' using the following character replacements: |
'
+ +'
'
+ +'
'
+ +' Character | Parameter separator | ? | [ | ] | < | > | @ | - | | | : | & | { | } |
'
+ +' Substitute | %% | ^ | << | >> | | | ` | ~ | | | | & | { | } |
'
+ +' Alternative | \\vbar; | \\ques; | \\lbrak; | \\rbrak; | \\lt; | \\gt; | \\at; | \\dash; | \\vbar; | \\clon; | \\amp; | \\lbrc; | \\rbrc; |
'
+ +'
'
+ +'
Commands cannot have a CR (carrage return/new line) in the middle of them, but CR can separate commands in multi-command sequences.
'
+ +'
If the parameter string ends with $$, this will ensure that a complete command up to the next CR is to be replaced (including everything up to the CR even if not part of the command). If there is not a $$ on the end of the parameter string, then only the command and parameters that are matched are replaced (using a parameter count of each old and new parameter separated by \'%%\') - the rest of the line (including any remaining parameters not so matched) will be left in place.
'
+ +'
Here are some examples of registration commands:
'
+ +'
--register Spells_menu|Open a menu with spell management functions|magic|~~spellmenu |\`{selected|token_id}
'
+ +'--register Use_power|Use a Power|magic|~~cast-spell|POWER%%\`{selected|token_id}
'
+ +'--register Attack_hit|Do an attack where Roll20 rolls the dice|attk|~~attk-hit|\`{selected|token_id}
'
+ +'
3.2 Edit ability macros
'
+ +'
--edit existing-string | new-string
'
+ +'
Danger: use this command with extreme care! It can destroy your Campaign! It is recommended that you make a backup copy of your Campaign before using this command. --register is more controlled, as it has been tested with the RPGMaster command strings, and any future releases that change the API commands will be fully tested before release for their effect on Campaigns, with accompanying release notes. Using the --edit function directly can have unintended consequences!
'
+ +'
Replaces an existing \'escaped\' string with a new replacement string in all ability macros on all Character Sheets. These strings both use the same escape sequence replacements as for the --register command (see section 3.1) as in fact --register and --edit use the same functionality.
'
+ +'
Examples of its use are to change API command calls, or Character Sheet field name access in macros should the field names change.
'
+ +'
'
+ +'
4. Other Commands
'
+ +'
4.1 Display help on these commands
'
+ +'
--help
'
+ +'
This command does not take any arguments. It displays a very short version of this document, showing the mandatory and optional arguments, and a brief description of each command.
'
+ +'
4.2 Switch on or off Debug mode
'
+ +'
--debug (ON/OFF)
'
+ +'
Takes one mandatory argument which should be ON or OFF.
'
+ +'
The command turns on a verbose diagnostic mode for the API which will trace what commands are being processed, including internal commands, what attributes are being set and changed, and more detail about any errors that are occurring. The command can be used by the DM or any Player - so the DM or a technical advisor can play as a Player and see the debugging messages.
'
+ +'
'
+ +'
',
+ },
+ LocksTraps_Help: {name:'Locks and Traps Help',
+ version:1.03,
+ avatar:'https://s3.amazonaws.com/files.d20.io/images/257656656/ckSHhNht7v3u60CRKonRTg/thumb.png?1638050703',
+ bio:''
+ +'
Containers, Locks & Traps Databases
'
+ +'
for RPGMaster APIs
'
+ +'
1. General Database information
'
+ +'
The RPGMaster APIs use a number of databases to hold Macros defining races, creatures, character classes, spells, powers, magic items and their effects, and now containers, locks & traps. The version of these databases distributed with the APIs are held internally to the APIs. However, the AttackMaster or MagicMaster API command --extract-db can be used to extract any or all standard databases to Character Sheets for examination and update. The APIs are distributed with many class, spell, power, magic item and container definitions, and DMs can add their own containers, locks, traps, character classes, spells, items, weapons, ammo and armour to additional databases in their own database character sheets, with new definitions for database items held in Ability Macros. Additional database character sheets should be named as follows:
'
+ +'
'
+ +' Wizard Spells: | additional databases: MU-Spells-DB-[added name] where [added name] can be replaced with anything you want. |
'
+ +' Priest Spells: | additional databases: PR-Spells-DB-[added name] where [added name] can be replaced with anything you want. |
'
+ +' Powers: | additional databases: Powers-DB-[added name] where [added name] can be replaced with anything you want. |
'
+ +' Magic Items: | additional databases: MI-DB-[added name] where [added name] can be replaced with anything you want. |
'
+ +' Character Classes: | additional databases: Class-DB-[added name] where [added name] can be replaced with anything you want. |
'
+ +' Races, Creatures & Containers: | additional databases: Race-DB-[added name] where [added name] can be replaced with anything you want. |
'
+ +' Locks & Traps: | additional databases: Locks-Traps-DB-[added name] where [added name] can be replaced with anything you want. |
'
+ +' Attack Calculations: | additional databases: Attacks-DB-[added name] where [added name] can be replaced with anything you want. |
'
+ +'
'
+ +'
However: the system will ignore any database with a name that includes a version number of the form "v#.#" where # can be any number or group of numbers e.g. "MI-DB v2.13" will be ignored. This is so that the DM can version control their databases, with only the current one (without a version number) being live.
'
+ +'
There can be as many additional databases as you want. Other Master series APIs come with additional databases, some of which overlap - this does not cause a problem as version control and merging unique macros is managed by the APIs.
'
+ +'
Important Note: all Character Sheet databases must have their \'ControlledBy\' value (found under the [Edit] button at the top right of each sheet) set to \'All Players\'. This must be for all databases, both those provided (set by the API) and any user-defined ones. Otherwise, Players will not be able to run the macros contained in them.
'
+ +'
Each added database has a similar structure, with:
'
+ +'
'
+ +' - Ability Macros named as the class, spell, power, magic item, locks or traps specified, and used to describe and provide effects for classes, containers, spells, powers and magic items using the commands in the RPGMaster APIs;
'
+ +' - Custom Attributes with the attribute name "ct-ability-macro-name", one per Ability Macro, which defines the casting time and casting cost for spells & powers, and speed and MI type for magic items (not currently used for Class, Race, Container, Lock, Trap or Attack definitions);
'
+ +' - An entry in a list on the character sheet in the spell book of the relevant Character Sheet tab (Spell Level of the spell defined, Powers tab, or various spell books for different Classes & Magic Items - see Lock and Trap entries below).
'
+ +'
'
+ +'
As with other RPGMaster suite databases, the GM need not worry about creating anything other than a correctly formatted macro entry, and then can run the !magic --check-db Database-Name command to check the database formatting, create the custom attributes and list entries, and re-index all database entries so that the new entries can be immediately used in live play.
'
+ +'
Ability Macros can be whatever the DM wants and can be as simple or as complex as desired. Roll Templates are very useful when defining class, spell, power, magic item, trap and lock ability macros. When a Player or an NPC or Monster views or casts a spell, power or uses a container or magic item the APIs run the relevant Ability Macro from the databases as if it had been run by the Player from the chat window. All Roll20 functions for macros are available.
'
+ +'
1.1 Replacing Locks, Traps, Containers, Races, Classes, Spells & Items
'
+ +'
If you want to replace any Ability Macro provided in any of the databases, you can do so simply by creating an Ability Macro in one of your own databases with exactly the same name as the provided item to be replaced. The API gives preference to Ability Macros in user-defined databases, so yours will be selected in preference to the one provided with the APIs.
'
+ +'
'
+ +'
2. How Container Locks & Traps Work
'
+ +'
Important Note: In order for Drag & Drop containers to work, you must have the ChatSetAttr and TokenMod Mods loaded as well as RPGMaster suite APIs and ChatSetAttr must have "Players can modify all characters" option ticked, and TokenMod must have "Players can use --ids" option ticked.
'
+ +'
Any token representing a character sheet can be a container. This includes characters, NPCs, and creatures as well as token/character sheet pairs specifically intended to be containers such as chests, barrels, desks, bags and the like. Characters can have equipment such as weapons and armour added to their sheets, and obtain magic items on their quest - this is the character acting as a "container" for these items and equipment. Characters (and NPCs and some creatures) can search containers to find and loot items from them using the !magic --search command (see MagicMaster Help handout) or the MI menu / Search for MIs & Treasure action selection. They can also store items in a container using !magic --pickorput or MI menu / Store MIs. The GM can also store and edit items in any container by using the GM\'s Add Items dialog, which also can configure the number of slots for items in a container, and the type of a container, as well as many other container and item management functions - see the MagicMaster Help handout for more information on the !magic --gm-edit-mi command (which is what the Add Items button calls).
'
+ +'
2.1 Container Management
'
+ +'
When any container is searched by a character (or NPC or creature), depending on the type of container (see below) it will eventually show its contents (if any). The contents can be added by the GM using the GM\'s Add Items dialog, or by characters, NPCs or creatures storing items in the container. The contents of the container are shown to those searching in one of two possible dialogs - one which shows a button for each item or stack of items (long menu), and another which provides a drop-down list of the items (short menu). Either dialog allows the searcher to select items to take from the container and add to their own equipment.
'
+ +'
The GM can use the controls on the Add Items menu to mark any container to either show the exact names of the contents in these dialogs, or only show the type of each item: e.g. Potion of Healing might be shown simply as a Potion, or a Broadsword +2 be displayed as a Long Blade i.e. only describing what the character sees. When the searcher takes the item into their own equipment it might then be listed in that searcher\'s equipment by its true name (unless the GM has also hidden the item as another item or hidden it automatically with the Looks-Like function: see MagicMaster Help and Magic Database Help handouts).
'
+ +'
The GM can also set the maximum number of "slots" that a container has: each unique item or type of item requires a slot to store it in. Once all slots are full, no more items can be stored in the container. Certain types of item can be "stacked": e.g. Flight Arrows can be stacked, with any number of Flight Arrows occupying one slot. However, Flight Arrows and Sheaf Arrows cannot be stacked together, and nor can Flight Arrows and Flight Arrows +1. A wand with multiple charges will perhaps look like a stacked item (as the quantity reflects the number of charges), but another wand of the same type cannot be stacked with it, as each is a unique item. When stacks are looted, a dialog will appear asking how many of the items in the stack want to be taken: alternatively, when a unique item with multiple charges is looted, the whole item will automatically be taken (i.e. a Wand of Missiles with 20 charges cannot be split into two or more with fewer charges).
'
+ +'
2.2 Types of Container
'
+ +'
Not all containers will react the same way when searched. How the container reacts is determined by the type of container set on the character sheet by the GM using the Add Items dialog, or automatically when creatures or containers are Dragged & Dropped. The current types are:
'
+ +'
'
+ +'Type | # | Description |
'
+ +'Empty Inanimate Object | 0 | A simple container that is not a character, NPC or creature, such as a simple chest or a dead body, does not have a lock or trap, but is empty apart (perhaps) for some text-only treasure descriptions. |
'
+ +'Inanimate Container with stuff | 1 | A simple container that is not a character, NPC or creature, does not have a lock or trap, and may contain items and equipment and possibly some text-only treasure descriptions. |
'
+ +'Empty Sentient Creature | 2 | A character, NPC or creature that requires its "pocket to be picked" in order to loot stuff, but is empty (or their items are not pick-able) apart (perhaps) for some text-only treasure descriptions. |
'
+ +'Sentient Creature with Stuff | 3 | A character, NPC or creature that requires its "pocket to be picked" in order to loot stuff, and may possess items and equipment and possibly some text-only treasure descriptions. |
'
+ +'Trapped Container | 4 | A container of any type that may have a lock or trap that must be overcome before items it contains can be looted, and may or may not possess items and equipment and possibly some text-only treasure descriptions. |
'
+ +'
'
+ +'
The default type for a new character sheet just created is 0, an Empty Inanimate Container. However, if a Drag & Drop creature is created, the type is set to 2 (Empty Sentient Creature), or if a trapped or locked Drag & Drop container is created, the type is set to 4 (Trapped Container). If the Add Items dialog or any character action adds items to an empty container or empty sentient creature, the type is changed to 1 or 3 respectively. As with everything to do with containers, the container type can be changed in the GM\'s Add Items dialog.
'
+ +'
2.3 Picking Pockets of Sentient Creatures
'
+ +'
When an attempt is made to search a container with type 2 or 3 (a sentient creature), the API will ask the searcher to make a "Pick Pockets" roll (whether the searcher is a Rogue or otherwise). The Pick Pockets percentage displayed is that shown on the Rogue tab of the character sheet (minimum 5%). If successful, the looting process is the same as any other container. If failed, the contents are not displayed and, as per the Dungeon Master\'s Guide, the chance of the victim noticing is a percentage equal to 3 x victim\'s experience level. The API notifies the GM with the result of this roll, i.e. whether the victim notices the Pick Pockets attempt or not. The GM can then decide what happens next.
'
+ +'
2.4 Trapped and Locked Containers
'
+ +'
Containers of type 4 are seen by the APIs as perhaps being trapped or locked, and instead of displaying their contents the API runs the Ability Macro on the container\'s character sheet with the name "Trap-@{container-name|trap-version}". Generally, when first called, the attribute "trap-version" on the container character sheet will either not exist (the API will default it to a value of 0) or be 0, so the Ability Macro "Trap-0" will be run. If no Ability Macro with the name "Trap-0" exists on the container\'s sheet, the API tries to run one called just "Trap". If neither of these exist, the API just displays the contents of the container as if no trap or lock existed. The value of the "trap-version" attribute can be used to change the behavior of the container as actions occur, with Ability Macros "Trap-1", "Trap-2", etc having different outcomes on future searches of the same container - e.g. a successful removal of a trap may change the trap-version to 1 and the "Trap-1" macro just display the contents without having to overcome the trap again.
'
+ +'
The trap / lock Ability Macros are standard Roll20 macros and can do anything that a standard Roll20 macro can do. See the Roll20 Help Center for more information on macros. Typically, the "Trap-0" macro will ask the searcher to provide some key, password, combination number or perform some other activity in order to unlock its contents without negative consequences. The macro can call other macros, perhaps via API buttons or Roll Queries (see Roll20 help) which offer choices. For those Game Authors and GMs who are less comfortable coding Ability Macros, the RPGMaster suite offers configurable Drag & Drop containers which do all the hard work for you!
'
+ +'
2.5 Drag & Drop Containers
'
+ +'
From v2.2 of RPGMaster suite, Drag & Drop containers are provided with the APIs, alongside a database of Lock & Trap Macros they use to provide their locks and traps. When Dragged & Dropped (in the same way as a Drag & Drop creature: create a new blank character sheet, give it a sensible name, and then just drag it onto the playing surface to drop a token) the Race, Class & Creature dialog pops up, but now also with a new button called [Containers]. Remember to ensure the newly dropped token is selected, then selecting the [Containers] button opens a drop-down list in the centre of the screen allowing you to select a basic container type. Each of these have default images associated with them that will display a token appropriate to the container selected. Select the one you want and a dialog appears supporting the selection of various pre-programmed locks & traps, the ability to change the images used for the container, and to change the effects of some locks and traps by setting different values. Once selected, the token is automatically given a representative icon and all necessary aspects of the character sheet are configured for the trapped / locked container. The GM just needs to (optionally) add items to it using their Add Items dialog.
'
+ +'
The description of the container can be looked at (including instructions on configuring it) by opening the "Bio" tab of the container\'s character sheet. Typically, the Drag & Drop container will come with an action button displayed when the container\'s token is selected to close any lock and/or trap without changing its status, so once opened the player characters can close the container and searching it will open it again (often without setting off the trap again!). There is also a new GM Macro Bar macro button added which allows the GM to reset the locks and traps on the container (so you can test the trap/lock and then reset it for others to find) - go to the Collection tab of the Chat Window and enable Reset Container to be in your Macro Bar. The GM\'s [Token Setup] button (or the command !cmd --token-img) can be used to configure the container (give the token new images, choose new locks & traps, and set variables the macros can use to new values). Review the container\'s "Bio" to check what the configuration options are - e.g. how to set a new list of password choices, set a new combination, set the key number that must be possessed, etc.
'
+ +'
2.6 Images and Image URLs
'
+ +'
The Drag & Drop Container system supports images to make tokens dynamic, appearing to change state such as opening, being destroyed and becoming a pile of ash, turning into a summoned creature, etc. To do this it stores image URLs, and the GM can change these images to apear as they desire.
'
+ +'
Image URLs must comply with the Roll20 rules for any token image set by Roll20 Mods and APIs. That includes that they can\'t be Premium Asset images, such as those from the Market Place: they must be from your own image library. The images provided in the databases are from "Creative Commons" licenced sources. If you wish to replace the images provided, the best way to do so is to select the Container token, use the GM\'s [Token Setup] button to open the Container Configuration dialogue, then drag an image to the playing surface from your "My Library" image library, ensure that newly dropped image is selected and press the appropriate image button on the configuration dialogue. That will save the correctly formatted URL to the container.
'
+ +'
You can add your own images to your "My Library" images using the [Upload] button on the "My Library" tab of the chat. Please source images responsibly.
'
+ +'
2.7 Who Rolls for Finding Traps?
'
+ +'
If you read the Player\'s Handbook when it describes Thieving skills, the roll for Find Traps is normally made by the GM. Drag & Drop containers can work in two ways, depending on the configuration settings: the GM can be prompted to make the roll for the Player (the default setting); or the Player can make the roll. In either case, the result of the roll will be handled by the coding of the Drag & Drop container.
'
+ +'
In order to change which of the two options is in operation, use the GM\'s [Config-RPGM] button or the !magic --config command and set the "Thievish Chance" configuration as desired.
'
+ +'
There are other rolls that can be made by Players when encountering locked and/or trapped containers: only the Find Traps roll is set by default to be able to be rolled by either the player or the GM, based on the configuration. However, the Locks-Traps-DB includes example "GM-Roll-" versions of the macros involved in making Remove Traps, Pick Locks, and Pick Pockets rolls. The GM or game creator can use these in programming their own containers in their own extensions to the Locks-Traps-DB.
'
+ +'
2.8 Data Inheritance
'
+ +'
In order to save time, effort and data space, any Race definition can "inherrit" data values from a "parent" definition, or even a "parent tree". As containers are considered to be a form of "Race" by the APIs, they too can inherrit data values, meaning that "families" of containers can be created where common data settings can be set once in the root definition. Any inherrited data tags can be overwritten with different values, and additional ones specified just by adding them to a data specification of the same name in the inherriting (child) definition. In the case of container definitions, the data is held as RaceData specifications.
'
+ +'
In order to inherrit data, the Specs specification field four (the Supertype) for the inherriting "child" container must name the "parent" to be inherrited from. If the "parent" also has a Specs Supertype field that refers to a "grand-parent" the tree will be followed on upward until a Supertype that does not specify a valid definition of the same database item Class (Specs field two) is encountered: typically in the case of containers the tree would terminate with a database item of Supertype "Container".
'
+ +'
Note: this inheritance does not work for Lock and Trap definitions in the Locks-Traps-DB as in those definitions the Supertype specifically refers to the stored ability macro, and cannot refer to a parent database item.
'
+ +'
2.9 Roll Template Merging
'
+ +'
Another way of reusing common aspects of database definitions is to use the standard Roll20 macro technique of merging one ability macro specification into another, using the syntax "%{character_name|ability_macro}". However, in the case of use with RPGMaster database entries, the "character_name" can be the name of any internal or external database, or even just a database root name ending in "-DB" (e.g. the root name of the Race-DB-Containers database is Race-DB). This is the case even if the referred to ability is in a database held in code: the merge will occur as if between externally held database macros. As with inheritance, chaining of specifications can occur, and "%{...|...}" entries will be resolved until the point that no unresolved entries remain.
'
+ +'
The way the merge progresses means that uniquely named Roll Template fields will all appear in the final display, but those with the same names will only display the data in the last specified field of that name in the merged templates, but in the position in sequence of the first encountered field of that name. Also, Roll Template fields with no data after the "=" will not be included in the display: this is also the case for fields defined as "{{}}" (allowing for bracketing of Specs & Data fields that must be defined between template fields in very short templates).
'
+ +'
Important Note: The APIs always find the first Specs= and ....Data= specifications in any merged database entries. It is best to ensure that the Specs and Data specifications are as early as possible in the specification, ahead of any "%{...|...}, so that it is those from the called database entry are used.
'
+ +'
2.10 No Whispering
'
+ +'
As with other RPGMaster database items, when updating the existing Lock & Trap items or creating new ones you should not add Roll20 "whispers", "emotes" etc. The APIs do some fairly special stuff with working out where posts should go, in terms of which players, characters, the GM, and also redirecting output when players are not logged on, and the APIs add their own Roll20 posting commands to ensure the right players see the right information at the right time, and don\'t see what they shouldn\'t.
'
+ +'
That does not stop players from whispering, using emotes and other commands in chat to each other and the GM, or the GM in using "/desc" and other commands as normal.
'
+ +'
3. Drag & Drop Containers Database
'
+ +'
The Drag & Drop container system draws on definitions for different types of basic containers that are contained in the Containers Database. As with all other RPGMaster suite databases, this Database is distributed with the APIs in code, but can be extracted to review and copy elements by using the !magic --extract-db Race-DB-Containers command, which will extract the database to a character sheet, where the entries can be seen as ability macros. (It is recommended that you do not keep complete extracted databases, but instead copy those elements you want to use to your own database and then delete the extracted database - this will optimise system performance).
'
+ +'
The Containers databases have names that start with Race-DB-Containers (or, in fact, can just start with Race-DB) and can have anything put at the end, though those with version numbers of the form v#.# as part of the name will be ignored.
'
+ +'
As previously stated, each database definition has 3 parts in the database (see Section 1): an Ability Macro with a name that is unique and describes the type of container, a custom Attribute with the name of the Ability Macro preceded by "ct-", and a listing in the database character sheet of the ability macro name separated by \'|\' along with other container macros. The quickest way to understand these entries is to examine existing entries. Do extract the root databases and take a look (but remember to delete them after exploring the items in them, so as not to slow the system down unnecessarily).
'
+ +'
Note: The DM creating new containers does not need to worry about anything other than the Ability Macro in the database, as running the !magic -check-db < Database name > command will update all other aspects of the database appropriately, as long as the Specs fields are correctly defined.
'
+ +'
Ability macros can be added to a database just by using the [+Add] button at the top of the Abilities column in the Attributes and Abilities tab of the Database Character Sheet, and then using the edit "pencil" icon on the new entry to open it for editing. Ability macros are standard Roll20 functionality and not dependent on the API. Refer to the Roll20 Help Center for more information.
'
+ +'
3.1 Example Container Definition
'
+ +'
The Containers database includes a number of example container definitions, but the GM or game creator can add to these with their own definitions by following the information in this handout (and their own imagination!). Here is an example of a container definition:
'
+ +'
Large Chest
'
+ +'
&{template:RPGMdefault}{{title=Large Chest}}{{subtitle=Container}}Specs=[Large Chest,Container,0H,Container]{{Size=3ft x 2ft x 2ft, capacity 100lbs}}{{Slots=This chest has stackable 18 slots}}RaceData=[w:Large Chest, slots:18, lock:No-Lock, trap:No-Trap, attr:ac=4|hp=20, cimg:https://s3.amazonaws.com/files.d20.io/images/163011054/ LD6xZDT2SlYSow0Q5QHb3g/thumb.png?1599509586|105|75, oimg:https://s3.amazonaws.com/files.d20.io/images/352175458/ BYTfuvbA_JvbL0IUjeM0Ug/thumb.png?1690472095|105|105]{{GM Info=Use the GM\'s [Token Setup] button, or the **!cmd --token-img** command to change the token\'s images, locks & traps, and set variables to vary behaviour. Items can be stored in it by using the GM\'s [Add Items] button, or the **!magic --gm-edit-mi** command}}{{desc=This is an ordinary chest, which can be configured to have locks and traps. When searched, after locks and traps have been overcome, it will open and list its contents. Resetting it closes it again and resets the locks and traps.}}
'
+ +'
There are a number of important aspects to this definition:
'
+ +'
Roll Template:The first element of note in this definition is that it is using a Roll Template for formatting the message to the player. Roll Templates are standard Roll20 functionality, generally provided by character sheet authors, but the RPGMaster suite has its own suite of Roll Template definitions, of which RPGMdefault is one. See the RPGMaster Library Help handout for details of RPGMaster Roll Templates
'
+ +'
Specs: The next item to note is the Specs field, with a format that is standard across all RPGMaster database entries.
'
+ +'
Specs=[Large Chest,Container,0H,Container]
'
+ +'
Slotted between Roll Template fields, the Specs field will not appear to the players, but is only available to the APIs. The first field is always the database item type (or name), the second is the class of database item (in this case a "Container" database item), the third is the handedness of the item (not yet relevant to Container items), and the fourth the Super-type which in the case of Container items is usually "Container": however, if using "Race Definition Inheritance", the fourth element will be the name of the Container definition that this container inherits its RaceData from (see information on inheritance above).
'
+ +'
RaceData: As any character or creature can be a container, chests are part of the Race family that use RaceData specifications. Indeed, the preloaded examples include a sleeping character (who will wake if they detect you picking their pockets...) and a "dead(?)" body that transforms into a Zombie (or any other undead you want). RaceData can be "inherited" from another container definition - set the fourth Specs field to be the name of the Container database entry to inherrit from. See information on "Inheritance" above.
'
+ +'
The elements in the RaceData specification define data that the locks & traps use during game play, that may affect their behaviour. Some of the relevant data tags are:
'
+ +'
'
+ +'Tag | Format | Default | Description |
'
+ +'w: | Text | \' \' | The name of the container |
'
+ +'slots: | # | 18 | The initial maximum number of container slots |
'
+ +'lock: | Text | \' \' | The default Lock for this type of container |
'
+ +'trap: | Text | \' \' | The default Trap for this type of container |
'
+ +'attr: | Data Tags | \' \' | Attribute specifications for the container, typically AC & HP |
'
+ +'cimg: | < url > | undefined | The URL of the image to use for a closed container |
'
+ +'oimg: | < url > | undefined | The URL of the image to use for an open container |
'
+ +'limg#: | < url >[%%label] | undefined | The optional URL of a user-definable image related to locks stored as lock-img# with an optional variable label |
'
+ +'timg#: | < url >[%%label] | undefined | The optional URL of a user-definable image related to traps stored as trap-img# with an optional variable label |
'
+ +'lvar#: | < text or # >[%%label] | \' \' | An initial setting for lock-var# with an optional variable label |
'
+ +'tvar#: | < text or # >[%%label]> | \' \' | An initial setting for trap-var# with an optional variable label |
'
+ +'
'
+ +'
The Large Chest container is specified as having 18 slots, no lock (represented by the "No-Lock" lock type), no trap (represented by the "No-Trap" trap type), an Armour Class of 4, 20 hit points, an image URL for a closed container and an image URL for an open container. No lock or trap variables are preset by this container definition.
'
+ +'
Any of the RaceData tags can be inherrited from another container definition as described above, under the description for the Specs. Also, any of these tags can be overwritten by the Locks and/or Traps set for the container (not just the default ones specified in the container definition, but any lock or trap subsequently set).
'
+ +'
The "attr" tag allows certain attributes on the character sheet of the container to be set, in the case of the Large Chest setting an Armour Class (AC) of 4 and 20 Hit Points(HP). The data format is for a pipe-delimited string of "< tag >=< value >|< tag >=< value >| ... ". The full list that can be used can be found at the end of this document, and also in more detail in the Class & Race Database Help handout.
'
+ +'
The Lock and Trap variables (lvar# and tvar#) can be preset with values and variable names. The names for the variables appear on the Container Configuration dialogue to prompt the user to enter appropriate data. Generally, lock and trap variables are set by the lock & trap definitions.
'
+ +'
The Open & Closed Container image URLs must be of the correct format (see above), and are generally set by the container definition (though they can be overwritten by the Lock and Trap definitions if needed). The Open & Closed Container image tags do not accept a name specification, as they are always just those images. Alternate images can be specified for the container, for use by Lock and Trap macros to display when the container enters other states: however, generally speaking, these Lock & Trap images are set by the Lock & Trap definitions.
'
+ +'
3.5 Lock & Trap Status Attributes
'
+ +'
There are a number of character sheet attributes that are set by various conditions and by some macros in the Locks-Traps-DB that can be useful to GMs and game creators that are programming their own locks & traps. The table below gives you an idea of what they are and how they are used, but the best way to learn is to extract the database and view some examples. Note: many of these attributes are set by each Trap-# macro when it is run by using the ChatSetAttr !setAttr command (see database for example Trap-# macros). You can add and set others to your own Trap-# macros as you require. Remember, these attributes can be accessed in the lock & trap macros by using the form @{^^chest^^|attribute-name}.
'
+ +'
'
+ +'Attribute | Values | Description |
'
+ +'trap-version | # | The version of the "trap-" macros that will be called if a --search is conducted: initially 0 |
'
+ +'trap-status | Armed or Disarmed | Flag stating if the trap has already been disarmed |
'
+ +'trap-status|max | Locked or Unlocked | Flag stating if the container has already been unlocked |
'
+ +'gm-rolls | \'GM-Roll-\' or \' \' | Set to GM-Roll- if the configuration is for GMs to roll for Find Traps |
'
+ +'trap-name | < text > | The name of the trap on this container |
'
+ +'trap-name|max | < text > | The name of the lock on this container |
'
+ +'chest | token_id | The token ID of the container |
'
+ +'playerid | player_id | The player ID of the player that controls the character that is searching the container |
'
+ +'thief | token_id | The token ID of the character searching the container |
'
+ +'charName | < text > | The name of the character that is searching the container |
'
+ +'tstr | # | The strength score of the character searching the container |
'
+ +'tint | # | The intelligence score of the character searching the container |
'
+ +'tdex | # | The dexterity score of the character searching the container |
'
+ +'bruteStr | # | The "bend-bars" chance of the character searching the container |
'
+ +'openLock | # | The "open locks" score of the character searching the container |
'
+ +'remTrap | # | The "find/remove traps" score of the character searching the container |
'
+ +'
'
+ +'
The attributes "gm-rolls" & "trap-status" are used in the macros as qualifiers to onward macro calls. For example:
'
+ +'
!magic --display-ability @{^^chest^^|thief}|^^chestid^^|@{^^chest^^|gm-rolls}Unlocked
'
+ +'
will either run the macro Unlocked
or GM-Roll-Unlocked
depending on the current value of "gm-rolls" on that container, where the "Unlocked" macro allows the Player to roll the dice for finding traps, whereas "GM-Roll-Unlocked" has the GM make the roll. And as another example:
'
+ +'
!magic --display-ability @{^^chest^^|thief}|^^chestid^^|Trap-@{^^chest^^|trap-status}
'
+ +'
will run either the macro Trap-Armed
or Trap-Disarmed
depending on the value of "trap-status" with alternative consequences for the party!
'
+ +'
Of course, the ChatSetAttr command !setAttr can be used to change the values of these attributes as the player progresses through the sequence of macros, successfully removing the trap and setting trap-status to "Disarmed", or getting the correct combination and setting the trap-status|max to "Unlocked". Use of these statuses is important when the !magic --find-traps command or the equivalent Items Menu / Find Traps dialog is used, which finds (and possibly removes) the trap before tackling any lock.
'
+ +'
4. Locks & Traps Database
'
+ +'
The Drag & Drop container draws upon ability macro definitions in the Locks & Traps Database to configure their traps and locks. As with all other RPGMaster suite databases, this Database is distributed with the APIs in code, but can be extracted to review and copy elements by using the !magic --extract-db Locks-Traps-DB command, which will extract the database to a character sheet, where the entries can be seen as ability macros. (It is recommended that you do not keep complete extracted databases, but instead copy those elements you want to use to your own database and then delete the extracted database - this will optimise system performance).
'
+ +'
The Locks & Traps databases have names that start with Locks-Traps-DB and can have anything put at the end, though those with version numbers of the form v#.# as part of the name will be ignored.
'
+ +'
As previously stated, each database definition has 3 parts in the database (see Section 1): an Ability Macro with a name that is unique and matches the trap/lock action, a custom Attribute with the name of the Ability Macro preceded by "ct-", and a listing in the database character sheet of the ability macro name separated by \'|\' along with other trap/lock macros. The quickest way to understand these entries is to examine existing entries. Do extract the root databases and take a look (but remember to delete them after exploring the items in them, so as not to slow the system down unnecessarily).
'
+ +'
Note: The DM creating new trap/lock macros does not need to worry about anything other than the Ability Macro in the database, as running the !magic -check-db Locks-Traps-DB command will update all other aspects of the database appropriately, as long as the Specs fields are correctly defined.
'
+ +'
Ability macros can be added to a database just by using the [+Add] button at the top of the Abilities column in the Attributes and Abilities tab of the Database Character Sheet, and then using the edit "pencil" icon on the new entry to open it for editing. Ability macros are standard Roll20 functionality and not dependent on the API. Refer to the Roll20 Help Center for more information.
'
+ +'
4.1 Trap-# Ability Macros
'
+ +'
Here is an example of a Lock & Trap Database entry for a "Trap-0" type macro. Note that Trap-# macros are somewhat different from other Ability Macros in the Locks-Traps-DB, as they set up the trap/lock on first selection of the locked / trapped container.
'
+ +'
Key Lock
'
+ +'
&{template:RPGMmessage}{{title=^^chest^^}}Specs=[Key-Lock,Lock|Ability,0H,Trap-0]{{desc=Do you have the key? [Key @{^^chest^^|lock-var1}](!magic --display-ability c|^^tid^^|^^chest^^|Unlocked). If not are you going to try and pick the lock? To do so [Roll 1d100](~^^chest^^|Open-Locks) and get less than your Open Locks percentage, which is [[{ {@{selected|olt} },{5} }kh1]]. If neither, then I suppose you can try [Brute Strength](!magic --display-ability c|^^tid^^|^^chest^^|Smash-the-Lock)?}}AbilityData=[w:Key Lock, lvar1:53%%Key Number, ns:11],[cl:AB,w:Open+List],[cl:AB,w:Opened-Lock],[cl:AB,w:Pick-a-Lock],[cl:AB,w:Return-Trap-2],[cl:AB,w:Find-Trap-Roll],[cl:AB,w:Return-Trap-3],[cl:AB,w:Find-Remove-Traps],[cl:AB,w:Smash-Lock],[cl:AB,w:Lock-Smash],[cl:AB,w:Not-Smashed],[cl:AB,w:Reset-Trap,action:1]{{GM desc=A key lock requires the searcher to have in their possession (though the system does not check) a particular key - or alternatively the searcher can try to pick the lock or smash it. If the lock pick fails or a critical fail is made on smashing the lock, any associated trap is triggered.
The GM can set the key name and the critical fail roll by selecting the container token and using the GM\'s [Token Setup] button, or the **!cmd --abilities** command.}}
!setattr --silent --charid ^^chestid^^ --dexterity|@{^^cname^^|dexterity} --thief|^^tid^^ --chest|^^targettid^^ --bruteStr|@{^^cname^^|bendbar} --strength|@{^^cname^^|strength} --openLock|@{^^cname^^|olt} --remTrap|@{^^cname^^|rtt} --intelligence|@{^^cname^^|intelligence} --charName|^^cname^^
'
+ +'
There are a number of aspects in common with the Container database entry described in the previous section: it uses a Roll Template, in this case one provided by the RPGMaster suite, it has a Specs specification in common with all RPGMaster database items, and there is a Data specification. However, the Specs and Data specifications have some differences:
'
+ +'
Specs: the format that is standard across all RPGMaster database entries:
'
+ +'
Specs=[Key-Lock,Lock|Ability,0H,Trap-0]
'
+ +'
Slotted between Roll Template fields, the Specs field will not appear to the players, but is only available to the APIs. The first field is always the database item type (or name), the second is the class of database item (in this case a "Lock|Ability" database item), the third is the handedness of the item (not currently relevant to Lock & Trap items), and the fourth the Super-type which in the case of Lock & Trap items is the name this macro will be stored as in the container character sheet that uses it.
'
+ +'
Important Note: Lock & Trap database entry names (both the name of the Ability Macro and the first Specs data field) must be different from any Super-type Specs field (the fourth field). This ensures the database & character sheet tidying functions don\'t delete the lock & trap macros from trapped / locked container character sheets. Trapped / locked containers run from Roll20 macros stored on the character sheet - if a --tidy function is executed on a trapped / locked container, any ability macros on the character sheet that have the same name as a Locks-Traps-DB data entry will be deleted (the API assumes that they can be read from the database, but in the case of Locks & Traps they can\'t).
'
+ +'
The database entry class (the second Specs field) can be one of Lock|Ability, Trap|Ability, or just Ability. The (somewhat obvious) meaning is that those with Lock specify types of lock, and those with Trap specify types of trap. Those with just Ability specify steps in the action of a lock or trap. Locks and traps can be mixed for any container, allowing lots of interesting combinations.
'
+ +'
AbilityData: AbilityData specifications cannot "inherit" from parent ability definitions, as stated above. The elements in the AbilityData specification define data that the locks & traps use during game play, that may affect their behaviour. The data tags in the AbilityData are very similar to those in RaceData specifications for containers, and will overwrite those in the container definition when selected as a lock or trap for a container. Some of the relevant data tags are:
'
+ +'
'
+ +'Tag | Format | Default | Description |
'
+ +'w: | Text | \' \' | The name of the lock/trap |
'
+ +'magical: | [ 0 | 1 ] | 0 | Only for traps: trap is magical in nature (1), so "Remove Trap" rolls have half the chance they would otherwise |
'
+ +'cimg: | url | undefined | The URL of the image to use for a closed container |
'
+ +'oimg: | url | undefined | The URL of the image to use for an open container |
'
+ +'limg#: | < url >[%%label] | undefined | The optional URL of a user-definable image related to locks stored as lock-img# with an optional variable label |
'
+ +'timg#: | < url >[%%label] | undefined | The optional URL of a user-definable image related to traps stored as trap-img# with an optional variable label |
'
+ +'lvar#: | < text or # >[%%label] | \' \' | An initial setting for lock-var# with an optional variable label |
'
+ +'tvar#: | < text or # >[%%label]> | \' \' | An initial setting for trap-var# with an optional variable label |
'
+ +'ns: | # | 0 | The number of extra data specifications following the first dataset |
'
+ +'cl: | AB | AC | MI | WP | \' \' | The class of the extra dataset. AB = Abilities that form part of this lock/trap |
'
+ +'w: | Ability name | undefined | The name of the data item pointed to by the extra dataset, in this case a lock/trap ability |
'
+ +'action: | [ 0 / 1 ] | 0 | A flag indicating if the Ability should appear as a token Action Button |
'
+ +'
'
+ +'
The Key Lock is defined as: setting user variable 1 as 53 (in this case predefining an expectation that key 53 opens the chest) with a label of "Key Number"; states there are 11 additional extra datasets; all the extra datasets are of the Abilities class; and each of the extra datasets specifies a macro definition from the Locks-Traps-DB that will be processed and stored in the Dragged & Dropped container.
'
+ +'
Dynamic fields: There are a number of Dynamic Fields used in this macro - the fields of the format ^^...^^. These are dynamically replaced at run time with the data they represent, which is dependent on the specific circumstances at that point in time. Most of these are only valid in "Trap-" macros (any macro with a Supertype (Specs field 4) starting "Trap-"):
'
+ +'
'
+ +'Dynamic Field | Validity | Description |
'
+ +'^^chest^^ | All macros | The character sheet name of this particular container |
'
+ +'^^chestid^^ | All macros | The character sheet ID of this particular container |
'
+ +'^^cname^^ | Trap- only | The character name of the character searching (or storing items in) the container |
'
+ +'^^tname^^ | Trap- only | The token name of the character searching (or storing items in) the container |
'
+ +'^^cid^^ | Trap- only | The character sheet ID of the character searching (or storing items in) the container |
'
+ +'^^tid^^ | Trap- only | The token ID of the character searching (or storing items in) the container |
'
+ +'^^targetchar^^ | Trap- only | Another way of specifying the character sheet name of the container (but only in Trap- macros) |
'
+ +'^^targettoken^^ | Trap- only | The token name of the container |
'
+ +'^^targetcid^^ | Trap- only | The character sheet ID of the container |
'
+ +'^^targettid^^ | Trap- only | The token ID of the container |
'
+ +'
'
+ +'
API buttons: The lock & trap macros run using standard Roll20 functionality, and can contain any legitimate functions that Roll20 supports, as well as API calls to loaded mods (such as the RPGMaster suite itself). To support the player (and GM) interacting with the locks and traps, API buttons are used. API buttons are text enclosed in brackets, followed by commands in parentheses e.g. [Button text](command). These are standard Roll20 macro functionality and help on them can be found in the Roll20 Help Center.
'
+ +'
The most common use in locks & traps is to have the player run the next macro from a choice of possible actions: the next macro can be called using (~^^chest^^|macro-name) or (!magic --display-ability whisper-type|to-token-ID|^^chest^^|macro-name). The !magic --display-ability command has the advantage of being able to whisper to a character, player, the GM or publicly, whereas the tilde \'~\' macro call is less flexible, but \'~\' can allow 3D dice rolls, whereas !magic --display-ability will not. See MagicMaster Help handout for more information on the --display-ability command.
'
+ +'
Use of !setattr: the call to the ChatSetAttr API (see separate documentation) is used to set several local custom attributes on the container\'s character sheet, so that the values can be accessed as the trap / lock sequence of macros progresses. Each of the values stored may not be otherwise available, as the creature doing the searching may lose the focus, and no longer be the "selected" token which otherwise would cause errors.
'
+ +'
4.2 Other Lock & Trap Database Macros
'
+ +'
Ability Macros other than those that represent "Trap-" macros do not have a number of the same features. The Open-Locks macro from the Key Lock sequence is shown below: note that the Ability Macro name in the database is "Pick-a-Lock", following the rule that the database macro name and the Supertype must be different, with the Supertype being the name that will end up in the container:
'
+ +'
Pick a Lock
'
+ +'
&{template:RPGMdefault}{{title=^^chest^^}}Specs=[Pick-a-Lock,Ability,0H,Open-Locks]{{desc=You are trying to pick the lock of ^^chest^^. Your success is determined against your Open Locks percentage}}{{Target=[[{ {5},{@{^^chest^^|openLock} } }kh1]]%}}{{Roll=[[?{Roll to Pick the Lock|1d100}]]}}{{Result=Roll<=Target}}{{successcmd=!magic ~~display-ability c¦`{^^chest^^¦thief}¦^^chest^^¦Unlocked}}{{failcmd=!magic ~~display-ability public¦`{^^chest^^¦thief}¦^^chest^^¦Triggered}}
'
+ +'
Here it can be seen that the Specs database specifier shows that the database name is "Pick-a-Lock" (the first field), but it is saved in the container character sheet as "Open-Locks" (the 4th field). The macro also uses the value of OpenLock, a custom attribute that was stored using the ChatSetAttr API call in the "Trap-" macro call, as it cannot be guaranteed at this point in the process that the searching character token is still selected. It is also the case that the only dynamic fields available in macros other than the "Trap-" macros are "^^chest^^" and "^^chestid^^", which will always be replaced with the character sheet name and ID (respectively) of the container when it is built by the Drag & Drop process and the ability macros are added to its sheet.
'
+ +'
Note: This macro is using some specialised features of the RPGMaster Roll Templates: in this case the Result field tag will actually run a comparison of the numbers in the Roll and Target fields and display a green "Success" bar or a red "Failed" bar, depending on the result. The template will also run either the command string in the "successcmd" field, or the command string in the "failcmd" field, depending on the result, thus automatically affecting the macro sequence.
'
+ +'
The other macros required to make the Key Locked Chest work are defined and used in a similar fashion. See an extracted database for more examples.
'
+ +'
4.3 Trap/Lock Variables
'
+ +'
The author of the container ability macros can, of course, use the ChatSetAttr API command !setattr to store new custom attributes on any character sheet (but most typically the container\'s character sheet) to make changes in behavior. However, up to nine lock variables and nine trap variables exist that can be set using the RPGMaster container management dialog without going into the macro code. The AbilityData specification in any Lock|Ability or Trap|Ability macro can give them initial values and labels (using the syntax "lvar#:value%%label" or "tvar#:value%%label" with the %%label being optional), and those values altered for each individual dropped container to achieve changes in behavior as documented in each container specification. In the Ability Macros, these are then accessed either with @{^^chest^^|lock-var#} or @{^^chest^^|trap-var#}.
'
+ +'
4.4 Token Images
'
+ +'
There are up to 20 image URL variables that can be set by the Drag & Drop container system, each of which are paired with values for the width and height to set the token to. Two of these are reserved for the URLs of the images of the closed and open containers, nine are available for use by locks, and another nine for use by traps.
'
+ +'
'
+ +'Data Tag | Image variable | Width variable | Height variable | Used for |
'
+ +'cimg | closed-img | closed-img-size | closed-img-size|max | The image URL for a closed container |
'
+ +'oimg | open-img | open-img-size | open-img-size|max | The image URL for an open container |
'
+ +'limg1 | lock-img1 | lock-img1-size | lock-img1-size|max | The image URL for the first user-defined lock image |
'
+ +'limg2 | lock-img2 | lock-img2-size | lock-img2-size|max | The image URL for the second user-defined lock image |
'
+ +'limg# | ... | ... | ... | The image URL for the #th user-defined lock image |
'
+ +'limg9 | lock-img9 | lock-img9-size | lock-img9-size|max | The image URL for the ninth user-defined lock image |
'
+ +'timg1 | trap-img1 | trap-img1-size | trap-img1-size|max | The image URL for the first user-defined trap image |
'
+ +'timg# | ... | ... | ... | The image URL for the #th user-defined trap image |
'
+ +'timg9 | trap-img9 | trap-img9-size | trap-img9-size|max | The image URL for the ninth user-defined trap image |
'
+ +'
'
+ +'
All the variables and the images can be set using RaceData tags in the container specification, can be added to or overwritten by the AbilityData tags in the lock and trap specifications, and altered individually for each dropped container using the GM\'s [Token Setup] button or the !cmd --token-img token_id command. An example of the use of the trap-img1 is below:
'
+ +'
Chest 4 Poison Dart trap
'
+ +'
&{template:RPGMwarning}{{name=Poison Dart trap}}Specs=[Poison-dart-trap,Trap|Ability,0H,Triggered]{{desc=Oh no! You\'ve triggered a trap and four poison darts fly out, one from each side of the ^^chest^^, each doing [[@{^^chest^^|trap-var1}]]HP piercing damage and [[@{^^chest^^|trap-var2}]]HP poison damage (@{^^chest^^|trap-var3})}}AbilityData=[w:Poison Dart trap, magical:0, tvar1:1%%Dart Damage Roll, tvar2:2d4%%Poison Damage Roll, tvar3:Poison Type C%%Poison Type, timg1:https://s3.amazonaws.com/files.d20.io/images/352954823/u8yGNHOGKcTsoJQB_A3b6Q/thumb.png?1690920737|280%%Dart Ranges, ns:3],[cl:AB,w:Poison-dart-trap-noticed],[cl:AB,w:Remove-Trap-Roll],[cl:AB,w:Reset-trap,action:1]{{GM desc=The poison dart trap will shoot poison darts from the container if triggered. The GM can set the damage done by the darts, the damage done by the poison, the name of the poison type (DMG p73), and set trap image 1 displaying the ranges of the poison darts by selecting the container token and then using the GM\'s [Token Setup] button, or the **!cmd --abilities**.}}
!token-mod --ignore-selected --ids @{^^chest^^|chest} --set imgsrc|@{^^chest^^|trap-img1} width|@{^^chest^^|trap-img1-size} height|@{^^chest^^|trap-img1-size|max}
'
+ +'
The key part of this macro is the !token-mod call to the TokenMod API that changes the imgsrc, width, and height values of the container token, to the image stored in trap-img1 which in this case shows the chest with the ranges of the four poisoned darts that are ejected by the trap on this chest.
'
+ +'
3.4 Types of Container Traps and Locks
'
+ +'
The container database that comes with the APIs has examples of a number of different types of lock and trap:
'
+ +'
- A key lock that asks if those looting have a specific key
'
+ +'- A Password-based lock requiring the right password to open
'
+ +'- A three-digit Combination Lock
'
+ +'- An unlocked spell book to which a trap can be added
'
+ +'- A poison dart trap, with specifiable damage & poison type
'
+ +'- A wizard\'s spell trap, with specifiable spell and area of effect
'
+ +'- An exploding runes trap that turns the container to ash
'
+ +'- A dead body that can "come to life" as any specifiable Drag & Drop creature
'
+ +'- A sleeping character that wakes on an unsuccessful pick-pockets roll
'
+ +'
There may also be more than these - this is the list at the time of writing. And each lock can be matched to any trap (or none) - so matching a combination with "Wake the Dead" and get the combination wrong a Lich is summoned! These can be extracted from the APIs using the command !magic --extract-db Locks-Traps-DB and used as examples.
'
+ +'
4. Structure of a Locked/Trapped Container
'
+ +'
As you will recognise if you have reviewed the earlier sections of this document, there are a number of different Roll20 ability macros that are inserted into a container\'s character sheet by the Drag & Drop Container system. The combination of macros inserted to the character sheet is important to make sure the container locks and traps work. It is key that there is a starting point for a character searching and looting the container, and that this starting point leads on to a sequence of macros that lead the character on a journey to either open the container and the ability to loot its items, or to suffer the consequences of a lack of caution.
'
+ +'
4.1 The Starting Point
'
+ +'
The starting point is always a macro of database item Supertype (Specs field 4) Trap-# (generally Trap-0) (or just Trap). This macro will include text to describe to the player what they are faced with as a lock &/or trap, in the current state of the lock & trap. The state of the container will be determined by the Trap-version attribute of the container:
'
+ +'
'
+ +'Trap-version | State represented |
'
+ +'0 | Locks & Traps (if any) are in tact and in a locked & set state |
'
+ +'1 | Locks & Traps have all been overcome and the container is easily lootable |
'
+ +'2 | Lock partially overcome, or lock open and awaiting a hunt for traps |
'
+ +'3 | Found a trap and awaiting the removal of the trap |
'
+ +'# | Other numbers can represent additional states the container can be left in |
'
+ +'
'
+ +'
When a character conducts a search of the container, the RPGMaster APIs will start by calling a macro on the container called Trap-#, where "#" is the current value of the Trap-version. Thus, the character encounters the container in its current state.
'
+ +'
The Trap-0 macro is a special case: it not only is an entry point lock macro, but it defines the whole structure of the lock, the other database items that make it up, and the initial state of variables and images. It is always of database item class Lock|Ability. Its name will be the name of the lock displayed when specifying the lock for the container with the !cmd --token-img command, or the [Token Setup] action. It is the only lock macro to have an AbilityData specification. The AbilityData includes a number of repeating data sets, one for each additional Locks-Traps-DB database item that makes up the lock. Each of these extra data sets is of cl: type "AB" (although they can also include type "AC", "MI" or "WP" to add items, equipment or weapons to the container), and a w: of the database item name (not the Supertype of the item).
'
+ +'
Other Lock Macros
'
+ +'
Each of the database items named in the Trap-0 macro must have a Specs specification with:
'
+ +'
'
+ +'- First field: Type (or name) of the database item
'
+ +'- Second Field: "Ability"
'
+ +'- Third field: Handedness (not yet used for Lock or Trap macros)
'
+ +'- Forth field: Supertype - the name the macro will be given in the container sheet
'
+ +'
'
+ +'
The Supertypes of the lock must form links via API button calls (or other means of linking) in a meaningful sequence. The paths must lead to a hand-off to the macros that define any trap that is associated with the container. In general, the lock also accepts an interface from the trap macro path to a macro with a Supertype of "Opens-list" which is included in the Lock specification. The lock may also provide macros of Supertypes "Trap-1" and "Trap-2".
'
+ +'
Macros Specifying a Trap
'
+ +'
The trap macros will have entry points of "Triggered" and "Trap-Noticed". In this case, the special case is the macro of Supertype Triggered, with the database item class Trap|Ability. This macro is the one who\'s name will be listed when selecting a trap for the container with the !cmd --token-img command, or the [Token Setup] action. It is also the only trap macro to have an AbilityData specification specifying initial states for trap-var# attributes, any token images used by the trap which, like the lock "Trap-0" macro, includes a number of repeating data sets, one for each additional Locks-Traps-DB database item that makes up the trap. Each of these extra data sets is of cl: type "AB", and a w: of the database item name (not the Supertype of the item).
'
+ +'
Other Trap Macros
'
+ +'
Each of the database items named in the Triggered macro must have a Specs specification of the same structure as the lock macros. As with locks, the Supertypes of the trap macros must form links via API button calls (or other means of linking) in a meaningful sequence. The paths typically lead to a conclusion that either results in inflicting some sort of penalty on the character trying to loot the container, or the container opening and revealing its contents. The opening is generally by handing off to a macro provided by the lock of Supertype "Opens-list".
'
+ +'
A macro of Supertype "Trap-Noticed" will be called by the lock macros if a trap has been found by the character, and they want to attempt to remove it. The Trap-Noticed" macro will do what is necessary to determine if the particular trap selected can be removed successfully, or if the trap is actually triggered, calling other macros in sequence as necessary, often including calling the Triggered macro if the trap is not removed successfully.
'
+ +'
Example Lock/Trap Ability Flow
'
+ +'
Here is an example of how a lock and a trap, taken from the Locks-Traps-DB, create a sequence of ability macros in the chosen container character sheet. It is based on the Key Lock and Poison Dart Trap already introduced earlier in this help handout.
'
+ +'
'
+ +'Yellow = A part of the Lock | Green = A part of the Trap |
'
+ +'Trap-1 | => | Opens-List |
'
+ +'Trap-3 | => | Trap-Noticed | => | Unlocked-Remove-Trap | [Success] | => |
'
+ +'Trap-2 | => | Unlocked | => | Unlocked-Find-Trap | [Success] | => | [Fail] | => | Triggered |
'
+ +'Trap-0 | [Have Key] | => | [Fail] | => |
'
+ +'[Pick the Lock] | => | Open-Locks | [Success] | => |
'
+ +'[Fail] | => |
'
+ +'[Brute Strangth] | => | Smash-The-Lock | => | Smashed-Lock-Check | [Success] | => | Unlocked | ^^^ | |
'
+ +'[Critical Fail] | => |
'
+ +'[Fail] | => | Still-Locked |
'
+ +'
'
+ +'
5. Specs & Data field values
'
+ +'
Below are lists of the current possible values for the Lock and Trap database Ability macro sections.
'
+ +'
5.1 Specs sections
'
+ +'
Specs=[Lock Type, Lock|Ability, Handedness, Trap-0 (or Trap)]
'
+ +'
Specs=[Lock Type, Ability, Handedness, Supertype]
'
+ +'
Specs=[Trap Type, Trap|Ability, Handedness, Triggered]
'
+ +'
Specs=[Trap Type, Ability, Handedness, Supertype]
'
+ +'
If the item class (field 2) is "Lock|Ability", the Supertype must be "Trap-0" or "Trap", and visa-versa.
'
+ +'
If the item class (field 2) is "Trap|Ability", the Supertype must be "Triggered", and visa-versa.
'
+ +'
All fields must be explicitly specified.
'
+ +'
5.1(a) Lock and Trap Types
'
+ +'
There is an infinite list of lock types: the type of the "Lock|Ability" macro is the Lock name.
'
+ +'
There is an infinite list of trap types: the type of the "Trap|Ability" macro is the Trap name.
'
+ +'
5.1(b) Macro Class
'
+ +'
Classes: One of "Lock|Ability", "Trap|Ability", or just "Ability". This field is used to add the Lock or Trap name to the right base list for selection by the GM to configure the container.
'
+ +'
5.1(c) Handedness
'
+ +'
Handedness for Locks & Traps are not currently restricted or used by the system. In future, the number of hands specified for a lock or trap might indicate how many hands need to be contributed to enact the opening of a lock or the removal of a trap.
'
+ +'
5.1(d) Lock & Trap Supertypes
'
+ +'
The following Supertypes must exist for each defined lock:
'
+ +'
Trap-0 (or Trap), Opens-list
'
+ +'
The following Supertypes must be called by each defined lock:
'
+ +'
Triggered
'
+ +'
The following Supertypes must exist for each defined trap:
'
+ +'
Triggered, Trap-Noticed
'
+ +'
Below is a table of the Supertypes currently provided and used in the Locks-Traps-DB as distributed with the APIs. Each Supertype may be used by several lock or trap sequence macros, each having a slightly different effect for that stage in the sequence. Some Supertypes require different processing for certain Locks/Traps if the Player is rolling for skills as opposed to the GM (set by the !magic --config command) - the appropriate macro will be used depending on the configuration for who rolls for skills at the point the Drag & Drop container is built. Note: changing the configuration after the container is built will not alter the behaviour of the container. The container must be rebuilt if you wish the behaviour to change.
'
+ +'
'
+ +'Supertype | Macro Versions |
'
+ +'Player Rolls | GM Rolls |
'
+ +'Trap-0 | Combination-Lock Key-Lock Password-Lock No-Lock Sleeping-Creature Undead-Body |
'
+ +'Triggered | Four-Dart-Trap Destroying-Spell-Trap Single-Poison-Dart-Trap Summon-Undead Summon-Creature Wizard-Spell-Trap Combination-Wrong-No-Trap Explosive-Runes-Trap No-Trap |
'
+ +' |
'
+ +'First-Digit-0 | First-Digit-Right |
'
+ +'First-Digit-1 | First-Digit-Wrong |
'
+ +'Second-Digit-0 | Second-Digit-Right |
'
+ +'Second-Digit-1 | Second-Digit-Wrong |
'
+ +'Third-Digit-0 | Third-Digit-Right |
'
+ +'Third-Digit-1 | Third-Digit-Wrong |
'
+ +'Attempt-Right | Password-Right |
'
+ +'Attempt-Wrong | Password-Wrong |
'
+ +'Open-Locks | Pick-a-Lock Pick-a-Pocket | GM-Roll-Pick-a-Lock GM-Roll-Pick-a-Pocket |
'
+ +'Lock-Unlocked | Unlocked-Lock |
'
+ +'Unlocked | Find-Traps | GM-Roll-Find-Traps |
'
+ +'Successful-PP |
'
+ +'Unlocked-Find-Trap | Find-Trap-Roll | GM-Roll-Find-Trap-Roll |
'
+ +'Open-Or-Find-Traps | No-Traps-Found |
'
+ +'Unlocked-Remove-Trap | Remove-Trap-Roll | GM-Roll-Remove-Trap |
'
+ +'Trap-Not-Removed | Trap-Remains |
'
+ +'Detected-Runes | Detect-Runes |
'
+ +'Smash-the-Lock | Smash-Lock | GM-Roll-Smash-Lock |
'
+ +'Smashed-Lock-Check | Lock-Smash | GM-Roll-Lock-Smash |
'
+ +'Still-Locked | Not-Smashed |
'
+ +'Trap-Noticed | Poison-dart-trap-noticed Found-Trap | GM-Roll-Dart-Trap-Noticed GM-Roll-Found-Trap |
'
+ +'No-Trap-Noticed Runes-Trap-Noticed |
'
+ +'No-Lock-Trap | No-Lock-No-Trap No-Lock-Is-Trapped |
'
+ +'Trake-Damage | Taken-Damage |
'
+ +'Opens-List | Open+List Open-the-Spellbook |
'
+ +'Trap-1 | Opened-Lock Opened-the-Spellbook |
'
+ +'Trap-2 | Return-Trap-2 |
'
+ +'Trap-3 | Return-Trap-3 |
'
+ +'Trap-4 | Destroyed-Container Destroyed-the-Spellbook |
'
+ +'Close | Close-Container |
'
+ +'Reset | Reset-Trap |
'
+ +'
'
+ +'
'
+ +'
5.2 Trap-version Values
'
+ +'
'
+ +'Trap-version | Mandatory | State represented |
'
+ +'0 (or none) | Yes | Locks & Traps (if any) are in tact and in a locked & set state |
'
+ +'1 | No | Locks & Traps have all been overcome and remain so and the container is easily lootable |
'
+ +'2 | No | Lock partially overcome, or lock open and awaiting a hunt for traps |
'
+ +'3 | No | Found a trap and awaiting the removal of the trap |
'
+ +'# | No | Other numbers can represent additional states the container can be left in |
'
+ +'
'
+ +'
5.3 Data Sections
'
+ +'
Below are the definitions for each of the possible RaceData fields.
'
+ +'
Note: Always refer to the database specification definitions in other sections above for detailed information on the use of these Field specifiers. Not all specifiers have an obvious use. Square brackets \'[...]\' indicate optional data - don\'t include the brackets when specifying the optional data.
'
+ +'
'
+ +' '
+ +' '
+ +' Field | '
+ +' Format | '
+ +' Default Value | '
+ +' Attribute | '
+ +' Description | '
+ +'
'
+ +' '
+ +' w: | < text > | \' \' | | Name of the database item |
'
+ +' magical: | [ 0 | 1 ] | 0 | Only for traps: trap is magical in nature (1), so "Remove Trap" rolls have half the chance they would otherwise |
'
+ +' slots: | # | 18 | container-size | Number of slots available in the container |
'
+ +' lvar#: | < text > | undefined | lock-var# | Variable used for lock processing. # can be 1 to 9 |
'
+ +' tvar#: | < text > | undefined | trap-var# | Variable used for trap processing. # can be 1 to 9 |
'
+ +' cimg: | URL [| width [| height ]] | Image of a closed chest | closed-img | URL of image of closed container, in a valid Roll20 format. Can be followed by width and/or height in pixels separated by pipes \'|\' |
'
+ +' oimg: | URL [| width [| height ]] | Image of an open chest | open-img | URL of image of open container, in a valid Roll20 format. Can be followed by width and/or height in pixels separated by pipes \'|\' |
'
+ +' limg#: | URL [| width [| height ]] [%% name] | undefined | lock-img# lock-img#-size lock-img#-size|max | URL of alternate lock image of container, in a valid Roll20 format. Can be followed by width and/or height in pixels separated by pipes \'|\', and a label for the image preceded by %% |
'
+ +' timg#: | URL [| width [| height ]] [%% name] | undefined | trap-img# trap-img#-size trap-img#-size|max | URL of alternate trap image of container, in a valid Roll20 format. Can be followed by width and/or height in pixels separated by pipes \'|\', and a label for the image preceded by %% |
'
+ +' ns: | < # > | 0 | | Number of repeating data sets |
'
+ +' cl: | < AB | MI | AC | WP > | \' \' | | Type of the repeating data set, AB = Lock / Trap ability |
'
+ +' w: | < text > | \' \' | | In repeating data set, database item name of macro to include in a lock or trap flow |
'
+ +'
'
+ +'
'
+ +'
5.4 Character Sheet data fields
'
+ +'
The Character Sheet field mapping to the API script can be altered using the definition of the fields object, the definition for which can be found at the top of the relevant RPGMaster Library API. You can find the complete mapping for all APIs in the RPGMaster series, with an explanation of each, in a separate document - ask the API Author for a copy.
'
+ +'
',
+ },
+ });
+
+ /*
+ * Handles for other RPG and Character Sheet specific data tables
+ * obtained from the RPGMaster Library.
+ */
+
+ var fieldGroups;
+ var primeClasses;
+ var classLevels;
+ var spellLevels;
+ var saveLevels;
+ var baseSaves;
+ var raceSaveMods;
+ var clTypeLists;
+ var miTypeLists;
+ var spTypeLists;
+ var classMap;
+ var reSpellSpecs;
+ var reClassSpecs;
+ var reAttr;
+ var baseThac0table;
+
+ const PR_Enum = Object.freeze({
+ YESNO: 'YESNO',
+ CUSTOM: 'CUSTOM',
+ });
+
+ const messages = Object.freeze({
+ noChar: '&{template:'+fields.warningTemplate+'} {{name=^^tname^^\'s\nMagic Items Bag}}{{desc=^^tname^^ does not have an associated Character Sheet, and so cannot attack}}',
+ initMsg:'&{template:'+fields.menuTemplate+'} {{name=Initialisation Complete}}{{desc=Initialisation complete. Command macros created. Go to Macro tab (next to the cog at the top of the Chat window), and select them to show In Bar, and turn on the Macro Quick Bar. Then start by dragging some characters on to the map to create tokens, and use Token-setup and Add-Items on each}}',
+ waitMsg:'&{template:'+fields.warningTemplate+'} {{name=Please Wait}}{{desc=Gathering data. Please wait for the menu to appear.}}',
+ convMsg:'&{template:'+fields.warningTemplate+'} {{name=Sheet Conversion}}{{Section1=You are about to convert the selected sheets to work with RPGMaster. This will move data from current tables and other places where it has previously been entered, and move it to where RPGMaster can make use of it. This means that the Character Sheets will probably become unusable in the way you were previously playing.